doctor cannot prove never on a project with packages installed — 35/35 land in NOT CLASSIFIED where index_coverage proves them permanent #218

Closed
opened 2026-09-07 18:12:14 +02:00 by buildagent · 1 comment
Member

Follow-up to #210, reported by the lane that fixed it — against its own fix. Filed because the fix is weaker on the reporting repository than #210's text implies, and the reason is structural.

What #210 achieved, and where it stops

Before, on this repo:

[ WARN ] index freshness  782 indexed file(s); 0 drifted, 0 gone from disk,
                          35 on disk with no row: fuzz/abi.dict (no row), … (+30 more)

After:

[  OK  ] index freshness  … 0 coverable with no row; 0 provably never indexable;
                          35 NOT CLASSIFIED (packages_installed_not_consulted x35)

Both harms named in #210 are gone: no false staleness claim, the permanent WARN is cleared, and real drift would now show up in the coverable with no row figure instead of being buried. The two surfaces no longer contradict each other — one proves never, the other declines to guess.

But the useful half is missing. index_coverage proves those same 35 paths are never / ineligible_extension / hint: "Permanent". doctor can only say it did not classify them.

Why, precisely

~/.code-index/approvals holds an approval for this project, so packages::any_installed(root) is true. The completeness gate that #210 correctly adopted — the same one Eligibility::from_builtins applies — then says a builtin refusal proves nothing, because a package could claim .wasm.

That gate is right. A package can only ADD claims, and Manifest::validate refuses at discovery any package whose claims intersect a compiled-in language's — so a builtin Code verdict is sound without consulting the package set, while a builtin Ineligible is a proof of permanence only when no package could claim anything here.

index_coverage escapes this because it asks the daemon and gets eligibility_source: "project" — the project's real extractor set. doctor is a synchronous CLI with no tokio runtime and no IndexAccess, so it cannot ask, and correctly degrades rather than guessing.

So on any project with at least one package installed, doctor's never-indexable population is permanently empty and everything lands in NOT CLASSIFIED. On a package-free project the full three-way split appears as designed.

The fix

Give doctor the path_claims RPC — the same call index_coverage uses to learn the project's claimed extensions — so it can consult the active generation instead of falling back to builtins.

The cost is real and is why the #210 lane did not do it: it turns a synchronous check into an asynchronous one, which is a structural change to doctor, well outside the scope of the issue it was fixing. That was the right call; it belongs here.

Requirements:

  • When the daemon is reachable, doctor must reach the same verdict index_coverage does for the same path, and the NOT CLASSIFIED population must go to zero on this repository.
  • When it is not reachable, the current honest degradation must remain exactly as it is. A doctor that guesses when the daemon is down is worse than one that declines.
  • eligibility_source should be reported so the reader can tell which of the two answered.

Mutations

  • Point doctor at builtins while the daemon is up → the "matches index_coverage" assertion must go RED.
  • Make the daemon-unreachable path fall back to builtins and claim never → the honest-degradation assertion must go RED. This is the important one: it is the failure the current code avoids and the fix could reintroduce.
  • Kill the daemon mid-check → the reply must degrade, not error or hang.

The same lane found an adjacent gap in Eligibility::from_builtins itself, filed separately: PathEligibility::Ineligible("auto-generated (plugin-excluded)") is package-independent by construction and is degraded anyway. Fixing that would strengthen both doctor and index_coverage without any RPC.

Follow-up to #210, reported by the lane that fixed it — against its own fix. Filed because the fix is **weaker on the reporting repository than #210's text implies, and the reason is structural**. ## What #210 achieved, and where it stops Before, on this repo: ``` [ WARN ] index freshness 782 indexed file(s); 0 drifted, 0 gone from disk, 35 on disk with no row: fuzz/abi.dict (no row), … (+30 more) ``` After: ``` [ OK ] index freshness … 0 coverable with no row; 0 provably never indexable; 35 NOT CLASSIFIED (packages_installed_not_consulted x35) ``` Both harms named in #210 are gone: no false staleness claim, the permanent WARN is cleared, and real drift would now show up in the `coverable with no row` figure instead of being buried. The two surfaces no longer contradict each other — one proves `never`, the other declines to guess. But the useful half is missing. `index_coverage` proves those same 35 paths are `never` / `ineligible_extension` / `hint: "Permanent"`. `doctor` can only say it did not classify them. ## Why, precisely `~/.code-index/approvals` holds an approval for this project, so `packages::any_installed(root)` is true. The completeness gate that #210 correctly adopted — the same one `Eligibility::from_builtins` applies — then says a builtin refusal proves nothing, because a package *could* claim `.wasm`. That gate is right. A package can only ADD claims, and `Manifest::validate` refuses at discovery any package whose claims intersect a compiled-in language's — so a builtin `Code` verdict is sound without consulting the package set, while a builtin `Ineligible` is a proof of permanence **only when no package could claim anything here**. `index_coverage` escapes this because it asks the **daemon** and gets `eligibility_source: "project"` — the project's real extractor set. `doctor` is a synchronous CLI with no tokio runtime and no `IndexAccess`, so it cannot ask, and correctly degrades rather than guessing. So on any project with at least one package installed, `doctor`'s never-indexable population is permanently empty and everything lands in NOT CLASSIFIED. On a package-free project the full three-way split appears as designed. ## The fix Give `doctor` the `path_claims` RPC — the same call `index_coverage` uses to learn the project's claimed extensions — so it can consult the active generation instead of falling back to builtins. The cost is real and is why the #210 lane did not do it: it turns a synchronous check into an asynchronous one, which is a structural change to `doctor`, well outside the scope of the issue it was fixing. That was the right call; it belongs here. Requirements: * When the daemon is reachable, `doctor` must reach the same verdict `index_coverage` does for the same path, and the NOT CLASSIFIED population must go to zero on this repository. * When it is **not** reachable, the current honest degradation must remain exactly as it is. A `doctor` that guesses when the daemon is down is worse than one that declines. * `eligibility_source` should be reported so the reader can tell which of the two answered. ## Mutations * Point `doctor` at builtins while the daemon is up → the "matches `index_coverage`" assertion must go RED. * Make the daemon-unreachable path fall back to builtins **and claim `never`** → the honest-degradation assertion must go RED. This is the important one: it is the failure the current code avoids and the fix could reintroduce. * Kill the daemon mid-check → the reply must degrade, not error or hang. ## Related, and NOT fixed The same lane found an adjacent gap in `Eligibility::from_builtins` itself, filed separately: `PathEligibility::Ineligible("auto-generated (plugin-excluded)")` is package-independent **by construction** and is degraded anyway. Fixing that would strengthen both `doctor` and `index_coverage` without any RPC.
Author
Member

Fixed in f28df60 — "doctor proves what index_coverage proves, by asking the project" — on master, shipping in v0.27.0.

doctor could not prove never on a project with packages installed, so 35 of 35 files landed in NOT CLASSIFIED. It now asks the project's own extractor set rather than a built-in list, which is what index_coverage already did — so the two surfaces give the same verdict on the same file, and the answer carries eligibility_source=project.

Closing on merge.

Fixed in `f28df60` — *"`doctor` proves what `index_coverage` proves, by asking the project"* — on `master`, shipping in v0.27.0. `doctor` could not prove `never` on a project with packages installed, so 35 of 35 files landed in NOT CLASSIFIED. It now asks the project's own extractor set rather than a built-in list, which is what `index_coverage` already did — so the two surfaces give the same verdict on the same file, and the answer carries `eligibility_source=project`. Closing on merge.
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#218
No description provided.