Skip to content

Commit 25a6b31

Browse files
committed
feat(daemon): inherit parent context for sub-agent sessions
1 parent f9193be commit 25a6b31

20 files changed

Lines changed: 1081 additions & 82 deletions

File tree

docs/API.md

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2386,12 +2386,22 @@ for injection into the harness system prompt. Requires `remember` permission
23862386
```json
23872387
{
23882388
"harness": "claude-code",
2389+
"project": "/workspace/repo",
2390+
"agentId": "optional-signet-agent-id",
2391+
"harnessAgentId": "optional-harness-subagent-id",
2392+
"parentSessionKey": "optional-parent-session-key",
23892393
"sessionKey": "session-uuid",
23902394
"runtimePath": "plugin"
23912395
}
23922396
```
23932397

2394-
`harness` is required.
2398+
`harness` is required. `agentId` is the Signet persistence scope. Harness
2399+
native sub-agent identifiers, such as Claude Code's `agent_id`, must be sent as
2400+
`harnessAgentId`; they are lineage hints and are not used for Signet data
2401+
scoping. `parentSessionKey` may be provided when the harness exposes explicit
2402+
lineage. If it is absent, Signet infers parent context where possible from
2403+
harness-native signals such as OpenClaw lineage session keys or recent Claude
2404+
Code parent activity in the same project.
23952405

23962406
**Response** — implementation-defined context object returned by
23972407
`handleSessionStart`.
@@ -2774,6 +2784,69 @@ Both raw keys (`abc123`) and prefixed keys (`session:abc123`) are accepted.
27742784

27752785
Returns `404` if the session key is not found.
27762786

2787+
### GET /api/sessions/:key/transcript
2788+
2789+
Return the canonical cleaned transcript for a session. Results are scoped to
2790+
the authenticated agent; pass `agent_id` only when calling with an authorized
2791+
agent scope.
2792+
2793+
Both raw keys (`abc123`) and prefixed keys (`session:abc123`) are accepted.
2794+
2795+
**Response**
2796+
2797+
```json
2798+
{
2799+
"sessionKey": "session-uuid",
2800+
"agentId": "default",
2801+
"content": "User: ...\nAssistant: ..."
2802+
}
2803+
```
2804+
2805+
Returns `404` if no transcript exists for that session and agent scope.
2806+
2807+
### POST /api/sessions/search
2808+
2809+
Search active or completed session transcripts. This route powers the
2810+
`session_search` MCP tool and is intended for sub-agents that need to inspect
2811+
the parent session without forcing a large token snapshot into every spawn.
2812+
Results are agent-scoped and require `recall` permission.
2813+
2814+
**Request body**
2815+
2816+
```json
2817+
{
2818+
"query": "Juniper trunk ports",
2819+
"sessionKey": "optional-specific-session",
2820+
"currentSessionKey": "agent:nicholai:subagent:abc123",
2821+
"agentId": "nicholai",
2822+
"project": "/workspace/repo",
2823+
"limit": 5
2824+
}
2825+
```
2826+
2827+
`query` is required. `limit` is clamped to `1..20`. If `sessionKey` is absent
2828+
and `currentSessionKey` encodes OpenClaw sub-agent lineage, Signet defaults the
2829+
search to the inferred parent session. Otherwise, Signet searches transcripts
2830+
in the requested agent and project scope while excluding `currentSessionKey`.
2831+
2832+
**Response**
2833+
2834+
```json
2835+
{
2836+
"query": "Juniper trunk ports",
2837+
"hits": [
2838+
{
2839+
"sessionKey": "agent:nicholai:main",
2840+
"project": "/workspace/repo",
2841+
"updatedAt": "2026-03-25T10:05:00.000Z",
2842+
"excerpt": "keep the Juniper EX4300 VLAN audit focused on trunk ports",
2843+
"rank": -1.2
2844+
}
2845+
],
2846+
"count": 1
2847+
}
2848+
```
2849+
27772850
### GET /api/sessions/summaries
27782851

27792852
List temporal summary nodes used for drill-down and `MEMORY.md` synthesis.
@@ -3852,9 +3925,9 @@ MCP Server
38523925
Model Context Protocol endpoint using Streamable HTTP transport (stateless).
38533926
Supports POST (send messages), GET (SSE stream), and DELETE (session teardown).
38543927

