feat: Autorenkonventionen nach Eigentum geschnitten - kb/CONVENTIONS.md, deklarierte Collections (3.0.0)
CI / verify (push) Successful in 53s
Release / release (push) Successful in 38s

Files changed:
- .gitea/workflows/ci.yml
- .wikitool-kb.json
- AGENTS.md
- CHANGES.md
- INSTALL.md
- README.md
- VERSION
- instructions/CONTRACT.md
- instructions/dev/testing-conventions.md
- instructions/german-terminology.md
- instructions/kb-profiles.md
- instructions/migrations/3.0.0-authoring-conventions.md
- instructions/private-instance.md
- instructions/setup-instance.md
- instructions/wiki-ingest/SKILL.md
- instructions/wiki-manage/SKILL.md
- kb/CONTRACT.md
- kb/CONVENTIONS.md
- kb/CONVENTIONS.md.template
- kb/comparisons/COLLECTION.md
- kb/concepts/COLLECTION.md
- kb/entities/COLLECTION.md
- kb/sources/COLLECTION.md
- tools/CONTRACT.md
- tools/README.md
- tools/chemenu/commands/dist_cmd.py
- tools/chemenu/commands/docs_verify.py
- tools/chemenu/commands/doctor.py
- tools/chemenu/commands/new_page.py
- tools/chemenu/conventions.py
- tools/chemenu/kb_collections.py
- tools/chemenu/kb_scan.py
- tools/chemenu/provenance.py
- tools/chemenu/sections.py
- tools/chemenu/tests/conftest.py
- tools/chemenu/tests/test_conventions.py
- tools/chemenu/tests/test_dist_cmd.py
- tools/chemenu/tests/test_doctor.py
- tools/chemenu/tests/test_new_page.py
- tools/chemenu/tests/test_types_cmd.py
- types/comparison.md
- types/concept.md
- types/entity.md
- types/source.md
- types/type-spec.md
This commit is contained in:
2026-09-02 15:02:10 +02:00
parent 9843df99d3
commit 502971d147
45 changed files with 1817 additions and 232 deletions
+74 -72
View File
@@ -7,12 +7,25 @@ material in `raw/`, and is expected to stay correct without being re-derived.
**Quality goal:** a page should answer a future question *without* re-reading the source it
came from. If answering still requires the raw file, the page is incomplete.
This file holds the rules that apply in **every** collection. Each `kb/<name>/COLLECTION.md`
declares that it inherits them and adds only what is local to its own subtree - read this file
together with the target collection's contract before writing or editing a page.
This file holds the rules that apply in **every** collection **and in every instance**. That
second half is the cut: what is written here is enforced by `tools/wikitool` or follows from
how it works, so it is identical everywhere and `dist export` ships it verbatim.
**What an instance decides for itself is next door, in
[kb/CONVENTIONS.md](CONVENTIONS.md)** - the language pages are written in and its three
tool-owned section headings, the naming forms, the tone, the relationship-label vocabulary, the
confidence rubric. That file binds exactly as this one does; it is simply owned by the instance
rather than by the stack, so the distribution ships only its `.template` and the instance writes
the real one. Read both, plus the target collection's `kb/<name>/COLLECTION.md` (also
instance-owned), before writing or editing a page.
The split is by **who may change the sentence**, not by what it is about. Language, tone and
naming used to sit here, which meant every instance that answered "not German" to
`setup-instance.md` was locally editing a file the stack also ships - and a merge from upstream
would quietly hand it back.
Structural facts (which frontmatter fields exist, which are required, what the body skeleton
looks like) are *not* here - they belong to the type-specs and are printed by
looks like) are in neither - they belong to the type-specs and are printed by
`tools/wikitool types describe <type>`. Never hand-write frontmatter; scaffold with
`tools/wikitool new <type> --name "<Name>" --set field=value ...`.
@@ -21,7 +34,15 @@ looks like) are *not* here - they belong to the type-specs and are printed by
`kb/` is a **namespace, not a collection**. It carries no `COLLECTION.md` of its own.
A directory under `kb/` is a **collection** exactly when it contains a `COLLECTION.md`. That
file is the local authoring contract for every page in the subtree.
file is the local authoring contract for every page in the subtree, and it belongs to the
instance: it declares in its frontmatter which profile from
[instructions/kb-profiles.md](../instructions/kb-profiles.md) it adopted, and whether the stack
resolves against it by name.
| Field | Means |
|---|---|
| `profile:` | Which catalogue entry this contract started from, or `none`. Free text - the catalogue is a palette, not an enum, and a collection an instance invented has no entry to name |
| `required_by_stack:` | Whether `wikitool` itself depends on this collection *by name*. Not the instance's to choose: `docs verify` checks it against the stack's own list. `kb/sources/` is `true` - `sources coverage`, `[^cite-id]` resolution and `kb/provenance.md` all resolve against that name - and everything else is `false` |
- A subdirectory *inside* a collection is an **area**. It inherits the enclosing contract and
must not carry a `COLLECTION.md` of its own - `kb/entities/systems/` is an area of
@@ -40,9 +61,11 @@ file is the local authoring contract for every page in the subtree.
| `kb/sources/` | One summary page per ingested source, carrying its `raw_files:` provenance | [sources/COLLECTION.md](sources/COLLECTION.md) |
| `kb/comparisons/` | Structured comparisons of two or more existing pages | [comparisons/COLLECTION.md](comparisons/COLLECTION.md) |
**Adding a collection:** `mkdir kb/<name>` and write a `kb/<name>/COLLECTION.md`. Collections
The four rows above are this instance's collections, not a fixed set. **Adding one:**
`mkdir kb/<name>` and write a `kb/<name>/COLLECTION.md` with the two fields above. Collections
are discovered by contract presence, so no code change is needed. A collection only becomes
*writable* once some type-spec declares a matching `base_dir:`.
*writable* once some type-spec declares a matching `base_dir:`. Renaming or dropping one is the
instance's call too - except where `required_by_stack: true` says otherwise.
**Where a page goes** is decided by its type-spec, never by hand - see
[types/type-spec.md](../types/type-spec.md).
@@ -61,18 +84,16 @@ Never hand-edit these; they are produced by `tools/wikitool`:
To *find* a page, search rather than read the catalog: `tools/wikitool search "<text>"`, or
`tools/wikitool search --field <predicate>` for a structured query over frontmatter.
## Naming
## Titles are identifiers
- Human-readable titles with spaces: `Hybrid Search.md`, `Gitea Actions.md` - not kebab-case.
- Singular for entities: `ha-core.md`, not `ha-cores.md`.
- Comparison pages read as a comparison: `Go vs Rust.md`.
- ADRs are prefixed: `adr-001-use-go-modules.md`.
- The filename stem *is* the page title, and `[[wikilinks]]` must match it exactly.
- Prefer readability over convention when the two conflict.
**The filename stem *is* the page title, and `[[wikilinks]]` must match it exactly.** That is
not a naming preference; it is the wiki's only way to address a page. `wikitool lint` reports an
H1 that stops matching its title, `rename`/`rm` rewrite every reference to a stem, and a
`[^cite-id]` resolves through one.
What to name a thing: projects use their repository or common name; systems a descriptive
name; tools the tool's own name; technologies their standard spelling and capitalization;
people a full name or common handle.
Which *form* those titles take - spaces or kebab-case, singular or plural, what prefixes a
decision record - is the instance's, in
[kb/CONVENTIONS.md § Naming](CONVENTIONS.md#naming).
## Every page should
@@ -83,31 +104,20 @@ people a full name or common handle.
- [ ] Duplicate no existing page
- [ ] Appear in the catalog (guaranteed by `wikitool index rebuild`)
## Tone
## Quotation cap
Wikipedia style: factual, neutral, specific.
At most 2 blockquoted lines per page. `wikitool lint` reports overages as advisory, since
exceeding the cap can be a legitimate judgment call - but the page should carry the knowledge
itself, not delegate it to quotations. The cap is about how much of the page you let quotes
carry; it does not apply to text you are citing verbatim from a source.
- No buzzwords ("bahnbrechend", "hochmodern", "leistungsstark", "revolutioniert").
- No AI filler ("es sei angemerkt", "es ist wichtig zu betonen", "in der heutigen Zeit").
- No em-dash asides carrying parenthetical reasoning.
- At most 2 blockquoted lines per page. `wikitool lint` reports overages as advisory, since
exceeding the cap can be a legitimate judgment call - but the page should carry the
knowledge itself, not delegate it to quotations. The cap is about how much of the page you
let quotes carry; it does not apply to text you are citing verbatim from a source.
The register those lines are written in - what counts as a buzzword, what filler is refused -
is the instance's, in [kb/CONVENTIONS.md § Tone](CONVENTIONS.md#tone).
Good: "MQTT ist ein leichtgewichtiges Publish-Subscribe-Protokoll für Geräte mit knappen
Ressourcen."
## Language and identifiers
Bad: "MQTT ist ein bahnbrechendes, hochmodernes Protokoll, das die IoT-Kommunikation
revolutioniert - und es sei angemerkt, dass es ein Publish-Subscribe-Muster verwendet."
## Language
Pages are written in **German**. This binds `kb/` and the authoring surface that shapes it -
the page type-specs `types/entity.md`, `types/concept.md`, `types/source.md` and
`types/comparison.md`. `raw/` is untouched ([raw/CONTRACT.md](../raw/CONTRACT.md)), and the
control plane stays English: AGENTS.md, the stage contracts including this one, `instructions/`,
and the type-specs for non-page artifacts.
*Which* language pages are written in is [kb/CONVENTIONS.md](CONVENTIONS.md)'s to say. What
follows here is the part that is not a choice, because the tool resolves against it.
Every line of a page is either **prose** or an **identifier**. Only prose is translated.
@@ -118,20 +128,14 @@ source page's Summary / Key Takeaways / Action Items / Not Extracted, and `summa
| Identifier | Why |
|---|---|
| Page titles, and the H1 that repeats one | A title is the wiki's only identifier for a page and follows the subject's own established name - see [Naming](#naming). `wikitool lint` reports an H1 that stops matching its title |
| Page titles, and the H1 that repeats one | A title is the wiki's only identifier for a page and follows the subject's own established name - see [Titles are identifiers](#titles-are-identifiers). `wikitool lint` reports an H1 that stops matching its title |
| The subtype value on the generated `**Typ:**` line | It renders a schema enum value (`technology`, `workflow`), which `search --field` filters on. The label is prose; the value is not |
| `tags:` | Search keys, not prose |
| Commands, paths, config keys, hostnames, code | They are what they are |
| Quotations | Quoted verbatim in the source's own language |
Established English technical terms stay English inside German prose - "GitOps", "Ownership
Model", "Reverse Proxy", "Pull Request". Translate a term only where the German one is genuinely
the more common usage. A coined German equivalent nobody else writes makes the page harder to
find, not more idiomatic.
Which terms those are, which have a settled German form, and the register the prose is written in:
[instructions/german-terminology.md](../instructions/german-terminology.md). It is lookup material,
not a second rule - every entry in it is a decision that was made wrong once first.
Which foreign technical terms stay untranslated inside that prose is a judgment call the
instance records - see [kb/CONVENTIONS.md § Language](CONVENTIONS.md#language).
**A source in another language** is still summarized in the KB language: a source page is
evidence *about* a source, not a substitute for it. Quote verbatim in the original language and
@@ -141,14 +145,18 @@ record the raw file's language in `source_language:`.
Three headings are a vocabulary the tool owns rather than prose an author picks: `xref add`
writes into Relationships and See Also, and `cite add` owns the trailing Footnotes block. They
follow the KB language like everything else - `## Beziehungen`, `## Siehe auch`, `## Fußnoten` -
and `tools/chemenu/sections.py` is the single place naming them.
follow the KB language like everything else, so **the instance names them**, in
`kb/CONVENTIONS.md`'s `sections:` frontmatter. `tools/chemenu/conventions.py` reads that
declaration and `tools/chemenu/sections.py` is what the rest of the compiler asks - there is no
heading text in the compiler itself.
Each has aliases the tool still *recognizes* but no longer writes, which is what lets the corpus
be translated page by page: a page still carrying `## Relationships` is found and appended to
correctly, and `cite sync` leaves an untranslated `## Footnotes` heading alone rather than
retitling it. Renaming a heading is the translation pass's job, never a side effect of another
command. Any *other* heading an author adds is ordinary prose and is translated with the rest.
retitling it. The recognized set is the canonical name, any `section_aliases:` the instance
declared, and the names this stack wrote before the declaration existed. Renaming a heading is
the translation pass's job, never a side effect of another command. Any *other* heading an
author adds is ordinary prose and is translated with the rest.
## Linking
@@ -156,14 +164,10 @@ Every page links to what it mentions, in both directions. Cross-references are c
`tools/wikitool xref add --a "<A>" --b "<B>" --rel-a "<label>" --rel-b "<label>"`, never by
hand-editing the `related:` array or the Relationships/See Also bullets.
Use a typed relationship label rather than a generic one:
`hängt ab von` · `verwendet` · `implementiert` · `erweitert` · `ersetzt` · `steht in Konflikt mit`
· `benötigt` · `erzeugt` · `konsumiert` · `besitzt` · `pflegt` · `läuft auf` · `verwandt mit`
(last resort)
The labels are prose written into a `- **label:** [[Title]]` bullet; no code matches on them, so
an untranslated page's English label is stale wording, not a broken reference.
Use a typed relationship label rather than a generic one. The label is free text as far as the
tool is concerned - it is written into a `- **label:** [[Title]]` bullet and no code matches on
it - so which vocabulary this instance uses is
[kb/CONVENTIONS.md § Relationship labels](CONVENTIONS.md#relationship-labels)'s to list.
A page is expected to have at least one inbound link; `wikitool lint` reports orphans.
Comparison pages are exempt - they are reached through the catalog.
@@ -187,15 +191,16 @@ Every claim is either traceable to a raw file or explicitly marked as not.
command, or config value. `tools/wikitool cite add --page "<Title>" --source "Source - X"
[--file <qualifier>]` mints the id, upserts its `[[Source - X]]` (or
`[[Source - X|storage-model.md]]` for a multi-file source) definition in the page's trailing
`## Footnotes` block, and adds `Source - X` to `sources:` - it prints the marker to paste at
Footnotes block (named per [Section headings](#section-headings)), and adds `Source - X` to
`sources:` - it prints the marker to paste at
the fact; placing it is still manual. Never hand-type a cite-id (AGENTS.md invariant 1). This
differs from a plain `[[Source - X]]` link, which only means "related to".
- **Notation inside code is notation, not a reference.** A `[^cite-id]` or a `[[wikilink]]`
written in backticks or a fenced block is read as an example: the citation does not count and
the link does not exist. That is what lets a page document this stack's own syntax. It also
means a marker appended to a line *inside* a fence cites nothing - put it on a
`Quelle: [^cite-id]` line under the block, where it renders as a footnote instead of
travelling with the command when someone copies it.
means a marker appended to a line *inside* a fence cites nothing - put it on a source line
under the block (`<source-word>: [^cite-id]`, in the KB language), where it renders as a
footnote instead of travelling with the command when someone copies it.
- A source cited inline must also appear in the page's frontmatter `sources:` list;
`wikitool lint` checks this in both directions, and hard-errors on a leftover pre-migration
`^[[...]]` marker, an undefined `[^cite-id]` reference, or an orphaned Footnotes definition.
@@ -215,23 +220,20 @@ one - and never file the synthesized version back into the wiki.
`confidence` is *derived* from it by `tools/wikitool confidence decay` and must never be
edited directly.
Base score for a single source is 0.5, adjusted by:
- **+0.2 per supporting source** (max +0.6)
- **+0.2** if confirmed <30 days ago, **+0.1** if <90 days
- **+0.1** for official documentation, **+0.05** for a reputable secondary source
- **+0.1** if multiple independent sources agree
Re-assess a page with `tools/wikitool touch --page "<Title>" --confidence-base <value>`.
In prose, hedge according to the score: below 0.6 write "möglicherweise"/"kann"; below 0.4
write "unsicher"/"unbestätigt".
What the number *means* - the base score, what raises it and by how much, and how to hedge in
prose below a threshold - is a rubric rather than a mechanism, so it is
[kb/CONVENTIONS.md § Confidence rubric](CONVENTIONS.md#confidence-rubric)'s.
## What does not belong here
- Raw source material - it stays immutable under `raw/`.
- Type definitions, frontmatter contracts, or templates - those live in `types/`.
- Procedures for operating the tooling - those live in `instructions/`.
- **Anything an instance would have to rewrite for itself** - language, naming forms, tone,
relationship labels, the confidence rubric. Those are `kb/CONVENTIONS.md`'s, and a sentence
of that kind here is a sentence the stack ships over the instance's own answer.
- Rules that apply to only one collection - those belong in that collection's
`COLLECTION.md`.
- Hand-edited generated files - see [Generated files](#generated-files).
+126
View File
@@ -0,0 +1,126 @@
---
language: de
profile: german
sections:
relationships: Beziehungen
see_also: Siehe auch
footnotes: Fußnoten
---
# kb/ - Authoring Conventions of This Instance
The decisions [kb/CONTRACT.md](CONTRACT.md) deliberately does not make. The contract holds what
the code enforces and is identical in every instance; this file holds what *this* instance
chose, and no other instance has to agree with a word of it.
**It binds all the same.** Everything below applies to every page under `kb/`, exactly as the
contract does. The difference is ownership, not authority: a rule here is changed by editing
this file, a rule there by changing the stack.
Adopted from the `german` profile in
[instructions/kb-profiles.md](../instructions/kb-profiles.md). That catalogue is a palette, not
an enum - what is written here is what holds, whether or not a profile says the same thing.
The frontmatter above is the one machine-read part. `sections:` names the three headings
`wikitool xref` and `wikitool cite` write into; `tools/chemenu/conventions.py` reads them and
`tools/chemenu/sections.py` is what the rest of the compiler asks. Renaming one here changes
what the tool *writes*; what it still *recognizes* is the union of that name, any
`section_aliases:` declared beside it, and the names this stack wrote before this file existed.
That asymmetry is the translation path: a page keeps working under its old heading until it is
itself translated.
## Language
Pages are written in **German**. This binds `kb/` and the authoring surface that shapes it -
the page type-specs `types/entity.md`, `types/concept.md`, `types/source.md` and
`types/comparison.md`. `raw/` is untouched ([raw/CONTRACT.md](../raw/CONTRACT.md)), and the
control plane stays English: `AGENTS.md`, the stage contracts, this file, `instructions/`, and
the type-specs for non-page artifacts.
Which line is prose and which is an identifier - and therefore what is translated at all - is
the contract's rule, not this file's: see
[kb/CONTRACT.md § Language and identifiers](CONTRACT.md#language-and-identifiers).
Established English technical terms stay English inside German prose - "GitOps", "Ownership
Model", "Reverse Proxy", "Pull Request". Translate a term only where the German one is genuinely
the more common usage. A coined German equivalent nobody else writes makes the page harder to
find, not more idiomatic.
Which terms those are, which have a settled German form, and the register the prose is written
in: [instructions/german-terminology.md](../instructions/german-terminology.md). It is lookup
material, not a second rule - every entry in it is a decision that was made wrong once first.
### Section headings
The canonical names are the frontmatter's: `## Beziehungen`, `## Siehe auch`, `## Fußnoten`.
The English forms this stack wrote before the corpus was translated are still recognized, so a
page carrying `## Relationships` is found and appended to correctly and `cite sync` leaves an
untranslated `## Footnotes` alone. Renaming such a heading is the translation pass's job, never
a side effect of another command. Any *other* heading an author adds is ordinary prose and is
translated with the rest.
## Naming
- Human-readable titles with spaces: `Hybrid Search.md`, `Gitea Actions.md` - not kebab-case.
- Singular for entities: `ha-core.md`, not `ha-cores.md`.
- Comparison pages read as a comparison: `Go vs Rust.md`.
- ADRs are prefixed: `adr-001-use-go-modules.md`.
- Prefer readability over convention when the two conflict.
What to name a thing: projects use their repository or common name; systems a descriptive
name; tools the tool's own name; technologies their standard spelling and capitalization;
people a full name or common handle.
The one naming fact that is *not* a choice, and therefore lives in the contract: the filename
stem is the page title, and `[[wikilinks]]` must match it exactly.
## Tone
Wikipedia style: factual, neutral, specific.
- No buzzwords ("bahnbrechend", "hochmodern", "leistungsstark", "revolutioniert").
- No AI filler ("es sei angemerkt", "es ist wichtig zu betonen", "in der heutigen Zeit").
- No em-dash asides carrying parenthetical reasoning.
Good: "MQTT ist ein leichtgewichtiges Publish-Subscribe-Protokoll für Geräte mit knappen
Ressourcen."
Bad: "MQTT ist ein bahnbrechendes, hochmodernes Protokoll, das die IoT-Kommunikation
revolutioniert - und es sei angemerkt, dass es ein Publish-Subscribe-Muster verwendet."
The blockquote cap is not here: `wikitool lint` reports it, so it is the contract's.
## Relationship labels
`tools/wikitool xref add --rel-a/--rel-b` takes a free-text label. This instance uses a typed
one rather than a generic one:
`hängt ab von` · `verwendet` · `implementiert` · `erweitert` · `ersetzt` · `steht in Konflikt mit`
· `benötigt` · `erzeugt` · `konsumiert` · `besitzt` · `pflegt` · `läuft auf` · `verwandt mit`
(last resort)
The labels are prose written into a `- **label:** [[Title]]` bullet; no code matches on them, so
an untranslated page's English label is stale wording, not a broken reference.
## Confidence rubric
`confidence_base` is set by hand and `confidence` is derived from it - that mechanism is the
contract's. What the number *means* is this instance's:
Base score for a single source is 0.5, adjusted by:
- **+0.2 per supporting source** (max +0.6)
- **+0.2** if confirmed <30 days ago, **+0.1** if <90 days
- **+0.1** for official documentation, **+0.05** for a reputable secondary source
- **+0.1** if multiple independent sources agree
In prose, hedge according to the score: below 0.6 write "möglicherweise"/"kann"; below 0.4
write "unsicher"/"unbestätigt".
## Keeping this file honest
Change it when a convention actually changes, and treat a change to `sections:` as a corpus
migration rather than an edit: existing pages keep their old headings until something translates
them, and the alias list is what carries them in the meantime. `wikitool doctor` FAILs on a
missing or unfilled file, and `wikitool docs verify` refuses a `sections:` block that does not
name all three slots.
+104
View File
@@ -0,0 +1,104 @@
---
# wikitool:template-unfilled - delete this line once the file is answered.
language: en
profile: none
sections:
relationships: Relationships
see_also: See Also
footnotes: Footnotes
# Headings this instance no longer writes but still recognizes, so a corpus can
# be translated page by page instead of all at once. Optional; the names this
# stack wrote before this file existed are always recognized anyway.
# section_aliases:
# relationships: [Beziehungen]
# see_also: [Siehe auch]
# footnotes: [Fußnoten]
---
# kb/ - Authoring Conventions of This Instance
The decisions [kb/CONTRACT.md](CONTRACT.md) deliberately does not make. The contract holds what
the code enforces and is identical in every instance; this file holds what *this* instance
chooses, and no other instance has to agree with a word of it.
**It binds all the same.** Everything below applies to every page under `kb/`, exactly as the
contract does. The difference is ownership, not authority: a rule here is changed by editing
this file, a rule there by changing the stack.
Ready-made answers to every section below - including a complete German profile - are in
[instructions/kb-profiles.md](../instructions/kb-profiles.md). That catalogue is a palette, not
an enum: adopt an entry, adapt it, or write your own. What is written *here* is what holds.
The frontmatter above is the one machine-read part. `sections:` names the three headings
`wikitool xref` and `wikitool cite` write into. Set them before the first page is written:
afterwards, changing one is a corpus migration rather than an edit.
## Language
Pages are written in **{language}**. This binds `kb/` and the authoring surface that shapes it -
the page type-specs `types/entity.md`, `types/concept.md`, `types/source.md` and
`types/comparison.md`, whose `## Template` blocks are the body skeleton every new page starts
from. `raw/` is untouched ([raw/CONTRACT.md](../raw/CONTRACT.md)), and the control plane stays
English: `AGENTS.md`, the stage contracts, this file, `instructions/`, and the type-specs for
non-page artifacts.
Which line is prose and which is an identifier - and therefore what is translated at all - is
the contract's rule, not this file's: see
[kb/CONTRACT.md § Language and identifiers](CONTRACT.md#language-and-identifiers).
{Which established foreign-language technical terms stay untranslated inside this instance's
prose, and where the vocabulary for that is looked up. Delete this paragraph if the KB language
is the one those terms are already in.}
### Section headings
The canonical names are the frontmatter's. Any name this instance previously wrote stays
recognized through `section_aliases:`, which is what lets a corpus be translated page by page.
Renaming such a heading is the translation pass's job, never a side effect of another command.
Any *other* heading an author adds is ordinary prose.
## Naming
- {Title form - words and spaces, or kebab-case, or the subject's own spelling.}
- {Singular or plural for entities.}
- {How a comparison page's title reads.}
- {The ADR prefix, if this instance files decisions as pages.}
- {What to name a thing: projects, systems, tools, technologies, people.}
The one naming fact that is *not* a choice, and therefore lives in the contract: the filename
stem is the page title, and `[[wikilinks]]` must match it exactly.
## Tone
{The register pages are written in, in one line.}
- {Words and constructions this instance refuses, with examples in the KB language.}
Good: {one sentence that is what this instance wants.}
Bad: {the same sentence written the way it must not be.}
## Relationship labels
`tools/wikitool xref add --rel-a/--rel-b` takes a free-text label. Listing the ones this
instance uses is what keeps a graph typed rather than a wiki full of "related to":
{the label vocabulary, in the KB language}
No code matches on these, so an old label on an untranslated page is stale wording, not a
broken reference.
## Confidence rubric
`confidence_base` is set by hand and `confidence` is derived from it - that mechanism is the
contract's. What the number *means* is this instance's:
{the base score, what raises it, and by how much}
{How to hedge in prose at a low score, in the KB language.}
## Keeping this file honest
Change it when a convention actually changes, and treat a change to `sections:` as a corpus
migration rather than an edit. `wikitool doctor` FAILs on a missing or unfilled file, and
`wikitool docs verify` refuses a `sections:` block that does not name all three slots.
+12 -4
View File
@@ -1,3 +1,8 @@
---
profile: comparisons
required_by_stack: false
---
# kb/comparisons/ - Collection Contract
Structured head-to-head evaluations of two or more things that already have pages here. A
@@ -7,8 +12,10 @@ comparison exists so that neither subject's own page has to argue against the ot
That needs named, checkable dimensions and a stated trade-off; a page that lists differences
without saying what they cost has described, not compared.
Inherits [kb/CONTRACT.md](../CONTRACT.md) - naming, tone, linking, provenance and confidence
are defined there and are not restated here.
Inherits [kb/CONTRACT.md](../CONTRACT.md) for the rules the stack enforces - linking mechanics,
provenance, citation, the confidence machinery - and
[kb/CONVENTIONS.md](../CONVENTIONS.md) for what this instance decided: language, naming forms,
tone, relationship labels, the confidence rubric. Neither is restated here.
## Types offered
@@ -16,8 +23,9 @@ are defined there and are not restated here.
## Naming
The title reads as a comparison: `Go vs Rust.md`, `Traefik vs nginx.md`. Order the subjects as
they are most commonly spoken, not alphabetically.
The title form is [kb/CONVENTIONS.md § Naming](../CONVENTIONS.md#naming)'s. What is local here
is the ordering: name the subjects as they are most commonly spoken together, not
alphabetically.
## Requirements
+11 -4
View File
@@ -1,3 +1,8 @@
---
profile: concepts
required_by_stack: false
---
# kb/concepts/ - Collection Contract
Ideas rather than things: architectures, patterns, protocols, workflows, recurring problems,
@@ -8,8 +13,10 @@ records *what*.
without the reader having to open the entity pages that use it. If the explanation only makes
sense once you already know the system, it is on the wrong page.
Inherits [kb/CONTRACT.md](../CONTRACT.md) - naming, tone, linking, provenance and confidence
are defined there and are not restated here.
Inherits [kb/CONTRACT.md](../CONTRACT.md) for the rules the stack enforces - linking mechanics,
provenance, citation, the confidence machinery - and
[kb/CONVENTIONS.md](../CONVENTIONS.md) for what this instance decided: language, naming forms,
tone, relationship labels, the confidence rubric. Neither is restated here.
## Types offered
@@ -17,8 +24,8 @@ are defined there and are not restated here.
## Decisions and ADRs
An architectural decision is a concept page prefixed `adr-NNN-`, e.g.
`adr-001-use-go-modules.md`. It records:
An architectural decision is a concept page, prefixed as
[kb/CONVENTIONS.md § Naming](../CONVENTIONS.md#naming) says. It records:
- **Context** - what forced a decision.
- **Decision** - what was chosen.
+9 -2
View File
@@ -1,3 +1,8 @@
---
profile: entities
required_by_stack: false
---
# kb/entities/ - Collection Contract
Concrete things that exist: a project, a deployed system, a CLI tool, a technology, a person or
@@ -7,8 +12,10 @@ an organization. If it can be pointed at, it is an entity.
is, where it actually is, and whether that is still true. An entity page that describes a
system correctly but names no host, path, version or status has not earned its keep.
Inherits [kb/CONTRACT.md](../CONTRACT.md) - naming, tone, linking, provenance and confidence
are defined there and are not restated here.
Inherits [kb/CONTRACT.md](../CONTRACT.md) for the rules the stack enforces - linking mechanics,
provenance, citation, the confidence machinery - and
[kb/CONVENTIONS.md](../CONVENTIONS.md) for what this instance decided: language, naming forms,
tone, relationship labels, the confidence rubric. Neither is restated here.
## Types offered
+13 -2
View File
@@ -1,3 +1,8 @@
---
profile: sources
required_by_stack: true
---
# kb/sources/ - Collection Contract
One page per ingested source. A source page is the bridge between the untrusted material in
@@ -9,8 +14,14 @@ concluded from it. Where the source is wrong, say what it claims and let the sub
carry the correction. A source page that has been improved beyond its source is no longer
evidence for anything.
Inherits [kb/CONTRACT.md](../CONTRACT.md) - naming, tone, linking, provenance and confidence
are defined there and are not restated here.
Inherits [kb/CONTRACT.md](../CONTRACT.md) for the rules the stack enforces - linking mechanics,
provenance, citation, the confidence machinery - and
[kb/CONVENTIONS.md](../CONVENTIONS.md) for what this instance decided: language, naming forms,
tone, relationship labels, the confidence rubric. Neither is restated here.
**This collection is `required_by_stack`.** `sources coverage`, `[^cite-id]` resolution and
`kb/provenance.md` resolve against it by name, so unlike every other collection it may not be
renamed or dropped - its authoring rules below are the instance's, its existence is not.
## Types offered