--- type: types/instruction.md name: 3.0.0-authoring-conventions description: 'Adopt the instance-owned authoring conventions introduced in 3.0.0 - write kb/CONVENTIONS.md, declare profile:/required_by_stack: on every COLLECTION.md, and replace kb/CONTRACT.md with the shipped one.' manual: true migrates_to: 3.0.0 migration_kind: mechanical --- # Adopt this instance's own authoring conventions (3.0.0) Until 3.0.0, the rules for writing a page were split by *location*: everything about `kb/` sat in `kb/CONTRACT.md`, a file every distribution ships verbatim. Half of it was never the stack's to decide - the language pages are written in, the three tool-owned section headings, the naming forms, the tone, the relationship labels, the confidence rubric - so an instance that wanted something else edited a file the stack also ships, and an upstream merge handed the stack's answer back. 3.0.0 splits it by *ownership* instead. `kb/CONTRACT.md` keeps only what `wikitool` enforces; everything else moves into a new `kb/CONVENTIONS.md` that belongs to this instance, and each `kb//COLLECTION.md` now declares what it is. The compiler reads its section headings from that file rather than from `tools/chemenu/sections.py`. **No page changes.** Not one line under `kb/entities/`, `kb/concepts/`, `kb/sources/` or `kb/comparisons/` is touched. What changes are the contracts beside them, which is why this is `mechanical` and takes minutes rather than a workshop. ## When to run After installing 3.0.0 machinery over an instance that was on 2.x, when `tools/wikitool doctor` reports `FAIL conventions` or `tools/wikitool docs verify` reports a `COLLECTION.md` with no frontmatter. `tools/wikitool migrate status` names this document. **Until it has run, the compiler answers out of a fallback.** `xref add` and `cite add` write `## Beziehungen` / `## Siehe auch` / `## Fußnoten` - what this stack hardcoded before the conventions file existed. That is correct for a corpus written under them and wrong for any other, so run this before the next `wiki-ingest` or `wiki-manage`, not afterwards. ## Steps 1. **Replace `kb/CONTRACT.md` from the release.** It is machinery that happens to live under a content directory, and the tarball update path used to skip it (see `INSTALL.md`, which now names it explicitly). The 3.0.0 version is roughly half the length of the 2.x one - the removed half is what step 2 is about to write into a file of yours. ```bash cp /kb/CONTRACT.md kb/CONTRACT.md ``` A private instance cloned from an upstream takes it with the merge instead - see [private-instance.md](../private-instance.md), whose update procedure now re-takes the upstream side for exactly this path. 2. **Write `kb/CONVENTIONS.md`.** Two ways in, and the first is almost always right: - **This instance writes German pages** (it did, unless you changed it): copy the release's `kb/CONVENTIONS.md.template` and fill it from the `german` profile in [kb-profiles.md](../kb-profiles.md) - whose worked full text is the origin repo's own `kb/CONVENTIONS.md`. Everything in it was already true of your corpus; it was simply written down somewhere you did not own. - **You had changed the language**, and therefore hold local edits to `kb/CONTRACT.md`, `types/*.md` and `tools/chemenu/sections.py`: those edits are what this file replaces. Copy the canonical heading names out of your old `sections.py` into `sections:`, the labels and tone rules out of your old `kb/CONTRACT.md`, then **discard the local edits under `tools/` and `types/`** and take the shipped versions. That is the whole point of the change: there is nothing left to patch there. The minimum the tool needs is the frontmatter: ```yaml --- language: de profile: german sections: relationships: Beziehungen see_also: Siehe auch footnotes: Fußnoten --- ``` Set `sections:` to the names **your existing pages already carry**, not to what you would prefer. Changing them is a separate, real corpus migration; `section_aliases:` is how it is done page by page ([migrate-corpus.md](../migrate-corpus.md)). Drop the `wikitool:template-unfilled` sentinel line while filling it in - `doctor` FAILs on a renamed-but-unanswered template exactly as it does for `USER.md`. 3. **Declare each collection.** Two frontmatter lines at the top of every `kb//COLLECTION.md`: ```yaml --- profile: required_by_stack: false --- ``` `required_by_stack: true` on `kb/sources/` and **nowhere else**. It is not a preference: `sources coverage`, `[^cite-id]` resolution and `kb/provenance.md` resolve against that name, and `docs verify` checks the field against the stack's own list in both directions. For the four default collections, the shipped `kb//COLLECTION.md.template` files carry the right values already. 4. **Verify.** All three must pass: ```bash tools/wikitool doctor # `conventions` must be OK tools/wikitool docs verify tools/wikitool lint ``` `migrate verify` is deliberately not in that list: it compares pages, and no page changed. Running it would report nothing and prove nothing. 5. **Record it.** ```bash tools/wikitool migrate done 3.0.0 --pages 0 ``` `--pages 0` is honest, not a placeholder - see the note under step 1. ## How to tell a migrated instance from an unmigrated one `kb/CONVENTIONS.md` exists, carries no `wikitool:template-unfilled` line, and names all three slots under `sections:`; every `kb/*/COLLECTION.md` opens with a frontmatter block; and `kb/CONTRACT.md` has a `## Language and identifiers` heading rather than a `## Language` one. `doctor` answers all of that in one call. ## Decision points - **`doctor` says `conventions: FAIL` after step 2?** It prints which slot is missing. The three keys are `relationships`, `see_also` and `footnotes` - the *slot* names are fixed, only their values are yours. - **A collection this instance invented, with no profile behind it?** `profile: none`. The field records where the text came from; it is free text and `docs verify` does not check it against the catalogue, because an invented collection has no entry there to name. - **Tempted to point `profile:` at the catalogue instead of copying the text?** Do not. An adopted profile is a copy; a reference would put your binding authoring rules in a file the stack ships and upgrades, which is the arrangement 3.0.0 exists to end. - **Your old `kb/CONTRACT.md` had local edits you still want?** They belong in `kb/CONVENTIONS.md` now. If something you edited has no home there, it was a stack rule you overrode - file it as an issue against the origin repo rather than re-applying it. ## Scope One instance's contracts, once. It changes no page, no frontmatter on a page, and nothing under `raw/`. The machinery half of the 3.0.0 upgrade - copying `tools/`, `types/`, `instructions/`, `AGENTS.md`, `VERSION` and `.wikitool-release.json` - is `INSTALL.md`'s, and has to have happened before step 1.