# Glossary: link-taxonomy-migration Vocabulary decided while processing one page, carried forward so u3 (concepts) and u2 (projects/people/comparisons) do not re-decide it. Add to this file before dispatching the next unit or sub-session. ## Mechanism correction, discovered in u3 (concepts): `xref add` is always safe `xref add --a A --b B --rel X` **only ever touches page A** - it upserts (idempotent by target), so calling it on a pair that already has an unlabelled or even a differently-labelled entry just relabels it in place. `xref remove` is the only bidirectional, destructive call (strips the pair from **both** pages' `related:` and matching body lines). u1 already learned to sequence removes before adds per pair; u3 goes further and mostly **stops calling `xref remove` at all** for drift-only entries. Standing policy for the rest of this migration: when a frontmatter `related:` entry does not deserve its most literal label, relabel it with the best authorised fit - `see-also` if truly nothing fits - via `xref add`, rather than removing it. Only remove when the entry is a misplaced mention with nothing worth keeping on either side, and only after confirming (grep) that the target page carries no reciprocal reference that a bidirectional strip would destroy. This avoided several near-misses in u3 (`CPPC`/`amd-pstate` already carried `amd-pstate implements CPPC` from u1 - removing would have destroyed it; relabelled as `CPPC mechanism amd-pstate` instead). ## Unit sizing correction (2026-09-02) u1 as written in `plan.md` (`kb/entities/systems, tools, technologies`, estimated ~45 pages) is actually **57 pages carrying 199 `related:` entries** (systems 6/19, technologies 20/69, tools 31/111). At one `wikitool` call per edge (no bulk mode exists for `xref add`/`xref remove`), that is far past the 60-call session ceiling. Decided with the user: run u1 as planned in scope (all three areas, one eventual publish), but as **per-area sub-sessions**, each under its own `WIKITOOL_SESSION_ID`, holding `index rebuild`/`lint`/`log append`/`publish` until every area is done: - `link-taxonomy-migration/u1` - systems (done, see below) - `link-taxonomy-migration/u1-technologies` - technologies - `link-taxonomy-migration/u1-tools` - tools ## Recurring pattern: reverse-reading edge, correct statement already elsewhere Several old bullets read true only backwards, and the *correct* forward statement already exists (as still-unmigrated prose) on the other page - sometimes in a collection this unit does not touch. Rule applied: drop the backward one from the current page's `related:` (via `xref remove`, so it stops showing as an unlabelled edge) and note the correct edge here for whichever unit owns the other page. Never invert the label to fake the direction. Deferred edges for later units, discovered while processing systems: - **u3 (concepts):** `Denylist over Allowlist` invokes-or-operates-on `AGENTS.md` (its own body already says "beruft sich auf: AGENTS.md" - pick the label when concepts' outbound set is in front of you). - **u3 (concepts):** `LLM Wiki Pattern` derived-from-or-abstracted-from `Memex` (Memex's old "Geistiger Vorgänger von" bullet reads backwards from Memex's side). - **u2 (people):** `Vannevar Bush` owns `Memex` (Memex's "Erfunden von" bullet is `owns`'s unlabelled inverse; `owns` has no catalogue inverse, so it must be authored from Bush's page). - **u2 (people):** `E3DC GmbH` owns `E3DC` (same reasoning: `owns` has no inverse to assert from the owned entity's side). - **u2 (projects):** no action needed on `ha-core`/`hacs-e3dc` - E3DC's page independently asserts `required-by` (a real pair with a genuine inverse), which already covers the relationship without needing anything written on the project pages. ## Label choices worth reusing - A file that is normative *because* a tool enforces it (`AGENTS.md` vs. `wikitool`) is `depends-on`, not `implements`/`mechanism` - those realization labels are entities-to-concepts only, and these pages are both entities. - An optional dependency that the source tolerates the absence of (`CLAUDE.md`'s `@ENVIRONMENT.md` import) is `uses`, not `depends-on` - the catalogue's own test ("does removing the target break this thing?") answers no. - A root file that another root file's own prose defines the rules for (`AGENTS.md` defines what `ENVIRONMENT.md` is and is allowed to contain) is `owns` from the defining page, not asserted back from the defined one (no inverse exists). - A hardware/software pairing where the dependent side is a specific integration package, not the general platform (E3DC vs. `ha-core`/`hacs-e3dc` vs. Home Assistant broadly): assert `required-by` from the depended-upon entity's page, and do not manufacture an edge to the broad platform if no specific claim holds there. - A device supporting a communication standard: `implements` reads fine even outside pure software (E3DC implements Modbus). - Two entities in the same wiki cited as parallel real-world examples of the same concept, with no sharper label fitting: `see-also` is correct and not a cop-out (Memex/Tolkien Gateway). - **Taxonomy gap, confirmed while processing u2 (people):** there is no "created by" / "authored" / "extends the work of" label for a person-entity pointing at another entity or at a concept. `owns` covers a person being *accountable for* an entity going forward (used for `Vannevar Bush owns Memex`, `Rohit Gupta owns Agent Memory`, `E3DC GmbH owns E3DC`), but a one-time historical act of creating/originating a *concept* (Karpathy authoring the LLM Wiki Pattern, Bush originating Memex-the-idea) or of one person's work building on another's (Gupta extending Karpathy) has nothing in Realization or Lineage that is authorised for a person: those registers are concept-to-concept or concept-to-entity, never entity-to-entity or entity-to-concept for authorship. Resolved as `see-also` in every such case on Karpathy's, Gupta's and Bush's own pages, checked against every register first - not a stretch, a genuine gap. Worth proposing a label (`originates`/`authored-by`?) if this recurs in u3/u4. - **`kb/sources/` pages carry no `related:` field either, same as comparisons.** `types/source.md` declares only `page_ref_fields: [entities, concepts]` - `xref add` refuses there with the identical "type does not declare a related: field" error. Unlike comparisons, though, there is nothing left to migrate by hand: every one of the 27 source pages already had `entities:`/`concepts:` correctly populated via `xref link-source` at ingest time, and their prose "Verwandte Entities"/"Verwandte Concepts" sections already just mirror those fields - there was never a labelled-vs-unlabelled distinction to fix here. `migrate verify --from 177c7e9 --path kb/sources` returns 0 findings against baseline. u4 closes with zero page edits. - **comparisons pages carry no `related:` field at all.** `types/comparison.md` declares only `entities` (`page_ref_fields: [entities]`) - unlabelled by the schema, like `sources:`. `xref add`/`xref remove` refuse on this type ("type does not declare a related: field"). The `compares-with` label from `kb/comparisons/COLLECTION.md`'s `outbound:` block is documentational only for this type: it is written into the `## Beziehungen` prose by hand (there is no marker region either), never into machine data. Confirmed on `amd-pstate vs acpi-cpufreq.md`. - A dependent-side project whose own page only names the platform vaguely ("Kernintegrationsbibliothek für E3DC-Systeme") while a specific downstream package (a HACS component, an automation blueprint) explicitly wraps it: assert `required-by` from the depended-upon project's page for each specific downstream package, mirroring `depends-on` asserted on each dependent's own page - the same genuine two-sided pair as `E3DC`/`ha-core` from u1, one level up the stack (`ha-core`/`hacs-e3dc`, `ha-core`/`hacs-integration-blueprint`). - An external, out-of-wiki reference project cited only as "look how someone else solved this" (a GitHub repo mentioned as a structural analogue, no functional dependency): `see-also` asserted from the external project's own page toward the project it inspired, not the reverse - matches "reads correctly from the source page" even though nothing here is a stretch, just weak by nature (`wiki-skills`, `wiki-skills-vanillaflava`, `llm-wiki-skills` -> `Chemenu`).