fix(gates): a real server↔JS leaf parity check — gate-24 was verifying nothing - #158
Merged
Merged
Conversation
hermiq registers an integration leaf on BOTH faces — the `hermiq-agent`
`LeafDescriptor` contributed through `RegisterLeafProvidersEvent`, and the
`registerIntegration({ id: 'hermiq-agent' })` mount pair in
`src/integration-leaf.js` — but shipped no `scripts/check-integration-parity.sh`,
so hydra gate-24 reported:
[gate-24] integration-parity: SKIPPED (structural) — ... server↔JS leaf
parity (ADR-066 Decisions 4/7 ...) is UNVERIFIED
Nothing correlated the two halves. The listener's own comment says the
`surfaces` list is written out on both halves "so the cross-layer parity gate
(gate-24) has two explicit sets to compare" — there was no gate comparing them.
This adds the checker gate-24 invokes. It is SELF-CONTAINED on purpose: the
canonical Node check in @conduction/nextcloud-vue validates that library's own
built-ins, its ADR-066 cross-reference is WARN-only, and its `scripts/` dir is
not published to npm — so the historic wrapper shape resolves nothing in CI and
exits 0 having checked nothing. Every way this one can fail to check exits
non-zero with a named reason instead.
Rules, all hard (ADR-019 AD-11/AD-13, ADR-066 decisions 4 and 7):
R1 complete render pair for the declared renderMode (mount+unmount / tab+widget)
R2 server↔JS id correlation, both ways (phantom leaf / orphan registration)
R3 renderMode agreement across layers under a shared id
R4 metadata agreement (label, icon, group, requiredApp, referenceType, surfaces)
R5 a spread-inherited identity must come from the leaf-owning package
R6 an offlineConfig must name schemas/properties the repo actually declares
hermiq exercises R1 (1), R2 (2), R3 (1) and R4 (5) — the counts are printed, so
"verified" and "nothing to verify" are distinguishable in the log. A run where
every rule has zero subject matter fails rather than passes.
Positive control (proved it can fail, then restored):
* renderMode drift — PHP RENDER_MODE_MOUNT -> RENDER_MODE_COMPONENT
=> exit 1, "[R3 renderMode] leaf "hermiq-agent" declares renderMode
"component" server-side ... but "mount" in its JS registration"
* surfaces drift — dropped 'single-entity' from the PHP SURFACES const
=> exit 1, "[R4 metadata] leaf "hermiq-agent" field `surfaces` mismatch
across layers"
Both restored; the check passes on the unmodified tree.
rubenvdlinde
requested review from
Rem-Dam,
SudoThijn,
WilcoLouwerse,
bbrands02,
remko48 and
rjzondervan
as code owners
August 5, 2026 18:50
Contributor
Quality Report — ConductionNL/hermiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-specs | ✅ | ||||
| check-manifest | ✅ | ||||
| test-l10n | ✅ | ||||
| composer | ✅ | ✅ 117/117 | |||
| npm | ✅ | ✅ 744/744 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ✅ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-08-05 19:02 UTC
Download the full PDF report from the workflow artifacts.
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.
What
hermiq registers its
hermiq-agentleaf on both faces — theLeafDescriptorcontributed throughRegisterLeafProvidersEvent(lib/Listener/RegisterAgentLeafListener.php) and theregisterIntegration({ id: 'hermiq-agent' })mount pair (src/integration-leaf.js) — but shipped noscripts/check-integration-parity.sh. So hydra gate-24 said, at the v1.3.0 pin:The listener's own comment says the
surfaceslist is spelled out on both halves "so the cross-layer parity gate (gate-24) has two explicit sets to compare". Nothing was comparing them.Why it is self-contained
The obvious move — copy openregister's wrapper, which resolves the canonical check out of
@conduction/nextcloud-vue— produces a dead gate:scripts/dir, and the hydra-gates job never runsnpm ci, so the resolution always misses in CI;exit 0and a friendly message → gate-24 reports PASS having correlated nothing;So this checker reads only this repo's sources, needs no
node_modules, and every way it can fail to check something exits non-zero with a named reason.Rules (all hard — ADR-019 AD-11/AD-13, ADR-066 decisions 4 and 7)
mount+unmount/tab+widget)label,icon,group,requiredApp,referenceType,surfacesofflineConfigmust name schemas/properties the repo actually declaresOutput on this repo:
The per-rule counts are printed so "verified" and "there was nothing to verify" are distinguishable. A run where every rule has zero subject matter exits 1, so this cannot become the thing it was written to replace.
Positive control — it has been seen to FAIL
renderMode: RENDER_MODE_MOUNT→RENDER_MODE_COMPONENT[R3 renderMode] leaf "hermiq-agent" declares renderMode "component" server-side … but "mount" in its JS registrationsingle-entityfrom the PHPSURFACESconst[R4 metadata] leaf "hermiq-agent" field \surfaces` mismatch across layers`Both restored; the check passes on the unmodified tree.
gate-24, measured with the v1.3.0 script
[gate-24] integration-parity: SKIPPED (structural) — … is UNVERIFIED[gate-24] integration-parity: PASSand the coverage line moves
61 of 62 applicable gates ran→62 of 62, with gate-24 leaving the "GATES THAT DID NOT RUN" list. It passes because the checker ran and returned 0 — the gate only reaches_pass 24insideif [ -f scripts/check-integration-parity.sh ], after executing it.No shipped code changes: two new files under
scripts/(not linted byeslint src, not loaded at runtime).