3855-
Exposes memory tools: `memory_search`, `memory_store`, `memory_get`,
3856-
`memory_list`, `memory_modify`, `memory_forget`. See `docs/MCP.md` for full
3857-
tool documentation.
3928+
Exposes memory/session tools: `memory_search`, `session_search`,
3929+
`memory_store`, `memory_get`, `memory_list`, `memory_modify`, `memory_forget`.
3930+
See `docs/MCP.md` for full tool documentation.
38583931

38593932
**POST /mcp** — Send MCP JSON-RPC messages. Returns JSON or SSE stream.
38603933

docs/CONFIGURATION.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,29 @@ Checkpoints are triggered by five events: `periodic`, `pre_compaction`,
916916
storage.
917917

918918

919+
### Sub-agents (`subagents`)
920+
921+
Controls deterministic parent-session context inherited by sub-agent sessions
922+
at `session-start`. This uses stored active transcripts and checkpoints; it
923+
does not make an LLM call.
924+
925+
| Field | Default | Range | Description |
926+
|-------|---------|-------|-------------|
927+
| `inheritContext` | `true` | — | Inject a compact parent context block when parent lineage is available |
928+
| `tailChars` | `3000` | 0-20000 | Max transcript tail characters included from the parent session |
929+
930+
```yaml
931+
memory:
932+
pipelineV2:
933+
subagents:
934+
inheritContext: true
935+
tailChars: 3000
936+
```
937+
938+
Set `inheritContext: false` to disable automatic inherited context while
939+
leaving the explicit `session_search` MCP/API surface available.
940+
941+
919942
### Telemetry (`telemetry`)
920943

921944
Anonymous usage telemetry. Only active when `telemetryEnabled: true`.

docs/HARNESSES.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,9 @@ Claude Code also gets native MCP tool access to Signet memory via the
227227
}
228228
```
229229

230-
This gives Claude Code direct access to `memory_search`, `memory_store`,
231-
`memory_get`, `memory_list`, `memory_modify`, and `memory_forget` tools.
230+
This gives Claude Code direct access to `memory_search`, `session_search`,
231+
`memory_store`, `memory_get`, `memory_list`, `memory_modify`, and
232+
`memory_forget` tools.
232233

233234
### Prerequisites
234235

@@ -269,7 +270,7 @@ lineage.
269270
2. On session start, Codex fires `SessionStart` → calls `signet hook session-start -H codex --codex-json` → Signet returns identity + memories as `hookSpecificOutput.additionalContext` with `suppressOutput: true`, injected into the model's context window without printing the hook payload to the user transcript.
270271
3. On every user prompt, Codex fires `UserPromptSubmit` → calls `signet hook user-prompt-submit -H codex --codex-json` → Signet returns per-prompt recalled memories as `hookSpecificOutput.additionalContext` with `suppressOutput: true` so the context is model-visible but not printed into the user transcript. This is blocking — Codex waits for the hook before sending to the model.
271272
4. On session end, Codex fires `Stop` → calls `signet hook session-end -H codex` → Signet extracts memories from the transcript.
272-
5. The MCP server exposes `memory_store`, `memory_search`, and other memory tools that Codex can invoke directly during sessions.
273+
5. The MCP server exposes `memory_store`, `memory_search`, `session_search`, and other tools that Codex can invoke directly during sessions.
273274

274275
Codex `SessionStart` hook timeout defaults to 20 seconds: the Signet CLI
275276
waits up to `SIGNET_SESSION_START_TIMEOUT` (`15000` ms by default) for
@@ -313,6 +314,7 @@ tools (namespaced as `mcp__signet__*`):
313314

314315
- `memory_store` — save a memory
315316
- `memory_search` — hybrid recall (vector + keyword)
317+
- `session_search` — search active or completed session transcripts
316318
- `memory_list` — list recent memories
317319
- `memory_modify` — update existing memory
318320
- `memory_forget` — delete a memory
@@ -738,6 +740,7 @@ Hermes lifecycle.
738740
| Tool | Description |
739741
|------|-------------|
740742
| `memory_search` | Hybrid memory search (keyword + semantic + knowledge graph) |
743+
| `session_search` | Search active or completed session transcripts |
741744
| `memory_store` | Store a fact/preference/decision with auto entity extraction |
742745
| `memory_get` | Retrieve a memory by ID |
743746
| `memory_list` | List memories with optional filters |

docs/HOOKS.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,16 @@ Called when a new agent session begins. Returns memories and context formatted f
7979
{
8080
"harness": "openclaw",
8181
"agentId": "optional-agent-id",
82+
"harnessAgentId": "optional-harness-native-subagent-id",
83+
"parentSessionKey": "optional-parent-session-key",
8284
"context": "optional context string",
8385
"sessionKey": "optional-session-identifier"
8486
}
8587
```
8688

