Skip to content

fix(e2e): two anchors #2057 broke that 49 green checks did not see - #2123

Merged
rubenvdlinde merged 1 commit into
developmentfrom
fix/two-anchors-2057-broke
Sep 9, 2026
Merged

fix(e2e): two anchors #2057 broke that 49 green checks did not see#2123
rubenvdlinde merged 1 commit into
developmentfrom
fix/two-anchors-2057-broke

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Follow-up to #2116, which merged while this was being measured. Two things it got wrong.

#2057 broke two anchors and every check passed

#2057 renumbered the kanban delta's scenarios from DASH-V1-006d/e to 006f/g, to clear a collision
with two scenarios the dashboard spec already had. It did not update the two citations in
tests/e2e/spec-coverage/kanban-board-keyboard-status-transition.spec.ts, which still named 006d and
006e.

The tests kept running. They kept reporting green. They cited scenarios that no longer existed. 49
checks passed, twice, across #2057 and #2066.

Nothing caught it because gate 46 does not read @e2e. Under @spec it would have failed the same
afternoon. This is the clearest example I have of the gap now filed as ConductionNL/.github#726, and it
is self-inflicted, which is why it is worth writing down rather than quietly fixing.

Both are repointed at the canonical openspec/specs/dashboard/spec.md#scenario-dash-v1-006f-… and
…006g-…, per the convention #2116 landed. Each fragment was probed through the real helper before
it was written.

The measurement in #2116 was wrong, and wrong the way everything else here was wrong

#2116 claims "6,244 anchors, zero unresolvable". That was measured with a reimplementation of gate
46's resolver rather than the resolver, and it was wrong in both directions.

Mine missed two things the real one does:

  • the flat openspec/specs/<cap>.md spelling, which predates the directory form and which the
    helper explicitly normalises. That alone made mine call 13 of planix's healthy anchors dangling.
  • fragment checking. The helper verifies that a #fragment names a heading somebody actually
    wrote. Mine stopped at the file.

Run properly, dossiq has 28 unresolved @e2e anchors, every one of them anchor not found rather
than a missing file. That is exactly the opencatalogi#85 shape gate 46 was built for, surviving in the
half of the corpus the gate does not read.

before after
unresolved @e2e 28 26
unresolved @spec (real gate, real scope) 0 0

The 26 that remain are pre-existing and stay. Each needs a judgement about which scenario it meant,
which is the work rather than the sed, and the gate fix filed upstream surfaces them on the next PR
touching those files. Tracked as task 5.3 on the still-open spec-anchors-name-the-capability change,
which is why that change is not archived.

Upstream, filed with the fleet measurement

Taken with the real helper across all 21 fleet apps, by rewriting @e2e tags to @spec in a probe
file outside each repo and running check_spec_anchors.py with cwd set to the app:

The rule underneath all of it

Stop reimplementing the instrument. Every wrong number in this investigation came from a hand-rolled
resolver: 420, then 2,955, then "zero unresolvable". Every right one came from running
check_spec_anchors.py. It is the same failure three times, and the third time it was mine after I had
already written up the first two.

… for the same reason

"6,244 anchors, zero unresolvable" was measured with a reimplementation of gate
46's resolver rather than the resolver. It was wrong in both directions.

Mine ignored two things the real one does. The flat `openspec/specs/<cap>.md`
spelling, which predates the directory form and which the helper explicitly
normalises: that alone made it call 13 of planix's healthy anchors dangling. And
fragment checking: the helper verifies a `#fragment` names a heading somebody
wrote, and mine stopped at the file.

Run properly, this repo has 28 unresolved `@e2e` anchors, every one of them
"anchor not found" rather than a missing file. That is the opencatalogi#85 shape
the gate was built for, surviving in the half of the corpus the gate does not
read.

Two of the 28 are this session's own. #2057 renumbered the kanban delta's
scenarios from `DASH-V1-006d/e` to `006f/g` to clear a collision with two the
spec already had, and left `kanban-board-keyboard-status-transition.spec.ts`
citing the old ids. Every check passed, the tests kept running, and they kept
reporting green while naming scenarios that no longer existed. Gate 46 never
looked because they are `@e2e`. Both are repointed at the canonical
`openspec/specs/dashboard/spec.md`, per the rule this change writes down, and
each fragment was probed through the real helper before it was written.

The other 26 are pre-existing and stay. Each needs a judgement about which
scenario it meant, which is the work rather than the sed, and the gate fix filed
upstream surfaces them on the next PR that touches those files.

Upstream gaps filed with the fleet measurement, taken with the real helper across
21 apps: ConductionNL/.github#726 (gate 46's pattern excludes `@e2e`; 1,964 such
anchors fleet-wide, 194 dangling, against 55,720 `@spec` anchors with 1) and #727
(`appinfo/` and `scripts/` never enumerated; 52 anchors unopened, and 8 of
openregister's 9 in `routes.php` are dangling, two of them ending in a stray full
stop that was never a path).

The rule underneath all of it: stop reimplementing the instrument. Every wrong
number here came from a hand-rolled resolver and every right one came from
running `check_spec_anchors.py`.
@rubenvdlinde
rubenvdlinde merged commit 78eff00 into development Sep 9, 2026
47 of 48 checks passed
@rubenvdlinde
rubenvdlinde deleted the fix/two-anchors-2057-broke branch September 9, 2026 11:34
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/dossiq @ 7b81b63

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
check-vue3-compile
test-l10n
format
check-schema-l10n
check-l10n-js
composer ✅ 106/106
npm ✅ 549/549
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman ⏭️
Playwright
Hydra gates

Quality workflow — 2026-09-09 11:36 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde

Copy link
Copy Markdown
Contributor Author

CI

302 passed, 4 failed, 1 flaky. The 4 are identical to development's own set at fe1fa34f
(run), the same four that have been
red all day:

case-actions-menu:332   case-type-authoring-extras:494
contacts-domain:362     case-type-authoring-extras:645

The flaky one is case-type-authoring-extras:326, failed once and passed on retry, excluded by keeping
only specs with no passing attempt so it reconciles with the runner's 4 failed / 1 flaky rather than
reporting five.

47 checks, not 4: this branch is MERGEABLE, unlike #2116 before its merge.

The two tests whose anchors this fixes both ran and passed

✓ a case card exposes a keyboard-operable "Move to…" menu   (12.x s)
✓ case cards remain draggable for mouse/touch users         (10.3s)

Which is the whole point. They were passing before too, while citing scenarios that had not existed
since #2057. A green test proves the behaviour; it says nothing about whether the requirement it claims
to prove is still there. That is the job of gate 46, and gate 46 does not read @e2e
(ConductionNL/.github#726).

Anchor state after this PR

count
unresolved @spec, real gate over its real scope 0
unresolved @e2e, real resolver over all 284 26 (was 28)

The 26 are pre-existing, tracked as task 5.3 on the open spec-anchors-name-the-capability change.
Each needs a judgement about which scenario it meant, so they are deliberately not swept here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant