daftari 1.20.0 → 1.22.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 (100) hide show
  1. package/CHANGELOG.md +89 -0
  2. package/README.md +4 -1
  3. package/dist/access/rbac.d.ts +1 -0
  4. package/dist/access/rbac.d.ts.map +1 -1
  5. package/dist/access/rbac.js +7 -0
  6. package/dist/access/rbac.js.map +1 -1
  7. package/dist/cli.d.ts.map +1 -1
  8. package/dist/cli.js +10 -0
  9. package/dist/cli.js.map +1 -1
  10. package/dist/consolidate/birth.d.ts +74 -0
  11. package/dist/consolidate/birth.d.ts.map +1 -0
  12. package/dist/consolidate/birth.js +253 -0
  13. package/dist/consolidate/birth.js.map +1 -0
  14. package/dist/consolidate/clocks.d.ts +15 -0
  15. package/dist/consolidate/clocks.d.ts.map +1 -0
  16. package/dist/consolidate/clocks.js +127 -0
  17. package/dist/consolidate/clocks.js.map +1 -0
  18. package/dist/consolidate/constants.d.ts +26 -0
  19. package/dist/consolidate/constants.d.ts.map +1 -0
  20. package/dist/consolidate/constants.js +83 -0
  21. package/dist/consolidate/constants.js.map +1 -0
  22. package/dist/consolidate/decorrelation.d.ts +69 -0
  23. package/dist/consolidate/decorrelation.d.ts.map +1 -0
  24. package/dist/consolidate/decorrelation.js +287 -0
  25. package/dist/consolidate/decorrelation.js.map +1 -0
  26. package/dist/consolidate/derivation-prompt.d.ts +28 -0
  27. package/dist/consolidate/derivation-prompt.d.ts.map +1 -0
  28. package/dist/consolidate/derivation-prompt.js +72 -0
  29. package/dist/consolidate/derivation-prompt.js.map +1 -0
  30. package/dist/consolidate/edge-write.d.ts +10 -0
  31. package/dist/consolidate/edge-write.d.ts.map +1 -0
  32. package/dist/consolidate/edge-write.js +76 -0
  33. package/dist/consolidate/edge-write.js.map +1 -0
  34. package/dist/consolidate/index.d.ts +2 -0
  35. package/dist/consolidate/index.d.ts.map +1 -0
  36. package/dist/consolidate/index.js +477 -0
  37. package/dist/consolidate/index.js.map +1 -0
  38. package/dist/consolidate/priority.d.ts +25 -0
  39. package/dist/consolidate/priority.d.ts.map +1 -0
  40. package/dist/consolidate/priority.js +103 -0
  41. package/dist/consolidate/priority.js.map +1 -0
  42. package/dist/consolidate/revision.d.ts +75 -0
  43. package/dist/consolidate/revision.d.ts.map +1 -0
  44. package/dist/consolidate/revision.js +232 -0
  45. package/dist/consolidate/revision.js.map +1 -0
  46. package/dist/consolidate/state.d.ts +10 -0
  47. package/dist/consolidate/state.d.ts.map +1 -0
  48. package/dist/consolidate/state.js +54 -0
  49. package/dist/consolidate/state.js.map +1 -0
  50. package/dist/curation/edges.d.ts +5 -0
  51. package/dist/curation/edges.d.ts.map +1 -1
  52. package/dist/curation/edges.js +82 -9
  53. package/dist/curation/edges.js.map +1 -1
  54. package/dist/curation/lint.d.ts +2 -0
  55. package/dist/curation/lint.d.ts.map +1 -1
  56. package/dist/curation/lint.js +5 -0
  57. package/dist/curation/lint.js.map +1 -1
  58. package/dist/curation/provenance.d.ts +1 -0
  59. package/dist/curation/provenance.d.ts.map +1 -1
  60. package/dist/curation/provenance.js +1 -0
  61. package/dist/curation/provenance.js.map +1 -1
  62. package/dist/curation/shadow.d.ts +58 -0
  63. package/dist/curation/shadow.d.ts.map +1 -0
  64. package/dist/curation/shadow.js +221 -0
  65. package/dist/curation/shadow.js.map +1 -0
  66. package/dist/eval/llm.d.ts +3 -1
  67. package/dist/eval/llm.d.ts.map +1 -1
  68. package/dist/eval/llm.js +6 -2
  69. package/dist/eval/llm.js.map +1 -1
  70. package/dist/index.js +1 -1
  71. package/dist/storage/index-db.d.ts +1 -0
  72. package/dist/storage/index-db.d.ts.map +1 -1
  73. package/dist/storage/index-db.js +14 -9
  74. package/dist/storage/index-db.js.map +1 -1
  75. package/dist/tools/curation.d.ts +2 -0
  76. package/dist/tools/curation.d.ts.map +1 -1
  77. package/dist/tools/curation.js +5 -1
  78. package/dist/tools/curation.js.map +1 -1
  79. package/dist/tools/edges.d.ts.map +1 -1
  80. package/dist/tools/edges.js +14 -10
  81. package/dist/tools/edges.js.map +1 -1
  82. package/dist/tools/staged-actions.d.ts +1 -0
  83. package/dist/tools/staged-actions.d.ts.map +1 -1
  84. package/dist/tools/staged-actions.js +18 -5
  85. package/dist/tools/staged-actions.js.map +1 -1
  86. package/dist/tools/write.d.ts +1 -0
  87. package/dist/tools/write.d.ts.map +1 -1
  88. package/dist/tools/write.js +93 -7
  89. package/dist/tools/write.js.map +1 -1
  90. package/dist/utils/config.d.ts +2 -0
  91. package/dist/utils/config.d.ts.map +1 -1
  92. package/dist/utils/config.js +17 -1
  93. package/dist/utils/config.js.map +1 -1
  94. package/dist/utils/git.d.ts +1 -0
  95. package/dist/utils/git.d.ts.map +1 -1
  96. package/dist/utils/git.js +19 -0
  97. package/dist/utils/git.js.map +1 -1
  98. package/package.json +1 -1
  99. package/templates/config.yaml +3 -0
  100. package/templates/reviewer-vault/.daftari/config.yaml +3 -0
