feat: Prosa ist kein Identifier - Link-Taxonomie als Enum, generierte Regionen mit Markern (4.0.0)
Files changed: - .gitea/workflows/ci.yml - AGENTS.md - CHANGES.md - VERSION - instructions/CONTRACT.md - instructions/link-taxonomy.md - instructions/migrations/4.0.0-link-taxonomy.md - instructions/setup-instance.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/blocks.py - tools/chemenu/cli.py - tools/chemenu/commands/cite_cmd.py - tools/chemenu/commands/dist_cmd.py - tools/chemenu/commands/docs_verify.py - tools/chemenu/commands/doctor.py - tools/chemenu/commands/links_cmd.py - tools/chemenu/commands/migrate_cmd.py - tools/chemenu/commands/new_page.py - tools/chemenu/commands/page_ops.py - tools/chemenu/commands/run_budget.py - tools/chemenu/commands/xref.py - tools/chemenu/conventions.py - tools/chemenu/corpus_diff.py - tools/chemenu/frontmatter_io.py - tools/chemenu/kb_collections.py - tools/chemenu/kb_state.py - tools/chemenu/links.py - tools/chemenu/lint_core.py - tools/chemenu/provenance.py - tools/chemenu/sections.py - tools/chemenu/tests/conftest.py - tools/chemenu/tests/test_blocks.py - tools/chemenu/tests/test_cite_cmd.py - tools/chemenu/tests/test_conventions.py - tools/chemenu/tests/test_dist_cmd.py - tools/chemenu/tests/test_doctor.py - tools/chemenu/tests/test_migrate_cmd.py - tools/chemenu/tests/test_new_page.py - tools/chemenu/tests/test_pipeline_l0.py - tools/chemenu/tests/test_types_cmd.py - tools/chemenu/tests/test_xref.py - types/concept.schema.yaml - types/entity.md - types/entity.schema.yaml - types/instruction.schema.yaml - types/type-spec.md - work/link-taxonomy-migration/README.md - work/link-taxonomy-migration/plan.md
This commit is contained in:
+53
-27
@@ -12,9 +12,8 @@ second half is the cut: what is written here is enforced by `tools/wikitool` or
|
||||
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
|
||||
[kb/CONVENTIONS.md](CONVENTIONS.md)** - the language pages are written in, the headings its two
|
||||
generated regions render under, the naming forms, the tone, 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.
|
||||
@@ -99,7 +98,8 @@ decision record - is the instance's, in
|
||||
|
||||
- [ ] Carry a clear, descriptive title and a summary near the top
|
||||
- [ ] Use consistent terminology with the rest of the wiki
|
||||
- [ ] Link to every entity and concept it mentions, and be linked to in return
|
||||
- [ ] Link to the entities and concepts it mentions, and declare an edge where the relationship
|
||||
is worth naming - in the direction this page asserts it, not in both
|
||||
- [ ] Cite its hard facts (see [Provenance and citation](#provenance-and-citation))
|
||||
- [ ] Duplicate no existing page
|
||||
- [ ] Appear in the catalog (guaranteed by `wikitool index rebuild`)
|
||||
@@ -141,36 +141,62 @@ instance records - see [kb/CONVENTIONS.md § Language](CONVENTIONS.md#language).
|
||||
evidence *about* a source, not a substitute for it. Quote verbatim in the original language and
|
||||
record the raw file's language in `source_language:`.
|
||||
|
||||
### Section headings
|
||||
### Generated regions
|
||||
|
||||
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, 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.
|
||||
Two regions of a page body are **generated**, not authored: the links region `xref` owns and the
|
||||
footnotes region `cite` owns. Each sits between a marker pair:
|
||||
|
||||
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. 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.
|
||||
```markdown
|
||||
<!-- wikitool:links -->
|
||||
## Beziehungen
|
||||
|
||||
- **depends-on:** [[Hermes]]
|
||||
<!-- /wikitool:links -->
|
||||
```
|
||||
|
||||
The marker is what the tool locates the region by, and everything between the markers -
|
||||
**heading included** - is replaced wholesale on the next write. An author never edits inside
|
||||
them; anything left there is overwritten without warning, exactly as in `kb/index.md`. A region
|
||||
with nothing to show is absent rather than empty.
|
||||
|
||||
The heading is therefore a *rendering* value, taken from `kb/CONVENTIONS.md`'s `sections:`. No
|
||||
heading text exists in the compiler, and nothing matches on it: changing the declaration
|
||||
re-renders the words on the next write and cannot split a page.
|
||||
|
||||
That is not how it used to work. The tool located these regions by matching their heading text,
|
||||
which made a translated heading a structural fact - and made the region's *end* a guess. It ran
|
||||
to the next heading, and before that to the end of the file, which silently deleted whatever sat
|
||||
after it on eight pages. Any *other* heading a page carries is ordinary prose.
|
||||
|
||||
## Linking
|
||||
|
||||
Every page links to what it mentions, in both directions. Cross-references are created with
|
||||
`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.
|
||||
**An edge is authored in one direction**, on the page that asserts it, and carries a label that
|
||||
is a machine value rather than prose:
|
||||
|
||||
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.
|
||||
```yaml
|
||||
related:
|
||||
- depends-on: Hermes
|
||||
```
|
||||
|
||||
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.
|
||||
Created with `tools/wikitool xref add --a "<A>" --b "<B>" --rel <label>`, never by hand-editing
|
||||
`related:` or the rendered bullet. Say the sentence before choosing the label - `[A] <label>
|
||||
[B]` - and if it only reads true backwards, the edge belongs on the other page.
|
||||
|
||||
**A reverse edge is a separate decision, not a mirror.** Write one when it independently helps a
|
||||
reader at the other end; do not write one to make the graph symmetric. Navigation does not
|
||||
depend on it either way: `index rebuild` renders the inbound view from the graph, completely and
|
||||
without maintenance.
|
||||
|
||||
Which labels exist is [instructions/link-taxonomy.md](../instructions/link-taxonomy.md), a
|
||||
palette that binds nothing. Which of them a page may *use* is its own collection's `outbound:`
|
||||
block, per destination - the **source** collection decides, because the rules that govern an
|
||||
edge are the rules of the collection asserting it. `xref add` refuses an unauthorised label and
|
||||
`lint` reports one.
|
||||
|
||||
A page is expected to have at least one inbound edge; `wikitool lint` reports orphans.
|
||||
Comparison pages are exempt - they are reached through the catalog. Directional edges mean more
|
||||
pages qualify than under the old mirrored model, and that is the check measuring reachability
|
||||
rather than measuring whether `xref` ran.
|
||||
|
||||
Renaming a page, deleting one, or dropping a single reference are tool operations with their
|
||||
own procedure: see [instructions/page-lifecycle.md](../instructions/page-lifecycle.md).
|
||||
|
||||
+22
-29
@@ -2,8 +2,7 @@
|
||||
language: de
|
||||
profile: german
|
||||
sections:
|
||||
relationships: Beziehungen
|
||||
see_also: Siehe auch
|
||||
links: Beziehungen
|
||||
footnotes: Fußnoten
|
||||
---
|
||||
|
||||
@@ -21,13 +20,11 @@ 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.
|
||||
The frontmatter above is the one machine-read part. `sections:` names the headings the two
|
||||
**generated regions** render under - the links region `wikitool xref` owns and the footnotes
|
||||
region `wikitool cite` owns. Each sits between a marker pair, and the marker is what the tool
|
||||
locates it by, so the heading here is a display value: changing it re-renders the words above
|
||||
those regions and nothing else. Nothing matches on this text.
|
||||
|
||||
## Language
|
||||
|
||||
@@ -52,12 +49,13 @@ material, not a second rule - every entry in it is a decision that was made wron
|
||||
|
||||
### 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.
|
||||
The two generated regions render under `## Beziehungen` and `## Fußnoten`. An author never
|
||||
writes inside them - they are rebuilt from frontmatter on every write, exactly like
|
||||
`kb/index.md` - and never has to write the heading either. Any *other* heading on a page is
|
||||
ordinary prose and is translated with the rest.
|
||||
|
||||
There is no `## Siehe auch` region any more. It was the reciprocal half of a bidirectional
|
||||
`xref add`; under authored directional edges, `see-also` is a *label* inside the links region.
|
||||
|
||||
## Naming
|
||||
|
||||
@@ -92,15 +90,11 @@ The blockquote cap is not here: `wikitool lint` reports it, so it is the contrac
|
||||
|
||||
## 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.
|
||||
**Not this file's to list, and not localized.** A label is a machine value in `related:`, drawn
|
||||
from [instructions/link-taxonomy.md](../instructions/link-taxonomy.md) and authorised per
|
||||
destination in each `kb/<name>/COLLECTION.md`'s `outbound:` block. `- **depends-on:** [[Hermes]]`
|
||||
is what a German page carries, and that is deliberate: the label is an identifier, so translating
|
||||
it would make the graph's semantics depend on the prose again.
|
||||
|
||||
## Confidence rubric
|
||||
|
||||
@@ -119,8 +113,7 @@ 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.
|
||||
Change it when a convention actually changes. `sections:` is safe to change at any time - the
|
||||
regions are located by their markers and re-rendered under the new words on the next write.
|
||||
`wikitool doctor` FAILs on a missing or unfilled file, and `wikitool docs verify` refuses a
|
||||
`sections:` block that does not name both regions.
|
||||
|
||||
+11
-26
@@ -3,16 +3,8 @@
|
||||
language: en
|
||||
profile: none
|
||||
sections:
|
||||
relationships: Relationships
|
||||
see_also: See Also
|
||||
links: Relationships
|
||||
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
|
||||
@@ -29,9 +21,9 @@ Ready-made answers to every section below - including a complete German profile
|
||||
[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.
|
||||
The frontmatter above is the one machine-read part. `sections:` names the headings the two
|
||||
generated regions render under. Safe to change at any time - each region is located by its
|
||||
marker pair, so a rename re-renders words and nothing else.
|
||||
|
||||
## Language
|
||||
|
||||
@@ -52,10 +44,8 @@ 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.
|
||||
The two generated regions render under the frontmatter's headings. An author never writes inside
|
||||
them - they are rebuilt from frontmatter on every write. Any *other* heading is ordinary prose.
|
||||
|
||||
## Naming
|
||||
|
||||
@@ -80,13 +70,9 @@ 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.
|
||||
**Not this file's to list, and not localized.** A label is a machine value in `related:`, drawn
|
||||
from [instructions/link-taxonomy.md](../instructions/link-taxonomy.md) and authorised per
|
||||
destination in each `kb/<name>/COLLECTION.md`'s `outbound:` block.
|
||||
|
||||
## Confidence rubric
|
||||
|
||||
@@ -99,6 +85,5 @@ contract's. What the number *means* is this instance's:
|
||||
|
||||
## 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.
|
||||
Change it when a convention actually changes. `wikitool doctor` FAILs on a missing or unfilled
|
||||
file, and `wikitool docs verify` refuses a `sections:` block that does not name both regions.
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
---
|
||||
profile: comparisons
|
||||
outbound:
|
||||
any: [compares-with, contrasts, see-also]
|
||||
required_by_stack: false
|
||||
---
|
||||
|
||||
@@ -37,11 +39,22 @@ alphabetically.
|
||||
- State the trade-off, not a winner. Where a recommendation is genuinely warranted, scope it:
|
||||
"for X workload", not "better".
|
||||
|
||||
## Authorised labels
|
||||
|
||||
The `outbound:` block above is what `wikitool lint` and `xref add` check: which labels a page in
|
||||
this collection may use, per destination. The catalogue they are drawn from - and what each one
|
||||
asserts - is [instructions/link-taxonomy.md](../../instructions/link-taxonomy.md), which binds
|
||||
nothing on its own.
|
||||
|
||||
Narrow for the opposite reason: a comparison's substance is its table, and its links to the compared subjects are the one relationship it asserts.
|
||||
|
||||
Adding a label here is a deliberate contract change, not a way around a refusal.
|
||||
|
||||
## Outbound linking
|
||||
|
||||
A comparison links to every subject with `related to`, and each subject links back. Comparison
|
||||
pages are **exempt from the orphan check** - they are reached through `index.md` rather than
|
||||
through inbound prose links.
|
||||
A comparison links to every subject with `compares-with`. The subjects do not have to link back:
|
||||
a comparison is reached through the catalog, and each subject's inbound view renders the edge
|
||||
anyway. Comparison pages are **exempt from the orphan check** for the same reason.
|
||||
|
||||
## What does not belong here
|
||||
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
---
|
||||
profile: concepts
|
||||
outbound:
|
||||
concepts: [extends, grounds, rests-on, enables, precondition, exemplifies, abstracted-from, contrasts, compares-with, contradicts, composition, part-of, supersedes, derived-from, adapted-from, see-also]
|
||||
entities: [operationalized-from, mechanism, procedure, applies-when, operates-on, invokes, exemplifies, see-also]
|
||||
sources: [evidenced-by, derived-from, adapted-from, defined-in, see-also]
|
||||
comparisons: [compares-with, see-also]
|
||||
required_by_stack: false
|
||||
---
|
||||
|
||||
@@ -33,8 +38,19 @@ An architectural decision is a concept page, prefixed as
|
||||
- **Status** - proposed / accepted / deprecated / superseded.
|
||||
- Links to every entity the decision affects.
|
||||
|
||||
A superseded ADR is never deleted or rewritten; a new one supersedes it and both link to the
|
||||
other with `replaces` / `replaced by`.
|
||||
A superseded ADR is never deleted or rewritten. The new one declares `supersedes` pointing at
|
||||
it; the old one needs no edge back, because its inbound view renders the replacement.
|
||||
|
||||
## Authorised labels
|
||||
|
||||
The `outbound:` block above is what `wikitool lint` and `xref add` check: which labels a page in
|
||||
this collection may use, per destination. The catalogue they are drawn from - and what each one
|
||||
asserts - is [instructions/link-taxonomy.md](../../instructions/link-taxonomy.md), which binds
|
||||
nothing on its own.
|
||||
|
||||
The widest authorisation in this instance, because argumentation is what concept pages do. Note that the operational labels are absent: a concept does not `depend-on` anything - the entity implementing it does.
|
||||
|
||||
Adding a label here is a deliberate contract change, not a way around a refusal.
|
||||
|
||||
## Outbound linking
|
||||
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
---
|
||||
profile: entities
|
||||
outbound:
|
||||
entities: [depends-on, required-by, runs-on, hosts, uses, produces, consumes, maintains, owns, part-of, composition, supersedes, see-also]
|
||||
concepts: [implements, exemplifies, rests-on, applies-when, operates-on, invokes, see-also]
|
||||
sources: [evidenced-by, defined-in, see-also]
|
||||
comparisons: [compares-with, see-also]
|
||||
required_by_stack: false
|
||||
---
|
||||
|
||||
@@ -43,6 +48,17 @@ These are areas, not collections: they inherit this contract and carry no `COLLE
|
||||
- **People** - role, affiliation, and the projects or decisions they are connected to. Nothing
|
||||
personal beyond what the source states.
|
||||
|
||||
## Authorised labels
|
||||
|
||||
The `outbound:` block above is what `wikitool lint` and `xref add` check: which labels a page in
|
||||
this collection may use, per destination. The catalogue they are drawn from - and what each one
|
||||
asserts - is [instructions/link-taxonomy.md](../../instructions/link-taxonomy.md), which binds
|
||||
nothing on its own.
|
||||
|
||||
Operational labels dominate here because an entity's relationships are mostly to other concrete things. `implements` points *out* to a concept; the concept does not point back unless that direction is a statement of its own.
|
||||
|
||||
Adding a label here is a deliberate contract change, not a way around a refusal.
|
||||
|
||||
## Outbound linking
|
||||
|
||||
An entity links to the technologies it uses, the systems it runs on, the projects that depend
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
---
|
||||
profile: sources
|
||||
outbound:
|
||||
any: [is-evidence-for, defined-in, see-also]
|
||||
required_by_stack: true
|
||||
---
|
||||
|
||||
@@ -38,6 +40,17 @@ The `raw_files:`/`source_url:`/citation rules are shared and live in
|
||||
- `tools/wikitool sources trace --raw <path>` answers "what did we learn from this?";
|
||||
`tools/wikitool sources coverage` lists raw files no source page claims yet.
|
||||
|
||||
## Authorised labels
|
||||
|
||||
The `outbound:` block above is what `wikitool lint` and `xref add` check: which labels a page in
|
||||
this collection may use, per destination. The catalogue they are drawn from - and what each one
|
||||
asserts - is [instructions/link-taxonomy.md](../../instructions/link-taxonomy.md), which binds
|
||||
nothing on its own.
|
||||
|
||||
Deliberately narrow. A source page is evidence *about* a source; almost everything it would want to say is already carried by `raw_files:`, `sources:` and `[^cite-id]`, which are the mechanical provenance path rather than authored edges.
|
||||
|
||||
Adding a label here is a deliberate contract change, not a way around a refusal.
|
||||
|
||||
## Outbound linking
|
||||
|
||||
A source page links to every entity and concept it produced or updated.
|
||||
|
||||
Reference in New Issue
Block a user