Skip to content

ci(quality): move the hydra-gates pin v1.0.1 -> v1.3.0 - #130

Merged
rubenvdlinde merged 2 commits into
developmentfrom
ci/hydra-gates-pin-v1.2.0
Aug 5, 2026
Merged

ci(quality): move the hydra-gates pin v1.0.1 -> v1.3.0#130
rubenvdlinde merged 2 commits into
developmentfrom
ci/hydra-gates-pin-v1.2.0

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Moves this repo's hydra-gates-ref pin from v1.0.1 to v1.2.0.

Why

v1.0.1's gate-5 (route-auth) had four defects. Two were reported as
ConductionNL/.github#153;
the other two were found while fixing it, and one of those is the expensive
direction:

  1. A resolution failure was reported as a security finding. When
    lib/Controller/<X>Controller.php did not exist, the verdict read
    "N routed method(s) missing auth attribute". On ADR-040 AppHost adopters
    those files are absent by design — the controllers are OpenRegister
    generics aliased at runtime — and the attributes live in the openregister
    package. The gate was reporting "I cannot see it" as "it is absent".
  2. It was not diff-scoped. The missing-file branch continued before
    the _in_scope call, so those findings fired on a package.json-only
    Dependabot bump. Now scoped per ADR-020.
  3. camelCase route slugs were invisible. Gate-5 read route names through
    '[a-z_]+#…'. Gate-14 already used a wider regex; the narrower one was the
    security gate. On scholiq, 14 of 37 routed names matched — the other 23
    were never opened.
  4. The 20-line attribute lookback was not bounded by the start of the
    method,
    so a short guarded method within 20 lines above an unguarded one
    donated its #[NoAdminRequired] to its neighbour. A false negative, and
    invisible, because a pass leaves no log.

Fixed in ConductionNL/.github#162 with 25 control-pair assertions, mutation-tested
against three realistic degradations.

v1.2.0 also brings, from v1.1.0, a countable gate-22 (it printed
FAIL — 0 while a real finding sat in its log) and the runner's COVERAGE
accounting
v1.0.1's summary printed only N gate(s) failed, so a gate
that never ran was indistinguishable from one that passed.

Expect red

Gate-5 now sees code it never saw. New findings from this PR are the point of
it, not a regression.
Nothing has been baselined or suppressed to keep a repo
green.

⚠️ Note for whoever reads the job log: the Hydra Gates job on this PR diffs a
single workflow file, and the gates are diff-scoped — so its green says almost
nothing. The measurement that matters is the next real code PR.

🤖 Generated with Claude Code

v1.0.1's gate-5 (route-auth) could not tell "this routed method has no auth
attribute" from "I could not resolve the controller class", and reported both
as the former. It also read route names through `'[a-z_]+#...'`, so every
camelCase route slug was invisible to it in either direction, and its 20-line
attribute lookback could borrow the PREVIOUS method's attribute.

Fixed in ConductionNL/.github#162 (closing #153). v1.2.0 also carries the
runner's COVERAGE accounting, which v1.0.1 does not have at all: v1.0.1's
summary printed only "N gate(s) failed", so a gate that never ran was
indistinguishable from one that passed.

EXPECT NEW FINDINGS. gate-5 now sees code it never saw. Red is the honest
outcome of a measurement that previously was not taken; nothing here is
baselined or suppressed to avoid it.
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/openbuild @ 6c3f2bf

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
test-l10n
composer ✅ 101/101
npm ✅ 654/654
PHPUnit
Newman ⏭️
Playwright ⏭️
Hydra gates

Quality workflow — 2026-08-05 13:29 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde

Copy link
Copy Markdown
Contributor Author

Adopting this rather than opening a duplicate — but v1.2.0 is no longer a green target, and the green tick on this PR is stale. Please re-point it to v1.3.0.

The tick predates the contract change. This PR's Code Quality run 31010171177 was created 13:26:03Z and finished 13:30:06Z. .github#164 merged at 13:52:03Z26 minutes later. That run executed against the previous quality.yml, so it is evidence about a contract that no longer exists. Re-run it and it goes red.

What #164 changed. It flipped hydra-gates-require-full-coverage to default: true in the shared quality.yml. Every repo references that file at @main, so the flip went live everywhere immediately. But the accounting that makes the flag survivable — NOT APPLICABLE, as distinct from a structural or a wiring gap — ships in the pinned package. The workflow and the package can therefore desync, and right now they are desynced for every pin older than f7eaf2a.

Measured, same repo, same branch, both runs after #164 merged (app-versions, one-file diff, diff-scoped against origin/development exactly as CI scopes it):

pin CI run quality / Hydra Gates
v1.2.0 31012647428 13:56:22Z failure--require-full-coverage was set: treating incomplete coverage as failure (exit 98)
v1.3.0 31013564400 14:07:14Z success — 52 applicable gates ran and passed, 11 named NOT APPLICABLE

Reproduced locally at all three pins, each run in its own mount namespace with a private tmpfs:

v1.0.1  exit 98   FAIL
v1.2.0  exit 98   FAIL
v1.3.0  exit 0    PASS

v1.3.0 is f7eaf2a = .github@main including #164. I tagged it so the ref stays reproducible and a later gate change cannot move a repo's verdict without a commit in that repo.

One line to change: hydra-gates-ref: v1.2.0 -> v1.3.0. I am bumping the rest of the fleet to v1.3.0 and am leaving this repo to you to avoid a conflicting edit — say the word if you'd rather I pushed it.

v1.2.0 added the COVERAGE accounting but not the declarations that accounting
asks for. v1.0.1/v1.2.0 have no `_skip` vocabulary, so a gate whose
prerequisite is absent emits nothing and require-full-coverage (default ON)
counts it as DID NOT RUN. v1.3.0 ships 36 not-applicable declarations;
measured on doriath PR #160, Hydra Gates went failure -> success on the pin
alone. Lands this repo on the same pin as the rest of the fleet.
@rubenvdlinde rubenvdlinde changed the title ci(quality): move the hydra-gates pin v1.0.1 -> v1.2.0 ci(quality): move the hydra-gates pin v1.0.1 -> v1.3.0 Aug 5, 2026
@rubenvdlinde

Copy link
Copy Markdown
Contributor Author

Advanced this PR's pin v1.2.0 -> v1.3.0 rather than opening a competing PR, so the whole fleet lands on one pin in a single wave.

v1.2.0 delivered the COVERAGE accounting but not the declarations that accounting asks for. hydra-gates-require-full-coverage (default ON) fails a run when a gate whose subject matter EXISTS did not report, and its contract is that a not-applicable gate must declare itself. Neither v1.0.1 nor v1.2.0 has any _skip / na / structural / wiring vocabulary, so such a gate emits nothing and is counted as "DID NOT RUN". v1.3.0 ships 36 such declarations.

Measured on doriath PR #160 (merged): on the pin change alone, Hydra Gates went failure -> success and gates 4/24/33 moved from unexplained "DID NOT RUN" to explicit NOT APPLICABLE with a named reason each.

The control argument in the file's comment is untouched — it concerns gate-5/gate-14, which v1.3.0 does not change.

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/openbuild @ 346864d

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
test-l10n
composer ✅ 101/101
npm ✅ 654/654
PHPUnit
Newman ⏭️
Playwright ⏭️
Hydra gates

Quality workflow — 2026-08-05 18:11 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde
rubenvdlinde merged commit 4bac221 into development Aug 5, 2026
34 checks passed
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