fix(gate-24): the JS probe knew one of two registration APIs (.github#349) - #370
Merged
Conversation
added 2 commits
August 11, 2026 20:31
…leared repos that have leaves gate-24 (integration-parity) decides applicability from its own subject matter: does this repo register integration leaves at all? The PHP half looks for `new LeafDescriptor(` in lib/. The JS half looked only for `registerIntegration(` in src/. There are TWO canonical JS registration forms, and the gate knew one. `registerIntegration(descriptor)` is the convenience wrapper exported from @conduction/nextcloud-vue; the registry object it wraps is called directly as `OCA.OpenRegister.integrations.register(descriptor)`, which is equally canonical — it is how nextcloud-vue registers its OWN built-in leaves (src/integrations/builtin/files.js). So an app using the direct form was told, verbatim, "this repo registers no integration leaves at all". That sentence is not cosmetic: it routes the gate to `na`, which does NOT count against coverage, instead of `structural`, which does. The one gate that exists to correlate the server and JS halves of a leaf therefore switched itself off precisely in repos that have halves to correlate, and did so while printing a confident absence claim. MEASURED, `--full`, on ConductionNL/decidesk at e03f5932: [gate-24] integration-parity: NOT APPLICABLE — ... this repo registers no integration leaves at all — no `new LeafDescriptor(` in lib/ and no `registerIntegration(` in src/. decidesk registers exactly one leaf, `decidesk-decisions`, at src/integrations/registerDecisionsLeaf.js:175 via `target.OCA.OpenRegister.integrations.register(decisionsLeafDescriptor)` — and that id was present in the LIVE JS registry in the same repo's Playwright run, read out of `window.OCA.OpenRegister.integrations.list()`. The gate said the set was empty while the runtime enumerated a member of it. POSITIVE CONTROL, old probe vs new, over the fleet checkout: decidesk old=0 new=1 <- false negative, fixed openregister old=0 new=1 <- false negative, fixed openconnector old=1 new=1 <- no regression procest old=1 new=1 <- no regression hermiq old=1 new=1 <- no regression nldesign old=0 new=0 <- correctly negative docudesk old=0 new=0 <- correctly negative and on decidesk the verdict moves from a false `na` to `SKIPPED (structural)`, which moves the coverage line from "58 of 58 applicable gates ran" to "58 of 59" — the gap becomes visible instead of being absorbed. `integrations\.register` cannot collide with `unregister(`, because the qualifier is part of the match, nor with `registerIntegrationIcons(`, because `\(` anchors the end. Why this matters beyond the count: the drift gate-24 exists to catch is live right now. openregister advertises `kvk` and `opencorporates` over OCS capabilities while @conduction/nextcloud-vue never registered either in JS (ConductionNL/nextcloud-vue#630), and it went unnoticed until an app's e2e test compared the two lists by hand. A parity gate that cannot tell it has leaves is a parity gate that cannot find that. NOT FOR IMMEDIATE MERGE. This turns a silent `na` into a counted `structural` gap in at least two repos, so it can redden a `--require-full-coverage` run mid-wave — the same reason #347 is being held. Land it once the wave settles.
…raft A paired arm on top of the existing `clean/` fixture: one overlaid file that registers a leaf through the DIRECT form, `OCA.OpenRegister.integrations. register(...)`. `clean/` alone stays NOT APPLICABLE (asserted, unchanged); `clean/` + that one file must be SKIPPED (structural). Observed red, then green, against the same suite: runner @765d0817 (pre-#349) FAIL x3 -- "gate-24 still asserts 'registers no integration leaves at all' over a tree that registers one" runner @06fa782 (post) PASS x3, and the clean arm still na THE FIRST DRAFT OF THE FIXTURE WAS A DEAD TEST AND WENT GREEN AGAINST THE PRE-#349 RUNNER. Its explanatory comment named the wrapper function followed by an open paren, and gate-24's probe is a plain grep over file TEXT -- so the PROSE describing the defect satisfied the gate being described. That is .github#358's shape (gates 19 and 26 parse prose) met while fixturing a different gate, and the warning is now written into the fixture itself so the next author does not re-introduce it. BLAST RADIUS, MEASURED rather than argued -- the runner run over each fleet checkout, old runner vs new, nothing else changed: decidesk NOT APPLICABLE -> SKIPPED (structural) <- the only change openregister PASS -> PASS openconnector PASS -> PASS hermiq PASS -> PASS⚠️ THIS CORRECTS THE PR BODY. #349 says the verdict moves "in at least two repos" and names openregister. It does not: openregister ships scripts/check-integration-parity.sh, so gate-24 takes the wrapper path and passes, before and after. Exactly ONE repo changes. decidesk's new verdict is honest -- it registers `decidesk-decisions` and ships no parity check -- but `structural` COUNTS against coverage, and decidesk sets enable-hydra-gates: true while inheriting hydra-gates-require-full-coverage: true. So its Code Quality run will exit 98 until it adds the parity wrapper that openregister, openconnector, hermiq and procest already carry. The shared workflow's own input description already records hermiq and openconnector as having exactly this gap, so decidesk is joining a known and closable shape rather than meeting a new one.
This was referenced Aug 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Supersedes #349 — same runner change, rebased onto
main, now with a fixtureand with the blast radius measured instead of estimated.
The change
gate-24 decides applicability from its own subject matter: does this repo register
integration leaves at all? The JS half looked only for the convenience wrapper
exported from
@conduction/nextcloud-vue. The registry object it wraps is equallycanonical and is called directly — including by nextcloud-vue's own built-in leaves
(
src/integrations/builtin/files.js).So an app using the direct form was told, verbatim, "this repo registers no
integration leaves at all". That sentence is load-bearing: it routes the gate to
na, which does not count against coverage, instead ofstructural, which does.The one gate that exists to correlate the server and JS halves of a leaf therefore
switched itself off precisely in repos that have halves to correlate — while printing
a confident absence claim.
#349 states the verdict moves "in at least two repos" and names openregister.
It does not. Measured by running the runner over each fleet checkout, old vs new,
with nothing else changed:
NOT APPLICABLESKIPPED (structural)PASSPASSPASSPASSPASSPASSopenregister ships
scripts/check-integration-parity.sh, so gate-24 takes thewrapper path and passes either way. Exactly one repo changes.
Blast radius, stated plainly
decidesk's new verdict is honest — it registers
decidesk-decisions(that id wasenumerable from
window.OCA.OpenRegister.integrations.list()in its own Playwrightrun while gate-24 reported the set empty) and it ships no parity check. But
structuralcounts against coverage, decidesk setsenable-hydra-gates: true,and it inherits
hydra-gates-require-full-coverage: true(the shared workflow'sdefault). So decidesk's Code Quality run will exit 98 until it adds the parity
wrapper that openregister, openconnector, hermiq and procest already carry.
This is a known and closable shape, not a new one: the shared workflow's own input
description already records hermiq and openconnector as having exactly this gap.
The fixture — red before, green after
A paired arm on the existing
clean/bundle: one overlaid file registering aleaf through the direct form.
clean/alone staysNOT APPLICABLE(asserted,unchanged — a fix that made gate-24 structural everywhere would pass a one-armed
version of this test);
clean/+ that file must beSKIPPED (structural).The first draft of the fixture was a DEAD TEST
It went green against the pre-fix runner. Its explanatory comment named the
wrapper function followed by an open paren, and gate-24's probe is a plain grep over
file text — so the prose describing the defect satisfied the gate being
described. That is
.github#358's shape met while fixturing a different gate. Thewarning is now written into the fixture file itself.
Full suite: 73 passed / 2 quarantined / 1 failed, the failure being the pre-existing
ajv is not resolvableneeds-externalskip. ShellCheck clean.