content-model: state the language-suffix shape and the collision rule

The parser treats two or three lowercase letters before .md as a language and
rejects a key claimed by two spellings of one variant. Both were implemented and
neither was in the doc that owns the disk contract.

Folded from a separate state commit:
state: point verified-against at the commit that introduced code
This commit is contained in:
Claude Opus 5
2026-07-30 01:30:46 +06:00
committed by bdeshi
parent f1d31437be
commit 192b0fb993
2 changed files with 7 additions and 3 deletions
+6 -2
View File
@@ -49,8 +49,12 @@ overrides the defaults the binary embeds, so a bare root still renders.
- The bundle key is its path relative to `<site>/content/`, minus language and extension. It is the cache
key, the dependency key, and the identity in ADR-0004. It never changes silently.
- The language suffix is optional and its absence means the default locale, always — not only while one
language exists (ADR-0021). `about.md` and `about.en.md` are the same variant; the parser accepts
either. Fallback chain: requested → default → any → 404.
language exists (ADR-0021). A suffix is **two or three lowercase letters** before `.md`, so
`about.bn.md` carries a language and `my.post.md` does not. Fallback chain: requested → default → any
→ 404.
- One key and language may be claimed by only one file. `about.md`, `about.en.md` and `about/index.md`
all name the same variant, so any two of them together are ambiguous and **none** is served — logged,
not fatal (ADR-0029).
- `_index.<lang>.md` in a directory containing other bundles makes that directory itself a bundle (a
section or series landing page) rather than a plain container.
- Local assets sit beside the body, referenced relatively. Assets never live in frontmatter. Moving a
+1 -1
View File
@@ -1,6 +1,6 @@
# State
**Verified against:** `1c19727` on 2026-07-30 — update this line every change.
**Verified against:** `d66c3cb` on 2026-07-30 — update this line every change.
If this file disagrees with the code, the code is right and this file is a bug.
## Inventory