Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/FLOWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,9 @@ sequenceDiagram
```

当前本地 agent tools 包括文件系统、命令执行、chat settings、subagent orchestration 等能力。
Subagent 会话以 `sessionKind='subagent'` 存储,父会话通过 tape merge/discard 处理子会话结果。
Subagent 会话以 `sessionKind='subagent'` 存储;父会话写入同时冻结 child Tape incarnation 与 head 的
Tape link,并通过显式 linked Tape view 回查子会话内容,不复制 child entries。reset/rebuild 后的 child
必须重新 link,不能用复用的 entry ID 冒充旧快照。
MCP/Skill/ToolPresenter 继续拥有资源和执行策略;LoopEngine 只依赖窄 port,不 import presenter。

## 4. 会话恢复、分页和搜索
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ Do not rename, merge or recreate these stores in this goal:

- user/final/tool facts remain monotonic and idempotent by provenance;
- edit/delete are replacement/retraction facts, not in-place Tape mutation;
- effective view, bootstrap/backfill, anchors, handoff/fork/merge/discard remain compatible;
- effective view, bootstrap/backfill, anchors, handoff, true-fork merge/discard, and production
subagent Tape links remain compatible;
- one ViewManifest write is synchronously attempted before each actual provider request at the current point;
write failure logs and remains fail-open, so a request may legally have no manifest;
- trace/replay default remains metadata-only; raw payload inclusion stays opt-in;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ interface AgentSharedDataPorts {
- `AgentTranscriptReadPort` 服务 title/history/export/message lookup;
- `AgentTranscriptMutationPort` 服务 clear/edit/delete/fork/retry preparation,retry preparation 继续执行原
summary 与 Memory invalidation,再把合法 input 交给当前 backend;
- `AgentTapePort` 服务 query/handoff/replay 与 subagent merge/discard。
- `AgentTapePort` 服务 query/handoff/replay、显式 linked Tape view 与 production subagent link
finalization。

当前这些 port 由 `AgentRuntimePresenter` 作为过渡 adapter 实现,但 direct ACP 的网络 prompt、pending、
permission、generation 和 ACP control 不通过该 presenter 执行。后续 ownership slice 可以替换 adapter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
> ASLR-080 added a pure-read causal observation slice in the existing Tape service. It joins only persisted
> facts and reports the renderer event-history gap explicitly. ASLR-081 proved the reader does not mutate Tape,
> projections, replay state or Memory ingestion; the event-history gap remains explicit and unresolved.
> Subagent Tape lineage now separates true fork merge from production subagent finalization. True fork deltas
> and their receipt commit atomically; production children remain independent Tapes linked by a frozen-head
> `subagent/tape_linked` event and exposed only through an explicit, authorized, read-only View scope.

## 1. 模块目的

Expand Down Expand Up @@ -107,6 +110,33 @@ error、记录 warning 并返回 `null`,保持请求 fail-open。
- message projection 与 Tape 无法单事务时,保持当前 commit/recovery 顺序并测试 crash window;
- Memory extraction 使用 effective Tape lineage,不从临时 mutable blocks 猜测最终事实。

### True fork 与 production subagent lineage

- true fork 在创建时记录精确 parent head,在 merge 开始时冻结 fork head;只复制 cutoff 内的 semantic
delta,排除 `session/start` 与 `fork/start`;
- copied delta 与 parent `fork/merge` receipt 在同一 SQLite transaction 中 append;失败不留下部分 delta,
已提交 retry 复用并校验既有 receipt;
- production subagent 是 durable child session/Tape,其 child entries 不进入 parent effective view。
结算统一调用 typed `linkSubagentTape()`,以 `completed | error | cancelled` outcome append
idempotent `subagent/tape_linked`;
- link receipt 冻结 child head/count,link event 同时冻结 child Tape incarnation identity。缺失
capability 或 append 失败不得把任务标记为 Tape finalized;
- legacy external `fork/merge` 可在 direct-child ownership 成立时作为 completed link 读取;legacy
`fork/discard` 只保留 audit 语义。true fork receipt 不会被误判为 external child link。

### Cross-Tape recall

- `AgentTapeViewScope` 只允许 `current | linked_subagents | current_and_linked`,默认仍是 `current`;
- linked source 每次读取都以 `new_sessions` 的 persisted direct-child relationship 授权,并同时校验
link 的 Tape incarnation identity 与 frozen head;不递归 grandchildren,不接受任意 session id;
- search result 携带 source `sessionId` 并在所有 source 合并后应用一个 global limit;context 的
`sourceSessionId` 每次只展开一个 Tape,窗口不跨 source;
- linked read 不触发 bootstrap、backfill、projection/FTS repair、Memory ingestion 或 event publish;已
finalize 但被单独删除或 reset/rebuild 的 child 明确返回 unavailable,直到新 incarnation 被重新
link;
- model surface 仍只有 `tape_search` 与 `tape_context`,没有第三个 tool,也不会把 linked child 自动注入
provider context。

## 7. ViewManifest 与 trace

ViewManifest 记录 context 的构成、policy/version、source entry references、summary/reconstruction 等可审计
Expand Down
34 changes: 29 additions & 5 deletions docs/architecture/deepchat-tape-baseline/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ Status: current implementation baseline. Retained Tape implementation specs are
[deepchat-tape-replay-contract](../deepchat-tape-replay-contract/spec.md),
[deepchat-tape-view-assembler](../deepchat-tape-view-assembler/spec.md),
[deepchat-tape-view-policy](../deepchat-tape-view-policy/spec.md),
[deepchat-tape-policy-provenance](../deepchat-tape-policy-provenance/spec.md), and
[deepchat-tape-policy-selector](../deepchat-tape-policy-selector/spec.md).
[deepchat-tape-policy-provenance](../deepchat-tape-policy-provenance/spec.md),
[deepchat-tape-policy-selector](../deepchat-tape-policy-selector/spec.md), and
[subagent-tape-lineage](../subagent-tape-lineage/spec.md).

This document keeps the Tape vision aligned with the current DeepChat codebase. The implementation
path is:
Expand Down Expand Up @@ -37,7 +38,8 @@ DeepChat already has the main Tape primitives.
| View policy | `tapeViewPolicy.ts` | Registry and selector boundary; `legacy_context_v1` delegates to the current selector. |
| Context selection | `contextBuilder.ts` | Legacy token-budget selector used by `legacy_context_v1`. |
| Request trace | `deepchat_message_traces` | Stores redacted provider request previews for the trace dialog. |
| Model recall tools | `agentTapeTools.ts` | Exposes the atomic `tape_search` / `tape_context` pair only when both runtime ports are available for a persisted DeepChat session. |
| Tape lineage | `DeepChatTapeService` + `new_sessions` | Keeps true forks as copy-on-merge branches and production subagents as independently readable, frozen-head Tape links. |
| Model recall tools | `agentTapeTools.ts` | Exposes the atomic `tape_search` / `tape_context` pair only when both runtime ports are available for a persisted DeepChat session; linked-subagent recall is an explicit scope on the same pair. |
| Diagnostic/runtime APIs | `DeepChatTapeService` + `SessionProjectionCoordinator` | Retains info, anchor listing, and handoff below the model-tool boundary; these capabilities are not user-configurable Agent tools. |

The first implementation step uses this baseline as the single runtime path. `DeepChatTapeService`
Expand All @@ -60,11 +62,14 @@ docs/architecture/deepchat-tape-policy-provenance/
└── spec.md
docs/architecture/deepchat-tape-policy-selector/
└── spec.md
docs/architecture/subagent-tape-lineage/
└── spec.md
```

