Commit Graph

102 Commits

Author SHA1 Message Date
Tianyi Cui
cf255eebb1 fix(scope): harden merged tool and skill boundaries 2026-07-11 23:41:37 +08:00
Tianyi Cui
56e34619d7 Merge remote-tracking branch 'origin/master' into codex/pr224-rfc-rewrite
# Conflicts:
#	docs/architecture.md
#	docs/capability-seams.md
#	docs/config-catalog.md
#	docs/cookbook/extension-cookbook.md
#	docs/cordis-catalog/events.md
#	docs/cordis-catalog/services.md
#	docs/event-producer-consumer.md
#	docs/module-graph.md
#	docs/rfc/implemented/feature/2026-06-30-interception-seams.md
#	docs/rfc/proposed/feature/2026-06-14-acp-agent-client-protocol.md
#	docs/tool-execution-pipeline.md
#	packages/cordis/tool-cordis/src/api-catalog.ts
#	packages/core/agent-core/README.md
#	packages/core/agent-loop/README.md
#	packages/core/tools/README.md
#	packages/core/tools/src/index.ts
#	packages/core/tools/tests/tools.spec.ts
#	packages/core/tools/tsconfig.json
#	packages/ui/acp/src/index.ts
#	scripts/doc-budgets.manifest.json
#	scripts/gen-cordis-catalog.ts
#	scripts/gen-doc-graphs.ts
2026-07-11 23:14:09 +08:00
Tianyi Cui
36c94fbe3e docs: align the agent-scope contracts 2026-07-11 22:55:40 +08:00
Tianyi Cui
3baaecc078 Merge remote-tracking branch 'origin/master' into codex/skill-system
# Conflicts:
#	docs/rfc/INDEX.md
#	examples/acp-agent/tests/snapshots/both-mode-turn/session.jsonl
#	examples/acp-agent/tests/snapshots/code-mode-turn/session.jsonl
#	examples/acp-agent/tests/snapshots/text-turn/session.jsonl
#	packages/README.md
2026-07-11 22:31:28 +08:00
Tianyi Cui
b29a8eca71 fix(review): reconcile sandbox and approval contracts 2026-07-11 21:37:38 +08:00
Tianyi Cui
fc0357a100 Merge remote-tracking branch 'origin/master' into codex/pr224-rfc-rewrite
# Conflicts:
#	docs/architecture.md
#	docs/event-producer-consumer.md
#	docs/module-graph.md
#	scripts/doc-budgets.manifest.json
#	scripts/gen-doc-graphs.ts
2026-07-11 20:38:25 +08:00
kingwl
3f663c9154 feat(modes): per-session sandbox/approval switching — the session log as the store, ACP config options
effective(session) = findLast(the session own knob events)?.value ?? the
composition-config default. One log-only event per knob, owned by its
domain (bash/sandbox-mode in dsh-bash, approval/policy in dsh-approval),
each exporting the same three-piece kit: the event declaration, a pure
fold, and THE write path — a switch IS its event; no owner service, no
facts map. Restart immunity and multi-session isolation fall out of the
log replay by construction.

Execution follows the fold on both sides: the bash tool stamps
escalation grant > session override > executor default, and the approval
seam prepends the never-gate that auto-rejects before any interactive
answerer. Visibility is two layers per knob: a per-agent prompt section
states the effective value on every request (logged through
request/header*, so what-the-model-was-told replays from the log), and an
agent/pre-step narrator injects at most one coalesced delta notice with
positional attribution (user switch vs operator/config drift). The ACP
bridge advertises one capability-gated select per composable knob with
currentValue folded per session, validates set_config_option against the
closed vocabularies, and anchors idle switches at the next turn
prompt-submit under the turn-enclosure contract.
2026-07-10 15:44:38 +08:00
kingwl
2eed448acf feat(bash): the sandboxed executor — per-call policy carrier, denial facts, runner-failure classification
dsh-bash grows the per-call policy carrier: BashExecRequest.sandboxMode
(request-optional, spec required-but-nullable — the owner pattern; resolve()
is the one explicit defaulting step) and the BashExecutor.sandboxMode
capability fact (undefined in the base class — composition truth the tool
layer can read). dsh-bash-local carries the field verbatim and confines
nothing.

