Commit Graph

1394 Commits

Author SHA1 Message Date
Tianyi Cui
a9cb70d896 fix(scope): harden final ownership boundaries 2026-07-12 05:13:17 +08:00
Tianyi Cui
36b8370027 fix(scope): close remaining ownership boundaries 2026-07-12 03:51:55 +08:00
Tianyi Cui
3dca90261c Merge remote-tracking branch 'origin/master' into codex/pr224-rfc-rewrite
# Conflicts:
#	examples/coding-agent/tests/code-mode-keyless-smoke.e2e.ts
#	examples/coding-agent/tests/keyless-smoke.e2e.ts
#	examples/cordis-agent/tests/keyless-smoke.e2e.ts
#	examples/echo-agent/tests/echo.e2e.ts
2026-07-12 01:39:29 +08:00
Tianyi Cui
4cda9dd03d Merge pull request #254 from deepseek-harness/codex/system-prompt-snapshots
test(acp): snapshot system prompts as Markdown
2026-07-12 01:36:31 +08:00
Tianyi Cui
35715423f8 fix(workflow): honor subagent readiness boundary 2026-07-12 01:35:09 +08:00
Tianyi Cui
c632b693c6 test(e2e): tolerate bounded loader contention 2026-07-12 00:50:50 +08:00
Tianyi Cui
cb05300ba7 docs: remove duplicate scoped-event explanation 2026-07-12 00:38:38 +08:00
Tianyi Cui
3529b3c166 fix(scope): close final ownership races
Drain idle injection flushes before agent teardown, snapshot approval and subagent provider inputs, and gate subagent lifecycle events on real child readiness. Align the RFCs and generated contracts with the hardened behavior.
2026-07-12 00:31:46 +08:00
Tianyi Cui
382c243e78 test(e2e): widen keyless boot-smoke kill budgets to 30s
The keyless Loader-path smokes killed the child 10s after spawn, but a
loaded CI e2e runner routinely needs longer just to boot the unbuilt tsx
tree: on this branch's run the coding-agent smoke burned both retries and
failed at 30s wall-clock, and the sibling smokes passed only on retry x2
(master's latest run shows the same near-misses). The budget guards
against a HANG, not slowness — raise kill to 30s and the vitest test
timeout to 45s so a slow boot no longer masquerades as one.
2026-07-11 23:56:16 +08:00
Tianyi Cui
bac97a5b2e test(acp-snapshot): cover the delta-insert trailing-newline branch
formatSystemPromptSnapshot's insert-join ternary had its already-newline-
terminated arm unexercised (a delta whose insert ends in a blank line),
failing the per-file 100% branch gate on suite.ts (99.24%).
2026-07-11 23:55:56 +08:00
Tianyi Cui
e6c7522a75 fix(agent-loop): nest config resume teardown 2026-07-11 23:45:01 +08:00
Tianyi Cui
06e42f439c docs: regenerate merged catalogs 2026-07-11 23:42:52 +08:00
Tianyi Cui
cf255eebb1 fix(scope): harden merged tool and skill boundaries 2026-07-11 23:41:37 +08:00
Tianyi Cui
172005e0e6 fix(scope): align merged agent event contracts 2026-07-11 23:22:57 +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
3263dab822 fix(core): enforce agent-scoped ownership boundaries 2026-07-11 22:55:26 +08:00
Tianyi Cui
da9cef381c Merge remote-tracking branch 'origin/master' into codex/system-prompt-snapshots
# Conflicts:
#	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/support/acp-snapshot/src/suite.ts
2026-07-11 22:48:14 +08:00
Tianyi Cui
7331720c8a Merge pull request #109 from deepseek-harness/codex/skill-system
Add skill registry and local provider
2026-07-11 22:35:05 +08:00
Tianyi Cui
169f86966a fix(review): lint prompt Markdown paragraphs 2026-07-11 22:33:33 +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
9339622d3b test(acp): snapshot system prompts as Markdown 2026-07-11 22:24:20 +08:00
Tianyi Cui
28f7fa0969 docs(rfc): record deferred skill extensions 2026-07-11 22:18:58 +08:00
Tianyi Cui
9b4ce4f301 Merge pull request #169 from deepseek-harness/feat/sandbox-support
feat(sandbox): file-sandboxed bash execution — sandbox seam + approval seam + escalation + per-session mode switching over ACP config options
2026-07-11 22:17:15 +08:00
Tianyi Cui
0d23d95dde docs(sandbox): record follow-up boundaries 2026-07-11 22:07:56 +08:00
Tianyi Cui
1e2d8014a5 Merge remote-tracking branch 'origin/master' into feat/sandbox-support
# Conflicts:
#	packages/workflow/workflow-workerthread/tests/workflow-workerthread.spec.ts
2026-07-11 21:43:10 +08:00
Tianyi Cui
b29a8eca71 fix(review): reconcile sandbox and approval contracts 2026-07-11 21:37:38 +08:00
Tianyi Cui
1b1384c8b8 Merge branch 'master' into codex/skill-system 2026-07-11 21:27:17 +08:00
Tianyi Cui
850796bb35 fix(tools): reserve the Code Mode transport 2026-07-11 20:47:45 +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
Tianyi Cui
6091c0a3dc docs: rewrite the agent-scope RFC 2026-07-11 14:01:49 +08:00
Tianyi Cui
ee3e4ea8f9 Merge pull request #245 from deepseek-harness/fix/subagent-acp-onerror-containment
fix(subagent-acp): contain onError sink exceptions to keep result from rejecting
2026-07-10 23:33:03 +08:00
Tianyi Cui
a8b68e1303 Merge branch 'master' into fix/subagent-acp-onerror-containment 2026-07-10 23:31:17 +08:00
Yichen Jiang
386d4d3ec4 Merge branch 'master' into codex/skill-system 2026-07-10 22:58:15 +08:00
Tianyi Cui
ee15a01f61 Merge pull request #252 from deepseek-harness/eslint-project-service
chore(lint): one shared project service; ignore harness-local .claude state
2026-07-10 22:52:21 +08:00
Tianyi Cui
dce2945211 Merge branch 'master' into eslint-project-service 2026-07-10 22:50:28 +08:00
Tianyi Cui
feb457d425 Merge pull request #236 from deepseek-harness/codex/mock-snapshot-rerecord
Add keyless snapshot refresh mode
2026-07-10 22:36:48 +08:00
Tianyi Cui
65587c6091 Merge remote-tracking branch 'origin/master' into codex/mock-snapshot-rerecord
# Conflicts:
#	packages/workflow/workflow-workerthread/tests/workflow-workerthread.spec.ts
2026-07-10 22:19:18 +08:00
kingwl
53f6a959e2 chore(lint): one shared project service; ignore harness-local .claude state
Two independent multipliers were pushing bare `pnpm run lint` past node's
default heap:

1. parserOptions.project expanded to every package tsconfig plus the root
   one — each matched config built its OWN ts.Program, and the dev paths
   map pulls sibling package SOURCES (plus the vendored Cordis stack) into
   every such program, so resident memory grew as sum-of-closures, not
   repo size: ~4.6 GB peak for 425 repo files. projectService shares one
   tsserver-style graph: ~2.0 GB peak, ~28 s → ~14 s wall.

2. `eslint .` traversed .claude/ harness-local state — stale worktree
   checkouts there carry tens of thousands of additional .ts files
   (whole-repo copies), roughly tripling the work again even under the
   project service. Other checkouts are not this one's sources; ignore
   them like node_modules. (#169 carries the identical ignore line inside
   its chain; the hunks dedupe on its next rebase.)

Type-aware rules verified live under the service: a floating-promise
probe still trips no-floating-promises.
2026-07-10 22:13:40 +08:00
Yichen Jiang
e4be19b29e Merge remote-tracking branch 'origin/master' into codex/skill-system
# Conflicts:
#	packages/workflow/workflow-workerthread/tests/workflow-workerthread.spec.ts
2026-07-10 21:10:58 +08:00
Tianyi Cui
afb0a2b5cd Merge pull request #246 from deepseek-harness/fix/workflow-workerthread-waitfor
test(workflow-workerthread): flake-proof the lifecycle spec's waits under CI load
2026-07-10 21:05:58 +08:00
pku-xht
dd2f37b80f fix(workflow-workerthread): tighten post-result promptness waits back down
Review follow-up: the blanket 10s default correctly targets worker-thread
cold-start races (starting, first-script-line, async child-registration
messages — genuinely CPU-bound under CI contention), but four waits assert
something different — that the HOST reacted PROMPTLY to an event that
already happened (a settled result, an observed worker death). Those had no
cold-start left to wait on, so the generous default just widened the window
a real regression could hide in.

Verified by injecting a 6s delay into the settle-reap's abort call: the
un-overridden helper's test still passed in ~6s. The same mutation now fails
in ~1s with the explicit 1000ms override restored on all four sites (the
abort-on-settle test's own assertion, the two worker-death cancel/dispose
reap checks, and the dispose-ack-race check). The other 12 waits keep the
10s default — they run BEFORE a result is awaited, waiting on the worker to
actually start rather than on a host reaction. Doc comment corrected to
describe the split instead of claiming every wait is a cold-start race.
2026-07-10 20:48:14 +08:00
Yichen Jiang
c2c238d36d fix(skill): forward cancellation to local reads 2026-07-10 17:47:28 +08:00
Yichen Jiang
0b20353424 test(acp): clarify skill snapshot fixture 2026-07-10 17:47:11 +08:00
pku-xht
64b4e2ed2d test(workflow-workerthread): flake-proof the lifecycle spec's waits under CI load
The spec's 16 vi.waitFor sites used the 1s default timeout to wait for
worker-thread startup and child registration — CPU-bound work that blows
past 1s on a contended runner. The CI coverage lane (4 vitest workers plus
suites that spawn real subprocesses) hit this 3 times across 4 recent PR
runs, each a different subset of the cancellation/worker-death tests, each
green on rerun.

Every wait now goes through a shared helper with a 10s bound, and the file
sets a 30s test timeout to make room for it. The one deliberately tight
wait keeps its 800ms bound through the helper's override — it proves the
host (not the wedged worker's later loop turn) delivered the cancel, so a
generous bound would erase what it tests. No behavior under test changed.
2026-07-10 16:43:41 +08:00
pku-xht
62627d7625 fix(subagent-acp): contain onError sink exceptions to keep result from rejecting
spec.onError is a caller-supplied callback boundary, but the flattening
catch invoked it unguarded: a throwing sink rejected the whole async result,
breaking the seam's "result never rejects on a child-level failure"
contract (and docs/defensive-patterns.md's contain-callback-exceptions
rule). The sink's own throw is now swallowed — named as such — while the
original child failure still settles as stopReason 'error'. Regression test
drives a spawn failure through a throwing sink and asserts result resolves.

Same defect as the codex backend's, fixed there on PR #240; this is the
symmetric fix for the already-merged ACP backend.
2026-07-10 16:42:20 +08:00
kingwl
6a13dcb364 test(workflow): give the wedged-child waitFors loaded-runner headroom
The three wedged-child scenarios busy-spin their worker for 1.5s while the
host waits for the start RPC; under a loaded 2-core CI runner (this branch
adds several parallel suites) the RPC lands after vi.waitFor default 1s,
failing the coverage lane three runs in a row at the same three sites. An
explicit 10s waitFor timeout (well inside each test own 15s budget) makes
the assertions load-tolerant without weakening them. Belongs upstream with
dsh-workflow-workerthread; carried here because it gates this PR.
2026-07-10 15:44:38 +08:00
kingwl
ca39fd89b0 feat(example): sandbox-acp-agent — the live composition; RFCs to implemented
The three-entry cordis.yml (dsh-sandbox-local + dsh-bash-sandbox at a
read-only default + dsh-approval) served over ACP: the first live approval
composition. Recorded snapshot scenarios pin the wire end to end —
config-options advertisement, the mode-switching arc as the suite pinned
header (both switches, the prompt-section delta, one changed-by-the-user
notice per knob, a confined write landing under the switched mode), and
both escalation branches over scripted permissionAnswers (a grant runs
confined under workspace-write; a rejection executes nothing and pins the
fail-closed text). The with-key escalation e2e drives a real model +
real runner + the real bridge answerer, world-verified; ci.yml snapshot
lane and e2e.yml install bubblewrap so the confined replays actually
execute.

Both RFCs move to implemented/ (Decision/Consequences form, deferred
phases tracked in their own sections), with every cross-reference flipped.
2026-07-10 15:44:38 +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
0e49615a3d feat(tool-bash): sandbox escalation — one approved wider retry after a denial
The tool gate advertises sandbox_permissions (an enum of exactly the modes
STRICTLY WIDER than the mounted executor default — the schema makes a
non-widening request inexpressible) plus a required justification, exactly
when ctx.bash.sandboxMode reports a confining mode at registration:
composition truth, never a dead lever. An escalating call resolves
ctx.approval BEFORE anything executes with the audit-self-contained reason
"escalate sandbox to <mode>: <justification>"; allowed-once stamps the
granted mode onto that one bash request (the seam-level per-call override),
while rejected / cancelled / unavailable and the no-service / no-agent
paths each fail closed with their own error text and execute nothing. The
description teaches the flow only when the fields exist: retry the SAME
command once after a real denial, never preemptively; a rejected
escalation is final. No new session events: the attempt is an ordinary
tool/call, the decision is the approval audit pair, the outcome an
ordinary tool/result whose facts name the mode it ran under.
2026-07-10 15:43:28 +08:00