RFC: Composable Peers — Universal Identity Containers for Honcho
Status: Draft Owner: vineeth Last updated: 2026-03-22
1. Problem Statement
Honcho’s peer model is intended to represent arbitrary concepts — people, agents, groups, organizations, projects — but in practice peers are treated as individual interlocutors in conversations. The system’s rigidity manifests in several ways:
-
Peers are not composable. You can’t express “engineering-team contains alice, bob, charlie” or “alice has a work context and a personal context.” Each peer is an island. There’s no way to segment a peer’s identity or aggregate knowledge across related peers.
-
Data can only flow into peers through conversations. Sessions → messages → deriver is the only ingestion path. There’s no way to feed a peer arbitrary documents or external data without creating synthetic sessions and injecting fake messages with hacky metacommentary.
-
No per-peer or per-session extraction guidance. The deriver treats every peer and every session the same way. But extracting personality traits from a person, architectural decisions from a project, and policy compliance from an organization are fundamentally different tasks.
-
The reasoning chain is immutable. Messages can’t be deleted, peers can’t be renamed, conclusions can’t be corrected without potentially invalidating the entire DAG of derived knowledge above them.
-
No developer-extensible reasoning. The dreamer runs fixed consolidation logic. Developers can’t define custom reasoning tasks like “maintain a weekly engagement summary” or “auto-segment this peer’s identity facets.”
-
Files aren’t native. There’s no clean place to store peer cards, dream outputs, reference knowledge, or agent memory files. These get stuffed into
internal_metadataor faked as messages.
Competitive Context
This RFC was informed by analysis of how Endearing (an AI companion product) uses Supermemory for memory. Key observations:
- Supermemory uses arbitrary container tags (e.g.,
user_123,groupchat_456,user_123-chat_789) that are created implicitly and carry per-container extraction guidance (“entity context”). - Containers are isolated by default. Cross-container search requires explicit fan-out.
- There’s no enforced relationship model. Containers are flat and semantically meaningless to the system — all meaning lives in the entity context and naming conventions.
Supermemory’s flexibility comes at the cost of having no cognitive layer — it stores and retrieves but doesn’t reason, model perspectives, or build theory of mind. Honcho’s advantage is its reasoning pipeline (deriver, dreamer, dialectic). The goal is to achieve Supermemory’s flexibility while preserving and extending Honcho’s cognitive differentiation.
2. Goals
- Make peers composable through a sub-peer model — any peer can have sub-peers, any peer can belong to multiple parent peers, and knowledge aggregates upward naturally.
- Add custom instructions / extraction context at the peer, session, and message levels so the deriver can tailor its reasoning. (Note: this work is already in progress separately.)
- Introduce peer-scoped markdown files for storing peer cards, dream outputs, reference knowledge, and agent memory.
- Enable restructuring operations (rename, merge, split) with managed invalidation of the reasoning chain.
- Extend the dreamer to support developer-defined materialized dreams — scheduled reasoning tasks that produce and maintain living documents.
- Add session-level filtering to dialectic and conclusion queries for fine-grained isolation.
3. Non-Goals
- Storing binary files (PDFs, images, etc.). Peer files are markdown/text only. External content continues to be converted to messages for ingestion.
- Turning Honcho into a general-purpose vector database. The value is in reasoning, not just retrieval.
- Breaking backward compatibility. Existing peers continue to work exactly as they do today — sub-peers are purely additive.
- Introducing a new entity type. Sub-peers are just peers. The
peer_membershipstable is the only new concept.
4. Design
4.1 Sub-peers: Hierarchical Peer Composition
The core idea: a peer can have sub-peers, and a peer can belong to multiple parent peers. Sub-peers are not a new type — they are regular peers with a membership relationship. Every peer can function independently: participate in sessions, have conclusions, have files, be queried directly.
Knowledge aggregation is directional:
- Query a parent peer → sees the parent’s own knowledge + all sub-peers’ knowledge (aggregation)
- Query a sub-peer → sees only that sub-peer’s knowledge (isolation)
This naturally provides both composition and isolation without scope tags, permissions, or special filtering. Think of it like a file system:
alice/ ← query here: sees everything
├── alice-dm/ ← query here: only DM knowledge
│ └── sessions, conclusions
├── alice-groupchat-standup/ ← query here: only group chat knowledge
│ └── sessions, conclusions
├── alice-gmail/ ← query here: only gmail knowledge
│ └── sessions, conclusions
├── sessions ← alice's own direct sessions
├── conclusions ← alice's own top-level conclusions
└── files/
├── card.md
└── profile.md
alice.message("hello") stores at the alice level. alice_dm.message("hello") stores at the sub-peer level. Both are valid. The parent peer is just a peer that happens to have members.
Schema:
CREATE TABLE peer_memberships (
id TEXT PRIMARY KEY,
workspace_name TEXT NOT NULL,
parent_peer TEXT NOT NULL,
child_peer TEXT NOT NULL,
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT now(),
UNIQUE (workspace_name, parent_peer, child_peer),
FOREIGN KEY (parent_peer, workspace_name) REFERENCES peers(name, workspace_name),
FOREIGN KEY (child_peer, workspace_name) REFERENCES peers(name, workspace_name)
);API surface:
POST /v3/workspaces/{id}/peers/{parent_peer}/members -- add a sub-peer
GET /v3/workspaces/{id}/peers/{parent_peer}/members -- list sub-peers
DELETE /v3/workspaces/{id}/peers/{parent_peer}/members/{child} -- remove a sub-peer
GET /v3/workspaces/{id}/peers/{peer_id}/parents -- list parent peers
Aggregation behavior:
When querying a peer’s representation, conclusions, or via the dialectic:
- The query includes the peer’s own knowledge
- Plus all immediate sub-peers’ knowledge (depth 1 by default)
- Configurable via
depthparameter:0= self only,1= self + immediate children (default),2= two levels,all= full tree - Cycle detection enforced at membership creation time (adding A as child of B fails if B is already a descendant of A)
Many-to-many membership:
A peer can belong to multiple parents. Alice can be a sub-peer of both engineering-team and project-alpha. Her knowledge aggregates upward to both. This is the same peer — not a copy.
Interaction with the existing observer/observed model:
The collection model (observer/observed) is unchanged. Collections store conclusions at the individual peer level. Sub-peer aggregation happens at query time, not storage time. The deriver continues to write conclusions to the specific peer that owns the session/messages — aggregation to parent peers is a read-time concern.
4.2 Custom Instructions (Context Fields)
Note: this work is already in progress separately. Included here for completeness and to show how it integrates with sub-peers.
Peers, sessions, and messages each gain a freeform context / custom_instructions field that the deriver incorporates into its extraction prompt:
- Peer-level: what kind of entity, what to focus on
- Session-level: what this session represents, how to interpret its contents
- Message-level: what this specific content is, who authored it
The deriver constructs its prompt from the full hierarchy. This replaces the hacky metacommentary pattern — instead of faking a message from Alice, you provide real content with context that explains its provenance.
4.3 Peer Files (Markdown)
Peers gain a lightweight file storage layer for markdown/text content:
CREATE TABLE peer_files (
id TEXT PRIMARY KEY,
workspace_name TEXT NOT NULL,
peer_name TEXT NOT NULL,
path TEXT NOT NULL,
content TEXT NOT NULL,
managed_by TEXT, -- null = user-created, 'system' = honcho-managed, 'dream:{name}' = dream output
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
UNIQUE (workspace_name, peer_name, path)
);What files are for:
- Peer cards: move from
internal_metadatato/card.md— readable and editable via API - Summaries: session summaries as inspectable files
- Dream outputs: materialized dreams write their results to files
- Reference knowledge: skills, org policies, agent instructions, style guides
- Agent memory: Claude Code-style
.mdfiles that agents read/write
What files are NOT for:
- Binary file storage (PDFs, images). These get converted to messages.
- Replacing the conclusion/collection model. Files are supplementary storage, not the reasoning substrate.
API surface:
POST /v3/workspaces/{id}/peers/{peer_id}/files -- create a file
GET /v3/workspaces/{id}/peers/{peer_id}/files -- list files
GET /v3/workspaces/{id}/peers/{peer_id}/files/{path} -- read a file
PUT /v3/workspaces/{id}/peers/{peer_id}/files/{path} -- update a file
DELETE /v3/workspaces/{id}/peers/{peer_id}/files/{path} -- delete a file
Enrichment: Files can optionally be chunked and embedded for semantic search. The dialectic gains a search_files(peer_id, query) tool. Files are NOT automatically processed by the deriver — they’re reference material, not conversation. If a developer wants a file’s content to produce conclusions, they ingest it as messages in a session.
Aggregation with sub-peers: When searching files on a parent peer, sub-peers’ files are included (respecting the same depth parameter as conclusion queries).
4.4 Reasoning Chain Invalidation
To enable restructuring operations (rename, merge, delete, correct), the system needs managed invalidation of derived knowledge.
Approach: Tombstone + staleness propagation with dreamer reconciliation.
- Staleness flag. Conclusions gain a
staleboolean andstale_reasontext field. - Source tracking. Conclusions already have
source_ids(JSONB array of premise document IDs). When a source is tombstoned or marked stale, downstream conclusions referencing it are also marked stale. - Dreamer reconciliation. The dreamer gains a new task type:
reconcile_stale. It re-evaluates stale conclusions against current evidence and either confirms, updates, or tombstones them. - Bounded propagation. Staleness propagates through the
source_idsDAG but is bounded — semantically independent downstream conclusions can be unmarked without re-derivation.
Restructuring operations:
| Operation | Mechanism |
|---|---|
| Delete message | Tombstone message; mark directly-derived conclusions stale; dreamer reconciles |
| Rename peer | Create new peer; migrate conclusions, memberships, files; tombstone old peer |
| Merge peers | Create target peer; migrate data from sources; dreamer resolves duplicates; tombstone sources |
| Split peer | Create sub-peers; move conclusions by criteria; mark affected derived conclusions stale |
| Correct conclusion | Update content; mark downstream conclusions stale; dreamer reconciles |
Open concern: Data flowing in while old data hasn’t been reconciled. New conclusions could be derived from stale premises. Mitigation: the deriver should skip stale conclusions as premises, and the dreamer should prioritize reconciliation over new dream tasks.
4.5 Materialized Dreams
The dreamer gains the ability to run developer-defined reasoning tasks that produce and maintain living outputs.
Schema:
CREATE TABLE dream_definitions (
id TEXT PRIMARY KEY,
workspace_name TEXT NOT NULL,
name TEXT NOT NULL,
peer_name TEXT,
prompt TEXT NOT NULL,
sources JSONB NOT NULL,
output_type TEXT NOT NULL, -- 'conclusions', 'file'
output_path TEXT, -- file path if output_type = 'file'
trigger_type TEXT NOT NULL, -- 'cron', 'on_change', 'on_demand'
cron_expression TEXT,
debounce_seconds INTEGER DEFAULT 300, -- min time between on_change triggers
enabled BOOLEAN DEFAULT true,
last_run_at TIMESTAMPTZ,
next_run_at TIMESTAMPTZ,
run_count INTEGER DEFAULT 0,
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT now(),
UNIQUE (workspace_name, name)
);API surface:
POST /v3/workspaces/{id}/dreams -- create
GET /v3/workspaces/{id}/dreams -- list
GET /v3/workspaces/{id}/dreams/{dream_id} -- get definition + last output
PATCH /v3/workspaces/{id}/dreams/{dream_id} -- update
DELETE /v3/workspaces/{id}/dreams/{dream_id} -- delete
POST /v3/workspaces/{id}/dreams/{dream_id}/trigger -- manually trigger
Output types:
conclusions: Dream produces conclusions stored in the target peer’s collection.file: Dream produces a markdown document written to a peer file atoutput_path. The file’smanaged_byis set todream:{name}.
Trigger system:
cron: Scheduler checks periodically, enqueues due dreams.on_change: Fires when new conclusions are added to source peers. Debounced bydebounce_secondsto prevent rapid re-runs during batch ingestion.on_demand: Only via explicit API trigger.
Built-in system dream — identity segmentation:
Honcho runs an automatic dream for every peer that discovers natural facets of their identity (professional, personal, interests, relationships, current-state, etc.). Conclusions are tagged with discovered facets via a facets field. This is a differentiator from Supermemory’s static developer-assigned categories.
4.6 Session-Level Filtering
The dialectic and conclusion query endpoints gain session-level filtering for fine-grained isolation within a peer:
# Only see conclusions derived from specific sessions
honcho.peers.get_representation(
peer_id="alice",
session_ids=["session-123", "session-456"]
)
# Exclude conclusions from specific sessions
honcho.peers.get_representation(
peer_id="alice",
exclude_session_ids=["private-session-789"]
)This composes with sub-peers:
- Sub-peers = coarse isolation (work vs home, DM vs group chat)
- Session filter = fine isolation (this specific conversation)
- Metadata filter = arbitrary isolation (existing capability)
For derived conclusions (deductive, inductive) that have no direct session: filter on the direct session_name field. Derived conclusions with null session are general knowledge — included by default, excludable via a exclude_derived: true flag.
4.7 Dialectic Enhancement
The dialectic agent gains new tools:
list_sub_peers(peer_id)— discover sub-peerslist_parent_peers(peer_id)— discover parent peerssearch_files(peer_id, query, top_k)— semantic search across a peer’s filesget_materialized_dream(peer_id, dream_name)— read a dream outputget_identity_facets(peer_id)— list discovered identity facetsget_representation_by_facet(peer_id, facet)— scoped representation
The existing tools (search_memory, get_representation, get_peer_card) continue to work. When called on a parent peer, they automatically include sub-peer knowledge (respecting depth).
5. Mapping: Endearing’s Supermemory Architecture
| Supermemory Pattern | Composable Peers Equivalent |
|---|---|
user_{id} container | Parent peer alice — query here for full knowledge |
groupchat_{chatId} container | Sub-peer alice-groupchat-123 — query here for group-only knowledge |
user_{id}-chat_{chatId} (force-scoped) | Sub-peer alice-chat-456 or session filter on parent peer |
| Entity context per container | extraction_context / custom instructions per peer |
| Filter prompt (org-wide) | Workspace-level configuration (existing) |
client.profile() (core + dynamic) | Representation on parent peer + materialized dream |
| Personalization agents (Gmail/LinkedIn) | Sub-peer alice-gmail with ingestion sessions |
| Memory categories (personal/professional) | Automatic identity segmentation (discovered facets) |
| Fan-out search across containers | Query parent peer (aggregates sub-peers automatically) |
| Container isolation | Query specific sub-peer (only that sub-peer’s knowledge) |
| Container merging | Peer merge operation with dreamer reconciliation |
| Conversation compaction | Session summaries (existing) |
6. Schema Changes Summary
Modified tables:
-- peers: add extraction context (custom instructions work may handle this separately)
ALTER TABLE peers ADD COLUMN extraction_context TEXT;
-- sessions: add context field
ALTER TABLE sessions ADD COLUMN context TEXT;
-- messages: add context field
ALTER TABLE messages ADD COLUMN context TEXT;
-- documents (conclusions): add staleness tracking and facets
ALTER TABLE documents ADD COLUMN stale BOOLEAN DEFAULT false;
ALTER TABLE documents ADD COLUMN stale_reason TEXT;
ALTER TABLE documents ADD COLUMN facets JSONB DEFAULT '[]';New tables:
-- peer_memberships: sub-peer composition
CREATE TABLE peer_memberships (
id TEXT PRIMARY KEY,
workspace_name TEXT NOT NULL,
parent_peer TEXT NOT NULL,
child_peer TEXT NOT NULL,
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT now(),
UNIQUE (workspace_name, parent_peer, child_peer),
FOREIGN KEY (parent_peer, workspace_name) REFERENCES peers(name, workspace_name),
FOREIGN KEY (child_peer, workspace_name) REFERENCES peers(name, workspace_name)
);
-- peer_files: markdown file storage
CREATE TABLE peer_files (
id TEXT PRIMARY KEY,
workspace_name TEXT NOT NULL,
peer_name TEXT NOT NULL,
path TEXT NOT NULL,
content TEXT NOT NULL,
managed_by TEXT,
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
UNIQUE (workspace_name, peer_name, path)
);
-- dream_definitions: materialized dreams
CREATE TABLE dream_definitions (
id TEXT PRIMARY KEY,
workspace_name TEXT NOT NULL,
name TEXT NOT NULL,
peer_name TEXT,
prompt TEXT NOT NULL,
sources JSONB NOT NULL,
output_type TEXT NOT NULL,
output_path TEXT,
trigger_type TEXT NOT NULL,
cron_expression TEXT,
debounce_seconds INTEGER DEFAULT 300,
enabled BOOLEAN DEFAULT true,
last_run_at TIMESTAMPTZ,
next_run_at TIMESTAMPTZ,
run_count INTEGER DEFAULT 0,
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT now(),
UNIQUE (workspace_name, name)
);7. Implementation Phases
Phase 1: Custom Instructions + Peer Enhancements
- Add
extraction_contextto peers (may be handled by parallel custom instructions work) - Add
contextto sessions and messages - Deriver reads and incorporates context hierarchy
- Validates: does context-aware extraction meaningfully improve quality?
Phase 2: Sub-peers
- Implement
peer_membershipstable and CRUD endpoints - Aggregation logic in representation, conclusion queries, and search
- Cycle detection at insertion time
- Configurable aggregation depth
- Validates: does sub-peer composition cover the target modeling scenarios?
Phase 3: Peer Files
- Implement
peer_filestable and CRUD endpoints - Migrate peer cards and summaries from internal_metadata to files
- File chunking and embedding for search
- Dialectic
search_filestool - Validates: is the file interface useful for developers and for system-managed outputs?
Phase 4: Invalidation & Restructuring
- Staleness propagation on conclusion DAG
- Dreamer
reconcile_staletask type - Peer rename, merge, split operations
- Validates: can the system recover coherent state after restructuring?
Phase 5: Materialized Dreams
dream_definitionstable and CRUD API- Dreamer task types:
materialize_conclusions,materialize_file - Trigger system: cron scheduler, on_change hooks with debouncing, on_demand
- Built-in identity segmentation dream
- Validates: can developers define useful custom reasoning tasks?
8. Open Questions
-
Aggregation depth default. Should the default be 1 (immediate children) or 0 (self only, opt-in aggregation)? Default 1 is more useful but could surprise developers with unexpected data inclusion.
-
Collection model interaction. Collections use
(observer, observed, workspace). When querying a parent peer’s representation, should we query all collections where the observed is any sub-peer? Or create aggregate collections? Query-time fan-out is simpler but potentially slower. -
Dream cost control. Developer-defined dreams run LLM calls. Per-workspace quotas? Max runs per day?
-
Staleness during active ingestion. New conclusions could be derived from stale premises while reconciliation is pending. Should the deriver check for stale premises and skip them?
-
File embedding and search. Should peer files be automatically embedded for semantic search, or opt-in? Auto-embedding is convenient but adds cost.
-
Facet stability. Auto-segmentation could produce different facet names on each run. Should the dreamer reference previous facets to ensure consistency?
-
Multi-parent knowledge exposure. When a peer belongs to multiple parents, its knowledge aggregates to all parents. This is usually desired but could leak context across boundaries. Developers need to understand this implication.
-
Context field length limits. How long can custom instructions be? Must fit in the deriver’s prompt budget alongside actual content.
9. Success Criteria
- A developer can model people, teams, brands, codebases, documents, and multi-agent systems using composable peers with sub-peers (see Appendix A).
- Querying a parent peer aggregates knowledge from sub-peers. Querying a sub-peer provides isolation. Both work without special configuration.
- A developer can ingest external data via sessions with context, and the deriver produces meaningfully different extractions based on that context.
- Peer cards, dream outputs, and reference knowledge are stored as inspectable, editable markdown files.
- A developer can define materialized dreams with cron, on_change, or on_demand triggers.
- Peers can be renamed, merged, and split with the system recovering coherent state.
- Existing API consumers experience no breaking changes.
Appendix A: Modeling Scenarios
A.1 People
Alice uses an AI companion across DMs and group chats. The application needs DM knowledge isolated from group chat knowledge, but wants the full picture when queried at the top level.
alice/ ← query here: full picture of alice
├── alice-fae-dm/ ← query here: only DM knowledge
│ └── sessions, conclusions
├── alice-groupchat-standup/ ← query here: only group chat knowledge
│ └── sessions, conclusions
├── alice-gmail/ ← query here: only gmail knowledge
│ └── sessions (ingestion), conclusions
├── sessions ← alice's own direct sessions
├── conclusions ← top-level, cross-cutting knowledge
└── files/
├── card.md ← peer card (system-managed)
└── profile.md ← materialized dream output
- DM agent queries
alice→ sees everything - Group chat agent queries
alice-groupchat-standup→ only group context, isolated from DMs - Personalization system writes to
alice-gmailvia ingestion sessions with context - Dreamer consolidates across all sub-peers into top-level conclusions on
alice
A.2 Teams
Engineering team of 5. Want collective knowledge + access to individual knowledge.
engineering-team/
├── alice/ ← same alice peer from above (many-to-many membership)
├── bob/
├── charlie/
├── sessions ← team-level sessions (standups, planning)
├── conclusions ← team-level decisions ("we chose Rust for the rewrite")
└── files/
└── team-norms.md
- Query
engineering-team→ team conclusions + alice’s + bob’s + charlie’s knowledge - Query
alicedirectly → alice’s knowledge only (does NOT include team-level conclusions — aggregation flows up, not down) - Team standup sessions belong to
engineering-teampeer, deriver attributes conclusions there
Design decision: aggregation depth. When querying engineering-team, do we recurse into alice’s sub-peers (alice-dm, alice-gmail, etc.)? With depth=1, we see alice’s top-level knowledge but not her sub-peer details. With depth=all, we see everything. Default depth=1 is likely correct — the team sees what alice has made available at her top level, not her private sub-contexts.
A.3 A Brand
Modeling a company’s brand identity — voice, values, audience, competitive landscape.
acme-brand/
├── acme-voice/ ← tone, style, do's and don'ts
│ └── sessions (ingestion of style guides), conclusions
├── acme-audience/ ← target demographics, research
│ └── sessions, conclusions
├── acme-competitors/ ← competitive intelligence
│ └── sessions, conclusions
├── conclusions ← top-level brand facts
└── files/
├── card.md ← brand summary
├── style-guide.md ← reference doc
└── dreams/
└── competitive-brief.md ← materialized dream
- Brand assistant queries
acme-brand→ full brand knowledge - Content writer queries
acme-voice→ just tone/style - Custom instructions on
acme-brand: “This peer represents a brand. Focus on voice, positioning, audience fit, and competitive differentiation.” - Materialized dream: “Weekly competitive brief from acme-competitors conclusions”
A.4 A Codebase
AI coding assistant that understands a project.
my-project/
├── my-project-architecture/ ← design decisions
│ └── sessions (ingestion of design docs), conclusions
├── my-project-api/ ← API contracts, endpoints
│ └── sessions (ingestion of specs), conclusions
├── my-project-bugs/ ← known issues, past incidents
│ └── sessions (issue tracker data), conclusions
├── my-project-conventions/ ← coding standards
│ └── sessions, conclusions
├── conclusions ← cross-cutting project knowledge
└── files/
├── card.md
├── CLAUDE.md ← agent instructions (reference file)
└── dreams/
└── architecture-overview.md
- Coding agent queries
my-project→ full project context - Code review agent queries
my-project-conventions→ just patterns - Custom instructions: “This peer represents a software project. Extract: architectural decisions, API contracts, conventions, known issues.”
- Materialized dream: “Maintain architecture overview from design decision conclusions”
A.5 A Document / A Person’s Writings
Modeling a person based on their published writing. Two approaches:
Option A — sub-peer per document:
author-jane/
├── jane-paper-on-llms/
├── jane-blog-post-march/
├── jane-book-chapter-3/
├── conclusions ← cross-document knowledge
└── files/
└── dreams/
└── writing-style-analysis.md
Each document is a sub-peer with its own conclusions. Granular isolation per document. Works well for a small number of important documents.
Option B — sub-peer for the category (recommended for most cases):
jane/
├── jane-writings/
│ └── sessions (one per document), conclusions
├── jane-conversations/
│ └── sessions, conclusions
├── conclusions
Fewer peers. Session filtering within jane-writings provides per-document scoping. Better for prolific authors.
Principle: sub-peers for meaningfully different contexts or identity facets. Sessions for different instances within a context. Don’t create a sub-peer where a session would suffice.
A.6 An Autonomous Agent
An agent that acts independently, calls tools, learns from its own experience.
research-agent/
├── research-agent-web/ ← knowledge from web browsing
│ └── sessions (per research task), conclusions
├── research-agent-tools/ ← tool usage patterns
│ └── sessions, conclusions
├── research-agent-tasks/ ← past task outcomes
│ └── sessions (one per task), conclusions
├── sessions ← direct conversations with humans
├── conclusions ← agent self-knowledge
└── files/
├── card.md ← agent capabilities
├── skills.md ← reference: known skills
└── dreams/
└── tool-effectiveness.md ← materialized: which tools work for what
- Agent queries itself → full self-knowledge
- Supervisor queries
research-agent-tasks→ task history only - Custom instructions: “This peer represents an autonomous research agent. Extract: task outcomes, tool effectiveness, failure modes, learned strategies.”
- Tool calls are ingested as messages with context: “Agent called search API, returned 5 results about X”
A.7 Multi-Agent Orchestration
Coordinator agent with sub-agents working on a shared project.
project-alpha/ ← the project
├── researcher-for-alpha/ ← research agent's work on THIS project
│ └── sessions (research tasks), conclusions
├── writer-for-alpha/ ← writer's work on THIS project
│ └── sessions (writing tasks), conclusions
├── reviewer-for-alpha/ ← reviewer's work on THIS project
│ └── sessions (reviews), conclusions
├── sessions ← project-level (planning, handoffs)
├── conclusions ← project-level decisions
└── files/
├── brief.md ← project brief (reference)
└── dreams/
└── progress-report.md ← materialized: current status
- Coordinator queries
project-alpha→ sees all agents’ work + project context - Researcher queries its own sub-peer → only its own research
- Materialized dream: “Progress report across all sub-agents”
Important pattern: Agents that work across multiple projects need project-scoped sub-peers (researcher-for-alpha, researcher-for-beta), not a single researcher peer added to multiple projects. Otherwise the researcher’s project-alpha knowledge would leak to project-beta through parent aggregation.
If the researcher also needs persistent cross-project self-knowledge (tool preferences, learned strategies), it has its own independent peer:
researcher/ ← the agent's own identity
├── sessions, conclusions ← cross-project self-knowledge
└── files/
└── skills.md
project-alpha/
├── researcher-for-alpha/ ← project-scoped work (separate peer)
project-beta/
├── researcher-for-beta/ ← project-scoped work (separate peer)
The researcher agent queries both its own peer and its project-scoped sub-peer when working on a task. The project owner only sees the project-scoped sub-peer.