@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
package/lib/rules.d.ts ADDED
@@ -0,0 +1,267 @@
1
+ import { z } from 'zod';
2
+ export declare const RULE_STATUS: readonly ["proposed", "core", "revoked"];
3
+ export type RuleStatus = (typeof RULE_STATUS)[number];
4
+ /** §7.1: two tiers, one store. Absent scope on any file or record ⇒ `project`. */
5
+ export declare const RULE_SCOPE: readonly ["project", "session"];
6
+ export type RuleScope = (typeof RULE_SCOPE)[number];
7
+ /** How the bytes came to be: a person, the deterministic marker, or the model. */
8
+ export declare const RULE_DERIVED_FROM: readonly ["human", "marker", "model"];
9
+ export type RuleDerivedFrom = (typeof RULE_DERIVED_FROM)[number];
10
+ /**
11
+ * The WARRANT behind a rule — what a human reads when deciding whether to trust
12
+ * it (record §7.5, amended 2026-10-21). `stated` means a human sentence is behind
13
+ * the rule; `inferred` means the model judged that a standing order would help and
14
+ * nobody said it. BOTH govern by default, because the premise of the tier is that
15
+ * the human may not know the rule yet — the distinction is displayed, not used as
16
+ * a permission check. Requiring a human to have already said it would make this
17
+ * tier redundant with the deterministic `ADD RULE:` marker.
18
+ */
19
+ export declare const RULE_BASIS: readonly ["human", "marker", "stated", "inferred"];
20
+ export type RuleBasis = (typeof RULE_BASIS)[number];
21
+ export interface RuleRecord {
22
+ id: string;
23
+ projectKey: string;
24
+ number: number;
25
+ path: string;
26
+ category: string;
27
+ title: string;
28
+ sourceSession: string;
29
+ at: string;
30
+ /** §7.1 tier; absent ⇒ 'project' (the pre-#50 default). The `| undefined`
31
+ * unions are load-bearing: `exactOptionalPropertyTypes` is on, and this
32
+ * interface is what `ruleRecordSchema` types at the registry boundary. */
33
+ scope?: RuleScope | undefined;
34
+ /** session tier only: the session whose tree this rule belongs to (§7.5). */
35
+ session?: string | undefined;
36
+ /** §7.1 provenance; absent ⇒ 'human'. */
37
+ derivedFrom?: RuleDerivedFrom | undefined;
38
+ /** §7.4 always-rendered class; human-set only. */
39
+ pinned?: boolean | undefined;
40
+ /** §7.5 (amended 2026-10-21): review posture, NOT an evidence test. A mined
41
+ * rule is inert until this machine approves it only when `rulesAutoActivate` is
42
+ * off. The default is that it governs immediately — inferring a useful standing
43
+ * order IS the point of the tier. */
44
+ reviewOnly?: boolean | undefined;
45
+ /** §7.5: the warrant a human reads alongside the text. */
46
+ basis?: RuleBasis | undefined;
47
+ /** the chapter a mined rule came from (provenance for the review surface) */
48
+ chapter?: number | undefined;
49
+ }
50
+ export declare const ruleRecordSchema: z.ZodObject<{
51
+ id: z.ZodString;
52
+ projectKey: z.ZodString;
53
+ number: z.ZodNumber;
54
+ path: z.ZodString;
55
+ category: z.ZodString;
56
+ title: z.ZodString;
57
+ sourceSession: z.ZodString;
58
+ at: z.ZodString;
59
+ scope: z.ZodOptional<z.ZodEnum<{
60
+ project: "project";
61
+ session: "session";
62
+ }>>;
63
+ session: z.ZodOptional<z.ZodString>;
64
+ derivedFrom: z.ZodOptional<z.ZodEnum<{
65
+ model: "model";
66
+ human: "human";
67
+ marker: "marker";
68
+ }>>;
69
+ pinned: z.ZodOptional<z.ZodBoolean>;
70
+ reviewOnly: z.ZodOptional<z.ZodBoolean>;
71
+ basis: z.ZodOptional<z.ZodEnum<{
72
+ human: "human";
73
+ marker: "marker";
74
+ stated: "stated";
75
+ inferred: "inferred";
76
+ }>>;
77
+ chapter: z.ZodOptional<z.ZodNumber>;
78
+ }, z.core.$strip>;
79
+ export declare const ruleSlug: (category: string, title: string) => string;
80
+ export declare const rulePath: (storeRoot: string, harnessId: string, number: number, category: string, title: string) => string;
81
+ /** one write, ever: rules are proposed by their author and never rewritten (status rides facts) */
82
+ export declare function renderRuleFile(input: {
83
+ number: number;
84
+ category: string;
85
+ title: string;
86
+ sourceSession: string;
87
+ at: string;
88
+ body: string;
89
+ scope?: RuleScope | undefined;
90
+ session?: string | undefined;
91
+ derivedFrom?: RuleDerivedFrom | undefined;
92
+ pinned?: boolean | undefined;
93
+ reviewOnly?: boolean | undefined;
94
+ basis?: RuleBasis | undefined;
95
+ chapter?: number | undefined;
96
+ }): string;
97
+ export interface ParsedRule {
98
+ number: number;
99
+ category: string;
100
+ title: string;
101
+ fileStatus: RuleStatus;
102
+ sourceSession: string;
103
+ body: string;
104
+ scope: RuleScope;
105
+ session: string;
106
+ derivedFrom: RuleDerivedFrom;
107
+ pinned: boolean;
108
+ reviewOnly: boolean;
109
+ basis: RuleBasis;
110
+ chapter: number;
111
+ }
112
+ export declare function parseRuleFile(text: string): ParsedRule | null;
113
+ export interface RuleStatusFact {
114
+ rule: string;
115
+ status: RuleStatus;
116
+ at: string;
117
+ }
118
+ /** the machine's own facts, last-write-wins per rule (append-only file order) */
119
+ export declare function loadRuleStatusFacts(mirrorDir: string, harnessId: string): Map<string, RuleStatusFact>;
120
+ /** append-only, like every other curation write */
121
+ export declare function appendRuleStatusFact(mirrorDir: string, harnessId: string, fact: RuleStatusFact): void;
122
+ export declare function effectiveStatus(ruleId: string, facts: Map<string, RuleStatusFact>, fileStatus: RuleStatus): RuleStatus;
123
+ /**
124
+ * §7.4: a PIN is a curation fact, never a rewrite. Rule files are write-once
125
+ * (§1.3) and the append-only rule has no exceptions, so "always show this one"
126
+ * rides `edits/<harness>/curation.jsonl` as its own fact type — one writer per
127
+ * file, per-machine by construction, and a git-revertable line.
128
+ */
129
+ export interface RulePinFact {
130
+ rule: string;
131
+ pinned: boolean;
132
+ at: string;
133
+ }
134
+ export declare function appendRulePinFact(mirrorDir: string, harnessId: string, fact: RulePinFact): void;
135
+ /** the machine's pins, last-write-wins (so `unpin` is a later fact, not a delete) */
136
+ export declare function loadRulePins(mirrorDir: string, harnessId: string): Set<string>;
137
+ export interface MirrorRule {
138
+ id: string;
139
+ relPath: string;
140
+ status: RuleStatus;
141
+ category: string;
142
+ title: string;
143
+ body: string;
144
+ bodyTokens: number;
145
+ /** §7.1 tier. A session rule has no business appearing in the mirror (§7.5);
146
+ * if one does (a hand-copied pool, an older build), the builder still only
147
+ * renders session rules collected from the LOCAL store for this ancestor
148
+ * path — so a smuggled file cannot govern a head. */
149
+ scope: RuleScope;
150
+ session: string;
151
+ derivedFrom: RuleDerivedFrom;
152
+ pinned: boolean;
153
+ /** §7.5: inert pending review — set only when `rulesAutoActivate` is off */
154
+ reviewOnly: boolean;
155
+ basis: RuleBasis;
156
+ chapter: number;
157
+ }
158
+ /** every rule file the mirror knows for one project, with THIS machine's effective status */
159
+ export declare function collectMirrorRules(mirrorDir: string, projectKey: string, harnessId: string): MirrorRule[];
160
+ export type RulesSectionResult = {
161
+ kind: 'none';
162
+ } | {
163
+ kind: 'ok';
164
+ text: string;
165
+ tokens: number;
166
+ shown: {
167
+ project: number;
168
+ session: number;
169
+ };
170
+ withheld: {
171
+ project: number;
172
+ session: number;
173
+ };
174
+ } | {
175
+ kind: 'refusal';
176
+ reason: string;
177
+ perRule: Array<{
178
+ id: string;
179
+ tokens: number;
180
+ }>;
181
+ cap: number;
182
+ total: number;
183
+ };
184
+ /** §7.3 options. Every #50 field is optional: with none of them supplied the
185
+ * builder renders exactly what it rendered before #50 — which is what keeps the
186
+ * existing notice goldens, the four door call sites, and the tape corpus intact. */
187
+ export interface RulesSectionOptions {
188
+ projectKey: string;
189
+ harnessId: string;
190
+ budgetTokens: number;
191
+ /** local store root (`<cwd>/<storeRoot>`); supplies the session tier (§7.5). */
192
+ storeDir?: string | undefined;
193
+ /** this session's ancestor path, including itself (§7.5 activation). */
194
+ ancestorSessions?: ReadonlySet<string> | undefined;
195
+ /** §7.4 per-tier count caps; absent ⇒ unlimited (the pre-#50 behavior). */
196
+ projectCap?: number | undefined;
197
+ sessionCap?: number | undefined;
198
+ /** §7.4 relevance input: the archived span's topic signatures (or a query). */
199
+ relevanceTopics?: readonly string[] | undefined;
200
+ }
201
+ /**
202
+ * §7.4 selection: pinned first (ground rules are OLD — anything that ranks by
203
+ * recency or topicality evicts them first), then topicality when topics are
204
+ * supplied, then the pre-#50 category/id order. A pure function of the inputs,
205
+ * so two machines with the same files render the same head and the tapes stay
206
+ * stable.
207
+ */
208
+ export declare function selectRules(rules: readonly MirrorRule[], topics?: readonly string[]): MirrorRule[];
209
+ /** the rule ids a human switched off on THIS machine (both tiers) */
210
+ export declare function revokedRuleIds(mirrorDir: string, harnessId: string): Set<string>;
211
+ /**
212
+ * §7.5: session rules are collected from the LOCAL store, never from the pool
213
+ * mirror — they are not staged (`planStoreToRepo` skips `scope: session`), so
214
+ * the only place they exist is `<storeDir>/rules/<harness>/*.md`. Same parser,
215
+ * same id shape, so `list`, numbering and search stay one mechanism for both
216
+ * tiers.
217
+ */
218
+ export declare function collectStoreRules(storeDir: string, harnessId: string,
219
+ /** §7.5: this machine's `rule-status` facts, so a human `approve` can switch a
220
+ * SUGGESTED model rule on without rewriting the write-once file. */
221
+ facts?: Map<string, RuleStatusFact> | undefined): MirrorRule[];
222
+ /**
223
+ * §7.5 transport predicate: is this authored rule file part of the machine-local
224
+ * session tier? Reads it through the SAME parser the collectors use — one
225
+ * definition of `scope`, never a second lightweight guess that can drift from it.
226
+ * An unreadable or non-rule file is treated as project (staged), because the
227
+ * exclusion must be a decision about the session tier specifically, not a
228
+ * side-effect of a parse miss.
229
+ */
230
+ export declare function isSessionRuleFile(absPath: string): boolean;
231
+ /**
232
+ * §7.5 activation, DERIVED rather than approved: a session rule binds exactly
233
+ * one session tree — its own session must be on the current session's ancestor
234
+ * path — and a human `revoke` is the one fact that can switch it off (files are
235
+ * write-once, §1.3, so there is nothing else to edit).
236
+ */
237
+ export declare function sessionRuleActive(rule: MirrorRule,
238
+ /** `facts` is unused here (the caller resolves status into `rule.status`); it is
239
+ * accepted so both collectors and callers pass ONE options object around. */
240
+ opts: {
241
+ ancestorSessions: ReadonlySet<string>;
242
+ revoked: ReadonlySet<string>;
243
+ facts?: Map<string, RuleStatusFact> | undefined;
244
+ }): boolean;
245
+ /** The session-tier view for one rebuilt head: active rules, id-ordered. */
246
+ export declare function collectActiveSessionRules(storeDir: string, harnessId: string, opts: {
247
+ ancestorSessions: ReadonlySet<string>;
248
+ revoked: ReadonlySet<string>;
249
+ facts?: Map<string, RuleStatusFact> | undefined;
250
+ }): MirrorRule[];
251
+ /**
252
+ * §7.5 re-derivation and the capture path: scan text for the marker at LINE
253
+ * START and return the rule bodies, in order, deduped by exact body.
254
+ *
255
+ * Deterministic and model-free by contract (§1 invariant 1) — this is the
256
+ * per-turn path AND the rebuild-after-loss path, so it must never touch `ctx.llm`.
257
+ */
258
+ export declare function parseRuleMarkers(text: string, prefix: string): string[];
259
+ /**
260
+ * §7.3: the rules block a rebuilt head carries. `kind: 'none'` (no active rules
261
+ * and no corpus) MUST produce zero injected bytes at the call site — the tape
262
+ * corpus depends on it. Overflow of the TOKEN ceiling refuses with per-rule
263
+ * numbers, never clips (§1.2); a count CAP selects, and what it left out is
264
+ * ANNOUNCED, because silent selection would rebuild "lost in the noise" inside
265
+ * the fix for it.
266
+ */
267
+ export declare function buildRulesSection(mirrorDir: string, opts: RulesSectionOptions): RulesSectionResult;