@panaversity/ksor 0.0.9 → 0.0.10

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,160 @@
1
1
  # @panaversity/ksor
2
2
 
3
+ ## 0.0.10
4
+
5
+ ### Patch Changes
6
+
7
+ - c07a5db: `ksor calibrate` states what its measurement is worth, not just its result
8
+
9
+ The default door synthesizes in-corpus questions by asking a model to write one
10
+ FROM each sampled passage, then scores those questions against the corpus that
11
+ contains the passage. They share vocabulary a reader's question will not, so the
12
+ in-corpus distribution sits higher than real traffic will and the separation the
13
+ run reports is an UPPER BOUND. The `--queries-file` door carried a caveat about
14
+ its own distribution; the default door — the biased one — carried none.
15
+
16
+ Found live: a real record calibrated this way reported min in-corpus 0.682
17
+ against max out-of-corpus 0.580 and recommended `vector_floor: 0.631`. Questions
18
+ the record demonstrably answers then scored 0.530 to 0.606 — every one below the
19
+ recommended floor. Pasting it would have made the record abstain on questions
20
+ whose answers it had just cited, which is the failure abstention exists to
21
+ prevent, arrived at from the other side.
22
+
23
+ The block now carries that caveat, and prints the one number it always left the
24
+ reader to work out: the separation margin, with the probe counts behind it. A
25
+ margin of 0.054 over six in-corpus and four out-of-corpus probes is a different
26
+ claim from the same margin over sixty, and both figures were already on the
27
+ report without ever reaching the page. The mathematics and the recommended value
28
+ are unchanged.
29
+
30
+ It also names the generation it measured. With nothing pinned — the ordinary
31
+ case, calibrating what is being served — the report carried no generation at
32
+ all, so the provenance comment beside a pasted floor read `on generation unknown
33
+ (no generation pinned)`. A floor is a threshold inside ONE generation's embedding
34
+ space, and the query that counts the chunks had already resolved which one.
35
+
36
+ `runCalibration` had no test of any kind; it has one now, against real Postgres.
37
+
38
+ - d00f3a2: The signing keys are discovered, not guessed — any standards-compliant SSO now works.
39
+
40
+ `KSOR_SSO_URL` is documented as "the AS base", and the verifier appended one
41
+ vendor's layout to it (`/api/auth/jwks`, Better Auth's). Auth0, Okta, Entra,
42
+ Keycloak, Cognito and Google all publish elsewhere, so every one of them failed
43
+ the key fetch — which is classified transient, so the door booted clean and
44
+ returned 503 to every request with nothing naming the cause. The only posture an
45
+ operator could actually reach was `KSOR_ALLOW_PUBLIC_UNAUTHENTICATED=1`: the one
46
+ key we handed people was the one that props the door open.
47
+
48
+ `jwks_uri` is now read from the SSO's own metadata document — RFC 8414 first,
49
+ then OpenID Discovery — with `KSOR_JWKS_URL` kept as an explicit override, and
50
+ the vendor path kept as a last resort that reports itself as a guess. Where the
51
+ keys came from is stated on the boot line.
52
+
53
+ Verified against three real providers: Google (RFC 8414, cross-origin
54
+ `jwks_uri`), GitHub Actions OIDC, and Entra — whose issuer carries a path,
55
+ the case a naive `${sso}/.well-known/…` gets wrong.
56
+
57
+ Discovery never refuses to boot: an unreachable AS falls back and says so.
58
+
59
+ - 9062088: A loopback authorization server's keys are reachable again.
60
+
61
+ JWKS discovery refused a cleartext `jwks_uri`, which is right for a network AS
62
+ and wrong for a local one: a dev authorization server on loopback advertises
63
+ `http://127.0.0.1:…/jwks`, the resolver refused it, the vendor guess was used
64
+ instead, and every request returned 503. `assertHttpUrl` already exempts
65
+ loopback for the SSO base for exactly this reason; the resolver now does too.
66
+ Cleartext to any non-loopback host is still refused.
67
+
68
+ Found by writing the first test that boots the gateway in bearer mode.
69
+
70
+ - 995ec48: A governance act names its actor; the tool no longer guesses one.
71
+
72
+ `ksor takedown --actor` fell back to `$USER` / `$USERNAME` / `"operator"`, so a
73
+ ledger row read `runner` under CI and `root` in a container — a self-asserted
74
+ string wearing a schema, indistinguishable from a person who was never there.
75
+ `retrieval_log.actor` is `NOT NULL` with the comment "NO default: unset errors
76
+ loudly", and the fallback is precisely what stopped it erroring.
77
+
78
+ Denying or revoking now REFUSES without `--actor`, before the DSN is resolved:
79
+ a missing actor is an argument error (exit 1), not an environment one. The
80
+ read-only modes — `--list`, `--ledger`, `--export` — write no ledger row and
81
+ need nothing.
82
+
83
+ - 41b0c38: Reading order is one rule again: the MCP door now reads `order:`
84
+
85
+ `order:` is the only ordering key a record may declare — it is in the governed
86
+ frontmatter set the format checker closes, and the checker's own remedy for a
87
+ stray `meta.json` says so. The MCP door never read it. The tree adapter was
88
+ converted from the predecessor, whose ordering keys were Docusaurus's
89
+ `position:` / `sidebar_position:`, neither of which a compliant record may
90
+ declare — so `outline` reported the record's structure in filename order and
91
+ called it the reading order, while the website honoured `order:`. On a
92
+ curriculum, where reading order IS the content, an agent asking "what do I read
93
+ first" got a different answer from the two surfaces.
94
+
95
+ Four smaller disagreements went with it, each now a row in a shared decision
96
+ table: unordered documents sorted at 10 000 rather than after everything;
97
+ fractional orders were truncated; ties compared `example.md` against
98
+ `example-two.md`, where `.` sorts after `-`, reversing ordinary pairs; and one
99
+ side folded case while the other did not.
100
+
101
+ The rule now lives in one file, copied into the scaffold and asserted
102
+ byte-identical, with `ORDER_CASES` run against BOTH surfaces — so a surface that
103
+ drifts fails on the row it broke.
104
+
105
+ - 41b0c38: `ksor serve` reports its own posture instead of forwarding other people's warnings
106
+
107
+ Booting printed four alarming paragraphs at an operator who had done nothing
108
+ wrong: the driver's multi-line `SECURITY WARNING` about `sslmode` aliases, ksor's
109
+ own three-line restatement of the same thing, and the MCP SDK's note about a
110
+ `responseMode` ksor chose deliberately.
111
+
112
+ The driver's warning is correct and its remedy is one word, so ksor now applies
113
+ it: a remote `sslmode=require|prefer|verify-ca` is rewritten to `verify-full`
114
+ before the connection is made. The connection is unchanged today — pg 8 was
115
+ already resolving all three to full verification, which is the entire content of
116
+ its warning — and it can no longer be silently downgraded by a driver upgrade.
117
+ The SDK's note describes a recorded decision, not a defect, and is suppressed by
118
+ exact message so that anything else it says still reaches the operator.
119
+
120
+ What is left is the record's posture, aligned and in ksor's own voice, with the
121
+ two lines that decide whether to trust what happens next saying what they mean:
122
+ auth `DISABLED` now names the bind it is survivable on, and an absent abstention
123
+ floor says out-of-corpus questions will be answered rather than refused.
124
+
125
+ - bea7d80: `read` names every section it will accept, not just the top-level ones
126
+
127
+ `read` resolves a `heading` three ways: a full heading path, any prefix of one,
128
+ and a section's last segment when that segment is unique in the document. The
129
+ error for a section it could not find listed only the TOP-LEVEL segments — a
130
+ strict subset of its own vocabulary — so it reported real, reachable sections as
131
+ absent. Found live: a nested section was refused by name and served on the next
132
+ call under the same name.
133
+
134
+ The error now lists the full heading paths (the form that always resolves and
135
+ never collides), states the unique-last-segment shorthand rather than doubling
136
+ the list to enumerate it, and counts the tail past twenty instead of printing an
137
+ unbounded list. The `heading` input and the `sections` output now describe the
138
+ same vocabulary in the tool schema, where an agent reads it before making the
139
+ call rather than after failing one.
140
+
141
+ - 4631268: Correct every remaining document that said `pnpm serve` publishes.
142
+
143
+ `serve` was `pnpm schema && pnpm grant && pnpm ingest && ksor serve` and is now
144
+ `ksor serve` alone. Three adopter-facing places still described the old chain:
145
+ the scaffolded `instance.md`'s own comment ("copy .env.example to .env, then run
146
+ `pnpm serve`"), the scaffold README's file table ("the agent surface: schema →
147
+ grant → ingest → serve"), and AGENTS.md's runbook ("`pnpm serve` is the only
148
+ command this rung needs"). Following any of them serves an empty record.
149
+
150
+ All three now say the same thing the CLI does: `pnpm provision` once,
151
+ `pnpm refresh` to publish, `pnpm serve` to serve — and why publishing is
152
+ separate, since a restart or an autoscaling event must not republish a record.
153
+
154
+ A test now asserts the CLAIM rather than the command. The existing guard could
155
+ not catch this: it checks that a named command exists, and `pnpm serve` does
156
+ exist — what was wrong was the sentence attached to it.
157
+
3
158
  ## 0.0.9
4
159
 
5
160
  ### Patch Changes