@isaacriehm/cairn-core 0.19.1 → 0.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.
- 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/index.d.ts +0 -2
- package/dist/attention/index.js +0 -2
- package/dist/attention/index.js.map +1 -1
- package/dist/attention/restore.d.ts +1 -1
- package/dist/attention/restore.js +1 -1
- package/dist/attention/source-strip.d.ts +2 -2
- package/dist/attention/source-strip.js +4 -3
- package/dist/attention/source-strip.js.map +1 -1
- package/dist/components/audit.d.ts +7 -1
- package/dist/components/audit.js +144 -72
- package/dist/components/audit.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 +102 -9
- 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 +4 -5
- package/dist/gc/citation-integrity.js +11 -33
- package/dist/gc/citation-integrity.js.map +1 -1
- package/dist/gc/classify.js +3 -16
- package/dist/gc/classify.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 +66 -12
- 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/sweep.d.ts +1 -1
- package/dist/gc/sweep.js +13 -1
- 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.d.ts +1 -2
- package/dist/hooks/post-tool-use/ask-user-blocked.js +3 -4
- package/dist/hooks/post-tool-use/ask-user-blocked.js.map +1 -1
- package/dist/hooks/post-tool-use/citation-scanner.d.ts +9 -7
- 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.d.ts +1 -5
- package/dist/hooks/post-tool-use/write-guardian.js +25 -18
- 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 +103 -4
- package/dist/hooks/runners/session-start.js.map +1 -1
- package/dist/hooks/runners/stop.js +46 -42
- 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 +4 -0
- package/dist/index.js +3 -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.d.ts +3 -2
- package/dist/init/detect-components.js +33 -15
- package/dist/init/detect-components.js.map +1 -1
- package/dist/init/detect.d.ts +1 -5
- package/dist/init/detect.js +157 -143
- package/dist/init/detect.js.map +1 -1
- package/dist/init/eta-calibration.js +2 -2
- package/dist/init/eta-calibration.js.map +1 -1
- package/dist/init/glob-inference.js +24 -0
- package/dist/init/glob-inference.js.map +1 -1
- package/dist/init/index.d.ts +4 -4
- package/dist/init/index.js +2 -2
- package/dist/init/index.js.map +1 -1
- package/dist/init/init.d.ts +8 -0
- package/dist/init/init.js +16 -20
- package/dist/init/init.js.map +1 -1
- package/dist/init/mapper-merge.d.ts +1 -4
- package/dist/init/mapper-merge.js +4 -17
- package/dist/init/mapper-merge.js.map +1 -1
- package/dist/init/mapper-parallel.js +1 -1
- package/dist/init/mapper-parallel.js.map +1 -1
- package/dist/init/mapper-prompts.d.ts +1 -23
- package/dist/init/mapper-prompts.js +1 -25
- package/dist/init/mapper-prompts.js.map +1 -1
- package/dist/init/mapper.d.ts +0 -6
- package/dist/init/mapper.js +2 -5
- package/dist/init/mapper.js.map +1 -1
- package/dist/init/module-slicer.js +3 -24
- package/dist/init/module-slicer.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/overlay.js +5 -16
- package/dist/init/overlay.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 +3 -3
- 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 +1 -2
- package/dist/init/source-comments/strip-replace.js +19 -3
- package/dist/init/source-comments/strip-replace.js.map +1 -1
- package/dist/init/source-comments/walker.js +8 -79
- package/dist/init/source-comments/walker.js.map +1 -1
- package/dist/init/types.d.ts +8 -16
- package/dist/init/walker.d.ts +1 -1
- package/dist/init/walker.js +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 -4
- package/dist/mcp/schemas.js +23 -1
- package/dist/mcp/schemas.js.map +1 -1
- package/dist/mcp/serve.js +9 -0
- package/dist/mcp/serve.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/decision-get.js +2 -2
- package/dist/mcp/tools/decision-get.js.map +1 -1
- package/dist/mcp/tools/index.js +5 -6
- 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/mission-advance.d.ts +3 -4
- package/dist/mcp/tools/mission-advance.js +15 -19
- 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 +17 -9
- package/dist/mcp/tools/record-decision.js.map +1 -1
- package/dist/mcp/tools/resolve-attention.js +70 -34
- 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 +24 -0
- package/dist/migrate/config-io.js +73 -0
- package/dist/migrate/config-io.js.map +1 -0
- 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 +6 -0
- package/dist/migrate/index.js +6 -0
- package/dist/migrate/index.js.map +1 -0
- package/dist/migrate/migrations/0001-drop-dead-config-fields.d.ts +12 -0
- package/dist/migrate/migrations/0001-drop-dead-config-fields.js +39 -0
- package/dist/migrate/migrations/0001-drop-dead-config-fields.js.map +1 -0
- 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/registry.d.ts +9 -0
- package/dist/migrate/registry.js +11 -0
- package/dist/migrate/registry.js.map +1 -0
- package/dist/migrate/runner.d.ts +45 -0
- package/dist/migrate/runner.js +177 -0
- package/dist/migrate/runner.js.map +1 -0
- package/dist/migrate/semver.d.ts +11 -0
- package/dist/migrate/semver.js +35 -0
- package/dist/migrate/semver.js.map +1 -0
- package/dist/migrate/types.d.ts +47 -0
- package/dist/migrate/types.js +13 -0
- package/dist/migrate/types.js.map +1 -0
- package/dist/missions/task-link.js +7 -8
- 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 +6 -11
- package/dist/sensors/catalog.js.map +1 -1
- package/dist/sensors/decisions.js +55 -19
- package/dist/sensors/decisions.js.map +1 -1
- package/dist/sensors/diff.d.ts +12 -0
- package/dist/sensors/diff.js +103 -0
- package/dist/sensors/diff.js.map +1 -1
- package/dist/sensors/index.d.ts +4 -5
- package/dist/sensors/index.js +2 -3
- package/dist/sensors/index.js.map +1 -1
- package/dist/sensors/runner.d.ts +34 -37
- package/dist/sensors/runner.js +63 -53
- package/dist/sensors/runner.js.map +1 -1
- package/dist/sensors/stub-catalog.d.ts +6 -3
- package/dist/sensors/stub-catalog.js +7 -19
- package/dist/sensors/stub-catalog.js.map +1 -1
- package/dist/sensors/types.d.ts +11 -55
- package/dist/sensors/types.js +4 -8
- package/dist/sensors/types.js.map +1 -1
- package/dist/session-start/build.js +36 -21
- package/dist/session-start/build.js.map +1 -1
- package/dist/session-start/templates.d.ts +1 -1
- package/dist/session-start/templates.js +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.d.ts +3 -4
- package/dist/tasks/lifecycle.js +19 -21
- 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 -22
- package/templates/.github/workflows/cairn-check.yml +8 -0
- package/dist/attention/bulk-accept.d.ts +0 -78
- package/dist/attention/bulk-accept.js +0 -348
- package/dist/attention/bulk-accept.js.map +0 -1
- package/dist/attention/serve/api.d.ts +0 -24
- package/dist/attention/serve/api.js +0 -383
- package/dist/attention/serve/api.js.map +0 -1
- package/dist/attention/serve/index.d.ts +0 -63
- package/dist/attention/serve/index.js +0 -219
- package/dist/attention/serve/index.js.map +0 -1
- 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
- package/dist/mcp/tools/attention-serve.d.ts +0 -23
- package/dist/mcp/tools/attention-serve.js +0 -84
- package/dist/mcp/tools/attention-serve.js.map +0 -1
- package/dist/mcp/tools/attention-wait.d.ts +0 -18
- package/dist/mcp/tools/attention-wait.js +0 -84
- package/dist/mcp/tools/attention-wait.js.map +0 -1
- package/dist/mcp/tools/bulk-accept-attention.d.ts +0 -22
- package/dist/mcp/tools/bulk-accept-attention.js +0 -84
- package/dist/mcp/tools/bulk-accept-attention.js.map +0 -1
- package/dist/sensors/attestation.d.ts +0 -44
- package/dist/sensors/attestation.js +0 -262
- package/dist/sensors/attestation.js.map +0 -1
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ghost state backup (ghost-mode design).
|
|
3
|
+
*
|
|
4
|
+
* Ghost state lives out-of-repo at `<stateHome>/<repo-id>/`, so it never rides
|
|
5
|
+
* the client repo's history — which means it has no version control at all
|
|
6
|
+
* unless Cairn gives it some. The decided design: the state dir is its OWN git
|
|
7
|
+
* repo (unrelated to the client repo), auto-committed on the Stop hook (fires
|
|
8
|
+
* every turn). The operator adds a private per-client remote and pushes →
|
|
9
|
+
* off-machine backup + full history/rollback of the decision memory.
|
|
10
|
+
*
|
|
11
|
+
* The seeded `.gitignore` already sits at the state-dir root in ghost (the
|
|
12
|
+
* `.cairn/.gitignore` denylist, redirected out-of-repo by the seed), so the
|
|
13
|
+
* backup repo tracks exactly the durable ground state (decisions, invariants,
|
|
14
|
+
* config, scope-index, brand, canonical-map) and skips churn (sessions, runs,
|
|
15
|
+
* events, locks, caches, init-state). No separate ignore list to maintain.
|
|
16
|
+
*
|
|
17
|
+
* Local commit only — the Stop hook is the hot turn-end path, so a network
|
|
18
|
+
* push never runs here; the operator pushes on their own cadence. Strictly
|
|
19
|
+
* `isGhost`-gated: a committed repo's `.cairn/` is inside the client tree and
|
|
20
|
+
* versioned by the operator's normal git flow — a nested backup repo there
|
|
21
|
+
* would be a footprint bug.
|
|
22
|
+
*/
|
|
23
|
+
export interface GhostBackupResult {
|
|
24
|
+
/** A new snapshot commit was created this call. */
|
|
25
|
+
committed: boolean;
|
|
26
|
+
/** The state dir was `git init`-ed this call (first backup). */
|
|
27
|
+
initialized: boolean;
|
|
28
|
+
/** Why nothing was committed (when `committed` is false). */
|
|
29
|
+
reason?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Commit the ghost state dir's durable ground state. `git init`s the dir on
|
|
33
|
+
* first call. Skips cleanly when nothing tracked-worthy changed (no empty
|
|
34
|
+
* commits). Best-effort: every failure is swallowed + logged so a backup
|
|
35
|
+
* problem never blocks the end of a turn. No-op outside ghost.
|
|
36
|
+
*/
|
|
37
|
+
export declare function ghostBackupCommit(repoRoot: string): GhostBackupResult;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ghost state backup (ghost-mode design).
|
|
3
|
+
*
|
|
4
|
+
* Ghost state lives out-of-repo at `<stateHome>/<repo-id>/`, so it never rides
|
|
5
|
+
* the client repo's history — which means it has no version control at all
|
|
6
|
+
* unless Cairn gives it some. The decided design: the state dir is its OWN git
|
|
7
|
+
* repo (unrelated to the client repo), auto-committed on the Stop hook (fires
|
|
8
|
+
* every turn). The operator adds a private per-client remote and pushes →
|
|
9
|
+
* off-machine backup + full history/rollback of the decision memory.
|
|
10
|
+
*
|
|
11
|
+
* The seeded `.gitignore` already sits at the state-dir root in ghost (the
|
|
12
|
+
* `.cairn/.gitignore` denylist, redirected out-of-repo by the seed), so the
|
|
13
|
+
* backup repo tracks exactly the durable ground state (decisions, invariants,
|
|
14
|
+
* config, scope-index, brand, canonical-map) and skips churn (sessions, runs,
|
|
15
|
+
* events, locks, caches, init-state). No separate ignore list to maintain.
|
|
16
|
+
*
|
|
17
|
+
* Local commit only — the Stop hook is the hot turn-end path, so a network
|
|
18
|
+
* push never runs here; the operator pushes on their own cadence. Strictly
|
|
19
|
+
* `isGhost`-gated: a committed repo's `.cairn/` is inside the client tree and
|
|
20
|
+
* versioned by the operator's normal git flow — a nested backup repo there
|
|
21
|
+
* would be a footprint bug.
|
|
22
|
+
*/
|
|
23
|
+
import { execFileSync } from "node:child_process";
|
|
24
|
+
import { existsSync } from "node:fs";
|
|
25
|
+
import { join } from "node:path";
|
|
26
|
+
import { cairnHome, isGhost } from "@isaacriehm/cairn-state";
|
|
27
|
+
import { logger } from "../logger.js";
|
|
28
|
+
const log = logger("ghost-backup");
|
|
29
|
+
// Inline commit identity — never persisted to the repo's config, never the
|
|
30
|
+
// operator's real name/email (no operator-private strings, and no dependency on
|
|
31
|
+
// a global git identity being present).
|
|
32
|
+
const COMMIT_IDENTITY = [
|
|
33
|
+
"-c",
|
|
34
|
+
"user.name=Cairn",
|
|
35
|
+
"-c",
|
|
36
|
+
"user.email=cairn@localhost",
|
|
37
|
+
];
|
|
38
|
+
function git(cwd, args) {
|
|
39
|
+
return execFileSync("git", args, {
|
|
40
|
+
cwd,
|
|
41
|
+
encoding: "utf8",
|
|
42
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Commit the ghost state dir's durable ground state. `git init`s the dir on
|
|
47
|
+
* first call. Skips cleanly when nothing tracked-worthy changed (no empty
|
|
48
|
+
* commits). Best-effort: every failure is swallowed + logged so a backup
|
|
49
|
+
* problem never blocks the end of a turn. No-op outside ghost.
|
|
50
|
+
*/
|
|
51
|
+
export function ghostBackupCommit(repoRoot) {
|
|
52
|
+
if (!isGhost(repoRoot)) {
|
|
53
|
+
return { committed: false, initialized: false, reason: "not-ghost" };
|
|
54
|
+
}
|
|
55
|
+
const dir = cairnHome(repoRoot);
|
|
56
|
+
if (!existsSync(dir)) {
|
|
57
|
+
return { committed: false, initialized: false, reason: "no-state-dir" };
|
|
58
|
+
}
|
|
59
|
+
let initialized = false;
|
|
60
|
+
try {
|
|
61
|
+
if (!existsSync(join(dir, ".git"))) {
|
|
62
|
+
git(dir, ["init", "-q"]);
|
|
63
|
+
initialized = true;
|
|
64
|
+
}
|
|
65
|
+
git(dir, ["add", "-A"]);
|
|
66
|
+
// After staging, an empty index diff means nothing durable changed (the
|
|
67
|
+
// `.gitignore` filtered the churn) — skip rather than fail on an empty
|
|
68
|
+
// commit.
|
|
69
|
+
const staged = git(dir, ["status", "--porcelain"]).trim();
|
|
70
|
+
if (staged.length === 0) {
|
|
71
|
+
return { committed: false, initialized, reason: "clean" };
|
|
72
|
+
}
|
|
73
|
+
const ts = new Date().toISOString();
|
|
74
|
+
git(dir, [...COMMIT_IDENTITY, "commit", "-q", "-m", `cairn ghost snapshot ${ts}`]);
|
|
75
|
+
return { committed: true, initialized };
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
log.warn({ err: err instanceof Error ? err.message : String(err) }, "ghost backup commit failed");
|
|
79
|
+
return { committed: false, initialized, reason: "git-error" };
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=ghost-backup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ghost-backup.js","sourceRoot":"","sources":["../../src/hooks/ghost-backup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,MAAM,GAAG,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;AAEnC,2EAA2E;AAC3E,gFAAgF;AAChF,wCAAwC;AACxC,MAAM,eAAe,GAAG;IACtB,IAAI;IACJ,iBAAiB;IACjB,IAAI;IACJ,4BAA4B;CAC7B,CAAC;AAWF,SAAS,GAAG,CAAC,GAAW,EAAE,IAAc;IACtC,OAAO,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE;QAC/B,GAAG;QACH,QAAQ,EAAE,MAAM;QAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;KACpC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IACvE,CAAC;IACD,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IAChC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;IAC1E,CAAC;IAED,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;YACnC,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;YACzB,WAAW,GAAG,IAAI,CAAC;QACrB,CAAC;QACD,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;QACxB,wEAAwE;QACxE,uEAAuE;QACvE,UAAU;QACV,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QAC5D,CAAC;QACD,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACpC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,eAAe,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,wBAAwB,EAAE,EAAE,CAAC,CAAC,CAAC;QACnF,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CACN,EAAE,GAAG,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EACzD,4BAA4B,CAC7B,CAAC;QACF,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAChE,CAAC;AACH,CAAC"}
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
* optional config file.
|
|
9
9
|
*/
|
|
10
10
|
import { existsSync, readFileSync } from "node:fs";
|
|
11
|
-
import { join } from "node:path";
|
|
12
11
|
import { parse as parseYaml } from "yaml";
|
|
13
12
|
import { z } from "zod";
|
|
13
|
+
import { cairnDir } from "@isaacriehm/cairn-state";
|
|
14
14
|
const CopySafetySchema = z.object({
|
|
15
15
|
enabled: z.boolean().optional(),
|
|
16
16
|
globs: z.array(z.string()).optional(),
|
|
@@ -55,7 +55,7 @@ const DEFAULT = {
|
|
|
55
55
|
allowlist: [],
|
|
56
56
|
};
|
|
57
57
|
export function readCopySafetyConfig(repoRoot) {
|
|
58
|
-
const path =
|
|
58
|
+
const path = cairnDir(repoRoot, "config", "sensors.yaml");
|
|
59
59
|
if (!existsSync(path))
|
|
60
60
|
return defaultsCopy();
|
|
61
61
|
let parsed;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"allowlist-reader.js","sourceRoot":"","sources":["../../../src/hooks/post-tool-use/allowlist-reader.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"allowlist-reader.js","sourceRoot":"","sources":["../../../src/hooks/post-tool-use/allowlist-reader.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
* so the Stop hook's stalled-task scanner skips it (the work can't
|
|
5
5
|
* progress until the operator answers).
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
* existing `blocked_on: operator` skip rule in
|
|
7
|
+
* Producer pair for the `blocked_on: operator` skip rule in
|
|
9
8
|
* `runners/stop.ts:scanStalledRunningTasks`.
|
|
10
9
|
*
|
|
11
10
|
* No-op when:
|
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
* so the Stop hook's stalled-task scanner skips it (the work can't
|
|
5
5
|
* progress until the operator answers).
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
* existing `blocked_on: operator` skip rule in
|
|
7
|
+
* Producer pair for the `blocked_on: operator` skip rule in
|
|
9
8
|
* `runners/stop.ts:scanStalledRunningTasks`.
|
|
10
9
|
*
|
|
11
10
|
* No-op when:
|
|
@@ -16,13 +15,13 @@
|
|
|
16
15
|
* - `blocked_on: operator` already present (idempotent).
|
|
17
16
|
*/
|
|
18
17
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
19
|
-
import { join } from "node:path";
|
|
20
18
|
import { z } from "zod";
|
|
21
19
|
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
|
22
20
|
import { resolveRepoRoot } from "../../session-start/index.js";
|
|
23
21
|
import { findCurrentActiveTask } from "../../tasks/index.js";
|
|
24
22
|
import { readHookStdin } from "../runners/payload.js";
|
|
25
23
|
import { logger } from "../../logger.js";
|
|
24
|
+
import { cairnDir } from "@isaacriehm/cairn-state";
|
|
26
25
|
const log = logger("hooks.post-tool-use.ask-user-blocked");
|
|
27
26
|
const PayloadSchema = z
|
|
28
27
|
.object({
|
|
@@ -74,7 +73,7 @@ export async function runAskUserBlockedHook() {
|
|
|
74
73
|
emitShapeB("");
|
|
75
74
|
return;
|
|
76
75
|
}
|
|
77
|
-
const statusPath =
|
|
76
|
+
const statusPath = cairnDir(repoRoot, "tasks", "active", taskId, "status.yaml");
|
|
78
77
|
if (!existsSync(statusPath)) {
|
|
79
78
|
emitShapeB("");
|
|
80
79
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ask-user-blocked.js","sourceRoot":"","sources":["../../../src/hooks/post-tool-use/ask-user-blocked.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ask-user-blocked.js","sourceRoot":"","sources":["../../../src/hooks/post-tool-use/ask-user-blocked.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Scans the visible body of a Read tool's content for cairn citation
|
|
3
|
-
* patterns: §INV invariants
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* patterns: §INV invariants and §DEC decisions. Both `§INV-<hash>` and
|
|
4
|
+
* `§DEC-<hash>` are the canonical bare-symbol citation forms produced by the
|
|
5
|
+
* strip-replace phase and resolved by the read-enricher into the legend.
|
|
6
|
+
*
|
|
7
|
+
* (`TODO(TSK-…)` source markers used to be a third pattern, but nothing ever
|
|
8
|
+
* emitted them once the Phase-12 strip stub was removed, so the dead reader was
|
|
9
|
+
* cut — task↔source links can return later as a `MarkerProjection` output.)
|
|
7
10
|
*
|
|
8
11
|
* Per READ_ENRICHER_SPEC §3 — line numbers in the legend should reflect
|
|
9
12
|
* the original source line, so when content is `cat -n`-prefixed
|
|
@@ -11,15 +14,14 @@
|
|
|
11
14
|
* number as the reported line. The body text itself is NEVER mutated.
|
|
12
15
|
*/
|
|
13
16
|
export interface CitationMatch {
|
|
14
|
-
/** Citation id, e.g. "INV-2323232" or "
|
|
17
|
+
/** Citation id, e.g. "INV-2323232" or "DEC-a3f7b2c". */
|
|
15
18
|
id: string;
|
|
16
19
|
/** 1-indexed line number from cat -n prefix, or iteration index. */
|
|
17
20
|
line: number;
|
|
18
21
|
}
|
|
19
22
|
export interface ScannedCitations {
|
|
20
23
|
invariants: CitationMatch[];
|
|
21
|
-
|
|
22
|
-
/** §DEC-NNNN citations resolved against the decisions ledger. */
|
|
24
|
+
/** §DEC-<hash> citations resolved against the decisions ledger. */
|
|
23
25
|
decisions: CitationMatch[];
|
|
24
26
|
}
|
|
25
27
|
export declare function scanCitations(content: string): ScannedCitations;
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Scans the visible body of a Read tool's content for cairn citation
|
|
3
|
-
* patterns: §INV invariants
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* patterns: §INV invariants and §DEC decisions. Both `§INV-<hash>` and
|
|
4
|
+
* `§DEC-<hash>` are the canonical bare-symbol citation forms produced by the
|
|
5
|
+
* strip-replace phase and resolved by the read-enricher into the legend.
|
|
6
|
+
*
|
|
7
|
+
* (`TODO(TSK-…)` source markers used to be a third pattern, but nothing ever
|
|
8
|
+
* emitted them once the Phase-12 strip stub was removed, so the dead reader was
|
|
9
|
+
* cut — task↔source links can return later as a `MarkerProjection` output.)
|
|
7
10
|
*
|
|
8
11
|
* Per READ_ENRICHER_SPEC §3 — line numbers in the legend should reflect
|
|
9
12
|
* the original source line, so when content is `cat -n`-prefixed
|
|
@@ -11,7 +14,6 @@
|
|
|
11
14
|
* number as the reported line. The body text itself is NEVER mutated.
|
|
12
15
|
*/
|
|
13
16
|
const INVARIANT_RE = /§INV-([0-9a-f]{7,})/g;
|
|
14
|
-
const TODO_RE = /TODO\(TSK-([^)]+)\)/g;
|
|
15
17
|
// Require `§` prefix so plain `DEC-<hash>` strings (URL fragments, prose
|
|
16
18
|
// citations in markdown bodies, GitHub-style refs) don't false-match.
|
|
17
19
|
// The strip-replace phase ALWAYS emits the `§` prefix on accepted
|
|
@@ -20,10 +22,9 @@ const DEC_RE = /§DEC-([0-9a-f]{7,})/g;
|
|
|
20
22
|
const CAT_N_PREFIX_RE = /^(\d+)\t/;
|
|
21
23
|
export function scanCitations(content) {
|
|
22
24
|
const invariants = [];
|
|
23
|
-
const todos = [];
|
|
24
25
|
const decisions = [];
|
|
25
26
|
if (content.length === 0) {
|
|
26
|
-
return { invariants,
|
|
27
|
+
return { invariants, decisions };
|
|
27
28
|
}
|
|
28
29
|
const lines = content.split(/\r?\n/);
|
|
29
30
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -47,12 +48,6 @@ export function scanCitations(content) {
|
|
|
47
48
|
continue;
|
|
48
49
|
invariants.push({ id: `INV-${digits}`, line: lineNumber });
|
|
49
50
|
}
|
|
50
|
-
for (const m of lineText.matchAll(TODO_RE)) {
|
|
51
|
-
const tail = m[1];
|
|
52
|
-
if (tail === undefined)
|
|
53
|
-
continue;
|
|
54
|
-
todos.push({ id: `TSK-${tail}`, line: lineNumber });
|
|
55
|
-
}
|
|
56
51
|
for (const m of lineText.matchAll(DEC_RE)) {
|
|
57
52
|
const digits = m[1];
|
|
58
53
|
if (digits === undefined)
|
|
@@ -60,6 +55,6 @@ export function scanCitations(content) {
|
|
|
60
55
|
decisions.push({ id: `DEC-${digits}`, line: lineNumber });
|
|
61
56
|
}
|
|
62
57
|
}
|
|
63
|
-
return { invariants,
|
|
58
|
+
return { invariants, decisions };
|
|
64
59
|
}
|
|
65
60
|
//# sourceMappingURL=citation-scanner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"citation-scanner.js","sourceRoot":"","sources":["../../../src/hooks/post-tool-use/citation-scanner.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"citation-scanner.js","sourceRoot":"","sources":["../../../src/hooks/post-tool-use/citation-scanner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAeH,MAAM,YAAY,GAAG,sBAAsB,CAAC;AAC5C,yEAAyE;AACzE,sEAAsE;AACtE,kEAAkE;AAClE,mEAAmE;AACnE,MAAM,MAAM,GAAG,sBAAsB,CAAC;AACtC,MAAM,eAAe,GAAG,UAAU,CAAC;AAEnC,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,MAAM,UAAU,GAAoB,EAAE,CAAC;IACvC,MAAM,SAAS,GAAoB,EAAE,CAAC;IAEtC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;IACnC,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3B,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAC/C,IAAI,QAAgB,CAAC;QACrB,IAAI,UAAkB,CAAC;QACvB,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;YACtD,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAC3D,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACN,UAAU,GAAG,CAAC,GAAG,CAAC,CAAC;YACnB,QAAQ,GAAG,GAAG,CAAC;QACjB,CAAC;QAED,uDAAuD;QACvD,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YAChD,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACpB,IAAI,MAAM,KAAK,SAAS;gBAAE,SAAS;YACnC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,OAAO,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;QAC7D,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1C,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACpB,IAAI,MAAM,KAAK,SAAS;gBAAE,SAAS;YACnC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,OAAO,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;AACnC,CAAC"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* (decisions/invariants in scope) when one was found for the file.
|
|
6
6
|
*/
|
|
7
7
|
import type { ScannedCitations } from "./citation-scanner.js";
|
|
8
|
-
import type { DecisionsLedgerSnapshot, LedgerSnapshot
|
|
8
|
+
import type { DecisionsLedgerSnapshot, LedgerSnapshot } from "@isaacriehm/cairn-state";
|
|
9
9
|
export interface ScopeIndexHint {
|
|
10
10
|
/** DEC-IDs in scope for the file. */
|
|
11
11
|
decisions: string[];
|
|
@@ -21,4 +21,4 @@ export interface ScopeIndexHint {
|
|
|
21
21
|
* can call `cairn_propose_decision({ slug })` to surface a passage
|
|
22
22
|
* the operator has clearly committed to as a rule.
|
|
23
23
|
*/
|
|
24
|
-
export declare function buildLegend(matches: ScannedCitations, invariantsLedger: LedgerSnapshot | null, decisionsLedger: DecisionsLedgerSnapshot | null, scopeHint: ScopeIndexHint | null,
|
|
24
|
+
export declare function buildLegend(matches: ScannedCitations, invariantsLedger: LedgerSnapshot | null, decisionsLedger: DecisionsLedgerSnapshot | null, scopeHint: ScopeIndexHint | null, unpromotedCandidates?: number): string | null;
|
|
@@ -19,11 +19,10 @@ function row(content) {
|
|
|
19
19
|
* can call `cairn_propose_decision({ slug })` to surface a passage
|
|
20
20
|
* the operator has clearly committed to as a rule.
|
|
21
21
|
*/
|
|
22
|
-
export function buildLegend(matches, invariantsLedger, decisionsLedger, scopeHint,
|
|
22
|
+
export function buildLegend(matches, invariantsLedger, decisionsLedger, scopeHint, unpromotedCandidates = 0) {
|
|
23
23
|
const hasScopeHint = scopeHint !== null &&
|
|
24
24
|
(scopeHint.decisions.length > 0 || scopeHint.invariants.length > 0);
|
|
25
25
|
const hasCitations = matches.invariants.length > 0 ||
|
|
26
|
-
matches.todos.length > 0 ||
|
|
27
26
|
matches.decisions.length > 0;
|
|
28
27
|
const hasCandidates = unpromotedCandidates >= 1;
|
|
29
28
|
if (!hasScopeHint && !hasCitations && !hasCandidates)
|
|
@@ -64,9 +63,6 @@ export function buildLegend(matches, invariantsLedger, decisionsLedger, scopeHin
|
|
|
64
63
|
for (const inv of matches.invariants) {
|
|
65
64
|
lines.push(row(renderInvariant(inv.id, invariantsLedger)));
|
|
66
65
|
}
|
|
67
|
-
for (const todo of matches.todos) {
|
|
68
|
-
lines.push(row(renderTodo(todo.id, resolveTask(todo.id))));
|
|
69
|
-
}
|
|
70
66
|
lines.push(BOTTOM_BORDER);
|
|
71
67
|
return lines.join("\n");
|
|
72
68
|
}
|
|
@@ -114,18 +110,4 @@ function renderInvariant(id, ledger) {
|
|
|
114
110
|
const title = entry.title.length > 0 ? entry.title : "(no title)";
|
|
115
111
|
return `${label} → ${title} [active]`;
|
|
116
112
|
}
|
|
117
|
-
function renderTodo(id, result) {
|
|
118
|
-
// id arrives as "TSK-<id>" — display in the TODO(...) form.
|
|
119
|
-
const label = `TODO(${id})`;
|
|
120
|
-
if (result.found === "not_found") {
|
|
121
|
-
return `${label} → [NOT FOUND]`;
|
|
122
|
-
}
|
|
123
|
-
const title = result.title !== undefined && result.title.length > 0
|
|
124
|
-
? result.title
|
|
125
|
-
: id;
|
|
126
|
-
if (result.found === "done") {
|
|
127
|
-
return `${label} → ${title} [DONE — this TODO can be removed]`;
|
|
128
|
-
}
|
|
129
|
-
return `${label} → ${title} [active]`;
|
|
130
|
-
}
|
|
131
113
|
//# sourceMappingURL=legend-builder.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"legend-builder.js","sourceRoot":"","sources":["../../../src/hooks/post-tool-use/legend-builder.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"legend-builder.js","sourceRoot":"","sources":["../../../src/hooks/post-tool-use/legend-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,7 @@ import { resolveRepoRoot } from "../../session-start/index.js";
|
|
|
11
11
|
import { readHookStdin } from "../runners/payload.js";
|
|
12
12
|
import { executeSotAlign } from "./sot-align.js";
|
|
13
13
|
import { executeWriteGuardian } from "./write-guardian.js";
|
|
14
|
+
import { runComponentFreshness } from "../../components/freshness.js";
|
|
14
15
|
import { logger } from "../../logger.js";
|
|
15
16
|
const log = logger("hooks.post-tool-use.post-write");
|
|
16
17
|
const ClaudePostToolUsePayloadSchema = z.object({
|
|
@@ -104,12 +105,28 @@ export async function runPostWriteHook() {
|
|
|
104
105
|
}
|
|
105
106
|
// 2. Run SoT Align (hint only)
|
|
106
107
|
const alignSummary = await executeSotAlign(payload, repoRoot);
|
|
107
|
-
// 3.
|
|
108
|
+
// 3. Ghost component freshness gate (§3.8.1). Deterministic, NO LLM —
|
|
109
|
+
// detects an identity-relevant change to a registered headerless
|
|
110
|
+
// component and flags it for a (deferred) re-confirm. `isGhost`-gated
|
|
111
|
+
// inside, so committed repos pay nothing. Best-effort: a failure here
|
|
112
|
+
// must never affect the Write.
|
|
113
|
+
let freshnessHint = "";
|
|
114
|
+
try {
|
|
115
|
+
const fr = runComponentFreshness(repoRoot, relPath);
|
|
116
|
+
if (fr.hint)
|
|
117
|
+
freshnessHint = fr.hint;
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
log.warn({ err: err instanceof Error ? err.message : String(err) }, "component freshness gate threw; ignoring");
|
|
121
|
+
}
|
|
122
|
+
// 4. Merge and Emit
|
|
108
123
|
const sections = [];
|
|
109
124
|
if (guard.message)
|
|
110
125
|
sections.push(guard.message);
|
|
111
126
|
if (alignSummary.length > 0)
|
|
112
127
|
sections.push(alignSummary);
|
|
128
|
+
if (freshnessHint.length > 0)
|
|
129
|
+
sections.push(freshnessHint);
|
|
113
130
|
emitShapeB(sections.join("\n\n"));
|
|
114
131
|
}
|
|
115
132
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"post-write.js","sourceRoot":"","sources":["../../../src/hooks/post-tool-use/post-write.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"post-write.js","sourceRoot":"","sources":["../../../src/hooks/post-tool-use/post-write.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,MAAM,GAAG,GAAG,MAAM,CAAC,gCAAgC,CAAC,CAAC;AAErD,MAAM,8BAA8B,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACtC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC1B,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACtC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;QACnB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAChC,mBAAmB;QACnB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACjC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACjC,mBAAmB;QACnB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAC/B,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;IAC3B,aAAa,EAAE,CAAC,CAAC,MAAM,CAAC;QACtB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC9B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC3B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAC9B,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;CAC5B,CAAC,CAAC,WAAW,EAAE,CAAC;AAkBjB,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACxC,IAAI,CAAC;QACH,MAAM,GAAG,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,MAAM,GAAG,8BAA8B,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAC7D,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,iBAAyB;IAC3C,MAAM,GAAG,GAA4B;QACnC,QAAQ,EAAE,IAAI;QACd,kBAAkB,EAAE;YAClB,aAAa,EAAE,aAAa;YAC5B,iBAAiB;SAClB;KACF,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,SAAS,CAAC,MAAc;IAC/B,MAAM,GAAG,GAA2B;QAClC,QAAQ,EAAE,KAAK;QACf,QAAQ,EAAE,OAAO;QACjB,MAAM;KACP,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,aAAa,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QAElC,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC;QAC/B,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACxC,UAAU,CAAC,EAAE,CAAC,CAAC;YACf,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,EAAE,SAAS,CAAC;QAC/C,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpD,UAAU,CAAC,EAAE,CAAC,CAAC;YACf,OAAO;QACT,CAAC;QAED,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QACzC,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACtB,UAAU,CAAC,EAAE,CAAC,CAAC;YACf,OAAO;QACT,CAAC;QAED,8BAA8B;QAC9B,6CAA6C;QAC7C,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,EAAE,OAAO,IAAI,OAAO,CAAC,aAAa,EAAE,IAAI,IAAI,OAAO,CAAC,aAAa,EAAE,MAAM,IAAI,EAAE,CAAC;QACrH,gEAAgE;QAChE,oEAAoE;QACpE,kDAAkD;QAClD,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC3D,MAAM,KAAK,GAAG,oBAAoB,CAAC;YACjC,QAAQ;YACR,OAAO;YACP,OAAO;YACP,OAAO;SACR,CAAC,CAAC;QACH,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC3B,SAAS,CAAC,KAAK,CAAC,OAAO,IAAI,SAAS,CAAC,CAAC;YACtC,OAAO;QACT,CAAC;QAED,+BAA+B;QAC/B,MAAM,YAAY,GAAG,MAAM,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAE9D,sEAAsE;QACtE,oEAAoE;QACpE,yEAAyE;QACzE,yEAAyE;QACzE,kCAAkC;QAClC,IAAI,aAAa,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,qBAAqB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACpD,IAAI,EAAE,CAAC,IAAI;gBAAE,aAAa,GAAG,EAAE,CAAC,IAAI,CAAC;QACvC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,IAAI,CACN,EAAE,GAAG,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EACzD,0CAA0C,CAC3C,CAAC;QACJ,CAAC;QAED,oBAAoB;QACpB,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,IAAI,KAAK,CAAC,OAAO;YAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAChD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACzD,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAE3D,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,GAAG,CAAC,IAAI,CACN,EAAE,GAAG,EAAE,OAAO,EAAE,EAChB,4CAA4C,CAC7C,CAAC;QACF,UAAU,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;AACH,CAAC"}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* `cairn hook read-enrich` — PostToolUse hook on the Read tool.
|
|
3
3
|
*
|
|
4
4
|
* Scans the file content the agent just read for cairn citation
|
|
5
|
-
* patterns (`§INV
|
|
6
|
-
*
|
|
5
|
+
* patterns (`§INV-<hash>`, `§DEC-<hash>`) and prepends a legend block to
|
|
6
|
+
* Shape-B `additionalContext`.
|
|
7
7
|
*
|
|
8
8
|
* This hook is critical for "Honest Agent" context continuity — it
|
|
9
9
|
* ensures that if an agent reads a file carrying a bare cite, it
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* `cairn hook read-enrich` — PostToolUse hook on the Read tool.
|
|
3
3
|
*
|
|
4
4
|
* Scans the file content the agent just read for cairn citation
|
|
5
|
-
* patterns (`§INV
|
|
6
|
-
*
|
|
5
|
+
* patterns (`§INV-<hash>`, `§DEC-<hash>`) and prepends a legend block to
|
|
6
|
+
* Shape-B `additionalContext`.
|
|
7
7
|
*
|
|
8
8
|
* This hook is critical for "Honest Agent" context continuity — it
|
|
9
9
|
* ensures that if an agent reads a file carrying a bare cite, it
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { resolve, relative } from "node:path";
|
|
16
16
|
import { z } from "zod";
|
|
17
|
-
import { getDecisionsLedger, getInvariantsLedger, getScopeIndexEntry,
|
|
17
|
+
import { getDecisionsLedger, getInvariantsLedger, getScopeIndexEntry, } from "@isaacriehm/cairn-state";
|
|
18
18
|
import { readHookStdin, emitShapeB, appendTelemetry, } from "../runners/payload.js";
|
|
19
19
|
import { resolveRepoRoot } from "../../session-start/index.js";
|
|
20
20
|
import { scanCitations } from "./citation-scanner.js";
|
|
@@ -90,15 +90,13 @@ export async function runReadEnricher() {
|
|
|
90
90
|
const scopeEntry = getScopeIndexEntry(repoRoot, relPath);
|
|
91
91
|
const decisionsLedger = getDecisionsLedger(repoRoot);
|
|
92
92
|
const invariantsLedger = getInvariantsLedger(repoRoot);
|
|
93
|
-
const
|
|
94
|
-
const legend = buildLegend(citations, invariantsLedger, decisionsLedger, scopeEntry, resolveTaskFn);
|
|
93
|
+
const legend = buildLegend(citations, invariantsLedger, decisionsLedger, scopeEntry);
|
|
95
94
|
outcome = {
|
|
96
95
|
ok: true,
|
|
97
96
|
path: relPath,
|
|
98
97
|
citations: {
|
|
99
98
|
invariants: citations.invariants.length,
|
|
100
99
|
decisions: citations.decisions.length,
|
|
101
|
-
todos: citations.todos.length,
|
|
102
100
|
},
|
|
103
101
|
legend_chars: legend?.length ?? 0,
|
|
104
102
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-enricher.js","sourceRoot":"","sources":["../../../src/hooks/post-tool-use/read-enricher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"read-enricher.js","sourceRoot":"","sources":["../../../src/hooks/post-tool-use/read-enricher.ts"],"names":[],"mappings":"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"}
|
|
@@ -54,7 +54,7 @@ import { z } from "zod";
|
|
|
54
54
|
import { readHookStdin } from "../runners/payload.js";
|
|
55
55
|
import { resolveRepoRoot } from "../../session-start/index.js";
|
|
56
56
|
import { runClaude } from "../../claude/index.js";
|
|
57
|
-
import { bindDec, bodyContentHash, decisionsDir, deriveLedgerDecId, deriveLedgerInvId, emptyAnchorMap, invariantsDir, readAnchorMap, readSotBindings, readSotCache, readTopicIndex, recordDriftEvent, setAnchor, setSotCacheEntry, setTopic, topicSlug, writeAlignmentPending, writeAnchorMap, writeSotBindings, writeSotCache, writeTopicIndex, writeFileSafe, } from "@isaacriehm/cairn-state";
|
|
57
|
+
import { cairnDir, bindDec, bodyContentHash, decisionsDir, deriveLedgerDecId, deriveLedgerInvId, emptyAnchorMap, invariantsDir, isGhost, readAnchorMap, readScopeIndex, readSotBindings, readSotCache, readTopicIndex, recordDriftEvent, setAnchor, setSotCacheEntry, setTopic, topicSlug, writeAlignmentPending, writeAnchorMap, writeScopeIndex, writeSotBindings, writeSotCache, writeTopicIndex, writeFileSafe, } from "@isaacriehm/cairn-state";
|
|
58
58
|
import { writeDecisionsLedger, writeInvariantsLedger } from "@isaacriehm/cairn-state";
|
|
59
59
|
import { applyStripReplace, formatBareCitation, } from "../../init/source-comments/strip-replace.js";
|
|
60
60
|
import { appendAlignUndoEntry, } from "../../align-undo/index.js";
|
|
@@ -934,6 +934,28 @@ function surroundingContext(fileSource, startOffset, endOffset) {
|
|
|
934
934
|
const ctxEnd = Math.min(fileSource.length, endOffset + SOURCE_CONTEXT_RADIUS);
|
|
935
935
|
return fileSource.slice(ctxStart, ctxEnd);
|
|
936
936
|
}
|
|
937
|
+
/**
|
|
938
|
+
* Ghost: record the `file → entity` binding in the out-of-repo scope-index at
|
|
939
|
+
* emit time. Committed mode derives this binding later from the in-source `§`
|
|
940
|
+
* cite, but ghost writes no cite (applyStripReplace no-ops), so emit is the only
|
|
941
|
+
* chance to record it — GC liveness (entity-orphan) and read-enricher recall
|
|
942
|
+
* both read this binding. No-op outside ghost. Caller holds the write lock.
|
|
943
|
+
*/
|
|
944
|
+
function bindGhostScope(repoRoot, file, id, isDec) {
|
|
945
|
+
if (!isGhost(repoRoot))
|
|
946
|
+
return;
|
|
947
|
+
const idx = readScopeIndex(repoRoot) ?? {
|
|
948
|
+
generated: new Date().toISOString(),
|
|
949
|
+
files: {},
|
|
950
|
+
};
|
|
951
|
+
const entry = idx.files[file] ?? { decisions: [], invariants: [] };
|
|
952
|
+
const list = isDec ? entry.decisions : entry.invariants;
|
|
953
|
+
if (!list.includes(id))
|
|
954
|
+
list.push(id);
|
|
955
|
+
idx.files[file] = entry;
|
|
956
|
+
idx.generated = new Date().toISOString();
|
|
957
|
+
writeScopeIndex(repoRoot, idx);
|
|
958
|
+
}
|
|
937
959
|
async function emitLedgerEntity(args) {
|
|
938
960
|
const { repoRoot, block, kind } = args;
|
|
939
961
|
const isDec = kind === "decision";
|
|
@@ -1018,6 +1040,8 @@ async function emitLedgerEntity(args) {
|
|
|
1018
1040
|
});
|
|
1019
1041
|
updatedAm.generated = now;
|
|
1020
1042
|
writeAnchorMap(repoRoot, updatedAm);
|
|
1043
|
+
// Ghost: no `§` cite will ever bind this file → id, so record it now.
|
|
1044
|
+
bindGhostScope(repoRoot, block.file, id, isDec);
|
|
1021
1045
|
try {
|
|
1022
1046
|
if (isDec)
|
|
1023
1047
|
writeDecisionsLedger({ repoRoot });
|
|
@@ -1064,7 +1088,7 @@ function writeVerdictCache(repoRoot, scope, blockBody, scopeKey, verdict) {
|
|
|
1064
1088
|
}
|
|
1065
1089
|
function verdictCachePath(repoRoot, scope, blockBody, scopeKey) {
|
|
1066
1090
|
const blockHash = createHash("sha256").update(blockBody, "utf8").digest("hex").slice(0, 12);
|
|
1067
|
-
return
|
|
1091
|
+
return cairnDir(repoRoot, "cache", "haiku", scope, `${blockHash}-${scopeKey}.json`);
|
|
1068
1092
|
}
|
|
1069
1093
|
/* -------------------------------------------------------------------------- */
|
|
1070
1094
|
/* Staleness defer + statusline */
|
|
@@ -1080,7 +1104,7 @@ function deferToStaleness(repoRoot, block, reason) {
|
|
|
1080
1104
|
});
|
|
1081
1105
|
// Append the verbatim block + reason to a Layer-A-specific JSONL so
|
|
1082
1106
|
// Layer C can pick it up without re-walking the file.
|
|
1083
|
-
const path =
|
|
1107
|
+
const path = cairnDir(repoRoot, "staleness", "layer-a-deferred.jsonl");
|
|
1084
1108
|
mkdirSync(dirname(path), { recursive: true });
|
|
1085
1109
|
appendFileSync(path, `${JSON.stringify({
|
|
1086
1110
|
ts: new Date().toISOString(),
|
|
@@ -1321,6 +1345,8 @@ async function emitAugmentSibling(args) {
|
|
|
1321
1345
|
});
|
|
1322
1346
|
updatedAm.generated = now;
|
|
1323
1347
|
writeAnchorMap(repoRoot, updatedAm);
|
|
1348
|
+
// Ghost: bind file → id at emit (augment path) — no cite will record it.
|
|
1349
|
+
bindGhostScope(repoRoot, block.file, id, !isInv);
|
|
1324
1350
|
try {
|
|
1325
1351
|
if (isInv)
|
|
1326
1352
|
writeInvariantsLedger({ repoRoot });
|