Keep the approval-identity test seam beside its only reader

Merged
VA
2d ago
+18-3

Summary

Main's (7c05f9cdc) harness unit tests don't compile under --features filesystem, the plain native build without hooks. The error is E0433: cannot find hooks in crate, at runtime/tools.rs:217.

  • Breaking commit: #982 (32a9ae569). It added an approval-identity negative-control switch to crate::hooks::mcp_identity_tests. It also read that switch from runtime::tools::tool_approval_binding under cfg(all(test, not(wasm32))). hooks only exists with feature = "hooks", so every test build without hooks stopped compiling.
  • Why the gate missed it: every native harness test suite in the gate runs with --all-features, which always turns hooks on. No gate step compiled the unit tests with an optional native feature switched off.

Fix

  • The SUBSTITUTE_APPROVAL_NAME seam now lives next to its only reader, in runtime/tools.rs, under the same cfg as that reader. It therefore exists in every build that compiles the read.
  • hooks::mcp_identity_tests refers to it as crate::runtime::SUBSTITUTE_APPROVAL_NAME.
  • The gate lane now runs cargo check --locked -p acyclic-harness --features filesystem --lib --tests.
  • test-plan-qualification.mjs asserts that the gate branch keeps that step.

Guarantee

  • Class: a test-only seam whose owner sits behind a narrower cfg than its reader. The result is unit-test builds that fail to compile under feature sets the all-features gate never builds.
  • Structural fix: the seam is defined under exactly the cfg of its reader, so it can't be missing where it's read. The gate now builds the unit-test closure without the optional native features. With only filesystem on, the step catches any future seam that crosses the hooks, MCP, search, objects, machines, grpc or tui feature gates, not just this one.
  • Exhaustive proof:
    • Under --features filesystem --lib --tests, this branch compiles (bb BUILD_SLOT_TREE e6d5c6fdb on 7c05f9cdc, rc=0).
    • Negative control: the same command on unfixed main 7c05f9cdc fails with E0433 cannot find hooks in crate at runtime/tools.rs:217 (rc=101).
    • Under --all-features, hooks::mcp_identity_tests passes, including negative_control_detects_approval_identity_substitution. So the seam still drives the approval-identity mutant through the moved switch.
    • CI-plan negative control: dropping --tests from the new gate step makes node scripts/test-plan-qualification.mjs fail. Restoring it passes 23/23.
  • Entry points: there was one reader of the seam, tool_approval_binding, and one writer, negative_control_detects_approval_identity_substitution. Both changed. SUBSTITUTE_HOOK_NAME has its reader and owner both under hooks, so it is unaffected.
  • Gaps: none.

Gate once

I ran cargo test --locked -p acyclic-harness -p acyclic-harness-providers --all-features --no-fail-fast once on head 321d201ad, which is main 7c05f9cdc plus this change. Then I compared it against the newest main gate, ws-4b9c84541:

  • This branch: 19 failures.
  • Main gate: 70 failures.
  • Failures not in the main list: two. Both are known races on main that the children lane owns, and neither touches the moved seam:
    • work_tests::preparation_status_preserves_bytes_and_errors_without_loading_its_report fails with Conflict("workspace generation changed"). This is the #821 directory-record batch-observation race; the fix is in flight on hf/main-green-kind-only-lookups.
    • work_tests::replay_admission_preserves_results_and_errors_with_zero_workspace_work fails because concurrent tests' work kinds leak into the trace. #1021 covers this.

Separately observed, not in scope

The plain --features filesystem lib (non-test) build has 10 pre-existing dead-code warnings, for example in task_volume/child_queries.rs:5, task_volume/files.rs:86 and durable_host/observations.rs:7. That's why the new gate step doesn't use -Dwarnings. I'm reporting it to the coordinator as a separate root cause.

🤖 Generated with Claude Code