87-
`harness` is required. Everything else is optional.
89+
`harness` is required. Everything else is optional. `agentId` is the Signet
90+
persistence scope. Harness-native sub-agent identifiers should be sent as
91+
`harnessAgentId`; they are used only for parent-session inference.
8892

8993
### Response
9094

docs/MCP.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ When to Use MCP vs Hooks
5151
| Session start/end lifecycle | Hooks |
5252
| Automatic memory extraction after each prompt | Hooks |
5353
| Agent wants to search memories mid-conversation | MCP (`memory_search`) |
54+
| Sub-agent needs to inspect its parent session | MCP (`session_search`) |
5455
| Agent wants to store a specific fact | MCP (`memory_store`) |
5556
| Agent needs to run a command with secrets | MCP (`secret_exec`) |
5657
| Compaction boundary handling | Hooks |
@@ -302,6 +303,40 @@ whose memory IDs were actually recorded for the given session and agent.
302303
are supported for backward compatibility, but the MCP tool is recorded
303304
immediately on the current turn.
304305

306+
### session_search
307+
308+
Search active or completed session transcripts. This is the pull side of
309+
sub-agent context continuity: session-start injects a compact parent context
310+
block when Signet can infer the parent, while `session_search` lets the child
311+
query the parent transcript on demand.
312+
313+
**Parameters:**
314+
315+
| Name | Type | Required | Description |
316+
|------|------|----------|-------------|
317+
| `query` | string | yes | Transcript search query |
318+
| `session_key` | string | no | Specific transcript session key to search |
319+
| `current_session_key` | string | no | Current session key; OpenClaw lineage can resolve this to the parent |
320+
| `agent_id` | string | no | Agent scope (default `default`) |
321+
| `project` | string | no | Optional project path filter |
322+
| `limit` | number | no | Max hits to return (default 10, max 20) |
323+
324+
**Returns:** Object with `query`, `hits`, and `count`. Each hit includes
325+
`sessionKey`, `project`, `updatedAt`, `excerpt`, and `rank`.
326+
327+
**Example:**
328+
329+
```json
330+
{
331+
"query": "trunk ports",
332+
"current_session_key": "agent:nicholai:subagent:abc123",
333+
"agent_id": "nicholai",
334+
"limit": 5
335+
}
336+
```
337+
338+
**Daemon endpoint:** `POST /api/sessions/search`
339+
305340
### agent_peers
306341

307342
List currently active peer sessions for cross-agent coordination.

docs/specs/INDEX.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,7 @@ Legend:
751751
| `marketplace-reviews-cloudflare-staging` | planning | `docs/specs/planning/marketplace-reviews-cloudflare-staging.md` | - | - | |
752752
| `predictor-agent-feedback` | approved | `docs/specs/approved/predictor-agent-feedback.md` | `predictive-memory-scorer` | - | |
753753
| `retroactive-supersession` | planning | `docs/specs/planning/retroactive-supersession.md` | `knowledge-architecture-schema` | - | Informed by MSAM-COMPARISON, RESEARCH-COMPETITIVE-SYSTEMS |
754-
| `sub-agent-context-continuity` | planning | `docs/specs/planning/sub-agent-context-continuity.md` | `session-continuity-protocol`, `multi-agent-support` | - | Parent transcript query + deterministic sub-agent inheritance (issue #315) |
754+
| `sub-agent-context-continuity` | approved | `docs/specs/approved/sub-agent-context-continuity.md` | `session-continuity-protocol`, `multi-agent-support` | - | Parent transcript query + deterministic sub-agent inheritance (issue #315) |
755755
| `ontology-evolution-core` | planning | `docs/specs/planning/ontology-evolution-core.md` | `knowledge-architecture-schema`, `desire-paths-epic` | `ontology-governance-workflow` | Confidence/provenance edges, co-occurrence signals, typed relationships, temporal lineage |
756756
| `ontology-governance-workflow` | planning | `docs/specs/planning/ontology-governance-workflow.md` | `ontology-evolution-core`, `knowledge-architecture-schema` | - | Proposal/review workflow for ontology-impacting schema changes |
757757
| `ssm-foundation-evaluation` | planning | `docs/specs/planning/ssm-foundation-evaluation.md` | `predictive-memory-scorer`, `desire-paths-epic` | `ssm-temporal-backbone` | Benchmark harness and canary gates for SSM adoption |

0 commit comments

Comments
 (0)