dsh-bash-sandbox extends LocalBashExecutor and hands ctx.sandbox the exact
argv it is about to spawn. A denial is a RESULT FACT (the command RAN;
result.sandbox.denied is orthogonal to exitCode/signal), classified
conservatively against the wrap own dialect; a RUNNER failure outranks
denial — foreground re-throws the structured SANDBOX_UNAVAILABLE, a settled
background task stamps sandbox.runnerFailed — so a broken sandbox never
reads as a failing command and the command never runs unconfined.
dsh-tool-bash renders the markers and teaches the model not to retry around
a policy denial; escalation and per-session switching are staged follow-ups.
2026-07-10 15:43:02 +08:00
kingwl
7b8c3a9b40 feat(sandbox): the confinement seam and the per-platform native runner chains
ctx.sandbox (dsh-sandbox): confine(argv, policy) returns the argv to spawn
instead — wrapped so the process and its children run confined — plus the
enforcement completeness and the backend denial/runner-failure dialects;
no usable backend throws the fail-closed SANDBOX_UNAVAILABLE. Policy rides
per call. dsh-sandbox-local selects by platform and caches the verdict:
multi-candidate chains probe FUNCTIONALLY in preference order (Linux:
bwrap → the registry-installed node-addon-landlock-run launcher), a sole
candidate is selected unprobed (darwin: sandbox-exec/Seatbelt) and fails
closed at execution via runnerFailureSignatures; win32 is a reserved empty
chain. Profile parity is honest per backend (documented temp-area and ABI
differences; enforcement full|partial is a structured result fact).

CI: the sandbox-e2e matrix proves real-kernel confinement per rung (bwrap,
Landlock per architecture through the registry-installed launcher,
Seatbelt), failing on a silent all-skip; the packed-install rehearsal
installs the launcher family from the registry and asserts the binary
executable apart from kernel enforcement.
2026-07-10 15:43:02 +08:00
kingwl
ef35007d75 feat(approval): the approval seam — one-shot permission decisions over a waterfall of answerers
ctx.approval (dsh-approval): request() dispatches the approval/request
waterfall and always resolves a closed outcome — allowed-once / rejected /
cancelled / unavailable — never rejects; zero listeners fall through to
fail-closed unavailable; abort settles cancelled and discards late answers;
throwing or rogue answerers are contained as unavailable; every ask lands
the log-only approval/asked / approval/decided audit pair. dsh-tools routes
a pre-execute ask through the seam opportunistically (ctx.get) with three
distinct deny reasons, keeping the historical ask→deny degrade when the
seam is absent.

The per-session policy tier, the ACP bridge answerer, and the sandbox
escalation asker are staged follow-ups of the approval-seam RFC.
2026-07-10 15:43:02 +08:00
Yichen Jiang
680ae53bb6 Merge remote-tracking branch 'origin/master' into codex/skill-system
# Conflicts:
#	docs/architecture.md
#	docs/config-catalog.md
#	docs/module-graph.md
#	docs/rfc/INDEX.md
#	examples/acp-agent/tests/snapshots/text-turn/session.jsonl
#	packages/core/agent-core/src/index.ts
#	packages/core/tools/tests/gen-tool-catalog.spec.ts
#	packages/support/acp-snapshot/src/suite.ts
#	packages/ui/acp-agent/src/index.ts
2026-07-10 14:43:33 +08:00
Yichen Jiang
6292d52236 feat(skill): move catalogs into session prefixes 2026-07-10 14:19:06 +08:00
Tianyi Cui
4751a7be0b Merge origin/master: Code Mode composed with agent scopes
Master advanced 11 commits mid-merge (the Code Mode registry integration:
mode config, run_code, the tools:sdk section, the ACP run_code cards and
unified demos). The fusion makes Code Mode scope-aware end to end:

- wireSchemas(scope): the mode-aware wire contribution is computed from the
  CALLING SCOPE's visible set (scoped tools join, shadowing and restrictions
  apply) and feeds the {schemas, knownNames} provider protocol.
