@panaversity/ksor 0.0.43 → 0.0.45

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,105 @@
1
1
  # @panaversity/ksor
2
2
 
3
+ ## 0.0.45
4
+
5
+ ### Patch Changes
6
+
7
+ - 1875d06: **`pnpm preview` — somewhere for `pnpm build` to land.**
8
+
9
+ The site is a static export, so there is no server to start; that is what makes
10
+ the record hostable anywhere. But it also means the natural thing to try after a
11
+ build — `pnpm start` — answers `ERR_PNPM_NO_SCRIPT_OR_SERVER`, which explains
12
+ none of that. `pnpm preview` serves `system/site/out` on the same bytes a host
13
+ would. It is `node:http` and nothing else: no dependency, no network fetch, works
14
+ offline and behind a firewall, for the same reason the build downloads nothing.
15
+ Run before a build, it says so and exits `3`.
16
+
17
+ **And the Vercel dashboard import now says what actually goes wrong.** Vercel
18
+ auto-detects a root directory by looking for a framework, finds the Next app, and
19
+ fills the field with `system/site`. The build then reads
20
+ `system/site/vercel.json`, which does not exist, and fails with
21
+ `Project framework is set to "services", but no services are declared` — even
22
+ though the import screen just listed both services, because that step reads the
23
+ root file and the build step uses the Root Directory override. The fix is one
24
+ field: set Root Directory to the repository root. `docs/deploying.md` now names
25
+ the error, the cause and the fix, plus the site-only fallback.
26
+
27
+ Found by an adopter, and it will recur on every dashboard import until Vercel's
28
+ detection changes — the layout that triggers it is decision 8 and is not moving.
29
+
30
+ **And the intake interview asks three questions, not seven.** Seven did not
31
+ survive contact: an agent running the skill decided five were too many,
32
+ defaulted them, and reported "answered: all seven" — including the one that
33
+ decides who may approve a document, which it filled from a git handle. A
34
+ process the tool executing it shortcuts is too long.
35
+
36
+ Scope, Boundary and Authority are asked, because none can be defaulted: the
37
+ first two give the abstention gate an edge to be outside of, and the third is
38
+ a governance act, which never gets guessed (decision 21). The other four are
39
+ STATED as defaults in one block — read by both, declines firmly, one `public`
40
+ audience, no sources yet — written only if the owner does not object, and the
41
+ write-back must name which were answered and which were defaulted. Reporting a
42
+ default as an answer is now called out in the skill as the thing not to do.
43
+
44
+ **The scaffold README no longer tells you to uncomment something that ships
45
+ uncommented.** 0.0.42 filled in `instance.md`'s `database:` block; the README
46
+ kept instructing the adopter to uncomment it, and named a refusal
47
+ (`instance.md declares no database: block`) they could no longer reach. The
48
+ emitted `AGENTS.md` had already been corrected and the README had not — two
49
+ documents describing one file, and only one of them updated. Vercel is three
50
+ steps ending in the Root Directory fix, `preview` sits beside `build`, and a
51
+ "When something refuses you" table maps every refusal an adopter meets to what
52
+ to do about it.
53
+
54
+ **The scaffold README is restructured around what the record is FOR.** It now
55
+ opens on the agent interface — an MCP door that answers with citations and
56
+ declines what the record does not cover — rather than on an architecture
57
+ diagram, because a reader classifies the project in the first fifteen seconds
58
+ and "governed markdown plus a site" puts it in the wrong bucket.
59
+
60
+ `ksor calibrate` moves into the main command path, between `refresh` and
61
+ `serve`. It was a parenthetical and a remedy-after-the-fact, which meant the
62
+ README's own three-question test failed at exactly the question it says
63
+ matters. Verified on the five-document starter: calibrate needs an ingested
64
+ corpus but NO running server, produces `vector_floor: 0.609`, and with it
65
+ applied the test passes as written — the paraphrased in-corpus question is
66
+ answered at 0.701 while an adjacent miss abstains at 0.550 and a far-outside
67
+ one at 0.512. The "expect answers, not refusals" note moves from postscript to
68
+ precondition, where it prevents the disappointment instead of explaining it.
69
+
70
+ Also: Neon is named for hosted Postgres rather than leaving it abstract (it is
71
+ already what this project's own docs are measured against, and pgvector is on
72
+ its free tier), the deploy section ends at the Root Directory fix, and a
73
+ "When something refuses you" table maps every refusal an adopter meets to the
74
+ one thing to do about it.
75
+
76
+ ## 0.0.44
77
+
78
+ ### Patch Changes
79
+
80
+ - 2ece135: **A lighter starter, and `refresh` finally says what it does** (issues #173, #171).
81
+
82
+ `ksor init` put five of `knowledge/`'s eleven files onto a single concept — 199
83
+ lines of companions against a 40-line document — so the first thing an adopter
84
+ opened was one document wearing four attachments. The flashcards, quiz and
85
+ slides companions are gone; `what-is-a-ksor.summary.md` stays, because it is the
86
+ only companion carrying a governance rule (exactly `type: Summary`, one key), so
87
+ the profile marker is still demonstrated. `knowledge/` goes from 11 files to 8.
88
+
89
+ What that costs, stated rather than glossed: the recall, quiz and slides tabs are
90
+ no longer shown by the starter, and an adopter meets those features in the docs
91
+ instead. Nothing about the companion mechanism changed — decision 24 is
92
+ untouched, and the migrate fixture that proves a deck migrates byte-identically
93
+ is frozen from an older tree, so it still covers the case.
94
+
95
+ And `pnpm refresh` was a name the constitution never defined, sitting beside
96
+ `pnpm ingest` and `ksor ingest` with nothing saying how the three relate. It has
97
+ a vocabulary entry now, and `docs/ingesting.md` opens with the model: `ksor
98
+ build` makes the SITE correct with no database, `ksor ingest` makes the AGENT
99
+ DOOR correct, and `pnpm refresh` runs both. The split between the scaffold's
100
+ script and the underlying verb is deliberate, and now it is written down instead
101
+ of inferred.
102
+
3
103
  ## 0.0.43
4
104
 
5
105
  ### Patch Changes
package/dist/cli.mjs CHANGED
@@ -11329,6 +11329,7 @@ function transformManifest(source, manager) {
11329
11329
  const SCRIPT_NAMES = [
11330
11330
  "dev",
11331
11331
  "build",
11332
+ "preview",
11332
11333
  "check",
11333
11334
  "serve",
11334
11335
  "provision",
package/docs/deploying.md CHANGED
@@ -113,6 +113,34 @@ What the image deliberately does NOT contain (see `.dockerignore`):
113
113
 
114
114
  ## Deploying both surfaces to Vercel
115
115
 
116
+ > **Importing from the Vercel dashboard: clear the Root Directory first.**
117
+ > Vercel auto-detects a root directory by looking for a framework, finds the
118
+ > Next app, and fills the field with **`system/site`**. The build then reads
119
+ > `system/site/vercel.json`, which does not exist, and fails with:
120
+ >
121
+ > ```
122
+ > Error: Project framework is set to "services", but no services are declared.
123
+ > ```
124
+ >
125
+ > The services ARE declared — in `vercel.json` at the repository root, which is
126
+ > the only place they can be, because one of them builds the site and the other
127
+ > builds a container from the root `Dockerfile`. The import screen even lists
128
+ > both, because that step reads the root file; the BUILD step uses the Root
129
+ > Directory override instead.
130
+ >
131
+ > **Set Root Directory to the repository root (`./`) and redeploy.** Nothing in
132
+ > the record changes. Found by an adopter on 2026-08-26, and it will happen on
133
+ > every dashboard import until Vercel's detection changes — the layout that
134
+ > triggers it, code under `system/`, is decision 8 and is not moving.
135
+ >
136
+ > Also confirm **Application Preset is `Services`**; with any other preset the
137
+ > `services` key is ignored and `/mcp` never exists. Vercel Services is in Beta.
138
+ >
139
+ > **If it still argues, deploy the site alone** — it needs no preset and no
140
+ > services: build command `pnpm -C system/site build`, output directory
141
+ > `system/site/out`. That is the stricter posture decision 29 describes, and
142
+ > the door can be deployed separately.
143
+
116
144
  The emitted `vercel.json` declares both services and routes between them:
117
145
 
118
146
  ```json
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.43",
3
+ "version": "0.0.45",
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",
@@ -12,49 +12,75 @@ 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 first six questions
16
-
17
- Ask these one at a time; follow up until each answer is concrete enough to
18
- act on:
19
-
20
- 1. **Authority** "What should this record be the _final word_ on? Finish
21
- the sentence: when someone here disagrees with this corpus, the corpus
22
- wins about ___."
23
- 2. **Boundary** — "What is explicitly _outside_ it — near-miss topics people
24
- will ask about that this record should refuse rather than guess at?"
25
- 3. **Audience** "Who reads it people, agents, both? In what situations,
26
- making what decisions?"
27
- 4. **Sources** — "Which existing materials are authoritative inputs (name
28
- the actual documents, systems, people), and which are explicitly _not_
29
- trusted?"
30
- 5. **Strictness** — "When the record doesn't cover a question, how firmly
31
- should it decline? ('Not in this corpus' is a correct answer here —
32
- confirm the owner wants that behavior and where they want it softened.)"
33
- 6. **Audiences** "Does every reader of this record see every document? If
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.
15
+ ## Ask THREE questions, one at a time
16
+
17
+ Seven questions is where this skill used to start, and it did not survive
18
+ contact: an agent running it decided five were too many, defaulted them, and
19
+ reported "answered: all seven" — including the one that decides who may
20
+ approve a document. A process the tool executing it shortcuts is too long.
21
+
22
+ So three are asked, and they are the three that cannot be defaulted:
23
+
24
+ 1. **Scope** "What should this record be the _final word_ on? Finish the
25
+ sentence: when someone here disagrees with this corpus, the corpus wins
26
+ about ___."
27
+ 2. **Boundary** — "What is just _outside_ that the near-miss topics people
28
+ will ask about here that the record should refuse rather than guess at?"
29
+ 3. **Authority** — "Who may approve a document for publication, and who may
30
+ withdraw one?"
31
+
32
+ Scope and Boundary are asked because the abstention gate is meaningless
33
+ without an edge: a record authoritative for everything has no outside, so an
34
+ agent asked something the owner never wrote about reaches for its training
35
+ instead of declining. Authority is asked because a governance act names its
36
+ actor and the tool never guesses one — the scaffold ships `human:you` in
37
+ both authority lists, and a placeholder that survives this conversation is a
38
+ person who was never there.
39
+
40
+ Follow up until each is concrete. "Our engineering docs" is not yet an
41
+ answer; "our leave, expense and conduct policies the current ones, not
42
+ historical versions" is.
43
+
44
+ ## Then STATE the defaults; do not ask them
45
+
46
+ Show these as a block, say they are defaults, and invite a correction. Do not
47
+ walk them one at a time they are near-constant, and asking makes the
48
+ interview feel like a form.
49
+
50
+ | | default |
51
+ | --------- | ------------------------------------------------- |
52
+ | read by | people and agents both |
53
+ | declines | firmly "not in this corpus" is a correct answer |
54
+ | audiences | one, `public` every reader sees every document |
55
+ | sources | none yet — the corpus is still the samples |
56
+
57
+ Each is written only if the owner does not object, and the write-back names
58
+ which were answered and which were defaulted. **Never report a default as an
59
+ answer.** Two answered and four defaulted is an honest sentence; "all seven
60
+ answered" is not, and it is what happened the first time this skill ran.
61
+
62
+ **If the owner says NOT every reader sees every document**, then and only
63
+ then: register each audience in `.ksor/governance.yaml` under `audiences:`
64
+ with a one-line `description:` of who is in it — `public` is reserved and
65
+ never registered. There is no ranking and no default: a document lists the
66
+ audiences that may read it, a reader holds a list that always includes
67
+ `public`, and the document is visible when the two lists OVERLAP. Tell them
68
+ what this does and does not do: builds are made per audience, but anyone who
69
+ can clone the repository reads everything in it — if someone must not read a
70
+ document and can clone, that document belongs in a different repository.
71
+
72
+ ## What the answers become
73
+
74
+ Scope and Boundary become the BODY of `instance.md`, which `ksor serve` wires
75
+ into the MCP server's instructions — so it is read by every agent that
76
+ connects, and vague prose there is vague instructions everywhere.
77
+
78
+ Authority becomes `approval_authorities` and `takedown_authorities` in
79
+ `.ksor/governance.yaml`. Names, not roles-in-the-abstract: the checker refuses
80
+ an approval or a takedown by anyone the policy does not name. An actor is
81
+ `human:<handle>`, `process:<name>` or `<producer>/<version>`; handles are
82
+ published with the record, so use the handle the owner would put in a commit,
83
+ never an email address.
58
84
 
59
85
  ## Then write
60
86
 
@@ -12,49 +12,75 @@ 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 first six questions
16
-
17
- Ask these one at a time; follow up until each answer is concrete enough to
18
- act on:
19
-
20
- 1. **Authority** "What should this record be the _final word_ on? Finish
21
- the sentence: when someone here disagrees with this corpus, the corpus
22
- wins about ___."
23
- 2. **Boundary** — "What is explicitly _outside_ it — near-miss topics people
24
- will ask about that this record should refuse rather than guess at?"
25
- 3. **Audience** "Who reads it people, agents, both? In what situations,
26
- making what decisions?"
27
- 4. **Sources** — "Which existing materials are authoritative inputs (name
28
- the actual documents, systems, people), and which are explicitly _not_
29
- trusted?"
30
- 5. **Strictness** — "When the record doesn't cover a question, how firmly
31
- should it decline? ('Not in this corpus' is a correct answer here —
32
- confirm the owner wants that behavior and where they want it softened.)"
33
- 6. **Audiences** "Does every reader of this record see every document? If
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.
15
+ ## Ask THREE questions, one at a time
16
+
17
+ Seven questions is where this skill used to start, and it did not survive
18
+ contact: an agent running it decided five were too many, defaulted them, and
19
+ reported "answered: all seven" — including the one that decides who may
20
+ approve a document. A process the tool executing it shortcuts is too long.
21
+
22
+ So three are asked, and they are the three that cannot be defaulted:
23
+
24
+ 1. **Scope** "What should this record be the _final word_ on? Finish the
25
+ sentence: when someone here disagrees with this corpus, the corpus wins
26
+ about ___."
27
+ 2. **Boundary** — "What is just _outside_ that the near-miss topics people
28
+ will ask about here that the record should refuse rather than guess at?"
29
+ 3. **Authority** — "Who may approve a document for publication, and who may
30
+ withdraw one?"
31
+
32
+ Scope and Boundary are asked because the abstention gate is meaningless
33
+ without an edge: a record authoritative for everything has no outside, so an
34
+ agent asked something the owner never wrote about reaches for its training
35
+ instead of declining. Authority is asked because a governance act names its
36
+ actor and the tool never guesses one — the scaffold ships `human:you` in
37
+ both authority lists, and a placeholder that survives this conversation is a
38
+ person who was never there.
39
+
40
+ Follow up until each is concrete. "Our engineering docs" is not yet an
41
+ answer; "our leave, expense and conduct policies the current ones, not
42
+ historical versions" is.
43
+
44
+ ## Then STATE the defaults; do not ask them
45
+
46
+ Show these as a block, say they are defaults, and invite a correction. Do not
47
+ walk them one at a time they are near-constant, and asking makes the
48
+ interview feel like a form.
49
+
50
+ | | default |
51
+ | --------- | ------------------------------------------------- |
52
+ | read by | people and agents both |
53
+ | declines | firmly "not in this corpus" is a correct answer |
54
+ | audiences | one, `public` every reader sees every document |
55
+ | sources | none yet — the corpus is still the samples |
56
+
57
+ Each is written only if the owner does not object, and the write-back names
58
+ which were answered and which were defaulted. **Never report a default as an
59
+ answer.** Two answered and four defaulted is an honest sentence; "all seven
60
+ answered" is not, and it is what happened the first time this skill ran.
61
+
62
+ **If the owner says NOT every reader sees every document**, then and only
63
+ then: register each audience in `.ksor/governance.yaml` under `audiences:`
64
+ with a one-line `description:` of who is in it — `public` is reserved and
65
+ never registered. There is no ranking and no default: a document lists the
66
+ audiences that may read it, a reader holds a list that always includes
67
+ `public`, and the document is visible when the two lists OVERLAP. Tell them
68
+ what this does and does not do: builds are made per audience, but anyone who
69
+ can clone the repository reads everything in it — if someone must not read a
70
+ document and can clone, that document belongs in a different repository.
71
+
72
+ ## What the answers become
73
+
74
+ Scope and Boundary become the BODY of `instance.md`, which `ksor serve` wires
75
+ into the MCP server's instructions — so it is read by every agent that
76
+ connects, and vague prose there is vague instructions everywhere.
77
+
78
+ Authority becomes `approval_authorities` and `takedown_authorities` in
79
+ `.ksor/governance.yaml`. Names, not roles-in-the-abstract: the checker refuses
80
+ an approval or a takedown by anyone the policy does not name. An actor is
81
+ `human:<handle>`, `process:<name>` or `<producer>/<version>`; handles are
82
+ published with the record, so use the handle the owner would put in a commit,
83
+ never an email address.
58
84
 
59
85
  ## Then write
60
86