@fractalsynapse/dsh-chapters 0.0.0-stage → 0.2.21

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.
Files changed (195) hide show
  1. package/LICENSE +14 -0
  2. package/README.md +76 -2
  3. package/cordis.patch.yml +363 -0
  4. package/docs/architecture.md +692 -0
  5. package/docs/autorun-guide.md +248 -0
  6. package/docs/backlog.md +2022 -0
  7. package/docs/contract.md +938 -0
  8. package/docs/development.md +990 -0
  9. package/docs/host-compaction-seam.md +225 -0
  10. package/docs/host-protected-head-ask.md +80 -0
  11. package/docs/knowledge-repo.md +1332 -0
  12. package/docs/plans-carriage.md +571 -0
  13. package/docs/project-state.md +642 -0
  14. package/docs/provider.md +98 -0
  15. package/docs/superpowers/plans/2026-10-17-chapters-save.md +198 -0
  16. package/docs/superpowers/plans/2026-11-02-chapter-removal.md +151 -0
  17. package/docs/superpowers/specs/2026-11-02-chapter-removal-design.md +115 -0
  18. package/docs/verify.md +561 -0
  19. package/lib/archive.d.ts +161 -0
  20. package/lib/archive.js +229 -0
  21. package/lib/archive.js.map +1 -0
  22. package/lib/arrival.d.ts +23 -0
  23. package/lib/arrival.js +125 -0
  24. package/lib/arrival.js.map +1 -0
  25. package/lib/artifact-query.d.ts +62 -0
  26. package/lib/artifact-query.js +187 -0
  27. package/lib/artifact-query.js.map +1 -0
  28. package/lib/attach.d.ts +46 -0
  29. package/lib/attach.js +120 -0
  30. package/lib/attach.js.map +1 -0
  31. package/lib/auto-save.d.ts +145 -0
  32. package/lib/auto-save.js +334 -0
  33. package/lib/auto-save.js.map +1 -0
  34. package/lib/aux-message.d.ts +17 -0
  35. package/lib/aux-message.js +20 -0
  36. package/lib/aux-message.js.map +1 -0
  37. package/lib/client.js +1419 -0
  38. package/lib/client.js.map +1 -0
  39. package/lib/codegraph.d.ts +76 -0
  40. package/lib/codegraph.js +190 -0
  41. package/lib/codegraph.js.map +1 -0
  42. package/lib/commands.d.ts +52 -0
  43. package/lib/commands.js +946 -0
  44. package/lib/commands.js.map +1 -0
  45. package/lib/compose.d.ts +30 -0
  46. package/lib/compose.js +185 -0
  47. package/lib/compose.js.map +1 -0
  48. package/lib/continue-core.d.ts +245 -0
  49. package/lib/continue-core.js +405 -0
  50. package/lib/continue-core.js.map +1 -0
  51. package/lib/diag.d.ts +55 -0
  52. package/lib/diag.js +186 -0
  53. package/lib/diag.js.map +1 -0
  54. package/lib/engine-core.d.ts +301 -0
  55. package/lib/engine-core.js +531 -0
  56. package/lib/engine-core.js.map +1 -0
  57. package/lib/engine-note.d.ts +35 -0
  58. package/lib/engine-note.js +32 -0
  59. package/lib/engine-note.js.map +1 -0
  60. package/lib/engine.d.ts +329 -0
  61. package/lib/engine.js +1179 -0
  62. package/lib/engine.js.map +1 -0
  63. package/lib/enrich-queue.d.ts +66 -0
  64. package/lib/enrich-queue.js +126 -0
  65. package/lib/enrich-queue.js.map +1 -0
  66. package/lib/enrich-store.d.ts +31 -0
  67. package/lib/enrich-store.js +103 -0
  68. package/lib/enrich-store.js.map +1 -0
  69. package/lib/enrich-wire.d.ts +163 -0
  70. package/lib/enrich-wire.js +353 -0
  71. package/lib/enrich-wire.js.map +1 -0
  72. package/lib/enrich.d.ts +102 -0
  73. package/lib/enrich.js +267 -0
  74. package/lib/enrich.js.map +1 -0
  75. package/lib/gitops.d.ts +107 -0
  76. package/lib/gitops.js +539 -0
  77. package/lib/gitops.js.map +1 -0
  78. package/lib/index.d.ts +241 -0
  79. package/lib/index.js +1162 -0
  80. package/lib/index.js.map +1 -0
  81. package/lib/indexing.d.ts +98 -0
  82. package/lib/indexing.js +223 -0
  83. package/lib/indexing.js.map +1 -0
  84. package/lib/injections.d.ts +90 -0
  85. package/lib/injections.js +165 -0
  86. package/lib/injections.js.map +1 -0
  87. package/lib/last-resort.d.ts +24 -0
  88. package/lib/last-resort.js +27 -0
  89. package/lib/last-resort.js.map +1 -0
  90. package/lib/log-shape.d.ts +38 -0
  91. package/lib/log-shape.js +93 -0
  92. package/lib/log-shape.js.map +1 -0
  93. package/lib/models-command.d.ts +74 -0
  94. package/lib/models-command.js +100 -0
  95. package/lib/models-command.js.map +1 -0
  96. package/lib/notice.d.ts +74 -0
  97. package/lib/notice.js +92 -0
  98. package/lib/notice.js.map +1 -0
  99. package/lib/plans.d.ts +154 -0
  100. package/lib/plans.js +315 -0
  101. package/lib/plans.js.map +1 -0
  102. package/lib/preset.d.ts +186 -0
  103. package/lib/preset.js +212 -0
  104. package/lib/preset.js.map +1 -0
  105. package/lib/prompt-keys.d.ts +7 -0
  106. package/lib/prompt-keys.js +8 -0
  107. package/lib/prompt-keys.js.map +1 -0
  108. package/lib/prompt-loop.d.ts +73 -0
  109. package/lib/prompt-loop.js +147 -0
  110. package/lib/prompt-loop.js.map +1 -0
  111. package/lib/prompt-push.d.ts +47 -0
  112. package/lib/prompt-push.js +115 -0
  113. package/lib/prompt-push.js.map +1 -0
  114. package/lib/prompt-runner.d.ts +48 -0
  115. package/lib/prompt-runner.js +90 -0
  116. package/lib/prompt-runner.js.map +1 -0
  117. package/lib/prompt-state.d.ts +142 -0
  118. package/lib/prompt-state.js +101 -0
  119. package/lib/prompt-state.js.map +1 -0
  120. package/lib/prompt.d.ts +270 -0
  121. package/lib/prompt.js +408 -0
  122. package/lib/prompt.js.map +1 -0
  123. package/lib/provider.d.ts +44 -0
  124. package/lib/provider.js +66 -0
  125. package/lib/provider.js.map +1 -0
  126. package/lib/redact.d.ts +24 -0
  127. package/lib/redact.js +85 -0
  128. package/lib/redact.js.map +1 -0
  129. package/lib/registry.d.ts +187 -0
  130. package/lib/registry.js +235 -0
  131. package/lib/registry.js.map +1 -0
  132. package/lib/removal.d.ts +159 -0
  133. package/lib/removal.js +556 -0
  134. package/lib/removal.js.map +1 -0
  135. package/lib/render.d.ts +97 -0
  136. package/lib/render.js +530 -0
  137. package/lib/render.js.map +1 -0
  138. package/lib/repair-run.d.ts +76 -0
  139. package/lib/repair-run.js +506 -0
  140. package/lib/repair-run.js.map +1 -0
  141. package/lib/repair.d.ts +208 -0
  142. package/lib/repair.js +357 -0
  143. package/lib/repair.js.map +1 -0
  144. package/lib/repo.d.ts +78 -0
  145. package/lib/repo.js +184 -0
  146. package/lib/repo.js.map +1 -0
  147. package/lib/rules-commands.d.ts +46 -0
  148. package/lib/rules-commands.js +379 -0
  149. package/lib/rules-commands.js.map +1 -0
  150. package/lib/rules.d.ts +267 -0
  151. package/lib/rules.js +478 -0
  152. package/lib/rules.js.map +1 -0
  153. package/lib/save-core.d.ts +72 -0
  154. package/lib/save-core.js +220 -0
  155. package/lib/save-core.js.map +1 -0
  156. package/lib/search.d.ts +112 -0
  157. package/lib/search.js +282 -0
  158. package/lib/search.js.map +1 -0
  159. package/lib/session-rules.d.ts +222 -0
  160. package/lib/session-rules.js +454 -0
  161. package/lib/session-rules.js.map +1 -0
  162. package/lib/signature.d.ts +45 -0
  163. package/lib/signature.js +199 -0
  164. package/lib/signature.js.map +1 -0
  165. package/lib/store.d.ts +156 -0
  166. package/lib/store.js +368 -0
  167. package/lib/store.js.map +1 -0
  168. package/lib/sync.d.ts +220 -0
  169. package/lib/sync.js +810 -0
  170. package/lib/sync.js.map +1 -0
  171. package/lib/tools.d.ts +113 -0
  172. package/lib/tools.js +1090 -0
  173. package/lib/tools.js.map +1 -0
  174. package/lib/treedx/client.d.ts +57 -0
  175. package/lib/treedx/client.js +82 -0
  176. package/lib/treedx/client.js.map +1 -0
  177. package/lib/treedx/provider.d.ts +39 -0
  178. package/lib/treedx/provider.js +479 -0
  179. package/lib/treedx/provider.js.map +1 -0
  180. package/lib/treedx/state.d.ts +27 -0
  181. package/lib/treedx/state.js +65 -0
  182. package/lib/treedx/state.js.map +1 -0
  183. package/lib/types.d.ts +210 -0
  184. package/lib/types.js +31 -0
  185. package/lib/types.js.map +1 -0
  186. package/lib/version.d.ts +9 -0
  187. package/lib/version.js +10 -0
  188. package/lib/version.js.map +1 -0
  189. package/lib/vocabulary.d.ts +41 -0
  190. package/lib/vocabulary.js +118 -0
  191. package/lib/vocabulary.js.map +1 -0
  192. package/lib/warnings.d.ts +10 -0
  193. package/lib/warnings.js +18 -0
  194. package/lib/warnings.js.map +1 -0
  195. package/package.json +151 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ import { type FindingClass, type JournalEntry, type RepairFinding, type RepairFileSet } from './repair.ts';