- knownNames under the mode collapse: a per-scope RESTRICTION is runtime
  state, so the universe stays pre-restriction (a restricted-away tool in
  toolOrder is a normal absence) — but the MODE collapse is deployment
  config, so under mode 'code' the universe is [run_code] and a toolOrder
  naming a native tool fails every assembly loud (master's tested decision,
  kept).
- The tools:sdk section renders per assembly CONTEXT: the SDK declares
  exactly the calling agent's callable set, using the section-text provider
  signature this branch already had.
- run_code bindings enumerate schemas(exec.agent) — a program can bind
  exactly what its prompt promised; sub-dispatches already threaded
  exec.agent through registry.execute, so scoped resolution and carriers
  flow unchanged.
- dsh-tools declares both sides' new deps (dsh-scope + dsh-session);
  lockfile and all generated catalogs/graphs/api-catalog regenerated.

Gates green on the merged tree: typecheck, lint, per-file 100% coverage
(2710 tests), snapshots (41), doc-sync, module graph, build, hygiene, demo
smoke.
2026-07-09 23:57:50 +08:00
Tianyi Cui
58a5088feb Merge remote-tracking branch 'origin/master' into workflow-vm-to-workerthread
# Conflicts:
#	docs/config-catalog.md
#	docs/event-producer-consumer.md
#	packages/core/tools/tests/gen-tool-catalog.spec.ts
2026-07-09 23:48:17 +08:00
Tianyi Cui
2489402610 Merge origin/master: scope-aware fusion of the tools/execute seam, session-prefix, and tool-cordis
Master brought 50 commits (the tool-cordis group, dsh-code-runtime + worker,
the tools/execute around-dispatch seam + timeout-policy, repeat-tool-guard,
agent/session-prefix, the ui reorganization). Beyond the ten textual
conflicts, the merge reconciles master's new seams with this branch's
scoped-registration world:

- tools/execute (new waterfall around core dispatch): dispatched with the
  SAME exec.agent carrier as the pre/post waterfalls — an agent.ctx wrapper
  times/retries only its own agent's calls — and its base thunk resolves the
  tool through the caller's visible view (get(exec.name, exec.agent)), so a
  scoped/shadowed tool dispatches and a restricted-away global stays
  UNKNOWN_TOOL. Declared this: Scoped<ToolRegistry> with the scope-filtered
  doc sentence; invariants table + verify-scoped-dispatch pin it (21 events).
- agent/session-prefix (new waterfall, once per loop instance): composed via
  the fused agentEvents dispatcher (scope-filtered like every agent-subject
  event), declared this: Scoped<Agent>, table-pinned. agent/pre-step keeps
  master's new sessionPrefix parameter with this branch's Scoped this.
- timeout-policy reads the budget through the caller's visible view
  (get(exec.name, exec.agent)): a scoped tool's own timeoutMs governs its
  calls; a global name-twin's budget is never misapplied to a shadowing
  per-agent variant.
- tool-cordis: cordis_inspect's tools section lists the CALLING agent's view
  (its description promises "what you can call"); the sandbox tool façade's
  reads resolve through the mount's own scope, mirroring where its register
  lands writes; sandboxRegisterTool's return type carries the exact-disposer
  union honestly. dsh-scope declared as peer+dev with the project reference.
