Skip to content

Phase 1: Memory namespace model — wire to cap-token + worker filter #108

@hanwencheng

Description

@hanwencheng

Context

Memory namespaces are the semantic dimension that makes the three-act M1 demo legible. Without them, "the toy sees travel memory but NOT the peanut allergy" is impossible to demonstrate — the worker either returns everything or nothing. Namespaces let cap-tokens carry "allowed namespaces" claims, the wire envelope carries the requested namespace, and the worker filters at request time.

This issue composes with the existing 4-type memory taxonomy (profile / procedural / semantic / episodic per docs/plan/agentkeys-memory-design.md). Types are structural (how the memory is encoded); namespaces are semantic (what life-context it belongs to). They compose: a single piece of episodic memory can live in the travel namespace.

Critical-path dependency for #107 (the MCP server's memory.get / memory.put tools depend on this).

Scope (M1)

  • Cap-token claim: add namespaces_allowed: ["personal", "travel"] to the broker-signed cap payload. The broker mints with the claim; the worker enforces it.
  • Wire-format field: add namespace: string field to memory put/get envelope. Out of band of S3 key derivation (preserves agent-iam-strategy.md §3.2a).
  • Memory worker filter: deterministic string-set membership check at request time. Wrong namespace → empty result + audit row (audit.namespace_violation).
  • v0 default namespaces: personal, family, work, travel (per agent-iam-strategy.md §3.5).
  • MCP server tools (Phase 1: AgentKeys MCP server — 7 active tools + 3 schema-only #107) accept + enforce the namespace param.

Out of scope (defer)

  • Path-prefixed namespace layout (keeps current S3 key derivation — defer until cross-namespace queries justify it; likely M4+)
  • Per-namespace embedding indexes (use existing global index — M2 if scale demands)
  • User-defined custom namespaces (v0 has 4 fixed; user-defined → M4 with delegation work)
  • kids / device / temp namespaces (M3-M4)

arch.md compatibility

Verified zero contradictions per IAM strategy §3.5. Compatible with:

  • arch.md §17.5 (data_class binding) — namespace orthogonal to data_class
  • arch.md §17 (per-actor PrincipalTag) — namespace is a worker-layer filter; doesn't change AWS IAM
  • arch.md §K3 epoch rotation — namespace metadata is not key-bound
  • agentkeys-memory-design.md §1 invariants — namespace is metadata, not encoding

Acceptance criteria

  • A device's cap-token with namespaces_allowed: ["travel"] successfully reads travel-tagged memory and returns empty result for personal / family / work namespaces
  • An audit row is emitted on cross-namespace access attempt (audit.namespace_violation)
  • The three-act demo Act 1 succeeds: toy sees Chengdu trip (travel), NOT peanut allergy (personal). Verified end-to-end against MagicLick 2.5 hardware running xiaozhi-esp32 firmware.
  • Unit tests for the worker's namespace filter (positive + negative)
  • Cap-token claim is signed (the broker's K1 signing covers namespaces_allowed) and the worker re-verifies before filtering

Risks

Risk Mitigation
Operators forget to tag memory at write time → memory becomes unreadable memory.put requires namespace param; missing param → 400 with clear error
Cross-namespace memory (e.g. "Chengdu trip with the kids" is both travel AND family) M1 ships single-namespace-per-write; cross-namespace tagging is M4 with delegation
Namespace name typos silently filter everything The 4 default namespaces are an enum at the wire layer; unknown name → 400

References

Effort

~3-4 days. Sequencing:

  1. (Day 1) Cap-token claim + broker mint flow + unit tests
  2. (Day 2) Memory worker filter + audit row + unit tests
  3. (Day 3) Wire envelope schema + worker integration test
  4. (Day 4) MCP server integration (handshake with Phase 1: AgentKeys MCP server — 7 active tools + 3 schema-only #107) + end-to-end test against mock backend

Depends on #107 MCP server scaffolding being far enough along that the memory.get / memory.put tools can be wired through.

Pickup notes for the next agent / developer

  • Read agent-iam-strategy.md §3.5 first — this is the strategic anchor
  • Then agentkeys-memory-design.md for the existing 4-type taxonomy
  • Existing memory worker lives at crates/agentkeys-worker-memory/ — extend its verify.rs filter logic
  • Cap-token shape lives in crates/agentkeys-broker-server/src/handlers/cap.rs — add the namespaces_allowed field there
  • The 4 default namespaces are an enum — represent as enum Namespace { Personal, Family, Work, Travel } with serde rename to lowercase strings
  • Watch for: namespace is NOT a substitute for data_class — data_class controls vault vs memory (per CLAUDE.md "Cap-tokens are data-class-explicit"); namespace is a sub-filter within memory only

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/brokerBroker server, cap-token issuance, OIDC issuancearea/memoryMemory worker, namespaces, semantic/episodic/profile/procedural storage

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions