Subscribe the admission work traces to the operations they assert
Failure
The two child-admission work tests fail when independent observation points record the same (&'static str, u64) type. The expected store operations remain intact, but #821's content read, decode document, decode index, and open workspace events enter the same trace.
The baseline main gate at 32a9ae569 reaches the exact counter assertions (Q:/lanes/main-gate/32a9ae569.log:2418,2425). This demonstrates the failure independently of #1013's separate workspace publication conflicts.
Change
differential::pair_of(kinds, initialize, run) filters the existing typed capture by an explicit subscription, preserving event order and payloads. Both admission tests name the operations they measure and retain their exact output, error, storage-work, and redundant-work assertions.
The review also restores all of #982's files that the initial commit accidentally reverted: stable tool aliases, provider grammar checks, native work funding, hook/approval identity checks, and provider scenarios. Those files now match the PR parent byte for byte. The final diff changes only the trace helper and its tests and the two admission captures.
Decisions
- Reuse the existing typed observer; add one named-operation pairing helper rather than another observation mechanism.
- Keep explicit allowlists for measured operations. Other typed captures retain their existing contracts.
- Preserve the existing provider naming implementation and its complete proof suite.
Guarantee
- Class: I, verification observer collision. The single
pair_ofentrypoint applies the caller's subscription to both independent captures. A different operation name cannot enter the returned trace. Production provider behavior matches the parent. - Proof:
named_subscriptions_preserve_exact_order_and_payloadsuses shrinking proptest sequences with arbitraryu64payloads and subscription subsets to compare both captures against an independently derived sequence. It covers empty traces/subscriptions, repetition, ordering, initialization outside capture, foreign event types, and unchanged results. The fixed named-kind test additionally covers absent names.negative_control_detects_missing_kind_subscriptionsends the former type-only capture through the same oracle and requires rejection; it first asserts that the capture really holds the foreignu64event, so the rejection cannot come from an empty trace. Removing the kind filter fails the property and the fixed test. Existing admission negative controls still detect redundant workspace opens and result reads. Restored #982 properties, parser fuzz/corpus, accounting tests, HTTP hook/approval tests, and provider scenarios retain their original guarantees. - Entry points:
recordfeeds the existingobserve/paircapture;pair_offilters both results. The two affected callers arelocal::children::admission::work_tests::{replay_admission_preserves_results_and_errors_with_zero_workspace_work, preparation_status_preserves_bytes_and_errors_without_loading_its_report}. Direct typed captures remain unchanged. Restored provider files are identical to the parent. No #1021 row or open gap is listed in the guarantee matrix; #982's F12 guarantee remains closed. - Gaps: none.
Validation
Validation at signed commit 729407c1e6b61a07a8925c5c5903ece5f6ea6845 (round 2 at 75b86e17d changed only the differential negative control: 15/15 differential tests, 0.00 s; windows-gnu check of acyclic-test-support passed), through Q:/lanes/bs.ps1:
| Focused suite | Passed | Wall time |
|---|---|---|
| Differential support, including shrinking properties and negative controls | 15 | 0.007 s |
| Tool-name properties, malformed batches, funding and negative controls | 20 | 0.020 s |
| HTTP hook/approval canonical identity and negative controls | 3 | 0.018 s |
Provider scenarios (E2E_FILTER=providers/) and runner validation | 2 | 0.505 s |
| Admission work traces, including redundant-work negative controls | 2 | 3.023 s |
42 passed, zero failed. Every suite is below 10 seconds. Both admission tests pass without #1013.
One Linux test build: 892.136 s. Windows GNU --lib --tests cross-check for acyclic-test-support, acyclic-harness-providers, and acyclic-harness: passed, 353.303 s. Initial compile-slot queue: 372 s. The review runner rejected flags before invoking the admission suite; that suite then ran directly from the already-built binary without recompilation.
Feature set (canonical aliases are absent on this base; reuse #982's native proof closure):
acyclic-harness/filesystem-local,acyclic-harness/native-execution,acyclic-harness/terminal,acyclic-harness/mcp-http,acyclic-harness/test-support,acyclic-harness/grpc
Build command: cargo test --locked -p acyclic-test-support -p acyclic-harness-providers -p acyclic-harness --lib --test e2e --features <set> --no-run --message-format=json. Run the resulting binaries with the table's filters (differential::, tool_name, hooks::mcp_identity_tests::, scenarios, and local::children::admission::work_tests::).
Windows command: cargo check --locked -p acyclic-test-support -p acyclic-harness-providers -p acyclic-harness --lib --tests --features <set> --target x86_64-pc-windows-gnu.
Signature verified; rustfmt and git diff --check passed. The provider restoration is byte-identical to the PR parent, verified with git diff --exit-code 32a9ae569 HEAD -- rust/crates/harness-providers rust/crates/harness/src/hooks rust/crates/harness/src/runtime/tools.rs rust/crates/harness/tests.
Why the gate missed it
The observer additions shared the store-operation event type. Earlier fixture conflicts could stop the tests before the counter assertions. The current main gate does reach and report those assertions. This belongs to the focused admission tests and shared test-support property suite; it requires no new GitHub-hosted Rust job.