Skip to content

gate-24 cannot find the canonical parity check — and bumping the dependency alone would turn an honest SKIP into a false PASS #402

Description

@rubenvdlinde

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

  1. Teach the canonical checker IntegrationProvider, and make its JS probe match
    both registration APIs. Without this, step 2 produces a false green.
  2. 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.
  3. Only then bump @conduction/nextcloud-vue past vue3.14 so the file resolves.
  4. Triage the ~29 ids with a probe that matches both APIs.
  5. 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.

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