Skip to content

gate-19 e2e-coverage: demoted to advisory — fix it properly, then restore it to blocking #477

Description

@rubenvdlinde

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:

  1. 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.

  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions