I3438 — A translation records the digest of its source, and site-check refuses one its source has moved past
A translation names its source and the digest of the source it was made from, [extra] translated_from = \"route/\" and source_digest = the SHA-256 of the source's bytes after its closing front-matter fence; site-check recomputes the digest and refuses a stale or missing one, printing the file, its source and the digest to record once re-synced, and refuses a digest on an original and a source outside the group. The check never rewrites a digest.
READY wave 1 · p2 · implementation profile · runs alone
Part of public-proof — A visitor sees the product prove itself, and can check every claim it makes.
Ready. Every dependency is done, so majordomus plan start I3438 will be accepted.
Objective
A translation names its source and the digest of the source it was made from, [extra] translated_from = \"route/\" and source_digest = the SHA-256 of the source's bytes after its closing front-matter fence; site-check recomputes the digest and refuses a stale or missing one, printing the file, its source and the digest to record once re-synced, and refuses a digest on an original and a source outside the group. The check never rewrites a digest.
Why
The owner asked on 2026-10-19 that language versions be kept in sync automatically. A translation silently trails an original edited after it, and nothing could tell; the re-sync is the translator's act, so the check makes the drift loud rather than hiding it by restamping. It belongs to public-proof with I3436 and I3437, whose check it extends.
Current state
No front matter key names the page a translation was made from, and nothing compares a translation with its source: site/content-src/dokumentace-kterou-lze-odmitnout.md and site/content-src/proof-carrying-documentation.md name each other by alternate only, so either may change without the other.
Desired state
Check 21 emits each translated_from row, recomputes the source's body digest with lib/sha256.sh, passes a match, and refuses a mismatch or an absent digest with the new digest in the message; an edit to the source's front matter alone leaves the digest fresh; case 3503 holds a fresh, a stale and a missing digest and proves the translation file is left untouched.
Scope
- scripts/site-check
- test/cases/3503_a_translation_group_agrees_and_keeps_up_with_its_source.sh
- .ai/repo/project/issues/I3438.yaml
Dependencies
Acceptance criteria
- A translation whose source_digest matches its source's body passes
- A source whose body changed after the digest fails naming the translation, its source and the digest to record, and the translation file is unchanged
- A translated_from without a digest, a digest without translated_from and a source outside the group each fail naming the file
- An edit to the source's front matter alone does not make its translations stale
Validation
- env -u MAJORDOMUS_SHARE -u MAJORDOMUS_HTTP_HOST -u MJ_ROOT bash test/run.sh 3503_a_translation_group_agrees_and_keeps_up_with_its_source
Evidence required
- stale_translation_is_refused
- fresh_translation_passes
Evidence
None recorded. Every token above needs a command or an artifact behind it before this issue can be completed; narrative is refused.
Timeline
- started
- —
- verified
- —
- completed
- —
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/I3438.yaml. Read it back with majordomus plan show I3438.