The public kill result used the awkward phrase already-terminal. Rename it to already-finished and keep the model-facing response aligned; not-alive would be inaccurate because a force-failed registry record can still correspond to orphaned producer work.
Task kinds were open strings even though producer namespaces are an extension point. Add the merge-extensible TaskKindMap and derived TaskKind, cover consumer declarations in task and bundle tests, and retain the runtime non-empty check for untyped callers.
With exactOptionalPropertyTypes, owner?: Agent | undefined allowed an explicit undefined value that no caller needs. Tighten the property to owner?: Agent so unowned work is expressed by omitting it.
Record the requested task-service/backend split as a follow-up, using a systemd-backed runtime as a concrete candidate without guessing its durability and ownership contract in this PR. Regenerate the type and Cordis catalogs so public docs match the declarations.
Refresh the background-task branch onto the latest repository baseline before applying review feedback. This preserves merge ancestry, incorporates the current CI and package-structure changes, and ensures the review fixes are validated against the code that will actually receive the PR.
The background-task change repeated its lifecycle design across implemented RFCs, package READMEs, JSDoc, test commentary, and model-visible schemas. That repetition obscured the contracts that maintainers must preserve and added avoidable prompt tokens.
Rewrite the implemented RFCs around the current design, keep authorization, exact-owner cleanup, wait/abort ordering, producer quiescence, and teardown-failure guarantees at their owning surfaces, and remove peer surveys, review history, control-flow narration, and emphatic restatement.
Shorten the task and subagent schema wording, synchronize the bilingual tool cookbook, and regenerate the config, service, RFC, tool, and replay snapshot derivatives. Runtime behavior is unchanged; test edits update prose-only assertions and descriptions.
The acp built-bin smoke killed its child and immediately rm'd the temp
consumer dir; POSIX tolerates unlinking a live process's cwd, Windows fails
EBUSY while the child still holds its cwd and session-log handles (the CI
windows job's only red step). Await the child's exit after SIGKILL and give
both smokes' rm a brief retry for the OS handle-release lag.
Repair cross-group README links whose targets changed groups
(ui/jsonrpc, ui/app-boot -> examples; examples/* -> ui seams),
re-record the bilingual-pair consistency hashes for the docs the
rename touched on both language sides, and condense the AGENTS.md and
packages/README.md group entries. The packages/README ceiling rises
710 -> 760 for the mandated new examples/ hierarchy row (5% headroom).
The @deepseek-ai/dsh-* wildcard maps each package name to its group's
src; the new packages/examples/ group needs its own glob, or the four
moved packages fall back to unbuilt lib/ and vitest cannot resolve them.
Also update the moved specs' plugin export-name assertions (acp-agent ->
acp-demo, stdio-agent -> stdio-demo, agent-core -> agent-spine-demo).
Add the packages/examples/ group README, drop the moved packages from the
core/ and ui/ group READMEs, and add the examples/ row to the packages
hierarchy table and the repo-layout in AGENTS.md.
Move the agent-spine bundle and the stdio/ACP/JSON-RPC app packages out of
core/ and ui/ into a new packages/examples/ group, renamed with a -demo
suffix so the npm name marks them as non-product surface:
core/agent-core -> examples/agent-spine-demo (dsh-agent-spine-demo)
ui/stdio-agent -> examples/stdio-demo (dsh-stdio-demo)
ui/acp-agent -> examples/acp-demo (dsh-acp-demo)
ui/jsonrpc-agent -> examples/jsonrpc-demo (dsh-jsonrpc-demo)
Update every code/config/test reference and reference-only doc mentions, and
regenerate module-graph, config-catalog, and doc-graphs. The jsonrpc bin
(dsh-jsonrpc-agent) and single-file exe (dsh-jsonrpc-agent-pkg) keep their
names; the SDK runtime-startup surface is reconciled separately.
The web-editor conflict resolution renamed the cordis snapshot keys to
rc.7 but left the mcp-client importer pointing at the deleted
cordis@4.0.0-rc.6(...rc.4) key, so every CI lane failed at
'pnpm install --frozen-lockfile' with ERR_PNPM_LOCKFILE_MISSING_DEPENDENCY.
Align the mcp-client cordis range with the repo-wide ^4.0.0-rc.7 sweep
from master and re-resolve the lockfile with pnpm.
Origin/master advanced after the reviewed fixes were first pushed, leaving PR #219 conflicted. Merge the new vendor Cordis/loader update into the PR branch rather than rewriting pushed history, so the task fixes remain based on the exact current landing target.
Preserve the upstream package graph, lockfile, app-boot, and built-bin adjustments as landed on master; resolve only genuine overlaps with the task fixes and regenerate derived artifacts where required.
# Conflicts:
# packages/subagent/tool-subagent/package.json
The PR branch advanced after the local blocker fixes with a merge of current origin/master. Merge that moving parent into this child fix branch instead of rewriting either pushed lineage, so the fixes are validated against the exact PR head and master state that would land.
The only conflicts were an already-paired adding-a-tool translation and nondeterministic approval UUIDs in replay snapshots. Keep the parent versions because the English source and replay behavior are unchanged, avoiding child-only documentation and generated-artifact churn while preserving the parent semantic-gate updates.
A background spawn failure currently resembles a signal-less kill, while a sandbox-runner failure resembles a completed wrapper exit. The generic task adapter cannot mark both as failed without a distinct infrastructure-failure fact on BashProcess. Mapping the existing states differently would also risk treating ordinary nonzero command exits as infrastructure failures.
Keep the current truthful model-visible diagnostics and record a scoped TODO at processOutcome. The eventual fix must widen the BashProcess seam first, then map spawn and runner failures to TaskOutcome failed while preserving completed for real command exits.
TaskService contained synchronous listener throws but discarded returned promises. An async TaskDoneListener could therefore reject as an unhandled process rejection even though the API promises per-listener containment.
Allow listeners to return PromiseLike<void> and attach a rejection handler to each result without awaiting it. This logs asynchronous failures independently while preserving the observation-only contract: later listeners, task waiters, and teardown are not delayed. Add a regression test and synchronize the public docs and generated API declaration.
Task records previously retained only ownerSession. If an old agent scope unwound after another agent reused the same agent and session ids, cleanup selected both records and could cancel replacement work. The completion surface also re-resolved the session at settlement, which could inject an old task notice into the replacement agent.
Retain the exact Agent instance for lifecycle work, select owner cleanup by object identity, and pass that exact owner to completion listeners. Keep read, list, kill, and wait authorization session-based as the runtime RFC intends. Add regressions for cleanup and notice routing under id reuse, then update the public docs and generated API catalogs.
Bring PR #219 onto current master before re-evaluating review findings so fixes are tested against the code that would actually land.
Resolve generated catalogs by regeneration, preserve the new ACP tool-schema sidecar format while refreshing affected snapshots keylessly, and update the newly paired Chinese adding-a-tool document to match the background-task guidance. This keeps generated and bilingual artifacts authoritative instead of choosing one conflict side blindly.