test: DAEMON_READERS is a hand-list with a summed floor, so an unregistered daemon reader is invisible to the generation-gate scan #129

Closed
opened 2026-09-04 20:54:35 +02:00 by buildagent · 1 comment
Member

Split out of #78. Gate hardening, not a live bug — verified 2026-09-04 that no escapee exists today.

The registry and its own doc

crates/indexer/tests/generation_build.rs:1354-1366:

/// Paths relative to `crates/indexer`. Listed rather than globbed
/// because a NEW file that reads `symbols` is a decision — it either
/// joins this list gated, or it is one of the diagnostics below — and a
/// glob would silently absorb it either way.
const DAEMON_READERS: &[&str] = &[
    "../daemon/src/local_index.rs",
    "../daemon/src/graph.rs",
    "../daemon/src/refactor.rs",
    "../daemon/src/handle.rs",
];

The doc argues the hand-list is better than a glob. It is the opposite: a glob is what makes an unregistered reader visible; the hand-list is what makes it invisible. The comment states the exact risk and then chooses it.

The gate

every_daemon_row_read_is_generation_gated, generation_build.rs:1906-1952. It loops for rel in DAEMON_READERS, accumulates sites += n, then:

assert!(
    sites >= 70,
    "only {sites} daemon row-table reads found — the scan matched almost nothing, so \
     its clean result means nothing. …"
);

83 is the census in the comment above it (47 in local_index.rs, 19 in graph.rs, 16 in refactor.rs, 1 in handle.rs); 70 is a deliberately slack floor.

Why that hides a new reader

The floor is a >= on a sum over the four registered files only. A new crates/daemon/src/whatever.rs with an ungated FROM symbols is never opened by the scan, so it contributes 0 ungated and 0 sites; the sum stays ~83 and the assertion passes. Nothing in the workspace enumerates crates/daemon/src and cross-checks it against DAEMON_READERS.

The sum also hides per-file collapse: handle.rs contributes 1 site, so it could stop being scanned entirely (renamed, split) and the sum would still clear 70.

Checked for a live escapee — there is none. Every daemon source containing FROM/JOIN on symbols|refs|imports is one of the four (local_index.rs 59 raw, graph.rs 19, refactor.rs 17, handle.rs 3; raw counts include test halves).

The backstop is off the shelf — this repo has the pattern twice

  • crates/mcp-server/tests/bounding_site_registry.rs discovers crate dirs by read_dir and walks every *.rs, with the_walk_reaches_every_crate_and_the_files_that_hid_caps as the discovery anchor (including a "the walk did not reach {anchor}" assertion).
  • crates/mcp-server/tests/reason_code_registry.rs's production_sources() does the same walk over crates/*/src, with anti-vacuity floors on how many sources were scanned.
  • The set-equality idiom is RPC_METHODS / rpc_coverage_e2e.rs, which asserts set equality between what is exercised and what production declares, rather than a floor.

So: read_dir over crates/daemon/src, collect every file whose production half matches the same six needles scan_daemon_reads uses, and assert that set equals DAEMON_READERS ∪ a registered-exception list. That turns "a new reader" from invisible into a red test naming the file. A per-file floor beside the sum would close the collapse half.

Split out of #78. Gate hardening, not a live bug — verified 2026-09-04 that **no escapee exists today**. ## The registry and its own doc `crates/indexer/tests/generation_build.rs:1354-1366`: ```rust /// Paths relative to `crates/indexer`. Listed rather than globbed /// because a NEW file that reads `symbols` is a decision — it either /// joins this list gated, or it is one of the diagnostics below — and a /// glob would silently absorb it either way. const DAEMON_READERS: &[&str] = &[ "../daemon/src/local_index.rs", "../daemon/src/graph.rs", "../daemon/src/refactor.rs", "../daemon/src/handle.rs", ]; ``` The doc argues the hand-list is *better* than a glob. It is the opposite: a glob is what makes an unregistered reader **visible**; the hand-list is what makes it invisible. The comment states the exact risk and then chooses it. ## The gate `every_daemon_row_read_is_generation_gated`, `generation_build.rs:1906-1952`. It loops `for rel in DAEMON_READERS`, accumulates `sites += n`, then: ```rust assert!( sites >= 70, "only {sites} daemon row-table reads found — the scan matched almost nothing, so \ its clean result means nothing. …" ); ``` 83 is the census in the comment above it (47 in `local_index.rs`, 19 in `graph.rs`, 16 in `refactor.rs`, 1 in `handle.rs`); 70 is a deliberately slack floor. ## Why that hides a new reader The floor is a `>=` on a **sum over the four registered files only**. A new `crates/daemon/src/whatever.rs` with an ungated `FROM symbols` is never opened by the scan, so it contributes 0 ungated *and* 0 sites; the sum stays ~83 and the assertion passes. Nothing in the workspace enumerates `crates/daemon/src` and cross-checks it against `DAEMON_READERS`. The sum also hides per-file collapse: `handle.rs` contributes 1 site, so it could stop being scanned entirely (renamed, split) and the sum would still clear 70. **Checked for a live escapee — there is none.** Every daemon source containing `FROM`/`JOIN` on `symbols|refs|imports` is one of the four (`local_index.rs` 59 raw, `graph.rs` 19, `refactor.rs` 17, `handle.rs` 3; raw counts include test halves). ## The backstop is off the shelf — this repo has the pattern twice * `crates/mcp-server/tests/bounding_site_registry.rs` discovers crate dirs by `read_dir` and walks every `*.rs`, with `the_walk_reaches_every_crate_and_the_files_that_hid_caps` as the discovery anchor (including a "the walk did not reach `{anchor}`" assertion). * `crates/mcp-server/tests/reason_code_registry.rs`'s `production_sources()` does the same walk over `crates/*/src`, with anti-vacuity floors on how many sources were scanned. * The set-equality idiom is `RPC_METHODS` / `rpc_coverage_e2e.rs`, which asserts *set equality* between what is exercised and what production declares, rather than a floor. So: `read_dir` over `crates/daemon/src`, collect every file whose production half matches the same six needles `scan_daemon_reads` uses, and assert that set **equals** `DAEMON_READERS` ∪ a registered-exception list. That turns "a new reader" from invisible into a red test naming the file. A per-file floor beside the sum would close the collapse half.
Author
Member

