@isaacriehm/cairn-core 0.4.3 → 0.6.0

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 (186) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/align-undo/index.d.ts +6 -0
  3. package/dist/align-undo/index.js +6 -0
  4. package/dist/align-undo/index.js.map +1 -0
  5. package/dist/align-undo/log.d.ts +53 -0
  6. package/dist/align-undo/log.js +162 -0
  7. package/dist/align-undo/log.js.map +1 -0
  8. package/dist/align-undo/undo.d.ts +65 -0
  9. package/dist/align-undo/undo.js +397 -0
  10. package/dist/align-undo/undo.js.map +1 -0
  11. package/dist/attention/bulk-accept.js +9 -22
  12. package/dist/attention/bulk-accept.js.map +1 -1
  13. package/dist/attention/dedup.js +1 -47
  14. package/dist/attention/dedup.js.map +1 -1
  15. package/dist/attention/serve/api.js +3 -17
  16. package/dist/attention/serve/api.js.map +1 -1
  17. package/dist/attention/serve/index.js +3 -3
  18. package/dist/attention/serve/index.js.map +1 -1
  19. package/dist/drain/drain.d.ts +77 -0
  20. package/dist/drain/drain.js +464 -0
  21. package/dist/drain/drain.js.map +1 -0
  22. package/dist/drain/index.d.ts +5 -0
  23. package/dist/drain/index.js +5 -0
  24. package/dist/drain/index.js.map +1 -0
  25. package/dist/fix-align/index.d.ts +7 -0
  26. package/dist/fix-align/index.js +6 -0
  27. package/dist/fix-align/index.js.map +1 -0
  28. package/dist/fix-align/run.d.ts +99 -0
  29. package/dist/fix-align/run.js +258 -0
  30. package/dist/fix-align/run.js.map +1 -0
  31. package/dist/fix-align/sentinel.d.ts +59 -0
  32. package/dist/fix-align/sentinel.js +149 -0
  33. package/dist/fix-align/sentinel.js.map +1 -0
  34. package/dist/fs.d.ts +5 -0
  35. package/dist/fs.js +11 -0
  36. package/dist/fs.js.map +1 -0
  37. package/dist/gc/apply.js +4 -4
  38. package/dist/gc/apply.js.map +1 -1
  39. package/dist/ground/alignment-pending.d.ts +28 -0
  40. package/dist/ground/alignment-pending.js +83 -0
  41. package/dist/ground/alignment-pending.js.map +1 -0
  42. package/dist/ground/anchor-map.d.ts +14 -0
  43. package/dist/ground/anchor-map.js +56 -0
  44. package/dist/ground/anchor-map.js.map +1 -0
  45. package/dist/ground/frontmatter.d.ts +12 -0
  46. package/dist/ground/frontmatter.js +28 -0
  47. package/dist/ground/frontmatter.js.map +1 -1
  48. package/dist/ground/index.d.ts +10 -3
  49. package/dist/ground/index.js +9 -3
  50. package/dist/ground/index.js.map +1 -1
  51. package/dist/ground/paths.d.ts +21 -0
  52. package/dist/ground/paths.js +43 -0
  53. package/dist/ground/paths.js.map +1 -1
  54. package/dist/ground/schemas.d.ts +201 -0
  55. package/dist/ground/schemas.js +135 -10
  56. package/dist/ground/schemas.js.map +1 -1
  57. package/dist/ground/scope-index.js +4 -4
  58. package/dist/ground/scope-index.js.map +1 -1
  59. package/dist/ground/slug.d.ts +60 -0
  60. package/dist/ground/slug.js +103 -0
  61. package/dist/ground/slug.js.map +1 -0
  62. package/dist/ground/sot-bindings.d.ts +14 -0
  63. package/dist/ground/sot-bindings.js +79 -0
  64. package/dist/ground/sot-bindings.js.map +1 -0
  65. package/dist/ground/sot-cache.d.ts +18 -0
  66. package/dist/ground/sot-cache.js +62 -0
  67. package/dist/ground/sot-cache.js.map +1 -0
  68. package/dist/ground/topic-index.d.ts +27 -0
  69. package/dist/ground/topic-index.js +82 -0
  70. package/dist/ground/topic-index.js.map +1 -0
  71. package/dist/hooks/post-tool-use/index.d.ts +2 -0
  72. package/dist/hooks/post-tool-use/index.js +1 -0
  73. package/dist/hooks/post-tool-use/index.js.map +1 -1
  74. package/dist/hooks/post-tool-use/sot-align.d.ts +166 -0
  75. package/dist/hooks/post-tool-use/sot-align.js +1306 -0
  76. package/dist/hooks/post-tool-use/sot-align.js.map +1 -0
  77. package/dist/hooks/pre-commit/index.d.ts +8 -0
  78. package/dist/hooks/pre-commit/index.js +8 -0
  79. package/dist/hooks/pre-commit/index.js.map +1 -0
  80. package/dist/hooks/pre-commit/sot-align-precommit.d.ts +60 -0
  81. package/dist/hooks/pre-commit/sot-align-precommit.js +221 -0
  82. package/dist/hooks/pre-commit/sot-align-precommit.js.map +1 -0
  83. package/dist/hooks/runners/session-start.js +41 -0
  84. package/dist/hooks/runners/session-start.js.map +1 -1
  85. package/dist/hooks/sot-align-common.d.ts +39 -0
  86. package/dist/hooks/sot-align-common.js +152 -0
  87. package/dist/hooks/sot-align-common.js.map +1 -0
  88. package/dist/index.d.ts +5 -0
  89. package/dist/index.js +5 -0
  90. package/dist/index.js.map +1 -1
  91. package/dist/init/index.d.ts +4 -2
  92. package/dist/init/index.js +2 -1
  93. package/dist/init/index.js.map +1 -1
  94. package/dist/init/ingest-docs.d.ts +30 -47
  95. package/dist/init/ingest-docs.js +113 -410
  96. package/dist/init/ingest-docs.js.map +1 -1
  97. package/dist/init/init.d.ts +8 -0
  98. package/dist/init/init.js +58 -29
  99. package/dist/init/init.js.map +1 -1
  100. package/dist/init/mapper.js +6 -6
  101. package/dist/init/mapper.js.map +1 -1
  102. package/dist/init/phases/5-brand.js +1 -1
  103. package/dist/init/phases/5-brand.js.map +1 -1
  104. package/dist/init/phases/5b-topic-index.d.ts +30 -0
  105. package/dist/init/phases/5b-topic-index.js +62 -0
  106. package/dist/init/phases/5b-topic-index.js.map +1 -0
  107. package/dist/init/phases/6-docs-ingest.d.ts +4 -5
  108. package/dist/init/phases/6-docs-ingest.js +5 -6
  109. package/dist/init/phases/6-docs-ingest.js.map +1 -1
  110. package/dist/init/phases/index.d.ts +2 -0
  111. package/dist/init/phases/index.js +1 -0
  112. package/dist/init/phases/index.js.map +1 -1
  113. package/dist/init/phases/parallel-678.d.ts +14 -17
  114. package/dist/init/phases/parallel-678.js +77 -98
  115. package/dist/init/phases/parallel-678.js.map +1 -1
  116. package/dist/init/phases/source-comments-output-io.d.ts +16 -10
  117. package/dist/init/phases/source-comments-output-io.js +7 -10
  118. package/dist/init/phases/source-comments-output-io.js.map +1 -1
  119. package/dist/init/phases/types.d.ts +1 -1
  120. package/dist/init/phases/types.js +1 -0
  121. package/dist/init/phases/types.js.map +1 -1
  122. package/dist/init/rules-merge/discover.d.ts +8 -3
  123. package/dist/init/rules-merge/discover.js +7 -3
  124. package/dist/init/rules-merge/discover.js.map +1 -1
  125. package/dist/init/rules-merge/ingest.d.ts +81 -28
  126. package/dist/init/rules-merge/ingest.js +456 -162
  127. package/dist/init/rules-merge/ingest.js.map +1 -1
  128. package/dist/init/sot-emit.d.ts +84 -0
  129. package/dist/init/sot-emit.js +214 -0
  130. package/dist/init/sot-emit.js.map +1 -0
  131. package/dist/init/source-comments/classify.d.ts +12 -10
  132. package/dist/init/source-comments/classify.js +13 -25
  133. package/dist/init/source-comments/classify.js.map +1 -1
  134. package/dist/init/source-comments/index.d.ts +1 -1
  135. package/dist/init/source-comments/index.js +1 -1
  136. package/dist/init/source-comments/index.js.map +1 -1
  137. package/dist/init/source-comments/ingest.d.ts +91 -67
  138. package/dist/init/source-comments/ingest.js +392 -361
  139. package/dist/init/source-comments/ingest.js.map +1 -1
  140. package/dist/init/topic-index/index.d.ts +36 -0
  141. package/dist/init/topic-index/index.js +46 -0
  142. package/dist/init/topic-index/index.js.map +1 -0
  143. package/dist/init/topic-index/judge.d.ts +20 -0
  144. package/dist/init/topic-index/judge.js +65 -0
  145. package/dist/init/topic-index/judge.js.map +1 -0
  146. package/dist/init/topic-index/resolve.d.ts +50 -0
  147. package/dist/init/topic-index/resolve.js +196 -0
  148. package/dist/init/topic-index/resolve.js.map +1 -0
  149. package/dist/init/topic-index/walk.d.ts +43 -0
  150. package/dist/init/topic-index/walk.js +293 -0
  151. package/dist/init/topic-index/walk.js.map +1 -0
  152. package/dist/mcp/schemas.d.ts +45 -8
  153. package/dist/mcp/schemas.js +43 -7
  154. package/dist/mcp/schemas.js.map +1 -1
  155. package/dist/mcp/tools/align-drain.d.ts +7 -0
  156. package/dist/mcp/tools/align-drain.js +26 -0
  157. package/dist/mcp/tools/align-drain.js.map +1 -0
  158. package/dist/mcp/tools/index.d.ts +1 -1
  159. package/dist/mcp/tools/index.js +3 -0
  160. package/dist/mcp/tools/index.js.map +1 -1
  161. package/dist/mcp/tools/init-phases.js +4 -1
  162. package/dist/mcp/tools/init-phases.js.map +1 -1
  163. package/dist/mcp/tools/record-decision.js +5 -2
  164. package/dist/mcp/tools/record-decision.js.map +1 -1
  165. package/dist/mcp/tools/resolve-attention.d.ts +2 -2
  166. package/dist/mcp/tools/resolve-attention.js +781 -5
  167. package/dist/mcp/tools/resolve-attention.js.map +1 -1
  168. package/dist/status-line/event-queue.d.ts +40 -0
  169. package/dist/status-line/event-queue.js +195 -0
  170. package/dist/status-line/event-queue.js.map +1 -0
  171. package/dist/status-line/format.d.ts +1 -1
  172. package/dist/status-line/format.js +49 -6
  173. package/dist/status-line/format.js.map +1 -1
  174. package/dist/status-line/index.d.ts +41 -0
  175. package/dist/status-line/index.js +14 -0
  176. package/dist/status-line/index.js.map +1 -1
  177. package/dist/status-line/reader.js +23 -18
  178. package/dist/status-line/reader.js.map +1 -1
  179. package/dist/status-line/writer.d.ts +1 -1
  180. package/dist/status-line/writer.js +5 -0
  181. package/dist/status-line/writer.js.map +1 -1
  182. package/dist/text/jaccard.d.ts +19 -0
  183. package/dist/text/jaccard.js +68 -0
  184. package/dist/text/jaccard.js.map +1 -0
  185. package/package.json +1 -1
  186. package/templates/.cairn/git-hooks/pre-commit +16 -3
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Layer A undo log + `cairn attention undo` runner. Plan §11.7.
3
+ */
4
+ export { AlignUndoEntry, alignUndoLogPath, appendAlignUndoEntry, pruneAlignUndoLog, readAlignUndoLog, } from "./log.js";
5
+ export { runAttentionUndo } from "./undo.js";
6
+ export type { UndoArgs, UndoEntryOutcome, UndoResult } from "./undo.js";
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Layer A undo log + `cairn attention undo` runner. Plan §11.7.
3
+ */
4
+ export { AlignUndoEntry, alignUndoLogPath, appendAlignUndoEntry, pruneAlignUndoLog, readAlignUndoLog, } from "./log.js";
5
+ export { runAttentionUndo } from "./undo.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/align-undo/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Layer A audit log for `cairn attention undo` (plan §11.7).
3
+ *
4
+ * Every Layer A auto-resolution (Tier 1 cite, Tier 2 same cite, Tier 3
5
+ * fresh DEC creation, augments-DEC/INV emission) appends one line to
6
+ * `.cairn/state/align-undo-log.jsonl`. The CLI command
7
+ * `cairn attention undo [--since <duration>]` reads recent entries and
8
+ * reverses them.
9
+ *
10
+ * The deviation from plan §11.7's literal "reads invalidation events
11
+ * from `.cairn/events/`" — invalidation events are designed for
12
+ * cross-session broadcast (kind, refs, source), not for carrying the
13
+ * (file, offset, original_raw) metadata that undo needs. Keeping the
14
+ * undo log separate avoids polluting the broadcast surface and lets
15
+ * the GC retention policy stay independent.
16
+ *
17
+ * Truncation policy: `cairn attention undo` rewrites the log keeping
18
+ * only entries OUTSIDE the undo window so re-running `undo` against
19
+ * the same window is idempotent.
20
+ */
21
+ import { z } from "zod";
22
+ export declare const AlignUndoEntry: z.ZodObject<{
23
+ ts: z.ZodString;
24
+ session_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
25
+ kind: z.ZodEnum<{
26
+ "tier1-cite": "tier1-cite";
27
+ "tier2-cite": "tier2-cite";
28
+ "tier3-creation": "tier3-creation";
29
+ augments: "augments";
30
+ }>;
31
+ file: z.ZodString;
32
+ start_offset: z.ZodNumber;
33
+ end_offset: z.ZodNumber;
34
+ original_raw: z.ZodString;
35
+ replacement: z.ZodString;
36
+ primary_id: z.ZodString;
37
+ primary_kind: z.ZodOptional<z.ZodEnum<{
38
+ DEC: "DEC";
39
+ INV: "INV";
40
+ }>>;
41
+ augments_existing_id: z.ZodOptional<z.ZodString>;
42
+ }, z.core.$strip>;
43
+ export type AlignUndoEntry = z.infer<typeof AlignUndoEntry>;
44
+ export declare function alignUndoLogPath(repoRoot: string): string;
45
+ export declare function appendAlignUndoEntry(repoRoot: string, entry: AlignUndoEntry): Promise<void>;
46
+ export declare function readAlignUndoLog(repoRoot: string): AlignUndoEntry[];
47
+ /**
48
+ * Rewrite the undo log keeping only the entries NOT in `undone`.
49
+ * Idempotency: running `cairn attention undo --since <window>` twice
50
+ * on the same window does nothing the second time because the entries
51
+ * inside the window have already been removed.
52
+ */
53
+ export declare function pruneAlignUndoLog(repoRoot: string, remaining: AlignUndoEntry[]): Promise<void>;
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Layer A audit log for `cairn attention undo` (plan §11.7).
3
+ *
4
+ * Every Layer A auto-resolution (Tier 1 cite, Tier 2 same cite, Tier 3
5
+ * fresh DEC creation, augments-DEC/INV emission) appends one line to
6
+ * `.cairn/state/align-undo-log.jsonl`. The CLI command
7
+ * `cairn attention undo [--since <duration>]` reads recent entries and
8
+ * reverses them.
9
+ *
10
+ * The deviation from plan §11.7's literal "reads invalidation events
11
+ * from `.cairn/events/`" — invalidation events are designed for
12
+ * cross-session broadcast (kind, refs, source), not for carrying the
13
+ * (file, offset, original_raw) metadata that undo needs. Keeping the
14
+ * undo log separate avoids polluting the broadcast surface and lets
15
+ * the GC retention policy stay independent.
16
+ *
17
+ * Truncation policy: `cairn attention undo` rewrites the log keeping
18
+ * only entries OUTSIDE the undo window so re-running `undo` against
19
+ * the same window is idempotent.
20
+ */
21
+ import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
22
+ import { dirname, join } from "node:path";
23
+ import { z } from "zod";
24
+ import { withWriteLock } from "../lock.js";
25
+ import { logger } from "../logger.js";
26
+ const log = logger("align-undo.log");
27
+ /**
28
+ * Drop entries older than this on the next append + GC sweep. Operators
29
+ * who never run `cairn attention undo` would otherwise accumulate one
30
+ * line per Layer A auto-resolution forever.
31
+ */
32
+ const MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;
33
+ /**
34
+ * Skip the read-rewrite GC pass when the log is below this line count
35
+ * — steady-state operators don't pay for the read on every append.
36
+ */
37
+ const GC_THRESHOLD_LINES = 256;
38
+ export const AlignUndoEntry = z.object({
39
+ ts: z.string(),
40
+ session_id: z.string().nullish(),
41
+ kind: z.enum(["tier1-cite", "tier2-cite", "tier3-creation", "augments"]),
42
+ file: z.string(),
43
+ start_offset: z.number(),
44
+ end_offset: z.number(),
45
+ /** Original prose block raw (incl. comment delimiters) before strip-replace. */
46
+ original_raw: z.string(),
47
+ /** Replacement that was inserted (e.g. `// §DEC-1234567`). */
48
+ replacement: z.string(),
49
+ /** DEC/INV id cited (tier1/tier2 cite) or freshly emitted (tier3 / augments). */
50
+ primary_id: z.string(),
51
+ /** For tier3-creation: was the freshly-emitted entity a DEC or INV? */
52
+ primary_kind: z.enum(["DEC", "INV"]).optional(),
53
+ /** For augments: the existing entity id that was augmented (its cite stays). */
54
+ augments_existing_id: z.string().optional(),
55
+ });
56
+ export function alignUndoLogPath(repoRoot) {
57
+ return join(repoRoot, ".cairn", "state", "align-undo-log.jsonl");
58
+ }
59
+ export async function appendAlignUndoEntry(repoRoot, entry) {
60
+ const validated = AlignUndoEntry.parse(entry);
61
+ const path = alignUndoLogPath(repoRoot);
62
+ // Wrap the read-trim-append cycle in the project write lock so two
63
+ // concurrent Layer A invocations (or a session running `cairn
64
+ // attention undo` in another shell) can't interleave a partial
65
+ // append against a rewrite.
66
+ await withWriteLock(repoRoot, () => {
67
+ try {
68
+ mkdirSync(dirname(path), { recursive: true });
69
+ const remaining = sweepStale(path);
70
+ if (remaining === null) {
71
+ appendFileSync(path, `${JSON.stringify(validated)}\n`, "utf8");
72
+ return;
73
+ }
74
+ remaining.push(validated);
75
+ writeFileSync(path, `${remaining.map((e) => JSON.stringify(e)).join("\n")}\n`, "utf8");
76
+ }
77
+ catch (err) {
78
+ log.warn({ err: err instanceof Error ? err.message : String(err) }, "align-undo log append failed");
79
+ }
80
+ });
81
+ }
82
+ /**
83
+ * Read the current log and drop entries older than `MAX_AGE_MS`.
84
+ * Returns the surviving entries when a GC pass actually ran, or `null`
85
+ * when the log is small enough to skip the rewrite (cheap append path).
86
+ */
87
+ function sweepStale(path) {
88
+ if (!existsSync(path))
89
+ return null;
90
+ let text;
91
+ try {
92
+ text = readFileSync(path, "utf8");
93
+ }
94
+ catch {
95
+ return null;
96
+ }
97
+ if (text.trim().length === 0)
98
+ return null;
99
+ const lines = text.split("\n").filter((line) => line.trim().length > 0);
100
+ if (lines.length < GC_THRESHOLD_LINES)
101
+ return null;
102
+ const cutoff = Date.now() - MAX_AGE_MS;
103
+ const surviving = [];
104
+ for (const line of lines) {
105
+ try {
106
+ const parsed = AlignUndoEntry.parse(JSON.parse(line));
107
+ const ts = Date.parse(parsed.ts);
108
+ if (Number.isFinite(ts) && ts >= cutoff)
109
+ surviving.push(parsed);
110
+ }
111
+ catch {
112
+ // Drop malformed entries on this GC pass.
113
+ }
114
+ }
115
+ return surviving;
116
+ }
117
+ export function readAlignUndoLog(repoRoot) {
118
+ const path = alignUndoLogPath(repoRoot);
119
+ if (!existsSync(path))
120
+ return [];
121
+ const text = readFileSync(path, "utf8");
122
+ if (text.trim().length === 0)
123
+ return [];
124
+ const out = [];
125
+ for (const line of text.split("\n")) {
126
+ const trimmed = line.trim();
127
+ if (trimmed.length === 0)
128
+ continue;
129
+ try {
130
+ out.push(AlignUndoEntry.parse(JSON.parse(trimmed)));
131
+ }
132
+ catch (err) {
133
+ log.warn({ err: err instanceof Error ? err.message : String(err) }, "skipping malformed align-undo entry");
134
+ }
135
+ }
136
+ return out;
137
+ }
138
+ /**
139
+ * Rewrite the undo log keeping only the entries NOT in `undone`.
140
+ * Idempotency: running `cairn attention undo --since <window>` twice
141
+ * on the same window does nothing the second time because the entries
142
+ * inside the window have already been removed.
143
+ */
144
+ export async function pruneAlignUndoLog(repoRoot, remaining) {
145
+ const path = alignUndoLogPath(repoRoot);
146
+ // Lock so a concurrent `appendAlignUndoEntry` from a parallel Layer A
147
+ // hook can't slip a write between our read and rewrite.
148
+ await withWriteLock(repoRoot, () => {
149
+ try {
150
+ mkdirSync(dirname(path), { recursive: true });
151
+ if (remaining.length === 0) {
152
+ writeFileSync(path, "", "utf8");
153
+ return;
154
+ }
155
+ writeFileSync(path, `${remaining.map((e) => JSON.stringify(e)).join("\n")}\n`, "utf8");
156
+ }
157
+ catch (err) {
158
+ log.warn({ err: err instanceof Error ? err.message : String(err) }, "align-undo log prune failed");
159
+ }
160
+ });
161
+ }
162
+ //# sourceMappingURL=log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/align-undo/log.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * `cairn attention undo` runner (plan §11.7).
3
+ *
4
+ * Reverses Layer A auto-resolutions logged at
5
+ * `.cairn/state/align-undo-log.jsonl`. The CLI passes `--since
6
+ * <duration>` (default 1h); only entries within the window are
7
+ * undone, the rest stay in the log.
8
+ *
9
+ * Reverses:
10
+ *
11
+ * - `tier1-cite` / `tier2-cite` — find the cite line in the current
12
+ * source, swap it back for the original prose block. Idempotent
13
+ * when the source has been hand-edited away from the cite already.
14
+ *
15
+ * - `tier3-creation` — delete the freshly-emitted DEC/INV file, drop
16
+ * its sot-bindings / sot-cache entries, clear the topic-index
17
+ * reference, refresh the affected ledger, and restore the source
18
+ * prose at the recorded offsets. All mutations run under
19
+ * `withWriteLock` so a parallel Layer A hook can't slip in
20
+ * mid-rollback.
21
+ *
22
+ * - `augments` — delete the sibling DEC/INV (steps mirror
23
+ * tier3-creation), then trim the double-cite line in source down to
24
+ * the existing-id cite (the augmented entity stays referenced).
25
+ *
26
+ * Idempotent: the runner truncates undone entries from the log so a
27
+ * second invocation against the same window is a no-op.
28
+ */
29
+ import { type AlignUndoEntry } from "./log.js";
30
+ export interface UndoArgs {
31
+ repoRoot: string;
32
+ /**
33
+ * Wall-clock window. Entries with `ts` newer than `now - sinceMs`
34
+ * are undone. Default 1h.
35
+ */
36
+ sinceMs?: number;
37
+ /** Dry-run: classify entries but do not modify source / log. */
38
+ dryRun?: boolean;
39
+ }
40
+ export interface UndoEntryOutcome {
41
+ entry: AlignUndoEntry;
42
+ /**
43
+ * - `reverted` — source was rewritten back to the original prose.
44
+ * - `already-reverted`— the cite token is no longer in source (operator beat us).
45
+ * - `not-supported` — kind requires manual surgery (tier3-creation, augments).
46
+ * - `source-missing` — source file no longer exists.
47
+ * - `error` — write failed (logged + reported).
48
+ */
49
+ status: "reverted" | "already-reverted" | "not-supported" | "source-missing" | "error";
50
+ detail?: string;
51
+ }
52
+ export interface UndoResult {
53
+ /** Total entries inside the undo window. */
54
+ windowEntries: number;
55
+ /** Entries left in the log because they were outside the window. */
56
+ outsideWindow: number;
57
+ /** Per-entry outcomes for everything inside the window. */
58
+ outcomes: UndoEntryOutcome[];
59
+ reverted: number;
60
+ alreadyReverted: number;
61
+ notSupported: number;
62
+ sourceMissing: number;
63
+ errors: number;
64
+ }
65
+ export declare function runAttentionUndo(args: UndoArgs): Promise<UndoResult>;