gate-19 e2e-coverage was demoted to advisory (non-blocking) so the fleet can
be brought green on the findings it has already fixed. This issue is the owner
that demotion promised: the gate needs fixing on its own merits, and then
restoring to blocking.
Why it was demoted
Measured across development on 2026-08-16:
| app |
scenarios missing @e2e |
| hermiq |
491 |
| docudesk |
405 |
| doriath |
149 |
| launchpad |
128 |
| total (4 apps) |
1,173 |
Two things made this unpayable as a blocking gate:
-
Most of it is not browser behaviour. On nldesign — the one app taken
end-to-end — roughly one scenario in five was genuinely reachable from a
browser. The rest were colour-derivation arithmetic, occ command file
writes, TimedJob intervals, outbound HTTP counted at the IClientService
boundary, and generated email markup. All real behaviour. All proven by
PHPUnit. None of it reachable from a page.
-
The cheap remedy is the wrong one. Left blocking, the realistic fix is
mass @e2e exclude. nldesign was already carrying 585 of 786 scenarios
excluded before any of this work began; closing its remaining 126 that way
would have taken it past 90%. A gate whose green is mostly waivers is not
measuring coverage.
There was also a structural cost: gate-19 is a shared red. Every app it
fails also fails Hydra Gates and Quality Report, which hides that app's
other gate findings behind the same red job. launchpad, doriath and docudesk
each have gate work already done that cannot show as green while gate-19 blocks.
What "fixed" would mean
Not "annotate 1,173 scenarios". The gate is asking the wrong question of some
of its subjects, and that is the part to fix:
- Distinguish browser-testable scenarios from the rest. A scenario whose
GIVEN/WHEN/THEN never mentions a page, a control or a rendered value cannot
have a Playwright proof, and asking for one produces a waiver every time.
Deciding this from the scenario text — rather than leaving it to each
author's judgement — is most of the work.
- Accept a non-browser proof.
@e2e is the only satisfying annotation
today. A scenario proven by a named PHPUnit test is covered; it is just not
covered by a browser. Recognising a second proof kind would convert most of
the current waiver population into real, checkable traceability.
- Reconsider the base. On a push to
development the suite runs with
HYDRA_GATE_BASE_REF=origin/beta, so the delta is the whole unreleased
release rather than one PR's worth of change. That is defensible, but it is
why the counts are in the hundreds rather than the tens.
- Audit the existing waivers. 585 excluded scenarios on one app is a
number nobody has read recently. Some will be honest; some will be the
"apologise to the gate" shape. The gate cannot be restored to blocking
without knowing which.
Restoring it
The demotion is _warn 19 in hydra-gates/scripts/run-hydra-gates.sh.
Restoring is a one-line change back to _fail 19, plus reverting the verdict
word in:
scripts/test-fixtures/gate-acceptance/prose-not-proof/expect.conf
scripts/lib/test_gate_exit_code_semantics.sh
scripts/lib/test_gate_base_ref_delivery_channel.sh
The _warn helper itself should stay — it is generally useful, and it is
deliberately distinct from _skip: a skip means the gate did not judge, a
warning means it judged and is not blocking.
What must stay true while it is advisory
- The count is still measured and printed on every run.
- gate-19 still registers in
_EMITTED_GATES, so the COVERAGE line does not
quietly shrink.
- The summary states that a green verdict means "nothing blocking failed", not
"nothing was found".
If those stop holding, the gate has effectively been retired rather than
demoted, and this issue is the place to say so.
gate-19 e2e-coveragewas demoted to advisory (non-blocking) so the fleet canbe brought green on the findings it has already fixed. This issue is the owner
that demotion promised: the gate needs fixing on its own merits, and then
restoring to blocking.
Why it was demoted
Measured across
developmenton 2026-08-16:@e2eTwo things made this unpayable as a blocking gate:
Most of it is not browser behaviour. On nldesign — the one app taken
end-to-end — roughly one scenario in five was genuinely reachable from a
browser. The rest were colour-derivation arithmetic,
occcommand filewrites,
TimedJobintervals, outbound HTTP counted at theIClientServiceboundary, and generated email markup. All real behaviour. All proven by
PHPUnit. None of it reachable from a page.
The cheap remedy is the wrong one. Left blocking, the realistic fix is
mass
@e2e exclude. nldesign was already carrying 585 of 786 scenariosexcluded before any of this work began; closing its remaining 126 that way
would have taken it past 90%. A gate whose green is mostly waivers is not
measuring coverage.
There was also a structural cost: gate-19 is a shared red. Every app it
fails also fails
Hydra GatesandQuality Report, which hides that app'sother gate findings behind the same red job. launchpad, doriath and docudesk
each have gate work already done that cannot show as green while gate-19 blocks.
What "fixed" would mean
Not "annotate 1,173 scenarios". The gate is asking the wrong question of some
of its subjects, and that is the part to fix:
GIVEN/WHEN/THEN never mentions a page, a control or a rendered value cannot
have a Playwright proof, and asking for one produces a waiver every time.
Deciding this from the scenario text — rather than leaving it to each
author's judgement — is most of the work.
@e2eis the only satisfying annotationtoday. A scenario proven by a named PHPUnit test is covered; it is just not
covered by a browser. Recognising a second proof kind would convert most of
the current waiver population into real, checkable traceability.
developmentthe suite runs withHYDRA_GATE_BASE_REF=origin/beta, so the delta is the whole unreleasedrelease rather than one PR's worth of change. That is defensible, but it is
why the counts are in the hundreds rather than the tens.
number nobody has read recently. Some will be honest; some will be the
"apologise to the gate" shape. The gate cannot be restored to blocking
without knowing which.
Restoring it
The demotion is
_warn 19inhydra-gates/scripts/run-hydra-gates.sh.Restoring is a one-line change back to
_fail 19, plus reverting the verdictword in:
scripts/test-fixtures/gate-acceptance/prose-not-proof/expect.confscripts/lib/test_gate_exit_code_semantics.shscripts/lib/test_gate_base_ref_delivery_channel.shThe
_warnhelper itself should stay — it is generally useful, and it isdeliberately distinct from
_skip: a skip means the gate did not judge, awarning means it judged and is not blocking.
What must stay true while it is advisory
_EMITTED_GATES, so the COVERAGE line does notquietly shrink.
"nothing was found".
If those stop holding, the gate has effectively been retired rather than
demoted, and this issue is the place to say so.