@cleocode/core 2026.9.8 → 2026.9.10
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/audit/reconstruct.d.ts +13 -43
- package/dist/audit/reconstruct.d.ts.map +1 -1
- package/dist/audit/reconstruct.js +295 -290
- package/dist/audit/reconstruct.js.map +1 -1
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +8 -2
- package/dist/bootstrap.js.map +1 -1
- package/dist/compliance/protocol-rules.d.ts.map +1 -1
- package/dist/compliance/protocol-rules.js +3 -1
- package/dist/compliance/protocol-rules.js.map +1 -1
- package/dist/dispatch/mutate-projection.d.ts.map +1 -1
- package/dist/dispatch/mutate-projection.js +12 -0
- package/dist/dispatch/mutate-projection.js.map +1 -1
- package/dist/dispatch/mvi-projection.d.ts +29 -6
- package/dist/dispatch/mvi-projection.d.ts.map +1 -1
- package/dist/dispatch/mvi-projection.js +109 -139
- package/dist/dispatch/mvi-projection.js.map +1 -1
- package/dist/docs/docs-read-model.d.ts +3 -2
- package/dist/docs/docs-read-model.d.ts.map +1 -1
- package/dist/docs/docs-read-model.js +4 -3
- package/dist/docs/docs-read-model.js.map +1 -1
- package/dist/docs/export-document.js +5129 -2297
- package/dist/docs/export-document.js.map +3 -3
- package/dist/docs/projection.d.ts +67 -0
- package/dist/docs/projection.d.ts.map +1 -0
- package/dist/docs/projection.js +370 -0
- package/dist/docs/projection.js.map +1 -0
- package/dist/doctor/acceptance-drift.d.ts +6 -2
- package/dist/doctor/acceptance-drift.d.ts.map +1 -1
- package/dist/doctor/acceptance-drift.js +43 -5
- package/dist/doctor/acceptance-drift.js.map +1 -1
- package/dist/doctor/knowledge-summary.d.ts +41 -0
- package/dist/doctor/knowledge-summary.d.ts.map +1 -0
- package/dist/doctor/knowledge-summary.js +81 -0
- package/dist/doctor/knowledge-summary.js.map +1 -0
- package/dist/doctor/knowledge.d.ts +192 -0
- package/dist/doctor/knowledge.d.ts.map +1 -0
- package/dist/doctor/knowledge.js +1864 -0
- package/dist/doctor/knowledge.js.map +1 -0
- package/dist/git/work-tree.d.ts +169 -0
- package/dist/git/work-tree.d.ts.map +1 -0
- package/dist/git/work-tree.js +341 -0
- package/dist/git/work-tree.js.map +1 -0
- package/dist/hooks/handlers/task-hooks.d.ts +8 -5
- package/dist/hooks/handlers/task-hooks.d.ts.map +1 -1
- package/dist/hooks/handlers/task-hooks.js +15 -60
- package/dist/hooks/handlers/task-hooks.js.map +1 -1
- package/dist/identity/cleo-identity.d.ts +13 -0
- package/dist/identity/cleo-identity.d.ts.map +1 -1
- package/dist/identity/cleo-identity.js +20 -6
- package/dist/identity/cleo-identity.js.map +1 -1
- package/dist/injection.d.ts.map +1 -1
- package/dist/injection.js +29 -13
- package/dist/injection.js.map +1 -1
- package/dist/internal.d.ts +3 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +4 -0
- package/dist/internal.js.map +1 -1
- package/dist/lifecycle/verification/satisfies-validator.d.ts.map +1 -1
- package/dist/lifecycle/verification/satisfies-validator.js +124 -120
- package/dist/lifecycle/verification/satisfies-validator.js.map +1 -1
- package/dist/llm/plugin-facade.js +4047 -1726
- package/dist/llm/plugin-facade.js.map +3 -3
- package/dist/memory/brain-backfill.d.ts +27 -12
- package/dist/memory/brain-backfill.d.ts.map +1 -1
- package/dist/memory/brain-backfill.js +325 -134
- package/dist/memory/brain-backfill.js.map +1 -1
- package/dist/memory/brain-doctor.d.ts +21 -0
- package/dist/memory/brain-doctor.d.ts.map +1 -1
- package/dist/memory/brain-doctor.js +111 -53
- package/dist/memory/brain-doctor.js.map +1 -1
- package/dist/memory/brain-links.d.ts.map +1 -1
- package/dist/memory/brain-links.js +31 -4
- package/dist/memory/brain-links.js.map +1 -1
- package/dist/memory/brain-reasoning.d.ts.map +1 -1
- package/dist/memory/brain-reasoning.js +28 -2
- package/dist/memory/brain-reasoning.js.map +1 -1
- package/dist/memory/brain-reconciler.d.ts +14 -19
- package/dist/memory/brain-reconciler.d.ts.map +1 -1
- package/dist/memory/brain-reconciler.js +70 -97
- package/dist/memory/brain-reconciler.js.map +1 -1
- package/dist/memory/brain-search.d.ts +2 -0
- package/dist/memory/brain-search.d.ts.map +1 -1
- package/dist/memory/brain-search.js +59 -29
- package/dist/memory/brain-search.js.map +1 -1
- package/dist/memory/brain-similarity.d.ts.map +1 -1
- package/dist/memory/brain-similarity.js +5 -4
- package/dist/memory/brain-similarity.js.map +1 -1
- package/dist/memory/brain-stub-prune.d.ts +31 -9
- package/dist/memory/brain-stub-prune.d.ts.map +1 -1
- package/dist/memory/brain-stub-prune.js +65 -18
- package/dist/memory/brain-stub-prune.js.map +1 -1
- package/dist/memory/brain-writer-handlers.d.ts +10 -1
- package/dist/memory/brain-writer-handlers.d.ts.map +1 -1
- package/dist/memory/brain-writer-handlers.js +23 -3
- package/dist/memory/brain-writer-handlers.js.map +1 -1
- package/dist/memory/brain-writer-thread.d.ts +11 -1
- package/dist/memory/brain-writer-thread.d.ts.map +1 -1
- package/dist/memory/brain-writer-thread.js +87 -20
- package/dist/memory/brain-writer-thread.js.map +1 -1
- package/dist/memory/brain-writer-worker.js +8 -1
- package/dist/memory/brain-writer-worker.js.map +1 -1
- package/dist/memory/decision-cross-link.d.ts +39 -0
- package/dist/memory/decision-cross-link.d.ts.map +1 -1
- package/dist/memory/decision-cross-link.js +316 -0
- package/dist/memory/decision-cross-link.js.map +1 -1
- package/dist/memory/decisions.d.ts +4 -1
- package/dist/memory/decisions.d.ts.map +1 -1
- package/dist/memory/decisions.js +7 -24
- package/dist/memory/decisions.js.map +1 -1
- package/dist/memory/dispatch-trace.d.ts +12 -5
- package/dist/memory/dispatch-trace.d.ts.map +1 -1
- package/dist/memory/dispatch-trace.js +17 -7
- package/dist/memory/dispatch-trace.js.map +1 -1
- package/dist/memory/eligibility.d.ts +51 -0
- package/dist/memory/eligibility.d.ts.map +1 -0
- package/dist/memory/eligibility.js +77 -0
- package/dist/memory/eligibility.js.map +1 -0
- package/dist/memory/engine-compat.d.ts +2 -0
- package/dist/memory/engine-compat.d.ts.map +1 -1
- package/dist/memory/engine-compat.js +10 -0
- package/dist/memory/engine-compat.js.map +1 -1
- package/dist/memory/extraction-gate.d.ts +21 -7
- package/dist/memory/extraction-gate.d.ts.map +1 -1
- package/dist/memory/extraction-gate.js +178 -216
- package/dist/memory/extraction-gate.js.map +1 -1
- package/dist/memory/graph-auto-populate.d.ts +38 -5
- package/dist/memory/graph-auto-populate.d.ts.map +1 -1
- package/dist/memory/graph-auto-populate.js +182 -60
- package/dist/memory/graph-auto-populate.js.map +1 -1
- package/dist/memory/graph-memory-bridge.d.ts +14 -1
- package/dist/memory/graph-memory-bridge.d.ts.map +1 -1
- package/dist/memory/graph-memory-bridge.js +66 -28
- package/dist/memory/graph-memory-bridge.js.map +1 -1
- package/dist/memory/index.d.ts +1 -19
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +1 -50
- package/dist/memory/index.js.map +1 -1
- package/dist/memory/learnings.d.ts.map +1 -1
- package/dist/memory/learnings.js +2 -23
- package/dist/memory/learnings.js.map +1 -1
- package/dist/memory/manifest-filter.d.ts +21 -0
- package/dist/memory/manifest-filter.d.ts.map +1 -0
- package/dist/memory/manifest-filter.js +51 -0
- package/dist/memory/manifest-filter.js.map +1 -0
- package/dist/memory/manifest-ingestion.d.ts +28 -30
- package/dist/memory/manifest-ingestion.d.ts.map +1 -1
- package/dist/memory/manifest-ingestion.js +104 -235
- package/dist/memory/manifest-ingestion.js.map +1 -1
- package/dist/memory/observer-reflector.d.ts +2 -0
- package/dist/memory/observer-reflector.d.ts.map +1 -1
- package/dist/memory/observer-reflector.js +6 -49
- package/dist/memory/observer-reflector.js.map +1 -1
- package/dist/memory/patterns.d.ts +10 -0
- package/dist/memory/patterns.d.ts.map +1 -1
- package/dist/memory/patterns.js +25 -33
- package/dist/memory/patterns.js.map +1 -1
- package/dist/memory/pipeline-manifest-sqlite.d.ts +72 -9
- package/dist/memory/pipeline-manifest-sqlite.d.ts.map +1 -1
- package/dist/memory/pipeline-manifest-sqlite.js +508 -412
- package/dist/memory/pipeline-manifest-sqlite.js.map +1 -1
- package/dist/memory/retrieval/build-retrieval-bundle.d.ts.map +1 -1
- package/dist/memory/retrieval/build-retrieval-bundle.js +16 -15
- package/dist/memory/retrieval/build-retrieval-bundle.js.map +1 -1
- package/dist/memory/retrieval/fetch.d.ts +7 -0
- package/dist/memory/retrieval/fetch.d.ts.map +1 -1
- package/dist/memory/retrieval/fetch.js +14 -11
- package/dist/memory/retrieval/fetch.js.map +1 -1
- package/dist/memory/retrieval/observe.d.ts +7 -1
- package/dist/memory/retrieval/observe.d.ts.map +1 -1
- package/dist/memory/retrieval/observe.js +58 -4
- package/dist/memory/retrieval/observe.js.map +1 -1
- package/dist/memory/retrieval/search.d.ts +14 -1
- package/dist/memory/retrieval/search.d.ts.map +1 -1
- package/dist/memory/retrieval/search.js +133 -69
- package/dist/memory/retrieval/search.js.map +1 -1
- package/dist/memory/retrieval/telemetry.d.ts +31 -0
- package/dist/memory/retrieval/telemetry.d.ts.map +1 -0
- package/dist/memory/retrieval/telemetry.js +53 -0
- package/dist/memory/retrieval/telemetry.js.map +1 -0
- package/dist/nexus/analyze-orchestrator.d.ts +41 -9
- package/dist/nexus/analyze-orchestrator.d.ts.map +1 -1
- package/dist/nexus/analyze-orchestrator.js +257 -58
- package/dist/nexus/analyze-orchestrator.js.map +1 -1
- package/dist/nexus/api-contracts.d.ts +2 -6
- package/dist/nexus/api-contracts.d.ts.map +1 -1
- package/dist/nexus/api-contracts.js +11 -2
- package/dist/nexus/api-contracts.js.map +1 -1
- package/dist/nexus/context.d.ts.map +1 -1
- package/dist/nexus/context.js +14 -37
- package/dist/nexus/context.js.map +1 -1
- package/dist/nexus/diff.d.ts.map +1 -1
- package/dist/nexus/diff.js +2 -1
- package/dist/nexus/diff.js.map +1 -1
- package/dist/nexus/identity.d.ts +29 -3
- package/dist/nexus/identity.d.ts.map +1 -1
- package/dist/nexus/identity.js +63 -12
- package/dist/nexus/identity.js.map +1 -1
- package/dist/nexus/impact.d.ts +21 -19
- package/dist/nexus/impact.d.ts.map +1 -1
- package/dist/nexus/impact.js +96 -192
- package/dist/nexus/impact.js.map +1 -1
- package/dist/nexus/knowledge.d.ts +80 -0
- package/dist/nexus/knowledge.d.ts.map +1 -0
- package/dist/nexus/knowledge.js +786 -0
- package/dist/nexus/knowledge.js.map +1 -0
- package/dist/nexus/living-brain.d.ts +8 -5
- package/dist/nexus/living-brain.d.ts.map +1 -1
- package/dist/nexus/living-brain.js +252 -188
- package/dist/nexus/living-brain.js.map +1 -1
- package/dist/nexus/registry.d.ts +11 -2
- package/dist/nexus/registry.d.ts.map +1 -1
- package/dist/nexus/registry.js +144 -128
- package/dist/nexus/registry.js.map +1 -1
- package/dist/nexus/source-roots.d.ts +16 -0
- package/dist/nexus/source-roots.d.ts.map +1 -0
- package/dist/nexus/source-roots.js +174 -0
- package/dist/nexus/source-roots.js.map +1 -0
- package/dist/nexus/task-evidence.d.ts +22 -0
- package/dist/nexus/task-evidence.d.ts.map +1 -0
- package/dist/nexus/task-evidence.js +210 -0
- package/dist/nexus/task-evidence.js.map +1 -0
- package/dist/nexus/tasks-bridge.d.ts +14 -7
- package/dist/nexus/tasks-bridge.d.ts.map +1 -1
- package/dist/nexus/tasks-bridge.js +81 -40
- package/dist/nexus/tasks-bridge.js.map +1 -1
- package/dist/orchestrate/lifecycle-ops.d.ts.map +1 -1
- package/dist/orchestrate/lifecycle-ops.js +170 -120
- package/dist/orchestrate/lifecycle-ops.js.map +1 -1
- package/dist/orchestrate/query-ops.d.ts +6 -7
- package/dist/orchestrate/query-ops.d.ts.map +1 -1
- package/dist/orchestrate/query-ops.js +509 -532
- package/dist/orchestrate/query-ops.js.map +1 -1
- package/dist/orchestration/bootstrap.d.ts +15 -1
- package/dist/orchestration/bootstrap.d.ts.map +1 -1
- package/dist/orchestration/bootstrap.js +21 -10
- package/dist/orchestration/bootstrap.js.map +1 -1
- package/dist/orchestration/index.d.ts +35 -3
- package/dist/orchestration/index.d.ts.map +1 -1
- package/dist/orchestration/index.js +64 -35
- package/dist/orchestration/index.js.map +1 -1
- package/dist/orchestration/lead-rollup.d.ts +24 -1
- package/dist/orchestration/lead-rollup.d.ts.map +1 -1
- package/dist/orchestration/lead-rollup.js +31 -11
- package/dist/orchestration/lead-rollup.js.map +1 -1
- package/dist/orchestration/spawn-prompt.d.ts.map +1 -1
- package/dist/orchestration/spawn-prompt.js +25 -45
- package/dist/orchestration/spawn-prompt.js.map +1 -1
- package/dist/orchestration/unblock.d.ts +15 -1
- package/dist/orchestration/unblock.d.ts.map +1 -1
- package/dist/orchestration/unblock.js +23 -12
- package/dist/orchestration/unblock.js.map +1 -1
- package/dist/orchestration/validate-spawn.d.ts.map +1 -1
- package/dist/orchestration/validate-spawn.js +3 -3
- package/dist/orchestration/validate-spawn.js.map +1 -1
- package/dist/orchestration/waves.d.ts +29 -13
- package/dist/orchestration/waves.d.ts.map +1 -1
- package/dist/orchestration/waves.js +43 -55
- package/dist/orchestration/waves.js.map +1 -1
- package/dist/paths.d.ts +17 -163
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +145 -496
- package/dist/paths.js.map +1 -1
- package/dist/project-info.d.ts +2 -11
- package/dist/project-info.d.ts.map +1 -1
- package/dist/project-info.js +3 -31
- package/dist/project-info.js.map +1 -1
- package/dist/project-scope.d.ts +239 -0
- package/dist/project-scope.d.ts.map +1 -0
- package/dist/project-scope.js +473 -0
- package/dist/project-scope.js.map +1 -0
- package/dist/release/pr-evidence.d.ts +23 -4
- package/dist/release/pr-evidence.d.ts.map +1 -1
- package/dist/release/pr-evidence.js +65 -9
- package/dist/release/pr-evidence.js.map +1 -1
- package/dist/render/nexus/graph/index.d.ts.map +1 -1
- package/dist/render/nexus/graph/index.js +4 -2
- package/dist/render/nexus/graph/index.js.map +1 -1
- package/dist/render/orchestration/audit-reconstruct.d.ts +11 -0
- package/dist/render/orchestration/audit-reconstruct.d.ts.map +1 -1
- package/dist/render/orchestration/audit-reconstruct.js +21 -6
- package/dist/render/orchestration/audit-reconstruct.js.map +1 -1
- package/dist/render/tasks/show.js +2 -1
- package/dist/render/tasks/show.js.map +1 -1
- package/dist/resources/spawn-wrapper.d.ts +82 -14
- package/dist/resources/spawn-wrapper.d.ts.map +1 -1
- package/dist/resources/spawn-wrapper.js +585 -27
- package/dist/resources/spawn-wrapper.js.map +1 -1
- package/dist/selfimprove/fix-gen.js +4055 -1734
- package/dist/selfimprove/fix-gen.js.map +3 -3
- package/dist/sequence/index.d.ts.map +1 -1
- package/dist/sequence/index.js +76 -68
- package/dist/sequence/index.js.map +1 -1
- package/dist/session/canon-lint.d.ts +24 -3
- package/dist/session/canon-lint.d.ts.map +1 -1
- package/dist/session/canon-lint.js +72 -31
- package/dist/session/canon-lint.js.map +1 -1
- package/dist/session/engine-ops.d.ts +1 -4
- package/dist/session/engine-ops.d.ts.map +1 -1
- package/dist/session/engine-ops.js +42 -6
- package/dist/session/engine-ops.js.map +1 -1
- package/dist/sessions/briefing.d.ts +11 -1
- package/dist/sessions/briefing.d.ts.map +1 -1
- package/dist/sessions/briefing.js +76 -8
- package/dist/sessions/briefing.js.map +1 -1
- package/dist/sessions/handoff.d.ts +3 -1
- package/dist/sessions/handoff.d.ts.map +1 -1
- package/dist/sessions/handoff.js +2 -0
- package/dist/sessions/handoff.js.map +1 -1
- package/dist/shutdown-deadline.d.ts +24 -33
- package/dist/shutdown-deadline.d.ts.map +1 -1
- package/dist/shutdown-deadline.js +71 -14
- package/dist/shutdown-deadline.js.map +1 -1
- package/dist/shutdown.d.ts +21 -10
- package/dist/shutdown.d.ts.map +1 -1
- package/dist/shutdown.js +89 -42
- package/dist/shutdown.js.map +1 -1
- package/dist/skills/index.d.ts +1 -1
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +1 -1
- package/dist/skills/index.js.map +1 -1
- package/dist/skills/orchestrator/validator.d.ts +87 -20
- package/dist/skills/orchestrator/validator.d.ts.map +1 -1
- package/dist/skills/orchestrator/validator.js +330 -241
- package/dist/skills/orchestrator/validator.js.map +1 -1
- package/dist/store/agent-resolver.d.ts.map +1 -1
- package/dist/store/agent-resolver.js +16 -9
- package/dist/store/agent-resolver.js.map +1 -1
- package/dist/store/attachment-store.d.ts +4 -1
- package/dist/store/attachment-store.d.ts.map +1 -1
- package/dist/store/attachment-store.js +20 -3
- package/dist/store/attachment-store.js.map +1 -1
- package/dist/store/background-jobs.d.ts +426 -105
- package/dist/store/background-jobs.d.ts.map +1 -1
- package/dist/store/background-jobs.js +1208 -252
- package/dist/store/background-jobs.js.map +1 -1
- package/dist/store/background-ops.d.ts +145 -8
- package/dist/store/background-ops.d.ts.map +1 -1
- package/dist/store/background-ops.js +459 -15
- package/dist/store/background-ops.js.map +1 -1
- package/dist/store/backup-inspect.d.ts +48 -4
- package/dist/store/backup-inspect.d.ts.map +1 -1
- package/dist/store/backup-inspect.js +384 -4
- package/dist/store/backup-inspect.js.map +1 -1
- package/dist/store/converters.d.ts.map +1 -1
- package/dist/store/converters.js +19 -2
- package/dist/store/converters.js.map +1 -1
- package/dist/store/data-accessor.d.ts +9 -1
- package/dist/store/data-accessor.d.ts.map +1 -1
- package/dist/store/data-accessor.js +22 -5
- package/dist/store/data-accessor.js.map +1 -1
- package/dist/store/data-safety-central.d.ts.map +1 -1
- package/dist/store/data-safety-central.js +272 -232
- package/dist/store/data-safety-central.js.map +1 -1
- package/dist/store/db-helpers.d.ts +19 -3
- package/dist/store/db-helpers.d.ts.map +1 -1
- package/dist/store/db-helpers.js +42 -58
- package/dist/store/db-helpers.js.map +1 -1
- package/dist/store/dual-scope-db.d.ts +63 -4
- package/dist/store/dual-scope-db.d.ts.map +1 -1
- package/dist/store/dual-scope-db.js +166 -19
- package/dist/store/dual-scope-db.js.map +1 -1
- package/dist/store/exodus/archive.d.ts +21 -7
- package/dist/store/exodus/archive.d.ts.map +1 -1
- package/dist/store/exodus/archive.js +60 -18
- package/dist/store/exodus/archive.js.map +1 -1
- package/dist/store/exodus/migrate.d.ts.map +1 -1
- package/dist/store/exodus/migrate.js +27 -23
- package/dist/store/exodus/migrate.js.map +1 -1
- package/dist/store/exodus/on-open.d.ts +16 -27
- package/dist/store/exodus/on-open.d.ts.map +1 -1
- package/dist/store/exodus/on-open.js +121 -169
- package/dist/store/exodus/on-open.js.map +1 -1
- package/dist/store/exodus/recovery.d.ts +90 -0
- package/dist/store/exodus/recovery.d.ts.map +1 -0
- package/dist/store/exodus/recovery.js +434 -0
- package/dist/store/exodus/recovery.js.map +1 -0
- package/dist/store/exodus/types.d.ts +15 -0
- package/dist/store/exodus/types.d.ts.map +1 -1
- package/dist/store/memory-accessor.d.ts +52 -3
- package/dist/store/memory-accessor.d.ts.map +1 -1
- package/dist/store/memory-accessor.js +122 -7
- package/dist/store/memory-accessor.js.map +1 -1
- package/dist/store/nexus-sqlite.d.ts +24 -6
- package/dist/store/nexus-sqlite.d.ts.map +1 -1
- package/dist/store/nexus-sqlite.js +39 -20
- package/dist/store/nexus-sqlite.js.map +1 -1
- package/dist/store/ports/domain-binding.d.ts.map +1 -1
- package/dist/store/ports/domain-binding.js +27 -5
- package/dist/store/ports/domain-binding.js.map +1 -1
- package/dist/store/schema/background-jobs.d.ts +181 -2
- package/dist/store/schema/background-jobs.d.ts.map +1 -1
- package/dist/store/schema/background-jobs.js +27 -3
- package/dist/store/schema/background-jobs.js.map +1 -1
- package/dist/store/schema/cleo-global/skills.d.ts +2 -2
- package/dist/store/schema/cleo-project/lifecycle.d.ts +2 -2
- package/dist/store/schema/cleo-project/runtime.d.ts +1 -1
- package/dist/store/schema/cleo-project/tasks-core.d.ts +1 -1
- package/dist/store/schema/lifecycle.d.ts +2 -2
- package/dist/store/schema/skills-schema.d.ts +2 -2
- package/dist/store/schema/tasks.d.ts +1 -1
- package/dist/store/session-store.d.ts +3 -1
- package/dist/store/session-store.d.ts.map +1 -1
- package/dist/store/session-store.js +252 -207
- package/dist/store/session-store.js.map +1 -1
- package/dist/store/sqlite-data-accessor.d.ts +39 -4
- package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
- package/dist/store/sqlite-data-accessor.js +689 -527
- package/dist/store/sqlite-data-accessor.js.map +1 -1
- package/dist/store/tasks-sqlite.d.ts +3 -1
- package/dist/store/tasks-sqlite.d.ts.map +1 -1
- package/dist/store/tasks-sqlite.js +309 -279
- package/dist/store/tasks-sqlite.js.map +1 -1
- package/dist/store/validation-schemas.d.ts +8 -8
- package/dist/store/writer-lease.d.ts +80 -8
- package/dist/store/writer-lease.d.ts.map +1 -1
- package/dist/store/writer-lease.js +503 -134
- package/dist/store/writer-lease.js.map +1 -1
- package/dist/system/audit.d.ts +2 -1
- package/dist/system/audit.d.ts.map +1 -1
- package/dist/system/audit.js +118 -71
- package/dist/system/audit.js.map +1 -1
- package/dist/system/backup.d.ts.map +1 -1
- package/dist/system/backup.js +5 -5
- package/dist/system/backup.js.map +1 -1
- package/dist/system/inject-generate.js +1 -1
- package/dist/task-work/index.d.ts +3 -0
- package/dist/task-work/index.d.ts.map +1 -1
- package/dist/task-work/index.js +34 -37
- package/dist/task-work/index.js.map +1 -1
- package/dist/tasks/ac-coverage-gate.d.ts.map +1 -1
- package/dist/tasks/ac-coverage-gate.js +4 -0
- package/dist/tasks/ac-coverage-gate.js.map +1 -1
- package/dist/tasks/ac-immutability.d.ts +7 -4
- package/dist/tasks/ac-immutability.d.ts.map +1 -1
- package/dist/tasks/ac-immutability.js +19 -17
- package/dist/tasks/ac-immutability.js.map +1 -1
- package/dist/tasks/ac-table.d.ts +5 -5
- package/dist/tasks/ac-table.d.ts.map +1 -1
- package/dist/tasks/ac-table.js +26 -12
- package/dist/tasks/ac-table.js.map +1 -1
- package/dist/tasks/acceptance-input.d.ts +52 -0
- package/dist/tasks/acceptance-input.d.ts.map +1 -0
- package/dist/tasks/acceptance-input.js +259 -0
- package/dist/tasks/acceptance-input.js.map +1 -0
- package/dist/tasks/add.d.ts +67 -29
- package/dist/tasks/add.d.ts.map +1 -1
- package/dist/tasks/add.js +255 -97
- package/dist/tasks/add.js.map +1 -1
- package/dist/tasks/complete.d.ts +16 -1
- package/dist/tasks/complete.d.ts.map +1 -1
- package/dist/tasks/complete.js +152 -55
- package/dist/tasks/complete.js.map +1 -1
- package/dist/tasks/decompose.d.ts +103 -0
- package/dist/tasks/decompose.d.ts.map +1 -0
- package/dist/tasks/decompose.js +224 -0
- package/dist/tasks/decompose.js.map +1 -0
- package/dist/tasks/delete.d.ts +5 -8
- package/dist/tasks/delete.d.ts.map +1 -1
- package/dist/tasks/delete.js +4 -3
- package/dist/tasks/delete.js.map +1 -1
- package/dist/tasks/dependency-check.d.ts +59 -0
- package/dist/tasks/dependency-check.d.ts.map +1 -1
- package/dist/tasks/dependency-check.js +73 -0
- package/dist/tasks/dependency-check.js.map +1 -1
- package/dist/tasks/deps-ready.d.ts +13 -1
- package/dist/tasks/deps-ready.d.ts.map +1 -1
- package/dist/tasks/deps-ready.js +16 -5
- package/dist/tasks/deps-ready.js.map +1 -1
- package/dist/tasks/engine-converters.d.ts +7 -0
- package/dist/tasks/engine-converters.d.ts.map +1 -1
- package/dist/tasks/engine-converters.js +8 -1
- package/dist/tasks/engine-converters.js.map +1 -1
- package/dist/tasks/evidence.d.ts +88 -27
- package/dist/tasks/evidence.d.ts.map +1 -1
- package/dist/tasks/evidence.js +344 -43
- package/dist/tasks/evidence.js.map +1 -1
- package/dist/tasks/find.d.ts +16 -12
- package/dist/tasks/find.d.ts.map +1 -1
- package/dist/tasks/find.js +107 -93
- package/dist/tasks/find.js.map +1 -1
- package/dist/tasks/gate-preview.d.ts +73 -0
- package/dist/tasks/gate-preview.d.ts.map +1 -0
- package/dist/tasks/gate-preview.js +119 -0
- package/dist/tasks/gate-preview.js.map +1 -0
- package/dist/tasks/gate-runner.d.ts +88 -14
- package/dist/tasks/gate-runner.d.ts.map +1 -1
- package/dist/tasks/gate-runner.js +719 -250
- package/dist/tasks/gate-runner.js.map +1 -1
- package/dist/tasks/hierarchy-policy.d.ts +8 -0
- package/dist/tasks/hierarchy-policy.d.ts.map +1 -1
- package/dist/tasks/hierarchy-policy.js +9 -2
- package/dist/tasks/hierarchy-policy.js.map +1 -1
- package/dist/tasks/hierarchy.d.ts +67 -1
- package/dist/tasks/hierarchy.d.ts.map +1 -1
- package/dist/tasks/hierarchy.js +81 -1
- package/dist/tasks/hierarchy.js.map +1 -1
- package/dist/tasks/index.d.ts +3 -0
- package/dist/tasks/index.d.ts.map +1 -1
- package/dist/tasks/index.js +3 -0
- package/dist/tasks/index.js.map +1 -1
- package/dist/tasks/infer-add-params.d.ts +1 -20
- package/dist/tasks/infer-add-params.d.ts.map +1 -1
- package/dist/tasks/infer-add-params.js +2 -203
- package/dist/tasks/infer-add-params.js.map +1 -1
- package/dist/tasks/list.d.ts +7 -2
- package/dist/tasks/list.d.ts.map +1 -1
- package/dist/tasks/list.js +24 -36
- package/dist/tasks/list.js.map +1 -1
- package/dist/tasks/ops.d.ts +6 -61
- package/dist/tasks/ops.d.ts.map +1 -1
- package/dist/tasks/ops.js +5 -53
- package/dist/tasks/ops.js.map +1 -1
- package/dist/tasks/plan.d.ts +15 -1
- package/dist/tasks/plan.d.ts.map +1 -1
- package/dist/tasks/plan.js +23 -25
- package/dist/tasks/plan.js.map +1 -1
- package/dist/tasks/population.d.ts +46 -0
- package/dist/tasks/population.d.ts.map +1 -0
- package/dist/tasks/population.js +88 -0
- package/dist/tasks/population.js.map +1 -0
- package/dist/tasks/reconcile-scope.d.ts +157 -0
- package/dist/tasks/reconcile-scope.d.ts.map +1 -0
- package/dist/tasks/reconcile-scope.js +242 -0
- package/dist/tasks/reconcile-scope.js.map +1 -0
- package/dist/tasks/req.d.ts +51 -12
- package/dist/tasks/req.d.ts.map +1 -1
- package/dist/tasks/req.js +125 -69
- package/dist/tasks/req.js.map +1 -1
- package/dist/tasks/session-scope.d.ts +6 -31
- package/dist/tasks/session-scope.d.ts.map +1 -1
- package/dist/tasks/session-scope.js +3 -17
- package/dist/tasks/session-scope.js.map +1 -1
- package/dist/tasks/severity-attestation.d.ts +39 -10
- package/dist/tasks/severity-attestation.d.ts.map +1 -1
- package/dist/tasks/severity-attestation.js +75 -36
- package/dist/tasks/severity-attestation.js.map +1 -1
- package/dist/tasks/task-next.d.ts +5 -0
- package/dist/tasks/task-next.d.ts.map +1 -1
- package/dist/tasks/task-next.js +10 -9
- package/dist/tasks/task-next.js.map +1 -1
- package/dist/tasks/task-reparent.d.ts.map +1 -1
- package/dist/tasks/task-reparent.js +3 -13
- package/dist/tasks/task-reparent.js.map +1 -1
- package/dist/tasks/update.d.ts +20 -43
- package/dist/tasks/update.d.ts.map +1 -1
- package/dist/tasks/update.js +64 -49
- package/dist/tasks/update.js.map +1 -1
- package/dist/validation/engine-ops.d.ts +17 -1
- package/dist/validation/engine-ops.d.ts.map +1 -1
- package/dist/validation/engine-ops.js +149 -11
- package/dist/validation/engine-ops.js.map +1 -1
- package/dist/workgraph/reparent-preflight.d.ts +1 -1
- package/dist/workgraph/reparent-preflight.d.ts.map +1 -1
- package/dist/workgraph/reparent-preflight.js +6 -1
- package/dist/workgraph/reparent-preflight.js.map +1 -1
- package/dist/workgraph/scaffold-apply.d.ts.map +1 -1
- package/dist/workgraph/scaffold-apply.js +81 -76
- package/dist/workgraph/scaffold-apply.js.map +1 -1
- package/dist/workgraph/structure-validation.d.ts +1 -1
- package/dist/workgraph/structure-validation.d.ts.map +1 -1
- package/dist/workgraph/structure-validation.js +6 -1
- package/dist/workgraph/structure-validation.js.map +1 -1
- package/migrations/drizzle-tasks/20260919180000_t12263-job-ownership-fences/migration.sql +34 -0
- package/migrations/drizzle-tasks/20260919184500_t12265-durable-pending-proposals/migration.sql +4 -0
- package/package.json +18 -13
- package/schemas/config.schema.json +2 -2
- package/schemas/project-context.schema.json +12 -0
- package/templates/CLEO-INJECTION.md +114 -101
|
@@ -18,12 +18,14 @@
|
|
|
18
18
|
*
|
|
19
19
|
* T1003: Staged backfill functions (stagedBackfillRun, approveBackfillRun,
|
|
20
20
|
* rollbackBackfillRun, listBackfillRuns) are appended below the graph
|
|
21
|
-
* back-fill core. Staged runs
|
|
22
|
-
*
|
|
21
|
+
* back-fill core. Staged runs capture exact source/version and incident-edge
|
|
22
|
+
* preconditions in brain_backfill_runs; approval reconstructs only those missing
|
|
23
|
+
* nodes, without synthesizing edges or invoking the broad graph back-fill.
|
|
23
24
|
*
|
|
24
25
|
* @task T530
|
|
25
26
|
* @epic T523
|
|
26
27
|
*/
|
|
28
|
+
import type { KnowledgeBackfillOptions } from '@cleocode/contracts';
|
|
27
29
|
import type { BrainBackfillRunRow } from '../store/schema/memory-schema.js';
|
|
28
30
|
/** Result returned by backfillBrainGraph. */
|
|
29
31
|
export interface BrainBackfillResult {
|
|
@@ -84,8 +86,9 @@ export interface StagedBackfillRunResult {
|
|
|
84
86
|
*
|
|
85
87
|
* Discovers all candidate node IDs from typed tables (decisions, patterns,
|
|
86
88
|
* learnings, observations, sticky notes) that are NOT yet in brain_page_nodes.
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
+
* Captures exact nodes, source hashes, incident-edge fingerprints and project binding in
|
|
90
|
+
* `rollback_snapshot_json`, and creates a `brain_backfill_runs`
|
|
91
|
+
* row with status='staged'. The ledger is written, but derived graph rows are unchanged.
|
|
89
92
|
*
|
|
90
93
|
* Pass `source` as a human-readable descriptor (e.g. a file path or session ID).
|
|
91
94
|
* Pass `kind` as the backfill kind (e.g. 'graph-backfill', 'observation-promotion').
|
|
@@ -95,18 +98,20 @@ export interface StagedBackfillRunResult {
|
|
|
95
98
|
* @returns StagedBackfillRunResult with the staged run record.
|
|
96
99
|
*
|
|
97
100
|
* @task T1003
|
|
101
|
+
* @remarks The snapshot captures exact source and relationship preconditions without mutating derived nodes.
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* const staged = await stagedBackfillRun(projectRoot, undefined);
|
|
105
|
+
* ```
|
|
98
106
|
*/
|
|
99
|
-
export declare function stagedBackfillRun(projectRoot: string, opts?:
|
|
100
|
-
source?: string;
|
|
101
|
-
kind?: string;
|
|
102
|
-
targetTable?: string;
|
|
103
|
-
}): Promise<StagedBackfillRunResult>;
|
|
107
|
+
export declare function stagedBackfillRun(projectRoot: string, opts?: KnowledgeBackfillOptions): Promise<StagedBackfillRunResult>;
|
|
104
108
|
/**
|
|
105
109
|
* Approve a staged backfill run, committing its rows to live brain tables.
|
|
106
110
|
*
|
|
107
|
-
* Reads the run
|
|
108
|
-
*
|
|
109
|
-
*
|
|
111
|
+
* Reads the staged run under a writer transaction, validates its exact source
|
|
112
|
+
* and graph preconditions, then inserts only its reviewed derived nodes. The
|
|
113
|
+
* same transaction records created-row hashes and approval metadata for recovery.
|
|
114
|
+
* Historical edges remain unchanged.
|
|
110
115
|
*
|
|
111
116
|
* Double-approve is idempotent: returns `{ alreadySettled: true }` if the run
|
|
112
117
|
* is already approved or rolled-back.
|
|
@@ -117,6 +122,11 @@ export declare function stagedBackfillRun(projectRoot: string, opts?: {
|
|
|
117
122
|
* @returns Result with the updated run record and graph backfill stats.
|
|
118
123
|
*
|
|
119
124
|
* @task T1003
|
|
125
|
+
* @remarks Approval inserts only the reviewed nodes and records recovery hashes atomically; stale source or graph state is rejected.
|
|
126
|
+
* @example
|
|
127
|
+
* ```ts
|
|
128
|
+
* const applied = await approveBackfillRun(projectRoot, runId, 'calling-agent');
|
|
129
|
+
* ```
|
|
120
130
|
*/
|
|
121
131
|
export declare function approveBackfillRun(projectRoot: string, runId: string, approvedBy?: string): Promise<{
|
|
122
132
|
run: BrainBackfillRunRow;
|
|
@@ -140,6 +150,11 @@ export declare function approveBackfillRun(projectRoot: string, runId: string, a
|
|
|
140
150
|
* @returns Result with the updated run record and optional delete count.
|
|
141
151
|
*
|
|
142
152
|
* @task T1003
|
|
153
|
+
* @remarks Recovery removes only unchanged nodes created by this run and refuses concurrent node or edge edits.
|
|
154
|
+
* @example
|
|
155
|
+
* ```ts
|
|
156
|
+
* const restored = await rollbackBackfillRun(projectRoot, runId);
|
|
157
|
+
* ```
|
|
143
158
|
*/
|
|
144
159
|
export declare function rollbackBackfillRun(projectRoot: string, runId: string): Promise<{
|
|
145
160
|
run: BrainBackfillRunRow;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"brain-backfill.d.ts","sourceRoot":"","sources":["../../src/memory/brain-backfill.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"brain-backfill.d.ts","sourceRoot":"","sources":["../../src/memory/brain-backfill.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAIH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAIpE,OAAO,KAAK,EACV,mBAAmB,EAOpB,MAAM,kCAAkC,CAAC;AAO1C,6CAA6C;AAC7C,MAAM,WAAW,mBAAmB;IAClC,uCAAuC;IACvC,MAAM,EAAE;QACN,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,sCAAsC;IACtC,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,gDAAgD;IAChD,aAAa,EAAE,MAAM,CAAC;IACtB,gDAAgD;IAChD,aAAa,EAAE,MAAM,CAAC;IACtB,qFAAqF;IACrF,YAAY,EAAE,MAAM,CAAC;IACrB,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AA8ED;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA8T1F;AAgBD;;;;;;;GAOG;AACH,MAAM,WAAW,uBAAuB;IACtC,0BAA0B;IAC1B,GAAG,EAAE,mBAAmB,CAAC;IACzB;;;OAGG;IACH,KAAK,EAAE,OAAO,CAAC;CAChB;AA+HD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE,wBAAwB,GAC9B,OAAO,CAAC,uBAAuB,CAAC,CAsGlC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC;IACT,GAAG,EAAE,mBAAmB,CAAC;IACzB,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,CAAC,EAAE,mBAAmB,CAAC;CACtC,CAAC,CAiGD;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;IACT,GAAG,EAAE,mBAAmB,CAAC;IACzB,cAAc,EAAE,OAAO,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC,CA6CD;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACzC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAqChC"}
|
|
@@ -18,13 +18,16 @@
|
|
|
18
18
|
*
|
|
19
19
|
* T1003: Staged backfill functions (stagedBackfillRun, approveBackfillRun,
|
|
20
20
|
* rollbackBackfillRun, listBackfillRuns) are appended below the graph
|
|
21
|
-
* back-fill core. Staged runs
|
|
22
|
-
*
|
|
21
|
+
* back-fill core. Staged runs capture exact source/version and incident-edge
|
|
22
|
+
* preconditions in brain_backfill_runs; approval reconstructs only those missing
|
|
23
|
+
* nodes, without synthesizing edges or invoking the broad graph back-fill.
|
|
23
24
|
*
|
|
24
25
|
* @task T530
|
|
25
26
|
* @epic T523
|
|
26
27
|
*/
|
|
27
28
|
import { createHash, randomBytes } from 'node:crypto';
|
|
29
|
+
import { realpathSync } from 'node:fs';
|
|
30
|
+
import { z } from 'zod';
|
|
28
31
|
import { getBrainAccessor } from '../store/memory-accessor.js';
|
|
29
32
|
import { getBrainDb, getBrainNativeDb } from '../store/memory-sqlite.js';
|
|
30
33
|
import * as brainSchema from '../store/schema/memory-schema.js';
|
|
@@ -403,13 +406,116 @@ function generateRunId() {
|
|
|
403
406
|
const rand = randomBytes(2).toString('hex');
|
|
404
407
|
return `bfr-${ts}-${rand}`;
|
|
405
408
|
}
|
|
409
|
+
const stagedSourceTableSchema = z.enum([
|
|
410
|
+
'brain_decisions',
|
|
411
|
+
'brain_patterns',
|
|
412
|
+
'brain_learnings',
|
|
413
|
+
'brain_observations',
|
|
414
|
+
'brain_sticky_notes',
|
|
415
|
+
]);
|
|
416
|
+
const stagedNodeSchema = z.object({
|
|
417
|
+
id: z.string(),
|
|
418
|
+
node_type: z.string(),
|
|
419
|
+
label: z.string(),
|
|
420
|
+
quality_score: z.number(),
|
|
421
|
+
content_hash: z.string(),
|
|
422
|
+
metadata_json: z.string(),
|
|
423
|
+
created_at: z.string(),
|
|
424
|
+
last_activity_at: z.string(),
|
|
425
|
+
updated_at: z.null(),
|
|
426
|
+
});
|
|
427
|
+
const stagedSnapshotSchema = z.object({
|
|
428
|
+
version: z.literal(2),
|
|
429
|
+
projectRoot: z.string(),
|
|
430
|
+
candidates: z
|
|
431
|
+
.array(z.object({
|
|
432
|
+
id: z.string(),
|
|
433
|
+
sourceTable: stagedSourceTableSchema,
|
|
434
|
+
sourceId: z.string(),
|
|
435
|
+
sourceHash: z.string(),
|
|
436
|
+
edgeHash: z.string(),
|
|
437
|
+
node: stagedNodeSchema,
|
|
438
|
+
}))
|
|
439
|
+
.max(500),
|
|
440
|
+
created: z
|
|
441
|
+
.array(z.object({ id: z.string(), rowHash: z.string(), edgeHash: z.string() }))
|
|
442
|
+
.max(500),
|
|
443
|
+
});
|
|
444
|
+
const stagedRunSchema = z.object({
|
|
445
|
+
id: z.string(),
|
|
446
|
+
kind: z.string(),
|
|
447
|
+
status: z.string(),
|
|
448
|
+
created_at: z.string(),
|
|
449
|
+
approved_at: z.string().nullable(),
|
|
450
|
+
rows_affected: z.number(),
|
|
451
|
+
rollback_snapshot_json: z.string().nullable(),
|
|
452
|
+
source: z.string(),
|
|
453
|
+
target_table: z.string(),
|
|
454
|
+
approved_by: z.string().nullable(),
|
|
455
|
+
});
|
|
456
|
+
const typedSourceSchema = z.record(z.string(), z.union([z.string(), z.number(), z.null()]));
|
|
457
|
+
const sourceKinds = {
|
|
458
|
+
brain_decisions: 'decision',
|
|
459
|
+
brain_patterns: 'pattern',
|
|
460
|
+
brain_learnings: 'learning',
|
|
461
|
+
brain_observations: 'observation',
|
|
462
|
+
brain_sticky_notes: 'sticky',
|
|
463
|
+
};
|
|
464
|
+
const volatileSourceFields = new Set([
|
|
465
|
+
'access_count',
|
|
466
|
+
'last_accessed_at',
|
|
467
|
+
'citation_count',
|
|
468
|
+
'last_cited_at',
|
|
469
|
+
'updated_at',
|
|
470
|
+
'retrieval_count',
|
|
471
|
+
'last_retrieved_at',
|
|
472
|
+
'last_activity_at',
|
|
473
|
+
'reinforcement_count',
|
|
474
|
+
]);
|
|
475
|
+
/** Hash source content and provenance without treating retrieval counters as an edit. */
|
|
476
|
+
function stagedSourceHash(row) {
|
|
477
|
+
return createHash('sha256')
|
|
478
|
+
.update(JSON.stringify(Object.entries(row)
|
|
479
|
+
.filter(([key]) => !volatileSourceFields.has(key))
|
|
480
|
+
.sort(([a], [b]) => a.localeCompare(b))))
|
|
481
|
+
.digest('hex');
|
|
482
|
+
}
|
|
483
|
+
/** Fingerprint exact graph rows, including concurrent relationship changes. */
|
|
484
|
+
function stagedGraphHash(value) {
|
|
485
|
+
return createHash('sha256').update(JSON.stringify(value)).digest('hex');
|
|
486
|
+
}
|
|
487
|
+
/** Read all incident edges without modifying historical relationships. */
|
|
488
|
+
function stagedEdgesHash(db, id) {
|
|
489
|
+
return stagedGraphHash(db
|
|
490
|
+
.prepare('SELECT * FROM main.brain_page_edges WHERE from_id = ? OR to_id = ? ORDER BY from_id, to_id, edge_type')
|
|
491
|
+
.all(id, id));
|
|
492
|
+
}
|
|
493
|
+
/** Reject legacy and cross-project snapshots rather than guessing which rows may be removed. */
|
|
494
|
+
function readStagedSnapshot(raw, projectRoot) {
|
|
495
|
+
if (raw.target_table !== 'brain_page_nodes')
|
|
496
|
+
throw new Error('Staged backfill supports derived brain_page_nodes only.');
|
|
497
|
+
const parsed = stagedSnapshotSchema.safeParse(JSON.parse(raw.rollback_snapshot_json ?? 'null'));
|
|
498
|
+
if (!parsed.success)
|
|
499
|
+
throw new Error('Backfill snapshot lacks exact source and recovery preconditions; discard this staged run and stage a new run. Legacy approved runs require their canonical backup.');
|
|
500
|
+
if (parsed.data.projectRoot !== realpathSync(projectRoot))
|
|
501
|
+
throw new Error('Backfill project binding changed.');
|
|
502
|
+
return parsed.data;
|
|
503
|
+
}
|
|
504
|
+
/** Read a validated ledger row while the caller holds the writer transaction. */
|
|
505
|
+
function readStagedRun(db, runId) {
|
|
506
|
+
const row = db.prepare('SELECT * FROM main.brain_backfill_runs WHERE id = ?').get(runId);
|
|
507
|
+
if (!row)
|
|
508
|
+
throw new Error(`Backfill run '${runId}' not found`);
|
|
509
|
+
return stagedRunSchema.parse(row);
|
|
510
|
+
}
|
|
406
511
|
/**
|
|
407
512
|
* Stage a graph backfill run against brain_page_nodes / brain_page_edges.
|
|
408
513
|
*
|
|
409
514
|
* Discovers all candidate node IDs from typed tables (decisions, patterns,
|
|
410
515
|
* learnings, observations, sticky notes) that are NOT yet in brain_page_nodes.
|
|
411
|
-
*
|
|
412
|
-
*
|
|
516
|
+
* Captures exact nodes, source hashes, incident-edge fingerprints and project binding in
|
|
517
|
+
* `rollback_snapshot_json`, and creates a `brain_backfill_runs`
|
|
518
|
+
* row with status='staged'. The ledger is written, but derived graph rows are unchanged.
|
|
413
519
|
*
|
|
414
520
|
* Pass `source` as a human-readable descriptor (e.g. a file path or session ID).
|
|
415
521
|
* Pass `kind` as the backfill kind (e.g. 'graph-backfill', 'observation-promotion').
|
|
@@ -419,61 +525,108 @@ function generateRunId() {
|
|
|
419
525
|
* @returns StagedBackfillRunResult with the staged run record.
|
|
420
526
|
*
|
|
421
527
|
* @task T1003
|
|
528
|
+
* @remarks The snapshot captures exact source and relationship preconditions without mutating derived nodes.
|
|
529
|
+
* @example
|
|
530
|
+
* ```ts
|
|
531
|
+
* const staged = await stagedBackfillRun(projectRoot, undefined);
|
|
532
|
+
* ```
|
|
422
533
|
*/
|
|
423
534
|
export async function stagedBackfillRun(projectRoot, opts) {
|
|
424
|
-
|
|
425
|
-
const
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
const
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
535
|
+
await getBrainDb(projectRoot);
|
|
536
|
+
const db = getBrainNativeDb(projectRoot);
|
|
537
|
+
if (!db)
|
|
538
|
+
throw new Error('brain.db native handle unavailable');
|
|
539
|
+
if (opts?.targetTable && opts.targetTable !== 'brain_page_nodes')
|
|
540
|
+
throw new Error('Staged backfill supports derived brain_page_nodes only.');
|
|
541
|
+
const selected = opts?.nodeIds === undefined
|
|
542
|
+
? undefined
|
|
543
|
+
: z.array(z.string().min(1)).min(1).max(500).parse(opts.nodeIds);
|
|
544
|
+
if (selected && new Set(selected).size !== selected.length)
|
|
545
|
+
throw new Error('Backfill nodeIds must not contain duplicates.');
|
|
546
|
+
db.exec('BEGIN IMMEDIATE');
|
|
547
|
+
try {
|
|
548
|
+
const now = new Date().toISOString();
|
|
549
|
+
const snapshot = {
|
|
550
|
+
version: 2,
|
|
551
|
+
projectRoot: realpathSync(projectRoot),
|
|
552
|
+
candidates: [],
|
|
553
|
+
created: [],
|
|
554
|
+
};
|
|
555
|
+
for (const sourceTable of stagedSourceTableSchema.options) {
|
|
556
|
+
const kind = sourceKinds[sourceTable];
|
|
557
|
+
const selection = selected
|
|
558
|
+
? ` AND (? || ':' || source.id) IN (${selected.map(() => '?').join(',')})`
|
|
559
|
+
: '';
|
|
560
|
+
const rows = db
|
|
561
|
+
.prepare(`SELECT source.* FROM main.${sourceTable} source
|
|
562
|
+
LEFT JOIN main.brain_page_nodes node ON node.id = ? || ':' || source.id
|
|
563
|
+
WHERE node.id IS NULL${selection} ORDER BY source.id LIMIT 501`)
|
|
564
|
+
.all(kind, ...(selected ? [kind, ...selected] : []));
|
|
565
|
+
for (const value of rows) {
|
|
566
|
+
const source = typedSourceSchema.parse(value);
|
|
567
|
+
if (typeof source.id !== 'string')
|
|
568
|
+
throw new Error('Backfill source identifier is invalid');
|
|
569
|
+
const id = `${kind}:${source.id}`;
|
|
570
|
+
if (selected &&
|
|
571
|
+
(source.invalid_at != null ||
|
|
572
|
+
(kind === 'decision' &&
|
|
573
|
+
(source.superseded_by != null || source.confirmation_state === 'superseded'))))
|
|
574
|
+
throw new Error(`Selected backfill source ${id} is not currently eligible.`);
|
|
575
|
+
const sourceHash = stagedSourceHash(source);
|
|
576
|
+
const label = source.decision ?? source.pattern ?? source.insight ?? source.title ?? source.content;
|
|
577
|
+
if (typeof label !== 'string' || !label.trim())
|
|
578
|
+
throw new Error(`Backfill source ${id} has no substantive label; resolve it before staging.`);
|
|
579
|
+
snapshot.candidates.push({
|
|
580
|
+
id,
|
|
581
|
+
sourceId: source.id,
|
|
582
|
+
sourceTable,
|
|
583
|
+
sourceHash,
|
|
584
|
+
edgeHash: stagedEdgesHash(db, id),
|
|
585
|
+
node: {
|
|
586
|
+
id,
|
|
587
|
+
node_type: kind,
|
|
588
|
+
label: label.slice(0, 200),
|
|
589
|
+
quality_score: typeof source.quality_score === 'number' ? source.quality_score : 0.5,
|
|
590
|
+
content_hash: sourceHash,
|
|
591
|
+
metadata_json: JSON.stringify({
|
|
592
|
+
sourceTable,
|
|
593
|
+
sourceId: source.id,
|
|
594
|
+
sourceHash,
|
|
595
|
+
derived: true,
|
|
596
|
+
}),
|
|
597
|
+
created_at: now,
|
|
598
|
+
last_activity_at: now,
|
|
599
|
+
updated_at: null,
|
|
600
|
+
},
|
|
601
|
+
});
|
|
602
|
+
if (snapshot.candidates.length > 500)
|
|
603
|
+
throw new Error('More than 500 missing nodes require a bounded source selection before staging.');
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
if (selected && snapshot.candidates.length !== selected.length) {
|
|
607
|
+
const found = new Set(snapshot.candidates.map((candidate) => candidate.id));
|
|
608
|
+
throw new Error(`Selected backfill IDs are missing, already indexed, or unsupported: ${selected.filter((id) => !found.has(id)).join(', ')}`);
|
|
609
|
+
}
|
|
610
|
+
const id = generateRunId();
|
|
611
|
+
db.prepare(`INSERT INTO main.brain_backfill_runs
|
|
612
|
+
(id, kind, status, created_at, rows_affected, rollback_snapshot_json, source, target_table)
|
|
613
|
+
VALUES (?, ?, 'staged', ?, ?, ?, ?, 'brain_page_nodes')`).run(id, opts?.kind ?? 'graph-backfill', now, snapshot.candidates.length, JSON.stringify(snapshot), opts?.source ?? 'staged-run');
|
|
614
|
+
const run = mapRunRow(readStagedRun(db, id));
|
|
615
|
+
db.exec('COMMIT');
|
|
616
|
+
return { run, empty: snapshot.candidates.length === 0 };
|
|
617
|
+
}
|
|
618
|
+
catch (error) {
|
|
619
|
+
db.exec('ROLLBACK');
|
|
620
|
+
throw error;
|
|
621
|
+
}
|
|
470
622
|
}
|
|
471
623
|
/**
|
|
472
624
|
* Approve a staged backfill run, committing its rows to live brain tables.
|
|
473
625
|
*
|
|
474
|
-
* Reads the run
|
|
475
|
-
*
|
|
476
|
-
*
|
|
626
|
+
* Reads the staged run under a writer transaction, validates its exact source
|
|
627
|
+
* and graph preconditions, then inserts only its reviewed derived nodes. The
|
|
628
|
+
* same transaction records created-row hashes and approval metadata for recovery.
|
|
629
|
+
* Historical edges remain unchanged.
|
|
477
630
|
*
|
|
478
631
|
* Double-approve is idempotent: returns `{ alreadySettled: true }` if the run
|
|
479
632
|
* is already approved or rolled-back.
|
|
@@ -484,43 +637,91 @@ export async function stagedBackfillRun(projectRoot, opts) {
|
|
|
484
637
|
* @returns Result with the updated run record and graph backfill stats.
|
|
485
638
|
*
|
|
486
639
|
* @task T1003
|
|
640
|
+
* @remarks Approval inserts only the reviewed nodes and records recovery hashes atomically; stale source or graph state is rejected.
|
|
641
|
+
* @example
|
|
642
|
+
* ```ts
|
|
643
|
+
* const applied = await approveBackfillRun(projectRoot, runId, 'calling-agent');
|
|
644
|
+
* ```
|
|
487
645
|
*/
|
|
488
646
|
export async function approveBackfillRun(projectRoot, runId, approvedBy) {
|
|
489
647
|
await getBrainDb(projectRoot);
|
|
490
|
-
const
|
|
491
|
-
if (!
|
|
648
|
+
const db = getBrainNativeDb(projectRoot);
|
|
649
|
+
if (!db)
|
|
492
650
|
throw new Error('brain.db native handle unavailable');
|
|
651
|
+
db.exec('BEGIN IMMEDIATE');
|
|
652
|
+
try {
|
|
653
|
+
const raw = readStagedRun(db, runId);
|
|
654
|
+
if (raw.status === 'approved' || raw.status === 'rolled-back') {
|
|
655
|
+
db.exec('COMMIT');
|
|
656
|
+
return { run: mapRunRow(raw), alreadySettled: true };
|
|
657
|
+
}
|
|
658
|
+
if (raw.status !== 'staged')
|
|
659
|
+
throw new Error('Backfill run is not staged.');
|
|
660
|
+
const snapshot = readStagedSnapshot(raw, projectRoot);
|
|
661
|
+
if (snapshot.created.length)
|
|
662
|
+
throw new Error('Staged backfill unexpectedly contains committed nodes.');
|
|
663
|
+
const beforeNodes = Number(db.prepare('SELECT COUNT(*) AS count FROM main.brain_page_nodes').get()?.count);
|
|
664
|
+
const beforeEdges = Number(db.prepare('SELECT COUNT(*) AS count FROM main.brain_page_edges').get()?.count);
|
|
665
|
+
const typedCounts = Object.fromEntries(stagedSourceTableSchema.options.map((table) => [
|
|
666
|
+
table,
|
|
667
|
+
Number(db.prepare(`SELECT COUNT(*) AS count FROM main.${table}`).get()?.count),
|
|
668
|
+
]));
|
|
669
|
+
for (const candidate of snapshot.candidates) {
|
|
670
|
+
const current = typedSourceSchema.parse(db
|
|
671
|
+
.prepare(`SELECT * FROM main.${candidate.sourceTable} WHERE id = ?`)
|
|
672
|
+
.get(candidate.sourceId));
|
|
673
|
+
if (candidate.id !== `${sourceKinds[candidate.sourceTable]}:${candidate.sourceId}` ||
|
|
674
|
+
candidate.node.id !== candidate.id ||
|
|
675
|
+
stagedSourceHash(current) !== candidate.sourceHash ||
|
|
676
|
+
db.prepare('SELECT id FROM main.brain_page_nodes WHERE id = ?').get(candidate.id) ||
|
|
677
|
+
stagedEdgesHash(db, candidate.id) !== candidate.edgeHash)
|
|
678
|
+
throw new Error(`Backfill proposal is stale for ${candidate.id}; stage a new run.`);
|
|
679
|
+
}
|
|
680
|
+
const insert = db.prepare(`INSERT INTO main.brain_page_nodes
|
|
681
|
+
(id, node_type, label, quality_score, content_hash, metadata_json, created_at, last_activity_at, updated_at)
|
|
682
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
683
|
+
const byType = {};
|
|
684
|
+
for (const candidate of snapshot.candidates) {
|
|
685
|
+
const node = candidate.node;
|
|
686
|
+
insert.run(node.id, node.node_type, node.label, node.quality_score, node.content_hash, node.metadata_json, node.created_at, node.last_activity_at, node.updated_at);
|
|
687
|
+
const created = db.prepare('SELECT * FROM main.brain_page_nodes WHERE id = ?').get(node.id);
|
|
688
|
+
if (!created)
|
|
689
|
+
throw new Error('Created backfill node is unreadable');
|
|
690
|
+
snapshot.created.push({
|
|
691
|
+
id: node.id,
|
|
692
|
+
rowHash: stagedGraphHash(created),
|
|
693
|
+
edgeHash: stagedEdgesHash(db, node.id),
|
|
694
|
+
});
|
|
695
|
+
byType[node.node_type] = (byType[node.node_type] ?? 0) + 1;
|
|
696
|
+
}
|
|
697
|
+
db.prepare(`UPDATE main.brain_backfill_runs SET status = 'approved', approved_at = ?, approved_by = ?, rollback_snapshot_json = ? WHERE id = ?`).run(new Date().toISOString(), approvedBy ?? 'owner', JSON.stringify(snapshot), runId);
|
|
698
|
+
const run = mapRunRow(readStagedRun(db, runId));
|
|
699
|
+
db.exec('COMMIT');
|
|
700
|
+
return {
|
|
701
|
+
run,
|
|
702
|
+
alreadySettled: false,
|
|
703
|
+
backfillResult: {
|
|
704
|
+
before: {
|
|
705
|
+
nodes: beforeNodes,
|
|
706
|
+
edges: beforeEdges,
|
|
707
|
+
decisions: typedCounts['brain_decisions'] ?? 0,
|
|
708
|
+
patterns: typedCounts['brain_patterns'] ?? 0,
|
|
709
|
+
learnings: typedCounts['brain_learnings'] ?? 0,
|
|
710
|
+
observations: typedCounts['brain_observations'] ?? 0,
|
|
711
|
+
stickyNotes: typedCounts['brain_sticky_notes'] ?? 0,
|
|
712
|
+
},
|
|
713
|
+
after: { nodes: beforeNodes + snapshot.created.length, edges: beforeEdges },
|
|
714
|
+
nodesInserted: snapshot.created.length,
|
|
715
|
+
edgesInserted: 0,
|
|
716
|
+
stubsCreated: 0,
|
|
717
|
+
byType,
|
|
718
|
+
},
|
|
719
|
+
};
|
|
493
720
|
}
|
|
494
|
-
|
|
495
|
-
.
|
|
496
|
-
|
|
497
|
-
if (!rawRun) {
|
|
498
|
-
throw new Error(`Backfill run '${runId}' not found`);
|
|
499
|
-
}
|
|
500
|
-
// If already settled, return as-is
|
|
501
|
-
if (rawRun.status === 'approved' || rawRun.status === 'rolled-back') {
|
|
502
|
-
const run = mapRunRow(rawRun);
|
|
503
|
-
return { run, alreadySettled: true };
|
|
721
|
+
catch (error) {
|
|
722
|
+
db.exec('ROLLBACK');
|
|
723
|
+
throw error;
|
|
504
724
|
}
|
|
505
|
-
// Execute the actual backfill
|
|
506
|
-
const backfillResult = await backfillBrainGraph(projectRoot);
|
|
507
|
-
// Mark run as approved
|
|
508
|
-
const now = new Date().toISOString().replace('T', ' ').slice(0, 19);
|
|
509
|
-
const approver = approvedBy ?? 'owner';
|
|
510
|
-
nativeDb
|
|
511
|
-
.prepare(`UPDATE brain_backfill_runs
|
|
512
|
-
SET status = 'approved', approved_at = ?, approved_by = ?
|
|
513
|
-
WHERE id = ?`)
|
|
514
|
-
.run(now, approver, runId);
|
|
515
|
-
// Re-fetch updated run
|
|
516
|
-
const updatedRaw = nativeDb
|
|
517
|
-
.prepare('SELECT * FROM brain_backfill_runs WHERE id = ? LIMIT 1')
|
|
518
|
-
.get(runId);
|
|
519
|
-
return {
|
|
520
|
-
run: mapRunRow(updatedRaw),
|
|
521
|
-
alreadySettled: false,
|
|
522
|
-
backfillResult,
|
|
523
|
-
};
|
|
524
725
|
}
|
|
525
726
|
/**
|
|
526
727
|
* Rollback a staged backfill run, discarding staged rows.
|
|
@@ -539,64 +740,54 @@ export async function approveBackfillRun(projectRoot, runId, approvedBy) {
|
|
|
539
740
|
* @returns Result with the updated run record and optional delete count.
|
|
540
741
|
*
|
|
541
742
|
* @task T1003
|
|
743
|
+
* @remarks Recovery removes only unchanged nodes created by this run and refuses concurrent node or edge edits.
|
|
744
|
+
* @example
|
|
745
|
+
* ```ts
|
|
746
|
+
* const restored = await rollbackBackfillRun(projectRoot, runId);
|
|
747
|
+
* ```
|
|
542
748
|
*/
|
|
543
749
|
export async function rollbackBackfillRun(projectRoot, runId) {
|
|
544
750
|
await getBrainDb(projectRoot);
|
|
545
|
-
const
|
|
546
|
-
if (!
|
|
751
|
+
const db = getBrainNativeDb(projectRoot);
|
|
752
|
+
if (!db)
|
|
547
753
|
throw new Error('brain.db native handle unavailable');
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
.
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
}
|
|
555
|
-
// Already rolled back — idempotent no-op
|
|
556
|
-
if (rawRun.status === 'rolled-back') {
|
|
557
|
-
return { run: mapRunRow(rawRun), alreadySettled: true, deletedRows: 0 };
|
|
558
|
-
}
|
|
559
|
-
let deletedRows = 0;
|
|
560
|
-
// If already approved, we need to DELETE committed rows from the target table
|
|
561
|
-
if (rawRun.status === 'approved' && rawRun.rollback_snapshot_json) {
|
|
562
|
-
let ids = [];
|
|
563
|
-
try {
|
|
564
|
-
ids = JSON.parse(rawRun.rollback_snapshot_json);
|
|
565
|
-
}
|
|
566
|
-
catch {
|
|
567
|
-
// Malformed snapshot — proceed without deleting
|
|
754
|
+
db.exec('BEGIN IMMEDIATE');
|
|
755
|
+
try {
|
|
756
|
+
const raw = readStagedRun(db, runId);
|
|
757
|
+
if (raw.status === 'rolled-back') {
|
|
758
|
+
db.exec('COMMIT');
|
|
759
|
+
return { run: mapRunRow(raw), alreadySettled: true, deletedRows: 0 };
|
|
568
760
|
}
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
'
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
const result = nativeDb
|
|
587
|
-
.prepare(`DELETE FROM ${targetTable} WHERE id IN (${placeholders})`)
|
|
588
|
-
.run(...chunk);
|
|
589
|
-
deletedRows += result.changes ?? 0;
|
|
590
|
-
}
|
|
761
|
+
let deletedRows = 0;
|
|
762
|
+
if (raw.status === 'approved') {
|
|
763
|
+
const snapshot = readStagedSnapshot(raw, projectRoot);
|
|
764
|
+
if (snapshot.created.length !== snapshot.candidates.length)
|
|
765
|
+
throw new Error('Backfill receipt does not cover every created node.');
|
|
766
|
+
for (const created of snapshot.created) {
|
|
767
|
+
const current = db
|
|
768
|
+
.prepare('SELECT * FROM main.brain_page_nodes WHERE id = ?')
|
|
769
|
+
.get(created.id);
|
|
770
|
+
if (!current ||
|
|
771
|
+
stagedGraphHash(current) !== created.rowHash ||
|
|
772
|
+
stagedEdgesHash(db, created.id) !== created.edgeHash)
|
|
773
|
+
throw new Error(`Backfill rollback is stale for ${created.id}; preserve concurrent changes and inspect the canonical backup.`);
|
|
774
|
+
}
|
|
775
|
+
for (const created of snapshot.created) {
|
|
776
|
+
const result = db.prepare('DELETE FROM main.brain_page_nodes WHERE id = ?').run(created.id);
|
|
777
|
+
deletedRows += Number(result.changes);
|
|
591
778
|
}
|
|
592
779
|
}
|
|
780
|
+
else if (raw.status !== 'staged')
|
|
781
|
+
throw new Error('Backfill run cannot be rolled back from its current state.');
|
|
782
|
+
db.prepare("UPDATE main.brain_backfill_runs SET status = 'rolled-back' WHERE id = ?").run(runId);
|
|
783
|
+
const run = mapRunRow(readStagedRun(db, runId));
|
|
784
|
+
db.exec('COMMIT');
|
|
785
|
+
return { run, alreadySettled: false, deletedRows };
|
|
786
|
+
}
|
|
787
|
+
catch (error) {
|
|
788
|
+
db.exec('ROLLBACK');
|
|
789
|
+
throw error;
|
|
593
790
|
}
|
|
594
|
-
// Mark run as rolled-back
|
|
595
|
-
nativeDb.prepare(`UPDATE brain_backfill_runs SET status = 'rolled-back' WHERE id = ?`).run(runId);
|
|
596
|
-
const updatedRaw = nativeDb
|
|
597
|
-
.prepare('SELECT * FROM brain_backfill_runs WHERE id = ? LIMIT 1')
|
|
598
|
-
.get(runId);
|
|
599
|
-
return { run: mapRunRow(updatedRaw), alreadySettled: false, deletedRows };
|
|
600
791
|
}
|
|
601
792
|
/**
|
|
602
793
|
* List backfill runs, optionally filtered by status.
|