@isaacriehm/cairn-core 0.21.0 → 0.22.1
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.
- package/dist/.tsbuildinfo +1 -1
- package/dist/align-undo/log.js +3 -2
- package/dist/align-undo/log.js.map +1 -1
- package/dist/attention/source-strip.js +2 -1
- package/dist/attention/source-strip.js.map +1 -1
- package/dist/components/emit.js +33 -6
- package/dist/components/emit.js.map +1 -1
- package/dist/components/freshness.d.ts +51 -0
- package/dist/components/freshness.js +121 -0
- package/dist/components/freshness.js.map +1 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.js +2 -0
- package/dist/components/index.js.map +1 -1
- package/dist/components/reconfirm.d.ts +64 -0
- package/dist/components/reconfirm.js +204 -0
- package/dist/components/reconfirm.js.map +1 -0
- package/dist/context/handoff-builder.js +3 -3
- package/dist/context/handoff-builder.js.map +1 -1
- package/dist/context/task-summary.js +2 -2
- package/dist/context/task-summary.js.map +1 -1
- package/dist/doctor/index.js +7 -7
- package/dist/doctor/index.js.map +1 -1
- package/dist/events/paths.js +2 -2
- package/dist/events/paths.js.map +1 -1
- package/dist/fix-align/sentinel.js +2 -3
- package/dist/fix-align/sentinel.js.map +1 -1
- package/dist/gc/attested-commits.js +2 -2
- package/dist/gc/attested-commits.js.map +1 -1
- package/dist/gc/canary.js +2 -3
- package/dist/gc/canary.js.map +1 -1
- package/dist/gc/citation-integrity.d.ts +2 -3
- package/dist/gc/citation-integrity.js +2 -26
- package/dist/gc/citation-integrity.js.map +1 -1
- package/dist/gc/completion-integrity.js +4 -3
- package/dist/gc/completion-integrity.js.map +1 -1
- package/dist/gc/entity-orphan.js +60 -8
- package/dist/gc/entity-orphan.js.map +1 -1
- package/dist/gc/ghost-anchor.d.ts +57 -0
- package/dist/gc/ghost-anchor.js +171 -0
- package/dist/gc/ghost-anchor.js.map +1 -0
- package/dist/gc/index.d.ts +2 -0
- package/dist/gc/index.js +1 -0
- package/dist/gc/index.js.map +1 -1
- package/dist/gc/runtime-prune.d.ts +59 -0
- package/dist/gc/runtime-prune.js +232 -0
- package/dist/gc/runtime-prune.js.map +1 -0
- package/dist/gc/sweep.js +18 -0
- package/dist/gc/sweep.js.map +1 -1
- package/dist/gc/types.d.ts +1 -1
- package/dist/hooks/bypass-detection.js +3 -2
- package/dist/hooks/bypass-detection.js.map +1 -1
- package/dist/hooks/defer.js +3 -2
- package/dist/hooks/defer.js.map +1 -1
- package/dist/hooks/ghost-backup.d.ts +37 -0
- package/dist/hooks/ghost-backup.js +82 -0
- package/dist/hooks/ghost-backup.js.map +1 -0
- package/dist/hooks/post-tool-use/allowlist-reader.js +2 -2
- package/dist/hooks/post-tool-use/allowlist-reader.js.map +1 -1
- package/dist/hooks/post-tool-use/ask-user-blocked.js +2 -2
- package/dist/hooks/post-tool-use/ask-user-blocked.js.map +1 -1
- package/dist/hooks/post-tool-use/citation-scanner.d.ts +8 -6
- package/dist/hooks/post-tool-use/citation-scanner.js +9 -14
- package/dist/hooks/post-tool-use/citation-scanner.js.map +1 -1
- package/dist/hooks/post-tool-use/legend-builder.d.ts +2 -2
- package/dist/hooks/post-tool-use/legend-builder.js +1 -19
- package/dist/hooks/post-tool-use/legend-builder.js.map +1 -1
- package/dist/hooks/post-tool-use/post-write.js +18 -1
- package/dist/hooks/post-tool-use/post-write.js.map +1 -1
- package/dist/hooks/post-tool-use/read-enricher.d.ts +2 -2
- package/dist/hooks/post-tool-use/read-enricher.js +4 -6
- package/dist/hooks/post-tool-use/read-enricher.js.map +1 -1
- package/dist/hooks/post-tool-use/sot-align.js +29 -3
- package/dist/hooks/post-tool-use/sot-align.js.map +1 -1
- package/dist/hooks/post-tool-use/write-guardian.js +4 -4
- package/dist/hooks/post-tool-use/write-guardian.js.map +1 -1
- package/dist/hooks/runners/context-threshold.js +3 -3
- package/dist/hooks/runners/context-threshold.js.map +1 -1
- package/dist/hooks/runners/payload.js +2 -1
- package/dist/hooks/runners/payload.js.map +1 -1
- package/dist/hooks/runners/phase-ready-surface.js +3 -2
- package/dist/hooks/runners/phase-ready-surface.js.map +1 -1
- package/dist/hooks/runners/session-start.js +124 -5
- package/dist/hooks/runners/session-start.js.map +1 -1
- package/dist/hooks/runners/stop.js +26 -12
- package/dist/hooks/runners/stop.js.map +1 -1
- package/dist/hooks/runners/user-prompt-submit.d.ts +2 -2
- package/dist/hooks/runners/user-prompt-submit.js +4 -9
- package/dist/hooks/runners/user-prompt-submit.js.map +1 -1
- package/dist/hooks/seed-attested.js +3 -2
- package/dist/hooks/seed-attested.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/init/baseline-audit.js +3 -3
- package/dist/init/baseline-audit.js.map +1 -1
- package/dist/init/claude-rule.js +13 -1
- package/dist/init/claude-rule.js.map +1 -1
- package/dist/init/curator/corpus.d.ts +1 -0
- package/dist/init/curator/corpus.js +6 -2
- package/dist/init/curator/corpus.js.map +1 -1
- package/dist/init/curator/emit.js +2 -3
- package/dist/init/curator/emit.js.map +1 -1
- package/dist/init/detect-components.js +2 -2
- package/dist/init/detect-components.js.map +1 -1
- package/dist/init/eta-calibration.js +2 -2
- package/dist/init/eta-calibration.js.map +1 -1
- package/dist/init/index.d.ts +1 -1
- package/dist/init/index.js +1 -1
- package/dist/init/index.js.map +1 -1
- package/dist/init/init.d.ts +8 -0
- package/dist/init/init.js +16 -6
- package/dist/init/init.js.map +1 -1
- package/dist/init/mapper.js +2 -2
- package/dist/init/mapper.js.map +1 -1
- package/dist/init/multi-dev/install.js +24 -0
- package/dist/init/multi-dev/install.js.map +1 -1
- package/dist/init/phases/11-baseline.js +1 -1
- package/dist/init/phases/11-baseline.js.map +1 -1
- package/dist/init/phases/4-seed.js +7 -5
- package/dist/init/phases/4-seed.js.map +1 -1
- package/dist/init/phases/9a-walker.js +4 -0
- package/dist/init/phases/9a-walker.js.map +1 -1
- package/dist/init/phases/9b-curate.d.ts +1 -0
- package/dist/init/phases/9b-curate.js +6 -2
- package/dist/init/phases/9b-curate.js.map +1 -1
- package/dist/init/phases/9d-comp-walk.js +2 -2
- package/dist/init/phases/9d-comp-walk.js.map +1 -1
- package/dist/init/phases/9e-comp-annotate.js +63 -3
- package/dist/init/phases/9e-comp-annotate.js.map +1 -1
- package/dist/init/phases/index.d.ts +0 -1
- package/dist/init/phases/index.js +0 -1
- package/dist/init/phases/index.js.map +1 -1
- package/dist/init/phases/mapper-output-io.d.ts +1 -1
- package/dist/init/phases/mapper-output-io.js +3 -2
- package/dist/init/phases/mapper-output-io.js.map +1 -1
- package/dist/init/phases/state-io.d.ts +1 -1
- package/dist/init/phases/state-io.js +3 -2
- package/dist/init/phases/state-io.js.map +1 -1
- package/dist/init/phases/types.d.ts +20 -8
- package/dist/init/phases/types.js +0 -1
- package/dist/init/phases/types.js.map +1 -1
- package/dist/init/progress.d.ts +1 -0
- package/dist/init/progress.js +3 -1
- package/dist/init/progress.js.map +1 -1
- package/dist/init/rules-merge/ingest.js +3 -3
- package/dist/init/rules-merge/ingest.js.map +1 -1
- package/dist/init/seed.js +54 -5
- package/dist/init/seed.js.map +1 -1
- package/dist/init/source-comments/strip-replace.d.ts +0 -1
- package/dist/init/source-comments/strip-replace.js +17 -1
- package/dist/init/source-comments/strip-replace.js.map +1 -1
- package/dist/join/index.d.ts +9 -0
- package/dist/join/index.js +82 -25
- package/dist/join/index.js.map +1 -1
- package/dist/lock.js +4 -3
- package/dist/lock.js.map +1 -1
- package/dist/mcp/bootstrap-guard.js +10 -1
- package/dist/mcp/bootstrap-guard.js.map +1 -1
- package/dist/mcp/schemas.d.ts +26 -0
- package/dist/mcp/schemas.js +26 -0
- package/dist/mcp/schemas.js.map +1 -1
- package/dist/mcp/server.js +3 -3
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/telemetry.js +4 -3
- package/dist/mcp/telemetry.js.map +1 -1
- package/dist/mcp/tools/component-reconfirm.d.ts +7 -0
- package/dist/mcp/tools/component-reconfirm.js +39 -0
- package/dist/mcp/tools/component-reconfirm.js.map +1 -0
- package/dist/mcp/tools/component-register.d.ts +15 -0
- package/dist/mcp/tools/component-register.js +65 -0
- package/dist/mcp/tools/component-register.js.map +1 -0
- package/dist/mcp/tools/index.js +8 -0
- package/dist/mcp/tools/index.js.map +1 -1
- package/dist/mcp/tools/init-phases.d.ts +2 -0
- package/dist/mcp/tools/init-phases.js +21 -5
- package/dist/mcp/tools/init-phases.js.map +1 -1
- package/dist/mcp/tools/migrate.d.ts +21 -0
- package/dist/mcp/tools/migrate.js +49 -0
- package/dist/mcp/tools/migrate.js.map +1 -0
- package/dist/mcp/tools/mission-advance.js +5 -5
- package/dist/mcp/tools/mission-advance.js.map +1 -1
- package/dist/mcp/tools/mission-resume.js +3 -3
- package/dist/mcp/tools/mission-resume.js.map +1 -1
- package/dist/mcp/tools/record-decision.js +11 -4
- package/dist/mcp/tools/record-decision.js.map +1 -1
- package/dist/mcp/tools/resolve-attention.js +20 -4
- package/dist/mcp/tools/resolve-attention.js.map +1 -1
- package/dist/mcp/tools/resume.js +3 -2
- package/dist/mcp/tools/resume.js.map +1 -1
- package/dist/mcp/tools/search.js +2 -2
- package/dist/mcp/tools/search.js.map +1 -1
- package/dist/mcp/tools/task-complete.js +2 -3
- package/dist/mcp/tools/task-complete.js.map +1 -1
- package/dist/mcp/tools/task-create.js +2 -2
- package/dist/mcp/tools/task-create.js.map +1 -1
- package/dist/migrate/config-io.d.ts +10 -2
- package/dist/migrate/config-io.js +21 -19
- package/dist/migrate/config-io.js.map +1 -1
- package/dist/migrate/gitignore.d.ts +28 -0
- package/dist/migrate/gitignore.js +82 -0
- package/dist/migrate/gitignore.js.map +1 -0
- package/dist/migrate/index.d.ts +1 -0
- package/dist/migrate/index.js +1 -0
- package/dist/migrate/index.js.map +1 -1
- package/dist/migrate/migrations/0001-drop-dead-config-fields.js +2 -2
- package/dist/migrate/migrations/0001-drop-dead-config-fields.js.map +1 -1
- package/dist/migrate/migrations/0002-backfill-gitignore.d.ts +14 -0
- package/dist/migrate/migrations/0002-backfill-gitignore.js +40 -0
- package/dist/migrate/migrations/0002-backfill-gitignore.js.map +1 -0
- package/dist/migrate/migrations/0003-prune-scaffolding.d.ts +19 -0
- package/dist/migrate/migrations/0003-prune-scaffolding.js +54 -0
- package/dist/migrate/migrations/0003-prune-scaffolding.js.map +1 -0
- package/dist/migrate/registry.js +7 -1
- package/dist/migrate/registry.js.map +1 -1
- package/dist/migrate/runner.js +17 -10
- package/dist/migrate/runner.js.map +1 -1
- package/dist/migrate/types.d.ts +10 -2
- package/dist/missions/task-link.js +4 -5
- package/dist/missions/task-link.js.map +1 -1
- package/dist/paths/index.d.ts +12 -1
- package/dist/paths/index.js +17 -3
- package/dist/paths/index.js.map +1 -1
- package/dist/sensors/catalog.js +3 -3
- package/dist/sensors/catalog.js.map +1 -1
- package/dist/session-start/build.js +31 -16
- package/dist/session-start/build.js.map +1 -1
- package/dist/status-line/event-queue.js +2 -1
- package/dist/status-line/event-queue.js.map +1 -1
- package/dist/status-line/reader.js +5 -5
- package/dist/status-line/reader.js.map +1 -1
- package/dist/status-line/writer.js +2 -1
- package/dist/status-line/writer.js.map +1 -1
- package/dist/tasks/lifecycle.js +10 -9
- package/dist/tasks/lifecycle.js.map +1 -1
- package/dist/trace/index.js +2 -2
- package/dist/trace/index.js.map +1 -1
- package/dist/update-check.d.ts +28 -0
- package/dist/update-check.js +137 -0
- package/dist/update-check.js.map +1 -0
- package/package.json +2 -2
- package/templates/.cairn/git-hooks/commit-msg +33 -5
- package/templates/.cairn/git-hooks/post-commit +13 -3
- package/templates/.cairn/git-hooks/pre-commit +48 -25
- package/dist/hooks/read-enrich.d.ts +0 -6
- package/dist/hooks/read-enrich.js +0 -11
- package/dist/hooks/read-enrich.js.map +0 -1
- package/dist/hooks/write-guard.d.ts +0 -6
- package/dist/hooks/write-guard.js +0 -11
- package/dist/hooks/write-guard.js.map +0 -1
- package/dist/init/phases/12-strip.d.ts +0 -10
- package/dist/init/phases/12-strip.js +0 -88
- package/dist/init/phases/12-strip.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"citation-integrity.js","sourceRoot":"","sources":["../../src/gc/citation-integrity.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"citation-integrity.js","sourceRoot":"","sources":["../../src/gc/citation-integrity.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,6 +15,7 @@ import { join } from "node:path";
|
|
|
15
15
|
import { simpleGit } from "simple-git";
|
|
16
16
|
import { parse as parseYaml } from "yaml";
|
|
17
17
|
import { z } from "zod";
|
|
18
|
+
import { cairnDir } from "@isaacriehm/cairn-state";
|
|
18
19
|
const PASS_ID = "completion-integrity";
|
|
19
20
|
const StatusSchema = z.object({
|
|
20
21
|
phase: z.string().optional(),
|
|
@@ -35,7 +36,7 @@ function ensureGit(repoRoot) {
|
|
|
35
36
|
}
|
|
36
37
|
/** Run the completion-integrity pass. */
|
|
37
38
|
export async function runCompletionIntegrity(opts) {
|
|
38
|
-
const doneDir =
|
|
39
|
+
const doneDir = cairnDir(opts.repoRoot, "tasks", "done");
|
|
39
40
|
const findings = [];
|
|
40
41
|
if (!existsSync(doneDir))
|
|
41
42
|
return { findings };
|
|
@@ -74,8 +75,8 @@ export async function runCompletionIntegrity(opts) {
|
|
|
74
75
|
findings.push(makeFinding(taskId, `task ${taskId} in tasks/done/ has no related_run_ids`));
|
|
75
76
|
continue;
|
|
76
77
|
}
|
|
77
|
-
const terminalDir =
|
|
78
|
-
const activeDir =
|
|
78
|
+
const terminalDir = cairnDir(opts.repoRoot, "runs", "terminal", runId);
|
|
79
|
+
const activeDir = cairnDir(opts.repoRoot, "runs", "active", runId);
|
|
79
80
|
let runDir = null;
|
|
80
81
|
if (existsSync(terminalDir))
|
|
81
82
|
runDir = terminalDir;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"completion-integrity.js","sourceRoot":"","sources":["../../src/gc/completion-integrity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"completion-integrity.js","sourceRoot":"","sources":["../../src/gc/completion-integrity.ts"],"names":[],"mappings":"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"}
|
package/dist/gc/entity-orphan.js
CHANGED
|
@@ -32,7 +32,8 @@
|
|
|
32
32
|
*/
|
|
33
33
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
34
34
|
import { join } from "node:path";
|
|
35
|
-
import { decisionsDir, invariantsDir, knownExtensions, parseFrontmatterRecord, } from "@isaacriehm/cairn-state";
|
|
35
|
+
import { decisionsDir, invariantsDir, isGhost, knownExtensions, parseFrontmatterRecord, readScopeIndex, } from "@isaacriehm/cairn-state";
|
|
36
|
+
import { makeGhostBlockResolver } from "./ghost-anchor.js";
|
|
36
37
|
import { walkSourceTree } from "./walk-source.js";
|
|
37
38
|
const PASS_ID = "entity-orphan";
|
|
38
39
|
const GRACE_DAYS = 7;
|
|
@@ -51,6 +52,40 @@ function fileExt(path) {
|
|
|
51
52
|
const idx = path.lastIndexOf(".");
|
|
52
53
|
return idx === -1 ? "" : path.slice(idx).toLowerCase();
|
|
53
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Ghost liveness floor (fallback) — there are no in-source `§` cites to grep,
|
|
57
|
+
* so the binding lives in the out-of-repo scope-index (the SoT in ghost). An
|
|
58
|
+
* entity is live when SOME still-existing file binds it. Used only for legacy
|
|
59
|
+
* entities that predate the `sot_content_hash` anchor; current entities use
|
|
60
|
+
* the sharper block-resolution check (`entityGhostLive`).
|
|
61
|
+
*/
|
|
62
|
+
function entityBoundLive(repoRoot, id, idx) {
|
|
63
|
+
if (idx === null)
|
|
64
|
+
return false;
|
|
65
|
+
for (const [file, entry] of Object.entries(idx.files)) {
|
|
66
|
+
if (entry.decisions.includes(id) || entry.invariants.includes(id)) {
|
|
67
|
+
if (existsSync(join(repoRoot, file)))
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Ghost liveness (§3.5.1/§3.6) — the governing comment block still resolves by
|
|
75
|
+
* content hash in its source file. Location-independent: survives the block
|
|
76
|
+
* moving within the file, but a deleted or rewritten comment correctly reads as
|
|
77
|
+
* dead even when the file itself remains (the bug `entityBoundLive` alone can't
|
|
78
|
+
* catch). Falls back to the coarse bound-file floor for legacy entities with no
|
|
79
|
+
* 64-char `sot_content_hash`.
|
|
80
|
+
*/
|
|
81
|
+
function entityGhostLive(repoRoot, id, fm, idx, resolveBlock) {
|
|
82
|
+
const sourceFile = typeof fm["source_file"] === "string" ? fm["source_file"] : "";
|
|
83
|
+
const hash = typeof fm["sot_content_hash"] === "string" ? fm["sot_content_hash"] : "";
|
|
84
|
+
if (hash.length === 64 && sourceFile.length > 0) {
|
|
85
|
+
return resolveBlock(sourceFile, hash).found;
|
|
86
|
+
}
|
|
87
|
+
return entityBoundLive(repoRoot, id, idx);
|
|
88
|
+
}
|
|
54
89
|
/** Set of every DEC/INV id cited by a `§` reference anywhere in the source tree. */
|
|
55
90
|
function collectCitedIds(repoRoot) {
|
|
56
91
|
const cited = new Set();
|
|
@@ -94,7 +129,14 @@ export function runEntityOrphan(opts) {
|
|
|
94
129
|
const now = opts.now ?? new Date();
|
|
95
130
|
const findings = [];
|
|
96
131
|
const orphans = [];
|
|
97
|
-
|
|
132
|
+
// Ghost: liveness keys on the out-of-repo scope-index binding, NEVER on
|
|
133
|
+
// in-source `§` cites (there are none — the naive cite scan would orphan the
|
|
134
|
+
// entire ledger on the first sweep). Skip the source walk entirely.
|
|
135
|
+
const ghost = isGhost(opts.repoRoot);
|
|
136
|
+
const cited = ghost ? new Set() : collectCitedIds(opts.repoRoot);
|
|
137
|
+
const scopeIdx = ghost ? readScopeIndex(opts.repoRoot) : null;
|
|
138
|
+
// One resolver for the whole sweep — walks each clustered source file once.
|
|
139
|
+
const resolveBlock = ghost ? makeGhostBlockResolver(opts.repoRoot) : null;
|
|
98
140
|
const groups = [
|
|
99
141
|
{ kind: "DEC", dir: decisionsDir(opts.repoRoot), rel: ".cairn/ground/decisions" },
|
|
100
142
|
{ kind: "INV", dir: invariantsDir(opts.repoRoot), rel: ".cairn/ground/invariants" },
|
|
@@ -139,18 +181,28 @@ export function runEntityOrphan(opts) {
|
|
|
139
181
|
}
|
|
140
182
|
}
|
|
141
183
|
else {
|
|
142
|
-
// ledger-backed —
|
|
143
|
-
|
|
184
|
+
// ledger-backed — liveness:
|
|
185
|
+
// committed: a live in-source `§` cite for this id
|
|
186
|
+
// ghost: the governing comment block still resolves by content
|
|
187
|
+
// hash in its source file (no cites exist — §3.5.1)
|
|
188
|
+
const live = ghost
|
|
189
|
+
? entityGhostLive(opts.repoRoot, id, fm, scopeIdx, resolveBlock)
|
|
190
|
+
: cited.has(id);
|
|
191
|
+
if (!live) {
|
|
144
192
|
const sourceFile = typeof fm["source_file"] === "string" ? fm["source_file"] : "";
|
|
145
193
|
const srcGone = sourceFile.length === 0 || !existsSync(join(opts.repoRoot, sourceFile));
|
|
194
|
+
// Ghost never auto-retires (no `safe`): there are no cites to confirm
|
|
195
|
+
// removal, so an unbound entity is surfaced for operator review only.
|
|
146
196
|
candidate = {
|
|
147
197
|
id,
|
|
148
198
|
kind: group.kind,
|
|
149
199
|
sotKind,
|
|
150
|
-
classification: srcGone ? "safe" : "ambiguous",
|
|
151
|
-
reason:
|
|
152
|
-
? "
|
|
153
|
-
:
|
|
200
|
+
classification: ghost ? "ambiguous" : srcGone ? "safe" : "ambiguous",
|
|
201
|
+
reason: ghost
|
|
202
|
+
? "ghost: governing comment block no longer resolves by content hash (review — never auto-retired)"
|
|
203
|
+
: srcGone
|
|
204
|
+
? "orphan-by-source: source_file gone and zero live §cites remain"
|
|
205
|
+
: "orphan-by-source: zero live §cites remain (source_file still present — review)",
|
|
154
206
|
entityPath,
|
|
155
207
|
};
|
|
156
208
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity-orphan.js","sourceRoot":"","sources":["../../src/gc/entity-orphan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACL,YAAY,EACZ,aAAa,EACb,eAAe,EACf,sBAAsB,
|
|
1
|
+
{"version":3,"file":"entity-orphan.js","sourceRoot":"","sources":["../../src/gc/entity-orphan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ghost content-hash anchoring (ghost-mode design).
|
|
3
|
+
*
|
|
4
|
+
* In committed mode a `// §DEC-<hash>` cite binds a code location to its
|
|
5
|
+
* decision and moves with the code. Ghost never writes that cite, so the
|
|
6
|
+
* binding lives out-of-repo and the *block* has to be re-located by content:
|
|
7
|
+
* the operator's decision comment stays verbatim in source (strip-replace is a
|
|
8
|
+
* no-op in ghost), and its body hash is the stable, location-independent key.
|
|
9
|
+
*
|
|
10
|
+
* Two consumers:
|
|
11
|
+
* - `resolveGhostBlock` — read-only liveness probe. Does a comment block whose
|
|
12
|
+
* body hashes to `contentHash` still exist in `sourceFile`? GC liveness
|
|
13
|
+
* (§3.6) keys on this instead of mere bound-file existence, so a deleted /
|
|
14
|
+
* rewritten comment correctly reads as orphaned even when the file remains.
|
|
15
|
+
* - `runGhostReanchor` — the re-anchor-on-reconcile pass. When a still-live
|
|
16
|
+
* block has *moved* (same hash, new line range), silently refresh the
|
|
17
|
+
* anchor-map `line_range`. Runs in the GC sweep — the periodic ghost analog
|
|
18
|
+
* of the cite that would otherwise move with the code.
|
|
19
|
+
*
|
|
20
|
+
* Both reuse the SAME comment extraction + `bodyContentHash` normalization the
|
|
21
|
+
* Layer A emit used, so a re-hash lines up with the stored `sot_content_hash`.
|
|
22
|
+
* Committed mode never calls these (the cite is the binding); every entry point
|
|
23
|
+
* is `isGhost`-gated.
|
|
24
|
+
*/
|
|
25
|
+
export interface GhostBlockResolution {
|
|
26
|
+
/** A comment block whose body hashes to `contentHash` still exists. */
|
|
27
|
+
found: boolean;
|
|
28
|
+
/** Fresh `[startLine, endLine]` of that block, or null when not found. */
|
|
29
|
+
lineRange: [number, number] | null;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Re-locate a governed comment block in `sourceFile` by its body hash. Pure
|
|
33
|
+
* read — no writes. Location-independent: the block is found wherever it moved
|
|
34
|
+
* to within the file. Returns `found: false` when the file is gone, unreadable,
|
|
35
|
+
* an unknown language, or carries no block matching the hash (deleted/rewritten).
|
|
36
|
+
*/
|
|
37
|
+
export declare function resolveGhostBlock(repoRoot: string, sourceFile: string, contentHash: string): GhostBlockResolution;
|
|
38
|
+
export type GhostBlockResolver = (sourceFile: string, contentHash: string) => GhostBlockResolution;
|
|
39
|
+
/**
|
|
40
|
+
* Build a per-run resolver that walks each source file at most once. A GC sweep
|
|
41
|
+
* resolves many ledger entities that cluster into a few files; the bare
|
|
42
|
+
* `resolveGhostBlock` re-reads + re-hashes the file once per entity. Share one
|
|
43
|
+
* resolver across a sweep so each file is read once. Per-run scope (a fresh Map
|
|
44
|
+
* each call) — never a module-level cache, so it can't go stale between sweeps.
|
|
45
|
+
*/
|
|
46
|
+
export declare function makeGhostBlockResolver(repoRoot: string): GhostBlockResolver;
|
|
47
|
+
export interface GhostReanchorResult {
|
|
48
|
+
/** Anchor entries whose `line_range` was refreshed because the block moved. */
|
|
49
|
+
reanchored: number;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Re-anchor-on-reconcile (§3.5.1). For every live ghost ledger entity whose
|
|
53
|
+
* comment block has moved within its file, refresh the anchor-map `line_range`
|
|
54
|
+
* so the (future) lens decorates the right span. Idempotent — writes only when
|
|
55
|
+
* a range actually changed. No-op (and no entity walk) outside ghost.
|
|
56
|
+
*/
|
|
57
|
+
export declare function runGhostReanchor(repoRoot: string): GhostReanchorResult;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ghost content-hash anchoring (ghost-mode design).
|
|
3
|
+
*
|
|
4
|
+
* In committed mode a `// §DEC-<hash>` cite binds a code location to its
|
|
5
|
+
* decision and moves with the code. Ghost never writes that cite, so the
|
|
6
|
+
* binding lives out-of-repo and the *block* has to be re-located by content:
|
|
7
|
+
* the operator's decision comment stays verbatim in source (strip-replace is a
|
|
8
|
+
* no-op in ghost), and its body hash is the stable, location-independent key.
|
|
9
|
+
*
|
|
10
|
+
* Two consumers:
|
|
11
|
+
* - `resolveGhostBlock` — read-only liveness probe. Does a comment block whose
|
|
12
|
+
* body hashes to `contentHash` still exist in `sourceFile`? GC liveness
|
|
13
|
+
* (§3.6) keys on this instead of mere bound-file existence, so a deleted /
|
|
14
|
+
* rewritten comment correctly reads as orphaned even when the file remains.
|
|
15
|
+
* - `runGhostReanchor` — the re-anchor-on-reconcile pass. When a still-live
|
|
16
|
+
* block has *moved* (same hash, new line range), silently refresh the
|
|
17
|
+
* anchor-map `line_range`. Runs in the GC sweep — the periodic ghost analog
|
|
18
|
+
* of the cite that would otherwise move with the code.
|
|
19
|
+
*
|
|
20
|
+
* Both reuse the SAME comment extraction + `bodyContentHash` normalization the
|
|
21
|
+
* Layer A emit used, so a re-hash lines up with the stored `sot_content_hash`.
|
|
22
|
+
* Committed mode never calls these (the cite is the binding); every entry point
|
|
23
|
+
* is `isGhost`-gated.
|
|
24
|
+
*/
|
|
25
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
26
|
+
import { join } from "node:path";
|
|
27
|
+
import { bodyContentHash, decisionsDir, invariantsDir, isGhost, parseFrontmatterRecord, readAnchorMap, setAnchor, writeAnchorMap, } from "@isaacriehm/cairn-state";
|
|
28
|
+
import { walkSourceComments } from "../init/source-comments/walker.js";
|
|
29
|
+
/**
|
|
30
|
+
* Re-locate a governed comment block in `sourceFile` by its body hash. Pure
|
|
31
|
+
* read — no writes. Location-independent: the block is found wherever it moved
|
|
32
|
+
* to within the file. Returns `found: false` when the file is gone, unreadable,
|
|
33
|
+
* an unknown language, or carries no block matching the hash (deleted/rewritten).
|
|
34
|
+
*/
|
|
35
|
+
export function resolveGhostBlock(repoRoot, sourceFile, contentHash) {
|
|
36
|
+
if (sourceFile.length === 0 || contentHash.length !== 64) {
|
|
37
|
+
return { found: false, lineRange: null };
|
|
38
|
+
}
|
|
39
|
+
const byHash = walkBlockHashes(repoRoot, sourceFile);
|
|
40
|
+
return lookupBlock(byHash, contentHash);
|
|
41
|
+
}
|
|
42
|
+
/** One source file walked once → `body content-hash → [startLine, endLine]`. */
|
|
43
|
+
function walkBlockHashes(repoRoot, sourceFile) {
|
|
44
|
+
if (!existsSync(join(repoRoot, sourceFile)))
|
|
45
|
+
return null;
|
|
46
|
+
let blocks;
|
|
47
|
+
try {
|
|
48
|
+
blocks = walkSourceComments({ repoRoot, onlyFiles: [sourceFile] }).blocks;
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const m = new Map();
|
|
54
|
+
for (const b of blocks) {
|
|
55
|
+
const h = bodyContentHash(b.prose);
|
|
56
|
+
if (!m.has(h))
|
|
57
|
+
m.set(h, [b.startLine, b.endLine]);
|
|
58
|
+
}
|
|
59
|
+
return m;
|
|
60
|
+
}
|
|
61
|
+
function lookupBlock(byHash, contentHash) {
|
|
62
|
+
if (byHash === null)
|
|
63
|
+
return { found: false, lineRange: null };
|
|
64
|
+
const range = byHash.get(contentHash);
|
|
65
|
+
return range ? { found: true, lineRange: range } : { found: false, lineRange: null };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Build a per-run resolver that walks each source file at most once. A GC sweep
|
|
69
|
+
* resolves many ledger entities that cluster into a few files; the bare
|
|
70
|
+
* `resolveGhostBlock` re-reads + re-hashes the file once per entity. Share one
|
|
71
|
+
* resolver across a sweep so each file is read once. Per-run scope (a fresh Map
|
|
72
|
+
* each call) — never a module-level cache, so it can't go stale between sweeps.
|
|
73
|
+
*/
|
|
74
|
+
export function makeGhostBlockResolver(repoRoot) {
|
|
75
|
+
const cache = new Map();
|
|
76
|
+
return (sourceFile, contentHash) => {
|
|
77
|
+
if (sourceFile.length === 0 || contentHash.length !== 64) {
|
|
78
|
+
return { found: false, lineRange: null };
|
|
79
|
+
}
|
|
80
|
+
let byHash = cache.get(sourceFile);
|
|
81
|
+
if (byHash === undefined) {
|
|
82
|
+
byHash = walkBlockHashes(repoRoot, sourceFile);
|
|
83
|
+
cache.set(sourceFile, byHash);
|
|
84
|
+
}
|
|
85
|
+
return lookupBlock(byHash, contentHash);
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/** Active ledger entities (DEC + INV) that carry a source-comment anchor. */
|
|
89
|
+
function collectGhostLedgerEntities(repoRoot) {
|
|
90
|
+
const out = [];
|
|
91
|
+
for (const dir of [decisionsDir(repoRoot), invariantsDir(repoRoot)]) {
|
|
92
|
+
let names;
|
|
93
|
+
try {
|
|
94
|
+
names = readdirSync(dir, { withFileTypes: true, encoding: "utf8" })
|
|
95
|
+
.filter((d) => d.isFile() && d.name.endsWith(".md") && !d.name.startsWith("_"))
|
|
96
|
+
.map((d) => d.name);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
for (const name of names) {
|
|
102
|
+
let fm;
|
|
103
|
+
try {
|
|
104
|
+
fm = parseFrontmatterRecord(readFileSync(join(dir, name), "utf8")).fm;
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
if (fm["sot_kind"] !== "ledger")
|
|
110
|
+
continue;
|
|
111
|
+
const status = typeof fm["status"] === "string" ? fm["status"] : "";
|
|
112
|
+
if (status === "archived" || status === "superseded")
|
|
113
|
+
continue;
|
|
114
|
+
const sourceFile = typeof fm["source_file"] === "string" ? fm["source_file"] : "";
|
|
115
|
+
const contentHash = typeof fm["sot_content_hash"] === "string" ? fm["sot_content_hash"] : "";
|
|
116
|
+
if (sourceFile.length === 0 || contentHash.length !== 64)
|
|
117
|
+
continue;
|
|
118
|
+
out.push({ sourceFile, contentHash });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return out;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Re-anchor-on-reconcile (§3.5.1). For every live ghost ledger entity whose
|
|
125
|
+
* comment block has moved within its file, refresh the anchor-map `line_range`
|
|
126
|
+
* so the (future) lens decorates the right span. Idempotent — writes only when
|
|
127
|
+
* a range actually changed. No-op (and no entity walk) outside ghost.
|
|
128
|
+
*/
|
|
129
|
+
export function runGhostReanchor(repoRoot) {
|
|
130
|
+
if (!isGhost(repoRoot))
|
|
131
|
+
return { reanchored: 0 };
|
|
132
|
+
const entities = collectGhostLedgerEntities(repoRoot);
|
|
133
|
+
if (entities.length === 0)
|
|
134
|
+
return { reanchored: 0 };
|
|
135
|
+
let map = readAnchorMap(repoRoot);
|
|
136
|
+
let changed = false;
|
|
137
|
+
let reanchored = 0;
|
|
138
|
+
const resolveBlock = makeGhostBlockResolver(repoRoot);
|
|
139
|
+
for (const ent of entities) {
|
|
140
|
+
const res = resolveBlock(ent.sourceFile, ent.contentHash);
|
|
141
|
+
if (!res.found || res.lineRange === null)
|
|
142
|
+
continue;
|
|
143
|
+
// Find the anchor entry for this block by (file, content_hash) — the slug
|
|
144
|
+
// key is opaque here, but (file, hash) uniquely identifies the block.
|
|
145
|
+
for (const [slug, entry] of Object.entries(map.anchors)) {
|
|
146
|
+
if (entry.file !== ent.sourceFile || entry.content_hash !== ent.contentHash) {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
const [ns, ne] = res.lineRange;
|
|
150
|
+
const cur = entry.line_range;
|
|
151
|
+
if (cur === undefined || cur[0] !== ns || cur[1] !== ne) {
|
|
152
|
+
map = setAnchor(map, slug, { ...entry, line_range: [ns, ne] });
|
|
153
|
+
changed = true;
|
|
154
|
+
reanchored += 1;
|
|
155
|
+
}
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (changed) {
|
|
160
|
+
try {
|
|
161
|
+
writeAnchorMap(repoRoot, map);
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
// best-effort — a failed re-anchor write never blocks the sweep; the
|
|
165
|
+
// stale line_range only affects lens display, not liveness.
|
|
166
|
+
return { reanchored: 0 };
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return { reanchored };
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=ghost-anchor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ghost-anchor.js","sourceRoot":"","sources":["../../src/gc/ghost-anchor.ts"],"names":[],"mappings":"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"}
|
package/dist/gc/index.d.ts
CHANGED
|
@@ -32,6 +32,8 @@ export { extractSectionByAnchor, runDocSourceDrift, slugifyHeading, } from "./do
|
|
|
32
32
|
export type { DocSourceDriftOptions, DocSourceDriftResult, } from "./doc-source-drift.js";
|
|
33
33
|
export { runEntityOrphan } from "./entity-orphan.js";
|
|
34
34
|
export type { EntityOrphanOptions, EntityOrphanResult, OrphanCandidate, OrphanClassification, } from "./entity-orphan.js";
|
|
35
|
+
export { resolveGhostBlock, runGhostReanchor } from "./ghost-anchor.js";
|
|
36
|
+
export type { GhostBlockResolution, GhostReanchorResult, } from "./ghost-anchor.js";
|
|
35
37
|
export { runEntityRetire } from "./retire.js";
|
|
36
38
|
export type { EntityRetireOptions, EntityRetireResult, } from "./retire.js";
|
|
37
39
|
export { runFrontmatterFreshness, } from "./frontmatter.js";
|
package/dist/gc/index.js
CHANGED
|
@@ -23,6 +23,7 @@ export { runDocClaimsVsRuntime } from "./doc-claims.js";
|
|
|
23
23
|
export { runDocGardening } from "./doc-gardening.js";
|
|
24
24
|
export { extractSectionByAnchor, runDocSourceDrift, slugifyHeading, } from "./doc-source-drift.js";
|
|
25
25
|
export { runEntityOrphan } from "./entity-orphan.js";
|
|
26
|
+
export { resolveGhostBlock, runGhostReanchor } from "./ghost-anchor.js";
|
|
26
27
|
export { runEntityRetire } from "./retire.js";
|
|
27
28
|
export { runFrontmatterFreshness, } from "./frontmatter.js";
|
|
28
29
|
export { runGeneratorDrift } from "./generator-drift.js";
|
package/dist/gc/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gc/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAYH,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,EAAE,WAAW,IAAI,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAK/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAKnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAOxD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAKrD,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,cAAc,GACf,MAAM,uBAAuB,CAAC;AAK/B,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAOrD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAK9C,OAAO,EACL,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAK1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAKzD,OAAO,EAAE,gBAAgB,IAAI,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAIjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAK7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAKvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAIpD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAKpD,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gc/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAYH,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,EAAE,WAAW,IAAI,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAK/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAKnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAOxD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAKrD,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,cAAc,GACf,MAAM,uBAAuB,CAAC;AAK/B,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAOrD,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAKxE,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAK9C,OAAO,EACL,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAK1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAKzD,OAAO,EAAE,gBAAgB,IAAI,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAIjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAK7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAKvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAIpD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAKpD,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GC pass — runtime-state pruning.
|
|
3
|
+
*
|
|
4
|
+
* Every other GC pass guards ground/doc *integrity*. This one guards
|
|
5
|
+
* `.cairn/` *footprint*: the per-clone runtime artifacts that grow without
|
|
6
|
+
* bound because nothing on the write path ever trims them. Left alone they
|
|
7
|
+
* reach tens of megabytes (observed: a 3 MB telemetry log, a 26 MB Haiku
|
|
8
|
+
* cache, a dozen 400 KB baseline snapshots) — pure derived/advisory state
|
|
9
|
+
* with no reader that needs the history.
|
|
10
|
+
*
|
|
11
|
+
* Three operations, all idempotent and best-effort (a single failure never
|
|
12
|
+
* aborts the rest):
|
|
13
|
+
*
|
|
14
|
+
* 1. Rotate append-only telemetry/advisory logs to a trailing window.
|
|
15
|
+
* ONLY logs that are pure append + never replayed:
|
|
16
|
+
* · staleness/mcp-calls.jsonl — MCP call telemetry (the trace sink
|
|
17
|
+
* in ~/.cairn/ owns the durable copy)
|
|
18
|
+
* · staleness/log.jsonl — drift events; only the recent tail
|
|
19
|
+
* is ever read
|
|
20
|
+
* Deliberately NOT touched — these are work queues / undo history whose
|
|
21
|
+
* head still matters: layer-a-deferred.jsonl, pre-commit-deferred.jsonl,
|
|
22
|
+
* state/align-undo-log.jsonl.
|
|
23
|
+
*
|
|
24
|
+
* 2. Evict Haiku cache entries older than the 30-day window the cache
|
|
25
|
+
* itself advertises. `claude/cache.ts` only evicts lazily on a *re-read*
|
|
26
|
+
* of the same key, so one-shot prompts (e.g. the thousands of per-file
|
|
27
|
+
* init classifications) are cached once and never looked up again →
|
|
28
|
+
* never evicted. This is the sweep half.
|
|
29
|
+
*
|
|
30
|
+
* 3. Keep only the newest N baseline snapshots per prefix. `baseline-audit`
|
|
31
|
+
* writes a fresh `components-<ts>.yaml` every audit and never reaps the
|
|
32
|
+
* old ones; only the latest is ever diffed against.
|
|
33
|
+
*
|
|
34
|
+
* Safe-class by construction (deletes derived/advisory state only), so the
|
|
35
|
+
* sweep runs it unconditionally and SessionStart calls it best-effort — no
|
|
36
|
+
* operator confirmation, no commit.
|
|
37
|
+
*/
|
|
38
|
+
export interface RotatedLog {
|
|
39
|
+
path: string;
|
|
40
|
+
fromBytes: number;
|
|
41
|
+
toBytes: number;
|
|
42
|
+
}
|
|
43
|
+
export interface RuntimePruneResult {
|
|
44
|
+
rotatedLogs: RotatedLog[];
|
|
45
|
+
haikuEvicted: number;
|
|
46
|
+
baselineRemoved: string[];
|
|
47
|
+
/** Total bytes reclaimed across all three operations. */
|
|
48
|
+
bytesFreed: number;
|
|
49
|
+
}
|
|
50
|
+
export interface RuntimePruneOptions {
|
|
51
|
+
repoRoot: string;
|
|
52
|
+
/** Override "now" for the age checks (tests). */
|
|
53
|
+
now?: Date;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Run all three runtime-prune operations against `repoRoot`. Best-effort
|
|
57
|
+
* and idempotent — safe to call from the GC sweep and from SessionStart.
|
|
58
|
+
*/
|
|
59
|
+
export declare function runRuntimePrune(opts: RuntimePruneOptions): RuntimePruneResult;
|