@@ -0,0 +1,477 @@
1
+ // `daftari consolidate` — the cortex consolidation loop entrypoint.
2
+ //
3
+ // Stage 1 (shipped): computes the edge due-queue + birth queue at session
4
+ // start and prints them. No LLM, no writes.
5
+ // Stage 2 (this PR): adds Component A. With `--mode=birth|revision|both`,
6
+ // the LLM re-derives queue items and emits edge_observe/edge_contest. Under
7
+ // `shadow_mode: true` the writes are journaled, not applied (calibration
8
+ // posture, spec §11.5). The auto-write tier graduates in Stage 5.
9
+ //
10
+ // Default mode is `scan` (Stage 1 behavior): no LLM, no writes — backward
11
+ // compatible. Stage 2 modes are explicit opt-in so an unsuspecting cron
12
+ // invocation doesn't start spending money.
13
+ //
14
+ // Spec: docs/superpowers/specs/2026-06-13-cortex-consolidation-loop.md
15
+ // Brief: docs/superpowers/drafts/2026-06-16-cortex-stage-2-component-a-brief.md
16
+ import { existsSync } from "node:fs";
17
+ import { posix, resolve } from "node:path";
18
+ import { listEdges } from "../curation/edges.js";
19
+ import { addTension, listTensions } from "../curation/tension.js";
20
+ import { loadDocuments } from "../curation/vault-docs.js";
21
+ import { createAnthropicClient } from "../eval/llm.js";
22
+ import { err, ok } from "../frontmatter/types.js";
23
+ import { vaultSearchRelated } from "../tools/search.js";
24
+ import { loadConfig } from "../utils/config.js";
25
+ import { changedSince, log as gitLog, isGitRepo } from "../utils/git.js";
26
+ import { appendBirthTrace, birthOne, } from "./birth.js";
27
+ import { birthQueue, decayBackstopDue, eventDue } from "./clocks.js";
28
+ import { CONSOLIDATE_AGENT, CONSOLIDATE_DEFAULT_BUDGET, CONSOLIDATE_DEFAULT_MODEL, CONSOLIDATE_PANEL_SIZE, estimateCostUSD, isModelPriced, } from "./constants.js";
29
+ import { formatDecorrelationReport, loadFixture, runDecorrelation } from "./decorrelation.js";
30
+ import { makeContest, makeObserve } from "./edge-write.js";
31
+ import { prioritize } from "./priority.js";
32
+ import { appendRevisionTrace, revisionPanel, } from "./revision.js";
33
+ import { readConsolidateState, writeConsolidateState } from "./state.js";
34
+ const HELP = `daftari consolidate — cortex loop scheduler + Component A (shadow-only).
35
+
36
+ Usage:
37
+ daftari consolidate [--vault <path>] [--budget <n>] [--mode <m>]
38
+ [--max-panels <n>] [--max-births <n>] [--model <id>]
39
+ daftari consolidate --report decorrelation --fixture <path> [--model <id>]
40
+
41
+ Modes (--mode, default 'scan'):
42
+ scan Stage 1: emit the edge due-queue + birth queue. No LLM, no writes.
43
+ birth Stage 2: re-derive each unprocessed doc's top-K neighbors and
44
+ edge_observe the survivors as k=0 candidates. (Requires
45
+ ANTHROPIC_API_KEY.)
46
+ revision Stage 2: cast an M-vote panel on each due edge, emit edge_observe
47
+ (survives) or edge_contest (fails) per vote.
48
+ both birth then revision (the full pass).
49
+
50
+ Stage 2 modes call the LLM and emit edge writes. Under shadow_mode:true those
51
+ writes go to .daftari/shadow-actions.jsonl, not .daftari/edges.jsonl. With
52
+ shadow_mode off, edge_observe/contest land for real — but Stage 2 ships with
53
+ NO auto-write graduation, so even off-shadow only the auto-write tier from
54
+ spec §4.2 lands (link / confidence-down / tension_log / contest revoke).
55
+
56
+ What it does:
57
+ Computes three clocks (event / decay / backstop) over the derives_from edge
58
+ store + git history at session start, ranks the due work into four slices
59
+ under a compute budget, then (mode != scan) runs Component A on those
60
+ items. The trace files (.daftari/{birth,revision}-trace.jsonl) are the
61
+ decorrelation report's input (brief item 8).
62
+
63
+ Reports:
64
+ --report decorrelation --fixture <path>
65
+ Run the shared foundational-ordering prompt against a ground-truth-labeled
66
+ fixture (brief item 8). Reports per-axis + majority accuracy, lift
67
+ (informational — the axes are identical under the deterministic prompt),
68
+ inter-axis agreement, error correlation. PASS/FAIL gates on ACCURACY: exits
69
+ 6 if majority accuracy < CONSOLIDATE_DIRECTION_MIN_ACCURACY (the foundational
70
+ prompt did not recover direction well enough — fix the elicitation/fixture).
71
+ Requires ANTHROPIC_API_KEY. A real fixture lives at
72
+ tests/fixtures/decorrelation-fixture-v2.json.
73
+
74
+ Exit codes:
75
+ 0 — ran cleanly
76
+ 2 — config error (no vault, bad flags, missing ANTHROPIC_API_KEY in LLM mode)
77
+ 3 — runtime error (edge store / vault I/O)
78
+ 4 — ran, but backstop-overdue work was left unserved (cron-alertable)
79
+ 5 — ran, but one or more trace writes failed (recall-evaluation data lost)
80
+ 6 — decorrelation report ran, accuracy below the gate (fix elicitation/fixture)
81
+ 7 — ran, but the event-clock baseline was unreachable (gap skipped, re-baselined to HEAD)
82
+ `;
83
+ const MS_PER_DAY = 86_400_000;
84
+ function flag(argv, name) {
85
+ const i = argv.indexOf(`--${name}`);
86
+ return i >= 0 && i + 1 < argv.length ? argv[i + 1] : undefined;
87
+ }
88
+ // Canonicalize a vault-relative path so the three joins (edge paths ↔ git-diff
89
+ // paths ↔ loaded-doc paths) key consistently. The edge store stores caller
90
+ // paths with only .trim() applied; an alias like `a/../a/x.md` or `./x.md`
91
+ // could otherwise silently miss the byPremise/birth join.
92
+ function canon(p) {
93
+ return posix.normalize(p).replace(/^\.\//, "");
94
+ }
95
+ const VALID_MODES = new Set(["scan", "birth", "revision", "both"]);
96
+ export async function runConsolidate(argv) {
97
+ if (argv.includes("--help") || argv.includes("-h")) {
98
+ process.stdout.write(HELP);
99
+ return 0;
100
+ }
101
+ // --report=decorrelation is an alternate entry point: no vault scan, no
102
+ // queue, no Component A — just runs the v1 axes against the fixture and
103
+ // emits the analysis. Branches early so the main consolidate flow stays
104
+ // unchanged.
105
+ const reportName = flag(argv, "report");
106
+ if (reportName === "decorrelation") {
107
+ return runDecorrelationReportCli(argv);
108
+ }
109
+ if (reportName !== undefined) {
110
+ process.stderr.write(`consolidate: --report must be 'decorrelation', got ${reportName}\n`);
111
+ return 2;
112
+ }
113
+ try {
114
+ const vaultRoot = resolve(flag(argv, "vault") ?? process.cwd());
115
+ if (!existsSync(vaultRoot)) {
116
+ process.stderr.write(`consolidate: no vault at ${vaultRoot}\n`);
117
+ return 2;
118
+ }
119
+ const budget = Number(flag(argv, "budget") ?? CONSOLIDATE_DEFAULT_BUDGET);
120
+ if (!Number.isFinite(budget) || budget <= 0) {
121
+ process.stderr.write("consolidate: --budget must be a number > 0\n");
122
+ return 2;
123
+ }
124
+ const modeStr = (flag(argv, "mode") ?? "scan").toLowerCase();
125
+ if (!VALID_MODES.has(modeStr)) {
126
+ process.stderr.write(`consolidate: --mode must be one of scan|birth|revision|both, got ${modeStr}\n`);
127
+ return 2;
128
+ }
129
+ const mode = modeStr;
130
+ const maxBirths = parseOptionalInt(flag(argv, "max-births"));
131
+ if (maxBirths.error) {
132
+ process.stderr.write(`consolidate: ${maxBirths.error}\n`);
133
+ return 2;
134
+ }
135
+ const maxPanels = parseOptionalInt(flag(argv, "max-panels"));
136
+ if (maxPanels.error) {
137
+ process.stderr.write(`consolidate: ${maxPanels.error}\n`);
138
+ return 2;
139
+ }
140
+ const model = flag(argv, "model") ?? CONSOLIDATE_DEFAULT_MODEL;
141
+ const now = new Date();
142
+ const state = readConsolidateState(vaultRoot);
143
+ const edgesRes = await listEdges(vaultRoot, {}, now);
144
+ if (!edgesRes.ok) {
145
+ process.stderr.write(`consolidate: ${edgesRes.error.message}\n`);
146
+ return 3;
147
+ }
148
+ const edges = edgesRes.value.map((e) => ({
149
+ ...e,
150
+ fromPath: canon(e.fromPath),
151
+ toPath: canon(e.toPath),
152
+ }));
153
+ const edgeByKey = new Map();
154
+ for (const e of edges)
155
+ edgeByKey.set(`${e.fromPath}\n${e.toPath}`, e);
156
+ const docsRes = await loadDocuments(vaultRoot);
157
+ if (!docsRes.ok) {
158
+ process.stderr.write(`consolidate: ${docsRes.error.message}\n`);
159
+ return 3;
160
+ }
161
+ const docs = docsRes.value.map((d) => ({ relPath: canon(d.path), content: d.content }));
162
+ const docByPath = new Map();
163
+ for (const d of docs)
164
+ docByPath.set(d.relPath, d);
165
+ const birthProcessed = {};
166
+ for (const [k, v] of Object.entries(state.birthProcessed))
167
+ birthProcessed[canon(k)] = v;
168
+ const inRepo = await isGitRepo(vaultRoot);
169
+ let eventEdges = [];
170
+ let staleBaseline = false;
171
+ if (state.lastConsolidationCommit && inRepo) {
172
+ const changed = await changedSince(vaultRoot, state.lastConsolidationCommit);
173
+ if (changed.ok)
174
+ eventEdges = eventDue(changed.value.map(canon), edges);
175
+ else {
176
+ // The stored baseline commit is unreachable (rebase / force-push / GC /
177
+ // re-clone). The event clock can't run for the gap — it re-baselines to
178
+ // HEAD below (the decay+backstop clock will still re-derive those edges
179
+ // within the cap), but the gap is NOT event-examined, so we surface a
180
+ // non-zero exit (7) rather than silently exit 0 as if all was covered.
181
+ staleBaseline = true;
182
+ process.stderr.write(`consolidate: stale baseline ${state.lastConsolidationCommit} — event clock skipped, ` +
183
+ `re-baselining to HEAD (gap relies on the backstop clock; exit 7)\n`);
184
+ }
185
+ }
186
+ const decayEdges = decayBackstopDue(edges, now);
187
+ const birth = birthQueue(docs, birthProcessed);
188
+ const ages = {};
189
+ for (const e of edges) {
190
+ ages[e.fromPath] = (now.getTime() - new Date(e.lastRederived).getTime()) / MS_PER_DAY;
191
+ }
192
+ const { queue, backstopOverdueRemaining } = prioritize({
193
+ edgeDue: [...eventEdges, ...decayEdges],
194
+ birth,
195
+ budget,
196
+ ages,
197
+ });
198
+ const edgeItems = queue.filter((q) => q.kind === "edge");
199
+ const birthItems = queue.filter((q) => q.kind === "birth");
200
+ // --- report header (mode-independent) -------------------------------------
201
+ let report = `consolidate @ ${vaultRoot}\n`;
202
+ report += ` edges: ${edges.length} | docs: ${docs.length} | budget: ${budget} | mode: ${mode}\n`;
203
+ report += ` edge due-queue (${edgeItems.length}):\n`;
204
+ for (const q of edgeItems) {
205
+ if (q.kind === "edge")
206
+ report += ` [${q.slice}/${q.reason}] ${q.fromPath} ← ${q.toPath}\n`;
207
+ }
208
+ report += ` birth queue (${birthItems.length}):\n`;
209
+ for (const q of birthItems) {
210
+ if (q.kind === "birth")
211
+ report += ` [birth] ${q.path}\n`;
212
+ }
213
+ report += ` backstop-overdue remaining: ${backstopOverdueRemaining}\n`;
214
+ // --- Stage 2: Component A dispatch ---------------------------------------
215
+ const stage2 = emptyStage2();
216
+ if (mode !== "scan") {
217
+ const cfg = await loadConfig(vaultRoot);
218
+ if (!cfg.ok) {
219
+ process.stderr.write(`consolidate: ${cfg.error.message}\n`);
220
+ return 2;
221
+ }
222
+ // ANTHROPIC_API_KEY check before constructing the client — fail-fast with
223
+ // a clear message rather than the SDK's terse internal throw.
224
+ if (!process.env.ANTHROPIC_API_KEY) {
225
+ process.stderr.write("consolidate: ANTHROPIC_API_KEY env var is required for --mode != scan\n");
226
+ return 2;
227
+ }
228
+ let llm;
229
+ try {
230
+ llm = createAnthropicClient();
231
+ }
232
+ catch (e) {
233
+ process.stderr.write(`consolidate: ${e instanceof Error ? e.message : String(e)}\n`);
234
+ return 2;
235
+ }
236
+ stage2.shadowMode = cfg.value.shadowMode;
237
+ const observe = makeObserve({
238
+ vaultRoot,
239
+ shadowMode: cfg.value.shadowMode,
240
+ principal: CONSOLIDATE_AGENT,
241
+ });
242
+ const contest = makeContest({
243
+ vaultRoot,
244
+ shadowMode: cfg.value.shadowMode,
245
+ principal: CONSOLIDATE_AGENT,
246
+ });
247
+ if (mode === "birth" || mode === "both") {
248
+ const cap = maxBirths.value ?? Number.POSITIVE_INFINITY;
249
+ const birthOnly = birthItems
250
+ .filter((q) => q.kind === "birth")
251
+ .slice(0, Math.min(birthItems.length, cap));
252
+ await runBirthLoop(birthOnly, docByPath, observe, llm, vaultRoot, model, stage2, birthProcessed);
253
+ }
254
+ if (mode === "revision" || mode === "both") {
255
+ const cap = maxPanels.value ?? Number.POSITIVE_INFINITY;
256
+ const edgeOnly = edgeItems
257
+ .filter((q) => q.kind === "edge")
258
+ .slice(0, Math.min(edgeItems.length, cap));
259
+ await runRevisionLoop(edgeOnly, edgeByKey, docByPath, observe, contest, llm, vaultRoot, model, stage2);
260
+ }
261
+ report += ` Component A (${mode}):\n`;
262
+ report += ` births_processed: ${stage2.birthsProcessed}\n`;
263
+ report += ` panels_cast: ${stage2.panelsCast} | votes_cast: ${stage2.votesCast}\n`;
264
+ report += ` observed: ${stage2.observedTotal} | contested: ${stage2.contestedTotal}\n`;
265
+ report += ` llm_calls: ${stage2.llmCalls} | tokens: ${stage2.inputTokens}/${stage2.outputTokens} in/out\n`;
266
+ report += ` est_cost_usd: ${estimateCostUSD(model, stage2.inputTokens, stage2.outputTokens).toFixed(4)} (${model})${isModelPriced(model) ? "" : " [pricing_fallback: haiku — model unpriced]"}\n`;
267
+ if (stage2.traceWriteFailures > 0) {
268
+ report += ` trace_write_failures: ${stage2.traceWriteFailures} — recall@K evaluator input lost (exit 5)\n`;
269
+ }
270
+ if (stage2.shadowMode) {
271
+ report += ` shadow_mode: true — edge writes journaled to shadow-actions.jsonl, store untouched\n`;
272
+ }
273
+ }
274
+ process.stdout.write(report);
275
+ // --- persist state -------------------------------------------------------
276
+ // Always persist birthProcessed (Stage 2 progress is independent of git).
277
+ // Only advance the event-clock baseline (lastConsolidationCommit) when we
278
+ // have a HEAD; in a non-git dir we keep the prior value (likely null) so
279
+ // the event clock stays in the nil-path on every run.
280
+ let newCommit = state.lastConsolidationCommit;
281
+ if (inRepo) {
282
+ const head = await gitLog(vaultRoot, { limit: 1 });
283
+ if (head.ok && head.value[0])
284
+ newCommit = head.value[0].hash;
285
+ }
286
+ const wrote = writeConsolidateState(vaultRoot, {
287
+ ...state,
288
+ lastConsolidationCommit: newCommit,
289
+ birthProcessed,
290
+ });
291
+ if (!wrote.ok)
292
+ process.stderr.write(`consolidate: ${wrote.error.message}\n`);
293
+ // --- exit code hierarchy --------------------------------------------------
294
+ // 5 (trace lost) > 4 (backstop unserved) > 7 (event-clock baseline lost) > 0.
295
+ // Trace loss silently corrupts the calibration data flow (most serious);
296
+ // backstop-overdue and a lost baseline are cron-alertable warnings the next
297
+ // session / a human can resolve.
298
+ if (stage2.traceWriteFailures > 0)
299
+ return 5;
300
+ if (backstopOverdueRemaining > 0)
301
+ return 4;
302
+ return staleBaseline ? 7 : 0;
303
+ }
304
+ catch (e) {
305
+ process.stderr.write(`${e instanceof Error ? e.message : String(e)}\n`);
306
+ return 2;
307
+ }
308
+ }
309
+ // --- helpers -----------------------------------------------------------------
310
+ function parseOptionalInt(raw) {
311
+ if (raw === undefined)
312
+ return { value: null };
313
+ const n = Number(raw);
314
+ if (!Number.isFinite(n) || n < 0 || !Number.isInteger(n)) {
315
+ return { value: null, error: `expected a non-negative integer, got ${JSON.stringify(raw)}` };
316
+ }
317
+ return { value: n };
318
+ }
319
+ function emptyStage2() {
320
+ return {
321
+ birthsProcessed: 0,
322
+ panelsCast: 0,
323
+ votesCast: 0,
324
+ observedTotal: 0,
325
+ contestedTotal: 0,
326
+ llmCalls: 0,
327
+ inputTokens: 0,
328
+ outputTokens: 0,
329
+ traceWriteFailures: 0,
330
+ shadowMode: false,
331
+ };
332
+ }
333
+ async function runBirthLoop(birthItems, docByPath, observe, llm, vaultRoot, model, stage2, birthProcessed) {
334
+ const searchNeighbors = async (docPath, k) => {
335
+ const r = await vaultSearchRelated(vaultRoot, { path: docPath, limit: k });
336
+ if (!r.ok)
337
+ return r;
338
+ return ok(r.value.hits.map((h) => h.path));
339
+ };
340
+ // Neighbor content is already in process (the docs map) — no disk read.
341
+ const loadNeighborContent = async (path) => {
342
+ const d = docByPath.get(canon(path));
343
+ return d ? ok(d.content) : err(new Error(`neighbor not in docs map: ${path}`));
344
+ };
345
+ // Direction-pending tensions are authored under the loop principal. Dedup on
346
+ // the canonical title (mirrors vaultEdgeContest): a doc re-births on every
347
+ // edit, so without this an unresolved direction-pending pair would re-append
348
+ // an identical tension on each re-birth and flood the advisory log.
349
+ const recordTension = async (input) => {
350
+ const existing = await listTensions(vaultRoot);
351
+ if (existing.ok && existing.value.some((t) => t.title === input.title && !t.resolved)) {
352
+ return ok(undefined); // already open for this pair — don't stack a duplicate
353
+ }
354
+ return addTension(vaultRoot, input);
355
+ };
356
+ const recordBirthTrace = (row) => appendBirthTrace(vaultRoot, row);
357
+ const opts = {
358
+ vaultRoot,
359
+ agent: CONSOLIDATE_AGENT,
360
+ axis: "forward",
361
+ budgetRemaining: Number.POSITIVE_INFINITY,
362
+ model,
363
+ };
364
+ for (const item of birthItems) {
365
+ const docPath = canon(item.path);
366
+ const doc = docByPath.get(docPath);
367
+ if (!doc)
368
+ continue; // queue → docs is reconstructible; a missing doc is non-fatal
369
+ const out = await birthOne(doc, { llm, searchNeighbors, loadNeighborContent, observe, recordTension, recordBirthTrace }, opts);
370
+ if (!out.ok) {
371
+ process.stderr.write(`consolidate: birth failed for ${docPath}: ${out.error.message}\n`);
372
+ continue;
373
+ }
374
+ accumulateBirth(stage2, out.value);
375
+ // Only mark the doc processed if its trace landed. A failed trace write
376
+ // (exit 5) must NOT be permanent: birthProcessed is keyed on content-hash, so
377
+ // marking it here would stop the doc ever re-birthing and the recall@K trace
378
+ // row — the whole reason birth mode exists — would be lost unrecoverably.
379
+ if (out.value.traceWritten)
380
+ birthProcessed[docPath] = out.value.contentHash;
381
+ }
382
+ }
383
+ function accumulateBirth(stage2, out) {
384
+ stage2.birthsProcessed++;
385
+ stage2.observedTotal += out.observations.length;
386
+ stage2.llmCalls += out.llmCalls;
387
+ stage2.inputTokens += out.inputTokens;
388
+ stage2.outputTokens += out.outputTokens;
389
+ if (!out.traceWritten)
390
+ stage2.traceWriteFailures++;
391
+ }
392
+ async function runRevisionLoop(edgeItems, edgeByKey, docByPath, observe, contest, llm, vaultRoot, model, stage2) {
393
+ const loadDoc = async (path) => {
394
+ const d = docByPath.get(canon(path));
395
+ if (!d) {
396
+ return { ok: false, error: new Error(`doc not in load set: ${path}`) };
397
+ }
398
+ return ok({ path: d.relPath, content: d.content });
399
+ };
400
+ const recordRevisionTrace = (row) => appendRevisionTrace(vaultRoot, row);
401
+ const opts = {
402
+ vaultRoot,
403
+ agent: CONSOLIDATE_AGENT,
404
+ panelSize: CONSOLIDATE_PANEL_SIZE,
405
+ budgetRemaining: Number.POSITIVE_INFINITY,
406
+ model,
407
+ };
408
+ for (const item of edgeItems) {
409
+ const key = `${canon(item.fromPath)}\n${canon(item.toPath)}`;
410
+ const edge = edgeByKey.get(key);
411
+ if (!edge)
412
+ continue;
413
+ // Defensive: the clocks already exclude direction-symmetric edges from the
414
+ // due-list, but the revision panel votes on a FIXED from→to direction and
415
+ // has no symmetric guard of its own. Keep the invariant next to the consumer
416
+ // so a future due-path (e.g. the deferred TTL clock) can't feed a pending
417
+ // edge into a directional verdict.
418
+ if (edge.directionVerdict === "symmetric")
419
+ continue;
420
+ const out = await revisionPanel(edge, { llm, loadDoc, observe, contest, recordRevisionTrace }, opts);
421
+ if (!out.ok) {
422
+ process.stderr.write(`consolidate: revision failed for ${key.replace("\n", "←")}: ${out.error.message}\n`);
423
+ continue;
424
+ }
425
+ accumulateRevision(stage2, out.value);
426
+ }
427
+ }
428
+ function accumulateRevision(stage2, out) {
429
+ stage2.panelsCast++;
430
+ stage2.votesCast += out.votes.length;
431
+ stage2.observedTotal += out.observedCount;
432
+ stage2.contestedTotal += out.contestedCount;
433
+ stage2.llmCalls += out.llmCalls;
434
+ stage2.inputTokens += out.inputTokens;
435
+ stage2.outputTokens += out.outputTokens;
436
+ if (!out.traceWritten)
437
+ stage2.traceWriteFailures++;
438
+ }
439
+ // --- --report=decorrelation ---------------------------------------------------
440
+ async function runDecorrelationReportCli(argv) {
441
+ const fixturePath = flag(argv, "fixture");
442
+ if (!fixturePath) {
443
+ process.stderr.write("consolidate --report decorrelation: --fixture <path> is required\n");
444
+ return 2;
445
+ }
446
+ if (!process.env.ANTHROPIC_API_KEY) {
447
+ process.stderr.write("consolidate --report decorrelation: ANTHROPIC_API_KEY env var is required\n");
448
+ return 2;
449
+ }
450
+ const fixtureRes = loadFixture(fixturePath);
451
+ if (!fixtureRes.ok) {
452
+ process.stderr.write(`consolidate: ${fixtureRes.error.message}\n`);
453
+ return 2;
454
+ }
455
+ if (fixtureRes.value.edges.length === 0) {
456
+ process.stderr.write("consolidate: fixture is empty\n");
457
+ return 2;
458
+ }
459
+ let llm;
460
+ try {
461
+ llm = createAnthropicClient();
462
+ }
463
+ catch (e) {
464
+ process.stderr.write(`consolidate: ${e instanceof Error ? e.message : String(e)}\n`);
465
+ return 2;
466
+ }
467
+ const model = flag(argv, "model") ?? CONSOLIDATE_DEFAULT_MODEL;
468
+ const reportRes = await runDecorrelation(fixtureRes.value, { llm }, { model, fixtureSource: fixturePath });
469
+ if (!reportRes.ok) {
470
+ process.stderr.write(`consolidate: ${reportRes.error.message}\n`);
471
+ return 3;
472
+ }
473
+ process.stdout.write(formatDecorrelationReport(reportRes.value));
474
+ // Kill condition fires → exit 6 so CI / a calibration wrapper can branch.
475
+ return reportRes.value.passes ? 0 : 6;
476
+ }
477
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/consolidate/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { DueEdge } from "./clocks.js";
2
+ export type Slice = "backstop" | "main" | "periphery" | "birth";
3
+ export type QueueItem = {
4
+ kind: "edge";
5
+ fromPath: string;
6
+ toPath: string;
7
+ reason: DueEdge["reason"];
8
+ slice: Slice;
9
+ } | {
10
+ kind: "birth";
11
+ path: string;
12
+ slice: "birth";
13
+ };
14
+ export interface PrioritizeInput {
15
+ edgeDue: DueEdge[];
16
+ birth: string[];
17
+ budget: number;
18
+ ages: Record<string, number>;
19
+ }
20
+ export interface PrioritizeOutput {
21
+ queue: QueueItem[];
22
+ backstopOverdueRemaining: number;
23
+ }
24
+ export declare function prioritize(input: PrioritizeInput): PrioritizeOutput;
25
+ //# sourceMappingURL=priority.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"priority.d.ts","sourceRoot":"","sources":["../../src/consolidate/priority.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAG3C,MAAM,MAAM,KAAK,GAAG,UAAU,GAAG,MAAM,GAAG,WAAW,GAAG,OAAO,CAAC;AAChE,MAAM,MAAM,SAAS,GACjB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GAC3F;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IAEf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AACD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,wBAAwB,EAAE,MAAM,CAAC;CAClC;AAID,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,gBAAgB,CAkGnE"}
@@ -0,0 +1,103 @@
1
+ // Four-slice priority partition + drain-under-ceiling (spec §3.3). Pure.
2
+ //
3
+ // backstop — guaranteed (the max-interval cap made real); oldest first.
4
+ // main — event + decay, ranked fragility × blast (blast = 1 in Stage 1).
5
+ // periphery — reserved, blast-blind, pure staleness — the fairness floor.
6
+ // birth — reserved, FIFO over the unprocessed-doc queue.
7
+ //
8
+ // Periphery is taken BEFORE main so a flood of high-fragility main items can't
9
+ // swallow the fairness floor (spec §3.3 — the reserved slice is the *full* fix,
10
+ // not a mitigation). Backstop is served in full (it borrows, nothing borrows
11
+ // from it); backstopOverdueRemaining is nonzero only under total-budget
12
+ // starvation, which is exactly the §9 cron-alert condition.
13
+ import { EDGE_K_CAP } from "../curation/edges.js";
14
+ import { CONSOLIDATE_SLICE_FRACTIONS } from "./constants.js";
15
+ const REASON_RANK = { backstop: 3, event: 2, decay: 1 };
16
+ export function prioritize(input) {
17
+ const { birth, budget, ages } = input;
18
+ const ek = (d) => `${d.fromPath}\n${d.toPath}`;
19
+ // Dedup by the full edge (from,to) — the edge is the review unit (§4); two
20
+ // edges sharing a `from` (a←b and a←c) are distinct work. Keep the strongest
21
+ // reason (backstop > event > decay) when one edge is due for several.
22
+ const best = new Map();
23
+ for (const d of input.edgeDue) {
24
+ const k = ek(d);
25
+ const prev = best.get(k);
26
+ if (!prev || REASON_RANK[d.reason] > REASON_RANK[prev.reason])
27
+ best.set(k, d);
28
+ }
29
+ const all = [...best.values()];
30
+ const backstop = all.filter((d) => d.reason === "backstop");
31
+ const nonBackstop = all.filter((d) => d.reason !== "backstop");
32
+ // Slice budgets. A reserved slice with a nonzero fraction yields at least ONE
33
+ // slot whenever the budget is positive — otherwise the periphery fairness floor
34
+ // silently rounds to zero below budget 7 (floor(6·0.15)=0), breaking the §3.3
35
+ // guarantee that the periphery gets nonzero compute every session.
36
+ // NOTE: at budget 1–2 the four caps (each ≥1) sum to >budget, so a single
37
+ // backstop-overdue edge can still consume the whole budget and starve the
38
+ // reserved slices that session. That is acceptable — backstop IS the guarantee,
39
+ // and a per-session budget below the number of reserved slices is degenerate
40
+ // (real budgets are CONSOLIDATE_DEFAULT_BUDGET-scale). The fairness floor holds
41
+ // for any budget ≥ the reserved-slice count.
42
+ const slot = (f) => (budget * f > 0 ? Math.max(1, Math.floor(budget * f)) : 0);
43
+ const cap = {
44
+ backstop: slot(CONSOLIDATE_SLICE_FRACTIONS.backstop),
45
+ main: slot(CONSOLIDATE_SLICE_FRACTIONS.main),
46
+ periphery: slot(CONSOLIDATE_SLICE_FRACTIONS.periphery),
47
+ birth: slot(CONSOLIDATE_SLICE_FRACTIONS.birth),
48
+ };
49
+ // Clamp ages at 0: a future-dated lastRederived (clock skew) yields a negative
50
+ // age that would otherwise invert the staleness ranking.
51
+ const ageOf = (p) => Math.max(0, ages[p] ?? 0);
52
+ const staleDesc = (a, b) => ageOf(b.fromPath) - ageOf(a.fromPath);
53
+ const fragility = (strength) => 1 - Math.min(strength, EDGE_K_CAP) / EDGE_K_CAP;
54
+ // Reserved demand for the protected slices: each reserves only what it will use,
55
+ // so unused reservation flows to main (§3.3.4 "yields its budget to the others").
56
+ const peripherySorted = [...nonBackstop].sort(staleDesc);
57
+ const reservedPeri = Math.min(cap.periphery, peripherySorted.length);
58
+ const reservedBirth = Math.min(cap.birth, birth.length);
59
+ // Allocation (the §3.3 invariants made explicit):
60
+ // - Backstop BASE (its cap) is the guarantee — served first, oldest first.
61
+ // - Backstop OVERFLOW (beyond cap) may eat only MAIN's budget (§3.3.1 "force
62
+ // capacity from the decay slice, never periphery"); it cannot touch the
63
+ // periphery or birth reserves.
64
+ // - Backstop demand that even main's budget can't absorb is left UNSERVED and
65
+ // surfaced as backstopOverdueRemaining → the §9 exit-4 cron alert. Backstop
66
+ // yields to the reserved fairness/cold-start floors, but loudly, never
67
+ // silently.
68
+ const bkSorted = [...backstop].sort(staleDesc);
69
+ let remaining = budget;
70
+ const bkBase = Math.min(cap.backstop, bkSorted.length, remaining);
71
+ const bkOverflowRoom = Math.max(0, remaining - bkBase - reservedPeri - reservedBirth);
72
+ const bkOverflow = Math.min(bkSorted.length - bkBase, bkOverflowRoom);
73
+ const backstopServe = bkBase + bkOverflow;
74
+ remaining -= backstopServe;
75
+ const backstopOverdueRemaining = bkSorted.length - backstopServe;
76
+ const servePeri = Math.min(reservedPeri, remaining);
77
+ remaining -= servePeri;
78
+ // Main gets the elastic remainder, but must leave room for the birth reserve.
79
+ const mainSorted = peripherySorted
80
+ .slice(servePeri) // periphery skimmed the stalest `servePeri`; main gets the rest
81
+ .sort((a, b) => REASON_RANK[b.reason] - REASON_RANK[a.reason] ||
82
+ fragility(b.strength) - fragility(a.strength));
83
+ const serveMain = Math.min(mainSorted.length, Math.max(0, remaining - reservedBirth));
84
+ remaining -= serveMain;
85
+ const serveBirth = Math.min(birth.length, remaining);
86
+ const edgeItem = (d, slice) => ({
87
+ kind: "edge",
88
+ fromPath: d.fromPath,
89
+ toPath: d.toPath,
90
+ reason: d.reason,
91
+ slice,
92
+ });
93
+ const queue = [
94
+ ...bkSorted.slice(0, backstopServe).map((d) => edgeItem(d, "backstop")),
95
+ ...peripherySorted.slice(0, servePeri).map((d) => edgeItem(d, "periphery")),
96
+ ...mainSorted.slice(0, serveMain).map((d) => edgeItem(d, "main")),
97
+ ...birth
98
+ .slice(0, serveBirth)
99
+ .map((path) => ({ kind: "birth", path, slice: "birth" })),
100
+ ];
101
+ return { queue, backstopOverdueRemaining };
102
+ }
103
+ //# sourceMappingURL=priority.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"priority.js","sourceRoot":"","sources":["../../src/consolidate/priority.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,EAAE;AACF,2EAA2E;AAC3E,gFAAgF;AAChF,4EAA4E;AAC5E,+DAA+D;AAC/D,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,6EAA6E;AAC7E,wEAAwE;AACxE,4DAA4D;AAE5D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAmB7D,MAAM,WAAW,GAAsC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;AAE3F,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;IACtC,MAAM,EAAE,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;IAExD,2EAA2E;IAC3E,6EAA6E;IAC7E,sEAAsE;IACtE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAmB,CAAC;IACxC,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QAChB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACzB,IAAI,CAAC,IAAI,IAAI,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC;YAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAChF,CAAC;IACD,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/B,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC;IAC5D,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC;IAE/D,8EAA8E;IAC9E,gFAAgF;IAChF,8EAA8E;IAC9E,mEAAmE;IACnE,0EAA0E;IAC1E,0EAA0E;IAC1E,gFAAgF;IAChF,6EAA6E;IAC7E,gFAAgF;IAChF,6CAA6C;IAC7C,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvF,MAAM,GAAG,GAAG;QACV,QAAQ,EAAE,IAAI,CAAC,2BAA2B,CAAC,QAAQ,CAAC;QACpD,IAAI,EAAE,IAAI,CAAC,2BAA2B,CAAC,IAAI,CAAC;QAC5C,SAAS,EAAE,IAAI,CAAC,2BAA2B,CAAC,SAAS,CAAC;QACtD,KAAK,EAAE,IAAI,CAAC,2BAA2B,CAAC,KAAK,CAAC;KAC/C,CAAC;IAEF,+EAA+E;IAC/E,yDAAyD;IACzD,MAAM,KAAK,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACvD,MAAM,SAAS,GAAG,CAAC,CAAU,EAAE,CAAU,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IACpF,MAAM,SAAS,GAAG,CAAC,QAAgB,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,GAAG,UAAU,CAAC;IAExF,iFAAiF;IACjF,kFAAkF;IAClF,MAAM,eAAe,GAAG,CAAC,GAAG,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACzD,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IACrE,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAExD,kDAAkD;IAClD,6EAA6E;IAC7E,+EAA+E;IAC/E,4EAA4E;IAC5E,mCAAmC;IACnC,gFAAgF;IAChF,gFAAgF;IAChF,2EAA2E;IAC3E,gBAAgB;IAChB,MAAM,QAAQ,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC/C,IAAI,SAAS,GAAG,MAAM,CAAC;IACvB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClE,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,YAAY,GAAG,aAAa,CAAC,CAAC;IACtF,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC;IACtE,MAAM,aAAa,GAAG,MAAM,GAAG,UAAU,CAAC;IAC1C,SAAS,IAAI,aAAa,CAAC;IAC3B,MAAM,wBAAwB,GAAG,QAAQ,CAAC,MAAM,GAAG,aAAa,CAAC;IAEjE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IACpD,SAAS,IAAI,SAAS,CAAC;IAEvB,8EAA8E;IAC9E,MAAM,UAAU,GAAG,eAAe;SAC/B,KAAK,CAAC,SAAS,CAAC,CAAC,gEAAgE;SACjF,IAAI,CACH,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACP,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC;QAC7C,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAChD,CAAC;IACJ,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,aAAa,CAAC,CAAC,CAAC;IACtF,SAAS,IAAI,SAAS,CAAC;IAEvB,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAErD,MAAM,QAAQ,GAAG,CAAC,CAAU,EAAE,KAAY,EAAa,EAAE,CAAC,CAAC;QACzD,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,KAAK;KACN,CAAC,CAAC;IACH,MAAM,KAAK,GAAgB;QACzB,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QACvE,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;QAC3E,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QACjE,GAAG,KAAK;aACL,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC;aACpB,GAAG,CAAC,CAAC,IAAI,EAAa,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;KACvE,CAAC;IAEF,OAAO,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC;AAC7C,CAAC"}