feat: people live on their organization's page until promoted; organization subtype, member-of, broken_anchors lint (#172)
CI / verify (push) Successful in 5m26s
CI / pwsh (push) Successful in 2m8s
Release / release (push) Successful in 34s

Files changed:
- CHANGES.md
- README.md
- VERSION
- instructions/kb-profiles.md
- instructions/link-taxonomy.md
- instructions/page-lifecycle.md
- instructions/wiki-ingest/SKILL.md
- instructions/wiki-lint/SKILL.md
- kb/entities/COLLECTION.md
- kb/entities/INDEX.md
- kb/entities/organizations/E3DC GmbH.md
- kb/entities/people/E3DC GmbH.md
- kb/index.md
- kb/log.md
- tools/CONTRACT.md
- tools/chemenu/commands/lint.py
- tools/chemenu/kb_scan.py
- tools/chemenu/lint_core.py
- tools/chemenu/tests/test_lint.py
- tools/chemenu/tests/test_new_page.py
- tools/chemenu/tests/test_type_resolver.py
- tools/chemenu/tests/test_types_cmd.py
- types/entity.md
- types/entity.organization.md
- types/entity.person.md
- types/entity.schema.yaml

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SnAJ7Z3CpVD3PRbN73QtU2
This commit is contained in:
torbenandClaude Opus 5.5 committed 2026-10-04 10:51:46 +02:00
1 parent f3ccbd86f9
commit 4ec22d376d
25 files changed
+368 -30

No files matched your search

