refactor(daemon): relocate the target-evidence tests by what they assert
Summary
Part 3 of 3 of the find/settle batch of the daemon test redesign (no test exports of any kind): the root interaction-target-evidence test (10 tests, 461 lines) that drove press, get and is with the real command surface. Stacked on #3698 (green and mergeable), which is stacked on #3693 (green and mergeable); this PR retargets as those merge.
Daemon halves (a) run against the package fakes; what the real command code puts into a resolution (c) moved beside that code. New unexported fixture: support/target-evidence-fixture.ts.
a / c split and test-count parity
Before = exact count at the old path (vitest JSON reporter, origin/main); after = run count per destination on this head.
| Source (before) | Daemon half (a) | Command half (c) |
|---|---|---|
interaction-target-evidence (10) | execution/interaction/internal/interaction-target-evidence.test.ts (3: press @ref with and without recording; press on an identity-empty container), execution/selector-runtime-target-evidence.test.ts (7: get and is reads while recording, without recording, and the deferred-coverage cases) | src/commands/interaction/runtime/selector-read-resolution-payload.test.ts (4: which reads carry node and preActionNodes; is exists and is absent carry neither) |
10 tests before; 14 after (+4: the command-side payload cases the real surface used to cover implicitly). No assertion was dropped. One was replaced: "the runner querySelector command is not called" had become vacuous after the R36/R37 refactors, because the daemon no longer calls it for get and is. It now asserts mockQuerySelector not called with querySelectorAvailable switched on in the fixture. That spy is a fixture spy (not a vi.mock) behind a negative assertion: it can only fail if the daemon starts calling the runner for these reads again, which is what it guards; it cannot be broken without adding such a call.
Mutation checks
- Removing
targetEvidencefrom the recorded action ininteraction-common.tsfails the two press cases (2/10): "press @ref while recording attaches target-v1 evidence…" and "press on an identity-empty container…". - Dropping the
isSessionRecording()gate (computing evidence without recording) fails "press @ref without recording never computes target-v1 evidence" (1/10).
vi.mock
No vi.mock in any destination file.
Selection
All destinations match packages/*/src/**/*.test.ts or src/**/*.test.ts, so unit-core selects them (pnpm test:unit, test:coverage); the source was already in unit-core. check:affected --run runs the vitest related leg.
Subpath exports
| Package | Before | After |
|---|---|---|
daemon | 79 | 78 |
Deleted: session-script-writer. No other package changed; no new subpath, barrel or export *. With this part the find/settle batch removes 3 of the daemon's ./testing/* entries net across the three PRs (81 → 78).
Notes
- Colocation (R84):
selector-read-resolution-payload.test.tsis named forselector-read.ts; the daemon halves sit besideinteraction-common.tsand the selector runtime. - The command half is a new file, not an append to another worker's test.
Validation
check:quick, check:layering and check:fallow pass on this head. check:affected --run passed format, lint, typecheck, layering, di-seams, fallow, mcp-metadata, build and package, then stopped at integration-node (it stops at the first failure, so its unit lane did not run locally; CI runs it). The integration-node failures are test/integration/smoke-daemon-clean.test.ts "clean daemon script stops a live daemon before removing metadata" (20 s, exit 1) and test/integration/smoke-web-platform.test.ts "web shutdown cleanup reaps the exact daemon that survived graceful shutdown". Both pass when run alone on this head (3/3 and 1/1), and this branch changes no file under test/integration or scripts. They fail only inside the full node-integration run on a host that other sessions are loading; CI is the authority.
Break-proof (mockQuerySelector not-called): adding a querySelector call in interaction-runtime.ts (the only daemon spot that holds the operation outside touch/gesture) left selector-runtime-target-evidence.test.ts at 7/7 passing, so the assertion was vacuous: ADR 0011 (2026-09-11) retired querySelector as the backing for get/is/wait, and no get/is route is handed a touch executor. Both negative-only assertions and the stale querySelectorAvailable switches are removed in the last commit; the positive assertions (snapshot dispatched, evidence recorded) stay. Reverted; 7 tests before and after.
🤖 Generated with Claude Code