Consolidate external hook clients on task volume requests

Draft
VA
1d ago
+29494-52504

Problem

Codex, Claude Code and Pi hooks had separate control-plane, writeback, transport and execution owners. They must use the shared harness task-file handler and the surviving per-user SDK provider owner.

The latest review found that cancellation after dispatch but before native preparation could escape as Error::Cancelled, leaving the original invocation and Pi's cancellation acknowledgement unpublished.

Signed pushed head: 6c9aa7c801fef198b9988588340b17b7ef114266. The cancellation fix is befcae8cd3f309346d938e1fb896eb943efcf006; the main merge and private-binding adaptations are now pushed after passing the mandatory Windows compile proof. This PR remains draft. Remaining: selected project-source binding and full retained host qualification.

Design

Hooks append immutable authenticated request files through the platform Streams client and follow result files. One per-user SDK provider owner opens LocalHarness per canonical workspace. The durable runtime owns authority, task state, cancellation and publication; shutdown drains effects and mounts before releasing ownership.

  • Shell/git dispatch receives the fenced execution context. Native children receive isolated project/private bindings and their staged session seed.
  • Fork and stop require the same immutable parent/label/native-session binding. Definite typed request rejections publish fenced failures and keep consuming; ownership or publication uncertainty fails closed.
  • Native launches use shared child preparation and durable native-process custody. One completion boundary settles the command session and wakes followers.
  • Selected native context is chunk files plus a manifest. The source Head and parent fence condition the pinning transaction. Provenance, complete exchanges and accepted cuts survive retries.
  • Additive native/MCP tools execute in their host and record authenticated calls/results. The harness executes its own catalog. Pi forwards abort as a task cancellation file and awaits original execution settlement.

Decisions

There is no standalone HarnessService, replacement harness gateway/socket protocol, actor WebSocket or channel. The retained multi-client owner is the existing platform Streams/fs provider binding required by review. Hooks never open LocalHarness. State and requests remain files observed through push follows.

Native preparation cancellation now shares RunTool's awaited settlement boundary. It converts only typed Cancelled after an authenticated cancellation follow, execution drain and partial-admission reconciliation. Other errors remain unresolved. The preparation worker returns a cancelled command outcome and retires its own original lease through its existing terminal workflow. Cleanup never adopts an observed reservation; an outstanding executor stays indeterminate. Original result and cancellation acknowledgement use the existing fenced publications.

This fixes the class of preparation errors bypassing both result publications. Earlier coverage cancelled before dispatch and missed the later cuts. New shared-entrypoint regressions pause the shipping path at budget construction, queued preparation, the running preparation worker and final child admission. The exhaustive model calls the actual budget constructor and production settlement/reconciliation helpers, requires all three modeled cancellation cuts, and detects escaping cancellation, omitted reconciliation and a stranded worker lease. The physical kill/reap model and broken control remain.

Main was merged because GitHub reported a conflict. The deleted Pi runtime stays deleted; main's constructor change is retained in the shared LocalHarness runtime. Native transcript staging uses the executing task's validated private writer through main's new API. The command-only external-hooks fixture supplies the explicit absent root-private binding.

The Git facade reports eligible non-directory files. The former five-file diff was a reserved-namespace bug; the common policy now covers diff/capture/commit/publication. The native regression still requires exactly two files. Pi does not forward a second completion for harness-owned results; additive host results still receive exactly one completion, checked with shrinking differential work assertions and a broken control.

No stack/deadline limits were raised. No retained behavioural assertions were deleted. The installed selected-Pi child/grandchild scenario now passes its original eight-second deadline. Full retained qualification remains open.

Deletions

Deleted ConcurrentServiceControl, the old plugin control plane/service/protocol and duplicated Pi owners. Manifests and shims call the shared client; Pi is 188 lines. Against merged main: +29,339/-52,504, net -23,165 lines. Review confirmed plugin/src shrank 89.3%.

Tests

All portable work and Windows GNU compile proof use Q:/lanes/bs.ps1, stable 1.98.1, one retained feature closure/target and source-matching binaries. Models use instrumented production synchronization or production future combinators; no Tokio dependency lock is represented as Loom-instrumented.

Pushed head ca95b97f9, bb2 job1792311137683-291599: 114 focused tests passed, no failures.

Focused suiteResultRuntime
External executor, models and broken controls78 passed4.04s
Local requests/cancellation/recovery8 passed2.14s
Native child isolation/admission/recovery3 passed3.09s
Owner-binding properties3 passed0.29s
External command-session integration7 passed1.89s
Selected task-file native integration1 passed2.60s
Pinned Pi hooks/activation/abort/owner/bootstrap/installation14 passed6.81s
Windows fs/harness/plugin/stream GNU check --lib --testspassed5m47s cold build

The combined Linux test build took 15m29s on the cold bb2 target. Every runtime suite finished under 10s. Model negative-control panics were expected and their tests passed. No limits were raised.

The latest reviewer at a44db8bf1 separately confirmed 104 focused tests, including selected task-file integration, native isolation/recovery, Pi activation/abort/installation/owner, child identity, fresh native launch and compaction/reopen; each suite was under 10s. These remain prior-head evidence. After main merged, the installed selected-Pi regression exposed an obsolete integer-array upload encoding. Commit d2d7418a6 uses the canonical text/base64 file codec; its shrinking UTF-8-boundary property and two corpus seeds cover split codepoints. Pi hook tests passed 9/9 in 0.797s; four-root Windows GNU proof passed in 3.59s and the embedded-plugin build took 9.35s.

Existing production checks include source/owner atomic publication models with negative controls, custody settlement/wakeup models, shrinking ownership/substitution and reserved-metadata properties, the checked external-hooks fuzz corpus, and future-size assertions below 16KiB.

At 6c9aa7c80, the unchanged source-bound native CLI and the pinned Pi RPC CLI passed fresh native launch 2.59s and selected child/grandchild launch 7.55s; the complete suite took 8.65s (bb2 job1792313618487-599669). The operation still has an eight-second deadline, all ancestry/context/isolation/custody assertions remain, and shutdown still requires zero owned mounts or processes. RPC get_state establishes actual CLI readiness before the operation; every scripted model step must run in that original process. Pi abort/drain and actual CLI exit precede provider shutdown. No Rust changed in this test-fixture commit; the four-crate Windows proof above applies unchanged.

Live steps

  1. Cancellation review fix and both Pi qualification corrections are signed and pushed; zero unresolved review threads. Current focused gates have finished.
  2. Selected project-source binding and retained Pi context/service/mail/fresh/pages/builtin/recursive assertions still need migration through shared task files. Native caller-context pinning and descendant inheritance passing does not close foreign-project sourcing or full host qualification.
  3. Finish real Codex/Claude/retained Pi qualification. The installed selected native-grandchild case passes the unchanged eight-second deadline; no raised deadline or restored duplicate owner.
  4. macOS native/performance validation is pending disk: ivar has 1.2GiB free, below the user's 10GB threshold. This lane created no Mac target/source/tar files to remove. Use exactly CARGO_TARGET_DIR=~/mac-target/gc-service with sccache when room permits; remove the lane target after the run under the consolidated rule.
  5. Hosted execution still needs platform compute/secret bindings. No new PR or series is being opened; the coordinator merges this PR.