Files
chemenu/instructions/link-taxonomy.md
T
torben 3916cb9541
CI / verify (push) Successful in 1m2s
Release / release (push) Successful in 37s
Link-Katalog: authored/alternative-to/addresses, entity→entity-Lineage, Lint-Befund redundant_see_also (4.7.0, #43 #49)
Files changed:
- CHANGES.md
- VERSION
- instructions/link-taxonomy.md
- kb/concepts/COLLECTION.md
- kb/entities/COLLECTION.md
- kb/entities/people/Andrej Karpathy.md
- kb/entities/people/Vannevar Bush.md
- tools/chemenu/evals/scorecard.py
- tools/chemenu/links.py
- tools/chemenu/lint_core.py
- tools/chemenu/tests/test_lint.py
2026-09-04 18:44:22 +02:00

247 lines
12 KiB
Markdown

---
type: types/instruction.md
name: link-taxonomy
description: The link-label catalogue - every relationship label a page may declare in related:, grouped by register, with the reader need each one names. A palette to authorise from in a COLLECTION.md, never binding on its own.
manual: true
---
# Pick a link label
**This page is a palette, not an enum.** It lists every label this stack ships with and what
each one asserts. What a page may actually *use* is decided by its own collection: each
`kb/<name>/COLLECTION.md` authorises a subset per destination, and `wikitool lint` checks
`related:` against that authorisation rather than against this file. A collection that
authorises six labels has six, however long this list gets.
A label is an **identifier, not prose**. It is written into `related:` as a machine value and
rendered verbatim into the page body, so it is never translated - not in a German wiki, not in
any other. Which words a page is *written* in stays [kb/CONVENTIONS.md](../kb/CONVENTIONS.md)'s;
this is not one of them.
## The invariant every label obeys
Every label completes, with the page carrying the link as the grammatical subject:
> `[source] <label> [target]`
The page containing the link asserts something **about** the target. `Hermes depends-on
PostgreSQL` reads correctly on Hermes' page; the same fact written on PostgreSQL's page is a
different label (`required-by`), not the same one pointing back. Omitted helper verbs ("is",
"a") are fine where they do not reverse the endpoints.
This is Commonplace's ADR-058, adopted wholesale, and it is what makes a label checkable rather
than a matter of taste: read the sentence out loud, and if it says the opposite of what you
meant, the label is wrong.
## Direction is authored, never mirrored
Each direction is a separate decision. A link back from the target is welcome when it
independently helps a reader *there* - and unnecessary when it does not. **Do not add a reverse
edge merely to mirror the first one.** The inbound view is rendered from the graph by
`index rebuild` and `search`, so a reader landing on the target sees what points at it whether
or not anyone wrote a second edge.
That is why most labels below have no inverse. Only three pairs do, because in each the reverse
direction is a genuine primary statement someone would write on its own: `depends-on` /
`required-by`, `runs-on` / `hosts`, and `composition` / `part-of`.
**A self-dual label is still written once.** `alternative-to` is its own inverse - the sentence
reads identically from either end - and that makes it the easiest label in the catalogue to
write twice by reflex. Symmetry means the relation holds in both directions, not that both pages
must declare it: one edge per pair, and the other page's inbound view carries it. The difference
is not cosmetic at scale. Seven mutually substitutable tools are 21 pairs; declared once each
that is 21 edges, declared from both ends it is 42, and the second 21 say nothing the first did
not. This is the shape a `see-also` clique already had in this corpus before the labels existed,
and relabelling such a clique without dropping to one edge per pair moves the problem rather
than fixing it.
The third was added after the 4.0.0 migration, from measurement rather than from the desk. A
parent-child structure - a tier list and its tiers, a spectrum and its levels - produces the
question on nearly every page: the parent writes `composition`, and the child then reaches for
either `part-of` or `see-also`. The migration run answered `see-also`, on the reading that
`part-of` would be a mirror, and left sixteen edges saying "these two are related" about a
relationship the catalogue already had a word for. It is not a mirror: the parent's sentence
lists its parts, the child's names the whole it belongs to, and a reader landing on the child
needs the second one.
## When to run
Adding or changing a `related:` entry, authorising labels in a `COLLECTION.md`, or judging
whether a relationship is worth naming as a formal edge at all.
## Steps
1. **Decide whether this is an edge.** Not every mention is one. An edge is a reader aid: it
says *follow this if you need X*. A subject mentioned once in passing is prose with a
`[[wikilink]]`, not a declared relationship. Over-declaring is how a graph becomes a list of
everything adjacent to everything.
2. **Say the sentence.** `[this page] <label> [that page]`. If it reads backwards, you want the
other page to carry the edge, or a different label.
3. **Pick from the register that fits the pair**, below. Prefer the most specific label that is
true; fall back outward only when nothing fits.
4. **Check the collection authorises it** for that destination -
`kb/<name>/COLLECTION.md`'s `outbound:` block. If the label you want is not authorised and
should be, that is a collection-contract change, made deliberately, not a lint error to
route around.
5. **Write it with the tool**, never by hand:
```bash
tools/wikitool xref add --a "<This Page>" --b "<That Page>" --rel <label>
```
## The catalogue
### Operational
Concrete things and how they stand to one another - the register this instance runs on. Mostly
entity to entity.
| label | inverse | asserts |
|---|---|---|
| `depends-on` | `required-by` | cannot function without the target |
| `required-by` | `depends-on` | the target cannot function without this |
| `runs-on` | `hosts` | executes on the target as its substrate |
| `hosts` | `runs-on` | provides the substrate the target executes on |
| `uses` | — | employs the target at runtime, but survives without it |
| `produces` | — | emits the target as an artifact or data |
| `consumes` | — | reads the target as an artifact or data |
| `maintains` | — | carries the upkeep of the target |
| `owns` | — | is accountable for the target's existence and decisions |
| `authored` | — | created the target as a one-time act |
| `alternative-to` | itself | serves the same purpose as the target, so a reader choosing between them wants both |
`uses` versus `depends-on` is the distinction worth keeping sharp: if removing the target breaks
this thing, it is `depends-on`.
`authored`, `owns` and `maintains` are three different sentences about the same pair, and often
three different people: origination, accountability, labour. `owns` is a *standing* claim - it
says someone answers for this thing now - so it reads false about a person who is dead or long
gone from the project, however plainly they made it. That is the case `authored` exists for, and
picking `owns` for it is not a weaker edge but a wrong one.
`alternative-to` versus `contrasts` versus `compares-with`: `contrasts` asserts a *difference
worth reading both for*, `alternative-to` asserts *substitutability* - two things a reader might
pick between for the same job. `compares-with` weighs them on named dimensions, which in this
instance is what routes to a `kb/comparisons/` page. Two agent CLIs are `alternative-to`; two
opposed design principles are `contrasts`, and swapping the two says something false about both.
### Realization
How an idea becomes a running thing. Usually concept to entity or the reverse.
| label | asserts |
|---|---|
| `implements` | is a concrete realization of the target |
| `operationalized-from` | is the prescriptive form of the target's theory |
| `mechanism` | is the mechanism by which the target works |
| `procedure` | is the procedure for carrying out the target |
| `applies-when` | applies under the condition the target describes |
| `operates-on` | acts upon the target as its subject matter |
| `invokes` | calls the target as a step within itself |
### Conceptual
Inference and comparison between ideas.
| label | asserts |
|---|---|
| `extends` | develops the target's argument further |
| `grounds` | provides the basis the target rests on |
| `rests-on` | takes the target as its premise |
| `enables` | is the operational prerequisite that makes the target possible |
| `precondition` | must hold before the target applies |
| `exemplifies` | is an instance of the general claim the target makes |
| `abstracted-from` | generalizes from the target |
| `contrasts` | differs from the target in a way worth reading both for |
| `compares-with` | is weighed against the target on shared dimensions |
| `contradicts` | asserts something the target denies |
| `addresses` | is a response to the problem the target describes |
| `composition` | is composed of the target |
| `part-of` | is a component of the target |
`composition` / `part-of` is the third **inverse pair**, alongside `depends-on` / `required-by`
and `runs-on` / `hosts` in the operational register. Being a pair does not make the second edge
obligatory - direction is still authored - it settles *which label* the second edge takes when
someone does write it. The child of a `composition` writes `part-of`, not `see-also`: what it
is a component of is a primary statement about the child, and `see-also` says strictly less
about the same fact.
`grounds` / `rests-on` is a genuine pair and both directions are primary statements; they are
listed separately rather than as inverses because either page may legitimately carry only its
own side.
`addresses` is the edge from a solution to the problem it answers - a decision to the trouble
that forced it, a mechanism to the failure it prevents. Keep it apart from `rests-on`, which
takes the target as a *premise* the source argues from: a decision usually does both, and the
one worth writing is the one a reader here would follow. `addresses` has no inverse. The problem
page's inbound view already answers "what did anyone do about this?", which is the only reason
someone would want the reverse.
### Lineage
Where something came from, and what replaced it.
| label | asserts |
|---|---|
| `supersedes` | replaces the target, which is now historical |
| `derived-from` | was produced from the target |
| `adapted-from` | was reworked from the target for a different purpose |
| `defined-in` | takes its definition from the target |
A superseded page is never deleted or rewritten - see the collection contract for
`kb/concepts/`.
### Evidence
The provenance register. Distinct from `sources:` and `[^cite-id]`, which are the *mechanical*
provenance path: these two are authored claims about how strongly something is backed.
| label | asserts |
|---|---|
| `evidenced-by` | is supported by the target as evidence |
| `is-evidence-for` | serves as evidence for the target's claim |
### Universal
| label | asserts |
|---|---|
| `see-also` | nothing more specific applies, and a reader here would still want the target |
**`see-also` is the last resort and should stay rare.** A collection where it is the commonest
label has a vocabulary problem, not a lot of loosely related pages. The previous vocabulary's
`verwandt mit` was exactly that, and it is the reason this catalogue exists.
## Extending it
Adding a label is a line of data, never a code change:
1. Add a row here, in the register it belongs to, with the sentence it completes.
2. Authorise it in the `COLLECTION.md` of every collection that may use it.
The registers are advisory groupings for readers, not a schema - nothing checks that a label is
used only within its register. Invent an intra-collection label the work needs and propose it
here afterwards; the architecture is deliberately loose, because the link theory is still
developing.
## Decision points
- **Two labels both fit?** Take the more specific one. If they are equally specific and mean
different things, the relationship is probably two edges.
- **The relationship reads better from the other page?** Write it there. Nothing is lost - the
inbound view renders it here.
- **You want a reverse edge for navigation?** You do not need one. That is what the rendered
inbound view is for, and it is complete in a way an authored mirror never was.
- **Nothing fits at all?** Use `see-also` and say so in the commit, or propose a label. Do not
stretch a label whose sentence reads false - a wrong edge is worse than a weak one, because
it is machine-readable and will be believed.
## Scope
Covers labels on `related:` edges between pages. Says nothing about `sources:` (the provenance
field, unlabelled by construction), `[^cite-id]` footnotes
([kb/CONTRACT.md](../kb/CONTRACT.md#provenance-and-citation)), or `tags:` (search keys, not
relationships).