Summary
On openregister, gate-24 reports:
[gate-24] integration-parity: SKIPPED (structural) — scripts/check-integration-parity.sh
ran but SKIPPED — it could not locate the canonical JS check, so NOTHING was
correlated — while this repo DOES register integration leaves. server↔JS leaf
parity (ADR-066 Decisions 4/7) is UNVERIFIED by this run — this is NOT a pass.
Measured identically on chore/nextcloud-coding-standard and on development with the
same package, so it is pre-existing and not a side effect of the coding-standard
reformat. (check-integration-parity.sh is blob 611d839d on both refs — a bash file
php-cs-fixer never touches.)
The gate is behaving correctly and saying so clearly. The problem is what happens
when you fix the obvious cause.
1. Why it cannot find the check — a reason that rotted
The canonical check is scripts/check-integration-parity.js inside
@conduction/nextcloud-vue. The wrapper looks in, in order:
$NEXTCLOUD_VUE_DIR/scripts/…
<repo>/node_modules/@conduction/nextcloud-vue/scripts/…
<repo>/../nextcloud-vue/scripts/…
openregister pins @conduction/nextcloud-vue 2.2.0-vue3.9 in both package.json
and package-lock.json. Measured against the registry: the published tarball first
contains a scripts/ directory at 2.2.0-vue3.14 — vue3.9/.10/.12/.13 ship zero
files under scripts/, vue3.14/.15 ship 14 including the parity check.
CI does run npm ci, so node_modules/@conduction/nextcloud-vue/ exists — the
directory is there and the file is not. The wrapper's own stated reason ("the
npm-published package does not ship the scripts/ dir") was true when written and
has since stopped being true. A reason that names a state of the world rots; one that
names a test artefact holds.
2. 🔴 Closing the dependency gap would make this WORSE, not better
This is the part worth reading twice. Bumping to vue3.15 makes the file resolvable —
and then:
- the canonical checker's
collectServerDescriptors() recognises only
new LeafDescriptor(
- openregister has none. Its server leaves are
IntegrationProvider classes under
lib/Service/Integration/Providers/
- so
descriptors.length === 0, the ADR-066 server↔JS half returns {ran: false}, and
reportCrossRef returns silently when !ran — printing neither a ✓ nor a
warning
- and that half is WARN-only anyway:
// Never changes the exit code
So after the "fix", gate-24 would report PASS having correlated nothing. Today it
refuses to pass and names exactly what it did not check. The honest skip is worth
more than the green would be, and shipping the bump alone converts a loud unknown
into a silent false assurance.
This fleet has paid for that shape before: gate-7 reported PASS over 11 real unguarded
IDOR endpoints, and its silences were trusted because its known failure mode was false
positives.
3. There is probably a real finding underneath
Running procest's repo-local parity checker — which does recognise
IntegrationProvider — against openregister produced 29 R2 id-correlation
violations, identical on both trees: message-dispatch, opencorporates,
openproject, photos, polls, shares, talk, time-tracker, xwiki, plus a
duplicate time-tracker from two files.
Treat 29 as an upper bound needing triage, not a verified defect count. procest's
checker probes JS with registerIntegration\s*\( only, and openregister registers via
integrations.register({…}), so at least the xwiki violation is a false positive of
that checker. The hydra gate's own probe was already fixed for precisely this — "THE
JS PROBE MUST MATCH BOTH SUPPORTED REGISTRATION APIs" — while procest's copy still
carries the single-form probe.
Suggested order of work
- Teach the canonical checker
IntegrationProvider, and make its JS probe match
both registration APIs. Without this, step 2 produces a false green.
- Make the cross-ref half loud when it cannot run.
reportCrossRef returning
silently on !ran is the defect; ran: false should print what it could not
correlate, the way the wrapper already does.
- Only then bump
@conduction/nextcloud-vue past vue3.14 so the file resolves.
- Triage the ~29 ids with a probe that matches both APIs.
- Consider adopting procest's pattern generally — a repo-local checker that exits
non-zero when it cannot check. Its wrapper docblock already states this issue's
whole thesis: "A gate whose absence looks exactly like its success is worse than no
gate."
Related
.github#399 (gate-16), .github#391 (gate-14), #388 (gate-48) — three gates that
misread reformatted code. This is not a fourth: gate-24 read it correctly and refused
to guess.
Summary
On openregister, gate-24 reports:
Measured identically on
chore/nextcloud-coding-standardand ondevelopmentwith thesame package, so it is pre-existing and not a side effect of the coding-standard
reformat. (
check-integration-parity.shis blob611d839don both refs — a bash filephp-cs-fixer never touches.)
The gate is behaving correctly and saying so clearly. The problem is what happens
when you fix the obvious cause.
1. Why it cannot find the check — a reason that rotted
The canonical check is
scripts/check-integration-parity.jsinside@conduction/nextcloud-vue. The wrapper looks in, in order:$NEXTCLOUD_VUE_DIR/scripts/…<repo>/node_modules/@conduction/nextcloud-vue/scripts/…<repo>/../nextcloud-vue/scripts/…openregister pins
@conduction/nextcloud-vue2.2.0-vue3.9 in bothpackage.jsonand
package-lock.json. Measured against the registry: the published tarball firstcontains a
scripts/directory at 2.2.0-vue3.14 — vue3.9/.10/.12/.13 ship zerofiles under
scripts/, vue3.14/.15 ship 14 including the parity check.CI does run
npm ci, sonode_modules/@conduction/nextcloud-vue/exists — thedirectory is there and the file is not. The wrapper's own stated reason ("the
npm-published package does not ship the
scripts/dir") was true when written andhas since stopped being true. A reason that names a state of the world rots; one that
names a test artefact holds.
2. 🔴 Closing the dependency gap would make this WORSE, not better
This is the part worth reading twice. Bumping to vue3.15 makes the file resolvable —
and then:
collectServerDescriptors()recognises onlynew LeafDescriptor(IntegrationProviderclasses underlib/Service/Integration/Providers/descriptors.length === 0, the ADR-066 server↔JS half returns{ran: false}, andreportCrossRefreturns silently when!ran— printing neither a✓nor awarning
// Never changes the exit codeSo after the "fix", gate-24 would report PASS having correlated nothing. Today it
refuses to pass and names exactly what it did not check. The honest skip is worth
more than the green would be, and shipping the bump alone converts a loud unknown
into a silent false assurance.
This fleet has paid for that shape before: gate-7 reported PASS over 11 real unguarded
IDOR endpoints, and its silences were trusted because its known failure mode was false
positives.
3. There is probably a real finding underneath
Running procest's repo-local parity checker — which does recognise
IntegrationProvider— against openregister produced 29 R2 id-correlationviolations, identical on both trees:
message-dispatch,opencorporates,openproject,photos,polls,shares,talk,time-tracker,xwiki, plus aduplicate
time-trackerfrom two files.Treat 29 as an upper bound needing triage, not a verified defect count. procest's
checker probes JS with
registerIntegration\s*\(only, and openregister registers viaintegrations.register({…}), so at least thexwikiviolation is a false positive ofthat checker. The hydra gate's own probe was already fixed for precisely this — "THE
JS PROBE MUST MATCH BOTH SUPPORTED REGISTRATION APIs" — while procest's copy still
carries the single-form probe.
Suggested order of work
IntegrationProvider, and make its JS probe matchboth registration APIs. Without this, step 2 produces a false green.
reportCrossRefreturningsilently on
!ranis the defect;ran: falseshould print what it could notcorrelate, the way the wrapper already does.
@conduction/nextcloud-vuepast vue3.14 so the file resolves.non-zero when it cannot check. Its wrapper docblock already states this issue's
whole thesis: "A gate whose absence looks exactly like its success is worse than no
gate."
Related
.github#399(gate-16),.github#391(gate-14),#388(gate-48) — three gates thatmisread reformatted code. This is not a fourth: gate-24 read it correctly and refused
to guess.