- doc-sync chain unions master's verify-cordis-api with this branch's
  verify-scoped-dispatch; the generated catalogs, event matrix (the
  zero-dispatcher guard passes over master's new events), module graph, and
  the cordis api-catalog are regenerated on the merged surface.

Full gate sequence green on the merged tree: typecheck, lint, per-file 100%
coverage (2668 tests), snapshots (38), doc-sync, module graph, build,
hygiene, demo smoke.
2026-07-09 23:24:42 +08:00
Yichen Jiang
b9bf67d0a7 Merge remote-tracking branch 'origin/master' into codex/skill-system 2026-07-09 23:11:10 +08:00
imccyu
64d0703c40 workflow: host-guarantee the agent-start/agent-end pairing on every stop path
agent-end was worker-authored only, so a start already forwarded to
observers lost its paired end whenever the worker could no longer speak
- the grace force-settle terminating a wedged script, or an unexpected
worker death - stranding progress consumers with agents that never
finish (ds-review-bot finding on #233).

The host now keeps a ledger of forwarded starts and funnels every
agent-end through one gate: worker-reported ends pair (and clear) their
entry, and both termination paths drain the remainder as synthesized
'cancelled' ends BEFORE the run settles, so ends always precede
workflow/end. A real settlement racing the force-settle loses to the
synthesized cancellation - the same first-wins override onResult applies
to the run's own result.
2026-07-09 23:05:43 +08:00
Tianyi Cui
2da28e89eb Merge remote-tracking branch 'origin/master' into code-mode-tools
# Conflicts:
#	examples/AGENTS.md
#	examples/README.md
#	package.json
#	packages/core/tools/tests/gen-tool-catalog.spec.ts
2026-07-09 22:58:58 +08:00
imccyu
053a2b9403 Merge remote-tracking branch 'origin/master' into workflow-vm-to-workerthread 2026-07-09 22:54:19 +08:00
Tianyi Cui
c39fe5cd30 Merge remote-tracking branch 'origin/master' into agent-request-messages
# Conflicts:
#	docs/cordis-catalog/services.md
2026-07-09 22:43:26 +08:00
Tianyi Cui
d976767fa6 Merge branch 'master' into recall-renderer-shared 2026-07-09 22:34:56 +08:00
imccyu
7f5b990aa1 Merge remote-tracking branch 'origin/master' into workflow-vm-to-workerthread 2026-07-09 21:34:52 +08:00
Yichen Jiang
0df497133c Merge branch 'master' into agent-request-messages 2026-07-09 21:12:31 +08:00
Tianyi Cui
19fc33f172 Merge remote-tracking branch 'origin/master' into code-mode-tools
# Conflicts:
#	docs/config-catalog.md
#	docs/module-graph.md
#	docs/tool-catalog.md
#	packages/core/tools/tests/gen-tool-catalog.spec.ts
#	packages/ui/acp-agent/package.json
#	pnpm-lock.yaml
#	scripts/gen-tool-catalog.ts
2026-07-09 21:10:40 +08:00
imccyu
d5c65e2b4c docs: describe the workflow engine as worker-thread first
The outer ring catches up with the engine swap (the package's own
README/JSDoc rode the port commit):

- Seam module doc and README name the worker-thread engine as THE
  implementation, with isolated-vm/separate-process sandboxing as the
  deferred hardening; the seam service doc states the holder-owned-runs
  contract (engine-fiber disposal deliberately leaves live runs to
  their holders).
- Seam contract precision: agentsStarted documents the termination-path
  degradation to the host-observed count; the events section scopes the
  agent-start/agent-end pair to calls that STARTED a child run;
  WorkflowRun wording drops the vm-era abandonment language.
- The dynamic-workflows RFC is rewritten in place to the shipped
  mechanism (implemented-RFC rule): why worker threads, the thread's
  concrete buys, the in-process node:vm first cut recorded under
  alternatives considered; the tool section describes the usage policy
  as the tool's own prompt section.
- gen-doc-graphs: six workflow/* DYNAMIC_EVENT_DISPATCHERS entries (the
  catalog no longer claims nothing dispatches them) and the seam-note
  wording; core-data-structures gains its workflow.md index row;
  packages/README + AGENTS.md layout line + example cordis.yml comments
  say worker-thread; catalogs regenerated.
2026-07-09 19:31:56 +08:00
Yichen Jiang
1e06fdbb86 refactor: colocate user interaction with ui packages 2026-07-09 17:59:02 +08:00
Ziya
fc6db791f1 refactor(compact): extract the shared transcript renderer into dsh-compact
Move compact-basic's private _extractText/_blocksToText into the interface
package as renderTranscript/renderContentBlocks, so the summarize path and a
future recall read path render one span identically. Byte-identical output
vs the private helpers it replaces; compact-basic delegates.
2026-07-08 22:39:55 -07:00
Yichen Jiang
bdab8c6a61 Merge remote-tracking branch 'origin/master' into codex/ask-user-question
# Conflicts:
#	docs/config-catalog.md
2026-07-09 13:34:13 +08:00
Tianyi Cui
a4553cc10d Merge remote-tracking branch 'origin/master' into code-mode-tools
# Conflicts:
#	docs/cordis-catalog/events.md
#	docs/cordis-catalog/services.md
#	docs/event-producer-consumer.md
#	docs/tool-execution-pipeline.md
#	packages/core/tools/README.md
#	scripts/gen-doc-graphs.ts
2026-07-09 13:30:26 +08:00
Yichen Jiang
e4331ca5e7 Merge branch 'master' into agent-request-messages 2026-07-09 13:30:11 +08:00
Tianyi Cui
7c5133488a refactor(core): every registry register-method returns the exact effect disposer
The exact-disposer fix (5fbac8be B1) repaired agents.register but left the
same wrapper (return () => void dispose()) at seven sibling sites:
tools.register, tools.restrict, systemPrompt.section/tools/variable,
agents.setFactory, and subagents.registerProvider. A wrapper makes correct
composite usage unrepresentable — the exact disposer cannot be recovered, so
a generator effect yielding it leaves the inner effect disposing as a
CONCURRENT SIBLING on owner unload, silently reproducing B1's ordering
corruption. The exact disposer serves both usages (composite-nestable AND
fire-and-forget callable); all seven now return it, typed
() => Promise<void> | void, with the convention pinned by a discriminating
test: an async-link composite probe that passes with the exact disposer and
observes the sibling unregistration firing mid-drain with a wrapper.

Re-auditing also surfaced that B1 itself SHIPPED a full-lint failure: it
changed register()'s return type without updating cross-file consumers
(agent.spec.ts dispose() statements, tool-bash's disposer list), which the
staged-scoped pre-commit lint never saw — pnpm run lint was red at HEAD.
Those three sites and this change's own fallout are fixed together: tests
now await disposers (stronger — they observe the full unwind), sync
paths void them, and the two annotation sites carry the honest union type.
agents.register's README line had drifted the same way (B1 updated the
JSDoc, not the README) — all seven README signatures now match; services
catalog regenerated.
2026-07-09 13:05:44 +08:00
Tianyi Cui
d5d5e3fa3c docs: regenerate services catalog for the register() disposer signature 2026-07-09 04:53:58 +08:00
Tianyi Cui
e7bcbb8bc6 feat(dx): scopeHost, agent-aware ACP presentation, and the scoped-dispatch drift gate
scopeHost(ctx, services) is the sanctioned way to mint scopes in tests: it
names absent services loudly instead of the cryptic cordis without-inject
dead end, and catches the silent-no-op host (cordis resolves a
dependency-pending fiber's await without running the inject callback).

The ACP ToolPresenter resolves presentations through the session agent's
view (tools.get(name, agent)) so a scoped/shadowed tool renders with the
same definition that executed.

verify-scoped-dispatch (doc-sync + pre-push) pins the dev-invariants
carrier table against the declaration JSDoc set: an event enforced but
undocumented, documented but unenforced, or a registry-subject notification
leaking into the table fails the build. subagent/start|end docs gain their
scoped-dispatch sentence (a real gap the gate caught on first run).
2026-07-09 02:38:54 +08:00
Tianyi Cui
f91eb39538 docs: regenerate catalogs and sync subagent type-equiv blocks for persona/toolFilter 2026-07-09 02:18:39 +08:00
Tianyi Cui
806e7a84cf docs: regenerate module graph, config catalog, and cordis catalogs for agent scoping 2026-07-09 01:21:27 +08:00
Yichen Jiang
b31399bdc4 Merge remote-tracking branch 'origin/master' into codex/ask-user-question
# Conflicts:
#	docs/module-graph.md
2026-07-08 22:22:25 +08:00
Yichen Jiang
765052a7d1 fix(agent-loop): compose the session prefix before pre-step; hand it to the pressure gate
ds-review-bot critical (follow-up): on the first step of a resumed or
seeded/forked instance, auto-compaction ran before runStep composed
this instance's prefix, so the gate read the PREVIOUS instance's logged
prefix from the header fold — a contributor that grew across
resume/fork (skills added, AGENTS.md grown: exactly the
environment-dependent case) could under-gate and ship an over-window
first request.

The loop now composes agent/session-prefix before the instance's first
agent/pre-step (still once per instance; runStep just reads the cache),
and agent/pre-step carries the composed prefix to its listeners.
CompactService.compactIfNeeded gains the sessionPrefix parameter;
BasicCompactService.estimatePressure gates on the handed value — the
header-fold read is gone, so the estimate is exact at every step
including a resumed/forked instance's first. Composition moving before
the boundary snapshot also means a composing listener's session append
now joins the CURRENT request (documented on the seam).

New coverage: composition precedes pre-step and the seam receives the
composed prefix; cancel and disposal landing inside the composition
window drop the step cleanly; the compact gate test hands the prefix
directly.
2026-07-08 20:30:10 +08:00
Yichen Jiang
f453ba77a2 refactor: split skill providers 2026-07-08 15:50:38 +08:00
Dudu-0223
ef2a150293 Merge remote-tracking branch 'origin/master' into timeout-design 2026-07-08 15:40:56 +08:00
Dudu-0223
395a0b8336 docs(timeout): update RFC + generated catalogs for the declaration split
The RFC's deployment-policy decision is unchanged; state the current
mechanism in place — the per-tool budget is declared on ToolDefinition
(timeoutMs, set by the owning tool plugin from its config) and the
enforcer is zero-config, so a mistyped tool name is impossible.
Regenerate config-catalog (timeout-policy -> no-config; tool-web gains
fetch/searchTimeoutMs), the event graph (tools/change loses its
timeout-policy consumer), the ToolDefinition type-equiv block, and a
source-line drift in the cordis services catalog.
2026-07-08 15:06:02 +08:00
Tianyi Cui
b59d245c7c feat: Code Mode — the registry's mode config, the SDK codegen, and the run_code bridge
The dsh-tools half of the Code Mode RFC (its fourth, final change): the
registry gains its first config — mode: native | code | both — and OWNS how
its tools reach the model. 'code' contributes exactly one wire tool,
run_code, plus a lazy tools:sdk prompt section declaring every other tool
as a generated TypeScript API (jsonSchemaToTs: total over the defineTool
subset, unknown degradation, lexicographic byte-identical rendering);
'both' ships both representations; 'native' is byte-for-byte the old
behavior. Non-native modes fail every assembly loudly without a
typescript-language ctx.codeRuntime.

run_code's dispatch bridge: JSON-normalizes each binding argument before
dispatch (what dispatches is what the tool/code-dispatch event logs — the
append can never fail on payload shape; BigInt/circulars reject that one
call), serializes all program tool calls through a per-run queue (even
Promise.all — no concurrency-safety metadata yet), routes every sub-call
through tools/pre-execute → tools/post-execute (a deny rejects the
program-side promise), drops sub-call additionalContext (no safe outlet
mid-run; pinned), owns a run-scoped abort that follows the outer signal in
and fires on settlement (in-flight sub-dispatch aborted, queued abandoned,
queue drained before returning), and converts a failed run into
CodeRunFailedError → a structured isError carrying kind + captured logs.
tool/code-dispatch joins SessionEventMap by declaration merging (log-only;
deriveMessages ignores it).

The composed surface: the tools config forwards through agent-core and
both app packages; examples/code-agent + demo:code run the worker runtime
under mode code (keyless boot smoke + a with-key e2e proving the collapsed
[run_code] header, the dispatch events, and the file the program wrote);
two new snapshot scenarios (code-mode-turn, both-mode-turn) record the SDK
section, collapsed header, dispatch events, and result card — each its own
header-pinning class (the harness gains per-scenario config overlays and
per-class pins). Catalogs, graphs, cookbook, hooks-bridge notes, and the
RFC (moved to implemented/, restructured to decision-era headings) updated
in the same change.
2026-07-08 12:58:23 +08:00
Dudu-0223
a76285c4e6 Merge origin/master into timeout-design
Resolve conflicts from master's catalog/doc refactors landing alongside the
tool-call timeout work:
- knip.json: keep both new workspace entries (util/timeout + support/acp-snapshot).
- tool-web/src/fetch.ts: keep the timeout_ms removal, adopt master's richer
  JSDoc @param/@returns style on parseFetchArgs/presentFetchCall.
- tools/README.md: keep the tools/execute pipeline wording, adopt master's
  flattened docs/tool-catalog.md path.
- Regenerate every generated doc (cordis-catalog, tool-catalog, config-catalog,
  doc-graphs, module-graph) so they carry both master's changes and the
  tools/execute event + timeout-policy package.
- Add @param/@returns to toolTimeoutResult for master's new verify-export-jsdoc gate.
2026-07-08 11:18:27 +08:00
Yichen Jiang
d3f86996f7 Merge remote-tracking branch 'origin/master' into codex/ask-user-question
# Conflicts:
#	docs/config-catalog.md
#	examples/acp-agent/tests/snapshots/text-turn/session.jsonl
#	pnpm-lock.yaml
2026-07-08 11:09:20 +08:00
Dudu-0223
8190016e2b feat(timeout): add tools/execute seam + tool-timeout policy plugin
Model-facing tool-call budgets were tangled into each capability's schema
(bash timeoutMs, web_fetch timeout_ms) with no shared home. Add a
tools/execute around-dispatch waterfall to dsh-tools whose base next() is
the dispatch-with-normalization thunk, and a new @deepseek-ai/dsh-timeout-policy
plugin (packages/timeout/) that arms a per-tool deadline on exec.signal and
returns a structured TOOL_TIMEOUT when it wins. Migrate web_fetch (drop the
model-facing timeout_ms) and web_search onto it; the fetch provider keeps its
timeout only as a resource backstop for direct callers. bash and hook command
execution keep BASH_TIMEOUT unchanged.

Named the plugin timeout-policy (not the RFC's tool-timeout) so it does not
trip the gen-tool-catalog packages/*/tool-* completeness guard, and replace
exec.signal by in-place mutation before next() since cordis waterfall next()
ignores passed arguments. RFC moved to implemented/ recording both deviations.
2026-07-08 10:10:37 +08:00
Tianyi Cui
15a3431913 docs: catalog the code-runtime seam vocabulary (Codex review finding)
Adds the missing core-data-structures coverage the catalog policy
requires for non-spine seam vocabulary: the code-runtime.md sub-page
with drift-checked type-equiv blocks for all six seam types, the core.md
sub-page row, the type-equiv manifest entries, and LINK_MAP entries so
the generated service signature links CodeRunRequest/CodeRunResult;
cordis/config catalogs regenerated.
2026-07-08 02:38:47 +08:00
Tianyi Cui
6da6f04016 feat: add the code-execution capability seam (ctx.codeRuntime)
New group packages/code-runtime/ with the interface package
@deepseek-ai/dsh-code-runtime, per the Code Mode RFC: abstract CodeRuntime
service (run() resolves program failures as an error field, rejects only
for seam misuse), the CodeRunRequest/CodeBindingNamespace/CodeRunResult/
CodeLogEntry/CodeRunFailure vocabulary, and readonly language/isolation
backend descriptors. Registered in the tsconfig maps, packages/README,
architecture service map, and the doc-graph service-role classification;
catalogs regenerated.

The RFC's one forward path token to the worker package becomes an npm-name
mention until PR3 creates that directory (verify-package-paths is
drift-scoped: the now-existing group made the token checkable).

docs/architecture.md ceiling 1630 -> 1640: the doc gained a genuinely new
capability-service row; the row itself is already minimal.
2026-07-08 02:17:24 +08:00
Tianyi Cui
a706ec7966 Merge branch 'structured-output-subagent-seam' into worktree-dynamic-workflows
# Conflicts:
#	docs/rfc/INDEX.md
#	examples/acp-agent/tests/snapshots/text-turn/session.jsonl
2026-07-07 23:10:50 +08:00
Tianyi Cui
0172e3b67d Merge remote-tracking branch 'origin/master' into structured-output-subagent-seam 2026-07-07 22:59:35 +08:00
Tianyi Cui
1f5db6e0b0 docs: satisfy the export-JSDoc gate across the workflow packages
Master's verify-export-jsdoc landed mid-stack; complete the six missing
@param/@returns on the workflow trio's public surface (and the services
catalog they regenerate into).
2026-07-07 22:39:05 +08:00
imccyu
958742cac6 fix: cordis-catalog 2026-07-07 22:33:09 +08:00