@panaversity/ksor 0.0.42 → 0.0.44

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 CHANGED
@@ -1,5 +1,85 @@
1
1
  # @panaversity/ksor
2
2
 
3
+ ## 0.0.44
4
+
5
+ ### Patch Changes
6
+
7
+ - 2ece135: **A lighter starter, and `refresh` finally says what it does** (issues #173, #171).
8
+
9
+ `ksor init` put five of `knowledge/`'s eleven files onto a single concept — 199
10
+ lines of companions against a 40-line document — so the first thing an adopter
11
+ opened was one document wearing four attachments. The flashcards, quiz and
12
+ slides companions are gone; `what-is-a-ksor.summary.md` stays, because it is the
13
+ only companion carrying a governance rule (exactly `type: Summary`, one key), so
14
+ the profile marker is still demonstrated. `knowledge/` goes from 11 files to 8.
15
+
16
+ What that costs, stated rather than glossed: the recall, quiz and slides tabs are
17
+ no longer shown by the starter, and an adopter meets those features in the docs
18
+ instead. Nothing about the companion mechanism changed — decision 24 is
19
+ untouched, and the migrate fixture that proves a deck migrates byte-identically
20
+ is frozen from an older tree, so it still covers the case.
21
+
22
+ And `pnpm refresh` was a name the constitution never defined, sitting beside
23
+ `pnpm ingest` and `ksor ingest` with nothing saying how the three relate. It has
24
+ a vocabulary entry now, and `docs/ingesting.md` opens with the model: `ksor
25
+ build` makes the SITE correct with no database, `ksor ingest` makes the AGENT
26
+ DOOR correct, and `pnpm refresh` runs both. The split between the scaffold's
27
+ script and the underlying verb is deliberate, and now it is written down instead
28
+ of inferred.
29
+
30
+ ## 0.0.43
31
+
32
+ ### Patch Changes
33
+
34
+ - 9ecfd78: **A document page that reads at a glance, and a dev server that sees new
35
+ documents again.**
36
+
37
+ The governance row is two tiers. It was one line carrying 79 characters, of
38
+ which the approver was 32 (41%) and the three labels 19 (24%) — so a producer
39
+ id was the longest thing on the page and the two facts a reader actually scans
40
+ for, what state this is in and whether anyone has checked it, competed with it.
41
+ Now the chips lead with Export beside them, and provenance sits beneath in
42
+ muted weight. Nothing is hidden: decision 21 requires a governance act to name
43
+ its actor and decision 27 requires a non-human approver to be disclosed, so the
44
+ approver moved one line down, not one click away, and every byte of it is still
45
+ in the server-rendered markup an agent parses.
46
+
47
+ Export no longer lands in the middle of the row. It and the reading time each
48
+ carried their own `ms-auto`, and on a row narrow enough to wrap they shared a
49
+ line — where two auto margins SPLIT the free space rather than stacking. They
50
+ are one right-hand cluster now.
51
+
52
+ **And adding a document to `knowledge/` while `pnpm dev` runs shows it again.**
53
+ This regressed in 0.0.41: `refreshStage` walked the STAGE and skipped anything
54
+ the stage did not already hold, so an arrival — which has no file to walk onto
55
+ — was never written, and the manifest naming what publishes never learned about
56
+ it. Measured: `/docs/<new>/` 404 → 200, sidebar 0 → 1, `llms.txt` 0 → 1;
57
+ 0.0.40 served it at 200, so this is a repair rather than a feature. Removals
58
+ still wait for a restart, deliberately — a deleted file leaves fumadocs'
59
+ generated imports pointing at something gone.
60
+
61
+ The comment explaining why arrivals were refused was also wrong, and is
62
+ corrected: fumadocs-mdx 15.3.0 DOES regenerate on a write into the
63
+ dot-prefixed stage. Our own function was the blocker.
64
+
65
+ Finally, the starter's `knowledge/surfaces/overview.md` was titled `Surfaces`
66
+ inside the Surfaces section, so its breadcrumb read `Surfaces › Surfaces`. It
67
+ is `Overview` now.
68
+
69
+ - 9ecfd78: **Two fixes on the document page.**
70
+
71
+ The governance row put **Export** in the middle of the row with nothing under
72
+ it. Export and the reading time each carried their own `ms-auto`, and on a row
73
+ narrow enough to wrap they landed on the same line — where two auto margins
74
+ SPLIT the free space between them rather than stacking, so Export came to rest
75
+ mid-row instead of at either end. They are now one right-hand cluster and
76
+ travel together at every width.
77
+
78
+ And the starter's `knowledge/surfaces/overview.md` was titled `Surfaces` inside
79
+ a section already called Surfaces, so its breadcrumb read `Surfaces › Surfaces`
80
+ and the sidebar showed a Surfaces inside Surfaces. It is titled `Overview` now,
81
+ matching its filename, and the generated section index was regenerated with it.
82
+
3
83
  ## 0.0.42
4
84
 
5
85
  ### Patch Changes
package/docs/ingesting.md CHANGED
@@ -14,6 +14,21 @@ embedding cost on every cold start and would need write credentials at runtime.
14
14
  So **a first deploy with no ingest serves an empty record.** It is not broken;
15
15
  nothing was ever published to it.
16
16
 
17
+ ## `ksor ingest` or `pnpm refresh`?
18
+
19
+ Both, and they are not alternatives — one contains the other.
20
+
21
+ | | makes correct | needs a database |
22
+ | -------------- | ----------------------------------------------------------------------------------- | ---------------- |
23
+ | `ksor build` | the **site** — checks the record, regenerates the indexes, writes `build.lock.json` | no |
24
+ | `ksor ingest` | the **agent door** — embeds, loads Postgres, flips a generation | yes |
25
+ | `pnpm refresh` | both, in order: `ksor build` → `ksor ingest --flip` → `ksor gc` | yes |
26
+
27
+ `pnpm refresh` is the scaffold's script and the one to reach for by hand — it
28
+ is a single command that leaves every surface current. `ksor ingest` is the
29
+ verb underneath it, and it is what CI, a deploy step, or an agent calls when
30
+ the individual step is the subject. The rest of this page is about that verb.
31
+
17
32
  ## Before the first command
18
33
 
19
34
  Ingest reads your markdown, sends each new chunk to an embedding provider, and
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@panaversity/ksor",
3
- "version": "0.0.42",
3
+ "version": "0.0.44",
4
4
  "description": "Knowledge System of Record — compile governed markdown into a static site for people and an MCP server for AI agents, with citations and measured abstention.",
5
5
  "keywords": [
6
6
  "abstention",
@@ -1,5 +1,5 @@
1
1
  # Surfaces
2
2
 
3
- * [Surfaces](overview.md) - One source, published through several synchronized projections.
3
+ * [Overview](overview.md) - One source, published through several synchronized projections.
4
4
  * [The human surface](for-people.md) - Pages for reading, reviewing and sharing the record.
5
5
  * [The agent surface](for-agents.md) - MCP for retrieval with citations, and machine-readable files beside it.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  type: Document
3
- title: Surfaces
3
+ title: Overview
4
4
  description: One source, published through several synchronized projections.
5
5
  status: stable
6
6
  order: 4
@@ -216,104 +216,132 @@ export function GovernanceMeta({
216
216
  // tier, `unverified` included, and that is the whole point of printing it.
217
217
  // The early return this replaced would have hidden the tier on exactly the
218
218
  // documents whose tier is the only governance fact they have.
219
+ /**
220
+ * TWO TIERS, because the row's length was never its vocabulary.
221
+ *
222
+ * Measured on the starter's own document: 79 characters, of which the
223
+ * APPROVER is 32 (41%) and the three labels 19 (24%). One producer id was
224
+ * longer than both governance chips together, so the two facts a reader
225
+ * scans for — what state is this in, and has anyone checked it — competed
226
+ * with a string that means nothing to them, and Export was pushed onto a
227
+ * line of its own.
228
+ *
229
+ * So the chips lead and the provenance follows beneath them. Nothing is
230
+ * hidden: decision 21 says a governance act NAMES its actor and decision
231
+ * 27's starter revision requires a non-human approver to be DISCLOSED, so
232
+ * demoting `ksor.approval` to a hover would trade a governance guarantee
233
+ * for a tidier row (critical rule 1). It is one line lower, not one click
234
+ * away, and every byte of it is still in the server-rendered markup an
235
+ * agent parses.
236
+ */
219
237
  return (
220
- <dl className="mb-7 flex flex-wrap items-baseline gap-x-8 gap-y-2.5 border-b border-fd-border pb-4">
221
- {state === null && alsoBadge === null ? null : (
222
- <Fact label="Status">
223
- <span className="flex flex-wrap items-baseline gap-1.5">
224
- {state === null ? null : <Chip text={state} tone={statusTone(status)} />}
225
- {alsoBadge === null ? null : (
226
- <BadgeChip badge={alsoBadge} effectiveFrom={effectiveFrom} />
227
- )}
228
- </span>
229
- </Fact>
230
- )}
231
- {/* The tier OKF's own vocabulary names, on every document including the
238
+ <div className="mb-7 border-b border-fd-border pb-4">
239
+ <dl className="flex flex-wrap items-baseline gap-x-8 gap-y-2.5">
240
+ {state === null && alsoBadge === null ? null : (
241
+ <Fact label="Status">
242
+ <span className="flex flex-wrap items-baseline gap-1.5">
243
+ {state === null ? null : <Chip text={state} tone={statusTone(status)} />}
244
+ {alsoBadge === null ? null : (
245
+ <BadgeChip badge={alsoBadge} effectiveFrom={effectiveFrom} />
246
+ )}
247
+ </span>
248
+ </Fact>
249
+ )}
250
+ {/* The tier OKF's own vocabulary names, on every document including the
232
251
  unverified ones — that is the honest state of a stable, approved
233
252
  concept nobody has reviewed, and hiding it would leave a reader unable
234
253
  to tell "checked" from "never mentioned" (research/okf-native.md
235
254
  §1.1). Never a colour: a tier is a fact about review, not a warning. */}
236
- <Fact label="Trust">
237
- <span className="flex flex-wrap items-baseline gap-1.5">
238
- <Chip text={trust.tier} />
239
- {trust.by === null ? null : (
240
- <span className="font-normal text-fd-muted-foreground">
241
- {trust.by}
242
- {trust.at === null ? null : <> · {day(trust.at)}</>}
243
- </span>
244
- )}
245
- </span>
246
- </Fact>
247
- {owner === null ? null : <Fact label="Owner">{owner}</Fact>}
248
- {/* Who let this into the record. `ksor.approval` is what makes a `stable`
255
+ <Fact label="Trust">
256
+ <span className="flex flex-wrap items-baseline gap-1.5">
257
+ <Chip text={trust.tier} />
258
+ {trust.by === null ? null : (
259
+ <span className="font-normal text-fd-muted-foreground">
260
+ {trust.by}
261
+ {trust.at === null ? null : <> · {day(trust.at)}</>}
262
+ </span>
263
+ )}
264
+ </span>
265
+ </Fact>
266
+ {/* Actions ride tier ONE: a reader who wants the bytes wants them
267
+ immediately, and this is the row with room. */}
268
+ {markdownUrl === undefined && minutes === undefined ? null : (
269
+ <div className="ms-auto flex items-center gap-x-6">
270
+ {markdownUrl === undefined ? null : <DocumentActions href={markdownUrl} />}
271
+ {minutes === undefined ? null : (
272
+ <div className="flex items-center gap-2 text-sm text-fd-muted-foreground">
273
+ <Clock aria-hidden className="size-3.5 shrink-0" />
274
+ <span>{minutes} min read</span>
275
+ </div>
276
+ )}
277
+ </div>
278
+ )}
279
+ </dl>
280
+ {/* Tier two RECEDES. It is provenance — who let this in, when it takes
281
+ effect, what it replaced — and it is read when a reader goes looking,
282
+ not scanned. At full `--foreground` weight it competed with the two
283
+ chips above it for the same attention, which is what made a producer
284
+ id the loudest thing on the page.
285
+
286
+ Links keep full strength: `Replaces` points at the document this one
287
+ superseded, and that is an action rather than a fact. */}
288
+ <dl className="mt-2.5 flex flex-wrap items-baseline gap-x-8 gap-y-2.5 empty:mt-0 [&_a]:text-fd-foreground [&_dd]:font-normal [&_dd]:text-fd-muted-foreground">
289
+ {owner === null ? null : <Fact label="Owner">{owner}</Fact>}
290
+ {/* Who let this into the record. `ksor.approval` is what makes a `stable`
249
291
  document stable at all (record spec §2.2), so a page that showed the
250
292
  word and not the signature would be publishing the claim without its
251
293
  author. */}
252
- {approval === null ? null : (
253
- <Fact label="Approved">
254
- <>
255
- {approval.by} · {day(approval.at)}
256
- </>
257
- </Fact>
258
- )}
259
- {/* found live 2026-08-25: a deprecated page named its successor and said
294
+ {approval === null ? null : (
295
+ <Fact label="Approved">
296
+ <>
297
+ {approval.by} · {day(approval.at)}
298
+ </>
299
+ </Fact>
300
+ )}
301
+ {/* found live 2026-08-25: a deprecated page named its successor and said
260
302
  nothing about WHO withdrew it, though `ksor.deprecated` is required on
261
303
  every deprecated concept (record spec §2.2) and readGovernance already
262
304
  refuses a document that omits it. Withdrawal is the most consequential
263
305
  act in a document's life; publishing it unattributed is exactly the
264
306
  gap the approver fact above closes at the other end. */}
265
- {deprecated === null ? null : (
266
- <Fact label="Withdrawn">
267
- <>
268
- {deprecated.by} · {day(deprecated.at)}
269
- </>
270
- </Fact>
271
- )}
272
- {replaces.length === 0 ? null : (
273
- // The other half of a supersession. The withdrawn document names its
274
- // successor above the title; this is the successor naming what it
275
- // replaced, so the history the record kept is reachable from the
276
- // current document instead of only from the retired one.
277
- <Fact label="Replaces">
278
- <>
279
- {replaces.map((entry, index) => (
280
- <span key={entry.href ?? `${index}-${entry.label}`}>
281
- {index === 0 ? null : ", "}
282
- {entry.href === null ? (
283
- entry.label
284
- ) : (
285
- <Link
286
- href={entry.href}
287
- className="underline underline-offset-4 transition-colors hover:text-fd-primary focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-fd-ring"
288
- >
289
- {entry.label}
290
- </Link>
291
- )}
292
- </span>
293
- ))}
294
- </>
295
- </Fact>
296
- )}
297
- {effectiveFrom === null || !showEffective ? null : (
298
- <Fact label="Effective from">{day(effectiveFrom)}</Fact>
299
- )}
300
- {staleAfter === null ? null : <Fact label="Review by">{day(staleAfter)}</Fact>}
301
- {markdownUrl === undefined ? null : (
302
- // On the governance row, not as a footnote below the sources: it is
303
- // how a reader hands this document to an agent (research/site-design.md
304
- // F2). Right-aligned: a column of things you DO, against a row of
305
- // things the record DECLARES (owner, 2026-08-22).
306
- <span className="ms-auto">
307
- <DocumentActions href={markdownUrl} />
308
- </span>
309
- )}
310
- {minutes === undefined ? null : (
311
- <div className="ms-auto flex items-center gap-2 text-sm text-fd-muted-foreground">
312
- <Clock aria-hidden className="size-3.5 shrink-0" />
313
- <span>{minutes} min read</span>
314
- </div>
315
- )}
316
- </dl>
307
+ {deprecated === null ? null : (
308
+ <Fact label="Withdrawn">
309
+ <>
310
+ {deprecated.by} · {day(deprecated.at)}
311
+ </>
312
+ </Fact>
313
+ )}
314
+ {replaces.length === 0 ? null : (
315
+ // The other half of a supersession. The withdrawn document names its
316
+ // successor above the title; this is the successor naming what it
317
+ // replaced, so the history the record kept is reachable from the
318
+ // current document instead of only from the retired one.
319
+ <Fact label="Replaces">
320
+ <>
321
+ {replaces.map((entry, index) => (
322
+ <span key={entry.href ?? `${index}-${entry.label}`}>
323
+ {index === 0 ? null : ", "}
324
+ {entry.href === null ? (
325
+ entry.label
326
+ ) : (
327
+ <Link
328
+ href={entry.href}
329
+ className="underline underline-offset-4 transition-colors hover:text-fd-primary focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-fd-ring"
330
+ >
331
+ {entry.label}
332
+ </Link>
333
+ )}
334
+ </span>
335
+ ))}
336
+ </>
337
+ </Fact>
338
+ )}
339
+ {effectiveFrom === null || !showEffective ? null : (
340
+ <Fact label="Effective from">{day(effectiveFrom)}</Fact>
341
+ )}
342
+ {staleAfter === null ? null : <Fact label="Review by">{day(staleAfter)}</Fact>}
343
+ </dl>
344
+ </div>
317
345
  );
318
346
  }
319
347
 
@@ -670,30 +670,51 @@ function fillStage(recordDir: string, stageDir: string, development: boolean): v
670
670
  }
671
671
 
672
672
  /**
673
- * Dev only: carry edits into the files the stage already holds, so
674
- * `pnpm dev` shows the record as the owner is writing it rather than as it
675
- * stood when the server started — the regenerated indexes included, so a
676
- * retitled document is retitled in its folder's listing too.
673
+ * Dev only: carry edits AND ARRIVALS into the stage, so `pnpm dev` shows the
674
+ * record as the owner is writing it rather than as it stood when the server
675
+ * started — the regenerated indexes included, so a retitled document is
676
+ * retitled in its folder's listing too.
677
677
  *
678
- * Edits only — never adds, never removals. fumadocs' own watcher cannot see
679
- * a dot-prefixed collection directory (measured 2026-08-18: adding a file to
680
- * the stage regenerated nothing, and removing one left the generated imports
681
- * pointing at a file that was gone), so a document that ARRIVES or changes
682
- * audience needs the restart `pnpm dev` already needs for instance.md. Leaving
683
- * that to a restart keeps dev honest in the direction that matters: the
684
- * published build is always staged from scratch.
678
+ * Adds and edits — never removals. The 2026-08-18 measurement this refused
679
+ * adds on ("fumadocs' own watcher cannot see a dot-prefixed collection
680
+ * directory") no longer holds: on fumadocs-mdx 15.3.0 a file written into
681
+ * `.staged-knowledge` DOES regenerate the collection, twice-observed as
682
+ * `[MDX] generated files` in the dev log. What actually kept a new document
683
+ * off every surface was this function, which walked the STAGE and skipped
684
+ * anything the stage did not already hold — so a plan entry with no file on
685
+ * disk was never written, and the manifest that names what publishes never
686
+ * learned about it either.
687
+ *
688
+ * Measured before and after, adding a document while `pnpm dev` ran:
689
+ * `/docs/<new>/` 404 -> 200, sidebar 0 -> 1, `llms.txt` 0 -> 1. It worked
690
+ * this way before the stage existed (0.0.40 serves an added document at 200),
691
+ * so this is a regression repaired rather than a feature.
692
+ *
693
+ * REMOVALS still wait for the restart `pnpm dev` already needs for
694
+ * instance.md: the same measurement found a deleted file leaves fumadocs'
695
+ * generated imports pointing at something gone, which takes the dev server
696
+ * down rather than showing a stale page. An arrival has no such failure mode
697
+ * — nothing points at a file that has only just appeared.
685
698
  */
686
699
  function refreshStage(recordDir: string, stageDir: string): void {
687
700
  // Under the lock like every other write here: a save landing while another
688
701
  // evaluation is refilling the stage is the same race from the other side.
689
702
  withStageLock(stageDir, () => {
690
703
  const plan = planStage(recordDir, true);
691
- const permitted = new Map(plan.entries.map((e) => [path.join(stageDir, e.rel), e] as const));
692
- for (const staged of walkFiles(stageDir)) {
693
- const entry = permitted.get(staged);
694
- if (entry === undefined) continue;
704
+ // Drive from the PLAN, not from the stage. Walking the stage could only
705
+ // ever find what was already there, which is exactly why an arrival was
706
+ // invisible: it has no file to walk onto.
707
+ for (const entry of plan.entries) {
708
+ const staged = path.join(stageDir, entry.rel);
695
709
  const bytes = entry.bytes();
696
- if (bytes.equals(readFileSync(staged))) continue;
710
+ let current: Buffer | null = null;
711
+ try {
712
+ current = readFileSync(staged);
713
+ } catch {
714
+ // Not staged yet — an arrival. Written below.
715
+ }
716
+ if (current !== null && current.equals(bytes)) continue;
717
+ mkdirSync(path.dirname(staged), { recursive: true });
697
718
  writeFileSync(staged, bytes);
698
719
  }
699
720
  writeManifest(stageDir, plan.manifest);
@@ -1,25 +0,0 @@
1
- # A recall deck for what-is-a-ksor.md.
2
- #
3
- # Every card states only what its parent document states — a deck is a way of
4
- # rehearsing the record, never a second source. Ask your coding agent to write
5
- # one of these from a document, and to check each answer against it.
6
- deck:
7
- title: What a KSoR is
8
- description: Recall checks for the record's own definition of itself.
9
- cards:
10
- - front: When a spreadsheet disagrees with the ledger, which one wins?
11
- back: The ledger. A system of record is the copy that governs.
12
- why: Which copy would your organization's agents trust today?
13
-
14
- - front: A traditional system of record settles the state of a business. What does a KSoR settle?
15
- back: What the organization knows and how it should operate — which policies apply, which thresholds are approved, what a term means here.
16
-
17
- - front: What problem does a KSoR solve?
18
- back: Scatter. Knowledge spread across wikis, decks, PDFs, prompts and someone's memory, with no authoritative answer to which knowledge an agent should trust.
19
-
20
- - front: Why can an assistant not tell you which of its sentences were checked?
21
- back: Because it answers from everything it has ever read. Nothing in that process distinguishes a checked claim from an unchecked one.
22
- why: This is the gap the record exists to close.
23
-
24
- - front: Does provenance prove that a document is correct?
25
- back: No. Provenance proves who said what, and when. Whether the source is any good is a separate matter, and the record never claims otherwise.
@@ -1,90 +0,0 @@
1
- # A quiz for what-is-a-ksor.md.
2
- #
3
- # Every question and every answer states only what its parent document states —
4
- # a quiz is a way of checking the record, never a second source. Ask your coding
5
- # agent to write one from a document, and to check each answer back against it.
6
- #
7
- # Two habits worth copying. The options are kept close in LENGTH, because if the
8
- # correct answer is reliably the longest one a reader passes by looking rather
9
- # than by reading. And the correct answer moves POSITION between questions: a
10
- # quiz whose answer is usually B is a quiz you can pass without the document.
11
- # `pnpm check` and `pnpm build` both refuse a quiz where either is true — the
12
- # first draft of this one was refused for putting four of five answers at B.
13
- quiz:
14
- title: Check yourself
15
- description: Five questions on what this record is, and what it is not.
16
- questions:
17
- - question: A spreadsheet and the ledger disagree about a number. Which one is authoritative?
18
- options:
19
- - Whichever of the two was most recently edited
20
- - The spreadsheet, being closer to the daily work
21
- - The ledger, because it is the governing copy
22
- - Neither, until a person reconciles the two
23
- answer: 2
24
- explanation: >
25
- A system of record is the copy that governs, so the ledger wins by
26
- definition rather than by being newer or closer to the work. Recency is
27
- not authority: an edit made this morning in a spreadsheet nobody governs
28
- is still ungoverned. Reconciliation is something a record makes possible,
29
- not a precondition for having an answer at all.
30
- source: The opening definition
31
-
32
- - question: What does a KSoR settle that a traditional system of record does not?
33
- options:
34
- - The state of a business, such as its balances
35
- - Which vendor an organization has chosen to use
36
- - How much storage the organization is paying for
37
- - What the organization knows and how it operates
38
- answer: 3
39
- explanation: >
40
- A traditional system of record settles the state of a business — what is
41
- owed, what is owned, what was transacted. A KSoR settles the layer above
42
- it: which policies apply, which thresholds are approved, and what a term
43
- means inside this organization. Vendor choice and storage cost are
44
- consequences of running one, never what it is authoritative for.
45
- source: What this record settles
46
-
47
- - question: Why can an ordinary assistant not tell you which of its sentences were checked?
48
- options:
49
- - It answers from everything it has ever read
50
- - It was not given enough context to work with
51
- - Its answers are checked, but only in summary
52
- - It lacks permission to reveal its own sources
53
- answer: 0
54
- explanation: >
55
- It answers from everything it has ever read, and nothing in that process
56
- separates a checked claim from an unchecked one. This is not a context
57
- problem and not a permissions problem: more context cannot create a
58
- distinction that was never recorded in the first place. The record closes
59
- the gap by governing what gets read.
60
- source: Why an assistant cannot answer that question
61
-
62
- - question: What problem does a KSoR exist to solve?
63
- options:
64
- - Storage costs across a growing organization
65
- - Scatter, with no authoritative copy to trust
66
- - The speed at which an assistant can reply
67
- - The difficulty of writing documentation well
68
- answer: 1
69
- explanation: >
70
- The problem is scatter: knowledge spread across wikis, decks, PDFs,
71
- prompts and somebody's memory, with no authoritative answer to which of
72
- them an agent should trust. Speed and cost are not what the record
73
- addresses, and writing well is valuable but does not by itself tell an
74
- agent which of two documents governs.
75
- source: The problem it solves
76
-
77
- - question: Abstention — answering "not in this corpus" — is best described as what?
78
- options:
79
- - An error state the record should minimise
80
- - A temporary gap, pending the next ingest
81
- - A setting an operator turns on when ready
82
- - A correct answer the record is meant to give
83
- answer: 3
84
- explanation: >
85
- Abstention is a correct answer, never an error and never a licence to
86
- fall back on general model knowledge. A record that answers everything
87
- has stopped being a record of anything in particular. It is not a gap
88
- waiting to be filled, and while the gate that enforces it is configured
89
- deliberately, the honesty it expresses is the product itself.
90
- source: What this record settles, and what it does not
@@ -1,65 +0,0 @@
1
- # The presentation that teaches what-is-a-ksor.md.
2
- #
3
- # These slides live IN the record: reviewed in a pull request, versioned with
4
- # the document, withdrawn when it is withdrawn, and rendered by the site — so
5
- # there is no third party, no dead link, and nothing to keep in step by hand.
6
- # Your coding agent writes them from the document; `.agents/skills/make-slides/`
7
- # is the procedure.
8
- #
9
- # A slide may only say what the document says. A deck is a way of presenting
10
- # the record, never a second source.
11
- slides:
12
- title: Introducing the record
13
- description: The 15-minute version, for a room.
14
- deck:
15
- # The opening slide does NOT repeat the page title. It sits directly under
16
- # it, so restating it wastes the one slide everyone actually looks at.
17
- - heading: Which copy should an agent trust?
18
- lead: That question is what this record exists to answer, and nothing in an ordinary assistant can.
19
- note: Open with the question, not the definition. The definition lands after they feel the problem.
20
-
21
- - heading: The problem it solves
22
- bullets:
23
- - Knowledge is scattered across wikis, decks, PDFs, prompts and memory
24
- - No authoritative answer to the question an agent has to ask
25
- - Which of these copies should I trust?
26
- note: Ask the room where their real answer lives today. Wait for the disagreement — it always comes.
27
-
28
- - heading: When two copies disagree, one wins
29
- bullets:
30
- - A traditional system of record settles the state of a business
31
- - The ledger is authoritative; the spreadsheet is not
32
- - Recency is not authority — a fresh edit to an ungoverned copy is still ungoverned
33
- note: This is the whole idea. If they take one slide away, it is this one.
34
-
35
- - heading: AI never had one
36
- bullets:
37
- - An assistant answers from everything it has ever read
38
- - Nothing in that separates a checked claim from an unchecked one
39
- - Which is exactly why it cannot tell you which of its sentences were verified
40
- note: Not a criticism of the models. It is a missing layer, and that layer is what we are building.
41
-
42
- - heading: What this record settles
43
- bullets:
44
- - Which policies apply, and which thresholds are approved
45
- - What a term means inside this organization
46
- - What to do when the answer is not known
47
- note: Point at the third one. It is the one people do not expect.
48
-
49
- - heading: Abstention is a feature
50
- lead: '"Not in this corpus" is a correct answer — never an error, and never a licence to fall back on model knowledge.'
51
- note: A record that answers everything has stopped being a record of anything in particular.
52
-
53
- - heading: One source, two surfaces
54
- bullets:
55
- - The website is for people
56
- - The MCP server is for agents
57
- - Both render the same build — they can never disagree
58
- note: Open llms.txt beside the page here. Seeing one source render twice lands better than describing it.
59
-
60
- - heading: Where the edges are
61
- bullets:
62
- - Provenance proves who said what, and when
63
- - It does not prove the source was right — that is a separate judgment
64
- - Governance is a ladder, not a gate; level 0 works on day one
65
- note: Say the second bullet out loud. Overselling provenance is how these systems lose trust.