I3092 — A translation-memory edit says which pages each changed key reaches, and refuses one that reaches none
Have the i18n pass write target/site-i18n/reach.json, every segment key of the English pages with the pages it occurs on, and give scripts/site-translate a `reach` command that lists, for every memory entry changed against a revision, the pages its key reaches and refuses (exit 10) one that reaches none; `import` refuses an entry whose key reaches no page.
DONE wave 0 · p2 · implementation profile · runs alone
Part of public-proof — A visitor sees the product prove itself, and can check every claim it makes.
Objective
Have the i18n pass write target/site-i18n/reach.json, every segment key of the English pages with the pages it occurs on, and give scripts/site-translate a `reach` command that lists, for every memory entry changed against a revision, the pages its key reaches and refuses (exit 10) one that reaches none; `import` refuses an entry whose key reaches no page.
Why
On 2026-10-20 a hand edit put the Czech for the site bar's toggle on the key of the plain sentence 'How it works' instead of the toggle's 'How it works<t1/>'. The memory took it, the bar stayed English, and only a peer reading the live page saw it. A key that no page carries is a translation nobody will ever read, and nothing said so.
Current state
The pass lists only what the memory does not know (missing.json); an entry whose key no page carries is kept silently, and site-translate import admits any key with a matching English.
Desired state
reach.json is written beside missing.json; `site-translate reach` names, for each changed key, its pages or that it reaches none, and fails on the latter; import refuses an unreachable key.
Scope
- scripts/lib/site-i18n.mjs
- scripts/site-translate
- test/cases/3590_the_site_is_derived_in_every_language.sh
- .ai/repo/project/issues/I3092.yaml
Out of scope
- Garbage-collecting unreachable entries already in the memory (they are listed, not removed)
Dependencies
None. This issue is a root of the graph.
Acceptance criteria
- reach.json lists every segment key of the English pages with its page count
- A changed memory entry whose key no page carries is named and refused; one whose key a page carries is listed with its pages
- import refuses an entry whose key reaches no page
Validation
- env -u MAJORDOMUS_SHARE bash test/run.sh 3590_the_site_is_derived_in_every_language
Evidence required
- unreached_key_is_refused
Evidence
| covers | type | command | result | at commit |
|---|---|---|---|---|
| unreached_key_is_refused | ci | bash test/run.sh 3590_the_site_is_derived_in_every_language | passed in train 3a validate 39712017896 (76c57859663, landed on master 2026-10-22) | 76c5785 |
Timeline
- started
- 2026-10-21T01:47:57Z
- verified
- 2026-10-21T01:51:20Z
- completed
- 2026-10-22T04:42:16Z
Those three fields, the evidence above and the state of the dependencies are all the status is made of. There is no status field to disagree with them.
Canonical record: .ai/repo/project/issues/I3092.yaml. Read it back with majordomus plan show I3092.