@panaversity/ksor 0.0.40 → 0.0.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +869 -0
- package/README.md +11 -7
- package/dist/checker/check-main.mjs +14049 -0
- package/dist/cli.mjs +11528 -5213
- package/dist/gateway-api-CF4ED9_g-BQusM_dK.mjs +10895 -0
- package/dist/gateway.d.mts +52 -13
- package/dist/gateway.mjs +2 -2
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{src-pl4aOpVs.mjs → src-dqpI-p1a.mjs} +1 -0
- package/docs/authorization.md +8 -6
- package/docs/deploying.md +36 -25
- package/docs/index.md +26 -13
- package/docs/ingesting.md +70 -22
- package/docs/tool-surface.md +69 -16
- package/package.json +4 -3
- package/schema/migrations/2.4-2.5__okf-profile.sql +114 -0
- package/schema/schema.sql +77 -14
- package/templates/scaffold/.agents/skills/add-sources/SKILL.md +63 -18
- package/templates/scaffold/.agents/skills/format-checker/SKILL.md +42 -33
- package/templates/scaffold/.agents/skills/format-checker/check.mjs +13827 -1314
- package/templates/scaffold/.agents/skills/intake-interview/SKILL.md +65 -27
- package/templates/scaffold/.agents/skills/make-slides/SKILL.md +7 -5
- package/templates/scaffold/.agents/skills/make-summary/SKILL.md +13 -6
- package/templates/scaffold/.claude/skills/add-sources/SKILL.md +63 -18
- package/templates/scaffold/.claude/skills/format-checker/SKILL.md +42 -33
- package/templates/scaffold/.claude/skills/format-checker/check.mjs +13827 -1314
- package/templates/scaffold/.claude/skills/intake-interview/SKILL.md +65 -27
- package/templates/scaffold/.claude/skills/make-slides/SKILL.md +7 -5
- package/templates/scaffold/.claude/skills/make-summary/SKILL.md +13 -6
- package/templates/scaffold/.github/workflows/validate.yml +9 -1
- package/templates/scaffold/.ksor/governance.yaml +17 -0
- package/templates/scaffold/AGENTS.md +234 -113
- package/templates/scaffold/Dockerfile +5 -1
- package/templates/scaffold/README.md +160 -42
- package/templates/scaffold/env.example +37 -6
- package/templates/scaffold/gitignore +13 -8
- package/templates/scaffold/instance.md +21 -17
- package/templates/scaffold/knowledge/governance-ladder.md +6 -2
- package/templates/scaffold/knowledge/index.md +9 -0
- package/templates/scaffold/knowledge/surfaces/for-agents.md +7 -6
- package/templates/scaffold/knowledge/surfaces/for-people.md +7 -6
- package/templates/scaffold/knowledge/surfaces/index.md +4 -20
- package/templates/scaffold/knowledge/surfaces/overview.md +25 -0
- package/templates/scaffold/knowledge/what-is-a-ksor.md +6 -5
- package/templates/scaffold/knowledge/what-is-a-ksor.summary.md +4 -0
- package/templates/scaffold/package.json +3 -4
- package/templates/scaffold/pnpm-lock.yaml +3 -0
- package/templates/scaffold/system/gateways/content.ts +13 -0
- package/templates/scaffold/system/site/app/(home)/page.tsx +2 -2
- package/templates/scaffold/system/site/app/.well-known/mcp/server.json/route.ts +10 -0
- package/templates/scaffold/system/site/app/docs/[[...slug]]/page.tsx +126 -91
- package/templates/scaffold/system/site/app/global.css +13 -5
- package/templates/scaffold/system/site/app/layout.tsx +8 -3
- package/templates/scaffold/system/site/app/llms-full.txt/route.ts +13 -7
- package/templates/scaffold/system/site/app/llms.txt/route.ts +12 -7
- package/templates/scaffold/system/site/app/md/[[...slug]]/route.ts +26 -25
- package/templates/scaffold/system/site/components/footer-mark.tsx +3 -2
- package/templates/scaffold/system/site/components/governance.tsx +205 -87
- package/templates/scaffold/system/site/components/record-index.tsx +5 -5
- package/templates/scaffold/system/site/components/record-stack.tsx +10 -9
- package/templates/scaffold/system/site/components/sidebar-status.tsx +19 -18
- package/templates/scaffold/system/site/lib/attachment-rule.ts +6 -1
- package/templates/scaffold/system/site/lib/attachments.ts +0 -28
- package/templates/scaffold/system/site/lib/audience-rule.ts +15 -21
- package/templates/scaffold/system/site/lib/audience.ts +42 -146
- package/templates/scaffold/system/site/lib/embed-rule.ts +9 -0
- package/templates/scaffold/system/site/lib/governance.ts +339 -225
- package/templates/scaffold/system/site/lib/index-routes.ts +125 -0
- package/templates/scaffold/system/site/lib/lifecycle-rule.ts +52 -0
- package/templates/scaffold/system/site/lib/lock.ts +282 -0
- package/templates/scaffold/system/site/lib/order-rule.ts +37 -0
- package/templates/scaffold/system/site/lib/record-href.ts +68 -0
- package/templates/scaffold/system/site/lib/record-link.tsx +26 -0
- package/templates/scaffold/system/site/lib/rules-version.ts +11 -0
- package/templates/scaffold/system/site/lib/shared.ts +67 -104
- package/templates/scaffold/system/site/lib/sim-rule.ts +49 -0
- package/templates/scaffold/system/site/lib/source.ts +256 -186
- package/templates/scaffold/system/site/lib/stage-knowledge.ts +566 -492
- package/templates/scaffold/system/site/lib/stage-manifest.ts +128 -0
- package/templates/scaffold/system/site/package.json +1 -0
- package/templates/scaffold/system/site/record/actor.ts +23 -0
- package/templates/scaffold/system/site/record/check.ts +571 -0
- package/templates/scaffold/system/site/record/citations.ts +312 -0
- package/templates/scaffold/system/site/record/frontmatter.ts +134 -0
- package/templates/scaffold/system/site/record/git-ledger.ts +171 -0
- package/templates/scaffold/system/site/record/hygiene.ts +320 -0
- package/templates/scaffold/system/site/record/index-file.ts +150 -0
- package/templates/scaffold/system/site/record/index.ts +103 -0
- package/templates/scaffold/system/site/record/instance.ts +257 -0
- package/templates/scaffold/system/site/record/instant.ts +43 -0
- package/templates/scaffold/system/site/record/ledger.ts +694 -0
- package/templates/scaffold/system/site/record/load.ts +129 -0
- package/templates/scaffold/system/site/record/lock.ts +306 -0
- package/templates/scaffold/system/site/record/near-miss.ts +37 -0
- package/templates/scaffold/system/site/record/policy.ts +414 -0
- package/templates/scaffold/system/site/record/profile.ts +535 -0
- package/templates/scaffold/system/site/record/refusal.ts +106 -0
- package/templates/scaffold/system/site/record/yaml-file.ts +103 -0
- package/templates/scaffold/system/site/source.config.ts +77 -22
- package/dist/gateway-api-CmIthmJS-IUA9qS-T.mjs +0 -3225
- package/templates/scaffold/system/site/lib/denial-rule.ts +0 -220
- package/templates/scaffold/system/site/lib/page-order.ts +0 -93
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: intake-interview
|
|
3
|
-
description: The first conversation with the owner of this Knowledge System of Record —
|
|
3
|
+
description: The first conversation with the owner of this Knowledge System of Record — seven questions that define what it is authoritative for, who may read it and who may approve it, then write instance.md together. Use when the owner asks to set up, configure, or "get started with" this project, when instance.md still contains its scaffold placeholder text, or when the scope of the corpus is unclear.
|
|
4
4
|
metadata:
|
|
5
|
-
version: "1.
|
|
5
|
+
version: "1.5.0"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Intake interview
|
|
@@ -12,7 +12,7 @@ prose IS the agent surface's system prompt (`ksor serve` wires it into the MCP
|
|
|
12
12
|
server's instructions). Do not draft it from guesses — interview the owner, one
|
|
13
13
|
question at a time, and write down what they actually say.
|
|
14
14
|
|
|
15
|
-
## The six questions
|
|
15
|
+
## The first six questions
|
|
16
16
|
|
|
17
17
|
Ask these one at a time; follow up until each answer is concrete enough to
|
|
18
18
|
act on:
|
|
@@ -31,33 +31,71 @@ act on:
|
|
|
31
31
|
should it decline? ('Not in this corpus' is a correct answer here —
|
|
32
32
|
confirm the owner wants that behavior and where they want it softened.)"
|
|
33
33
|
6. **Audiences** — "Does every reader of this record see every document? If
|
|
34
|
-
not, what are the audiences
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
`
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
34
|
+
not, what are the audiences?" A yes is the common answer and the whole
|
|
35
|
+
answer: register none, and every document says `ksor.audience: [public]`.
|
|
36
|
+
Anything else means registering each audience in
|
|
37
|
+
`.ksor/governance.yaml` under `audiences:`, with a one-line
|
|
38
|
+
`description:` of who is in it — `public` is reserved and never
|
|
39
|
+
registered. There is no ranking and no default: a document lists the
|
|
40
|
+
audiences that may read it, a reader holds a list that always includes
|
|
41
|
+
`public`, and the document is visible when the two lists OVERLAP. Tell
|
|
42
|
+
the owner what this does and does not do: builds are made per audience,
|
|
43
|
+
but anyone who can clone the repository reads everything in it — if
|
|
44
|
+
someone must not read a document and can clone, that document belongs in
|
|
45
|
+
a different repository.
|
|
46
|
+
|
|
47
|
+
## Then ask the seventh, because a policy cannot be guessed
|
|
48
|
+
|
|
49
|
+
7. **Authority** — "Who may approve a document for publication, and who may
|
|
50
|
+
withdraw one?" Names, not roles-in-the-abstract: they become
|
|
51
|
+
`approval_authorities` and `takedown_authorities` in
|
|
52
|
+
`.ksor/governance.yaml`, and the checker refuses an approval or a
|
|
53
|
+
takedown by anyone the policy does not name. The scaffold ships
|
|
54
|
+
`human:you` in both — a placeholder that must not survive this
|
|
55
|
+
conversation. An actor is `human:<handle>`, `process:<name>` or
|
|
56
|
+
`<producer>/<version>`; handles are published with the record, so use the
|
|
57
|
+
handle the owner would put in a commit, never an email address.
|
|
45
58
|
|
|
46
59
|
## Then write
|
|
47
60
|
|
|
48
|
-
- Rewrite `instance.md`
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
served MCP rung —
|
|
57
|
-
`AGENTS.md` → "Serving to agents"; that is a later
|
|
58
|
-
interview). The strictness answer from question 5
|
|
59
|
-
`retrieval.vector_floor` on that climb, measured
|
|
60
|
-
it in the prose now so it is ready.
|
|
61
|
+
- Rewrite `instance.md` from the answers. `title:` is the record's
|
|
62
|
+
**display title**, the human name every page leads with ("Acme Operations
|
|
63
|
+
Handbook", not the slug); `description:` is one sentence, and it seeds
|
|
64
|
+
`llms.txt` and the MCP discovery document; the BODY is the authority
|
|
65
|
+
sentence, boundary, audience and strictness — plain prose, handed in full
|
|
66
|
+
to every connecting agent as the MCP server's instructions, so write it
|
|
67
|
+
for a reader who must act on it. There is no `# H1`: the title is a key.
|
|
68
|
+
Leave `name:` and `toolchain:` alone. One block is added here only when
|
|
69
|
+
the owner stands up the served MCP rung — `database:`/`embedding:`/
|
|
70
|
+
`retrieval:` (see `AGENTS.md` → "Serving to agents"; that is a later
|
|
71
|
+
climb, not part of this interview). The strictness answer from question 5
|
|
72
|
+
is the intent behind the `retrieval.vector_floor` on that climb, measured
|
|
73
|
+
by `ksor calibrate` — capture it in the prose now so it is ready.
|
|
74
|
+
- Write `.ksor/governance.yaml` from questions 6 and 7: `version: "0.1"`,
|
|
75
|
+
the `audiences:` registry if there is one, and the two authority sets with
|
|
76
|
+
real actors. That file is the root of authority — every approval, every
|
|
77
|
+
deprecation and every ledger entry is checked against it. **Keep
|
|
78
|
+
`ksor-starter/KSOR-STAMP-VERSION` in `approval_authorities` while any starter
|
|
79
|
+
document is still in `knowledge/`.** Those five are approved by it, so a
|
|
80
|
+
policy rewritten without it refuses the next build by name
|
|
81
|
+
(`ksor-approver-unauthorised`). It leaves when the last sample does.
|
|
82
|
+
- **Offer to start replacing the starter documents — they are already
|
|
83
|
+
published.** All five ship `status: stable`, approved by
|
|
84
|
+
`ksor-starter/KSOR-STAMP-VERSION`, so the site and `llms.txt` carry them from
|
|
85
|
+
the first build. They describe KSoR itself rather than the owner's
|
|
86
|
+
organisation. Say it plainly: "Five sample documents about KSoR are published
|
|
87
|
+
on your record right now. The tool that wrote them approved them — nobody has
|
|
88
|
+
reviewed them, which is what the _unverified_ tier on each page says. Shall we
|
|
89
|
+
start replacing them with yours?" Replacing means deleting the sample and
|
|
90
|
+
writing a real document at `status: draft`; the owner approves it afterwards,
|
|
91
|
+
and that act is theirs. When the last sample is gone, delete
|
|
92
|
+
`ksor-starter/KSOR-STAMP-VERSION` from `approval_authorities` in the same
|
|
93
|
+
change — nothing of theirs should be approved by a tool. Never record an
|
|
94
|
+
approval nobody gave, and never write a `verified` entry: the approval is not
|
|
95
|
+
a review, and inventing one would retire the tier that exists to say nobody
|
|
96
|
+
has checked this.
|
|
97
|
+
- Run `ksor build` afterwards: it regenerates every folder's `index.md` from
|
|
98
|
+
the new title and refuses anything the profile does not accept.
|
|
61
99
|
- Restart `pnpm dev` afterwards so the site picks the new title up, and
|
|
62
100
|
show the owner their name on the page.
|
|
63
101
|
- Offer to capture the source list from question 4 as the first real
|
|
@@ -38,7 +38,8 @@ Read `<doc>.md` completely before writing anything. Note as you go:
|
|
|
38
38
|
- **the numbers** — thresholds, deadlines, limits, and their units
|
|
39
39
|
- **the cases** — what happens in each situation it names
|
|
40
40
|
- **the boundary** — what it explicitly does NOT cover
|
|
41
|
-
- **its governance** — `
|
|
41
|
+
- **its governance** — `status`, `ksor.owner` and `ksor.effective_from` from
|
|
42
|
+
the frontmatter
|
|
42
43
|
|
|
43
44
|
If the document carries `<doc>.summary.md`, read that too: it is a reviewed
|
|
44
45
|
compression of the same thing, and it tells you what the author thought was
|
|
@@ -108,16 +109,17 @@ the session it was made for, because the next presenter trusts it.
|
|
|
108
109
|
## 4 · Verify it
|
|
109
110
|
|
|
110
111
|
```sh
|
|
111
|
-
pnpm check # refuses an orphan
|
|
112
|
-
pnpm dev # look at the page — the deck renders
|
|
112
|
+
pnpm check # refuses an orphan deck
|
|
113
|
+
pnpm dev # look at the page — the deck renders after the introduction,
|
|
114
|
+
# immediately before the first `##` section
|
|
113
115
|
```
|
|
114
116
|
|
|
115
|
-
`pnpm build` refuses
|
|
117
|
+
`pnpm build` refuses — the deck's own shape is checked in the site build, not
|
|
118
|
+
by `pnpm check`:
|
|
116
119
|
|
|
117
120
|
- `ksor-slides-empty` — neither `deck:` nor `slides.url:`; nothing to show
|
|
118
121
|
- `ksor-slides-two-sources` — both, so nothing says which one governs
|
|
119
122
|
- `ksor-attachment-orphan` — no `<doc>.md` beside it
|
|
120
|
-
- `ksor-attachment-frontmatter` — an attachment carries none of its own
|
|
121
123
|
|
|
122
124
|
## 5 · Tell the owner what you did
|
|
123
125
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: make-summary
|
|
3
3
|
description: Write the summary of a document and attach it, so it renders as a second tab on that document's page. Use when the owner says "summarise X", "make a summary for this", "add summaries to the record", "give me the short version", or asks for a TL;DR, an abstract or a précis of a governed document.
|
|
4
4
|
metadata:
|
|
5
|
-
version: "1.
|
|
5
|
+
version: "1.1.0"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Writing the summary of a document
|
|
@@ -48,17 +48,24 @@ Read `<doc>.md` completely before writing anything. Note as you go:
|
|
|
48
48
|
- **the numbers** — thresholds, deadlines, limits, and their units
|
|
49
49
|
- **each `##` section** — and the one thing it is there to say
|
|
50
50
|
- **the boundary** — what the document explicitly does NOT cover
|
|
51
|
-
- **its governance** — `
|
|
51
|
+
- **its governance** — `status`, `ksor.owner` and `ksor.effective_from` from
|
|
52
|
+
the frontmatter
|
|
52
53
|
|
|
53
54
|
If the document already carries `<doc>.slides.yaml`, read it: it is a reviewed
|
|
54
55
|
compression of the same thing, and the two must not disagree.
|
|
55
56
|
|
|
56
57
|
## 2 · Write the summary
|
|
57
58
|
|
|
58
|
-
Write `<doc>.summary.md` beside the document.
|
|
59
|
-
|
|
59
|
+
Write `<doc>.summary.md` beside the document. Its frontmatter is exactly one
|
|
60
|
+
key and the checker refuses any other — a summary inherits its parent's
|
|
61
|
+
audience, status and takedown, and a second key there would claim governance a
|
|
62
|
+
non-document cannot carry:
|
|
60
63
|
|
|
61
64
|
```markdown
|
|
65
|
+
---
|
|
66
|
+
type: Summary
|
|
67
|
+
---
|
|
68
|
+
|
|
62
69
|
The lead: what this document settles, in one or two sentences, in the
|
|
63
70
|
document's own words. **Bold the thing a reader must not misremember.**
|
|
64
71
|
|
|
@@ -107,14 +114,14 @@ document, not before it.
|
|
|
107
114
|
## 4 · Verify it
|
|
108
115
|
|
|
109
116
|
```sh
|
|
110
|
-
pnpm check # refuses an orphan or
|
|
117
|
+
pnpm check # refuses an orphan, or frontmatter that is not exactly `type: Summary`
|
|
111
118
|
pnpm dev # open the page — a Summary tab appears beside Document
|
|
112
119
|
```
|
|
113
120
|
|
|
114
121
|
The build refuses:
|
|
115
122
|
|
|
116
123
|
- `ksor-attachment-orphan` — no `<doc>.md` beside it
|
|
117
|
-
- `ksor-attachment-frontmatter` —
|
|
124
|
+
- `ksor-attachment-frontmatter` — anything but exactly `type: Summary`
|
|
118
125
|
|
|
119
126
|
If no Summary tab appears, the file name is wrong: it must be exactly
|
|
120
127
|
`<doc>.summary.md`, matching the document's own name.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: add-sources
|
|
3
3
|
description: Turn source material — documents, pages, pasted text, notes — into governed knowledge in knowledge/. Use when the owner shares material to add, says "add this to the knowledge base", or asks how to get existing content in. Not for editing the site.
|
|
4
4
|
metadata:
|
|
5
|
-
version: "1.
|
|
5
|
+
version: "1.3.0"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Add sources
|
|
@@ -16,31 +16,76 @@ The rules that make it _governed_ rather than merely stored:
|
|
|
16
16
|
hyphens, a folder per natural grouping. Plain CommonMark `.md` — if the
|
|
17
17
|
source is rich (tables, images), tables become markdown tables and images
|
|
18
18
|
land _beside the document_ with relative links.
|
|
19
|
-
- A folder's
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
19
|
+
- A folder's `index.md` is GENERATED by `ksor build` and committed — never
|
|
20
|
+
author one. A folder's own introduction is a named document inside it,
|
|
21
|
+
such as `overview.md`. Reading order is the `order:` frontmatter key
|
|
22
|
+
(ordered documents first, ascending; the rest follow alphabetically) —
|
|
23
|
+
never `meta.json` or `sidebar_position`.
|
|
24
|
+
- Frontmatter is the KSoR Profile of OKF. Always: `type: Document`, `title`,
|
|
25
|
+
`description` (one sentence), `status: draft`, and `ksor.audience` (a
|
|
26
|
+
list). Reach for a reserved `type` — `Policy`, `Procedure`, `Control`,
|
|
27
|
+
`Standard`, `Definition`, `Decision Record`, `Example`,
|
|
28
|
+
`Attested Computation` — when the knowledge really is one; those additionally require `sources` and
|
|
29
|
+
`ksor.owner`, which is the point of them.
|
|
30
|
+
|
|
31
|
+
```yaml
|
|
32
|
+
---
|
|
33
|
+
type: Policy
|
|
34
|
+
title: Purchase approval
|
|
35
|
+
description: Who may approve a purchase, at which thresholds.
|
|
36
|
+
status: draft
|
|
37
|
+
sources:
|
|
38
|
+
- id: fin-2025
|
|
39
|
+
title: Finance policy manual §4.2, 2025 edition
|
|
40
|
+
resource: https://intranet.example.com/finance/manual.pdf
|
|
41
|
+
ksor:
|
|
42
|
+
audience: [public]
|
|
43
|
+
owner: team:finance
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
A purchase above 10,000 needs a director's signature. [^fin-2025]
|
|
47
|
+
|
|
48
|
+
[^fin-2025]: Finance policy manual §4.2, 2025 edition.
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Every source needs a `resource` — a URL where one exists, otherwise the
|
|
52
|
+
scope descriptor that names it ("Finance policy manual §4.2, 2025
|
|
53
|
+
edition"). Precision matters: that governs; "internal docs" does not. A
|
|
54
|
+
claim cites ONE of them by footnote, and the label must match a
|
|
55
|
+
`sources[].id` or the checker refuses it.
|
|
56
|
+
|
|
57
|
+
- `status: draft` always, and never anything else from here: `stable` needs
|
|
58
|
+
`ksor.approval` by an actor `.ksor/governance.yaml` names, and recording
|
|
59
|
+
an approval nobody gave is the one thing this skill must never do. Ask the
|
|
60
|
+
owner; if they approve, THEY are the approver and you write down what they
|
|
61
|
+
said.
|
|
62
|
+
- When `.ksor/governance.yaml` registers audiences, ask the owner which of
|
|
63
|
+
them may read the new material and list every one in `ksor.audience` —
|
|
64
|
+
never guess that restricted material is public, and never write an
|
|
65
|
+
identifier the registry does not declare (the checker refuses it, because
|
|
66
|
+
a typo reads as a restriction).
|
|
30
67
|
|
|
31
68
|
## Fidelity rules
|
|
32
69
|
|
|
33
70
|
- **Copy load-bearing values exactly** — numbers, thresholds, dates, names.
|
|
34
71
|
Never round, never paraphrase a figure.
|
|
35
|
-
- **Two disagreeing sources stay two statements**, each with its
|
|
36
|
-
— never smooth a conflict into one invented truth; flag it to the
|
|
72
|
+
- **Two disagreeing sources stay two statements**, each with its own
|
|
73
|
+
footnote — never smooth a conflict into one invented truth; flag it to the
|
|
74
|
+
owner.
|
|
37
75
|
- **Do not fill gaps from general knowledge.** If the source doesn't cover
|
|
38
76
|
something, the record doesn't either — that boundary is the product.
|
|
39
|
-
- A document replacing an older one: mark the old one `status:
|
|
40
|
-
with `
|
|
77
|
+
- A document replacing an older one: mark the old one `status: deprecated`
|
|
78
|
+
with `ksor.deprecated: { by, at }` (a takedown authority the policy names, or
|
|
79
|
+
the owner an `ownership:` rule resolves — never the document's own
|
|
80
|
+
`ksor.owner`; ask, never guess) and `ksor.superseded_by:` naming the
|
|
81
|
+
successor by id (`policies/refunds-v2`, no `./` and no `.md`) — never
|
|
82
|
+
delete it. The successor must exist, be `stable`, and be readable by every
|
|
83
|
+
reader of the deprecated one.
|
|
41
84
|
|
|
42
85
|
## Finish every batch
|
|
43
86
|
|
|
44
87
|
Run `pnpm check` and fix what it reports (its errors explain themselves),
|
|
45
|
-
then
|
|
46
|
-
|
|
88
|
+
then `ksor build` to regenerate every folder's `index.md` and write
|
|
89
|
+
`build.lock.json`, and commit both with the documents. Then show the owner
|
|
90
|
+
the rendered result (`pnpm dev`) — the site is the review surface: you write,
|
|
91
|
+
they check.
|
|
@@ -2,45 +2,54 @@
|
|
|
2
2
|
name: format-checker
|
|
3
3
|
description: The record's format rules as a runnable check — frontmatter, filenames, links, structure. Use before handing off any change to knowledge/, when a check fails and you need to fix it, or when unsure whether a document is well-formed. Run with `pnpm check` (or node .agents/skills/format-checker/check.mjs).
|
|
4
4
|
metadata:
|
|
5
|
-
version: "1.
|
|
5
|
+
version: "2.1.0"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Format checker
|
|
9
9
|
|
|
10
|
-
`pnpm check` runs `check.mjs` —
|
|
11
|
-
|
|
10
|
+
`pnpm check` runs `check.mjs` — a self-contained Node program that needs no
|
|
11
|
+
install. It is **generated** by ksor from the same rule set `ksor build` and
|
|
12
|
+
`ksor ingest` run, so the three can never disagree about what a well-formed
|
|
13
|
+
record is. Do not edit it: `ksor init` writes it and `ksor migrate` rewrites
|
|
14
|
+
both copies of it when you upgrade the tool, so an edit is overwritten rather
|
|
15
|
+
than kept. It is read-only in the other direction too — it reports, and never
|
|
16
|
+
rewrites a file.
|
|
12
17
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
|
|
21
|
-
(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
no `
|
|
18
|
+
If its refusals contradict this document, the checker is older than the record:
|
|
19
|
+
upgrade `@panaversity/ksor` and re-run `ksor migrate`, and never "fix" the
|
|
20
|
+
record by undoing what the migration wrote.
|
|
21
|
+
|
|
22
|
+
What it holds the record to (the full contract is ksor's record spec):
|
|
23
|
+
|
|
24
|
+
- Every document in `knowledge/` is a concept in the KSoR Profile of OKF:
|
|
25
|
+
frontmatter is real YAML carrying `type`, `title`, `description`, `status`
|
|
26
|
+
(`draft | stable | deprecated`) and `ksor.audience` (a list; `public` or
|
|
27
|
+
audiences registered in `.ksor/governance.yaml`). A `stable` concept carries
|
|
28
|
+
`generated` and an approval by an authorised actor; a `deprecated` one says
|
|
29
|
+
who deprecated it and usually names its successor; a reserved type (`Policy`,
|
|
30
|
+
`Procedure`, …) names `sources` and `ksor.owner`. Every timestamp is an
|
|
31
|
+
instant with an offset; every footnote label matches a `sources[].id`.
|
|
32
|
+
- `.ksor/governance.yaml` exists and names approval and takedown authorities;
|
|
33
|
+
`.ksor/takedowns.yaml` is append-only, every entry by a takedown authority,
|
|
34
|
+
and never names a concept that no longer exists.
|
|
35
|
+
- `index.md` files are generated by `ksor build`, never authored — a stale or
|
|
36
|
+
missing one is refused (`ksor-index-stale`; run `ksor build`). `log.md` and
|
|
37
|
+
`README.md` are reserved names.
|
|
38
|
+
- Filenames are portable identities: lowercase ascii, no spaces, no
|
|
39
|
+
case-collisions, no `x.md` beside `x/`, no parentheses or leading
|
|
40
|
+
underscore. `knowledge/` holds `.md`, companions (`<doc>.summary.md`,
|
|
41
|
+
`<doc>.{flashcards,quiz,slides}.yaml`) and images only.
|
|
42
|
+
- Links resolve inside `knowledge/` — inline, `<angle-bracketed>` and
|
|
43
|
+
reference-style alike; code is never a link — and never reach a document
|
|
44
|
+
that not every reader of the source may read (the widening rule).
|
|
45
|
+
- `instance.md` is `format: 2` with the closed key set the profile defines.
|
|
35
46
|
- `CLAUDE.md` stays a one-line pointer; `.agents/skills/` and
|
|
36
|
-
`.claude/skills/` hold the same files byte for byte
|
|
37
|
-
|
|
38
|
-
no content files.
|
|
47
|
+
`.claude/skills/` hold the same files byte for byte in both directions; the
|
|
48
|
+
site contains no content files.
|
|
39
49
|
|
|
40
|
-
Every failure prints
|
|
41
|
-
the printed fix literally; if it doesn't resolve
|
|
42
|
-
worth reporting to ksor.
|
|
50
|
+
Every failure prints where, the rule's slug (`problem: ksor-…`), why the rule
|
|
51
|
+
exists, and the fix — obey the printed fix literally; if it doesn't resolve
|
|
52
|
+
the problem, that is a bug worth reporting to ksor.
|
|
43
53
|
|
|
44
54
|
When you edit any skill under `.agents/skills/`, re-copy it to
|
|
45
|
-
`.claude/skills/` — the checker holds the two trees identical
|
|
46
|
-
notices a file added on either side.
|
|
55
|
+
`.claude/skills/` — the checker holds the two trees identical.
|