@panaversity/ksor 0.0.13 → 0.0.14

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.14
4
+
5
+ ### Patch Changes
6
+
7
+ - a0d98b0: Cut dead weight, and repair two guards that had quietly stopped guarding
8
+
9
+ A sweep across every package, with each candidate handed to a second reviewer
10
+ whose job was to prove it still alive. Net −154 lines. Nothing an adopter can
11
+ observe changes; two things that were supposed to fail no longer stay silent.
12
+
13
+ **The two repairs.** A guard asserting that no scaffolded document describes
14
+ serving as publishing — a claim this repo has had to correct four times — ran
15
+ `readFileSync` inside a `try` whose `catch` returned quietly, and one of its five
16
+ filenames was `.env.example` while the scaffold emits `env.example`. So the row
17
+ covering the file that actually carries the serving variables had never executed.
18
+ The name is fixed and a missing file now fails instead of passing. Separately,
19
+ two doc-blocks described a stdio transport in the present tense; there is no
20
+ stdio door in the product, and the suite claiming to drive one drives HTTP.
21
+
22
+ **The removals.** A 134-line live-walk script pinned to `@panaversity/ksor@0.0.4`
23
+ that nothing referenced. `AuthConfig.jwksUrl`, computed and stored but never read
24
+ — its live twin is `explicitJwksUrl`; the boot-time validation of
25
+ `KSOR_JWKS_URL` stays exactly where it was. An `allowedAudiences.length > 0 &&`
26
+ operand that no path can reach as false, and whose false side would have skipped
27
+ the audience allowlist entirely. A `PoolTimeoutError` message parameter no caller
28
+ passed, which was also the one input where two retry classifiers disagreed —
29
+ removing it closes that. Two `instanceof X || instanceof Error` disjuncts where
30
+ `X extends Error`, so the first could never decide anything. One unused icon
31
+ export in the workbench shell.
32
+
33
+ **Left alone deliberately.** `SearchScope.kinds` is genuinely dead, but removing
34
+ it renumbers positional parameters across three SQL statements, two of which
35
+ derive a shared CTE by string substitution, and the test that would catch a wrong
36
+ renumber is gated on a database. That is a change to make on its own, with the
37
+ gate watching — not alongside a release.
38
+
39
+ - ce1595b: Ingest names the real reason it could not record a commit
40
+
41
+ Every first ingest of a freshly scaffolded project printed "knowledge/ is not in
42
+ a git repository". That is false: `ksor init` runs `git init`, so the repository
43
+ exists — it simply has no commit yet, and `rev-parse HEAD` fails with "unknown
44
+ revision" rather than because nothing is there. The reader was sent to `git
45
+ init`, which they had already run, in the one message that decides whether an
46
+ answer can be traced back to a reviewed commit.
47
+
48
+ Three different states were collapsing into that one sentence, and each has a
49
+ different next command:
50
+
51
+ ```
52
+ knowledge/ is in a git repository with no commits yet …
53
+ fix: commit the record (git add knowledge && git commit) and re-run
54
+
55
+ knowledge/ is not in a git repository …
56
+ fix: git init, commit the record, and re-run
57
+
58
+ git is not installed …
59
+ fix: install git, or pass --source-commit <sha> if the record is versioned elsewhere
60
+ ```
61
+
62
+ Verified on a real scaffold: the fresh case prints the first, and committing the
63
+ record turns the next ingest's `source:` line into an actual SHA.
64
+
65
+ - 474dedc: Internal: the env-contract drift test scans only the checkout's source
66
+
67
+ No adopter-visible behaviour changes. The test that guarantees every
68
+ adopter-settable environment variable is named in the scaffold's `env.example`
69
+ walked `packages/` with a `statSync` per entry, and descended into the fake npm
70
+ install another suite roots inside `packages/ksor`. That cost two ways: the
71
+ copied template sources were scanned twice, and an entry deleted between the
72
+ `readdir` and the `statSync` crashed the whole run — which is what took CI red
73
+ on run 32526491721, on an `llms.txt` being cleaned up concurrently.
74
+
75
+ The walk now takes each entry's type from the readdir snapshot itself, so a
76
+ vanishing entry cannot crash it, and it skips transient install trees, so its
77
+ input no longer depends on whether another suite is mid-run. The `REPO_ONLY`
78
+ exemption list was deleted as dead: it named seven variables that no scanned
79
+ file can contain, because the walk excludes test files in the first place. The
80
+ honesty check that is supposed to catch stale exemptions now covers every
81
+ exemption list, which is what its name always claimed.
82
+
3
83
  ## 0.0.13
4
84
 
5
85
  ### Patch Changes
package/dist/cli.mjs CHANGED
@@ -16,7 +16,7 @@ import { bodyLimit } from "hono/body-limit";
16
16
  import { execFileSync, spawnSync } from "node:child_process";
17
17
  import { parseArgs } from "node:util";
18
18
  import { readFile, readdir, stat } from "node:fs/promises";
19
- //#region ../content-gateway/dist/main-B1G1VdMp.mjs
19
+ //#region ../content-gateway/dist/main-VL9lXhmT.mjs
20
20
  /**
21
21
  * A connection could not be ESTABLISHED in time — retryable.
22
22
  *
@@ -42,8 +42,8 @@ var ConnectTimeoutError$1 = class extends Error {
42
42
  * a thundering herd aimed at the component already drowning.
43
43
  */
44
44
  var PoolTimeoutError$1 = class extends Error {
45
- constructor(detail = "the configured checkout bound") {
46
- super(`pool checkout timed out (${detail}) — the pool is saturated; shedding this request is the recovery path, retrying it is not`);
45
+ constructor() {
46
+ super("pool checkout timed out (the configured checkout bound) — the pool is saturated; shedding this request is the recovery path, retrying it is not");
47
47
  this.name = "PoolTimeoutError";
48
48
  }
49
49
  };
@@ -3079,7 +3079,7 @@ function buildServer(ctx, version) {
3079
3079
  structuredContent: result
3080
3080
  };
3081
3081
  } catch (error) {
3082
- if (error instanceof EmptyQueryError || error instanceof Error) return {
3082
+ if (error instanceof Error) return {
3083
3083
  content: [{
3084
3084
  type: "text",
3085
3085
  text: `Error: ${error.message}`
@@ -3188,7 +3188,7 @@ function toolError(error) {
3188
3188
  return {
3189
3189
  content: [{
3190
3190
  type: "text",
3191
- text: `Error: ${error instanceof UnknownSlug || error instanceof Error ? error.message : String(error)}`
3191
+ text: `Error: ${error instanceof Error ? error.message : String(error)}`
3192
3192
  }],
3193
3193
  isError: true
3194
3194
  };
@@ -3366,12 +3366,10 @@ function configFromEnv(env) {
3366
3366
  const allowedAudiences = (env.KSOR_JWT_ALLOWED_AUDIENCES ?? "").split(",").map((a) => a.trim()).filter((a) => a !== "");
3367
3367
  const issuer = (env.KSOR_SSO_ISSUER ?? "").trim() || null;
3368
3368
  const explicit = (env.KSOR_JWKS_URL ?? "").trim();
3369
- const jwksUrl = explicit || `${ssoUrl}/api/auth/jwks`;
3370
- assertHttpUrl("KSOR_JWKS_URL", jwksUrl, true);
3369
+ assertHttpUrl("KSOR_JWKS_URL", explicit || `${ssoUrl}/api/auth/jwks`, true);
3371
3370
  return {
3372
3371
  ssoUrl,
3373
3372
  resourceUrl,
3374
- jwksUrl,
3375
3373
  explicitJwksUrl: explicit === "" ? null : explicit,
3376
3374
  allowedAudiences,
3377
3375
  issuer,
@@ -3492,7 +3490,7 @@ function createVerify(config, deps, jwksOf) {
3492
3490
  cause: err
3493
3491
  });
3494
3492
  }
3495
- if (config.allowedAudiences.length > 0 && !audOk(claims.aud, config.allowedAudiences)) {
3493
+ if (!audOk(claims.aud, config.allowedAudiences)) {
3496
3494
  reject(key);
3497
3495
  throw new TokenVerifyError(`token aud ${JSON.stringify(claims.aud ?? null)} not in allowlist ${JSON.stringify(config.allowedAudiences)}`, { transient: false });
3498
3496
  }
@@ -3648,8 +3646,8 @@ const UNDESCRIBED_RECORD = "instance.md is still the scaffold template — agent
3648
3646
  * Composition (oracle main.py's boot order, adapted): instance → DSN via
3649
3647
  * the declared env NAME → provider → pool → space guard → service context.
3650
3648
  * Auth is built by the door that needs it (http.ts) — BEFORE the pool
3651
- * serves anything; stdio is the local loopback-equivalent door and runs
3652
- * with auth off by construction.
3649
+ * serves anything; a loopback bind is the local-equivalent door and is the
3650
+ * only posture that may run with auth explicitly disabled.
3653
3651
  */
3654
3652
  async function compose(instancePath, version) {
3655
3653
  let instanceText;
@@ -4149,8 +4147,8 @@ var ConnectTimeoutError = class extends Error {
4149
4147
  * a thundering herd aimed at the component already drowning.
4150
4148
  */
4151
4149
  var PoolTimeoutError = class extends Error {
4152
- constructor(detail = "the configured checkout bound") {
4153
- super(`pool checkout timed out (${detail}) — the pool is saturated; shedding this request is the recovery path, retrying it is not`);
4150
+ constructor() {
4151
+ super("pool checkout timed out (the configured checkout bound) — the pool is saturated; shedding this request is the recovery path, retrying it is not");
4154
4152
  this.name = "PoolTimeoutError";
4155
4153
  }
4156
4154
  };
@@ -4454,7 +4452,7 @@ async function withPgRetry(op, options = {}) {
4454
4452
  throw lastError;
4455
4453
  }
4456
4454
  //#endregion
4457
- //#region ../content/dist/commands-LOfF_iLT.mjs
4455
+ //#region ../content/dist/commands-BRK58wVc.mjs
4458
4456
  /**
4459
4457
  * EVAL-LOCKED constants, quarried verbatim from the oracle
4460
4458
  * (sor-agentfactory @ b554f91, config.py) — changing any of these is a
@@ -8692,19 +8690,46 @@ function composeProvider(instance) {
8692
8690
  return fail$1(REFUSED, `instance embedding.provider: ${exc instanceof Error ? exc.message : String(exc)}`);
8693
8691
  }
8694
8692
  }
8695
- /**
8696
- * The commit the corpus was ingested from, resolved from git when the tree is
8697
- * in a repository.
8698
- *
8699
- * `--source-commit` has always existed and the golden path never passed it, so
8700
- * EVERY generation an adopter produced recorded the literal string
8701
- * "unspecified" — product principle 6 requires a build to record the exact
8702
- * corpus that produced it, and a placeholder records nothing (review
8703
- * 2026-08-20). Resolved here rather than in the scaffold script so it is right
8704
- * however the verb is invoked. A tree that is not a repository, or a git that
8705
- * is not installed, still records the honest sentinel rather than failing an
8706
- * ingest over provenance metadata.
8707
- */
8693
+ function provenanceGap(knowledgeDir) {
8694
+ if (knowledgeDir === void 0) return "not-asked";
8695
+ const run = (args) => {
8696
+ try {
8697
+ return {
8698
+ ok: true,
8699
+ out: execFileSync("git", [
8700
+ "-C",
8701
+ knowledgeDir,
8702
+ ...args
8703
+ ], {
8704
+ encoding: "utf8",
8705
+ stdio: [
8706
+ "ignore",
8707
+ "pipe",
8708
+ "ignore"
8709
+ ]
8710
+ }).trim()
8711
+ };
8712
+ } catch {
8713
+ return {
8714
+ ok: false,
8715
+ out: ""
8716
+ };
8717
+ }
8718
+ };
8719
+ if (!run(["--version"]).ok && !run(["rev-parse", "--git-dir"]).ok) return "no-git";
8720
+ if (!run(["rev-parse", "--git-dir"]).ok) return "no-repo";
8721
+ return "no-commit";
8722
+ }
8723
+ /** The remedy for each, because the reader's next command differs. */
8724
+ function provenanceNotice(gap) {
8725
+ const why = "so this generation cannot be traced back to a reviewed commit";
8726
+ switch (gap) {
8727
+ case "no-commit": return `source: unspecified — knowledge/ is in a git repository with no commits yet, ${why}.\n fix: commit the record (git add knowledge && git commit) and re-run`;
8728
+ case "no-repo": return `source: unspecified — knowledge/ is not in a git repository, ${why}.\n fix: git init, commit the record, and re-run`;
8729
+ case "no-git": return `source: unspecified — git is not installed, ${why}.\n fix: install git, or pass --source-commit <sha> if the record is versioned elsewhere`;
8730
+ case "not-asked": return `source: unspecified — no knowledge directory was given, ${why}.`;
8731
+ }
8732
+ }
8708
8733
  function detectSourceCommit(knowledgeDir) {
8709
8734
  if (knowledgeDir === void 0) return "unspecified";
8710
8735
  try {
@@ -8890,7 +8915,7 @@ async function ingestCommand(args) {
8890
8915
  process.stdout.write(`ingest: unchanged — generation ${report.generation} already serves this corpus\n`);
8891
8916
  return 0;
8892
8917
  }
8893
- process.stdout.write(sourceCommit === "unspecified" ? "source: unspecified — knowledge/ is not in a git repository, so this generation cannot be traced back to a reviewed commit\n" : `source: ${sourceCommit}\n`);
8918
+ process.stdout.write(sourceCommit === "unspecified" ? provenanceNotice(provenanceGap(values.knowledge)) + "\n" : `source: ${sourceCommit}\n`);
8894
8919
  process.stdout.write(`ingest: generation ${report.generation} — ${report.nodes} nodes, ${report.chunks} chunks; embedded ${report.embedded}, carried ${report.carried}, failed ${report.failed}\n`);
8895
8920
  if (report.unsearchable > 0) {
8896
8921
  const pct = Math.round(report.unsearchable / Math.max(report.chunks, 1) * 100);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@panaversity/ksor",
3
- "version": "0.0.13",
3
+ "version": "0.0.14",
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",