plugin enable indexes nothing on a newly-claimed extension, and package_fixture::XAML_BRIDGES holds a bridge key the production door refuses while its doc claims the guides show it #207

Closed
opened 2026-09-07 11:32:27 +02:00 by buildagent · 1 comment
Member

Two findings from the #45 lane, both measured, both minor today and both the kind that bite the next person rather than this one.


1. An activation build DEFERS a claimed path with no files row

Measured on the Ruby leg of the package ladder:

reparsed: 152    deferred: 152    contributions: 0

Every newly-claimed .rbx was deferred, because no builtin claims that extension, so none had ever been walked into files. The activation build re-routes existing files rows; it does not discover paths the walker never admitted.

So plugin enable alone indexes nothing on a newly-claimed extension. The daemon's next pass does it.

XAML does not show this, which is why it has gone unnoticed: .xaml is already a text-indexed extension, so its files row existed and the build re-routed it in place. The failure needs an extension that no builtin claims.

The disclosure gap: plugin enable's report does print deferred=N — but as a bare integer beside four others, with no sentence saying a further pass is owed. On the Ruby shape that integer is the entire activation, and an operator reading "deferred=152" beside "reparsed=152" has no way to know the enable did nothing yet.

Not a correctness defect — the daemon converges. A disclosure-quality gap, and the shape this project usually closes: a number that is the whole story rendered as one of five.


2. package_fixture::XAML_BRIDGES carries a key the production door refuses, under a doc comment that is false

The fixture holds:

"xaml:type->csharp:class"

approval::validate_grant matches on approval::bridge_key, whose source language is the wire id, so the accepted spelling is:

"de.h-dv.xaml/xaml:type->csharp:class"

Measured: the unqualified pair is refused with capability_not_granted, naming both declared keys.

And the fixture's doc comment claims "_prdoc/guides/80-operator-recovery.md and the package README both show an operator typing exactly these". Both of those documents use the qualified form. The comment asserts a correspondence that does not exist — the in-tree-prose-contradicting-the-tree class this project keeps closing.

Currently harmless, and the reason is worth stating so nobody over-reacts: live_host_xaml writes Approval.bridges directly, and its only two callers (plugin_path_cost, signature_gate) do not depend on the bridge grant taking effect. The next test that uses this fixture for a bridge assertion gets a silently empty grant and will look like a resolver bug.


What must NOT be done

  • (1) Do not "fix" the deferral by making plugin enable walk the tree. The deferral is correct — the walker owns discovery, and the enable path deliberately does not. What is missing is the sentence, not the work.
  • (1) Do not close it by pointing at deferred=N. That integer is present today and did not convey it; the finding is precisely that it reads as one metric among five.
  • (2) Do not change bridge_key to accept the unqualified form. The qualification is what stops one package's grant matching another's language id. Fix the fixture, not the door.
  • (2) Do not just delete the doc comment. It should say what is true — that the guides use the qualified form and so must this fixture.

#75 and #80 C3 (the inert/activation ladder these were found under), #45 (the lane), and the sibling finding filed alongside about gate 6 refusing the deliberate zero-grant activation.

Reported by the #45 lane, 2026-09-07.

Two findings from the #45 lane, both measured, both minor today and both the kind that bite the next person rather than this one. --- ## 1. An activation build DEFERS a claimed path with no `files` row Measured on the Ruby leg of the package ladder: ``` reparsed: 152 deferred: 152 contributions: 0 ``` Every newly-claimed `.rbx` was deferred, because **no builtin claims that extension, so none had ever been walked into `files`**. The activation build re-routes existing `files` rows; it does not discover paths the walker never admitted. So **`plugin enable` alone indexes nothing on a newly-claimed extension.** The daemon's next pass does it. XAML does not show this, which is why it has gone unnoticed: `.xaml` is already a text-indexed extension, so its `files` row existed and the build re-routed it in place. The failure needs an extension that *no* builtin claims. **The disclosure gap:** `plugin enable`'s report does print `deferred=N` — but as a bare integer beside four others, with no sentence saying a further pass is owed. On the Ruby shape that integer **is the entire activation**, and an operator reading "deferred=152" beside "reparsed=152" has no way to know the enable did nothing yet. Not a correctness defect — the daemon converges. A disclosure-quality gap, and the shape this project usually closes: a number that is the whole story rendered as one of five. --- ## 2. `package_fixture::XAML_BRIDGES` carries a key the production door refuses, under a doc comment that is false The fixture holds: ``` "xaml:type->csharp:class" ``` `approval::validate_grant` matches on `approval::bridge_key`, whose source language is the **wire id**, so the accepted spelling is: ``` "de.h-dv.xaml/xaml:type->csharp:class" ``` **Measured:** the unqualified pair is refused with `capability_not_granted`, naming both declared keys. And the fixture's doc comment claims *"`_prdoc/guides/80-operator-recovery.md` and the package README both show an operator typing exactly these"*. **Both of those documents use the qualified form.** The comment asserts a correspondence that does not exist — the in-tree-prose-contradicting-the-tree class this project keeps closing. **Currently harmless**, and the reason is worth stating so nobody over-reacts: `live_host_xaml` writes `Approval.bridges` directly, and its only two callers (`plugin_path_cost`, `signature_gate`) do not depend on the bridge grant taking effect. **The next test that uses this fixture for a bridge assertion gets a silently empty grant** and will look like a resolver bug. --- ## What must NOT be done - **(1) Do not "fix" the deferral by making `plugin enable` walk the tree.** The deferral is correct — the walker owns discovery, and the enable path deliberately does not. What is missing is the sentence, not the work. - **(1) Do not close it by pointing at `deferred=N`.** That integer is present today and did not convey it; the finding is precisely that it reads as one metric among five. - **(2) Do not change `bridge_key` to accept the unqualified form.** The qualification is what stops one package's grant matching another's language id. Fix the fixture, not the door. - **(2) Do not just delete the doc comment.** It should say what is true — that the guides use the qualified form and so must this fixture. ## Related #75 and #80 C3 (the inert/activation ladder these were found under), #45 (the lane), and the sibling finding filed alongside about gate 6 refusing the deliberate zero-grant activation. Reported by the #45 lane, 2026-09-07.
Author
Member

