@isaacriehm/cairn-core 0.1.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/LICENSE +21 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/claude/error.d.ts +33 -0
- package/dist/claude/error.js +58 -0
- package/dist/claude/error.js.map +1 -0
- package/dist/claude/index.d.ts +3 -0
- package/dist/claude/index.js +3 -0
- package/dist/claude/index.js.map +1 -0
- package/dist/claude/runner.d.ts +11 -0
- package/dist/claude/runner.js +132 -0
- package/dist/claude/runner.js.map +1 -0
- package/dist/claude/types.d.ts +52 -0
- package/dist/claude/types.js +14 -0
- package/dist/claude/types.js.map +1 -0
- package/dist/context/checkpoint.d.ts +10 -0
- package/dist/context/checkpoint.js +29 -0
- package/dist/context/checkpoint.js.map +1 -0
- package/dist/context/handoff-builder.d.ts +11 -0
- package/dist/context/handoff-builder.js +268 -0
- package/dist/context/handoff-builder.js.map +1 -0
- package/dist/context/index.d.ts +11 -0
- package/dist/context/index.js +11 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/spec-delta.d.ts +47 -0
- package/dist/context/spec-delta.js +237 -0
- package/dist/context/spec-delta.js.map +1 -0
- package/dist/decision-capture/capture.d.ts +57 -0
- package/dist/decision-capture/capture.js +186 -0
- package/dist/decision-capture/capture.js.map +1 -0
- package/dist/decision-capture/extractor.d.ts +20 -0
- package/dist/decision-capture/extractor.js +103 -0
- package/dist/decision-capture/extractor.js.map +1 -0
- package/dist/decision-capture/id.d.ts +21 -0
- package/dist/decision-capture/id.js +60 -0
- package/dist/decision-capture/id.js.map +1 -0
- package/dist/decision-capture/index.d.ts +25 -0
- package/dist/decision-capture/index.js +21 -0
- package/dist/decision-capture/index.js.map +1 -0
- package/dist/decision-capture/prompt.d.ts +15 -0
- package/dist/decision-capture/prompt.js +68 -0
- package/dist/decision-capture/prompt.js.map +1 -0
- package/dist/decision-capture/refinement-prompt.d.ts +25 -0
- package/dist/decision-capture/refinement-prompt.js +146 -0
- package/dist/decision-capture/refinement-prompt.js.map +1 -0
- package/dist/decision-capture/refinement-schema.d.ts +52 -0
- package/dist/decision-capture/refinement-schema.js +61 -0
- package/dist/decision-capture/refinement-schema.js.map +1 -0
- package/dist/decision-capture/refinement.d.ts +60 -0
- package/dist/decision-capture/refinement.js +439 -0
- package/dist/decision-capture/refinement.js.map +1 -0
- package/dist/decision-capture/schema.d.ts +70 -0
- package/dist/decision-capture/schema.js +71 -0
- package/dist/decision-capture/schema.js.map +1 -0
- package/dist/decision-capture/types.d.ts +201 -0
- package/dist/decision-capture/types.js +20 -0
- package/dist/decision-capture/types.js.map +1 -0
- package/dist/decision-capture/writer.d.ts +90 -0
- package/dist/decision-capture/writer.js +267 -0
- package/dist/decision-capture/writer.js.map +1 -0
- package/dist/doctor/index.d.ts +48 -0
- package/dist/doctor/index.js +460 -0
- package/dist/doctor/index.js.map +1 -0
- package/dist/events/index.d.ts +15 -0
- package/dist/events/index.js +14 -0
- package/dist/events/index.js.map +1 -0
- package/dist/events/paths.d.ts +2 -0
- package/dist/events/paths.js +6 -0
- package/dist/events/paths.js.map +1 -0
- package/dist/events/reader.d.ts +40 -0
- package/dist/events/reader.js +139 -0
- package/dist/events/reader.js.map +1 -0
- package/dist/events/writer.d.ts +61 -0
- package/dist/events/writer.js +68 -0
- package/dist/events/writer.js.map +1 -0
- package/dist/frontend-types.d.ts +243 -0
- package/dist/frontend-types.js +15 -0
- package/dist/frontend-types.js.map +1 -0
- package/dist/gc/apply.d.ts +26 -0
- package/dist/gc/apply.js +48 -0
- package/dist/gc/apply.js.map +1 -0
- package/dist/gc/canary.d.ts +42 -0
- package/dist/gc/canary.js +134 -0
- package/dist/gc/canary.js.map +1 -0
- package/dist/gc/citation-integrity.d.ts +24 -0
- package/dist/gc/citation-integrity.js +151 -0
- package/dist/gc/citation-integrity.js.map +1 -0
- package/dist/gc/classify.d.ts +25 -0
- package/dist/gc/classify.js +89 -0
- package/dist/gc/classify.js.map +1 -0
- package/dist/gc/completion-integrity.d.ts +22 -0
- package/dist/gc/completion-integrity.js +165 -0
- package/dist/gc/completion-integrity.js.map +1 -0
- package/dist/gc/doc-gardening.d.ts +29 -0
- package/dist/gc/doc-gardening.js +146 -0
- package/dist/gc/doc-gardening.js.map +1 -0
- package/dist/gc/frontmatter.d.ts +35 -0
- package/dist/gc/frontmatter.js +105 -0
- package/dist/gc/frontmatter.js.map +1 -0
- package/dist/gc/generator-drift.d.ts +28 -0
- package/dist/gc/generator-drift.js +53 -0
- package/dist/gc/generator-drift.js.map +1 -0
- package/dist/gc/index.d.ts +42 -0
- package/dist/gc/index.js +30 -0
- package/dist/gc/index.js.map +1 -0
- package/dist/gc/quality-update.d.ts +23 -0
- package/dist/gc/quality-update.js +69 -0
- package/dist/gc/quality-update.js.map +1 -0
- package/dist/gc/scope-coverage.d.ts +20 -0
- package/dist/gc/scope-coverage.js +70 -0
- package/dist/gc/scope-coverage.js.map +1 -0
- package/dist/gc/stub-hits.d.ts +31 -0
- package/dist/gc/stub-hits.js +78 -0
- package/dist/gc/stub-hits.js.map +1 -0
- package/dist/gc/sweep.d.ts +56 -0
- package/dist/gc/sweep.js +205 -0
- package/dist/gc/sweep.js.map +1 -0
- package/dist/gc/types.d.ts +129 -0
- package/dist/gc/types.js +26 -0
- package/dist/gc/types.js.map +1 -0
- package/dist/gc/walk-source.d.ts +14 -0
- package/dist/gc/walk-source.js +59 -0
- package/dist/gc/walk-source.js.map +1 -0
- package/dist/ground/drift.d.ts +8 -0
- package/dist/ground/drift.js +23 -0
- package/dist/ground/drift.js.map +1 -0
- package/dist/ground/frontmatter.d.ts +20 -0
- package/dist/ground/frontmatter.js +49 -0
- package/dist/ground/frontmatter.js.map +1 -0
- package/dist/ground/glob.d.ts +10 -0
- package/dist/ground/glob.js +46 -0
- package/dist/ground/glob.js.map +1 -0
- package/dist/ground/index.d.ts +16 -0
- package/dist/ground/index.js +11 -0
- package/dist/ground/index.js.map +1 -0
- package/dist/ground/ledgers.d.ts +18 -0
- package/dist/ground/ledgers.js +103 -0
- package/dist/ground/ledgers.js.map +1 -0
- package/dist/ground/manifest.d.ts +10 -0
- package/dist/ground/manifest.js +88 -0
- package/dist/ground/manifest.js.map +1 -0
- package/dist/ground/paths.d.ts +20 -0
- package/dist/ground/paths.js +61 -0
- package/dist/ground/paths.js.map +1 -0
- package/dist/ground/quality-grades.d.ts +11 -0
- package/dist/ground/quality-grades.js +98 -0
- package/dist/ground/quality-grades.js.map +1 -0
- package/dist/ground/schemas.d.ts +306 -0
- package/dist/ground/schemas.js +188 -0
- package/dist/ground/schemas.js.map +1 -0
- package/dist/ground/scope-index.d.ts +48 -0
- package/dist/ground/scope-index.js +120 -0
- package/dist/ground/scope-index.js.map +1 -0
- package/dist/ground/walk.d.ts +7 -0
- package/dist/ground/walk.js +53 -0
- package/dist/ground/walk.js.map +1 -0
- package/dist/hooks/bypass-detection.d.ts +28 -0
- package/dist/hooks/bypass-detection.js +106 -0
- package/dist/hooks/bypass-detection.js.map +1 -0
- package/dist/hooks/index.d.ts +12 -0
- package/dist/hooks/index.js +13 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/post-tool-use/allowlist-reader.d.ts +14 -0
- package/dist/hooks/post-tool-use/allowlist-reader.js +69 -0
- package/dist/hooks/post-tool-use/allowlist-reader.js.map +1 -0
- package/dist/hooks/post-tool-use/citation-scanner.d.ts +23 -0
- package/dist/hooks/post-tool-use/citation-scanner.js +59 -0
- package/dist/hooks/post-tool-use/citation-scanner.js.map +1 -0
- package/dist/hooks/post-tool-use/copy-scanner.d.ts +25 -0
- package/dist/hooks/post-tool-use/copy-scanner.js +192 -0
- package/dist/hooks/post-tool-use/copy-scanner.js.map +1 -0
- package/dist/hooks/post-tool-use/index.d.ts +19 -0
- package/dist/hooks/post-tool-use/index.js +15 -0
- package/dist/hooks/post-tool-use/index.js.map +1 -0
- package/dist/hooks/post-tool-use/ledger-cache.d.ts +32 -0
- package/dist/hooks/post-tool-use/ledger-cache.js +236 -0
- package/dist/hooks/post-tool-use/ledger-cache.js.map +1 -0
- package/dist/hooks/post-tool-use/legend-builder.d.ts +15 -0
- package/dist/hooks/post-tool-use/legend-builder.js +84 -0
- package/dist/hooks/post-tool-use/legend-builder.js.map +1 -0
- package/dist/hooks/post-tool-use/read-enricher.d.ts +13 -0
- package/dist/hooks/post-tool-use/read-enricher.js +157 -0
- package/dist/hooks/post-tool-use/read-enricher.js.map +1 -0
- package/dist/hooks/post-tool-use/write-guardian.d.ts +17 -0
- package/dist/hooks/post-tool-use/write-guardian.js +176 -0
- package/dist/hooks/post-tool-use/write-guardian.js.map +1 -0
- package/dist/hooks/read-enrich.d.ts +6 -0
- package/dist/hooks/read-enrich.js +11 -0
- package/dist/hooks/read-enrich.js.map +1 -0
- package/dist/hooks/runners/index.d.ts +12 -0
- package/dist/hooks/runners/index.js +11 -0
- package/dist/hooks/runners/index.js.map +1 -0
- package/dist/hooks/runners/payload.d.ts +32 -0
- package/dist/hooks/runners/payload.js +70 -0
- package/dist/hooks/runners/payload.js.map +1 -0
- package/dist/hooks/runners/session-end.d.ts +7 -0
- package/dist/hooks/runners/session-end.js +42 -0
- package/dist/hooks/runners/session-end.js.map +1 -0
- package/dist/hooks/runners/session-start.d.ts +10 -0
- package/dist/hooks/runners/session-start.js +167 -0
- package/dist/hooks/runners/session-start.js.map +1 -0
- package/dist/hooks/runners/stop.d.ts +18 -0
- package/dist/hooks/runners/stop.js +165 -0
- package/dist/hooks/runners/stop.js.map +1 -0
- package/dist/hooks/session-end.d.ts +5 -0
- package/dist/hooks/session-end.js +10 -0
- package/dist/hooks/session-end.js.map +1 -0
- package/dist/hooks/session-start.d.ts +7 -0
- package/dist/hooks/session-start.js +12 -0
- package/dist/hooks/session-start.js.map +1 -0
- package/dist/hooks/stop.d.ts +5 -0
- package/dist/hooks/stop.js +10 -0
- package/dist/hooks/stop.js.map +1 -0
- package/dist/hooks/write-guard.d.ts +6 -0
- package/dist/hooks/write-guard.js +11 -0
- package/dist/hooks/write-guard.js.map +1 -0
- package/dist/inbox.d.ts +17 -0
- package/dist/inbox.js +30 -0
- package/dist/inbox.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/init/baseline-audit.d.ts +71 -0
- package/dist/init/baseline-audit.js +377 -0
- package/dist/init/baseline-audit.js.map +1 -0
- package/dist/init/brand-setup.d.ts +44 -0
- package/dist/init/brand-setup.js +201 -0
- package/dist/init/brand-setup.js.map +1 -0
- package/dist/init/daemon-autostart.d.ts +16 -0
- package/dist/init/daemon-autostart.js +95 -0
- package/dist/init/daemon-autostart.js.map +1 -0
- package/dist/init/detect.d.ts +25 -0
- package/dist/init/detect.js +319 -0
- package/dist/init/detect.js.map +1 -0
- package/dist/init/index.d.ts +32 -0
- package/dist/init/index.js +18 -0
- package/dist/init/index.js.map +1 -0
- package/dist/init/ingest-docs.d.ts +74 -0
- package/dist/init/ingest-docs.js +499 -0
- package/dist/init/ingest-docs.js.map +1 -0
- package/dist/init/init.d.ts +165 -0
- package/dist/init/init.js +1166 -0
- package/dist/init/init.js.map +1 -0
- package/dist/init/mapper-legacy.d.ts +148 -0
- package/dist/init/mapper-legacy.js +238 -0
- package/dist/init/mapper-legacy.js.map +1 -0
- package/dist/init/mapper-merge.d.ts +38 -0
- package/dist/init/mapper-merge.js +238 -0
- package/dist/init/mapper-merge.js.map +1 -0
- package/dist/init/mapper-parallel.d.ts +48 -0
- package/dist/init/mapper-parallel.js +409 -0
- package/dist/init/mapper-parallel.js.map +1 -0
- package/dist/init/mapper-prompts.d.ts +135 -0
- package/dist/init/mapper-prompts.js +189 -0
- package/dist/init/mapper-prompts.js.map +1 -0
- package/dist/init/mapper.d.ts +211 -0
- package/dist/init/mapper.js +151 -0
- package/dist/init/mapper.js.map +1 -0
- package/dist/init/module-slicer.d.ts +39 -0
- package/dist/init/module-slicer.js +809 -0
- package/dist/init/module-slicer.js.map +1 -0
- package/dist/init/multi-dev/index.d.ts +2 -0
- package/dist/init/multi-dev/index.js +2 -0
- package/dist/init/multi-dev/index.js.map +1 -0
- package/dist/init/multi-dev/install.d.ts +40 -0
- package/dist/init/multi-dev/install.js +139 -0
- package/dist/init/multi-dev/install.js.map +1 -0
- package/dist/init/preflight-guards.d.ts +42 -0
- package/dist/init/preflight-guards.js +108 -0
- package/dist/init/preflight-guards.js.map +1 -0
- package/dist/init/prompts.d.ts +61 -0
- package/dist/init/prompts.js +66 -0
- package/dist/init/prompts.js.map +1 -0
- package/dist/init/rules-merge/discover.d.ts +21 -0
- package/dist/init/rules-merge/discover.js +78 -0
- package/dist/init/rules-merge/discover.js.map +1 -0
- package/dist/init/rules-merge/index.d.ts +10 -0
- package/dist/init/rules-merge/index.js +6 -0
- package/dist/init/rules-merge/index.js.map +1 -0
- package/dist/init/rules-merge/ingest.d.ts +56 -0
- package/dist/init/rules-merge/ingest.js +336 -0
- package/dist/init/rules-merge/ingest.js.map +1 -0
- package/dist/init/rules-merge/keep-markers.d.ts +39 -0
- package/dist/init/rules-merge/keep-markers.js +97 -0
- package/dist/init/rules-merge/keep-markers.js.map +1 -0
- package/dist/init/rules-merge/parse-sections.d.ts +24 -0
- package/dist/init/rules-merge/parse-sections.js +71 -0
- package/dist/init/rules-merge/parse-sections.js.map +1 -0
- package/dist/init/rules-merge/regenerate.d.ts +33 -0
- package/dist/init/rules-merge/regenerate.js +163 -0
- package/dist/init/rules-merge/regenerate.js.map +1 -0
- package/dist/init/secrets.d.ts +18 -0
- package/dist/init/secrets.js +76 -0
- package/dist/init/secrets.js.map +1 -0
- package/dist/init/seed.d.ts +21 -0
- package/dist/init/seed.js +96 -0
- package/dist/init/seed.js.map +1 -0
- package/dist/init/setup-runners.d.ts +15 -0
- package/dist/init/setup-runners.js +143 -0
- package/dist/init/setup-runners.js.map +1 -0
- package/dist/init/source-comments/classify.d.ts +98 -0
- package/dist/init/source-comments/classify.js +244 -0
- package/dist/init/source-comments/classify.js.map +1 -0
- package/dist/init/source-comments/index.d.ts +8 -0
- package/dist/init/source-comments/index.js +5 -0
- package/dist/init/source-comments/index.js.map +1 -0
- package/dist/init/source-comments/ingest.d.ts +51 -0
- package/dist/init/source-comments/ingest.js +236 -0
- package/dist/init/source-comments/ingest.js.map +1 -0
- package/dist/init/source-comments/strip-replace.d.ts +106 -0
- package/dist/init/source-comments/strip-replace.js +284 -0
- package/dist/init/source-comments/strip-replace.js.map +1 -0
- package/dist/init/source-comments/walker.d.ts +65 -0
- package/dist/init/source-comments/walker.js +777 -0
- package/dist/init/source-comments/walker.js.map +1 -0
- package/dist/init/submodules.d.ts +48 -0
- package/dist/init/submodules.js +149 -0
- package/dist/init/submodules.js.map +1 -0
- package/dist/init/types.d.ts +55 -0
- package/dist/init/types.js +10 -0
- package/dist/init/types.js.map +1 -0
- package/dist/init/visual.d.ts +69 -0
- package/dist/init/visual.js +265 -0
- package/dist/init/visual.js.map +1 -0
- package/dist/init/walker.d.ts +82 -0
- package/dist/init/walker.js +585 -0
- package/dist/init/walker.js.map +1 -0
- package/dist/init/workflow-block.d.ts +34 -0
- package/dist/init/workflow-block.js +110 -0
- package/dist/init/workflow-block.js.map +1 -0
- package/dist/join/index.d.ts +67 -0
- package/dist/join/index.js +256 -0
- package/dist/join/index.js.map +1 -0
- package/dist/lock.d.ts +39 -0
- package/dist/lock.js +129 -0
- package/dist/lock.js.map +1 -0
- package/dist/logger.d.ts +13 -0
- package/dist/logger.js +78 -0
- package/dist/logger.js.map +1 -0
- package/dist/mcp/bootstrap-guard.d.ts +29 -0
- package/dist/mcp/bootstrap-guard.js +47 -0
- package/dist/mcp/bootstrap-guard.js.map +1 -0
- package/dist/mcp/context.d.ts +23 -0
- package/dist/mcp/context.js +9 -0
- package/dist/mcp/context.js.map +1 -0
- package/dist/mcp/errors.d.ts +17 -0
- package/dist/mcp/errors.js +23 -0
- package/dist/mcp/errors.js.map +1 -0
- package/dist/mcp/history/index.d.ts +6 -0
- package/dist/mcp/history/index.js +5 -0
- package/dist/mcp/history/index.js.map +1 -0
- package/dist/mcp/history/prompt.d.ts +32 -0
- package/dist/mcp/history/prompt.js +99 -0
- package/dist/mcp/history/prompt.js.map +1 -0
- package/dist/mcp/history/schema.d.ts +58 -0
- package/dist/mcp/history/schema.js +41 -0
- package/dist/mcp/history/schema.js.map +1 -0
- package/dist/mcp/history/summarizer.d.ts +81 -0
- package/dist/mcp/history/summarizer.js +196 -0
- package/dist/mcp/history/summarizer.js.map +1 -0
- package/dist/mcp/history/walker.d.ts +57 -0
- package/dist/mcp/history/walker.js +156 -0
- package/dist/mcp/history/walker.js.map +1 -0
- package/dist/mcp/index.d.ts +13 -0
- package/dist/mcp/index.js +9 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/path-allowlist.d.ts +29 -0
- package/dist/mcp/path-allowlist.js +71 -0
- package/dist/mcp/path-allowlist.js.map +1 -0
- package/dist/mcp/result.d.ts +8 -0
- package/dist/mcp/result.js +18 -0
- package/dist/mcp/result.js.map +1 -0
- package/dist/mcp/schemas.d.ts +192 -0
- package/dist/mcp/schemas.js +174 -0
- package/dist/mcp/schemas.js.map +1 -0
- package/dist/mcp/serve.d.ts +15 -0
- package/dist/mcp/serve.js +71 -0
- package/dist/mcp/serve.js.map +1 -0
- package/dist/mcp/server.d.ts +11 -0
- package/dist/mcp/server.js +58 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/telemetry.d.ts +15 -0
- package/dist/mcp/telemetry.js +13 -0
- package/dist/mcp/telemetry.js.map +1 -0
- package/dist/mcp/tools/append-run-note.d.ts +18 -0
- package/dist/mcp/tools/append-run-note.js +47 -0
- package/dist/mcp/tools/append-run-note.js.map +1 -0
- package/dist/mcp/tools/append.d.ts +8 -0
- package/dist/mcp/tools/append.js +37 -0
- package/dist/mcp/tools/append.js.map +1 -0
- package/dist/mcp/tools/archive.d.ts +8 -0
- package/dist/mcp/tools/archive.js +72 -0
- package/dist/mcp/tools/archive.js.map +1 -0
- package/dist/mcp/tools/ask-operator.d.ts +34 -0
- package/dist/mcp/tools/ask-operator.js +97 -0
- package/dist/mcp/tools/ask-operator.js.map +1 -0
- package/dist/mcp/tools/canonical-for-topic.d.ts +6 -0
- package/dist/mcp/tools/canonical-for-topic.js +40 -0
- package/dist/mcp/tools/canonical-for-topic.js.map +1 -0
- package/dist/mcp/tools/decision-get.d.ts +6 -0
- package/dist/mcp/tools/decision-get.js +49 -0
- package/dist/mcp/tools/decision-get.js.map +1 -0
- package/dist/mcp/tools/decisions-for-symbol.d.ts +7 -0
- package/dist/mcp/tools/decisions-for-symbol.js +42 -0
- package/dist/mcp/tools/decisions-for-symbol.js.map +1 -0
- package/dist/mcp/tools/decisions-in-scope.d.ts +7 -0
- package/dist/mcp/tools/decisions-in-scope.js +47 -0
- package/dist/mcp/tools/decisions-in-scope.js.map +1 -0
- package/dist/mcp/tools/drop-task.d.ts +12 -0
- package/dist/mcp/tools/drop-task.js +68 -0
- package/dist/mcp/tools/drop-task.js.map +1 -0
- package/dist/mcp/tools/get-full.d.ts +7 -0
- package/dist/mcp/tools/get-full.js +46 -0
- package/dist/mcp/tools/get-full.js.map +1 -0
- package/dist/mcp/tools/ground-get.d.ts +7 -0
- package/dist/mcp/tools/ground-get.js +77 -0
- package/dist/mcp/tools/ground-get.js.map +1 -0
- package/dist/mcp/tools/index.d.ts +3 -0
- package/dist/mcp/tools/index.js +40 -0
- package/dist/mcp/tools/index.js.map +1 -0
- package/dist/mcp/tools/invariant-get.d.ts +6 -0
- package/dist/mcp/tools/invariant-get.js +49 -0
- package/dist/mcp/tools/invariant-get.js.map +1 -0
- package/dist/mcp/tools/invariants-in-scope.d.ts +7 -0
- package/dist/mcp/tools/invariants-in-scope.js +62 -0
- package/dist/mcp/tools/invariants-in-scope.js.map +1 -0
- package/dist/mcp/tools/query-history.d.ts +20 -0
- package/dist/mcp/tools/query-history.js +51 -0
- package/dist/mcp/tools/query-history.js.map +1 -0
- package/dist/mcp/tools/record-decision.d.ts +14 -0
- package/dist/mcp/tools/record-decision.js +98 -0
- package/dist/mcp/tools/record-decision.js.map +1 -0
- package/dist/mcp/tools/record-run-event.d.ts +10 -0
- package/dist/mcp/tools/record-run-event.js +32 -0
- package/dist/mcp/tools/record-run-event.js.map +1 -0
- package/dist/mcp/tools/resolve-attention.d.ts +31 -0
- package/dist/mcp/tools/resolve-attention.js +191 -0
- package/dist/mcp/tools/resolve-attention.js.map +1 -0
- package/dist/mcp/tools/search.d.ts +9 -0
- package/dist/mcp/tools/search.js +164 -0
- package/dist/mcp/tools/search.js.map +1 -0
- package/dist/mcp/tools/supersedes-chain.d.ts +6 -0
- package/dist/mcp/tools/supersedes-chain.js +66 -0
- package/dist/mcp/tools/supersedes-chain.js.map +1 -0
- package/dist/mcp/tools/timeline.d.ts +9 -0
- package/dist/mcp/tools/timeline.js +65 -0
- package/dist/mcp/tools/timeline.js.map +1 -0
- package/dist/mcp/tools/types.d.ts +9 -0
- package/dist/mcp/tools/types.js +2 -0
- package/dist/mcp/tools/types.js.map +1 -0
- package/dist/mirror/clone.d.ts +6 -0
- package/dist/mirror/clone.js +48 -0
- package/dist/mirror/clone.js.map +1 -0
- package/dist/mirror/dirty-overlap.d.ts +13 -0
- package/dist/mirror/dirty-overlap.js +42 -0
- package/dist/mirror/dirty-overlap.js.map +1 -0
- package/dist/mirror/index.d.ts +7 -0
- package/dist/mirror/index.js +7 -0
- package/dist/mirror/index.js.map +1 -0
- package/dist/mirror/paths.d.ts +18 -0
- package/dist/mirror/paths.js +45 -0
- package/dist/mirror/paths.js.map +1 -0
- package/dist/mirror/push.d.ts +9 -0
- package/dist/mirror/push.js +27 -0
- package/dist/mirror/push.js.map +1 -0
- package/dist/mirror/state.d.ts +4 -0
- package/dist/mirror/state.js +36 -0
- package/dist/mirror/state.js.map +1 -0
- package/dist/mirror/sync.d.ts +9 -0
- package/dist/mirror/sync.js +33 -0
- package/dist/mirror/sync.js.map +1 -0
- package/dist/mirror/types.d.ts +77 -0
- package/dist/mirror/types.js +2 -0
- package/dist/mirror/types.js.map +1 -0
- package/dist/paths/index.d.ts +23 -0
- package/dist/paths/index.js +50 -0
- package/dist/paths/index.js.map +1 -0
- package/dist/profiles/index.d.ts +3 -0
- package/dist/profiles/index.js +3 -0
- package/dist/profiles/index.js.map +1 -0
- package/dist/profiles/registry.d.ts +5 -0
- package/dist/profiles/registry.js +31 -0
- package/dist/profiles/registry.js.map +1 -0
- package/dist/profiles/types.d.ts +48 -0
- package/dist/profiles/types.js +11 -0
- package/dist/profiles/types.js.map +1 -0
- package/dist/profiles/unknown.d.ts +9 -0
- package/dist/profiles/unknown.js +17 -0
- package/dist/profiles/unknown.js.map +1 -0
- package/dist/prompt.d.ts +19 -0
- package/dist/prompt.js +50 -0
- package/dist/prompt.js.map +1 -0
- package/dist/sensors/attestation.d.ts +44 -0
- package/dist/sensors/attestation.js +262 -0
- package/dist/sensors/attestation.js.map +1 -0
- package/dist/sensors/catalog.d.ts +41 -0
- package/dist/sensors/catalog.js +123 -0
- package/dist/sensors/catalog.js.map +1 -0
- package/dist/sensors/decisions.d.ts +30 -0
- package/dist/sensors/decisions.js +393 -0
- package/dist/sensors/decisions.js.map +1 -0
- package/dist/sensors/diff.d.ts +27 -0
- package/dist/sensors/diff.js +148 -0
- package/dist/sensors/diff.js.map +1 -0
- package/dist/sensors/index.d.ts +13 -0
- package/dist/sensors/index.js +9 -0
- package/dist/sensors/index.js.map +1 -0
- package/dist/sensors/remediation.d.ts +20 -0
- package/dist/sensors/remediation.js +65 -0
- package/dist/sensors/remediation.js.map +1 -0
- package/dist/sensors/runner.d.ts +44 -0
- package/dist/sensors/runner.js +95 -0
- package/dist/sensors/runner.js.map +1 -0
- package/dist/sensors/structural.d.ts +30 -0
- package/dist/sensors/structural.js +204 -0
- package/dist/sensors/structural.js.map +1 -0
- package/dist/sensors/stub-catalog.d.ts +39 -0
- package/dist/sensors/stub-catalog.js +115 -0
- package/dist/sensors/stub-catalog.js.map +1 -0
- package/dist/sensors/types.d.ts +135 -0
- package/dist/sensors/types.js +14 -0
- package/dist/sensors/types.js.map +1 -0
- package/dist/session/events-marker.d.ts +39 -0
- package/dist/session/events-marker.js +74 -0
- package/dist/session/events-marker.js.map +1 -0
- package/dist/session/id.d.ts +83 -0
- package/dist/session/id.js +166 -0
- package/dist/session/id.js.map +1 -0
- package/dist/session/index.d.ts +14 -0
- package/dist/session/index.js +13 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session-start/build.d.ts +53 -0
- package/dist/session-start/build.js +645 -0
- package/dist/session-start/build.js.map +1 -0
- package/dist/session-start/index.d.ts +18 -0
- package/dist/session-start/index.js +18 -0
- package/dist/session-start/index.js.map +1 -0
- package/dist/session-start/templates.d.ts +6 -0
- package/dist/session-start/templates.js +38 -0
- package/dist/session-start/templates.js.map +1 -0
- package/dist/status-line/format.d.ts +14 -0
- package/dist/status-line/format.js +40 -0
- package/dist/status-line/format.js.map +1 -0
- package/dist/status-line/index.d.ts +29 -0
- package/dist/status-line/index.js +14 -0
- package/dist/status-line/index.js.map +1 -0
- package/dist/status-line/reader.d.ts +13 -0
- package/dist/status-line/reader.js +76 -0
- package/dist/status-line/reader.js.map +1 -0
- package/dist/status-line/writer.d.ts +33 -0
- package/dist/status-line/writer.js +72 -0
- package/dist/status-line/writer.js.map +1 -0
- package/dist/tier0/classify.d.ts +10 -0
- package/dist/tier0/classify.js +110 -0
- package/dist/tier0/classify.js.map +1 -0
- package/dist/tier0/index.d.ts +2 -0
- package/dist/tier0/index.js +2 -0
- package/dist/tier0/index.js.map +1 -0
- package/dist/tier0/ollama.d.ts +22 -0
- package/dist/tier0/ollama.js +63 -0
- package/dist/tier0/ollama.js.map +1 -0
- package/dist/tier0/types.d.ts +24 -0
- package/dist/tier0/types.js +9 -0
- package/dist/tier0/types.js.map +1 -0
- package/dist/tightener/index.d.ts +4 -0
- package/dist/tightener/index.js +4 -0
- package/dist/tightener/index.js.map +1 -0
- package/dist/tightener/prompt.d.ts +3 -0
- package/dist/tightener/prompt.js +67 -0
- package/dist/tightener/prompt.js.map +1 -0
- package/dist/tightener/schema.d.ts +68 -0
- package/dist/tightener/schema.js +44 -0
- package/dist/tightener/schema.js.map +1 -0
- package/dist/tightener/tighten.d.ts +2 -0
- package/dist/tightener/tighten.js +66 -0
- package/dist/tightener/tighten.js.map +1 -0
- package/dist/tightener/types.d.ts +74 -0
- package/dist/tightener/types.js +6 -0
- package/dist/tightener/types.js.map +1 -0
- package/dist/voice/index.d.ts +4 -0
- package/dist/voice/index.js +4 -0
- package/dist/voice/index.js.map +1 -0
- package/dist/voice/model.d.ts +23 -0
- package/dist/voice/model.js +46 -0
- package/dist/voice/model.js.map +1 -0
- package/dist/voice/pipe.d.ts +9 -0
- package/dist/voice/pipe.js +47 -0
- package/dist/voice/pipe.js.map +1 -0
- package/dist/voice/transcribe.d.ts +3 -0
- package/dist/voice/transcribe.js +43 -0
- package/dist/voice/transcribe.js.map +1 -0
- package/dist/voice/types.d.ts +26 -0
- package/dist/voice/types.js +9 -0
- package/dist/voice/types.js.map +1 -0
- package/package.json +54 -0
- package/templates/.archive/README.md +67 -0
- package/templates/.cairn/JOIN.md +87 -0
- package/templates/.cairn/config/sensors.yaml +185 -0
- package/templates/.cairn/config/stub-patterns.yaml +231 -0
- package/templates/.cairn/config/trust-policy.yaml +95 -0
- package/templates/.cairn/config/workflow.md +230 -0
- package/templates/.cairn/git-hooks/commit-msg +17 -0
- package/templates/.cairn/git-hooks/post-commit +28 -0
- package/templates/.cairn/git-hooks/pre-commit +24 -0
- package/templates/.cairn/ground/brand/overview.md +24 -0
- package/templates/.cairn/ground/brand/voice.md +20 -0
- package/templates/.cairn/ground/canonical-map/topics.yaml +54 -0
- package/templates/.cairn/ground/capabilities/mcp-tools.yaml +4 -0
- package/templates/.cairn/ground/capabilities/skills.yaml +3 -0
- package/templates/.cairn/ground/capabilities/snippets.yaml +3 -0
- package/templates/.cairn/ground/manifest.yaml +16 -0
- package/templates/.cairn/ground/product/personas.yaml +4 -0
- package/templates/.cairn/ground/product/positioning.md +21 -0
- package/templates/.claude/settings.json +57 -0
- package/templates/.github/workflows/cairn-check.yml +31 -0
- package/templates/.mcp.json +8 -0
- package/templates/README.md +24 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GC pass 4 — doc gardening.
|
|
3
|
+
*
|
|
4
|
+
* Walks every markdown in the canonical zone and surfaces:
|
|
5
|
+
* - broken-link findings: `[text](relative/path.md)` whose target doesn't exist
|
|
6
|
+
* under repoRoot. Absolute URLs (https://...) are skipped.
|
|
7
|
+
* - orphan-path findings: markdown files that are not referenced by any other
|
|
8
|
+
* markdown in the canonical zone. Orientation files (AGENTS.md, CLAUDE.md,
|
|
9
|
+
* README.md, RESUME_PROMPT.md) and explicitly-allowed roots are excluded.
|
|
10
|
+
*
|
|
11
|
+
* Phase 12 v1 surfaces only — moving orphans to `.archive/` per the original
|
|
12
|
+
* spec needs operator confirmation (it's a non-trivial canonical-zone change).
|
|
13
|
+
* The proposal type is set up so a future revision can attach an archive-move
|
|
14
|
+
* commit when the operator opts in.
|
|
15
|
+
*/
|
|
16
|
+
import type { GcFinding } from "./types.js";
|
|
17
|
+
export interface DocGardeningOptions {
|
|
18
|
+
repoRoot: string;
|
|
19
|
+
/**
|
|
20
|
+
* Additional repo-relative paths to treat as orphan-allowed roots. Useful
|
|
21
|
+
* for project-specific entry-point docs that nothing links to (e.g. wiki
|
|
22
|
+
* landing pages).
|
|
23
|
+
*/
|
|
24
|
+
orphanExcludes?: readonly string[];
|
|
25
|
+
}
|
|
26
|
+
export interface DocGardeningResult {
|
|
27
|
+
findings: GcFinding[];
|
|
28
|
+
}
|
|
29
|
+
export declare function runDocGardening(opts: DocGardeningOptions): DocGardeningResult;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GC pass 4 — doc gardening.
|
|
3
|
+
*
|
|
4
|
+
* Walks every markdown in the canonical zone and surfaces:
|
|
5
|
+
* - broken-link findings: `[text](relative/path.md)` whose target doesn't exist
|
|
6
|
+
* under repoRoot. Absolute URLs (https://...) are skipped.
|
|
7
|
+
* - orphan-path findings: markdown files that are not referenced by any other
|
|
8
|
+
* markdown in the canonical zone. Orientation files (AGENTS.md, CLAUDE.md,
|
|
9
|
+
* README.md, RESUME_PROMPT.md) and explicitly-allowed roots are excluded.
|
|
10
|
+
*
|
|
11
|
+
* Phase 12 v1 surfaces only — moving orphans to `.archive/` per the original
|
|
12
|
+
* spec needs operator confirmation (it's a non-trivial canonical-zone change).
|
|
13
|
+
* The proposal type is set up so a future revision can attach an archive-move
|
|
14
|
+
* commit when the operator opts in.
|
|
15
|
+
*/
|
|
16
|
+
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
17
|
+
import { dirname, posix, resolve } from "node:path";
|
|
18
|
+
import { walkCanonical } from "../ground/walk.js";
|
|
19
|
+
const PASS_ID = "doc-gardening";
|
|
20
|
+
const ORPHAN_ROOT_EXCLUDES = [
|
|
21
|
+
"AGENTS.md",
|
|
22
|
+
"CLAUDE.md",
|
|
23
|
+
"README.md",
|
|
24
|
+
"RESUME_PROMPT.md",
|
|
25
|
+
".cairn/config/workflow.md",
|
|
26
|
+
".cairn/config/sensors.yaml",
|
|
27
|
+
".cairn/config/stub-patterns.yaml",
|
|
28
|
+
".cairn/config/trust-policy.yaml",
|
|
29
|
+
];
|
|
30
|
+
export function runDocGardening(opts) {
|
|
31
|
+
const findings = [];
|
|
32
|
+
const allFiles = walkCanonical(opts.repoRoot);
|
|
33
|
+
const mdFiles = allFiles.filter((p) => p.endsWith(".md"));
|
|
34
|
+
const referenced = new Set();
|
|
35
|
+
for (const rel of mdFiles) {
|
|
36
|
+
const abs = resolve(opts.repoRoot, rel);
|
|
37
|
+
let source;
|
|
38
|
+
try {
|
|
39
|
+
source = readFileSync(abs, "utf8");
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
const links = extractMarkdownLinks(source);
|
|
45
|
+
for (const link of links) {
|
|
46
|
+
if (link.url.length === 0)
|
|
47
|
+
continue;
|
|
48
|
+
if (isExternalUrl(link.url))
|
|
49
|
+
continue;
|
|
50
|
+
if (link.url.startsWith("#"))
|
|
51
|
+
continue; // intra-page anchor
|
|
52
|
+
const target = resolveLinkTarget(opts.repoRoot, rel, link.url);
|
|
53
|
+
if (target === null)
|
|
54
|
+
continue;
|
|
55
|
+
if (!fileExists(opts.repoRoot, target)) {
|
|
56
|
+
findings.push({
|
|
57
|
+
pass: PASS_ID,
|
|
58
|
+
kind: "broken_link",
|
|
59
|
+
path: rel,
|
|
60
|
+
detail: `${rel}:${link.line} → \`${link.url}\` (target ${target} missing)`,
|
|
61
|
+
severity: "warn",
|
|
62
|
+
line: link.line,
|
|
63
|
+
matched_text: link.url,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
else if (target.endsWith(".md")) {
|
|
67
|
+
referenced.add(target);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Orphan detection — markdowns not referenced by any other markdown.
|
|
72
|
+
const allowOrphan = new Set([
|
|
73
|
+
...ORPHAN_ROOT_EXCLUDES,
|
|
74
|
+
...(opts.orphanExcludes ?? []),
|
|
75
|
+
]);
|
|
76
|
+
for (const rel of mdFiles) {
|
|
77
|
+
if (allowOrphan.has(rel))
|
|
78
|
+
continue;
|
|
79
|
+
if (!referenced.has(rel)) {
|
|
80
|
+
findings.push({
|
|
81
|
+
pass: PASS_ID,
|
|
82
|
+
kind: "orphan_path",
|
|
83
|
+
path: rel,
|
|
84
|
+
detail: `${rel} is not referenced by any other markdown in the canonical zone — candidate for .archive/ move`,
|
|
85
|
+
severity: "warn",
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return { findings };
|
|
90
|
+
}
|
|
91
|
+
function extractMarkdownLinks(source) {
|
|
92
|
+
// Match ](url) part of an inline link. Allow spaces inside text. Skip
|
|
93
|
+
// images (preceded by `!`) and reference-style links.
|
|
94
|
+
const out = [];
|
|
95
|
+
// Build line-index map.
|
|
96
|
+
const re = /(!?)\[([^\]\n]+)\]\(([^)\s]+)(?:\s+"[^"]*")?\)/g;
|
|
97
|
+
let m;
|
|
98
|
+
while ((m = re.exec(source)) !== null) {
|
|
99
|
+
const isImage = m[1] === "!";
|
|
100
|
+
const text = m[2] ?? "";
|
|
101
|
+
const url = m[3] ?? "";
|
|
102
|
+
if (isImage)
|
|
103
|
+
continue;
|
|
104
|
+
out.push({ text, url, line: lineOf(source, m.index) });
|
|
105
|
+
}
|
|
106
|
+
return out;
|
|
107
|
+
}
|
|
108
|
+
function isExternalUrl(url) {
|
|
109
|
+
return /^[a-z]+:\/\//i.test(url) || url.startsWith("mailto:");
|
|
110
|
+
}
|
|
111
|
+
function resolveLinkTarget(repoRoot, fromRel, url) {
|
|
112
|
+
// Strip fragment.
|
|
113
|
+
const hashIdx = url.indexOf("#");
|
|
114
|
+
const cleanUrl = hashIdx === -1 ? url : url.slice(0, hashIdx);
|
|
115
|
+
if (cleanUrl.length === 0)
|
|
116
|
+
return null;
|
|
117
|
+
// Absolute paths inside the repo (rare, but tolerated).
|
|
118
|
+
if (cleanUrl.startsWith("/")) {
|
|
119
|
+
return cleanUrl.replace(/^\/+/, "");
|
|
120
|
+
}
|
|
121
|
+
const fromDir = dirname(fromRel);
|
|
122
|
+
const joined = posix.normalize(posix.join(fromDir, cleanUrl));
|
|
123
|
+
if (joined.startsWith(".."))
|
|
124
|
+
return null; // escapes repo root
|
|
125
|
+
return joined;
|
|
126
|
+
}
|
|
127
|
+
function fileExists(repoRoot, rel) {
|
|
128
|
+
const abs = resolve(repoRoot, rel);
|
|
129
|
+
if (!existsSync(abs))
|
|
130
|
+
return false;
|
|
131
|
+
try {
|
|
132
|
+
return statSync(abs).isFile() || statSync(abs).isDirectory();
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function lineOf(text, charIndex) {
|
|
139
|
+
let line = 1;
|
|
140
|
+
for (let i = 0; i < charIndex && i < text.length; i++) {
|
|
141
|
+
if (text.charCodeAt(i) === 10 /* \n */)
|
|
142
|
+
line += 1;
|
|
143
|
+
}
|
|
144
|
+
return line;
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=doc-gardening.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doc-gardening.js","sourceRoot":"","sources":["../../src/gc/doc-gardening.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GC pass 1 — frontmatter freshness.
|
|
3
|
+
*
|
|
4
|
+
* Walks the canonical zone via `walkCanonical`, parses each markdown's
|
|
5
|
+
* provenance frontmatter, and surfaces docs whose `verified-at` exceeds the
|
|
6
|
+
* configured warn (30d) / block (60d) thresholds.
|
|
7
|
+
*
|
|
8
|
+
* Phase 12 v1 surfaces only — it does NOT auto-bump verified-at, because a
|
|
9
|
+
* timestamp bump without re-verification is a lie. Future revisions may add
|
|
10
|
+
* an opt-in "refresh-and-bump" proposal for safe-class docs whose content
|
|
11
|
+
* sha hasn't changed since the last verified-at, but that's out of v1 scope.
|
|
12
|
+
*
|
|
13
|
+
* Exception: when `forceRefresh: true` is passed (smoke / dev only), the pass
|
|
14
|
+
* proposes a frontmatter-only verified-at bump as a safe-class commit. The
|
|
15
|
+
* smoke uses this path to exercise the auto-merge end-to-end.
|
|
16
|
+
*/
|
|
17
|
+
import type { GcCommitProposal, GcFinding } from "./types.js";
|
|
18
|
+
export interface FrontmatterFreshnessOptions {
|
|
19
|
+
repoRoot: string;
|
|
20
|
+
warnDays?: number;
|
|
21
|
+
blockDays?: number;
|
|
22
|
+
/** Default = new Date(); injected for tests. */
|
|
23
|
+
now?: Date;
|
|
24
|
+
/**
|
|
25
|
+
* When true, produce a frontmatter-only safe-class commit proposal that
|
|
26
|
+
* bumps verified-at to `now` for every stale doc. Off by default — see
|
|
27
|
+
* module header. Smoke uses this.
|
|
28
|
+
*/
|
|
29
|
+
forceRefresh?: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface FrontmatterFreshnessResult {
|
|
32
|
+
findings: GcFinding[];
|
|
33
|
+
proposals: GcCommitProposal[];
|
|
34
|
+
}
|
|
35
|
+
export declare function runFrontmatterFreshness(opts: FrontmatterFreshnessOptions): FrontmatterFreshnessResult;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GC pass 1 — frontmatter freshness.
|
|
3
|
+
*
|
|
4
|
+
* Walks the canonical zone via `walkCanonical`, parses each markdown's
|
|
5
|
+
* provenance frontmatter, and surfaces docs whose `verified-at` exceeds the
|
|
6
|
+
* configured warn (30d) / block (60d) thresholds.
|
|
7
|
+
*
|
|
8
|
+
* Phase 12 v1 surfaces only — it does NOT auto-bump verified-at, because a
|
|
9
|
+
* timestamp bump without re-verification is a lie. Future revisions may add
|
|
10
|
+
* an opt-in "refresh-and-bump" proposal for safe-class docs whose content
|
|
11
|
+
* sha hasn't changed since the last verified-at, but that's out of v1 scope.
|
|
12
|
+
*
|
|
13
|
+
* Exception: when `forceRefresh: true` is passed (smoke / dev only), the pass
|
|
14
|
+
* proposes a frontmatter-only verified-at bump as a safe-class commit. The
|
|
15
|
+
* smoke uses this path to exercise the auto-merge end-to-end.
|
|
16
|
+
*/
|
|
17
|
+
import { readFileSync } from "node:fs";
|
|
18
|
+
import { resolve } from "node:path";
|
|
19
|
+
import { evaluateFreshness, parseFrontmatter } from "../ground/frontmatter.js";
|
|
20
|
+
import { walkCanonical } from "../ground/walk.js";
|
|
21
|
+
const PASS_ID = "frontmatter-freshness";
|
|
22
|
+
export function runFrontmatterFreshness(opts) {
|
|
23
|
+
const warnDays = opts.warnDays ?? 30;
|
|
24
|
+
const blockDays = opts.blockDays ?? 60;
|
|
25
|
+
const now = opts.now ?? new Date();
|
|
26
|
+
const findings = [];
|
|
27
|
+
const refreshes = [];
|
|
28
|
+
const files = walkCanonical(opts.repoRoot);
|
|
29
|
+
for (const rel of files) {
|
|
30
|
+
if (!rel.endsWith(".md"))
|
|
31
|
+
continue;
|
|
32
|
+
const abs = resolve(opts.repoRoot, rel);
|
|
33
|
+
const source = readFileSync(abs, "utf8");
|
|
34
|
+
const parsed = parseFrontmatter(source);
|
|
35
|
+
if (!parsed.frontmatter)
|
|
36
|
+
continue;
|
|
37
|
+
const verdict = evaluateFreshness(parsed.frontmatter, warnDays, blockDays, now);
|
|
38
|
+
if (verdict.status === "fresh" || verdict.status === "unknown")
|
|
39
|
+
continue;
|
|
40
|
+
findings.push({
|
|
41
|
+
pass: PASS_ID,
|
|
42
|
+
kind: "frontmatter_stale",
|
|
43
|
+
path: rel,
|
|
44
|
+
detail: verdict.status === "block"
|
|
45
|
+
? `verified-at is ${verdict.ageDays}d old (>=${blockDays}d block threshold) — re-verify before relying`
|
|
46
|
+
: `verified-at is ${verdict.ageDays}d old (>=${warnDays}d warn threshold)`,
|
|
47
|
+
severity: verdict.status === "block" ? "block" : "warn",
|
|
48
|
+
...(verdict.ageDays !== null ? { age_days: verdict.ageDays } : {}),
|
|
49
|
+
});
|
|
50
|
+
if (opts.forceRefresh) {
|
|
51
|
+
const refreshed = bumpVerifiedAt(source, now);
|
|
52
|
+
refreshes.push({ path: rel, content: refreshed });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const proposals = [];
|
|
56
|
+
if (refreshes.length > 0) {
|
|
57
|
+
const patch = {};
|
|
58
|
+
for (const r of refreshes)
|
|
59
|
+
patch[r.path] = r.content;
|
|
60
|
+
const paths = refreshes.map((r) => r.path).sort();
|
|
61
|
+
proposals.push({
|
|
62
|
+
pass: PASS_ID,
|
|
63
|
+
class: "safe",
|
|
64
|
+
paths,
|
|
65
|
+
patch,
|
|
66
|
+
commit_message: composeCommitMessage(paths.length, now),
|
|
67
|
+
findings: findings.filter((f) => paths.includes(f.path)),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return { findings, proposals };
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Rewrite the frontmatter block with verified-at bumped to `now`. Preserves
|
|
74
|
+
* key order by replacing only the `verified-at:` line (or inserting it
|
|
75
|
+
* directly after `generated:` when missing).
|
|
76
|
+
*/
|
|
77
|
+
function bumpVerifiedAt(source, now) {
|
|
78
|
+
const iso = now.toISOString();
|
|
79
|
+
// Frontmatter is fenced by `---` lines at the top of the file; replace the
|
|
80
|
+
// first `verified-at:` line in the fence region. If none, insert it after
|
|
81
|
+
// `generated:` if present, else at the end of the fence block.
|
|
82
|
+
const fenceEndIdx = source.indexOf("\n---", 3);
|
|
83
|
+
if (fenceEndIdx === -1)
|
|
84
|
+
return source;
|
|
85
|
+
const fenceText = source.slice(0, fenceEndIdx);
|
|
86
|
+
const restText = source.slice(fenceEndIdx);
|
|
87
|
+
const verifiedAtRe = /^verified-at:.*$/m;
|
|
88
|
+
if (verifiedAtRe.test(fenceText)) {
|
|
89
|
+
return fenceText.replace(verifiedAtRe, `verified-at: ${iso}`) + restText;
|
|
90
|
+
}
|
|
91
|
+
// Insert after generated: line if present.
|
|
92
|
+
const generatedRe = /^(generated:.*)$/m;
|
|
93
|
+
if (generatedRe.test(fenceText)) {
|
|
94
|
+
return fenceText.replace(generatedRe, `$1\nverified-at: ${iso}`) + restText;
|
|
95
|
+
}
|
|
96
|
+
return fenceText + `\nverified-at: ${iso}` + restText;
|
|
97
|
+
}
|
|
98
|
+
function composeCommitMessage(count, now) {
|
|
99
|
+
const ymd = now.toISOString().slice(0, 10);
|
|
100
|
+
const subject = `chore(gc): refresh frontmatter verified-at on ${count} doc${count === 1 ? "" : "s"} (${ymd})`;
|
|
101
|
+
const body = "GC frontmatter-freshness pass — content unchanged; bumping verified-at to today.\n" +
|
|
102
|
+
"Auto-applied as safe-class per L16 (PRIMER §12.2).\n";
|
|
103
|
+
return `${subject}\n\n${body}`;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=frontmatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../src/gc/frontmatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GC pass 2 — generator drift.
|
|
3
|
+
*
|
|
4
|
+
* Iterates every `Profile.extractors` and re-runs them. For each extractor:
|
|
5
|
+
* - run(ctx) → newContent | null
|
|
6
|
+
* - read existing file at outputRelPath → currentContent
|
|
7
|
+
* - if differ → emit a finding + a safe-class commit proposal that
|
|
8
|
+
* overwrites outputRelPath with newContent.
|
|
9
|
+
*
|
|
10
|
+
* Per spec: "auto-regenerate; commit `chore(gc): regenerate <artifact>` if no
|
|
11
|
+
* source change required". A regenerated artifact whose deterministic output
|
|
12
|
+
* matches the spec but doesn't match disk is exactly drift — replace it.
|
|
13
|
+
*
|
|
14
|
+
* The unknown profile has zero extractors, so on a vanilla repo this pass is
|
|
15
|
+
* a no-op. Future profiles (typescript-next-nest, etc.) wire their extractors
|
|
16
|
+
* via `registerProfile()` and they show up here automatically.
|
|
17
|
+
*/
|
|
18
|
+
import type { Profile } from "../profiles/types.js";
|
|
19
|
+
import type { GcCommitProposal, GcFinding } from "./types.js";
|
|
20
|
+
export interface GeneratorDriftOptions {
|
|
21
|
+
repoRoot: string;
|
|
22
|
+
profile: Profile;
|
|
23
|
+
}
|
|
24
|
+
export interface GeneratorDriftResult {
|
|
25
|
+
findings: GcFinding[];
|
|
26
|
+
proposals: GcCommitProposal[];
|
|
27
|
+
}
|
|
28
|
+
export declare function runGeneratorDrift(opts: GeneratorDriftOptions): Promise<GeneratorDriftResult>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GC pass 2 — generator drift.
|
|
3
|
+
*
|
|
4
|
+
* Iterates every `Profile.extractors` and re-runs them. For each extractor:
|
|
5
|
+
* - run(ctx) → newContent | null
|
|
6
|
+
* - read existing file at outputRelPath → currentContent
|
|
7
|
+
* - if differ → emit a finding + a safe-class commit proposal that
|
|
8
|
+
* overwrites outputRelPath with newContent.
|
|
9
|
+
*
|
|
10
|
+
* Per spec: "auto-regenerate; commit `chore(gc): regenerate <artifact>` if no
|
|
11
|
+
* source change required". A regenerated artifact whose deterministic output
|
|
12
|
+
* matches the spec but doesn't match disk is exactly drift — replace it.
|
|
13
|
+
*
|
|
14
|
+
* The unknown profile has zero extractors, so on a vanilla repo this pass is
|
|
15
|
+
* a no-op. Future profiles (typescript-next-nest, etc.) wire their extractors
|
|
16
|
+
* via `registerProfile()` and they show up here automatically.
|
|
17
|
+
*/
|
|
18
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
19
|
+
import { resolve } from "node:path";
|
|
20
|
+
const PASS_ID = "generator-drift";
|
|
21
|
+
export async function runGeneratorDrift(opts) {
|
|
22
|
+
const findings = [];
|
|
23
|
+
const proposals = [];
|
|
24
|
+
for (const extractor of opts.profile.extractors) {
|
|
25
|
+
const newContent = await extractor.run({ repoRoot: opts.repoRoot });
|
|
26
|
+
if (newContent === null)
|
|
27
|
+
continue; // extractor opted to skip
|
|
28
|
+
const outAbs = resolve(opts.repoRoot, extractor.outputRelPath);
|
|
29
|
+
const currentContent = existsSync(outAbs) ? readFileSync(outAbs, "utf8") : "";
|
|
30
|
+
if (currentContent === newContent)
|
|
31
|
+
continue;
|
|
32
|
+
const finding = {
|
|
33
|
+
pass: PASS_ID,
|
|
34
|
+
kind: "generator_drift",
|
|
35
|
+
path: extractor.outputRelPath,
|
|
36
|
+
detail: `extractor \`${extractor.id}\` produces output that differs from on-disk content (${currentContent.length === 0 ? "missing" : "stale"}) — regenerating`,
|
|
37
|
+
severity: "warn",
|
|
38
|
+
};
|
|
39
|
+
findings.push(finding);
|
|
40
|
+
proposals.push({
|
|
41
|
+
pass: PASS_ID,
|
|
42
|
+
class: "safe",
|
|
43
|
+
paths: [extractor.outputRelPath],
|
|
44
|
+
patch: { [extractor.outputRelPath]: newContent },
|
|
45
|
+
commit_message: `chore(gc): regenerate ${extractor.outputRelPath}\n\n` +
|
|
46
|
+
`GC generator-drift pass — extractor \`${extractor.id}\` produces output that differs from on-disk.\n` +
|
|
47
|
+
`Auto-applied as safe-class per PRIMER §12.2.\n`,
|
|
48
|
+
findings: [finding],
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return { findings, proposals };
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=generator-drift.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator-drift.js","sourceRoot":"","sources":["../../src/gc/generator-drift.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,MAAM,OAAO,GAAG,iBAA0B,CAAC;AAY3C,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAA2B;IAE3B,MAAM,QAAQ,GAAgB,EAAE,CAAC;IACjC,MAAM,SAAS,GAAuB,EAAE,CAAC;IAEzC,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QAChD,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACpE,IAAI,UAAU,KAAK,IAAI;YAAE,SAAS,CAAC,0BAA0B;QAE7D,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;QAC/D,MAAM,cAAc,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAE9E,IAAI,cAAc,KAAK,UAAU;YAAE,SAAS;QAE5C,MAAM,OAAO,GAAc;YACzB,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,iBAAiB;YACvB,IAAI,EAAE,SAAS,CAAC,aAAa;YAC7B,MAAM,EAAE,eAAe,SAAS,CAAC,EAAE,yDACjC,cAAc,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAC5C,kBAAkB;YAClB,QAAQ,EAAE,MAAM;SACjB,CAAC;QACF,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEvB,SAAS,CAAC,IAAI,CAAC;YACb,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,MAAM;YACb,KAAK,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC;YAChC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE,UAAU,EAAE;YAChD,cAAc,EACZ,yBAAyB,SAAS,CAAC,aAAa,MAAM;gBACtD,yCAAyC,SAAS,CAAC,EAAE,iDAAiD;gBACtG,gDAAgD;YAClD,QAAQ,EAAE,CAAC,OAAO,CAAC;SACpB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase 12 — garbage collection cadence.
|
|
3
|
+
*
|
|
4
|
+
* Public surface:
|
|
5
|
+
* - runGcSweep(opts) → composes all five passes
|
|
6
|
+
* - runGcBatch(opts) → sweep + classify + apply + canary
|
|
7
|
+
* - applyCommit(opts) → apply a single proposal
|
|
8
|
+
* - verifyBatchCanary(opts) → standalone canary check
|
|
9
|
+
* - classifyAutoMerge(args) → safe | code | high-stakes
|
|
10
|
+
* - runFrontmatterFreshness, runGeneratorDrift, runStubCatalogHits,
|
|
11
|
+
* runDocGardening, runQualityGradesUpdate — direct pass entry points
|
|
12
|
+
*
|
|
13
|
+
* Used by the CLI (`cairn gc run`) and the smoke test
|
|
14
|
+
* (`cairn/scripts/smoke-gc.ts`). Future cron / `/loop` integration consumes
|
|
15
|
+
* the same surface.
|
|
16
|
+
*/
|
|
17
|
+
export type { GcAutoMergeClass, GcBatchResult, GcCommitProposal, GcFinding, GcFindingKind, GcPassId, GcSweepResult, CanarySyntheticContext, } from "./types.js";
|
|
18
|
+
export { applyCommit } from "./apply.js";
|
|
19
|
+
export type { ApplyCommitOptions, ApplyCommitResult } from "./apply.js";
|
|
20
|
+
export { verifyBatchCanary, buildSyntheticContext, } from "./canary.js";
|
|
21
|
+
export type { BatchCanaryResult, BatchCanaryOptions, } from "./canary.js";
|
|
22
|
+
export { runCitationIntegrity } from "./citation-integrity.js";
|
|
23
|
+
export type { CitationIntegrityOptions, CitationIntegrityResult, } from "./citation-integrity.js";
|
|
24
|
+
export { classifyAutoMerge } from "./classify.js";
|
|
25
|
+
export type { ClassifyArgs } from "./classify.js";
|
|
26
|
+
export { runCompletionIntegrity } from "./completion-integrity.js";
|
|
27
|
+
export type { CompletionIntegrityOptions, CompletionIntegrityResult, } from "./completion-integrity.js";
|
|
28
|
+
export { runDocGardening } from "./doc-gardening.js";
|
|
29
|
+
export type { DocGardeningOptions, DocGardeningResult, } from "./doc-gardening.js";
|
|
30
|
+
export { runFrontmatterFreshness, } from "./frontmatter.js";
|
|
31
|
+
export type { FrontmatterFreshnessOptions, FrontmatterFreshnessResult, } from "./frontmatter.js";
|
|
32
|
+
export { runGeneratorDrift } from "./generator-drift.js";
|
|
33
|
+
export type { GeneratorDriftOptions, GeneratorDriftResult, } from "./generator-drift.js";
|
|
34
|
+
export { runQualityGradesUpdate } from "./quality-update.js";
|
|
35
|
+
export type { QualityUpdateOptions, QualityUpdateResult, } from "./quality-update.js";
|
|
36
|
+
export { runScopeCoverage } from "./scope-coverage.js";
|
|
37
|
+
export type { ScopeCoverageOptions, ScopeCoverageResult, } from "./scope-coverage.js";
|
|
38
|
+
export { runStubCatalogHits } from "./stub-hits.js";
|
|
39
|
+
export type { StubCatalogHitsOptions, StubCatalogHitsResult, } from "./stub-hits.js";
|
|
40
|
+
export { runGcBatch, runGcSweep } from "./sweep.js";
|
|
41
|
+
export type { RunGcBatchOptions, RunGcSweepOptions, } from "./sweep.js";
|
|
42
|
+
export { walkSourceTree, SOURCE_TREE_SKIP_DIRS } from "./walk-source.js";
|
package/dist/gc/index.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase 12 — garbage collection cadence.
|
|
3
|
+
*
|
|
4
|
+
* Public surface:
|
|
5
|
+
* - runGcSweep(opts) → composes all five passes
|
|
6
|
+
* - runGcBatch(opts) → sweep + classify + apply + canary
|
|
7
|
+
* - applyCommit(opts) → apply a single proposal
|
|
8
|
+
* - verifyBatchCanary(opts) → standalone canary check
|
|
9
|
+
* - classifyAutoMerge(args) → safe | code | high-stakes
|
|
10
|
+
* - runFrontmatterFreshness, runGeneratorDrift, runStubCatalogHits,
|
|
11
|
+
* runDocGardening, runQualityGradesUpdate — direct pass entry points
|
|
12
|
+
*
|
|
13
|
+
* Used by the CLI (`cairn gc run`) and the smoke test
|
|
14
|
+
* (`cairn/scripts/smoke-gc.ts`). Future cron / `/loop` integration consumes
|
|
15
|
+
* the same surface.
|
|
16
|
+
*/
|
|
17
|
+
export { applyCommit } from "./apply.js";
|
|
18
|
+
export { verifyBatchCanary, buildSyntheticContext, } from "./canary.js";
|
|
19
|
+
export { runCitationIntegrity } from "./citation-integrity.js";
|
|
20
|
+
export { classifyAutoMerge } from "./classify.js";
|
|
21
|
+
export { runCompletionIntegrity } from "./completion-integrity.js";
|
|
22
|
+
export { runDocGardening } from "./doc-gardening.js";
|
|
23
|
+
export { runFrontmatterFreshness, } from "./frontmatter.js";
|
|
24
|
+
export { runGeneratorDrift } from "./generator-drift.js";
|
|
25
|
+
export { runQualityGradesUpdate } from "./quality-update.js";
|
|
26
|
+
export { runScopeCoverage } from "./scope-coverage.js";
|
|
27
|
+
export { runStubCatalogHits } from "./stub-hits.js";
|
|
28
|
+
export { runGcBatch, runGcSweep } from "./sweep.js";
|
|
29
|
+
export { walkSourceTree, SOURCE_TREE_SKIP_DIRS } from "./walk-source.js";
|
|
30
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gc/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAaH,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,EACL,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,aAAa,CAAC;AAKrB,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAK/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAKnE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAKrD,OAAO,EACL,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAK1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAKzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAK7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAKvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAKpD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAKpD,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GC pass 5 — quality grades update.
|
|
3
|
+
*
|
|
4
|
+
* Rebuilds `.cairn/ground/quality-grades.yaml` from terminal-run history at
|
|
5
|
+
* `.cairn/runs/terminal/*`. The grounding daemon also writes this file on
|
|
6
|
+
* watch events, so GC's job is to ensure a fresh write lands on the GC cron
|
|
7
|
+
* and that any drift between the file's content and the latest reality is
|
|
8
|
+
* captured as a safe-class commit.
|
|
9
|
+
*
|
|
10
|
+
* Implementation: build the grades structure in-memory, compare against the
|
|
11
|
+
* file currently on disk (modules array as JSON, ignoring `generated:`
|
|
12
|
+
* timestamp churn), and emit a commit proposal only when content differs.
|
|
13
|
+
*/
|
|
14
|
+
import type { GcCommitProposal, GcFinding } from "./types.js";
|
|
15
|
+
export interface QualityUpdateOptions {
|
|
16
|
+
repoRoot: string;
|
|
17
|
+
recentRunCount?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface QualityUpdateResult {
|
|
20
|
+
findings: GcFinding[];
|
|
21
|
+
proposals: GcCommitProposal[];
|
|
22
|
+
}
|
|
23
|
+
export declare function runQualityGradesUpdate(opts: QualityUpdateOptions): QualityUpdateResult;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GC pass 5 — quality grades update.
|
|
3
|
+
*
|
|
4
|
+
* Rebuilds `.cairn/ground/quality-grades.yaml` from terminal-run history at
|
|
5
|
+
* `.cairn/runs/terminal/*`. The grounding daemon also writes this file on
|
|
6
|
+
* watch events, so GC's job is to ensure a fresh write lands on the GC cron
|
|
7
|
+
* and that any drift between the file's content and the latest reality is
|
|
8
|
+
* captured as a safe-class commit.
|
|
9
|
+
*
|
|
10
|
+
* Implementation: build the grades structure in-memory, compare against the
|
|
11
|
+
* file currently on disk (modules array as JSON, ignoring `generated:`
|
|
12
|
+
* timestamp churn), and emit a commit proposal only when content differs.
|
|
13
|
+
*/
|
|
14
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
15
|
+
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
|
16
|
+
import { buildQualityGrades } from "../ground/quality-grades.js";
|
|
17
|
+
import { qualityGradesPath } from "../ground/paths.js";
|
|
18
|
+
const PASS_ID = "quality-grades";
|
|
19
|
+
export function runQualityGradesUpdate(opts) {
|
|
20
|
+
const findings = [];
|
|
21
|
+
const proposals = [];
|
|
22
|
+
const grades = buildQualityGrades({
|
|
23
|
+
repoRoot: opts.repoRoot,
|
|
24
|
+
...(opts.recentRunCount !== undefined ? { recentRunCount: opts.recentRunCount } : {}),
|
|
25
|
+
});
|
|
26
|
+
const newContent = stringifyYaml(grades);
|
|
27
|
+
const filePath = qualityGradesPath(opts.repoRoot);
|
|
28
|
+
const relPath = ".cairn/ground/quality-grades.yaml";
|
|
29
|
+
const existing = existsSync(filePath) ? readFileSync(filePath, "utf8") : "";
|
|
30
|
+
const existingModules = existing.length > 0 ? safeParseModules(existing) : [];
|
|
31
|
+
const existingModulesJson = JSON.stringify(existingModules);
|
|
32
|
+
const newModulesJson = JSON.stringify(grades.modules);
|
|
33
|
+
if (existingModulesJson === newModulesJson) {
|
|
34
|
+
return { findings, proposals };
|
|
35
|
+
}
|
|
36
|
+
const finding = {
|
|
37
|
+
pass: PASS_ID,
|
|
38
|
+
kind: "quality_update",
|
|
39
|
+
path: relPath,
|
|
40
|
+
detail: `quality-grades.yaml modules changed (${grades.modules.length} module${grades.modules.length === 1 ? "" : "s"} graded)`,
|
|
41
|
+
severity: "info",
|
|
42
|
+
};
|
|
43
|
+
findings.push(finding);
|
|
44
|
+
proposals.push({
|
|
45
|
+
pass: PASS_ID,
|
|
46
|
+
class: "safe",
|
|
47
|
+
paths: [relPath],
|
|
48
|
+
patch: { [relPath]: newContent },
|
|
49
|
+
commit_message: `chore(gc): refresh quality-grades.yaml (${grades.modules.length} modules)\n\n` +
|
|
50
|
+
`GC quality-grades pass — recomputed from .cairn/runs/terminal/.\n` +
|
|
51
|
+
`Auto-applied as safe-class per PRIMER §12.2.\n`,
|
|
52
|
+
findings: [finding],
|
|
53
|
+
});
|
|
54
|
+
return { findings, proposals };
|
|
55
|
+
}
|
|
56
|
+
function safeParseModules(text) {
|
|
57
|
+
try {
|
|
58
|
+
const parsed = parseYaml(text);
|
|
59
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
60
|
+
const m = parsed.modules;
|
|
61
|
+
return Array.isArray(m) ? m : [];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// fall through
|
|
66
|
+
}
|
|
67
|
+
return [];
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=quality-update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quality-update.js","sourceRoot":"","sources":["../../src/gc/quality-update.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GC pass — scope-coverage.
|
|
3
|
+
*
|
|
4
|
+
* Surfaces drift between the source tree and `.cairn/ground/scope-index.yaml`:
|
|
5
|
+
* 1. Source files with no scope-index entry → `scope_uncovered`.
|
|
6
|
+
* 2. Index entries pointing at paths that no longer exist → `scope_drift_orphan`.
|
|
7
|
+
*
|
|
8
|
+
* If the scope-index file itself is missing, emits a single
|
|
9
|
+
* `scope_index_missing` finding telling the operator to rebuild it.
|
|
10
|
+
*
|
|
11
|
+
* Spec: docs/DOCS_SPEC.md §3.8.
|
|
12
|
+
*/
|
|
13
|
+
import type { GcFinding } from "./types.js";
|
|
14
|
+
export interface ScopeCoverageOptions {
|
|
15
|
+
repoRoot: string;
|
|
16
|
+
}
|
|
17
|
+
export interface ScopeCoverageResult {
|
|
18
|
+
findings: GcFinding[];
|
|
19
|
+
}
|
|
20
|
+
export declare function runScopeCoverage(opts: ScopeCoverageOptions): ScopeCoverageResult;
|