Triage 2026-09-06 at f6a878a: CLOSING. The hand-list is now a read_dir set equality with a per-file floor, and the four isolating mutations were run.

Verified against master and by re-running the test myself, not from a lane report.

What landed

  • the_daemon_reader_registry_names_every_daemon_source_that_reads_a_row — crates/indexer/tests/generation_build.rs:3089. It walks crates/daemon/src and asserts set equality against DAEMON_READERS ∪ DAEMON_READER_EXCEPTIONS, so a new daemon source that reads a row is a build failure rather than an invisible omission.
  • DAEMON_READER_EXCEPTIONS — generation_build.rs:3032, and it is currently empty. That matters: the gate went green on its first run with nothing waived, which is the outcome that distinguishes "the list was already right" from "the list was made right by exempting the awkward files".
  • PER_FILE_FLOOR — generation_build.rs:3093. This is the half the issue actually turned on: a summed floor lets one file's many hits cover another file's zero. A per-file floor cannot.
  • Anti-vacuity on the walk itself — scanned >= 15 at generation_build.rs:3126, so a broken read_dir fails loudly instead of passing over an empty scan. (This repo has been bitten by exactly that: a gate whose population collapsed to nothing and stayed green.)
  • The registry itself grew a fifth entry it had been missing — ../daemon/src/ref_aggregate.rs, generation_build.rs:1498-1512.
  • Four mutations are recorded as RUN at generation_build.rs:3059-3086, each with its isolating pair — RED under the new gate, GREEN under the old summed one. That pairing is what proves the new gate is the thing catching them, and it is exactly the evidence this issue asked for.

The run

$ export CARGO_INCREMENTAL=0
$ cargo test -p code-index-indexer --test generation_build -- --exact \
    the_daemon_reader_registry_names_every_daemon_source_that_reads_a_row
test the_daemon_reader_registry_names_every_daemon_source_that_reads_a_row ... ok
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 25 filtered out
EXIT=0

(run together with #128's storage test; both green)

Residual

None. The exception list is empty, so there is no waiver to keep true, and the floor is per-file rather than summed, which is the whole complaint.

🤖 Triage lane, 2026-09-06, master f6a878a

## Triage 2026-09-06 at `f6a878a`: CLOSING. The hand-list is now a `read_dir` set equality with a per-file floor, and the four isolating mutations were run. Verified against master and by re-running the test myself, not from a lane report. ### What landed - **`the_daemon_reader_registry_names_every_daemon_source_that_reads_a_row`** — `crates/indexer/tests/generation_build.rs:3089`. It walks `crates/daemon/src` and asserts **set equality** against `DAEMON_READERS` ∪ `DAEMON_READER_EXCEPTIONS`, so a new daemon source that reads a row is a build failure rather than an invisible omission. - **`DAEMON_READER_EXCEPTIONS`** — `generation_build.rs:3032`, and it is currently **empty**. That matters: the gate went green on its first run with nothing waived, which is the outcome that distinguishes "the list was already right" from "the list was made right by exempting the awkward files". - **`PER_FILE_FLOOR`** — `generation_build.rs:3093`. This is the half the issue actually turned on: a *summed* floor lets one file's many hits cover another file's zero. A per-file floor cannot. - **Anti-vacuity on the walk itself** — `scanned >= 15` at `generation_build.rs:3126`, so a broken `read_dir` fails loudly instead of passing over an empty scan. (This repo has been bitten by exactly that: a gate whose population collapsed to nothing and stayed green.) - The registry itself grew a fifth entry it had been missing — `../daemon/src/ref_aggregate.rs`, `generation_build.rs:1498-1512`. - Four mutations are recorded as RUN at `generation_build.rs:3059-3086`, **each with its isolating pair** — RED under the new gate, GREEN under the old summed one. That pairing is what proves the new gate is the thing catching them, and it is exactly the evidence this issue asked for. ### The run ``` $ export CARGO_INCREMENTAL=0 $ cargo test -p code-index-indexer --test generation_build -- --exact \ the_daemon_reader_registry_names_every_daemon_source_that_reads_a_row test the_daemon_reader_registry_names_every_daemon_source_that_reads_a_row ... ok test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 25 filtered out EXIT=0 ``` (run together with #128's storage test; both green) ### Residual None. The exception list is empty, so there is no waiver to keep true, and the floor is per-file rather than summed, which is the whole complaint. 🤖 Triage lane, 2026-09-06, master `f6a878a`
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
h-dv/code-index#129
No description provided.