docs: the adoption page lives here, and a test reads it #10

Merged
seeds-agent merged 1 commit from docs/the-adoption-page-is-checked into main 2026-10-28 20:33:11 +00:00
Collaborator

A page is a second source of truth the moment it is written

And a reader trusts the page over the registry, because the page is the one they can read. So the seeds-infra adoption page moves into docs/ — in English, as everything versioned here is — and tests/artifact_sync.py confronts it with registry/.

Its data is a JSON island, not a JavaScript literal: the test reads the same bytes the page renders. Parsing JavaScript would mean checking a transcription of the page rather than the page.

What is confronted, and the directions matter

org, env, target, domain EQUAL to the registry, not a subset. The decoder recognises tokens BY POSITION, so a code it does not know is painted as something else — and a code the registry dropped paints a name that can no longer exist
slug, location a subset (714 slugs and 57 locations are declared), plus every slug and location the page's own names use. That second half is what makes a subset safe
every v3 name through the kit's own checker, for the type the row names — 44 names
a run-shaped token refused anywhere but last
every tag row its keys against tags.order — 11 keys

The run rule had to exist separately, and that is the interesting part

see-prd-frg-ops-runner-r7f3-vm-01

This parses perfectly: r7f3 is a legal qualifier, so the checker has nothing to say. Only a reader sees a rehearsal segment sitting where a refinement belongs. A grammar cannot catch it; a rule about position can.

The first revision had already drifted

Which is why none of this is hypothetical. It showed that very name, and it tagged an entity as entity.dsd where the key is target. Both are caught now.

A third suspicion of mine was wrong: gbl IS a declared location code, and the test said so when I tried to break it with one.

Eight mutations of the page, all crying out

the run back in the qualifier slot    carries ['r7f3'] outside the last position
a tag key nobody emits                tag key 'entity' is not in tags.order
an org code dropped                   vocab.org is not the registry's - missing ['dgt']
an env code the registry has not      declares ['tst'], absent from the registry
a slug the page omits                 the page's own names use slug ['bkt']
a wrong slug on a real type           does not follow the standard grammar
a target code that is not one         does not follow the standard grammar
the island hidden                     refusing to pass on 0 rows, 0 names

The last one trips the floors rather than passing on an empty sweep — the shape of the ninth false positive found in this repository.

Two exceptions, for the stylesheet

font and sans are in the French word list. Scoped to docs/ with their reason: a stylesheet is not prose.

Verification

make check green, with artifact-sync now in it:

artifact-sync: 1 page, 70 rows, 44 names and 11 tag keys confronted with the registry, 0 findings
english:       92 files, 63,229 lines, 6 named exceptions, 0 findings

The hosted copy is republished from this very file, so the page and the repository hold the same bytes.

Branched from main, so it does not stack on #8. They touch CHANGELOG.md and README.md; whichever merges second gets rebased.

🤖 Generated with Claude Code

## A page is a second source of truth the moment it is written And a reader trusts the page over the registry, because the page is the one they can read. So the seeds-infra adoption page moves into `docs/` — in English, as everything versioned here is — and `tests/artifact_sync.py` confronts it with `registry/`. **Its data is a JSON island**, not a JavaScript literal: the test reads the same bytes the page renders. Parsing JavaScript would mean checking a transcription of the page rather than the page. ## What is confronted, and the directions matter | | | | --- | --- | | `org`, `env`, `target`, `domain` | **EQUAL** to the registry, not a subset. The decoder recognises tokens BY POSITION, so a code it does not know is painted as something else — and a code the registry dropped paints a name that can no longer exist | | `slug`, `location` | a subset (714 slugs and 57 locations are declared), **plus** every slug and location the page's own names use. That second half is what makes a subset safe | | every v3 name | through the kit's own checker, for the type the row names — **44 names** | | a run-shaped token | refused anywhere but last | | every tag row | its keys against `tags.order` — **11 keys** | ## The run rule had to exist separately, and that is the interesting part ``` see-prd-frg-ops-runner-r7f3-vm-01 ``` This parses **perfectly**: `r7f3` is a legal qualifier, so the checker has nothing to say. Only a reader sees a rehearsal segment sitting where a refinement belongs. A grammar cannot catch it; a rule about position can. ## The first revision had already drifted Which is why none of this is hypothetical. It showed that very name, and it tagged an entity as `entity.dsd` where the key is `target`. Both are caught now. A third suspicion of mine was **wrong**: `gbl` IS a declared location code, and the test said so when I tried to break it with one. ## Eight mutations of the page, all crying out ``` the run back in the qualifier slot carries ['r7f3'] outside the last position a tag key nobody emits tag key 'entity' is not in tags.order an org code dropped vocab.org is not the registry's - missing ['dgt'] an env code the registry has not declares ['tst'], absent from the registry a slug the page omits the page's own names use slug ['bkt'] a wrong slug on a real type does not follow the standard grammar a target code that is not one does not follow the standard grammar the island hidden refusing to pass on 0 rows, 0 names ``` The last one trips the **floors** rather than passing on an empty sweep — the shape of the ninth false positive found in this repository. ## Two exceptions, for the stylesheet `font` and `sans` are in the French word list. Scoped to `docs/` with their reason: a stylesheet is not prose. ## Verification `make check` green, with `artifact-sync` now in it: ``` artifact-sync: 1 page, 70 rows, 44 names and 11 tag keys confronted with the registry, 0 findings english: 92 files, 63,229 lines, 6 named exceptions, 0 findings ``` The hosted copy is republished from this very file, so the page and the repository hold the same bytes. > Branched from `main`, so it does not stack on #8. They touch `CHANGELOG.md` and `README.md`; whichever merges second gets rebased. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(registry)!: a forge namespace is a rule, not a charset
Some checks failed
ci / check (pull_request) Has been cancelled
b176a88c29
`forgejo_organization` was style `free`: the caller supplied the name and the kit
validated the charset and the length. The rule — a namespace is an org's long
form, plus the reserved `shared` — lived in the type's own notes, where nothing
could enforce it. `dataseeds` was accepted: typeable, inside the charset, under
40 characters, and an answer to no question the convention asks.

