Commit Graph

25 Commits

Author SHA1 Message Date
Tianyi Cui
d709a8a1a4 test(acp): await cancelled tool updates 2026-07-19 13:09:16 +08:00
Tianyi Cui
edaaa50fe3 test(acp): snapshot cancelled queued tool calls 2026-07-19 13:03:31 +08:00
Tianyi Cui
e846a115f2 test(acp-snapshot): cover pre-spawn launch failure 2026-07-18 13:51:44 +08:00
Tianyi Cui
9e1975b080 Merge branch 'codex/simp-snapshot-fixture-inventory' into codex/simp-shared-acp-test-launcher
# Conflicts:
#	examples/acp-agent/tests/acp.e2e.ts
#	examples/acp-agent/tests/escalation.e2e.ts
#	examples/acp-agent/tests/hooks.e2e.ts
#	packages/support/acp-snapshot/src/harness.ts
2026-07-18 13:47:53 +08:00
imccyu
de19c6ca08 fix(examples): run coverage subprocesses from built libs 2026-07-18 12:19:48 +08:00
Tianyi Cui
df2432cae2 Merge branch 'codex/simp-snapshot-fixture-inventory' into codex/simp-shared-acp-test-launcher
# Conflicts:
#	examples/acp-agent/tests/escalation.e2e.ts
#	packages/support/README.md
#	packages/support/acp-snapshot/README.md
#	packages/support/acp-snapshot/src/harness.ts
#	packages/support/acp-snapshot/tests/harness.spec.ts
2026-07-18 11:58:15 +08:00
imccyu
5039c4ae40 fix(snapshot): include agent stderr in failures 2026-07-15 23:57:44 +08:00
Tianyi Cui
66c2996b36 Merge branch 'codex/simp-snapshot-fixture-inventory' into codex/simp-shared-acp-test-launcher
# Conflicts:
#	docs/rfc/implemented/testing/2026-07-08-shared-acp-snapshot-package.md
#	examples/acp-agent/tests/acp.e2e.ts
#	examples/acp-agent/tests/escalation.e2e.ts
#	packages/support/acp-snapshot/README.md
#	packages/support/acp-snapshot/src/harness.ts
#	packages/support/acp-snapshot/src/index.ts
2026-07-14 18:40:49 +08:00
Tianyi Cui
2027c70a17 fix: drain failed ACP launches 2026-07-14 12:38:32 +08:00
Tianyi Cui
3e2ba3f557 fix: stop ACP teardown when fallback kill fails 2026-07-14 10:13:05 +08:00
Tianyi Cui
a8c0e8a03c test: cover successful ACP cleanup failure 2026-07-14 09:55:15 +08:00
Tianyi Cui
6b59b6050e fix: preserve ACP scenario cleanup failures 2026-07-14 09:43:12 +08:00
Tianyi Cui
e784e4dce5 fix: await ACP client callbacks during shutdown 2026-07-14 09:12:32 +08:00
Tianyi Cui
0b492e6e62 fix: drain ACP test launcher streams 2026-07-14 07:22:22 +08:00
Tianyi Cui
e2a5a160d3 fix: settle ACP update waiters on shutdown 2026-07-14 07:00:10 +08:00
Tianyi Cui
140d32681e fix: make ACP test teardown failure-safe 2026-07-14 06:33:22 +08:00
Tianyi Cui
60ce23d77c fix: surface ACP launcher spawn failures 2026-07-14 06:07:37 +08:00
Tianyi Cui
9028c9b63b fix: contain ACP update predicate failures 2026-07-14 05:35:34 +08:00
Tianyi Cui
0e7d539bbc refactor: share the ACP test launcher 2026-07-14 00:18:00 +08:00
Tianyi Cui
148046b9c8 docs: rebalance prose cleanup and add trimming skill 2026-07-13 23:27:00 +08:00
Tianyi Cui
75838e10b5 docs: trim generated prose 2026-07-12 03:36:43 +08:00
kingwl
80d8726601 feat(acp): the bridge approval answerer + scripted permission answers
The ACP bridge registers the first real approval answerer: an ask for an
agent it owns becomes session/request_permission attached to the already-
streamed tool call (one-shot allow_once/reject_once only), outcomes map
conservatively (unknown optionId never grants, client cancel → cancelled),
and foreign or call-less requests delegate down the waterfall. The snapshot
harness accepts scripted permissionAnswers (FIFO; an unscripted prompt
answers cancelled, fail closed) so recorded scenarios can drive the wire
keylessly.
2026-07-10 15:43:02 +08:00
kingwl
1097fa3507 fix review finding: an impossible scripted permission click rejects the run
A client-callback throw only becomes a JSON-RPC error RESPONSE to the
agent's session/request_permission — runScenario itself kept going, so a
tolerant agent could treat the error as a denial and the scenario would
pass, or worse, record: the impossible click baked into fixture and
golden, green on every replay. The mismatch is now captured as a harness
error while the agent is answered plain cancelled (a well-defined path
it cannot reinterpret), and the step loop rejects the run on it as soon
as the in-flight step settles. The spec asserts the rejection instead of
the agent-side error echo.
2026-07-08 02:46:23 +08:00
kingwl
b0144eaccd feat(acp-snapshot): scripted permission answers in the harness client
InputScript gains an optional permissionAnswers queue, consumed FIFO by
the harness's requestPermission handler. Each entry selects by option
KIND (allow_once, reject_once, …): option ids are agent-issued randoms a
committed script cannot know, while kinds are the ACP-stable vocabulary,
so the client maps kind → the offered optionId at answer time. An absent
or exhausted queue answers cancelled — existing scenarios and goldens
are untouched — and a scripted kind the request never offered throws,
surfacing as a JSON-RPC error on the permission request: the scenario
scripted an impossible click.

This is what lets an approval-flow suite (the sandbox composition) drive
allow/reject round-trips deterministically from input.json, per the
shared-acp-snapshot RFC.
2026-07-08 02:38:25 +08:00
kingwl
610c8e3709 test(acp-snapshot): fake ACP bin + unit specs to per-file 100% coverage
A scripted fake ACP agent bin (tests/fixtures/fake-acp-agent.ts) speaks
real newline JSON-RPC through the REAL runScenario spawn path (tsx
loader, temp cwd, env plumbing); every behavior — prompt outcome,
session/new rejection, persisted logs, filesystem noise — comes from a
behavior.json beside the fixture, so specs script whole subprocess runs
from data. harness.spec.ts drives every step op, both expect-error arms,
the permission-stub default, env forwarding, workspace seeding, and the
harvest ordering/noise/fallback branches. suite.spec.ts runs the factory
for real at collection time: a replay suite over committed synthetic
fixtures and a record suite over a temp copy (write-back never touches
the committed tree; ACP_SNAPSHOT_SPEC_BOOTSTRAP=1 re-bootstraps it),
plus direct cases for the exported pure helpers. The suite factory's
pure helpers (childFixturePaths, fixtureContext, normalizedHeaders,
headerDeltaCount) are exported for those direct specs.

Two branches carry justified v8 ignores, both structurally unreachable:
the waiter in-bounds guard (noUncheckedIndexedAccess) and waitForExit's
already-exited race guard (both call sites sit one synchronous frame
after stdin.end()/kill()). The fake bin substitutes the session/new cwd,
not process.cwd(), into scripted logs — the realpath difference
(/private on darwin) is exactly what the real bin's header carries.

packages/support/acp-snapshot/src is at 100% statements, branches,
functions, and lines under the per-file gate.
2026-07-08 02:38:25 +08:00