2
+ import { type SessionState } from './registry.ts';
3
+ import type { ChapterRecord } from './archive.ts';
4
+ import type { RegistryStore } from './store.ts';
5
+ import { type SaveSessionConfig } from './save-core.ts';
6
+ import type { SessionEventLike } from './types.ts';
7
+ export interface RefusalGroup {
8
+ cls: string;
9
+ items: string[];
10
+ }
11
+ export declare function groupRefusals(refused: string[]): RefusalGroup[];
12
+ /** How many named examples a grouped class keeps visible. The rest is COUNTED, never dropped silently. */
13
+ export declare const REFUSAL_EXAMPLES = 3;
14
+ export declare function renderRefusalGroups(refused: string[], examples?: number): string[];
15
+ export interface RepairPorts {
16
+ store: RegistryStore;
17
+ /** A PAYLOAD-BEARING read of the durable log (#58's lesson: never a metadata-only record list). */
18
+ readLog(sessionId: string): Promise<SessionEventLike[] | null>;
19
+ /** The session's workspace cwd — the store root lives here. */
20
+ cwd: string;
21
+ /** Every root session the registry knows about, so a sibling tree is not mistaken for litter (#60). */
22
+ knownRoots?: string[] | undefined;
23
+ config: SaveSessionConfig;
24
+ log(message: string): void;
25
+ warn(message: string): void;
26
+ }
27
+ export interface RepairOptions {
28
+ sessionId: string;
29
+ /** Which classes to act on. `all` is the default for the operator, not for the tests. */
30
+ classes: FindingClass[] | 'all';
31
+ dryRun?: boolean;
32
+ /** Chapter-file paths already known from the registry, when no directory scan is possible. */
33
+ listedPaths?: string[];
34
+ }
35
+ /** The file view of the store, from a real directory scan (the offline script's advantage over ctx.fs). */
36
+ export declare function fileSetFromDisk(cwd: string, storeRoot: string, rootSession: string, knownRoots?: readonly string[]): RepairFileSet;
37
+ /** The same view WITHOUT a directory scan — what the host can offer, declared honestly blind. */
38
+ export declare function fileSetFromRegistry(records: readonly ChapterRecord[], existsSync: (p: string) => boolean): RepairFileSet;
39
+ export interface RepairOutcome {
40
+ journalId: string;
41
+ findingsBefore: RepairFinding[];
42
+ findingsAfter: RepairFinding[];
43
+ blindSpots: FindingClass[];
44
+ applied: JournalEntry[];
45
+ refused: string[];
46
+ }
47
+ /**
48
+ * Run the repair. `dryRun` produces the same audit and the same plan — it simply writes nothing, which
49
+ * is what makes `dry-run` trustworthy as a preview of `apply`.
50
+ */
51
+ export declare function runRepair(ports: RepairPorts, opts: RepairOptions): Promise<RepairOutcome>;
52
+ /** Undo a whole applied run, newest entry first. Derived inverses — the journal is not trusted to describe itself. */
53
+ export declare function restoreRepair(ports: RepairPorts, journalId: string, sessionId: string): Promise<{
54
+ undone: number;
55
+ problems: string[];
56
+ }>;
57
+ export type { RepairFinding, SessionState };
58
+ /**
59
+ * Bound a repair report so one command result cannot outgrow the archive (#117).
60
+ *
61
+ * Why this is a function and not arithmetic in the command: the same rule has to hold for the in-host
62
+ * `/chapters-repair` and the offline runner, and a decision that exists in two places is a decision that
63
+ * drifts (#59's lesson). Pure, so the three things that matter are rows rather than intentions — the count
64
+ * always survives, the withheld remainder is counted and named with a remedy, and a short report is not
65
+ * wrapped in ceremony.
66
+ *
67
+ * The trigger was measured: a 23-session dry-run printed 2,796 findings as ONE `command/done` result —
68
+ * 311 KB, an event larger than `2 × chapterTokenTarget` — which is what made that session permanently
69
+ * un-compactable by `chapters_continue`. Clipping is forbidden by invariant, so the only honest options were
70
+ * to stop generating the monster or to cap with a remedy. Both are here: the cap, and the count leading.
71
+ */
72
+ export declare function capReportLines(body: readonly string[], capLines: number): {
73
+ shown: string[];
74
+ withheld: number;
75
+ capLine: string;
76
+ };
@@ -0,0 +1,506 @@
1
+ /**
2
+ * The repair runner (#60) — apply what `audit()` found, through the doors that already exist.
3
+ *
4
+ * There is no second archive implementation here, on purpose. Every mutation is either
5
+ * - a call into the SAME save core the other five archive moments call (`saveSession`, now with its
6
+ * repair-only `span` / `supersede` / `attemptSalt` knobs), or
7
+ * - one pure registry transition (`supersedeChapter`, `raiseCounters`, `expireBookkeeping`,
8
+ * `releaseReservation`) run inside a `store.mutate` section (#59).
9
+ * So a repaired chapter is byte-identical to a chapter that archived normally, and a repair cannot
10
+ * drift from the pipeline it is fixing.
11
+ *
12
+ * Ordering the run (docs/architecture.md § Repair):
13
+ * 1. audit (read-only, and the SAME function `dry-run` shows);
14
+ * 2. write the journal FIRST — if the journal cannot be written, the run refuses to start;
15
+ * 3. apply, journalling each move as it happens;
16
+ * 4. re-audit and report the before/after counts, so the operator sees whether the repair worked
17
+ * rather than whether it ran.
18
+ */
19
+ import { createHash } from 'node:crypto';
20
+ import fs from 'node:fs';
21
+ import path from 'node:path';
22
+ import { audit, coveringChapter, journalEntryInverse, markSupersededBy, raiseCounters, expireBookkeeping } from "./repair.js";
23
+ import { appendChapters, releaseReservation } from "./registry.js";
24
+ import { parseFrontmatter } from "./indexing.js";
25
+ import { resolveStoredPath } from "./archive.js";
26
+ import { resolveStoreRoot } from "./store.js";
27
+ import { saveSession } from "./save-core.js";
28
+ /**
29
+ * One refusal line → its class: the text before the first `': '`, or `'other'`. Grouping is presentation
30
+ * only — every item is kept — because the class is shared and the FILE NAMES are the content an operator
31
+ * needs (#101: 483 repeated `test-litter` lines buried 372 real findings in the maintainer's run, in the
32
+ * command surface, because only the offline report had been aggregated).
33
+ */
34
+ const refusalClassOf = (line) => {
35
+ const i = line.indexOf(':');
36
+ return i > 0 ? line.slice(0, i).trim() : 'other';
37
+ };
38
+ export function groupRefusals(refused) {
39
+ const order = [];
40
+ const map = new Map();
41
+ for (const r of refused) {
42
+ const cls = refusalClassOf(r);
43
+ const bucket = map.get(cls);
44
+ if (bucket === undefined) {
45
+ map.set(cls, [r]);
46
+ order.push(cls);
47
+ }
48
+ else
49
+ bucket.push(r);
50
+ }
51
+ // Loudest class first: the one that would otherwise fill the screen is the one to dispose of.
52
+ return order.map((cls) => ({ cls, items: map.get(cls) })).sort((a, b) => b.items.length - a.items.length);
53
+ }
54
+ /** How many named examples a grouped class keeps visible. The rest is COUNTED, never dropped silently. */
55
+ export const REFUSAL_EXAMPLES = 3;
56
+ export function renderRefusalGroups(refused, examples = REFUSAL_EXAMPLES) {
57
+ return groupRefusals(refused).map(({ cls, items }) => {
58
+ const detail = (r) => { const i = r.indexOf(':'); return i > 0 ? r.slice(i + 1).trim() : r; };
59
+ if (items.length === 1)
60
+ return `refused: ${items[0]}`;
61
+ const keep = Math.max(1, examples);
62
+ const shown = items.slice(0, Math.min(items.length, keep)).map(detail).join(' | ').slice(0, 300);
63
+ const withheld = items.length - Math.min(items.length, keep);
64
+ return `refused ×${String(items.length)} (${cls}): ${shown}`
65
+ + (withheld > 0 ? `; ${String(withheld)} more of the same class` : '')
66
+ + ' — each names its own file; nothing in this class is touched automatically';
67
+ });
68
+ }
69
+ const ACTABLE = {
70
+ 'hollow-payload': true, 'never-archived-span': true, 'dead-citation': true,
71
+ 'ghost-plan-manifest': true, 'unreleased-reservation': true, 'countervalue-drift': true,
72
+ // empty-artifact / duplicate-number / orphan-file are resolved BY the re-render of their chapter: a
73
+ // 0-byte ref disappears when its chapter is superseded and re-rendered by the fixed renderer, and a
74
+ // duplicate number is fixed by re-spending it correctly. Half-fixing them separately would leave a
75
+ // record citing a file we moved. Report-only until their parent finding runs.
76
+ 'empty-artifact': false, 'duplicate-number': false, 'orphan-file': false, 'unregistered-file': true,
77
+ 'tampered-file': false, 'test-litter': false, unrecoverable: false,
78
+ };
79
+ const sha256 = (buf) => createHash('sha256').update(buf).digest('hex');
80
+ /** The file view of the store, from a real directory scan (the offline script's advantage over ctx.fs). */
81
+ export function fileSetFromDisk(cwd, storeRoot, rootSession, knownRoots = []) {
82
+ const rel = (abs) => path.relative(cwd, abs).split(path.sep).join('/');
83
+ const subdirs = (dir) => {
84
+ try {
85
+ return fs.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => rel(path.join(dir, e.name)));
86
+ }
87
+ catch {
88
+ return [];
89
+ }
90
+ };
91
+ const listDir = (dir) => {
92
+ try {
93
+ return fs.readdirSync(dir, { withFileTypes: true }).flatMap((e) => {
94
+ const p = path.join(dir, e.name);
95
+ return e.isDirectory() ? listDir(p) : [p];
96
+ });
97
+ }
98
+ catch {
99
+ return [];
100
+ }
101
+ };
102
+ // The registry stores paths RELATIVE TO THE WORKSPACE (`.dsh-chapters/<root>/chapters/001-x.md`), so
103
+ // the file set speaks the same dialect — comparing `root-1/chapters/…` against `.dsh-chapters/root-1/…`
104
+ // is how a first draft invented an orphan for every chapter and called its own tree litter.
105
+ const treeRoot = path.join(cwd, storeRoot, rootSession);
106
+ const abs = (p) => path.isAbsolute(p) ? p : path.join(cwd, p);
107
+ const onDisk = listDir(treeRoot).map(rel);
108
+ const bytesOf = (p) => {
109
+ try {
110
+ return fs.statSync(abs(p)).size;
111
+ }
112
+ catch {
113
+ return -1;
114
+ }
115
+ };
116
+ return {
117
+ exists: (p) => fs.existsSync(abs(p)),
118
+ bytes: bytesOf,
119
+ shaMatches: (p, sha) => {
120
+ try {
121
+ return sha256(fs.readFileSync(abs(p))) === sha;
122
+ }
123
+ catch {
124
+ return false;
125
+ }
126
+ },
127
+ chapterPaths: onDisk.filter((p) => p.includes('/chapters/') && p.endsWith('.md') && !p.includes('/plan-')),
128
+ artifactPaths: onDisk.filter((p) => p.includes('/artifacts/')),
129
+ emptyArtifactPaths: onDisk.filter((p) => p.includes('/artifacts/') && bytesOf(p) === 0),
130
+ // ROOTS are the immediate SUBDIRECTORIES of the store root that NO registry row claims. Two false
131
+ // starts, both measured on the first real run: `listDir` returns FILES, so every chapter became a
132
+ // "second root" (36,000 findings), and then every OTHER SESSION's legitimate tree did (634). One
133
+ // directory per root session is the normal shape of this store — litter is a directory nothing owns.
134
+ roots: subdirs(resolveStoreRoot(cwd, storeRoot)).filter((d) => !knownRoots.includes(path.basename(d))),
135
+ // the #58 signature is a fact about the BYTES, so read it from the bytes
136
+ looksLikeShell: (p) => {
137
+ try {
138
+ const t = fs.readFileSync(abs(p), 'utf8');
139
+ return /tool: unknown/.test(t) || /arguments: \{\}/.test(t) || /result \(seq \d+, 0 B\)/.test(t);
140
+ }
141
+ catch {
142
+ return false;
143
+ }
144
+ },
145
+ canScan: true,
146
+ };
147
+ }
148
+ /** The same view WITHOUT a directory scan — what the host can offer, declared honestly blind. */
149
+ export function fileSetFromRegistry(records, existsSync) {
150
+ return {
151
+ exists: (p) => existsSync(p),
152
+ bytes: () => 0,
153
+ shaMatches: () => true,
154
+ chapterPaths: records.map((r) => r.path),
155
+ artifactPaths: records.flatMap((r) => r.artifacts.map((a) => a.path)),
156
+ emptyArtifactPaths: records.flatMap((r) => r.artifacts.filter((a) => a.bytes === 0).map((a) => a.path)),
157
+ canScan: false,
158
+ };
159
+ }
160
+ /** Log facts the audit needs, derived from the durable events — never from the registry's memory. */
161
+ function logFacts(events) {
162
+ const turnEndSeqs = events.filter((e) => e.type === 'turn/end').map((e) => e.seq);
163
+ const collections = events
164
+ .filter((e) => e.type === 'turn/end')
165
+ .map((e) => ({ from: e.seq, to: e.seq }));
166
+ return { turnEndSeqs, collections };
167
+ }
168
+ /**
169
+ * Run the repair. `dryRun` produces the same audit and the same plan — it simply writes nothing, which
170
+ * is what makes `dry-run` trustworthy as a preview of `apply`.
171
+ */
172
+ export async function runRepair(ports, opts) {
173
+ const { store, cwd, config } = ports;
174
+ const journalId = new Date().toISOString().replace(/[:.]/g, '-');
175
+ const state0 = await store.get(opts.sessionId);
176
+ const logEvents = await ports.readLog(opts.sessionId);
177
+ if (logEvents === null || logEvents.length === 0) {
178
+ // Invariant 1 is the whole reason repair exists. No log, nothing to re-derive from: say WHICH
179
+ // sessions are unrecoverable rather than reporting a clean store.
180
+ return {
181
+ journalId, findingsBefore: [], findingsAfter: [], blindSpots: ['unrecoverable'], applied: [],
182
+ refused: [`session ${opts.sessionId} has no readable durable log — its knowledge cannot be re-derived (unrecoverable)`],
183
+ };
184
+ }
185
+ // ONE closure does both audits. Two separate call sites drifted: the after-audit forgot
186
+ // `ports.knownRoots`, so it called every sibling session tree `test-litter`, and a journal reported
187
+ // "25 findings remain" where 1 was real. A before/after number is only worth printing — or storing in
188
+ // a journal — if both sides are computed by the same call with the same inputs (#60).
189
+ const auditNow = (st) => audit({
190
+ sessionId: opts.sessionId,
191
+ cwd,
192
+ state: st,
193
+ files: opts.listedPaths !== undefined
194
+ ? fileSetFromRegistry(st.chapters, () => false)
195
+ : fileSetFromDisk(cwd, config.artifactStoreRoot, st.rootSession, ports.knownRoots ?? []),
196
+ log: logFacts(logEvents),
197
+ });
198
+ const before = auditNow(state0);
199
+ const wanted = opts.classes === 'all' ? before.findings : before.findings.filter((f) => opts.classes.includes(f.class));
200
+ const actionable = wanted.filter((f) => ACTABLE[f.class]);
201
+ const deferred = wanted.filter((f) => !ACTABLE[f.class]);
202
+ if (opts.dryRun) {
203
+ ports.log(`repair dry-run ${opts.sessionId}: ${actionable.length} actionable, ${deferred.length} report-only`);
204
+ return { journalId, findingsBefore: before.findings, findingsAfter: before.findings, blindSpots: before.blindSpots, applied: [], refused: deferred.map((f) => `${f.class}: ${f.detail}`) };
205
+ }
206
+ // JOURNAL FIRST. An applied run with no journal is a story nobody can check or undo.
207
+ const repairsDir = path.join(cwd, config.artifactStoreRoot, state0.rootSession, 'repairs');
208
+ const journal = {
209
+ id: journalId, sessionId: opts.sessionId, startedAt: Date.now(),
210
+ classes: [...new Set(actionable.map((f) => f.class))], completedAt: null,
211
+ entries: [], findingsBefore: before.findings.length, findingsAfter: before.findings.length,
212
+ };
213
+ try {
214
+ fs.mkdirSync(repairsDir, { recursive: true });
215
+ fs.writeFileSync(path.join(repairsDir, `${journalId}.json`), `${JSON.stringify(journal, null, 2)}\n`);
216
+ }
217
+ catch (error) {
218
+ return { journalId, findingsBefore: before.findings, findingsAfter: before.findings, blindSpots: before.blindSpots, applied: [], refused: [`journal could not be written (${String(error.message).slice(0, 120)}) — refusing to apply anything`] };
219
+ }
220
+ const flush = () => {
221
+ try {
222
+ fs.writeFileSync(path.join(repairsDir, `${journalId}.json`), `${JSON.stringify(journal, null, 2)}\n`);
223
+ }
224
+ catch (error) {
225
+ ports.warn(`repair journal ${journalId} could not be updated: ${String(error.message).slice(0, 100)}`);
226
+ }
227
+ };
228
+ const quarantineDir = path.join(cwd, config.artifactStoreRoot, state0.rootSession, '.repair-quarantine');
229
+ void 0;
230
+ const quarantine = async (relPath) => {
231
+ const absP = path.join(cwd, relPath);
232
+ if (!fs.existsSync(absP))
233
+ return;
234
+ const to = path.join(quarantineDir, relPath.split('/').pop() ?? 'file');
235
+ fs.mkdirSync(quarantineDir, { recursive: true });
236
+ const beforeSha = sha256(fs.readFileSync(absP));
237
+ fs.copyFileSync(absP, to);
238
+ // every journal path is stored in the SAME dialect the registry uses (relative to the workspace
239
+ // cwd) — a mix of absolute and relative is how a restore silently finds nothing to undo (#60)
240
+ journal.entries.push({ kind: 'quarantine', path: relPath, beforeSha, afterSha: beforeSha, to: path.relative(cwd, to).split(path.sep).join('/') });
241
+ flush();
242
+ };
243
+ const refused = deferred.map((f) => `${f.class}: ${f.detail}`);
244
+ for (const f of actionable) {
245
+ try {
246
+ if (f.class === 'hollow-payload' && f.target.fromSeq !== undefined && f.target.toSeq !== undefined && f.target.number !== undefined) {
247
+ const huskPath = state0.chapters.find((c) => c.number === f.target.number)?.path;
248
+ // "already in the archive" is a THROW inside save-core, not an outcome — and for a repair it is
249
+ // an EXPECTED answer (an earlier run, or the door itself, archived the span). Swallow it into the
250
+ // same no-records shape so the coverage check below can supersede the husk by what already covers
251
+ // it; a throw reaching the per-finding catch would strand the record forever (#60).
252
+ let out;
253
+ try {
254
+ out = await saveSession({
255
+ events: logEvents, sessionId: opts.sessionId, cwd, store, config,
256
+ span: { fromSeq: f.target.fromSeq, toSeq: f.target.toSeq },
257
+ supersede: { over: f.target.number, reason: 'hollow-payload' },
258
+ attemptSalt: `repair:${journalId}`,
259
+ });
260
+ }
261
+ catch (error) {
262
+ out = { records: [], skipped: 'already-archived', warnings: [] };
263
+ ports.log(`ch.${f.target.number}: the re-read said "already archived" (${String(error.message).slice(0, 60)}) — looking for what covers the span`);
264
+ }
265
+ if (out.records.length === 0) {
266
+ // #60: a repair run after the first one finds the span ALREADY re-archived, so the re-read is
267
+ // a legitimate no-op — and the husk record would circulate forever. Hand it to whichever
268
+ // active chapter now covers its span instead of refusing.
269
+ const fresh = await store.get(opts.sessionId);
270
+ const cover = coveringChapter(fresh, f.target.fromSeq, f.target.toSeq, f.target.number);
271
+ if (cover.length === 0 || f.target.number === undefined) {
272
+ refused.push(`hollow-payload ch.${f.target.number}: the re-read rendered nothing (${out.skipped ?? 'no records'}) and no active chapter covers ${f.target.fromSeq}-${f.target.toSeq} — left in place, nothing was superseded`);
273
+ continue;
274
+ }
275
+ const marked = markSupersededBy(fresh, f.target.number, cover[0].number, 'hollow-payload');
276
+ if (marked.problem !== undefined) {
277
+ refused.push(`hollow-payload ch.${f.target.number}: ${marked.problem}`);
278
+ continue;
279
+ }
280
+ // #101: `mutate(id, () => snapshot)` is a stale `put` wearing a mutate's clothes — the fn must
281
+ // apply the change to the row mutate hands it, because another door may have committed between
282
+ // the `get` above and this write (measured once already: an enrichment put at 04:53:52.841
283
+ // rewound a compaction commit from 04:53:50.915). Re-derive from the fresh row; if the chapter
284
+ // we meant to supersede is gone or changed, refuse rather than resurrect a snapshot.
285
+ // captured, not re-read: `f.target.number` is proven non-undefined by the check above, and a
286
+ // closure cannot see that narrowing (a cast would have hidden the case where it ever changes).
287
+ const hollowTarget = f.target.number;
288
+ const hollowCover = cover[0].number;
289
+ await store.mutate(opts.sessionId, (live) => {
290
+ const re = markSupersededBy(live, hollowTarget, hollowCover, 'hollow-payload');
291
+ if (re.problem !== undefined) {
292
+ refused.push(`hollow-payload ch.${String(hollowTarget)}: ${re.problem} (row moved during repair)`);
293
+ return live;
294
+ }
295
+ return re.state;
296
+ });
297
+ journal.entries.push({ kind: 'registry', path: fresh.chapters.find((c) => c.number === f.target.number)?.path ?? `ch.${f.target.number}`, beforeSha: null, afterSha: cover[0].sha256 });
298
+ flush();
299
+ ports.log(`superseded hollow ch.${f.target.number} by ${cover.length} chapter(s) [${cover.map((c) => c.number).join(', ')}] that together carry seqs ${f.target.fromSeq}-${f.target.toSeq}`);
300
+ continue;
301
+ }
302
+ if (huskPath !== undefined)
303
+ await quarantine(huskPath);
304
+ journal.entries.push({ kind: 'write', path: out.records[0].path, beforeSha: null, afterSha: out.records[0].sha256 });
305
+ flush();
306
+ ports.log(`repaired hollow ch.${f.target.number} → ch.${out.records[0].number} (${out.records.length} chapter(s), seqs ${f.target.fromSeq}-${f.target.toSeq})`);
307
+ }
308
+ else if (f.class === 'never-archived-span' && f.target.fromSeq !== undefined && f.target.toSeq !== undefined) {
309
+ const out = await saveSession({
310
+ events: logEvents, sessionId: opts.sessionId, cwd, store, config,
311
+ span: { fromSeq: f.target.fromSeq, toSeq: f.target.toSeq },
312
+ attemptSalt: `repair:${journalId}`,
313
+ });
314
+ for (const r of out.records)
315
+ journal.entries.push({ kind: 'write', path: r.path, beforeSha: null, afterSha: r.sha256 });
316
+ flush();
317
+ if (out.records.length === 0)
318
+ refused.push(`never-archived-span ${f.target.fromSeq}-${f.target.toSeq}: rendered nothing (${out.skipped ?? 'unknown'})`);
319
+ else
320
+ ports.log(`archived the missed span ${f.target.fromSeq}-${f.target.toSeq} as ${out.records.length} chapter(s)`);
321
+ }
322
+ else if (f.class === 'dead-citation' && f.target.path !== undefined) {
323
+ // Satisfy the citation: render THAT manifest chapter's own span and write it AT the cited path.
324
+ const key = Object.keys(state0.plans ?? {}).find((k) => (state0.plans?.[k]?.chapters ?? []).some((c) => c.path === f.target.path));
325
+ const pc = key !== undefined ? state0.plans?.[key]?.chapters?.find((c) => c.path === f.target.path) : undefined;
326
+ if (pc === undefined) {
327
+ refused.push(`dead-citation ${f.target.path}: no manifest chapter carries its span`);
328
+ continue;
329
+ }
330
+ const out = await saveSession({
331
+ events: logEvents, sessionId: opts.sessionId, cwd, store, config,
332
+ span: { fromSeq: pc.startSeq, toSeq: pc.endSeq },
333
+ attemptSalt: `repair:${journalId}`,
334
+ });
335
+ const written = out.records[0];
336
+ if (written === undefined) {
337
+ refused.push(`dead-citation ${f.target.path}: the span rendered nothing (${out.skipped ?? 'no records'})`);
338
+ continue;
339
+ }
340
+ // The cited PATH is the promise; move the bytes onto it (a copy of the same content, same hash).
341
+ const fromAbs = resolveStoredPath(cwd, written.path);
342
+ const toAbs = resolveStoredPath(cwd, f.target.path);
343
+ if (fs.existsSync(fromAbs)) {
344
+ fs.mkdirSync(path.dirname(toAbs), { recursive: true });
345
+ fs.copyFileSync(fromAbs, toAbs);
346
+ journal.entries.push({ kind: 'write', path: toAbs, beforeSha: null, afterSha: sha256(fs.readFileSync(toAbs)) });
347
+ await store.mutate(opts.sessionId, (fresh) => ({
348
+ ...fresh,
349
+ chapters: fresh.chapters.map((c) => (c.number === written.number ? { ...c, path: f.target.path } : c)),
350
+ }));
351
+ flush();
352
+ ports.log(`dead citation satisfied: ${f.target.path} now exists with the re-rendered bytes (chapter ${written.number})`);
353
+ }
354
+ }
355
+ else if (f.class === 'unregistered-file' && f.target.path !== undefined) {
356
+ // The bytes ARE the archive; only the registry row was lost. Re-read the file's own
357
+ // frontmatter (the store's ONE parser, src/indexing.ts) and hand the row back. Nothing on disk
358
+ // moves — this is not a rewrite, it is the registry catching up with the store.
359
+ const relPath = f.target.path;
360
+ const absFile = path.join(cwd, relPath);
361
+ if (!fs.existsSync(absFile)) {
362
+ refused.push(`unregistered-file ${relPath}: vanished between audit and apply — re-run`);
363
+ continue;
364
+ }
365
+ const fm = parseFrontmatter(fs.readFileSync(absFile, 'utf8'));
366
+ const range = Array.isArray(fm.seqRange) ? fm.seqRange.map((x) => Number(x)) : [];
367
+ const num = /\/(\d{3})-/.exec(relPath)?.[1];
368
+ if (range.length !== 2 || Number.isNaN(range[0]) || num === undefined) {
369
+ refused.push(`unregistered-file ${relPath}: frontmatter has no usable seqRange — it cannot be re-registered honestly`);
370
+ continue;
371
+ }
372
+ const taken = state0.chapters.some((c) => c.number === Number(num));
373
+ if (taken) {
374
+ // Two files claiming one number is #59's twin. Choosing a winner is a HUMAN call: the loser's
375
+ // bytes stay, and the run says so instead of silently demoting knowledge.
376
+ refused.push(`unregistered-file ${relPath}: number ${Number(num)} is already carried by another record — a lost-update twin. Re-registering it would need a new number, which means renumbering a chapter; forbidden. A human decides which of the two survives.`);
377
+ continue;
378
+ }
379
+ const tokensField = typeof fm.tokens === 'string' ? Number(fm.tokens.split('#')[0]?.trim() ?? NaN) : NaN;
380
+ const record = {
381
+ number: Number(num),
382
+ path: relPath,
383
+ title: typeof fm.title === 'string' ? fm.title : relPath,
384
+ summary: typeof fm.summary === 'string' ? fm.summary : '',
385
+ startSeq: range[0], endSeq: range[1],
386
+ topics: Array.isArray(fm.topics) ? fm.topics : [],
387
+ // `messages` is NOT in chapter frontmatter. An absent field means "unknown"; writing 0 would
388
+ // claim a husk (render.ts: "absent for records written before counts existed — never a lying
389
+ // zero"), so it stays absent and the audit reads it as unknown, not as damage.
390
+ // The registry's anchor is the hash of the WHOLE file (archive.ts: "Hash the whole file, so
391
+ // verifyChapter() can re-check it with no knowledge of frontmatter layout"). The `sha256:`
392
+ // field INSIDE the frontmatter is a different thing — the body-hash that anchors enrichment —
393
+ // and copying it into the record made 162 honest re-registrations look tampered.
394
+ sha256: sha256(fs.readFileSync(absFile)),
395
+ estimatedTokens: Number.isFinite(tokensField) ? tokensField : 0,
396
+ artifacts: [],
397
+ repairs: [{ class: 'unregistered-file', over: 0, at: Date.now() }],
398
+ };
399
+ // append + counter-raise in ONE section: a re-registered number must never sit at or above
400
+ // `nextChapterNumber`, or the next door collides with it (#59's twin).
401
+ await store.mutate(opts.sessionId, (fresh) => raiseCounters(appendChapters(fresh, [record])));
402
+ journal.entries.push({ kind: 'registry', path: relPath, beforeSha: null, afterSha: record.sha256 });
403
+ flush();
404
+ ports.log(`re-registered ${relPath} (seqs ${record.startSeq}-${record.endSeq}, ${record.estimatedTokens} tokens) — file untouched, row restored`);
405
+ }
406
+ else if (f.class === 'unreleased-reservation') {
407
+ const key = /reservation (\S+) holds/.exec(f.detail)?.[1];
408
+ if (key !== undefined) {
409
+ await store.mutate(opts.sessionId, (st) => releaseReservation(st, key));
410
+ journal.entries.push({ kind: 'registry', path: opts.sessionId, beforeSha: null, afterSha: null });
411
+ flush();
412
+ ports.log(`released reservation ${key}`);
413
+ }
414
+ }
415
+ else if (f.class === 'ghost-plan-manifest') {
416
+ const key = /manifest (\S+) promises/.exec(f.detail)?.[1];
417
+ if (key !== undefined) {
418
+ await store.mutate(opts.sessionId, (st) => expireBookkeeping(st, [key]));
419
+ flush();
420
+ ports.log(`expired the ghost finalize manifest ${key} (its numbers stay spent)`);
421
+ }
422
+ }
423
+ else if (f.class === 'countervalue-drift') {
424
+ await store.mutate(opts.sessionId, (st) => raiseCounters(st));
425
+ flush();
426
+ ports.log('counters raised to the first unspent number (upward only)');
427
+ }
428
+ }
429
+ catch (error) {
430
+ // One bad finding must not abort the run — #59's poison-pill lesson, applied to repair itself.
431
+ ports.warn(`repair of ${f.class} (${opts.sessionId}) failed: ${String(error.message).slice(0, 140)}`);
432
+ refused.push(`${f.class}: failed — ${String(error.message).slice(0, 100)}`);
433
+ }
434
+ }
435
+ // the same call, the same inputs — see `auditNow` above
436
+ const after = auditNow(await store.get(opts.sessionId));
437
+ journal.completedAt = Date.now();
438
+ journal.findingsAfter = after.findings.length;
439
+ flush();
440
+ return { journalId, findingsBefore: before.findings, findingsAfter: after.findings, blindSpots: before.blindSpots, applied: journal.entries, refused };
441
+ }
442
+ /** Undo a whole applied run, newest entry first. Derived inverses — the journal is not trusted to describe itself. */
443
+ export async function restoreRepair(ports, journalId, sessionId) {
444
+ const { store, cwd, config } = ports;
445
+ const state = await store.get(sessionId);
446
+ const file = path.join(cwd, config.artifactStoreRoot, state.rootSession, 'repairs', `${journalId}.json`);
447
+ if (!fs.existsSync(file))
448
+ return { undone: 0, problems: [`no journal ${journalId} under ${path.dirname(file)}`] };
449
+ const journal = JSON.parse(fs.readFileSync(file, 'utf8'));
450
+ const at = (p) => path.isAbsolute(p) ? p : path.join(cwd, p);
451
+ const problems = [];
452
+ let undone = 0;
453
+ for (const entry of [...journal.entries].reverse()) {
454
+ const inverse = journalEntryInverse(entry);
455
+ const target = at(entry.path);
456
+ const moved = entry.to !== undefined ? at(entry.to) : undefined;
457
+ try {
458
+ if (inverse.undo === 'remove' && fs.existsSync(target)) {
459
+ // undoing a repair is a MOVE too: the bytes a repair wrote go to quarantine, they are not deleted
460
+ fs.mkdirSync(path.dirname(moved ?? target), { recursive: true });
461
+ fs.copyFileSync(target, moved ?? path.join(cwd, config.artifactStoreRoot, state.rootSession, '.repair-quarantine', path.basename(target)));
462
+ fs.rmSync(target);
463
+ undone += 1;
464
+ }
465
+ else if (inverse.undo === 'restore-from-quarantine' && moved !== undefined && fs.existsSync(moved) && !fs.existsSync(target)) {
466
+ fs.copyFileSync(moved, target);
467
+ undone += 1;
468
+ }
469
+ else if (inverse.undo === 'restore-registry-rev') {
470
+ problems.push(`registry change ${entry.path} cannot be un-applied by file restore — the row is append-only; run audit again to see what remains`);
471
+ }
472
+ }
473
+ catch (error) {
474
+ problems.push(`restore of ${entry.path} failed: ${String(error.message).slice(0, 100)}`);
475
+ }
476
+ }
477
+ // The RECORDS a repair committed stay: a restored file set is re-audited, never hand-reverted.
478
+ await store.mutate(sessionId, (fresh) => fresh);
479
+ return { undone, problems };
480
+ }
481
+ /**
482
+ * Bound a repair report so one command result cannot outgrow the archive (#117).
483
+ *
484
+ * Why this is a function and not arithmetic in the command: the same rule has to hold for the in-host
485
+ * `/chapters-repair` and the offline runner, and a decision that exists in two places is a decision that
486
+ * drifts (#59's lesson). Pure, so the three things that matter are rows rather than intentions — the count
487
+ * always survives, the withheld remainder is counted and named with a remedy, and a short report is not
488
+ * wrapped in ceremony.
489
+ *
490
+ * The trigger was measured: a 23-session dry-run printed 2,796 findings as ONE `command/done` result —
491
+ * 311 KB, an event larger than `2 × chapterTokenTarget` — which is what made that session permanently
492
+ * un-compactable by `chapters_continue`. Clipping is forbidden by invariant, so the only honest options were
493
+ * to stop generating the monster or to cap with a remedy. Both are here: the cap, and the count leading.
494
+ */
495
+ export function capReportLines(body, capLines) {
496
+ const cap = Math.max(1, Math.floor(capLines));
497
+ const withheld = Math.max(0, body.length - cap);
498
+ if (withheld === 0)
499
+ return { shown: [...body], withheld: 0, capLine: '' };
500
+ return {
501
+ shown: body.slice(0, cap),
502
+ withheld,
503
+ capLine: ` … report capped at ${String(cap)} of ${String(body.length)} lines (repairReportMaxLines) — ${String(withheld)} withheld, nothing dropped: per-session detail is /chapters-repair dry-run <session-id>, or raise the cap`,
504
+ };
505
+ }
506
+ //# sourceMappingURL=repair-run.js.map