Files
deepseek-harness/packages/subagent/subagent-fork
Tianyi Cui ecb8aa5b8e Add a gated Known Limitations and Deferred Work section to every package README
Every packages/*/* README now carries a canonical '## Known Limitations and
Deferred Work' section: condensed, evidence-backed bullets for consumer-visible
gaps (unimplemented features, platform caveats, MVP cuts) and consciously
postponed work (TODO/FIXME/XXX markers, RFC deferrals still open). The ten
pre-existing ad-hoc variants ('What is NOT here (TODO)', 'Deferred',
'Limitations (MVP)', 'Known limitations (tracked TODOs)', ...) are normalized
into the canonical heading.

A new doc-sync gate, scripts/verify-readme-limitations.ts, enforces the shape:
exactly one limitations-like heading per package README, byte-equal to the
canonical h2, with at least one bullet; near-miss headings fail so variants
cannot creep back. Packages with genuinely nothing to declare (dsh-brand,
dsh-timeout, dsh-subagent-mock, dsh-app-boot) are whitelisted in the script and
must NOT carry the section; whitelist entries are validated against the scanned
package set so a rename fails loud.

Wired into the doc-sync chain (package.json) and the run-gates doc-sync leaf
set; the standing rule lands in packages/AGENTS.md and the adding-a-package
cookbook; decision record in
docs/rfc/implemented/process/2026-07-10-readme-known-limitations-gate.md
(RFC index regenerated).

Also fixes two stale '(deferred)' markers claiming dsh-compact-basic is
unimplemented (the dsh-compact seam README's package table and the seam's
module doc comment).
2026-07-12 01:46:34 +08:00
..

@deepseek-ai/dsh-subagent-fork

The in-process fork subagent backend: a SubagentProvider that runs each child as a child Agent seeded with a prefix of the parent's session log — so the child inherits the parent's conversation context instead of starting fresh. Shares the run driver (startInProcessRun) with dsh-subagent-spawn; the only difference is the seed. The shared run.started boundary resolves only after the seeded child is published, so subagent/start observers see a live registry entry.

The seed boundary (the crux)

At the moment a subagent tool's execute runs, the parent's CURRENT turn is open and unbalanced: the log holds the assistant/message carrying this spawn's tool-call and the dangling tool/call with no tool/result yet. Seeding that raw prefix would give the child an open turn that the session constructor and the dev-mode invariants replay reject.

So the fork seeds only the balanced completed-turn prefix — the parent's log up to and including its last turn/end, excluding the in-flight turn entirely (completedTurnPrefix). Because the live log keeps seq === index, the slice is contiguous-from-0 and a valid seed. A parent on its very first (not-yet-complete) turn forks an empty seed — i.e. effectively a fresh child.

The seam this rides on: CreateAgentOptions.seed (added on dsh-agent, threaded through AgentLoop.createAgentctx.sessions.prepare({ seed })), the same primitive resume uses.

Capabilities

{ outputSchema: true, depthLimit: true, toolFilter: true, persona: true } — identical to spawn because the shared driver owns depth, model, persona, tool-filter, and structured-output behavior.

Config

Key Meaning
providerName Registry name on ctx.subagents (default fork).

See dsh-subagent-spawn for the run lifecycle, model inheritance, and depth tracking — all shared.

Known Limitations and Deferred Work

  • Tool-scoping (toolFilter) is not supported — declared false, so the service rejects a request needing it before start runs.
  • Runs expose no sendMessage/resume — the optional runtime capabilities are absent on in-process runs; the consumer collects synchronously.
  • The seed is a one-time snapshot — the child sees the parent's completed turns as of the fork and nothing the parent logs afterwards; there is no live context sharing.