Integrate the observed master checkpoint 7ab215e23e5d977aae7eb5d4fb91782d39969dbb without rewriting the earlier published checkpoints. Master adds current-directory events, directory-aware consumers, and retained Git worktrees; its old subagent startup paths overlapped the unified activation implementation.
Resolve directory selection within managed startup after acquiring parent ownership. Preserve the original Session origin while setting each new local child directory, retain persisted directory state on cold resume, and pass a required absolute cwd to external providers. Keep unified local/external ownership, full completion notices, parked-input host completion, SDK wait/error/shutdown behavior, and ACP cancellation semantics. Retain removal of the old in-process driver and continuation managers.
Combine SDK wait with the new directory requests, preserve the new master directory/worktree fixtures, regenerate derived catalogs from the combined sources, and refresh only the four stale prompt/schema sidecars. Preserve every protected historical schema, archived note, catalog-v2 acknowledgement, and recorded predecessor input.
Validation: full build; 59 CI static gates; 855 subagent tests with 100% coverage on changed core/external sources; affected consumer suites including 119 repaired-fixture tests; SDK 11 and headless 16 recorded scenarios; two local headless expected cases; six built nested SDK/ACP cases; lint, strict cast inventory, workspace constraints, and whitespace checks. Native Windows worker diagnostics remain additive and require the next CI run to classify the original crash.
Integrate master 78ae4fc2d4d8ecaebb4b674028f781a358b92cc9 after the four
independent review fixes. Keep this base update separate from those fixes
and from subsequent review changes so the integration is independently
reviewable and the observed-master checkpoint remains preserved.
Retain activation-owned execution, caller-independent local discovery,
and unconditional parent final-answer delivery. Preserve master's preset
scoped scheduling tools and all delegated-child schedule deny rules. Move
the new scheduling regression from the removed driver package into the
surviving subagent package and run it through a real Spawn activation.
Preserve master's removal of runtime invariant plugins, dependencies,
exports, and test mounts. Keep context disposal before fixture directory
cleanup. Combine Python workflow ordering with activation/catalog events
without inventing unsupported source-plane import paths.
Keep all frozen Agent Note archives byte-for-byte identical to master;
do not accept Git's automatic edits to renamed archived notes. Retain
current lifecycle and delivery facts in active documentation, repair its
links, and regenerate catalogs/persistence schemas from merged source.
All 62 master persistence roots remain; only subagent/catalog gains the
PR's external membership extension. Keep master's third-party lock graph
and update only workspace dependency changes.
Validation before this checkpoint: 683 focused tests passed, seven
Windows-only cases skipped; 2,772 archived artifacts verified. Generated
catalog and active-pair checks passed. Fresh artifact build and remaining
build-dependent documentation checks continue before publication.
A content-deduplicated shared file has no visible change record. If its
metadata became unavailable while the harness-home winner changed or vanished,
the reconciler skipped the failed candidate and still published the winner's
replacement or removal. Guidance that remained in the shared file disappeared
from the model's effective instructions. Content-read failures had the same
partial-group behavior even when metadata probing succeeded.
Rollback the probed candidate group whenever any metadata probe is unavailable
or its bounded content read cannot complete. Include candidates without a
visible predecessor and candidates previously removed as duplicates. Reuse
one rollback operation for proposed messages, deferred version updates,
metadata mutations, and retained digest bookkeeping, so a later successful pass
can reconstruct the complete group independent of cache warmth.
A filesystem path can also appear as a project instruction when the Harness
home is the project root. Releasing observed paths on rollback let that later
alias publish the very content withheld by the failed global group. A transient
failure of the first member also left failed and unvisited paths unreserved.
Factor the existing scope-to-file path calculation and reserve every eligible
member's absolute path for the rest of that pass when its group rolls back.
Project aliases therefore cannot bypass group preservation, without additional
filesystem operations. The shared resolver keeps probing and rollback path
calculations identical. Add metadata, content-read, and one-shot first-member
failure regressions for this supported same-file layout and its recovery.
Keep cancellation propagating to the caller. Keep explicit baseline-budget
exclusions outside observation rollback, because their removals are deliberate
policy decisions. No new session fields, baseline identities, polling, retries,
or process-global state are needed. Clarify the metadata/content and hidden
candidate guarantee in the bilingual README.
Add four real-plugin outage/recovery tests for metadata or content failure while
the retained home file is edited or deleted, plus a cold-cache reconciliation
regression. Add an authored headless session scenario with instance-local
provider failure injection: request two keeps baseline A while shared metadata
is unavailable; request three receives the home B replacement and shared A
addition together after recovery. The fixture restores the provider method on
disposal and asserts the real home/shared files before restoring observation.
Declare its test-only filesystem dependency without changing runtime packages.
Regenerate the persistence catalog's source anchors after the shared path
helper import shifts AgentInstructionSource by one line. Its persisted fields
and SHA-256 type fingerprint remain unchanged; no type acknowledgement or
Session migration is required for a source-location-only update.
Validation:
- All five new regressions failed with the intended partial-group emissions
before the source fix.
- pnpm exec vitest run packages/context/agent-instructions/tests/agent-instructions.spec.ts -t 'hidden duplicate has|cold global group|unavailable active candidate|unavailable scope': 8 passed.
- pnpm exec vitest run packages/context/agent-instructions: 174 passed.
- The focused authored headless snapshot refresh and replay passed.
- Restoring the early skip for an unavailable hidden candidate makes the
headless snapshot fail with the premature harness-home replacement.
- README translations were updated together and their pairing rerecorded.
- Three project-alias regressions failed on the initial group rollback fix,
then passed after reserving failed and unvisited candidate paths.
- pnpm exec vitest run packages/context/agent-instructions/tests/agent-instructions.spec.ts -t 'frozen across a project alias|hidden duplicate has|cold global group|caches a removed duplicate': 12 passed.
The user-global instruction scope now reads two roots: $DSH_HOME/AGENTS.md
first, then the shared agents root that other agent tools use
($DSH_AGENTS_HOME, else ~/.agents). Both resolve from the process environment
through @deepseek-ai/dsh-home-paths; no config field is added, because the
stack base (PR #5718) removed the per-row home override.
The two files are candidates of one candidate group: identical trimmed content
renders once from the harness home, an unobservable candidate preserves the
group's last-good state, and reconciliation probes both roots so external
edits, removals, and new files become visible change notices. A candidate
dropped as a duplicate keeps being reconciled, so deleting or changing the
retained candidate promotes it. The harness-home file keeps its recorded
`user-global` scope key; the shared file carries `agents-global`.
A user-global delta states `These user-global instructions apply to all work.`
instead of naming its reconciliation scope, and a project path whose first
component would collide with a user-global scope directory renders with a
leading `.` so it keeps its own scope.
The tools pipeline's ask decision now carries an optional displayReason
that ToolRuntime forwards to the approval service, so the Auto review
prompt is localized while the audited reason stays English.
Adds the auto-review-approval Web snapshot for a user rejection after a
reviewer denial and for a reviewer failure, and updates the permission
preset pages, READMEs, Agent Notes, and child-agent JSDoc that still
described the shared never bundle.
Delete constraints the model learns from the call result, shorten
implementation detail, and move per-parameter rules into the owning
parameter descriptions. Bash, pwsh, and fs share one
sandbox_permissions description in dsh-sandbox.
The standard preset's first-turn prompt drops from 7985 to 6551 tokens.
Compaction threshold snapshots lower their context windows by the
1548-token tool-schema estimate reduction so each trigger keeps its
position; their fixtures move to v4 generations.
* feat(workspace): stop a Session's running work before archiving it
Archiving was a pure visibility write, so a Session archived mid-turn kept
running out of sight. The Workspace registry now owns archive admission
through two Host events: `workspace/session-activity` reports what still
runs and refuses the plain archive as `workspace/session-active`;
`workspace/session-stop`, requested with `stopActivity`, stops that work the
way the user's own stop actions do before the archive write. The API Session
Controller reports and stops turns, subagent descendants, and owned jobs and
rejects any model step for an archived Session; the Schedule plugin reports
and deletes active reminders. The sidebar turns the refusal into a
stop-and-archive confirmation listing the Host's answer.
* test(workspace): pin the widened archive signature and prove child liveness by heartbeat
The Client inspect catalog spec pins archiveSession's new options
parameter, and the archive e2e reads the Bash child's liveness from a
heartbeat file instead of a pid: the Linux sandbox runs the tool in its own
PID namespace, so the pid it reports is not comparable from the test.
* test(workspace): cover the archive-admission providers and dialog to the per-file gate
Drop the provider's unused disposer and the dialog's unreachable confirm
guard, read reminders without a catch that no composition can reach, and
add the cases the coverage lane found missing: a stop without a jobs
registry, a looping lineage, a descendant whose projections reject, the
dialog's Escape guard and non-Error reason, and a family merged by another
provider.
* fix(workspace): write the archive before stopping, gate subagent lineage, and delete reminders under the schedule barriers
Review round on #4765. The registry now writes the archive set before it
dispatches `workspace/session-stop`, so the durable set already gates
every wake the stops induce; the controller's `agent/pre-step` gate also
blocks subagent descendants of an archived Session and contains each
cancel or kill on its own. The Schedule plugin's stop listener runs as a
management delete in the agent's transaction queue between the same two
persistence barriers the `schedule_delete` tool uses. The confirm dialog
selects singular or plural English lines and keys list rows by index.
Docs: archive-admission section with type-equiv blocks on the workspace
subsystem page, write-first order and residual windows in the READMEs
and the Agent Note, and the missing zh reminders sentence.
* test(web): scope the question composer's New Session wait to the Sessions tree
The wide sidebar's New Session button carries the same visible label as
a fresh session row, so the unscoped `getByText` either settled on the
button before the row existed or hit a strict-mode violation once the
row rendered first, which is how the snapshots lane failed on
ece68c2ab5. Waiting inside the Sessions tree names the row alone.
* fix(schedule): answer archive admission from the owned runtime's fold, not the projection registry
The `sessionProjections.snapshot` API is the Client projection view and
is not a Host read path (review on #4765). `ScheduleRuntime.activeRecords()`
folds the live log the way every drive does, and the archive-admission
listeners ask the owned runtime for that fold: a session without a live
agent or without an owned runtime has nothing armed to fire, so it reports
nothing and has nothing to stop. Covers the runtime-less agent, a fold that
turns unreadable at the persistence barrier, and the stopping/faulted
runtime answering nothing.
* refactor(subagent): report and stop subagent descendants from the Subagent runtime
The `subagent` family of archive admission moves out of the API Session
Controller into `dsh-subagent`, which records the lineage at delegation
and owns the descriptor (review on #4765): `SubagentRuntime` answers
`workspace/session-activity` with the running descendants, labelled from
each child's descriptor through a live Session observation, and
`workspace/session-stop` by cancelling each of them with the parent
cause. The controller keeps turns, owned jobs, and the lineage step gate,
and composes its provider through `ctx.plugin(SessionActivityProvider)`
with declared injections instead of a bare installer call. `dsh-workspace`
becomes an optional type-only peer of `dsh-subagent`.
* refactor(jobs): answer archive admission for owned jobs from the job registry seam
The `job` family moves out of the API Session Controller into `dsh-jobs`
(review on #4765): the seam's constructor installs the
`workspace/session-activity` and `workspace/session-stop` listeners for
every implementation through the abstract `list` and `kill` alone, so the
controller no longer knows the jobs vocabulary and keeps only the turn
family and the archived-lineage step gate. `dsh-workspace` becomes an
optional type-only peer of `dsh-jobs`.
* refactor(workspace): leave SessionActivityKindMap empty and let each provider merge its family
The workspace package no longer names any activity family (review on
#4765): `SessionActivityKindMap` is empty, and each provider merges its own
key from a module both its faces import — `turn` in the API Session
Controller's types, `job` in the job registry seam's view, `subagent` in
the Subagent runtime's control types, `schedule` in the Schedule plugin's
types. The confirm dialog imports those modules for its cases and keeps
the generic line for any other key; the registry and controller suites
merge test-owned families instead of borrowing the providers'.
* refactor(agent): report and stop the running turn from the Agent registry
The `turn` family moves out of the API Session Controller into `dsh-agent`
(review on #4765): the registry's constructor installs the
`workspace/session-activity` and `workspace/session-stop` listeners for
every Agent it publishes, answering with its own lookup and cancelling the
turn with the user cause, and merges the `turn` key from its client-safe
types. The controller keeps only the archived-lineage step gate, renamed
`ArchivedSessionGate`. `dsh-workspace` becomes an optional type-only peer
of `dsh-agent`; the workspace package depends on none of the providers,
so the edge stays acyclic.
Since #3127 a foreground Bash command is a registered job from its start,
so the archive dialog lists it beside the turn; the e2e and its ARIA golden
expect that row, and the capture keeps the running job by design.
The static CI gate rejected four new assertions to unknown in the
rewritten Team panel specs. Build the Session list, Session snapshot,
and injected-callback fixtures as typed values, prune the retired
baseline fingerprints, and regenerate the module graph, config, and
persistence catalogs for the removed Remote dependency edges and the
shifted source lines.
* feat(preset): declare Agent compositions in profile YAML
* fix(preset): share scope binding cleanup and refresh module graph
* fix(preset): use host syntax colors in the YAML editor
* fix(preset): write new profile declarations as block YAML
* fix(preset): align eager activation with browser and worker surfaces
* fix(ui-agent-preset): retain the existing preset card layout
* fix(preset): keep rows waiting for a Host service mounted and re-audit after settlement
A preset row whose Host provider was still activating at declaration time
was reported as waiting for a missing service, and the registry recorded the
definition as broken for the rest of the process. Split the mount audit into
failed and pending rows: failures and root-realm leaks still reject the
mount, while pending rows stay mounted and every read and binding re-audits
them after the Host Loader tree settles.
Remove the accidental self-dependency of @deepseek-ai/dsh-web-app and its
lockfile self-link. Archive the copy-only preset authoring note, which the
declarative-preset note fully supersedes, and update the ralph note's
restore recipe to the profile-patch mechanism.
* chore(lint): re-key and prune the unknown-cast baseline after the master merge
* refactor(web-app): ship each Agent preset as its own bundle patch file
`dsh.bundle.patch` accepts an ordered file list, so the four shipped preset
declarations move out of the 1000-line web patch into
`presets/<id>.patch.yml`, one insert per file, applied after the host patch.
The host patch keeps the preset registry row. Gates and test scaffolds that
read the web layer resolve every patch file through `bundlePatchPaths`
instead of one hardcoded path.
* refactor(preset): drop the save notice injected into live Agents
The notice duplicated the save result the Web editor already shows, and
after the producer-owned message sources it would have needed its own
persisted source kind. Saving now only persists and reports the activation
diagnostic; the persistence catalog is unchanged from master.
* docs: regenerate the module graph after dropping the registry's llm dependency
* test(ui-agent-preset): cover the guide dialog's keyboard handling on the declarative section
* fix(preset): address the remaining review comments
Apply the lowercase id rule only when creating a declaration, so presets
declared with other ids stay editable. Export `isBuiltInPreset` from the
display fold and key the client card groups on it. Remove the dead `error`
and `retry` locale keys, the JSDoc orphaned by the `trust` removal, the
`trust` fields in the plugin-inventory test fixtures, and the stale
`dsh-agent-presets` package name in comments and READMEs.
* refactor(preset): make the Web preset page view-and-select only
Remove the child-plugin YAML editor, the `agent_preset` tool and the
registry's read/save Remote methods. Presets are declared and changed only by
bundle patches; the settings page keeps the roster, the new-task default and
the mode help, and its question icon explains that and offers to start a
Creator-mode task. The `editing-cordis-compositions` skill and the Creator
persona describe the bundle-based path, and the authored skill-load Session
and Web snapshots are refreshed for it.
* docs(skill): make the composition skill self-sufficient for preset authoring
State where the shipped declarations live, list every declaration field,
inline a complete minimal bundle and an override example, and name the
verification calls, so Creator mode no longer reads DSH package sources to
infer the format. Refresh the authored skill-load Session for the new text.
* test(tools): drop the removed agent_preset tool from the catalog expectation