Skip to content

fix(gate-24): the JS probe knew one of two registration APIs (.github#349) - #370

Merged
rubenvdlinde merged 2 commits into
mainfrom
fix/gate-24-both-registration-apis
Aug 11, 2026
Merged

fix(gate-24): the JS probe knew one of two registration APIs (.github#349)#370
rubenvdlinde merged 2 commits into
mainfrom
fix/gate-24-both-registration-apis

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Supersedes #349 — same runner change, rebased onto main, now with a fixture
and 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 equally
canonical 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 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 — while printing
a confident absence claim.

⚠️ This corrects #349's own body

#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:

repo old runner new runner
decidesk NOT APPLICABLE SKIPPED (structural)
openregister PASS PASS
openconnector PASS PASS
hermiq PASS PASS

openregister ships scripts/check-integration-parity.sh, so gate-24 takes the
wrapper 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 was
enumerable from window.OCA.OpenRegister.integrations.list() in its own Playwright
run while gate-24 reported the set empty) and it ships no parity check. But
structural counts against coverage, decidesk sets enable-hydra-gates: true,
and it inherits hydra-gates-require-full-coverage: true (the shared workflow's
default). 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 a
leaf through the direct form. clean/ alone stays NOT APPLICABLE (asserted,
unchanged — a fix that made gate-24 structural everywhere would pass a one-armed
version of this test); clean/ + that file must be SKIPPED (structural).

runner @765d0817 (pre-fix)   FAIL x3 — "gate-24 still asserts 'registers no
                             integration leaves at all' over a tree that registers one"
runner @06fa782  (post-fix)  PASS x3, and the clean arm still na

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. The
warning 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 resolvable needs-external skip. ShellCheck clean.

Conduction Release Bot 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.
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