+6 -3
View File
@@ -128,13 +128,16 @@ want it.
### `entities`
Concrete, pointable things: codebases, deployed systems, tools, technologies, people.
Concrete, pointable things: codebases, deployed systems, tools, technologies, people,
organizations.
- **Quality goal:** pointability plus currency - what the thing is, where it actually is, and
whether that is still true.
- **Areas** driven by the `entity_type:` field: `codebases/`, `systems/`, `tools/`,
`technologies/`, `people/`. Areas, not collections - they inherit the contract and carry no
`COLLECTION.md`.
`technologies/`, `people/`, `organizations/`. Areas, not collections - they inherit the
contract and carry no `COLLECTION.md`.
- **People live on their organization's page** as a section until a source carries material for
a page of their own - the alternative to a directory of one-line person stubs.
- **Per-area emphasis** spelled out, so a system page is not written like a technology page.
- `required_by_stack: false`.
+5
View File
@@ -144,6 +144,7 @@ entity to entity.
| `staffed-by` | — | is carried out, in part, by the target's work |
| `consults` | — | draws on the target's judgment without the target carrying the work |
| `informs` | — | keeps the target informed, without the target taking part |
| `member-of` | — | belongs to the organization the target is |
| `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
@@ -172,6 +173,10 @@ A collection authorises whichever of the five its pages need. A household wiki m
and drop `involves`. Someone only mentioned - neither working, consulted nor informed - takes no
edge at all (step 1).
`member-of` versus `part-of`: a department is a component of its company and takes `part-of`; a
person belongs to one without being a component of it, and takes `member-of`. It has no inverse -
an organization page lists its people in its own text, and its inbound view shows the rest.
`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
+44 -4
View File
@@ -1,7 +1,7 @@
---
type: types/instruction.md
name: page-lifecycle
description: Rename a page, delete one, or drop a single cross-reference without breaking the links that point at it.
description: Rename a page, delete one, move it, promote a section of one to a page of its own, or drop a single cross-reference - without breaking the links that point at it.
---
# Rename, delete, or unlink a page
@@ -20,6 +20,7 @@ one and leaves the others pointing at nothing.
- [Rename](#rename)
- [Delete](#delete)
- [Move](#move)
- [Promote a section to its own page](#promote-a-section-to-its-own-page)
- [Drop a single reference](#drop-a-single-reference)
- [Afterwards](#afterwards)
- [Scope](#scope)
@@ -88,6 +89,45 @@ in case or Unicode normalization - is refused, not silently overwritten. That on
pre-existing duplicate-title collision, which `lint`'s **Duplicate Titles** and **Unportable
Titles** findings report separately.
## Promote a section to its own page
A subject can live as a section of another page until it earns its own - the shipped `entities`
profile does this with people on their organization's page. Promoting one is not a move: a new
page is born, and a section shrinks. No command does it in one step, because two of its steps
are judgments - which edges meant the person and which the organization - and it is rare.
1. **Create the page** from the section's content, with the tool:
```bash
tools/wikitool new entity --name "<Name>" --set entity_type=person --set provenance=<value>
```
Move the section's prose into it, and its citations with `cite add` against the same sources.
2. **Shrink the section** on the parent page to one bullet under the heading that held it -
`- [[<Name>]] - <role>` - and drop the section's own heading. With the heading gone, any link
step 4 misses stops resolving and step 5 reports it, instead of landing quietly on a stub.
3. **Connect the two** - for a person, the membership edge on the new page:
```bash
tools/wikitool xref add --a "<Name>" --b "<Organization>" --rel member-of
```
4. **Find every link that meant the section**, and point it at the new page:
```bash
tools/wikitool search "[[<Organization>#<Name>"
```
Search is literal by default, so the brackets need no escaping. Rewrite each hit to
`[[<Name>]]`, and move any edge on those pages that meant the person - `consults:
<Organization>` for a client contact, say - from the organization to the new page with
`xref remove` and `xref add`. An edge that meant the organization as a whole stays.
5. **Check** - `tools/wikitool lint` reports no `broken_anchors` and no `broken_links`. Then close
out as for a new page.
## Drop a single reference
```bash
@@ -101,9 +141,9 @@ hand-edit gets cleared. Idempotent.
## Afterwards
Always close out with [publish-cycle.md](publish-cycle.md), using `--op rename`, `--op delete`,
or `--op move`. A move changed no reference, so run `wikitool index rebuild` rather than
`sources rebuild-index` - the catalog is built from where a page's file sits, and nothing else
about it moved. Then confirm nothing was left dangling:
`--op move`, or `--op create` for a promotion. A move changed no reference, so run
`wikitool index rebuild` rather than `sources rebuild-index` - the catalog is built from where a
page's file sits, and nothing else about it moved. Then confirm nothing was left dangling:
```bash
tools/wikitool lint
+5 -2
View File
@@ -303,13 +303,16 @@ validator complains - and the ticked list is the only record that they happened.
not a page of its own. A page that only restates its own title is worse than the mention it
came from: `lint` measures structure and never substance, so nothing reports it, and the next
session reads it as covered ground and stops looking at the source. Applies per subject, not
per source - a wide source may well earn ten pages and decline twenty.
per source - a wide source may well earn ten pages and decline twenty. A person the source
names with no more than a role goes where the collection contract puts such people - with the
shipped `entities` profile, a section on their organization's page rather than a page of
their own.
New:
```bash
tools/wikitool new entity --name "<Name>" \
--set entity_type=<system|codebase|tool|technology|person> --set provenance=sourced
--set entity_type=<system|codebase|tool|technology|person|organization> --set provenance=sourced
```
(`mixed` if you will also add unsourced general-knowledge context.) Then write the
+2 -2
View File
@@ -41,8 +41,8 @@ mechanical half looks exactly like a complete one.
No flags: prints the sections that found something, writes the full report to
`reports/Lint Report <YYYY-MM-DD>.md`, and names that path. This deterministically finds
unreadable frontmatter, broken wikilinks, wikilinks wrapped across a line break, dangling
frontmatter references, orphan pages,
unreadable frontmatter, broken wikilinks, wikilinks wrapped across a line break, section
anchors that name no heading on their page, dangling frontmatter references, orphan pages,
catalog drift, missing fields, duplicate titles, titles that are not valid, unique file
names on Windows and macOS, filename/title mismatches, broken
`raw_files:` references, raw files claimed by more than one source page, invalid type paths,