A forge namespace is named by the ORG AXIS, because that is what it answers:
whose is this repository. The long form and not the code — a human types it into
a URL, and `see/infra-conventions` would read as noise.

So: a new style, `namespace`, in all three implementations.

  name supplied by nobody   the module derives it from context.org
  name supplied             accepted only if the rule already allows it
  anything else             refused, by the module AND by the policy

And a `namespaces` block in `registry/conventions.yaml` declaring what the names
are drawn from (`org.long`) beside the reserved ones (`shared`). Derived, never
written out: adding an org adds its namespace.

  see -> seeds        per -> personal        dgt -> digitank        + shared

TWO LINTS, because the set has to stay unambiguous. A reserved name that is also
an org long form would make one namespace answer two questions — "the org seeds"
and "held over every org" — and no rename repairs it: a forge namespace sits in
every clone URL already written down. And `namespaces.from` is confronted with
the one value that is implemented, so a typo there cannot silently mean nothing.

Verified, and each guard mutation-tested:

  75 module tests   (+5: 4 shared cases, 1 refusal)
  55 policy tests   (+5: the org form, the reserved one, a free name, an org
                     code, and a repository that stays free)
  13 lint mutations (+2), 0 silent

The module precondition was mutated to always pass and `namespace_outside_the_rule`
failed, which is the only thing that makes its green mean anything. OpenTofu
refuses a constant precondition outright, so the mutation had to stay referential.

A repository stays `free`: it is a functional name like a DNS record, and
recomposing it by the grammar would produce a URL nobody would type either.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
docs: the adoption page lives here, and a test reads it
Some checks failed
ci / check (pull_request) Has been cancelled
9f34baa3fb
A page showing a convention becomes a second source of truth the moment it is
written, and a reader trusts the page over the registry because the page is the
one they can read. So the seeds-infra adoption page moves into docs/ - in
English, as everything versioned here is - and tests/artifact_sync.py confronts
it with registry/.

ITS DATA IS A JSON ISLAND, not a JavaScript literal. The test reads the same
bytes the page renders; parsing JavaScript would mean the test checked a
transcription of the page rather than the page.

What is confronted, and the directions matter:

  org, env, target, domain   EQUAL to the registry, not a subset: the page's
                             decoder recognises tokens BY POSITION, so a code it
                             does not know is painted as something else, and a
                             code the registry dropped paints a name that can no
                             longer exist
  slug, location             a subset (714 slugs and 57 locations are declared),
                             plus every slug and location the page's OWN names
                             use. That second half is what makes a subset safe
  every v3 name              through the kit's own checker, for the type the row
                             names - 44 names
  a run-shaped token         refused anywhere but last
  every tag row              its keys against tags.order - 11 keys

THE RUN RULE NEEDED TO EXIST SEPARATELY, and that is the interesting part.
`see-prd-frg-ops-runner-r7f3-vm-01` parses perfectly: r7f3 is a legal
qualifier, so the checker has nothing to say. Only a reader sees a rehearsal
segment sitting where a refinement belongs.

AND THE FIRST REVISION HAD ALREADY DRIFTED, which is why this is not
hypothetical. It showed that very name, and it tagged an entity as `entity.dsd`
where the key is `target`. Both are now caught. A third suspicion of mine was
wrong: `gbl` IS a declared location code, and the test said so.

Eight mutations of the page, all crying out: the run in the qualifier slot, a
tag key nobody emits, an org code dropped from the decoder, an env code the
registry has not, a slug the page omits, a wrong slug on a real type, a target
code that is not one, and the island hidden - which trips the floors rather than
passing on an empty sweep.

Two exceptions added for the CSS: `font` and `sans` are French words, scoped to
docs/ with their reason, because a stylesheet is not prose.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
seeds-agent force-pushed docs/the-adoption-page-is-checked from 9f34baa3fb
Some checks failed
ci / check (pull_request) Has been cancelled
to cc4c756572
Some checks failed
ci / check (pull_request) Has been cancelled
2026-10-28 20:33:09 +00:00
Compare
seeds-agent deleted branch docs/the-adoption-page-is-checked 2026-10-28 20:33:11 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
shared/infra-conventions!10
No description provided.