@panaversity/ksor 0.0.58 → 0.0.59

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.
@@ -12672,6 +12672,139 @@ function nearMissOf(baseName) {
12672
12672
  return null;
12673
12673
  }
12674
12674
  /**
12675
+ * The takedown ledger's OTHER baseline: every entry any COMMITTED version of
12676
+ * `.ksor/takedowns.yaml` has ever carried.
12677
+ *
12678
+ * The committed lock is a baseline too, and a good one — it holds each entry's
12679
+ * digest, so an entry retargeted in place is caught. What it cannot do is prove
12680
+ * that an entry was never deleted, because the lock travels in the SAME change
12681
+ * as the ledger: delete the row, recompute `ledger_sha256`, empty
12682
+ * `ledger_entries`, and the two agree with each other about a denial that is
12683
+ * gone. Only history remembers.
12684
+ *
12685
+ * The baseline may be INCOMPLETE only if it SAYS so: every version history
12686
+ * holds is read, or `entries` comes back null and the caller reports that it
12687
+ * could not verify. A version silently skipped would contribute neither
12688
+ * digests nor ids while the answer still read "verified"
12689
+ * (`git-ledger.integration.test.ts`).
12690
+ *
12691
+ * This lives in the record module because THREE surfaces need the same answer —
12692
+ * `ksor build`, the emitted checker, and the site's stage (decision 19: a
12693
+ * surface that refuses must refuse on both surfaces). Plain `git log` / `git
12694
+ * show`, so nothing here needs installing.
12695
+ */
12696
+ const LEDGER = ".ksor/takedowns.yaml";
12697
+ /**
12698
+ * `spawnSync` defaults to a 1 MB stdout buffer, and past it the child is KILLED
12699
+ * — `status` comes back null, so the query reads as a failure. A ledger with a
12700
+ * few thousand entries, or one entry carrying a long reason, clears 1 MB
12701
+ * easily, and the version was then dropped from the baseline while the caller
12702
+ * was still told history had been verified. The ceiling stays finite on
12703
+ * purpose: past it this returns null, which is a state the caller SAYS.
12704
+ */
12705
+ const MAX_BUFFER$1 = 67108864;
12706
+ /** One git query, read-only. Null on any non-zero exit, including no git at all. */
12707
+ function git(root, args) {
12708
+ const r = spawnSync("git", [...args], {
12709
+ cwd: root,
12710
+ encoding: "utf8",
12711
+ maxBuffer: MAX_BUFFER$1
12712
+ });
12713
+ return r.status === 0 ? r.stdout : null;
12714
+ }
12715
+ function historicLedger(root) {
12716
+ const inside = git(root, ["rev-parse", "--is-inside-work-tree"]);
12717
+ if (inside === null || inside.trim() !== "true") return {
12718
+ repository: false,
12719
+ shallow: false,
12720
+ entries: null,
12721
+ unreadable: null
12722
+ };
12723
+ const shallow = (git(root, ["rev-parse", "--is-shallow-repository"]) ?? "").trim() === "true";
12724
+ const born = git(root, [
12725
+ "rev-parse",
12726
+ "--verify",
12727
+ "--quiet",
12728
+ "HEAD"
12729
+ ]) !== null;
12730
+ const entries = shallow ? null : born ? historicEntries(root) : [];
12731
+ return {
12732
+ repository: true,
12733
+ shallow,
12734
+ entries,
12735
+ unreadable: entries !== null ? null : shallow ? "shallow" : "unreadable"
12736
+ };
12737
+ }
12738
+ /**
12739
+ * Every id history has ever recorded, each with the text it carried the FIRST
12740
+ * time it was written. A version that parses contributes each entry's digest,
12741
+ * so an entry EDITED in place is caught, not only one deleted; a version that
12742
+ * no longer parses still contributes its ids, read permissively — the point
12743
+ * there is that an id once written never disappears.
12744
+ *
12745
+ * FIRST, not every: keying this by `id\tdigest` kept one baseline entry per
12746
+ * version an id ever had, so a tamper that was COMMITTED and then UNDONE left
12747
+ * two digests for one id, the restored entry matched only one of them, and
12748
+ * `ksor-ledger-amended` fired for good. The record became permanently
12749
+ * unbuildable — by a tamper that had already been put right — and the only
12750
+ * escape was rewriting git history, which is not a remedy a refusal may
12751
+ * demand (found in review, 2026-08-25).
12752
+ *
12753
+ * Taking the OLDEST is what makes the guarantee both enforceable and
12754
+ * escapable. It still refuses a committed tamper (the baseline is what the
12755
+ * entry said when it was written, so committing the edit does not launder
12756
+ * it), and the remedy it names — put the entry back — now actually clears
12757
+ * it. Taking the NEWEST would have done the opposite on both counts.
12758
+ */
12759
+ function historicEntries(root) {
12760
+ const atRoot = `${(git(root, ["rev-parse", "--show-prefix"]) ?? "").trim()}${LEDGER}`;
12761
+ const commits = git(root, [
12762
+ "log",
12763
+ "--full-history",
12764
+ "--topo-order",
12765
+ "--format=%H",
12766
+ "--",
12767
+ LEDGER
12768
+ ]);
12769
+ if (commits === null) return null;
12770
+ const seen = /* @__PURE__ */ new Map();
12771
+ for (const sha of commits.split("\n").filter((s) => s !== "")) {
12772
+ const text = git(root, ["show", `${sha}:${atRoot}`]);
12773
+ if (text === null) {
12774
+ const listed = git(root, [
12775
+ "ls-tree",
12776
+ "--full-tree",
12777
+ "--name-only",
12778
+ sha,
12779
+ "--",
12780
+ atRoot
12781
+ ]);
12782
+ if (listed !== null && listed.trim() === "") continue;
12783
+ return null;
12784
+ }
12785
+ const where = sha.slice(0, 7);
12786
+ const parsed = parseLedger(text, LEDGER);
12787
+ if (parsed.ok) {
12788
+ for (const entry of parsed.ledger.entries) seen.set(entry.id, {
12789
+ id: entry.id,
12790
+ digest: entryDigest(entry),
12791
+ entry,
12792
+ where
12793
+ });
12794
+ continue;
12795
+ }
12796
+ for (const m of text.matchAll(/^\s*(?:-\s+)?id:\s*["']?([^\s"']+)/gm)) {
12797
+ const id = m[1] ?? "";
12798
+ if (!seen.has(id)) seen.set(id, {
12799
+ id,
12800
+ digest: null,
12801
+ where
12802
+ });
12803
+ }
12804
+ }
12805
+ return [...seen.values()].sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
12806
+ }
12807
+ /**
12675
12808
  * The widening rule: a link, a `ksor.superseded_by` pointer or a companion
12676
12809
  * body may reach a target whose audience contains `public` or contains every
12677
12810
  * identifier in the source's — then every reader of the source can read the
@@ -13537,6 +13670,11 @@ function checkAgainstPolicy(concept, policy, refusals) {
13537
13670
  }
13538
13671
  const hex64 = string().regex(/^[0-9a-f]{64}$/, "a sha256 hex digest");
13539
13672
  const viewerList = array(string().min(1));
13673
+ const bundleEntry = object({
13674
+ viewer: string().min(1),
13675
+ sha256: hex64,
13676
+ files: number().int().nonnegative()
13677
+ }).strict();
13540
13678
  const lockSchema = object({
13541
13679
  format: literal(1),
13542
13680
  build_id: string().regex(/^sha256:[0-9a-f]{64}$/),
@@ -13584,7 +13722,8 @@ const lockSchema = object({
13584
13722
  indexes: array(object({
13585
13723
  path: string().min(1),
13586
13724
  sha256: hex64
13587
- }).strict())
13725
+ }).strict()),
13726
+ bundles: array(bundleEntry)
13588
13727
  }).strict();
13589
13728
  function parseLock(text) {
13590
13729
  let value;
@@ -13609,139 +13748,6 @@ function parseLock(text) {
13609
13748
  lock: parsed.data
13610
13749
  };
13611
13750
  }
13612
- /**
13613
- * The takedown ledger's OTHER baseline: every entry any COMMITTED version of
13614
- * `.ksor/takedowns.yaml` has ever carried.
13615
- *
13616
- * The committed lock is a baseline too, and a good one — it holds each entry's
13617
- * digest, so an entry retargeted in place is caught. What it cannot do is prove
13618
- * that an entry was never deleted, because the lock travels in the SAME change
13619
- * as the ledger: delete the row, recompute `ledger_sha256`, empty
13620
- * `ledger_entries`, and the two agree with each other about a denial that is
13621
- * gone. Only history remembers.
13622
- *
13623
- * The baseline may be INCOMPLETE only if it SAYS so: every version history
13624
- * holds is read, or `entries` comes back null and the caller reports that it
13625
- * could not verify. A version silently skipped would contribute neither
13626
- * digests nor ids while the answer still read "verified"
13627
- * (`git-ledger.integration.test.ts`).
13628
- *
13629
- * This lives in the record module because THREE surfaces need the same answer —
13630
- * `ksor build`, the emitted checker, and the site's stage (decision 19: a
13631
- * surface that refuses must refuse on both surfaces). Plain `git log` / `git
13632
- * show`, so nothing here needs installing.
13633
- */
13634
- const LEDGER = ".ksor/takedowns.yaml";
13635
- /**
13636
- * `spawnSync` defaults to a 1 MB stdout buffer, and past it the child is KILLED
13637
- * — `status` comes back null, so the query reads as a failure. A ledger with a
13638
- * few thousand entries, or one entry carrying a long reason, clears 1 MB
13639
- * easily, and the version was then dropped from the baseline while the caller
13640
- * was still told history had been verified. The ceiling stays finite on
13641
- * purpose: past it this returns null, which is a state the caller SAYS.
13642
- */
13643
- const MAX_BUFFER = 67108864;
13644
- /** One git query, read-only. Null on any non-zero exit, including no git at all. */
13645
- function git(root, args) {
13646
- const r = spawnSync("git", [...args], {
13647
- cwd: root,
13648
- encoding: "utf8",
13649
- maxBuffer: MAX_BUFFER
13650
- });
13651
- return r.status === 0 ? r.stdout : null;
13652
- }
13653
- function historicLedger(root) {
13654
- const inside = git(root, ["rev-parse", "--is-inside-work-tree"]);
13655
- if (inside === null || inside.trim() !== "true") return {
13656
- repository: false,
13657
- shallow: false,
13658
- entries: null,
13659
- unreadable: null
13660
- };
13661
- const shallow = (git(root, ["rev-parse", "--is-shallow-repository"]) ?? "").trim() === "true";
13662
- const born = git(root, [
13663
- "rev-parse",
13664
- "--verify",
13665
- "--quiet",
13666
- "HEAD"
13667
- ]) !== null;
13668
- const entries = shallow ? null : born ? historicEntries(root) : [];
13669
- return {
13670
- repository: true,
13671
- shallow,
13672
- entries,
13673
- unreadable: entries !== null ? null : shallow ? "shallow" : "unreadable"
13674
- };
13675
- }
13676
- /**
13677
- * Every id history has ever recorded, each with the text it carried the FIRST
13678
- * time it was written. A version that parses contributes each entry's digest,
13679
- * so an entry EDITED in place is caught, not only one deleted; a version that
13680
- * no longer parses still contributes its ids, read permissively — the point
13681
- * there is that an id once written never disappears.
13682
- *
13683
- * FIRST, not every: keying this by `id\tdigest` kept one baseline entry per
13684
- * version an id ever had, so a tamper that was COMMITTED and then UNDONE left
13685
- * two digests for one id, the restored entry matched only one of them, and
13686
- * `ksor-ledger-amended` fired for good. The record became permanently
13687
- * unbuildable — by a tamper that had already been put right — and the only
13688
- * escape was rewriting git history, which is not a remedy a refusal may
13689
- * demand (found in review, 2026-08-25).
13690
- *
13691
- * Taking the OLDEST is what makes the guarantee both enforceable and
13692
- * escapable. It still refuses a committed tamper (the baseline is what the
13693
- * entry said when it was written, so committing the edit does not launder
13694
- * it), and the remedy it names — put the entry back — now actually clears
13695
- * it. Taking the NEWEST would have done the opposite on both counts.
13696
- */
13697
- function historicEntries(root) {
13698
- const atRoot = `${(git(root, ["rev-parse", "--show-prefix"]) ?? "").trim()}${LEDGER}`;
13699
- const commits = git(root, [
13700
- "log",
13701
- "--full-history",
13702
- "--topo-order",
13703
- "--format=%H",
13704
- "--",
13705
- LEDGER
13706
- ]);
13707
- if (commits === null) return null;
13708
- const seen = /* @__PURE__ */ new Map();
13709
- for (const sha of commits.split("\n").filter((s) => s !== "")) {
13710
- const text = git(root, ["show", `${sha}:${atRoot}`]);
13711
- if (text === null) {
13712
- const listed = git(root, [
13713
- "ls-tree",
13714
- "--full-tree",
13715
- "--name-only",
13716
- sha,
13717
- "--",
13718
- atRoot
13719
- ]);
13720
- if (listed !== null && listed.trim() === "") continue;
13721
- return null;
13722
- }
13723
- const where = sha.slice(0, 7);
13724
- const parsed = parseLedger(text, LEDGER);
13725
- if (parsed.ok) {
13726
- for (const entry of parsed.ledger.entries) seen.set(entry.id, {
13727
- id: entry.id,
13728
- digest: entryDigest(entry),
13729
- entry,
13730
- where
13731
- });
13732
- continue;
13733
- }
13734
- for (const m of text.matchAll(/^\s*(?:-\s+)?id:\s*["']?([^\s"']+)/gm)) {
13735
- const id = m[1] ?? "";
13736
- if (!seen.has(id)) seen.set(id, {
13737
- id,
13738
- digest: null,
13739
- where
13740
- });
13741
- }
13742
- }
13743
- return [...seen.values()].sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
13744
- }
13745
13751
  /** The inputs a projection reads; nothing else moves `source_commit` (the lock itself included). */
13746
13752
  const INPUTS = [
13747
13753
  "knowledge",
@@ -12672,6 +12672,139 @@ function nearMissOf(baseName) {
12672
12672
  return null;
12673
12673
  }
12674
12674
  /**
12675
+ * The takedown ledger's OTHER baseline: every entry any COMMITTED version of
12676
+ * `.ksor/takedowns.yaml` has ever carried.
12677
+ *
12678
+ * The committed lock is a baseline too, and a good one — it holds each entry's
12679
+ * digest, so an entry retargeted in place is caught. What it cannot do is prove
12680
+ * that an entry was never deleted, because the lock travels in the SAME change
12681
+ * as the ledger: delete the row, recompute `ledger_sha256`, empty
12682
+ * `ledger_entries`, and the two agree with each other about a denial that is
12683
+ * gone. Only history remembers.
12684
+ *
12685
+ * The baseline may be INCOMPLETE only if it SAYS so: every version history
12686
+ * holds is read, or `entries` comes back null and the caller reports that it
12687
+ * could not verify. A version silently skipped would contribute neither
12688
+ * digests nor ids while the answer still read "verified"
12689
+ * (`git-ledger.integration.test.ts`).
12690
+ *
12691
+ * This lives in the record module because THREE surfaces need the same answer —
12692
+ * `ksor build`, the emitted checker, and the site's stage (decision 19: a
12693
+ * surface that refuses must refuse on both surfaces). Plain `git log` / `git
12694
+ * show`, so nothing here needs installing.
12695
+ */
12696
+ const LEDGER = ".ksor/takedowns.yaml";
12697
+ /**
12698
+ * `spawnSync` defaults to a 1 MB stdout buffer, and past it the child is KILLED
12699
+ * — `status` comes back null, so the query reads as a failure. A ledger with a
12700
+ * few thousand entries, or one entry carrying a long reason, clears 1 MB
12701
+ * easily, and the version was then dropped from the baseline while the caller
12702
+ * was still told history had been verified. The ceiling stays finite on
12703
+ * purpose: past it this returns null, which is a state the caller SAYS.
12704
+ */
12705
+ const MAX_BUFFER$1 = 67108864;
12706
+ /** One git query, read-only. Null on any non-zero exit, including no git at all. */
12707
+ function git(root, args) {
12708
+ const r = spawnSync("git", [...args], {
12709
+ cwd: root,
12710
+ encoding: "utf8",
12711
+ maxBuffer: MAX_BUFFER$1
12712
+ });
12713
+ return r.status === 0 ? r.stdout : null;
12714
+ }
12715
+ function historicLedger(root) {
12716
+ const inside = git(root, ["rev-parse", "--is-inside-work-tree"]);
12717
+ if (inside === null || inside.trim() !== "true") return {
12718
+ repository: false,
12719
+ shallow: false,
12720
+ entries: null,
12721
+ unreadable: null
12722
+ };
12723
+ const shallow = (git(root, ["rev-parse", "--is-shallow-repository"]) ?? "").trim() === "true";
12724
+ const born = git(root, [
12725
+ "rev-parse",
12726
+ "--verify",
12727
+ "--quiet",
12728
+ "HEAD"
12729
+ ]) !== null;
12730
+ const entries = shallow ? null : born ? historicEntries(root) : [];
12731
+ return {
12732
+ repository: true,
12733
+ shallow,
12734
+ entries,
12735
+ unreadable: entries !== null ? null : shallow ? "shallow" : "unreadable"
12736
+ };
12737
+ }
12738
+ /**
12739
+ * Every id history has ever recorded, each with the text it carried the FIRST
12740
+ * time it was written. A version that parses contributes each entry's digest,
12741
+ * so an entry EDITED in place is caught, not only one deleted; a version that
12742
+ * no longer parses still contributes its ids, read permissively — the point
12743
+ * there is that an id once written never disappears.
12744
+ *
12745
+ * FIRST, not every: keying this by `id\tdigest` kept one baseline entry per
12746
+ * version an id ever had, so a tamper that was COMMITTED and then UNDONE left
12747
+ * two digests for one id, the restored entry matched only one of them, and
12748
+ * `ksor-ledger-amended` fired for good. The record became permanently
12749
+ * unbuildable — by a tamper that had already been put right — and the only
12750
+ * escape was rewriting git history, which is not a remedy a refusal may
12751
+ * demand (found in review, 2026-08-25).
12752
+ *
12753
+ * Taking the OLDEST is what makes the guarantee both enforceable and
12754
+ * escapable. It still refuses a committed tamper (the baseline is what the
12755
+ * entry said when it was written, so committing the edit does not launder
12756
+ * it), and the remedy it names — put the entry back — now actually clears
12757
+ * it. Taking the NEWEST would have done the opposite on both counts.
12758
+ */
12759
+ function historicEntries(root) {
12760
+ const atRoot = `${(git(root, ["rev-parse", "--show-prefix"]) ?? "").trim()}${LEDGER}`;
12761
+ const commits = git(root, [
12762
+ "log",
12763
+ "--full-history",
12764
+ "--topo-order",
12765
+ "--format=%H",
12766
+ "--",
12767
+ LEDGER
12768
+ ]);
12769
+ if (commits === null) return null;
12770
+ const seen = /* @__PURE__ */ new Map();
12771
+ for (const sha of commits.split("\n").filter((s) => s !== "")) {
12772
+ const text = git(root, ["show", `${sha}:${atRoot}`]);
12773
+ if (text === null) {
12774
+ const listed = git(root, [
12775
+ "ls-tree",
12776
+ "--full-tree",
12777
+ "--name-only",
12778
+ sha,
12779
+ "--",
12780
+ atRoot
12781
+ ]);
12782
+ if (listed !== null && listed.trim() === "") continue;
12783
+ return null;
12784
+ }
12785
+ const where = sha.slice(0, 7);
12786
+ const parsed = parseLedger(text, LEDGER);
12787
+ if (parsed.ok) {
12788
+ for (const entry of parsed.ledger.entries) seen.set(entry.id, {
12789
+ id: entry.id,
12790
+ digest: entryDigest(entry),
12791
+ entry,
12792
+ where
12793
+ });
12794
+ continue;
12795
+ }
12796
+ for (const m of text.matchAll(/^\s*(?:-\s+)?id:\s*["']?([^\s"']+)/gm)) {
12797
+ const id = m[1] ?? "";
12798
+ if (!seen.has(id)) seen.set(id, {
12799
+ id,
12800
+ digest: null,
12801
+ where
12802
+ });
12803
+ }
12804
+ }
12805
+ return [...seen.values()].sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
12806
+ }
12807
+ /**
12675
12808
  * The widening rule: a link, a `ksor.superseded_by` pointer or a companion
12676
12809
  * body may reach a target whose audience contains `public` or contains every
12677
12810
  * identifier in the source's — then every reader of the source can read the
@@ -13537,6 +13670,11 @@ function checkAgainstPolicy(concept, policy, refusals) {
13537
13670
  }
13538
13671
  const hex64 = string().regex(/^[0-9a-f]{64}$/, "a sha256 hex digest");
13539
13672
  const viewerList = array(string().min(1));
13673
+ const bundleEntry = object({
13674
+ viewer: string().min(1),
13675
+ sha256: hex64,
13676
+ files: number().int().nonnegative()
13677
+ }).strict();
13540
13678
  const lockSchema = object({
13541
13679
  format: literal(1),
13542
13680
  build_id: string().regex(/^sha256:[0-9a-f]{64}$/),
@@ -13584,7 +13722,8 @@ const lockSchema = object({
13584
13722
  indexes: array(object({
13585
13723
  path: string().min(1),
13586
13724
  sha256: hex64
13587
- }).strict())
13725
+ }).strict()),
13726
+ bundles: array(bundleEntry)
13588
13727
  }).strict();
13589
13728
  function parseLock(text) {
13590
13729
  let value;
@@ -13609,139 +13748,6 @@ function parseLock(text) {
13609
13748
  lock: parsed.data
13610
13749
  };
13611
13750
  }
13612
- /**
13613
- * The takedown ledger's OTHER baseline: every entry any COMMITTED version of
13614
- * `.ksor/takedowns.yaml` has ever carried.
13615
- *
13616
- * The committed lock is a baseline too, and a good one — it holds each entry's
13617
- * digest, so an entry retargeted in place is caught. What it cannot do is prove
13618
- * that an entry was never deleted, because the lock travels in the SAME change
13619
- * as the ledger: delete the row, recompute `ledger_sha256`, empty
13620
- * `ledger_entries`, and the two agree with each other about a denial that is
13621
- * gone. Only history remembers.
13622
- *
13623
- * The baseline may be INCOMPLETE only if it SAYS so: every version history
13624
- * holds is read, or `entries` comes back null and the caller reports that it
13625
- * could not verify. A version silently skipped would contribute neither
13626
- * digests nor ids while the answer still read "verified"
13627
- * (`git-ledger.integration.test.ts`).
13628
- *
13629
- * This lives in the record module because THREE surfaces need the same answer —
13630
- * `ksor build`, the emitted checker, and the site's stage (decision 19: a
13631
- * surface that refuses must refuse on both surfaces). Plain `git log` / `git
13632
- * show`, so nothing here needs installing.
13633
- */
13634
- const LEDGER = ".ksor/takedowns.yaml";
13635
- /**
13636
- * `spawnSync` defaults to a 1 MB stdout buffer, and past it the child is KILLED
13637
- * — `status` comes back null, so the query reads as a failure. A ledger with a
13638
- * few thousand entries, or one entry carrying a long reason, clears 1 MB
13639
- * easily, and the version was then dropped from the baseline while the caller
13640
- * was still told history had been verified. The ceiling stays finite on
13641
- * purpose: past it this returns null, which is a state the caller SAYS.
13642
- */
13643
- const MAX_BUFFER = 67108864;
13644
- /** One git query, read-only. Null on any non-zero exit, including no git at all. */
13645
- function git(root, args) {
13646
- const r = spawnSync("git", [...args], {
13647
- cwd: root,
13648
- encoding: "utf8",
13649
- maxBuffer: MAX_BUFFER
13650
- });
13651
- return r.status === 0 ? r.stdout : null;
13652
- }
13653
- function historicLedger(root) {
13654
- const inside = git(root, ["rev-parse", "--is-inside-work-tree"]);
13655
- if (inside === null || inside.trim() !== "true") return {
13656
- repository: false,
13657
- shallow: false,
13658
- entries: null,
13659
- unreadable: null
13660
- };
13661
- const shallow = (git(root, ["rev-parse", "--is-shallow-repository"]) ?? "").trim() === "true";
13662
- const born = git(root, [
13663
- "rev-parse",
13664
- "--verify",
13665
- "--quiet",
13666
- "HEAD"
13667
- ]) !== null;
13668
- const entries = shallow ? null : born ? historicEntries(root) : [];
13669
- return {
13670
- repository: true,
13671
- shallow,
13672
- entries,
13673
- unreadable: entries !== null ? null : shallow ? "shallow" : "unreadable"
13674
- };
13675
- }
13676
- /**
13677
- * Every id history has ever recorded, each with the text it carried the FIRST
13678
- * time it was written. A version that parses contributes each entry's digest,
13679
- * so an entry EDITED in place is caught, not only one deleted; a version that
13680
- * no longer parses still contributes its ids, read permissively — the point
13681
- * there is that an id once written never disappears.
13682
- *
13683
- * FIRST, not every: keying this by `id\tdigest` kept one baseline entry per
13684
- * version an id ever had, so a tamper that was COMMITTED and then UNDONE left
13685
- * two digests for one id, the restored entry matched only one of them, and
13686
- * `ksor-ledger-amended` fired for good. The record became permanently
13687
- * unbuildable — by a tamper that had already been put right — and the only
13688
- * escape was rewriting git history, which is not a remedy a refusal may
13689
- * demand (found in review, 2026-08-25).
13690
- *
13691
- * Taking the OLDEST is what makes the guarantee both enforceable and
13692
- * escapable. It still refuses a committed tamper (the baseline is what the
13693
- * entry said when it was written, so committing the edit does not launder
13694
- * it), and the remedy it names — put the entry back — now actually clears
13695
- * it. Taking the NEWEST would have done the opposite on both counts.
13696
- */
13697
- function historicEntries(root) {
13698
- const atRoot = `${(git(root, ["rev-parse", "--show-prefix"]) ?? "").trim()}${LEDGER}`;
13699
- const commits = git(root, [
13700
- "log",
13701
- "--full-history",
13702
- "--topo-order",
13703
- "--format=%H",
13704
- "--",
13705
- LEDGER
13706
- ]);
13707
- if (commits === null) return null;
13708
- const seen = /* @__PURE__ */ new Map();
13709
- for (const sha of commits.split("\n").filter((s) => s !== "")) {
13710
- const text = git(root, ["show", `${sha}:${atRoot}`]);
13711
- if (text === null) {
13712
- const listed = git(root, [
13713
- "ls-tree",
13714
- "--full-tree",
13715
- "--name-only",
13716
- sha,
13717
- "--",
13718
- atRoot
13719
- ]);
13720
- if (listed !== null && listed.trim() === "") continue;
13721
- return null;
13722
- }
13723
- const where = sha.slice(0, 7);
13724
- const parsed = parseLedger(text, LEDGER);
13725
- if (parsed.ok) {
13726
- for (const entry of parsed.ledger.entries) seen.set(entry.id, {
13727
- id: entry.id,
13728
- digest: entryDigest(entry),
13729
- entry,
13730
- where
13731
- });
13732
- continue;
13733
- }
13734
- for (const m of text.matchAll(/^\s*(?:-\s+)?id:\s*["']?([^\s"']+)/gm)) {
13735
- const id = m[1] ?? "";
13736
- if (!seen.has(id)) seen.set(id, {
13737
- id,
13738
- digest: null,
13739
- where
13740
- });
13741
- }
13742
- }
13743
- return [...seen.values()].sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
13744
- }
13745
13751
  /** The inputs a projection reads; nothing else moves `source_commit` (the lock itself included). */
13746
13752
  const INPUTS = [
13747
13753
  "knowledge",
@@ -497,9 +497,14 @@ runs over every entry in the ledger at `pnpm check`, `ksor build` and ingest, so
497
497
  a line appended by hand in a pull request is refused exactly as the verb would
498
498
  refuse it. The read-only modes
499
499
  (`--list`, `--ledger`) need no actor — nobody is performing an act by looking.
500
- They do not need a database either: on a record that declares none they read
501
- the committed `.ksor/takedowns.yaml`, which is the whole record of the act
502
- anyway.
500
+ They do not need a database either: `--ledger` always reads the committed
501
+ `.ksor/takedowns.yaml`, which is the record of every act, and `--list` reads
502
+ the door's denylist rows when `KSOR_DB_URL` is set and otherwise the ledger's
503
+ denials, each labelled `not applied (no database)` because no row exists for
504
+ a door to refuse on. A denial itself, on this record with `KSOR_DB_URL` unset,
505
+ is refused by name (`ksor-takedown-dsn-missing`) unless `--file-only` records
506
+ the entry alone — `--apply` writes its row later, where the database is
507
+ reachable.
503
508
 
504
509
  **The MCP door stops serving it immediately. The SITE stops at its next
505
510
  build** — the site reads the committed ledger (`.ksor/takedowns.yaml`), not
@@ -516,7 +521,11 @@ ROOT, never `system/site/`), and every other host just serves the folder.
516
521
  record checked, `build.lock.json` written (commit it: it is the provenance
517
522
  every machine artefact stamps) — and a refusal stops the build before a byte
518
523
  is written. `ksor build --strict` additionally refuses an uncommitted input
519
- (`ksor-build-dirty`), which is the posture for a release.
524
+ (`ksor-build-dirty`), which is the posture for a release. `ksor build
525
+ --bundles` also writes one OKF bundle per viewer under
526
+ `.ksor/out/bundles/<viewer>/` (gitignored) — only what that viewer's machine
527
+ surfaces publish, readable by any OKF consumer with no ksor in the loop — for
528
+ handing the record to another system.
520
529
  `KSOR_BASE_PATH=/repo pnpm build` targets sub-path hosting. With audiences
521
530
  registered in `.ksor/governance.yaml`, plain `pnpm build` is the `public`
522
531
  viewer; `KSOR_AUDIENCE=public,<audience> pnpm build` — a comma list, always
@@ -607,7 +616,14 @@ CI — and a first deploy without it serves an empty record. Full walkthrough:
607
616
  audiences registered in `.ksor/governance.yaml`; never omitted, never
608
617
  inferred). A `stable` document carries `generated: { by, at }` and
609
618
  `ksor.approval: { by, at }` by an actor the policy authorises, with
610
- `generated.at` no later than the approval; a `deprecated` one carries
619
+ `generated.at` no later than the approval — and `generated.at` dates the
620
+ TEXT: edit a stable document's body and `ksor build` and `ksor ingest`
621
+ compare it against every committed version that was stable, and refuse
622
+ `ksor-generated-stale` until you move the stamp PAST the edit and re-approve
623
+ — leaving the stamp alone and backdating it are refused alike, because
624
+ neither advances it (a frontmatter-only edit, such as adding a `verified`
625
+ entry, is not a body change; `pnpm check` reads no document history, so it passes an
626
+ edit the build will refuse); a `deprecated` one carries
611
627
  `ksor.deprecated: { by, at }` and usually `ksor.superseded_by: <id>`
612
628
  (a stable document every reader of this one may read). Optional: `order`
613
629
  (reading position), `sources` (`{ id, resource, title }`, cited in the body
@@ -259,7 +259,9 @@ Never copy a floor from another corpus.
259
259
  It also prints its own caveat, and it is worth reading: the probes it writes are
260
260
  derived from your passages, so they share vocabulary a real question will not.
261
261
  The floor it reports is an upper bound on separation until you check it against
262
- questions the corpus did not write (`--queries-file`).
262
+ questions a person wrote: in-corpus ones with `--queries-file`, and — because
263
+ the built-in out-of-corpus probes are all far-domain — questions just outside
264
+ your scope with `--ooc-file`.
263
265
 
264
266
  A rerun on an unchanged record costs nothing: no new generation, no embedding,
265
267
  no rows. Edit a document and the next run picks up exactly that change.
@@ -724,6 +726,7 @@ map rather than a substitute.
724
726
  | the home page and `/llms.txt` are empty | every document is still a draft — correct, not broken | approve one and rebuild |
725
727
  | `ksor-record-empty` | every document was deleted — a record is never empty, so nothing was written | add one document of your own (or restore one from git) before deleting the last starter |
726
728
  | `ksor-approver-unauthorised` | a document is approved by an actor `.ksor/governance.yaml` no longer names — usually `human:you` after the interview | re-attribute the approval to your handle, or restore the actor to `approval_authorities` |
729
+ | `ksor-generated-stale` at `pnpm build` or `pnpm refresh` | a `stable` document's body changed since a commit where it was stable, and `generated.at` was not advanced past that commit's (left alone, or moved backward) — the stamp dates the text, and `pnpm check` reads no document history, so it passed | set `generated.at` to an instant after the edit and re-approve (`ksor.approval.at` may not precede it) |
727
730
  | a new document never appears on the built site | drafts reach no built surface at all | publish it — `status: stable` plus both governance keys |
728
731
  | an expired document still shows on the site but not through the door | the static build evaluated `stale_after` at build time | rebuild and redeploy; schedule a rebuild if you use it |
729
732
  | Vercel: `no services are declared` | Root Directory was auto-filled with `system/site` | set it to `./` |
@@ -66,6 +66,9 @@ KSOR_AUTH=disabled-local
66
66
  # NEXT_PUBLIC_KSOR_SSO_URL=https://your-sso.example.com
67
67
  # NEXT_PUBLIC_KSOR_OAUTH_CLIENT_ID=
68
68
  # NEXT_PUBLIC_KSOR_OAUTH_REDIRECT_URI=https://your-site.example.com/auth/callback
69
+ #
70
+ # Next.js telemetry is already off: the site's build and dev scripts run next
71
+ # through system/site/next-no-telemetry.mjs, which sets NEXT_TELEMETRY_DISABLED=1.
69
72
 
70
73
  # ── Production knobs ────────────────────────────────────────────────────────
71
74
  # Unset is fine for a local run; each one matters once this serves for real.