Skip to main content

Implementer's Reference

Implementation contract for the Personal AI Architecture. No rationale, no history -- only what you need to build against.


Architecture Overview

4 components, 2 APIs, 3 externals.

LayerElements
ComponentsYour Memory, Agent Loop, Auth, Gateway
APIsGateway API (clients <-> Gateway), Model API (Agent Loop <-> Models)
ExternalsClients, Models, Tools

Components

Your Memory (the platform)

Zero outward dependencies. Every other component depends on it; it depends on none.

PropertyRequirement
DependenciesNone -- readable with standard tools when all components are stopped
ExposureThrough tools only (internal tools = the system's own interface to its platform)
InspectabilityMust be inspectable without the system running (text editor, file browser, database viewer)
ExportMust support full export in open formats from day one. Even if the implementation is a simple archive of the memory root, export is non-negotiable.
Version historyMust be reliably established at startup. If version history cannot be initialized, fail startup -- do not degrade to a warning.

Core operations: read, write, edit, delete, search, list, history

history must return change records and previous states, not just metadata. Accept an optional commit/version identifier to retrieve file content at that point in time.

Storage mechanisms (out of the box):

MechanismImplementation
FilesMarkdown, plain text
Version controlGit

Implementations can add storage mechanisms as needed (SQLite for structured queries, vector indexes for semantic search, etc.). Adding a mechanism means adding tool implementations — it doesn't change the contract. See memory-spec.md §Evolution.

Substrate test: If it stores/retrieves/searches/versions data, it belongs to Your Memory. If it interprets or produces content, it belongs to the model.

Skills are prompts stored in Your Memory. The model reads and follows them.

Agent Loop (generic agent loop)

Generic, commodity, no product-specific logic.

Loop: accept message -> send to model -> execute tool calls -> stream response -> repeat until the model signals completion.

PropertyRequirement
ConfigurationPre-configured at boot with tool definitions and provider config (not per-request)
ConcurrencyMust handle multiple concurrent loops independently
ScopeConnects models to tools -- nothing else
Iteration capThe Agent Loop MUST NOT impose a default iteration cap. Implementations MAY configure a safety bound as a deployment choice.
Text preservationWhen the model emits text and tool calls in the same turn, the Agent Loop must preserve the text in the assistant message for the next loop iteration. Do not discard streamed text on tool continuation.

The Agent Loop does NOT:

  • Construct prompts
  • Manage skills
  • Handle approval state
  • Enforce scope
  • Decide context
  • Persist conversations
  • Authenticate
  • Have personality

Auth (cross-cutting layer)

Independent of Gateway -- both are swappable independently.

Three operations:

OperationSignature
Authenticaterequest -> identity
Authorize(identity, resource, action) -> allow/deny
Managemodify permissions

Middleware position: Sits between Gateway and the Agent Loop. Validates via headers, rejects unauthorized with 401.

Headers: X-Actor-ID, X-Actor-Permissions

Actor types: owner, collaborator, system agent, background agent, external agent, service, economic actor, federated

Policy model: (subject, resource, action) -> effect

Minimal tool surface (required from day one):

ToolReturns
auth_whoamiCurrent actor identity
auth_checkPermission decision for a given resource/action
auth_exportAuth configuration minus credentials

Data format is product-owned, not provider-specific.

Gateway (conversations and routing)

Manages conversations and routes to the Agent Loop. Content-agnostic, interface-agnostic.

Operations: create conversation (implicit on first message), list, resume, history

Guarantees: route, persist conversations, resume, stream, content-agnostic, interface-agnostic

Stores conversations in Your Memory.

Gateway does NOT:

  • Interpret messages
  • Execute tools
  • Authenticate
  • Influence model behavior
  • Route to models
  • Transform content
  • Inject context
  • Rate limit
  • Filter content

API Contracts

Gateway API (Clients <-> Gateway)

How the world interacts with the system.

DirectionPayload
InMessage content + conversation ID (optional) + metadata
OutStreamed response + conversation ID + message record

Built on prevailing industry standard. Swappable via adapter.

Model API (Agent Loop <-> Models)

How the system thinks.

DirectionPayload
InPrompt (system instructions + conversation + tool definitions + context)
OutStreamed completion (text + tool calls)

Model-native tool calling is the current approach. Swappable via adapter.


Internal Contract: Gateway <-> Agent Loop

One HTTP endpoint. Not a third API.

POST /engine/chat

Request:

{
"messages": [
{ "role": "system", "content": "..." },
{ "role": "user", "content": "..." }
],
"metadata": {
"conversation_id": "conv_abc123",
"correlation_id": "req_xyz789",
"trigger": "message",
"client_context": { "path": "/finances" }
}
}

Required fields:

FieldRequired
messagesYes
metadata.correlation_idYes
metadata.conversation_idNo
metadata.triggerNo
metadata.client_contextNo

Response: SSE stream

EventData Shape
text-delta{ content: string }
tool-call{ id: string, name: string, arguments: object }
tool-result{ id: string, output: string } or { id: string, error: string }
done{ finish_reason: string, usage: { prompt_tokens, completion_tokens } }
error{ code: string, message: string }

Pre-stream errors (HTTP status codes):

CodeMeaning
400Invalid request
401Auth rejected
503Agent Loop unavailable

Mid-stream error codes: provider_error, tool_error, context_overflow

Error message safety: SSE error event messages must be safe for client display. Never forward raw Error.message, stack traces, or file paths into the stream. Map each error code to a fixed safe message; log raw diagnostic detail to structured stdout only.

Auth middleware path: validate request -> attach X-Actor-ID + X-Actor-Permissions headers -> reject with 401 on failure.


Responsibility Matrix

ResponsibilityOwnerNOT
Persist, retrieve, search, version dataYour Memory (via tools)
Provide structure (paths, hierarchy)Your Memory provides itModel/owner decides what
Understand content, make meaningModelYour Memory, Agent Loop
Assemble promptsModel reads from Your MemoryAgent Loop, Your Memory
Select contextModelYour Memory, Agent Loop
Execute toolsAgent LoopYour Memory
Decide which tools to useModel (via agent loop)Your Memory, Gateway
Execute skillsModel + Agent LoopYour Memory
Protect access / permissionsAuthYour Memory, Gateway
Manage conversationsGatewayAgent Loop, Your Memory
Route requests to Agent LoopGatewayAuth
Connect to AI modelsModel APIAgent Loop internals
Accept client connectionsGateway APIAgent Loop
Provide intelligenceModels (external)Agent Loop, Your Memory
Display content to ownersClients (external)Gateway
Bootstrap the systemRuntime config (4 fields)Your Memory
Resolve concurrent writesTool implementationsYour Memory component

Configuration

Runtime Config (thin bootstrap -- 4 fields)

FieldPurpose
memory_rootWhere Your Memory lives
provider_adapterWhich adapter connects to models
auth_modeHow auth works
tool_sourcesWhere to find installed tools

Where things live

WhatWhere
PreferencesYour Memory (personal data, travels with you)
Tool definitionsSelf-describing (from the tools themselves)
SecretsEnvironment variables only (never in files)
SkillsPrompts in Your Memory
Bootstrap promptOne line in Agent Loop config: "Read AGENT.md for your instructions"
Bind addressDefault 127.0.0.1 (localhost only). Network binding (0.0.0.0) requires explicit configuration. See DEPLOY-3, DEPLOY-5.

Boot Sequence

  1. Load runtime config
  2. Load adapter config
  3. Discover tools
  4. Mount Your Memory
  5. Verify version history (git init or equivalent). Fail if version history cannot be established.
  6. Read preferences
  7. Ready

Conformance Criteria

Swap Tests

IDTestPass Condition
SWAP-1Provider swapChange provider_adapter + adapter config -> next message uses new provider -> no code changes
SWAP-2Model swapChange model preference in Your Memory -> next message uses new model -> no code changes
SWAP-3Tool swapAdd/remove a tool -> system functions -> no code changes

Architectural Invariant Tests

IDTestPass Condition
ARCH-1Memory zero dependenciesStop all components except Memory storage -> still readable with standard tools
ARCH-2Agent Loop swapReplace Agent Loop -> Gateway/Memory/Auth/tools unaffected
ARCH-3Client swapNew client speaks Gateway API -> system serves identically
ARCH-4Schema conformanceAll API payloads validate against canonical schemas
ARCH-5Error taxonomy complianceEngine emits correct error codes per failure type -> no catch-all code
ARCH-6Error message sanitizationNo SSE error event contains paths, stack traces, or credentials
ARCH-7Memory exportmemory_export produces complete archive in open formats -> readable without system
ARCH-8Auth tool surfaceauth_whoami, auth_check, auth_export exist and return correct results
ARCH-9Version history reliabilitySystem fails to start if version history cannot be initialized -> memory_history returns previous states

Deployment Invariant Tests

IDTestPass Condition
DEPLOY-1Offline operationDisconnect network -> system functions for all memory operations
DEPLOY-2Local data storageAll owner data on owner-controlled storage -> no silent external writes
DEPLOY-3Default localhostFresh install binds to localhost only
DEPLOY-4No silent outboundNo network calls except explicit provider/tool requests
DEPLOY-5Default bind addressGateway binds to 127.0.0.1 only -> network binding requires explicit config change

Foundation User Story Tests

IDTestPass Condition
FS-1Move Your MemoryExport -> import -> preferences honored, gaps reported, nothing lost
FS-2Add capabilityAdd tool/skill/client/provider -> Memory gains no dependencies -> structure holds
FS-3Run on own hardwareInstall locally -> no external service required -> full offline capability
FS-4Swap provider= SWAP-1
FS-5Swap client= ARCH-3
FS-6Evolve MemoryAdd search capability -> no other component changes
FS-7Swap Agent Loop= ARCH-2
FS-8Expand scope via toolsAdd tools -> broader capability -> no architectural changes

Swappability

WhatHow
Your MemorySwappable via tools
ComponentsSwappable via contracts
ContractsSwappable via adapters
AuthSwappable via cross-cutting independence

Adapters are thin, stateless translation layers. Each describable in one sentence. See adapter-spec.md §How Model Configuration Works in Practice for the concrete model/provider swap walkthrough.

Tools are data in the environment, not a component. Definitions self-describe, execution is the Agent Loop's job, permissions are Auth's job.

Everything is either memory (nouns/data) or tools (verbs/operations). No third category.