@panaversity/ksor 0.0.39 → 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.
Files changed (108) hide show
  1. package/CHANGELOG.md +965 -0
  2. package/README.md +29 -9
  3. package/dist/checker/check-main.mjs +14049 -0
  4. package/dist/cli.mjs +11528 -5213
  5. package/dist/gateway-api-CF4ED9_g-BQusM_dK.mjs +10895 -0
  6. package/dist/gateway.d.mts +52 -13
  7. package/dist/gateway.mjs +2 -2
  8. package/dist/index.d.mts +1 -1
  9. package/dist/index.mjs +1 -1
  10. package/dist/{src-pl4aOpVs.mjs → src-dqpI-p1a.mjs} +1 -0
  11. package/docs/authorization.md +8 -6
  12. package/docs/deploying.md +36 -25
  13. package/docs/index.md +26 -13
  14. package/docs/ingesting.md +70 -22
  15. package/docs/tool-surface.md +69 -16
  16. package/package.json +4 -3
  17. package/schema/migrations/2.4-2.5__okf-profile.sql +114 -0
  18. package/schema/schema.sql +77 -14
  19. package/templates/scaffold/.agents/skills/add-sources/SKILL.md +63 -18
  20. package/templates/scaffold/.agents/skills/format-checker/SKILL.md +42 -33
  21. package/templates/scaffold/.agents/skills/format-checker/check.mjs +13827 -1314
  22. package/templates/scaffold/.agents/skills/intake-interview/SKILL.md +65 -27
  23. package/templates/scaffold/.agents/skills/make-slides/SKILL.md +7 -5
  24. package/templates/scaffold/.agents/skills/make-summary/SKILL.md +13 -6
  25. package/templates/scaffold/.claude/skills/add-sources/SKILL.md +63 -18
  26. package/templates/scaffold/.claude/skills/format-checker/SKILL.md +42 -33
  27. package/templates/scaffold/.claude/skills/format-checker/check.mjs +13827 -1314
  28. package/templates/scaffold/.claude/skills/intake-interview/SKILL.md +65 -27
  29. package/templates/scaffold/.claude/skills/make-slides/SKILL.md +7 -5
  30. package/templates/scaffold/.claude/skills/make-summary/SKILL.md +13 -6
  31. package/templates/scaffold/.github/workflows/validate.yml +9 -1
  32. package/templates/scaffold/.ksor/governance.yaml +17 -0
  33. package/templates/scaffold/AGENTS.md +293 -119
  34. package/templates/scaffold/Dockerfile +5 -1
  35. package/templates/scaffold/README.md +160 -42
  36. package/templates/scaffold/env.example +37 -6
  37. package/templates/scaffold/gitignore +14 -6
  38. package/templates/scaffold/instance.md +21 -17
  39. package/templates/scaffold/knowledge/governance-ladder.md +11 -2
  40. package/templates/scaffold/knowledge/index.md +9 -0
  41. package/templates/scaffold/knowledge/surfaces/for-agents.md +13 -6
  42. package/templates/scaffold/knowledge/surfaces/for-people.md +7 -6
  43. package/templates/scaffold/knowledge/surfaces/index.md +4 -20
  44. package/templates/scaffold/knowledge/surfaces/overview.md +25 -0
  45. package/templates/scaffold/knowledge/what-is-a-ksor.md +6 -5
  46. package/templates/scaffold/knowledge/what-is-a-ksor.summary.md +4 -0
  47. package/templates/scaffold/package.json +3 -4
  48. package/templates/scaffold/pnpm-lock.yaml +3 -0
  49. package/templates/scaffold/system/gateways/content.ts +13 -0
  50. package/templates/scaffold/system/site/app/(home)/page.tsx +2 -2
  51. package/templates/scaffold/system/site/app/.well-known/mcp/server.json/route.ts +10 -0
  52. package/templates/scaffold/system/site/app/docs/[[...slug]]/page.tsx +134 -91
  53. package/templates/scaffold/system/site/app/global.css +198 -6
  54. package/templates/scaffold/system/site/app/layout.tsx +8 -3
  55. package/templates/scaffold/system/site/app/llms-full.txt/route.ts +13 -7
  56. package/templates/scaffold/system/site/app/llms.txt/route.ts +12 -7
  57. package/templates/scaffold/system/site/app/md/[[...slug]]/route.ts +26 -25
  58. package/templates/scaffold/system/site/components/code-block.tsx +87 -0
  59. package/templates/scaffold/system/site/components/embed.tsx +276 -0
  60. package/templates/scaffold/system/site/components/footer-mark.tsx +3 -2
  61. package/templates/scaffold/system/site/components/governance.tsx +219 -87
  62. package/templates/scaffold/system/site/components/mdx.tsx +10 -2
  63. package/templates/scaffold/system/site/components/record-index.tsx +5 -5
  64. package/templates/scaffold/system/site/components/record-stack.tsx +10 -9
  65. package/templates/scaffold/system/site/components/record-views.tsx +6 -17
  66. package/templates/scaffold/system/site/components/sidebar-status.tsx +19 -18
  67. package/templates/scaffold/system/site/lib/alert-rule.ts +214 -0
  68. package/templates/scaffold/system/site/lib/attachment-rule.ts +6 -1
  69. package/templates/scaffold/system/site/lib/attachments.ts +0 -28
  70. package/templates/scaffold/system/site/lib/audience-rule.ts +15 -21
  71. package/templates/scaffold/system/site/lib/audience.ts +42 -146
  72. package/templates/scaffold/system/site/lib/embed-rule.ts +255 -0
  73. package/templates/scaffold/system/site/lib/governance.ts +339 -225
  74. package/templates/scaffold/system/site/lib/index-routes.ts +125 -0
  75. package/templates/scaffold/system/site/lib/lifecycle-rule.ts +52 -0
  76. package/templates/scaffold/system/site/lib/lock.ts +282 -0
  77. package/templates/scaffold/system/site/lib/order-rule.ts +37 -0
  78. package/templates/scaffold/system/site/lib/record-href.ts +68 -0
  79. package/templates/scaffold/system/site/lib/record-link.tsx +26 -0
  80. package/templates/scaffold/system/site/lib/rules-version.ts +11 -0
  81. package/templates/scaffold/system/site/lib/shared.ts +67 -104
  82. package/templates/scaffold/system/site/lib/sim-rule.ts +49 -0
  83. package/templates/scaffold/system/site/lib/source.ts +256 -186
  84. package/templates/scaffold/system/site/lib/stage-knowledge.ts +638 -467
  85. package/templates/scaffold/system/site/lib/stage-manifest.ts +128 -0
  86. package/templates/scaffold/system/site/package.json +1 -0
  87. package/templates/scaffold/system/site/record/actor.ts +23 -0
  88. package/templates/scaffold/system/site/record/check.ts +571 -0
  89. package/templates/scaffold/system/site/record/citations.ts +312 -0
  90. package/templates/scaffold/system/site/record/frontmatter.ts +134 -0
  91. package/templates/scaffold/system/site/record/git-ledger.ts +171 -0
  92. package/templates/scaffold/system/site/record/hygiene.ts +320 -0
  93. package/templates/scaffold/system/site/record/index-file.ts +150 -0
  94. package/templates/scaffold/system/site/record/index.ts +103 -0
  95. package/templates/scaffold/system/site/record/instance.ts +257 -0
  96. package/templates/scaffold/system/site/record/instant.ts +43 -0
  97. package/templates/scaffold/system/site/record/ledger.ts +694 -0
  98. package/templates/scaffold/system/site/record/load.ts +129 -0
  99. package/templates/scaffold/system/site/record/lock.ts +306 -0
  100. package/templates/scaffold/system/site/record/near-miss.ts +37 -0
  101. package/templates/scaffold/system/site/record/policy.ts +414 -0
  102. package/templates/scaffold/system/site/record/profile.ts +535 -0
  103. package/templates/scaffold/system/site/record/refusal.ts +106 -0
  104. package/templates/scaffold/system/site/record/yaml-file.ts +103 -0
  105. package/templates/scaffold/system/site/source.config.ts +109 -23
  106. package/dist/gateway-api-CmIthmJS-IUA9qS-T.mjs +0 -3225
  107. package/templates/scaffold/system/site/lib/denial-rule.ts +0 -220
  108. 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 — six questions that define what it is authoritative for and who may read 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.
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.3.0"
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, from most public to most restricted?" A yes
35
- is the common answer and the whole answer: write no `audiences:` key and
36
- nothing about the project changes. A list means writing it into
37
- `instance.md`'s frontmatter ordered least- to most-restricted with
38
- `public` first, plus `default_visibility:` naming the audience a document
39
- takes when it says nothing (there is no safe guess, so the checker
40
- requires it). Tell the owner what the key does and does not do:
41
- documents carry `visibility:` and builds are made per audience, but
42
- anyone who can clone the repository reads everything in it if someone
43
- must not read a document and can clone, that document belongs in a
44
- different repository.
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`'s body from the answers: first the `# H1` the
49
- record's **display title**, the human name every page will lead with
50
- ("Acme Operations Handbook", not the slug) then the authority sentence,
51
- boundary, audience, and strictness plain prose, written for a reader
52
- who must act on it. Leave the identity frontmatter keys alone; two things
53
- are written there when they apply: an audience model from question 6, as
54
- `audiences:` (a list) and `default_visibility:` (`pnpm check` holds the
55
- record to it from that moment on); and only when the owner stands up the
56
- served MCP rung — the `database:`/`embedding:`/`retrieval:` blocks (see
57
- `AGENTS.md` → "Serving to agents"; that is a later climb, not part of this
58
- interview). The strictness answer from question 5 is the intent behind the
59
- `retrieval.vector_floor` on that climb, measured by `ksor calibrate` — capture
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** — `owner`, `effective`, `status` from the frontmatter
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, frontmatter, or a malformed deck
112
- pnpm dev # look at the page — the deck renders at the end
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.0.0"
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** — `owner`, `effective`, `status` from the frontmatter
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. **No frontmatter** an
59
- attachment carries none, and the checker refuses one:
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 an attachment carrying frontmatter
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` — an attachment carries none of its own
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.
@@ -16,8 +16,16 @@ jobs:
16
16
  - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
17
17
  with:
18
18
  persist-credentials: false
19
+ # Full history, and the checker below NEEDS it: the takedown ledger
20
+ # is append-only, and the committed build.lock.json cannot prove that
21
+ # on its own — it travels in this very pull request and can be edited
22
+ # in the same commit that deletes a denial. Git history is the
23
+ # baseline that is not in the change. On a shallow clone the checker
24
+ # says so (ksor-ledger-unverifiable) and falls back to the lock;
25
+ # `ksor build` refuses that state outright.
26
+ fetch-depth: 0
19
27
  - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
20
28
  with:
21
29
  node-version: "24"
22
- # The checker is dependency-free Node — no install step needed.
30
+ # The checker is self-contained Node (generated by ksor) — no install step needed.
23
31
  - run: node .agents/skills/format-checker/check.mjs
@@ -0,0 +1,17 @@
1
+ # The Governance Policy: who has authority over this record. The intake
2
+ # interview replaces `human:you` with real handles. `public` is implicit;
3
+ # register a restricted audience here before any document names it:
4
+ # audiences:
5
+ # internal:
6
+ # description: Employees
7
+ version: "0.1"
8
+ approval_authorities:
9
+ # `ksor-starter/...` approved the five sample documents it shipped, so a fresh
10
+ # record PUBLISHES on the first build instead of admitting nothing. It is a
11
+ # producer, not a person: it cannot be mistaken for a human who reviewed
12
+ # anything, and the trust tier stays `unverified`, which is the honest word
13
+ # for "nobody has checked this". Delete this actor once the samples are gone
14
+ # — nothing of yours should ever be approved by a tool.
15
+ - actors: [human:you, ksor-starter/KSOR-STAMP-VERSION]
16
+ takedown_authorities:
17
+ actors: [human:you]