Skip to content

feat(hydra-gates): gate 117 reads PHP and schema strings as missing, not only as unused - #782

Open
rubenvdlinde wants to merge 1 commit into
mainfrom
feat/gate-117-l10n-source-coverage
Open

rubenvdlinde wants to merge 1 commit into
mainfrom
feat/gate-117-l10n-source-coverage

Conversation

@rubenvdlinde

@rubenvdlinde rubenvdlinde commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

The defect

Every app vendored its own check-l10n.js. All of them computed missing the same way:

const missing = [...usedKeys].filter((k) => !keys.has(k))

usedKeys came from walking src/ for t() calls. PHP and schema JSON, where the better copies read them at all, only cleared an "unused" warning. A ->t('Approve') with no key in en.json could suppress a warning and could never raise one. No app in the fleet could see a server-side or schema string that had reached no catalogue at all.

The drift, measured

Fetched every copy across the 21 core apps at development on 2026-09-19.

Count
Copies found 18, across 15 repos
Distinct versions, normalised for app name and comments 13
Repos with two copies at two paths 3 (openregister, integriq, filinq: scripts/ and tests/l10n/)
Repos with no copy at all 3 (portaliq, humaniq, versioniq)
Copies whose missing reads only src/ 13 of 13

The largest cluster is five identical copies at 7047 bytes (buildiq, decidiq, filinq, hermiq, shillinq). opencatalogi's is the most advanced at 16447 bytes, and even it reads PHP only as a suppressor. check-l10n-parity.js is a different check and is left alone.

What this ships

hydra-gates/scripts/check-l10n.js, one shared checker reading four sources, each finding tagged with the source that produced it:

Source Where Feeds
SRC src/**/*.{vue,js,ts}, t() and n() missing, unused
PHP lib/, templates/, appinfo/, ->t() and ->n() missing, unused
MANIFEST src/manifest.json and src/manifest.d/*.json missing, unused
SCHEMA lib/Settings/**/*.json, register and schema title and description missing, unused

One deliberate exception: a PHP array value under a rendered field name clears an unused warning but never raises a missing one. Treating those as missing added 63 findings on opencatalogi and the sample was mostly MCP tool descriptions that no person reads. A ->t() call is an unambiguous claim that a string is user facing. An array key is not.

Gate 117 l10n-source-coverage, full tree, placed outside any _FAILED guard.

Warning first

Fourteen of twenty-one repos carry inherited findings. openregister alone carries 1,273. All 21 set enable-hydra-gates: true and resolve this file at @main, so a blocking launch reddens most of the fleet the minute it merges. The runner passes --warn-only and calls _warn, never _fail. Promotion to blocking is two deliberate edits in the gate block, and the l10n debt sweep owns that call.

What I verified

  • Acceptance suite scripts/lib/test_gate117_l10n_source_coverage.sh, auto discovered by run-helper-suites.sh. Five cases, all green.
  • The control that matters: the planted fixture hides one PHP string and one schema title, and leaves src/ and the manifest covered. Run at the incumbent's --source=SRC,MANIFEST scope it reports 0 missing. Run at the full scope it reports 2. The suite asserts both, so the promoted checker is proven to find what the copies could not.
  • The gate block executed against all four trees with stub helpers: clean gives PASS, planted gives WARNING, no catalogue gives SKIPPED na, a non app directory gives SKIPPED na.
  • A crash is not a finding: a malformed lib/Settings/*.json gives exit 9 with no terminal marker, and the block reports SKIPPED wiring.
  • Live run on opencatalogi at development@4af8e55a: 368 missing from en.json, being SCHEMA 319 and PHP 49, and 0 from SRC. The src leg agreeing with the incumbent is the point. The new findings come from the new sources, not from a stricter reading of the old one.
  • bash -n and shellcheck -S error clean on run-hydra-gates.sh.

Migration

hydra-gates/MIGRATION-check-l10n.md, linked from the README. It covers running the shared checker, comparing counts against the vendored copy, the reason bearing l10n/.l10n-source-ignore.json, and deleting the local copy. No app is changed in this pass.

Inherited findings

None introduced. The fleet counts this gate surfaces are pre-existing debt and belong to the l10n sweep, which is why the gate warns.

Base

main. The ten most recent pull requests on this repository all target main, and this repository has no development branch.

🤖 Generated with Claude Code

…not only as unused

Every vendored check-l10n.js in the fleet computed `missing` from src/ t()
calls alone. PHP and schema JSON, where they were read at all, only cleared an
"unused" warning. So no app could see a server-side or schema string that had
reached no catalogue.

Thirteen distinct versions of that script exist across fifteen repositories,
and all thirteen share the defect. This promotes one copy into hydra-gates and
widens it: SRC, PHP, MANIFEST and SCHEMA all feed missing.

Warning only at launch. Fourteen of twenty-one repos carry inherited findings
and openregister alone carries 1,273, so a blocking gate would redden most of
the fleet on merge. The runner passes --warn-only and calls _warn, never _fail.

Acceptance suite included. Its control asserts that the planted tree reads
clean at the incumbent's src-only scope, so the promoted checker is proven to
find what the copies could not.

This branch has not been deployed

No deployments
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