The retained scopes are `Existing TapeService + ViewManifest shadow mode`, replay/export
contracts, `TapeViewAssembler` as the production context assembly entry, and `TapeViewPolicy` as
the policy replacement boundary, `ViewManifest` policy provenance, and policy selector registry.
the policy replacement boundary, `ViewManifest` policy provenance, policy selector registry, and
the distinction between true fork merge and production subagent Tape links.

## Scope Boundary

Expand All @@ -86,7 +91,8 @@ the policy replacement boundary, `ViewManifest` policy provenance, and policy se
### Deferred scope for the first increment

- Creating a separate TapeStore abstraction.
- Memory graph retrieval, embedding-backed topic clustering, and cross-session recall.
- Memory graph retrieval, embedding-backed topic clustering, and unrestricted or recursive
cross-session recall. Explicit recall of finalized direct-subagent Tape links is implemented.
- Live LLM replay in CI.
- Full eval pipeline and training exports.

Expand All @@ -99,6 +105,24 @@ the policy replacement boundary, `ViewManifest` policy provenance, and policy se
manifest.
5. Keep old sessions compatible through existing lazy backfill and bootstrap anchors.
6. Treat `ViewManifest` as an explanation and regression artifact until parity is proven.
7. Treat persisted session ownership as the authorization source for linked Tape reads. Link events
freeze readable child heads but never copy child entries into the parent effective view.

## Subagent Tape Lineage

Production subagents own durable, independent Tapes. Finalization appends one idempotent
`subagent/tape_linked` event to the parent with a closed lifecycle outcome and frozen child head;
missing capability or failed persistence leaves finalization retryable. The parent can explicitly
search finalized direct children through `linked_subagents` or `current_and_linked`, and can expand
context within one authorized source Tape by `sourceSessionId`. These reads are bounded by the link
head and the linked child Tape incarnation; clearing and rebuilding a child cannot reuse entry IDs
to impersonate the snapshot. Reads do not bootstrap, backfill, repair projections, or mutate Memory
state.

True forks retain different semantics: their selected delta and `fork/merge` receipt append to the
parent in one SQLite transaction, retries reuse the committed receipt, and branch-local control
anchors are excluded. Legacy external `fork/merge` records remain readable as child links;
`fork/discard` remains audit-only. No database schema migration or third model tool was added.

## Target Flow

Expand Down
2 changes: 1 addition & 1 deletion docs/architecture/retire-agent-session-presenter/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ No object may re-export all four capability groups.
| --- | --- |
| create, detached create, subagent create, draft ensure, fork, delete | Lifecycle |
| send, steer, pending input, message mutation, compaction, cancel, interaction | Turn |
| transfer, runtime settings, ACP config/commands, subagent Tape merge/discard | AgentAssignment |
| transfer, runtime settings, ACP config/commands, subagent Tape link | AgentAssignment |
| session/message/Tape reads, window activation, rename/pin, title/status events | Projection |
| permission cleanup | existing `SessionPermissionPort` |

Expand Down
6 changes: 3 additions & 3 deletions docs/architecture/session-application-coordinators/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ Owns executable assignment and runtime-setting policy:
- transfer impact, batch move/delete, and single-session transfer;
- model, project, permission, generation settings, disabled tools, and subagent-enabled settings;
- ACP config options and commands;
- subagent Tape merge/discard.
- subagent Tape link finalization.

Session deletion remains a lifecycle transaction. Assignment may call a required narrow lifecycle
deletion port, but the composition graph must not use optional setters or circular construction.
Expand Down Expand Up @@ -253,8 +253,8 @@ defined as `Pick<IAgentSessionPresenter, ...>` and must not be grouped under a r
- Project updates retain their current non-transactional order; no rollback is introduced.
- ACP model lock, workdir requirement, permission modes, generation settings, disabled tools, and
config/command behavior remain unchanged.
- Subagent parent/slot/agent validation, ACP forced runtime settings, and Tape merge/discard parent
checks remain unchanged.
- Subagent parent/slot/agent validation, ACP forced runtime settings, and Tape link parent-child
checks remain explicit at finalization.

### Projection

Expand Down
3 changes: 2 additions & 1 deletion docs/architecture/session-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ ACP-provider source 只清 compatibility binding,不被误判成 direct ACP。
## Subagent、remote 与 cron

- Subagent 与普通 session 共享 app/message schema,用 `sessionKind`、`parentSessionId`、`subagentMeta`
区分;child backend 仍由 manager 选择,父 session 通过 Tape merge/discard 接收结果。
区分;child backend 仍由 manager 选择。子任务结算时父 session 记录 frozen-head Tape link;显式
cross-Tape View 只读 direct child,child entries 不复制进父 effective view。
- Remote 通过四个 consumer-owned session ports 调用 coordinator;active-generation lookup/cancel 仍使用
`AgentManagerGenerationPort`,不扫描 presenter runtime maps。
- Cron 的 composition-owned starter 通过 Lifecycle 创建 detached app session、通过 Turn send/cancel;
Expand Down
8 changes: 4 additions & 4 deletions docs/architecture/subagent-run-guardrails/spec.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Subagent Run Guardrails - Spec

> Status: **implemented; final validation pending**
> Status: **implemented and validated**

## Problem

Expand Down Expand Up @@ -29,9 +29,9 @@ inconsistent.
- Foreground and background runs enforce the same deadline.
- `list`, `info`, `log`, `wait`, and `kill` keep their existing meanings and run ownership checks.
- Serialized run data includes the configured timeout, absolute deadline, and cancellation reason.
- Manual cancellation, recursion prevention, and completed/error tape merge/discard behavior stay
compatible.
- A cancelled child tape is not discarded until the child cancellation request settles; the run
- Manual cancellation and recursion prevention stay compatible. Completed, errored, and cancelled
children are finalized through a frozen-head Tape link.
- A cancelled child Tape is not linked until the child cancellation request settles; the run
deadline itself still resolves without waiting for a blocked cancellation request.
- Focused fake-timer, capacity, serialization, and handoff tests pass.

Expand Down
110 changes: 110 additions & 0 deletions docs/architecture/subagent-tape-lineage/plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Subagent Tape Lineage - Implementation Plan

## Phase 1: Specify the boundary

- Record the distinction between true fork merge and durable subagent link.
- Freeze the event, outcome, authorization, head-cutoff, compatibility, and read-only view
contracts before changing production code.
- Keep the current session relationship as the topology and authorization source of truth.

## Phase 2: Harden true fork merge

- Persist the exact parent head in `fork/start`.
- Freeze the fork head when merge begins and select only entries at or below it.
- Exclude `session/start` and `fork/start` from copied delta entries.
- Add a narrow Tape-store transaction operation so copied delta and `fork/merge` receipt commit or
roll back together.
- Use stable merge provenance to return an existing receipt on retry.
- Reject missing, discarded, or malformed fork starts before creating a merge receipt, while
preserving retries of an already committed receipt after cleanup.
- Cover valid empty forks, missing/discarded forks, injected append failure, retry, and concurrent
tail append boundaries with native SQLite tests.

## Phase 3: Model production subagents as links

- Add typed `SubagentTapeLinkInput`, `SubagentTapeLinkOutcome`, and `SubagentTapeLinkReceipt`
contracts at the shared runtime boundary.
- Replace `mergeSubagentTape` and `discardSubagentTape` ports with one `linkSubagentTape` port across
DeepChat, direct ACP, session assignment, presenter, and tool runtime adapters.
- Append `subagent/tape_linked` with stable task provenance, a frozen child head/count, and a
cryptographic identity of the child Tape incarnation.
- Update orchestration finalization so completed, error, and cancelled tasks all link after child
settlement, while absent/failed capability leaves the task retryable. Polling retries a terminal
task even while sibling tasks remain active, without blocking on an in-flight link.
- Reconcile terminal runtime status observed before handoff settlement as soon as the task enters
its started state.
- Preserve legacy event reads without producing new legacy external fork records.

## Phase 4: Add authorized linked Tape views

- Introduce `AgentTapeViewScope` and a resolver that returns the current source and/or finalized
direct-child sources with immutable cutoffs.
- Reuse persisted session ownership for authorization and Tape events for finalized snapshots.
- Give newly created Tape bootstraps an opaque incarnation marker; derive a compatible stable
identity for existing unmarked Tapes without rewriting them.
- Validate linked incarnation identities through one batched first-entry query so reset/rebuild
cannot reuse entry IDs to impersonate the frozen snapshot.
- Resolve child ownership in one indexed JSON-set query so linked-source count cannot exhaust the
SQLite bind-variable limit.
- Extend projection/FTS reads to query a bounded authorized source set, enforce per-source cutoffs,
and apply one global result limit.
- Use projection/FTS ranking only for complete exact-head coverage; on partial freshness, fall back
all selected sources together so result scores remain comparable.
- Add source `sessionId` to search results.
- Extend context reads with `sourceSessionId`, reject mixed or unauthorized sources, and keep one
context window within one Tape.
- Return explicit diagnostics for deleted or unavailable linked Tapes without triggering bootstrap,
backfill, or repair writes.
- Build linked context evidence and summaries from the bounded authoritative rows already read at
the frozen head, without consulting a projection at a different freshness boundary.

## Phase 5: Expose cross-Tape recall through existing tools

- Add optional `scope` to `tape_search` and optional `sourceSessionId` to `tape_context`.
- Keep omitted fields compatible with current-session-only recall.
- Carry the types through tool manager, runtime session routes, DeepChat backend, and direct ACP
backend without adding another model tool.
- Add tool-schema, route, ownership, ACP, global-limit, and parent-effective-view non-interference
tests.

## Phase 6: Validate and finalize contracts

- Review the complete branch diff against hidden writes, compatibility, transactionality, edge
cases, performance, authorization, naming, test depth, and future maintenance cost.
- Run focused Tape/orchestrator/tool tests, native SQLite tests, main tests, typecheck, i18n, lint,
format, and format check.
- Update the retained Tape baseline, runtime Tape contract, and this task ledger only for behavior
proven by the implementation and validation.
- Do not run the full build in this slice because it refreshes unrelated provider and ACP registry
artifacts.

## Commit Strategy

1. `docs(tape): specify subagent tape lineage`
2. `fix(tape): make fork merge atomic`
3. `refactor(tape): model subagents as tape links`
4. `feat(tape): add linked tape views`
5. `feat(tools): add cross-tape recall`
6. `docs(tape): finalize subagent tape lineage`

If cumulative review finds an implementation defect not cleanly owned by the final documentation
commit, add `fix(tape): address lineage review findings` without rewriting prior commits.

## Review Gate

Before every commit:

1. Inspect status, full unstaged diff/stat/check, and run the smallest sufficient validation.
2. Review P0 through P3 for hidden side effects, compatibility, boundaries, performance, security,
semantic naming, test gaps, and maintenance cost.
3. Fix every in-scope actionable finding and repeat the review.
4. Stage explicit task paths only; inspect full staged diff/check and repeat the same severity review.
5. Commit only when staged changes contain no unrelated file and no actionable P0-P3 finding.

## Rollback and Compatibility

- The change adds no database schema migration; rollback leaves append-only link events readable as
inert unknown events by older code.
- Current-only tool calls and true fork event readers remain compatible.
- New code keeps a legacy reader for old external `fork/merge` events.
- No child Tape is deleted or copied as part of production subagent finalization.
Loading
Loading