feat: Autorenkonventionen nach Eigentum geschnitten - kb/CONVENTIONS.md, deklarierte Collections (3.0.0)
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:
+74
-72
@@ -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).
|
||||
|
||||
Reference in New Issue
Block a user