@cleocode/core 2026.9.7 → 2026.9.9
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/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 +5100 -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 +64 -0
- package/dist/git/work-tree.d.ts.map +1 -0
- package/dist/git/work-tree.js +111 -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 +2 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +2 -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 +4018 -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 +31 -1
- package/dist/memory/brain-writer-thread.d.ts.map +1 -1
- package/dist/memory/brain-writer-thread.js +166 -24
- 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 +16 -41
- 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 +16 -3
- package/dist/release/pr-evidence.d.ts.map +1 -1
- package/dist/release/pr-evidence.js +53 -7
- 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 +4026 -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 +6 -2
- 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 +91 -35
- 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 +54 -26
- package/dist/tasks/evidence.d.ts.map +1 -1
- package/dist/tasks/evidence.js +292 -40
- 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-runner.d.ts +88 -14
- package/dist/tasks/gate-runner.d.ts.map +1 -1
- package/dist/tasks/gate-runner.js +596 -253
- 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/teardown-signal.d.ts +72 -0
- package/dist/teardown-signal.d.ts.map +1 -0
- package/dist/teardown-signal.js +108 -0
- package/dist/teardown-signal.js.map +1 -0
- 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/templates/CLEO-INJECTION.md +103 -101
package/dist/tasks/add.js
CHANGED
|
@@ -13,17 +13,62 @@ import { resolveOrCwd } from '../paths.js';
|
|
|
13
13
|
import { allocateNextTaskId } from '../sequence/index.js';
|
|
14
14
|
import { requireActiveSession } from '../sessions/session-enforcement.js';
|
|
15
15
|
import { trackBackgroundOp } from '../store/background-ops.js';
|
|
16
|
-
import {
|
|
16
|
+
import { applyAcPlan, buildAcRowId, buildChildProjectionAcText, buildFreshAcRows, childProjectionFreshnessFingerprint, childProjectionSourceKey, } from './ac-table.js';
|
|
17
|
+
import { normalizeAcceptance } from './acceptance-input.js';
|
|
17
18
|
import { createAcceptanceEnforcement } from './enforcement.js';
|
|
18
19
|
import { findEpicAncestor, validateChildStageCeiling, validateEpicCreation, } from './epic-enforcement.js';
|
|
19
|
-
import {
|
|
20
|
+
import { childTypeForParentType } from './hierarchy.js';
|
|
21
|
+
import { exceedsMaxDepth, resolveHierarchyPolicy } from './hierarchy-policy.js';
|
|
20
22
|
import { resolveDefaultPipelineStage, validatePipelineStage } from './pipeline-stage.js';
|
|
21
|
-
|
|
22
|
-
export
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
import { prepareSignedSeverityAttestation } from './severity-attestation.js';
|
|
24
|
+
export { normalizeAcceptance } from './acceptance-input.js';
|
|
25
|
+
/**
|
|
26
|
+
* Translate canonical creation input into core options without dropping fields.
|
|
27
|
+
* @param params - Canonical task creation input.
|
|
28
|
+
* @returns Core options with the parent alias and enum boundaries resolved.
|
|
29
|
+
* @remarks Entry points share this boundary; CLI parsing does not establish authorization.
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* toTaskAddOptions({ title: 'Fix persistence', description: 'Verify durable task writes' });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export function toTaskAddOptions(params) {
|
|
36
|
+
const { parent, ...fields } = params;
|
|
37
|
+
return {
|
|
38
|
+
...fields,
|
|
39
|
+
parentId: parent,
|
|
40
|
+
priority: params.priority,
|
|
41
|
+
size: params.size,
|
|
42
|
+
kind: params.kind,
|
|
43
|
+
scope: params.scope,
|
|
44
|
+
severity: params.severity,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Enforce the established explicit-critical dependency policy before mutation.
|
|
49
|
+
* @param priority - Explicit requested priority; waivers require critical.
|
|
50
|
+
* @param justification - Original reason, retained verbatim in transaction audit details.
|
|
51
|
+
* @param dependencies - Effective dependencies after applying the requested changes.
|
|
52
|
+
* @throws CleoError for invalid waivers or critical mutations without dependencies.
|
|
53
|
+
* @remarks Entry points share this boundary; CLI parsing does not establish authorization.
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* validateDependencyWaiver('critical', 'Independent restoration', []);
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export function validateDependencyWaiver(priority, justification, dependencies) {
|
|
60
|
+
if (justification !== undefined &&
|
|
61
|
+
(typeof justification !== 'string' ||
|
|
62
|
+
justification.trim().length === 0 ||
|
|
63
|
+
priority !== 'critical')) {
|
|
64
|
+
throw new CleoError(ExitCode.VALIDATION_ERROR, 'Dependency waiver requires a non-empty justification and an explicit critical-priority mutation', {
|
|
65
|
+
details: { field: 'dependsWaiver' },
|
|
66
|
+
fix: 'Supply a non-empty --depends-waiver with --priority critical, or omit the waiver',
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
if (priority === 'critical' && dependencies.length === 0 && justification === undefined) {
|
|
70
|
+
throw new CleoError(ExitCode.VALIDATION_ERROR, 'Critical tasks must declare at least one dependency or supply a dependency waiver', { details: { field: 'depends' }, fix: 'Supply --depends or a non-empty --depends-waiver' });
|
|
71
|
+
}
|
|
27
72
|
}
|
|
28
73
|
/**
|
|
29
74
|
* Build the default verification metadata applied to every new task.
|
|
@@ -322,12 +367,14 @@ export function validateParent(parentId, tasks, maxDepth = 3, maxSiblings = 0) {
|
|
|
322
367
|
if (parent.type === 'subtask') {
|
|
323
368
|
throw new CleoError(ExitCode.INVALID_PARENT_TYPE, `Cannot add child to ${parentId}: subtasks cannot have children`, { fix: `Create as standalone task or add to parent's parent instead` });
|
|
324
369
|
}
|
|
325
|
-
// Check depth
|
|
370
|
+
// Check depth. Behaviourally identical to the previous `depth >= maxDepth`
|
|
371
|
+
// (this helper was always one of the two correct implementations); routed
|
|
372
|
+
// through the shared rule so there is exactly one copy of the comparison.
|
|
326
373
|
const depth = getTaskDepth(parentId, tasks);
|
|
327
|
-
if (depth
|
|
374
|
+
if (exceedsMaxDepth(depth, maxDepth)) {
|
|
328
375
|
throw new CleoError(ExitCode.DEPTH_EXCEEDED, `Cannot add child to ${parentId}: max hierarchy depth (${maxDepth}) would be exceeded`, {
|
|
329
376
|
fix: 'Reparent this task under a higher-level epic',
|
|
330
|
-
details: { field: 'parentId', expected: `depth
|
|
377
|
+
details: { field: 'parentId', expected: `depth <= ${maxDepth}`, actual: depth + 1 },
|
|
331
378
|
});
|
|
332
379
|
}
|
|
333
380
|
// Check sibling count
|
|
@@ -404,6 +451,23 @@ export function getTaskDepth(taskId, tasks) {
|
|
|
404
451
|
* console.assert(inferTaskType('T002', tasks) === 'subtask', 'task parent → subtask');
|
|
405
452
|
* ```
|
|
406
453
|
*/
|
|
454
|
+
/**
|
|
455
|
+
* Human-readable list of the tiers that may legally contain `childType`, per the
|
|
456
|
+
* PM-Core V2 containment matrix.
|
|
457
|
+
*
|
|
458
|
+
* Used to explain a refusal in the caller's own vocabulary ("a subtask can only
|
|
459
|
+
* be filed under a task") rather than quoting a numeric depth the caller never
|
|
460
|
+
* configured.
|
|
461
|
+
*
|
|
462
|
+
* @param childType - The tier the caller asked to create.
|
|
463
|
+
* @returns Comma-joined parent tier names, or `'nothing (it is a root tier)'`.
|
|
464
|
+
*/
|
|
465
|
+
function describeLegalParents(childType) {
|
|
466
|
+
const allowed = ['saga', 'epic', 'task', 'subtask']
|
|
467
|
+
.filter((parent) => isAllowedWorkGraphParentType(childType, parent))
|
|
468
|
+
.map((parent) => `${/^[aeiou]/.test(parent) ? 'an' : 'a'} ${parent}`);
|
|
469
|
+
return allowed.length === 0 ? 'nothing (it is a root tier)' : allowed.join(' or ');
|
|
470
|
+
}
|
|
407
471
|
export function inferTaskType(parentId, tasks) {
|
|
408
472
|
if (!parentId)
|
|
409
473
|
return 'task';
|
|
@@ -526,8 +590,12 @@ async function hasNoTasks(cwd, accessor) {
|
|
|
526
590
|
* @task T4460
|
|
527
591
|
*/
|
|
528
592
|
export async function addTask(options, cwd, accessor) {
|
|
593
|
+
const normalizedAcceptance = normalizeAcceptance(options.acceptance);
|
|
529
594
|
// Validate title (early-exit — can't proceed without a title)
|
|
530
595
|
validateTitle(options.title);
|
|
596
|
+
validateDependencyWaiver(options.priority, options.dependsWaiver, options.depends ?? []);
|
|
597
|
+
/** Set when `autoDecompose` converted a text-AC leaf parent into a container. */
|
|
598
|
+
let autoDecomposed;
|
|
531
599
|
// Skip session enforcement for dry-run — no data is written
|
|
532
600
|
if (!options.dryRun) {
|
|
533
601
|
await requireActiveSession('tasks.add', cwd);
|
|
@@ -537,7 +605,6 @@ export async function addTask(options, cwd, accessor) {
|
|
|
537
605
|
// preventing the common failure mode where agents drop flags like --parent.
|
|
538
606
|
const issues = [];
|
|
539
607
|
const warnings = [];
|
|
540
|
-
const normalizedAcceptance = normalizeAcceptance(options.acceptance);
|
|
541
608
|
// Anti-hallucination: title and description must be different (T5698)
|
|
542
609
|
if (options.description &&
|
|
543
610
|
options.title.trim().toLowerCase() === options.description.trim().toLowerCase()) {
|
|
@@ -765,12 +832,17 @@ export async function addTask(options, cwd, accessor) {
|
|
|
765
832
|
// Depth check using ancestor chain
|
|
766
833
|
const ancestors = await dataAccessor.getAncestorChain(parentId);
|
|
767
834
|
const parentDepth = ancestors.length;
|
|
768
|
-
if (parentDepth
|
|
835
|
+
if (exceedsMaxDepth(parentDepth, policy.maxDepth)) {
|
|
769
836
|
// T11491 — DHQ-044: produce a clear actionable message that names the
|
|
770
|
-
//
|
|
771
|
-
//
|
|
772
|
-
//
|
|
773
|
-
//
|
|
837
|
+
// container the caller SHOULD target instead.
|
|
838
|
+
//
|
|
839
|
+
// The ancestor chain is ordered [root, …, immediateParent]:
|
|
840
|
+
// `sqlite-data-accessor.ts` builds it with `ORDER BY depth DESC` and
|
|
841
|
+
// re-sorts "ancestors from root down", so the LAST element is the
|
|
842
|
+
// prospective parent's own parent — the grandparent of the node being
|
|
843
|
+
// added. (A prior comment here claimed the reverse order and pointed at
|
|
844
|
+
// ancestors[0]; the code was always right, the comment was not. Stated
|
|
845
|
+
// explicitly so nobody "fixes" the index to match the prose.)
|
|
774
846
|
//
|
|
775
847
|
// T11293: NEVER suggest "omit --parent to create a standalone task."
|
|
776
848
|
// Under strict-spine containment (T11811) only sagas may be root-level,
|
|
@@ -778,13 +850,28 @@ export async function addTask(options, cwd, accessor) {
|
|
|
778
850
|
// (so the user never supplied --parent in the first place). Point to a
|
|
779
851
|
// concrete higher-level container, or to --parent none to escape
|
|
780
852
|
// auto-inference (the task will still need a valid parent).
|
|
781
|
-
const
|
|
853
|
+
const grandparent = ancestors.length > 0 ? ancestors[ancestors.length - 1] : undefined;
|
|
854
|
+
// The tier the caller actually asked for. `taskType` is still the raw
|
|
855
|
+
// `--type` here (inference runs further down), so an unset type means
|
|
856
|
+
// "whatever this parent implies" — the same derivation the containment
|
|
857
|
+
// check below applies.
|
|
858
|
+
const requestedChildType = taskType ?? childTypeForParentType(parentTask.type ?? 'task');
|
|
859
|
+
// A suggestion that cannot be executed is worse than no suggestion. The
|
|
860
|
+
// previous version always offered `--parent <grandparent>` on the grounds
|
|
861
|
+
// that it is shallower, and said nothing about TYPE. But the caller's
|
|
862
|
+
// `--type` travels with the retry, and the containment matrix only admits
|
|
863
|
+
// saga→epic, epic→task, task→subtask — so `--type subtask --parent <epic>`
|
|
864
|
+
// clears this depth check and is then refused by the matrix below. Two
|
|
865
|
+
// field reports (GH: a user on 2026.9.5, and an agent that burned three
|
|
866
|
+
// `cleo add` calls) followed that hint from exit 11 straight into exit 6.
|
|
867
|
+
// Only offer the grandparent when it can legally hold what was asked for.
|
|
868
|
+
const grandparentAccepts = grandparent !== undefined &&
|
|
869
|
+
isAllowedWorkGraphParentType(requestedChildType, grandparent.type ?? 'task');
|
|
782
870
|
// T12136 (GH #1232/#1238) — when the parent was INHERITED rather than
|
|
783
871
|
// named, say so FIRST. Otherwise the message reads as though the caller
|
|
784
|
-
// asked to file under `parentId`, and the
|
|
785
|
-
//
|
|
786
|
-
//
|
|
787
|
-
// suggestion from misleading to optional.
|
|
872
|
+
// asked to file under `parentId`, and the only actionable-looking line
|
|
873
|
+
// points into a hierarchy the caller never intended to touch. Naming the
|
|
874
|
+
// inference converts the suggestion from misleading to optional.
|
|
788
875
|
const wasInherited = options.parentSource === 'session-inference';
|
|
789
876
|
const provenance = wasInherited
|
|
790
877
|
? `You did not pass --parent: ${parentId} was inherited from the active session ` +
|
|
@@ -793,20 +880,28 @@ export async function addTask(options, cwd, accessor) {
|
|
|
793
880
|
const escapeHint = wasInherited
|
|
794
881
|
? ' Or pass --parent <id> explicitly to override the session pointer, or --parent none to suppress inference.'
|
|
795
882
|
: '';
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
`
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
883
|
+
// T11293: NEVER suggest "omit --parent to create a standalone task" —
|
|
884
|
+
// under strict-spine containment only a saga may be a root.
|
|
885
|
+
const suggestion = grandparentAccepts
|
|
886
|
+
? ` File it under --parent ${grandparent?.id} as --type ${requestedChildType} instead.`
|
|
887
|
+
: ` A ${requestedChildType} can only be filed under ${describeLegalParents(requestedChildType)}, ` +
|
|
888
|
+
`and every one of those is already at or past the cap here. Re-scope the work so it ` +
|
|
889
|
+
`belongs to an existing container, or raise hierarchy.maxDepth in .cleo/config.json.`;
|
|
890
|
+
throw new CleoError(ExitCode.DEPTH_EXCEEDED, `${provenance}Cannot add a ${requestedChildType} under ${parentId}: it is a ` +
|
|
891
|
+
`${parentTask.type ?? 'task'} at depth ${parentDepth}, and a child would sit at depth ` +
|
|
892
|
+
`${parentDepth + 1}, past the hierarchy cap of ${policy.maxDepth} ` +
|
|
893
|
+
`(saga 0, epic 1, task 2, subtask 3).${suggestion}${escapeHint}`, {
|
|
894
|
+
fix: grandparentAccepts
|
|
895
|
+
? `cleo add --type ${requestedChildType} --parent ${grandparent?.id} --title "..." --acceptance "..."`
|
|
896
|
+
: `Re-scope under an existing container, or raise hierarchy.maxDepth above ${policy.maxDepth}`,
|
|
804
897
|
details: {
|
|
805
898
|
field: 'parentId',
|
|
806
|
-
expected: `depth
|
|
899
|
+
expected: `depth <= ${policy.maxDepth}`,
|
|
807
900
|
actual: parentDepth + 1,
|
|
808
|
-
|
|
809
|
-
|
|
901
|
+
requestedChildType,
|
|
902
|
+
// Only ever names a parent that can legally hold `requestedChildType`.
|
|
903
|
+
suggestedParentId: grandparentAccepts ? grandparent?.id : undefined,
|
|
904
|
+
suggestedParentTitle: grandparentAccepts ? grandparent?.title : undefined,
|
|
810
905
|
parentSource: options.parentSource ?? 'explicit',
|
|
811
906
|
},
|
|
812
907
|
});
|
|
@@ -841,12 +936,11 @@ export async function addTask(options, cwd, accessor) {
|
|
|
841
936
|
});
|
|
842
937
|
}
|
|
843
938
|
const parentTypeForValidation = parentTask.type ?? 'task';
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
: 'task');
|
|
939
|
+
// An explicit `--type` is honoured verbatim so the containment check below
|
|
940
|
+
// can REJECT it. Passing it as `currentType` instead would let the helper's
|
|
941
|
+
// reparent fallback rewrite it (`--type subtask` under an epic would become
|
|
942
|
+
// `task`) and silently create the wrong tier rather than refusing.
|
|
943
|
+
const childTypeForParent = taskType ?? childTypeForParentType(parentTypeForValidation);
|
|
850
944
|
if (!isAllowedWorkGraphParentType(childTypeForParent, parentTypeForValidation)) {
|
|
851
945
|
throw new CleoError(ExitCode.VALIDATION_ERROR, `Invalid parent type for ${taskType}: parent ${parentId} has type '${parentTask.type}'.`, {
|
|
852
946
|
fix: 'Use Saga→Epic, Epic→Task, and Task→Subtask containment.',
|
|
@@ -915,22 +1009,38 @@ export async function addTask(options, cwd, accessor) {
|
|
|
915
1009
|
// pure single-mode leaves are unaffected — the guard fires only when a
|
|
916
1010
|
// text-AC-bearing non-container leaf is about to gain its first child.
|
|
917
1011
|
if (parentId &&
|
|
1012
|
+
!options.skipMixedAcParentGuard &&
|
|
918
1013
|
parentTaskForProjection &&
|
|
919
1014
|
parentTaskForProjection.type !== 'epic' &&
|
|
920
1015
|
parentTaskForProjection.type !== 'saga') {
|
|
921
1016
|
const parentAcRows = await dataAccessor.getAcRows(parentId);
|
|
922
1017
|
const parentHasTextAc = parentAcRows.some((row) => row.kind === 'text');
|
|
923
|
-
if (parentHasTextAc) {
|
|
1018
|
+
if (parentHasTextAc && options.autoDecompose && !options.dryRun) {
|
|
1019
|
+
// Resolve the guard instead of reporting it. Dynamic import because
|
|
1020
|
+
// `decompose.ts` imports `addTask` from here — a static import would close
|
|
1021
|
+
// the cycle. The decompose runs BEFORE the projection write below, so by
|
|
1022
|
+
// the time this add inserts, the parent is a pure container and
|
|
1023
|
+
// design-point 3 holds for real rather than being waived.
|
|
1024
|
+
const { decomposeTask } = await import('./decompose.js');
|
|
1025
|
+
const moved = await decomposeTask({ taskId: parentId }, cwd, dataAccessor);
|
|
1026
|
+
if (moved.childId) {
|
|
1027
|
+
autoDecomposed = { childId: moved.childId, movedAcceptance: moved.movedAcceptance };
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
else if (parentHasTextAc) {
|
|
924
1031
|
throw new CleoError(ExitCode.VALIDATION_ERROR, `Cannot add child under ${parentId}: it is a ${parentTaskForProjection.type} with its ` +
|
|
925
1032
|
`own free-text acceptance criteria, and adding a child would mix hand-authored text ` +
|
|
926
1033
|
`ACs with machine-managed child_task projections (PM-Core V2 design-point 3). A ` +
|
|
927
1034
|
`${parentTaskForProjection.type} must be either a leaf defined by its own text ACs OR ` +
|
|
928
1035
|
`a container defined by its children, not both. (Epics and sagas are exempt — they are ` +
|
|
929
1036
|
`containers by design.)`, {
|
|
930
|
-
fix: `
|
|
931
|
-
|
|
932
|
-
`
|
|
933
|
-
`(
|
|
1037
|
+
fix: `Re-run this add with --auto-decompose to do it in one step, or run ` +
|
|
1038
|
+
`\`cleo decompose ${parentId}\` first — either moves ${parentId}'s text acceptance ` +
|
|
1039
|
+
`criteria onto a new first child in one step, leaving ${parentId} a pure ` +
|
|
1040
|
+
`container, after which this add succeeds. (Or promote ${parentId} to an epic ` +
|
|
1041
|
+
`if it is meant to hold children.) Note that clearing the ACs by hand with ` +
|
|
1042
|
+
`\`cleo update ${parentId} --acceptance ""\` does NOT work: acceptance ` +
|
|
1043
|
+
`enforcement rejects an empty criteria list.`,
|
|
934
1044
|
details: {
|
|
935
1045
|
field: 'parentId',
|
|
936
1046
|
parentId,
|
|
@@ -943,7 +1053,9 @@ export async function addTask(options, cwd, accessor) {
|
|
|
943
1053
|
}
|
|
944
1054
|
// BRAIN-powered duplicate detection (T1633) — query active tasks for semantic similarity.
|
|
945
1055
|
// Runs before the exact-title duplicate check so warnings/rejections surface early.
|
|
946
|
-
//
|
|
1056
|
+
// Capture the decision now; persist committed provenance with the task.
|
|
1057
|
+
let duplicateBypass;
|
|
1058
|
+
// Skip on dry-run (no data written).
|
|
947
1059
|
if (!options.dryRun) {
|
|
948
1060
|
const { checkDuplicatesBounded, buildWarnMessage, buildRejectMessage } = await import('./duplicate-detector.js');
|
|
949
1061
|
// T12117 (#1244): bounded and fail-OPEN. This runs BEFORE the insert, so a
|
|
@@ -963,16 +1075,14 @@ export async function addTask(options, cwd, accessor) {
|
|
|
963
1075
|
});
|
|
964
1076
|
}
|
|
965
1077
|
if (dupCheck.shouldReject && options.forceDuplicate) {
|
|
966
|
-
|
|
967
|
-
const { appendDuplicateBypassAudit } = await import('./duplicate-bypass-audit.js');
|
|
968
|
-
await appendDuplicateBypassAudit({
|
|
1078
|
+
duplicateBypass = {
|
|
969
1079
|
incomingTitle: options.title,
|
|
970
1080
|
incomingDescription: options.description ?? '',
|
|
971
1081
|
matchedCandidates: dupCheck.candidates,
|
|
972
1082
|
maxScore: dupCheck.maxScore,
|
|
973
1083
|
timestamp: new Date().toISOString(),
|
|
974
1084
|
agent: 'system',
|
|
975
|
-
}
|
|
1085
|
+
};
|
|
976
1086
|
}
|
|
977
1087
|
if (dupCheck.shouldWarn) {
|
|
978
1088
|
// Emit warning to stderr; does not block insertion.
|
|
@@ -985,7 +1095,16 @@ export async function addTask(options, cwd, accessor) {
|
|
|
985
1095
|
search: options.title,
|
|
986
1096
|
limit: 50,
|
|
987
1097
|
});
|
|
988
|
-
|
|
1098
|
+
// `forceDuplicate` is honoured here as well as by the semantic check above.
|
|
1099
|
+
// This 60-second window exists to absorb accidental double-submits, but it
|
|
1100
|
+
// returned the EXISTING task without inserting and without throwing, so a
|
|
1101
|
+
// caller that had explicitly said "yes, create it anyway" silently got back a
|
|
1102
|
+
// row it did not create. `cleo decompose` hits this every time it runs on a
|
|
1103
|
+
// task filed moments earlier — the common case — because the child it creates
|
|
1104
|
+
// deliberately inherits the parent's title.
|
|
1105
|
+
const duplicate = options.forceDuplicate
|
|
1106
|
+
? null
|
|
1107
|
+
: findRecentDuplicate(options.title, phase, candidateDupes);
|
|
989
1108
|
if (duplicate) {
|
|
990
1109
|
return { task: duplicate, duplicate: true };
|
|
991
1110
|
}
|
|
@@ -1184,6 +1303,15 @@ export async function addTask(options, cwd, accessor) {
|
|
|
1184
1303
|
const createdAcceptanceCriteriaIds = [];
|
|
1185
1304
|
const reopenedAncestorIds = [];
|
|
1186
1305
|
await dataAccessor.transaction(async (tx) => {
|
|
1306
|
+
const severityAttestation = options.severity === undefined
|
|
1307
|
+
? undefined
|
|
1308
|
+
: await prepareSignedSeverityAttestation({
|
|
1309
|
+
timestamp: now,
|
|
1310
|
+
title: task.title,
|
|
1311
|
+
severity: options.severity,
|
|
1312
|
+
taskId,
|
|
1313
|
+
...(parentId ? { epic: parentId } : {}),
|
|
1314
|
+
}, { cwd });
|
|
1187
1315
|
// Position shuffling via bulk SQL update (T025)
|
|
1188
1316
|
if (options.position !== undefined) {
|
|
1189
1317
|
await dataAccessor.shiftPositions(parentId, options.position, 1);
|
|
@@ -1204,14 +1332,13 @@ export async function addTask(options, cwd, accessor) {
|
|
|
1204
1332
|
// PM-Core V2 WorkGraph projection sync: parent_id is the containment edge,
|
|
1205
1333
|
// and each newly-added direct child is mirrored as a parent-owned AC row so
|
|
1206
1334
|
// completion criteria readers can resolve child work without inspecting
|
|
1207
|
-
// task_relations.
|
|
1208
|
-
//
|
|
1209
|
-
// child_task, source_key, and target_task_id state.
|
|
1335
|
+
// task_relations. Preserve existing gate objects in the parent JSON while
|
|
1336
|
+
// the row table carries child_task, source_key, and target_task_id state.
|
|
1210
1337
|
if (parentId && parentTaskForProjection) {
|
|
1211
1338
|
const parentAcRows = await tx.getAcRows(parentId);
|
|
1212
|
-
// PM-Core V2
|
|
1213
|
-
//
|
|
1214
|
-
//
|
|
1339
|
+
// PM-Core V2 child_task rows carry target_task_id/source_key fields.
|
|
1340
|
+
// The mixed JSON view retains existing typed gates and appends only the
|
|
1341
|
+
// new child projection as text. Text-input normalization is not a reader.
|
|
1215
1342
|
const parentChildAcText = buildChildProjectionAcText(taskId, options.title);
|
|
1216
1343
|
const parentChildOrdinal = parentAcRows.reduce((max, row) => Math.max(max, row.ordinal), 0) + 1;
|
|
1217
1344
|
const parentChildSourceKey = childProjectionSourceKey(taskId);
|
|
@@ -1228,12 +1355,14 @@ export async function addTask(options, cwd, accessor) {
|
|
|
1228
1355
|
};
|
|
1229
1356
|
await tx.insertAcRows([parentChildAcRow]);
|
|
1230
1357
|
createdAcceptanceCriteriaIds.push(parentChildAcRow.id);
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1358
|
+
// Re-read under the transaction: sibling creators may have appended
|
|
1359
|
+
// their parent projection after the initial validation snapshot.
|
|
1360
|
+
const currentParent = await dataAccessor.loadSingleTask(parentId);
|
|
1361
|
+
if (!currentParent)
|
|
1362
|
+
throw new CleoError(ExitCode.NOT_FOUND, `Parent task not found: ${parentId}`);
|
|
1363
|
+
const parentAcceptance = [...(currentParent.acceptance ?? []), parentChildAcText];
|
|
1235
1364
|
await tx.updateTaskFields(parentId, {
|
|
1236
|
-
acceptanceJson: JSON.stringify(parentAcceptance
|
|
1365
|
+
acceptanceJson: JSON.stringify(parentAcceptance),
|
|
1237
1366
|
updatedAt: now,
|
|
1238
1367
|
});
|
|
1239
1368
|
}
|
|
@@ -1241,15 +1370,20 @@ export async function addTask(options, cwd, accessor) {
|
|
|
1241
1370
|
// holds the unsatisfied child injected above. Mirrors coreTaskReopen:
|
|
1242
1371
|
// status→pending, clear completedAt, preserve completion history in notes.
|
|
1243
1372
|
for (const ancestor of ancestorsToReopen) {
|
|
1373
|
+
const currentAncestor = await dataAccessor.loadSingleTask(ancestor.id);
|
|
1374
|
+
if (!currentAncestor)
|
|
1375
|
+
throw new CleoError(ExitCode.NOT_FOUND, `Ancestor task not found: ${ancestor.id}`);
|
|
1376
|
+
if (currentAncestor.status !== 'done')
|
|
1377
|
+
continue;
|
|
1244
1378
|
const reopened = {
|
|
1245
|
-
...
|
|
1379
|
+
...currentAncestor,
|
|
1246
1380
|
status: 'pending',
|
|
1247
1381
|
completedAt: undefined,
|
|
1248
1382
|
updatedAt: now,
|
|
1249
1383
|
notes: [
|
|
1250
|
-
...(
|
|
1251
|
-
...(
|
|
1252
|
-
? [`[${now}] completion-history: completedAt=${
|
|
1384
|
+
...(currentAncestor.notes ?? []),
|
|
1385
|
+
...(currentAncestor.completedAt
|
|
1386
|
+
? [`[${now}] completion-history: completedAt=${currentAncestor.completedAt}`]
|
|
1253
1387
|
: []),
|
|
1254
1388
|
`[${now}] Reopened by add of child ${taskId} (done parent gained an unsatisfied child)`,
|
|
1255
1389
|
],
|
|
@@ -1268,11 +1402,65 @@ export async function addTask(options, cwd, accessor) {
|
|
|
1268
1402
|
action: 'task_created',
|
|
1269
1403
|
taskId,
|
|
1270
1404
|
actor: 'system',
|
|
1271
|
-
details: {
|
|
1405
|
+
details: {
|
|
1406
|
+
title: options.title,
|
|
1407
|
+
status,
|
|
1408
|
+
priority,
|
|
1409
|
+
...(severityAttestation
|
|
1410
|
+
? { severityAttestation: { ...severityAttestation, status: 'committed' } }
|
|
1411
|
+
: {}),
|
|
1412
|
+
...(options.forceDuplicate
|
|
1413
|
+
? {
|
|
1414
|
+
forceDuplicate: {
|
|
1415
|
+
...duplicateBypass,
|
|
1416
|
+
requested: true,
|
|
1417
|
+
bypassed: duplicateBypass !== undefined,
|
|
1418
|
+
status: 'committed',
|
|
1419
|
+
},
|
|
1420
|
+
}
|
|
1421
|
+
: {}),
|
|
1422
|
+
...(options.dependsWaiver !== undefined ? { dependsWaiver: options.dependsWaiver } : {}),
|
|
1423
|
+
},
|
|
1272
1424
|
before: null,
|
|
1273
1425
|
after: { title: options.title, status, priority },
|
|
1274
1426
|
});
|
|
1427
|
+
// T945 Stage A — mint a `task:T###` brain graph node at creation, not at
|
|
1428
|
+
// completion. Lazy registration defers execution until the actual outer commit,
|
|
1429
|
+
// including batch transactions; rollback never starts these graph effects.
|
|
1430
|
+
// Tracked (T10490) so the test harness can flush it before tearing down the
|
|
1431
|
+
// shared SQLite singleton; production still runs it fully detached.
|
|
1432
|
+
trackBackgroundOp(() => import('../memory/graph-auto-populate.js')
|
|
1433
|
+
.then(({ ensureTaskNode }) => ensureTaskNode(resolveOrCwd(cwd), taskId, options.title, {
|
|
1434
|
+
status,
|
|
1435
|
+
priority,
|
|
1436
|
+
type: taskType,
|
|
1437
|
+
...(parentId ? { parentId } : {}),
|
|
1438
|
+
}))
|
|
1439
|
+
.catch(() => {
|
|
1440
|
+
/* Graph population is best-effort — never fail addTask. */
|
|
1441
|
+
}));
|
|
1442
|
+
// T1634 — LOOM auto-init for new epics.
|
|
1443
|
+
// Every new epic automatically initializes the RCASD-IVTR lifecycle pipeline
|
|
1444
|
+
// at the 'research' stage so 'cleo orchestrate ready --epic <id>' always
|
|
1445
|
+
// has a LOOM context (and never returns 'epic has no children' due to an
|
|
1446
|
+
// uninitialized pipeline). Fire-and-forget: failures are swallowed inside
|
|
1447
|
+
// initLoomForEpic so LOOM init never blocks or fails epic creation.
|
|
1448
|
+
if (taskType === 'epic') {
|
|
1449
|
+
// Tracked (T10490) — initLoomForEpic touches the shared tasks singleton via
|
|
1450
|
+
// getDb(); flushing it before a test teardown prevents cross-test races.
|
|
1451
|
+
trackBackgroundOp(() => import('../orchestrate/lifecycle-ops.js')
|
|
1452
|
+
.then(({ initLoomForEpic }) => initLoomForEpic(taskId, resolveOrCwd(cwd)))
|
|
1453
|
+
.catch(() => {
|
|
1454
|
+
/* LOOM init is best-effort — never fail addTask. */
|
|
1455
|
+
}));
|
|
1456
|
+
}
|
|
1275
1457
|
});
|
|
1458
|
+
if (duplicateBypass) {
|
|
1459
|
+
// Compatibility mirror only; the task transaction contains authoritative evidence.
|
|
1460
|
+
const { appendDuplicateBypassAudit } = await import('./duplicate-bypass-audit.js');
|
|
1461
|
+
const committedBypass = { ...duplicateBypass, taskId, status: 'committed' };
|
|
1462
|
+
await appendDuplicateBypassAudit(committedBypass, resolveOrCwd(cwd));
|
|
1463
|
+
}
|
|
1276
1464
|
// T10538 / design-point 5: surface the ancestor reopen on the add result so
|
|
1277
1465
|
// the operator is never surprised by a parent silently transitioning out of
|
|
1278
1466
|
// `done`. The reopen itself already happened inside the transaction above.
|
|
@@ -1282,42 +1470,12 @@ export async function addTask(options, cwd, accessor) {
|
|
|
1282
1470
|
`because new child ${taskId} added unsatisfied work under a completed parent. ` +
|
|
1283
1471
|
`Re-complete the ancestor(s) once ${taskId} is done.`);
|
|
1284
1472
|
}
|
|
1285
|
-
// T945 Stage A — mint a `task:T###` brain graph node at creation, not at
|
|
1286
|
-
// completion. Prior to this hook, addTask never wrote to the graph, so new
|
|
1287
|
-
// tasks were invisible until completeTask ran. Fire-and-forget: any failure
|
|
1288
|
-
// is swallowed inside ensureTaskNode so graph writes never fail task creation.
|
|
1289
|
-
// Tracked (T10490) so the test harness can flush it before tearing down the
|
|
1290
|
-
// shared SQLite singleton; production still runs it fully detached.
|
|
1291
|
-
trackBackgroundOp(import('../memory/graph-auto-populate.js')
|
|
1292
|
-
.then(({ ensureTaskNode }) => ensureTaskNode(resolveOrCwd(cwd), taskId, options.title, {
|
|
1293
|
-
status,
|
|
1294
|
-
priority,
|
|
1295
|
-
type: taskType,
|
|
1296
|
-
...(parentId ? { parentId } : {}),
|
|
1297
|
-
}))
|
|
1298
|
-
.catch(() => {
|
|
1299
|
-
/* Graph population is best-effort — never fail addTask. */
|
|
1300
|
-
}));
|
|
1301
|
-
// T1634 — LOOM auto-init for new epics.
|
|
1302
|
-
// Every new epic automatically initializes the RCASD-IVTR lifecycle pipeline
|
|
1303
|
-
// at the 'research' stage so 'cleo orchestrate ready --epic <id>' always
|
|
1304
|
-
// has a LOOM context (and never returns 'epic has no children' due to an
|
|
1305
|
-
// uninitialized pipeline). Fire-and-forget: failures are swallowed inside
|
|
1306
|
-
// initLoomForEpic so LOOM init never blocks or fails epic creation.
|
|
1307
|
-
if (taskType === 'epic') {
|
|
1308
|
-
// Tracked (T10490) — initLoomForEpic touches the shared tasks singleton via
|
|
1309
|
-
// getDb(); flushing it before a test teardown prevents cross-test races.
|
|
1310
|
-
trackBackgroundOp(import('../orchestrate/lifecycle-ops.js')
|
|
1311
|
-
.then(({ initLoomForEpic }) => initLoomForEpic(taskId, resolveOrCwd(cwd)))
|
|
1312
|
-
.catch(() => {
|
|
1313
|
-
/* LOOM init is best-effort — never fail addTask. */
|
|
1314
|
-
}));
|
|
1315
|
-
}
|
|
1316
1473
|
return {
|
|
1317
1474
|
task,
|
|
1318
1475
|
createdIds: { tasks: [taskId], acceptanceCriteria: createdAcceptanceCriteriaIds },
|
|
1319
1476
|
...(warnings.length > 0 && { warnings }),
|
|
1320
1477
|
...(reopenedAncestorIds.length > 0 && { reopenedAncestors: reopenedAncestorIds }),
|
|
1478
|
+
...(autoDecomposed && { autoDecomposed }),
|
|
1321
1479
|
};
|
|
1322
1480
|
}
|
|
1323
1481
|
//# sourceMappingURL=add.js.map
|