Fixed on master at 4b332ff (merged e425320). Both halves.

Half 1 — the silent deferral

deferral_note in the CLI report, on the three-state contract:

  • no deferral — nothing said;
  • the deferral IS the activation — every claimed file deferred, so the enable produced nothing yet;
  • a remainder beside work that landed — some files deferred, some indexed.

Each naming the pass that heals it, so an operator has a next step rather than a silence.

The shape was reproduced live with a new .wpfx fixture claiming an extension no builtin claims — which is the condition this issue describes, and which no existing fixture created.

Half 2 — the bridge that never fires

package_fixture::XAML_BRIDGES now carries the package-qualified keys, and package_baseline's duplicate constant is collapsed onto it — so the ladder's own validate_grant grades the spelling rather than two constants agreeing with each other. M18 (unqualified bridge keys) → RED with capability_not_granted, the refusal naming both declared keys.

This did NOT share a root with #206, and that was measured rather than assumed

I briefed the lane to look for a shared root, since both render "this package produced nothing" opaquely. The mechanisms are disjoint:

fires at state
#207 deferral gate 3 (generation_build_files.file_id IS NULL) never reaches the admission arm — the new .wpfx e2e shows deferred=1 with admitted > 0
#206 inert gate 6 deferred = 0 — first_activation_admits's fixture reaches it with nothing deferred at all

And a third state neither issue described falls out of #206's clause: a granted package whose files are all deferred yields expected = 0 → inert rather than refused. That is this issue's Ruby shape, and it is self-healing — which is also why #206's prescribed rule ("requested some, admitted none, must keep refusing") was slightly too strong, and why the expectation is measured over the projection rather than the request.

Mutations

  • M14 (delete the deferred_note println) → RED on the CLI e2e, alone.
  • M15 (deferral_note always None) → RED on unit and e2e — reported as covered twice, not as one kill.
  • M16 / M17 (collapse the two arms / drop the deferred == 0 return) → RED on the unit test.
  • M18 → RED, above.

Binds unmoved by construction (nothing here is a resolver input); corpus_ratchet executed=7 unavailable=0, baseline.json md5 unmoved. Closing.

Fixed on `master` at `4b332ff` (merged `e425320`). Both halves. ## Half 1 — the silent deferral `deferral_note` in the CLI report, on the three-state contract: - **no deferral** — nothing said; - **the deferral IS the activation** — every claimed file deferred, so the enable produced nothing yet; - **a remainder beside work that landed** — some files deferred, some indexed. Each naming the pass that heals it, so an operator has a next step rather than a silence. The shape was **reproduced live** with a new `.wpfx` fixture claiming an extension no builtin claims — which is the condition this issue describes, and which no existing fixture created. ## Half 2 — the bridge that never fires `package_fixture::XAML_BRIDGES` now carries the **package-qualified** keys, and `package_baseline`'s duplicate constant is collapsed onto it — so the ladder's own `validate_grant` grades the spelling rather than two constants agreeing with each other. **M18** (unqualified bridge keys) → **RED** with `capability_not_granted`, the refusal naming both declared keys. ## This did NOT share a root with #206, and that was measured rather than assumed I briefed the lane to look for a shared root, since both render "this package produced nothing" opaquely. The mechanisms are disjoint: | | fires at | state | |---|---|---| | **#207** deferral | gate 3 (`generation_build_files.file_id IS NULL`) | never reaches the admission arm — the new `.wpfx` e2e shows `deferred=1` with `admitted > 0` | | **#206** inert | gate 6 | `deferred = 0` — `first_activation_admits`'s fixture reaches it with nothing deferred at all | And a **third state neither issue described** falls out of #206's clause: a granted package whose files are *all* deferred yields `expected = 0` → inert rather than refused. That is this issue's Ruby shape, and it is self-healing — which is also why #206's prescribed rule ("requested some, admitted none, must keep refusing") was slightly too strong, and why the expectation is measured over the projection rather than the request. ## Mutations - **M14** (delete the `deferred_note` println) → **RED on the CLI e2e, alone**. - **M15** (`deferral_note` always `None`) → **RED on unit and e2e** — reported as covered twice, not as one kill. - **M16 / M17** (collapse the two arms / drop the `deferred == 0` return) → RED on the unit test. - **M18** → RED, above. Binds unmoved by construction (nothing here is a resolver input); `corpus_ratchet` `executed=7 unavailable=0`, `baseline.json` md5 unmoved. Closing.
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#207
No description provided.