@cleocode/core 2026.9.20 → 2026.9.21
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/adapters/discovery.d.ts.map +1 -1
- package/dist/adapters/discovery.js +3 -10
- package/dist/adapters/discovery.js.map +1 -1
- package/dist/adrs/link-pipeline.js +2 -2
- package/dist/adrs/link-pipeline.js.map +1 -1
- package/dist/adrs/parse.js +3 -3
- package/dist/adrs/parse.js.map +1 -1
- package/dist/agents/invoke-meta-agent.d.ts.map +1 -1
- package/dist/agents/invoke-meta-agent.js +8 -4
- package/dist/agents/invoke-meta-agent.js.map +1 -1
- package/dist/bootstrap.d.ts +5 -1
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +41 -21
- package/dist/bootstrap.js.map +1 -1
- package/dist/cloud/crypto.d.ts +47 -0
- package/dist/cloud/crypto.d.ts.map +1 -0
- package/dist/cloud/crypto.js +223 -0
- package/dist/cloud/crypto.js.map +1 -0
- package/dist/cloud/http.d.ts +52 -0
- package/dist/cloud/http.d.ts.map +1 -0
- package/dist/cloud/http.js +98 -0
- package/dist/cloud/http.js.map +1 -0
- package/dist/cloud/index.d.ts +19 -0
- package/dist/cloud/index.d.ts.map +1 -0
- package/dist/cloud/index.js +19 -0
- package/dist/cloud/index.js.map +1 -0
- package/dist/cloud/journal.d.ts +169 -0
- package/dist/cloud/journal.d.ts.map +1 -0
- package/dist/cloud/journal.js +428 -0
- package/dist/cloud/journal.js.map +1 -0
- package/dist/cloud/keys.d.ts +213 -0
- package/dist/cloud/keys.d.ts.map +1 -0
- package/dist/cloud/keys.js +362 -0
- package/dist/cloud/keys.js.map +1 -0
- package/dist/cloud/manifest-check.d.ts +36 -0
- package/dist/cloud/manifest-check.d.ts.map +1 -0
- package/dist/cloud/manifest-check.js +70 -0
- package/dist/cloud/manifest-check.js.map +1 -0
- package/dist/cloud/projects.d.ts +13 -0
- package/dist/cloud/projects.d.ts.map +1 -0
- package/dist/cloud/projects.js +11 -0
- package/dist/cloud/projects.js.map +1 -0
- package/dist/cloud/signing.d.ts +105 -0
- package/dist/cloud/signing.d.ts.map +1 -0
- package/dist/cloud/signing.js +117 -0
- package/dist/cloud/signing.js.map +1 -0
- package/dist/cloud/streams.d.ts +6 -0
- package/dist/cloud/streams.d.ts.map +1 -0
- package/dist/cloud/streams.js +5 -0
- package/dist/cloud/streams.js.map +1 -0
- package/dist/decide/audit.d.ts +131 -0
- package/dist/decide/audit.d.ts.map +1 -0
- package/dist/decide/audit.js +98 -0
- package/dist/decide/audit.js.map +1 -0
- package/dist/decide/budget.d.ts +91 -0
- package/dist/decide/budget.d.ts.map +1 -0
- package/dist/decide/budget.js +194 -0
- package/dist/decide/budget.js.map +1 -0
- package/dist/decide/cache.d.ts +49 -0
- package/dist/decide/cache.d.ts.map +1 -0
- package/dist/decide/cache.js +87 -0
- package/dist/decide/cache.js.map +1 -0
- package/dist/decide/client.d.ts +103 -0
- package/dist/decide/client.d.ts.map +1 -0
- package/dist/decide/client.js +262 -0
- package/dist/decide/client.js.map +1 -0
- package/dist/decide/credentials.d.ts +159 -0
- package/dist/decide/credentials.d.ts.map +1 -0
- package/dist/decide/credentials.js +383 -0
- package/dist/decide/credentials.js.map +1 -0
- package/dist/decide/index.d.ts +18 -0
- package/dist/decide/index.d.ts.map +1 -0
- package/dist/decide/index.js +18 -0
- package/dist/decide/index.js.map +1 -0
- package/dist/decide/jev-wire.d.ts +155 -0
- package/dist/decide/jev-wire.d.ts.map +1 -0
- package/dist/decide/jev-wire.js +420 -0
- package/dist/decide/jev-wire.js.map +1 -0
- package/dist/decide/operations.d.ts +152 -0
- package/dist/decide/operations.d.ts.map +1 -0
- package/dist/decide/operations.js +199 -0
- package/dist/decide/operations.js.map +1 -0
- package/dist/decide/provider.d.ts +90 -0
- package/dist/decide/provider.d.ts.map +1 -0
- package/dist/decide/provider.js +43 -0
- package/dist/decide/provider.js.map +1 -0
- package/dist/decide/site.d.ts +148 -0
- package/dist/decide/site.d.ts.map +1 -0
- package/dist/decide/site.js +181 -0
- package/dist/decide/site.js.map +1 -0
- package/dist/decide/transport.d.ts +67 -0
- package/dist/decide/transport.d.ts.map +1 -0
- package/dist/decide/transport.js +350 -0
- package/dist/decide/transport.js.map +1 -0
- package/dist/docs/export-document.js +5908 -2436
- package/dist/docs/export-document.js.map +3 -3
- package/dist/docs/index.d.ts +2 -2
- package/dist/docs/index.d.ts.map +1 -1
- package/dist/docs/index.js +1 -1
- package/dist/docs/index.js.map +1 -1
- package/dist/docs/projection.d.ts.map +1 -1
- package/dist/docs/projection.js +2 -3
- package/dist/docs/projection.js.map +1 -1
- package/dist/docs/publish-pr.d.ts +69 -1
- package/dist/docs/publish-pr.d.ts.map +1 -1
- package/dist/docs/publish-pr.js +112 -10
- package/dist/docs/publish-pr.js.map +1 -1
- package/dist/doctor/db-substrate.d.ts +13 -8
- package/dist/doctor/db-substrate.d.ts.map +1 -1
- package/dist/doctor/db-substrate.js +39 -26
- package/dist/doctor/db-substrate.js.map +1 -1
- package/dist/doctor/index.d.ts +2 -0
- package/dist/doctor/index.d.ts.map +1 -1
- package/dist/doctor/index.js +1 -0
- package/dist/doctor/index.js.map +1 -1
- package/dist/doctor/knowledge.d.ts.map +1 -1
- package/dist/doctor/knowledge.js +5 -15
- package/dist/doctor/knowledge.js.map +1 -1
- package/dist/doctor/nexus-schema-residency.d.ts +1 -1
- package/dist/doctor/nexus-schema-residency.d.ts.map +1 -1
- package/dist/doctor/nexus-schema-residency.js +3 -0
- package/dist/doctor/nexus-schema-residency.js.map +1 -1
- package/dist/doctor/project-identity.d.ts +44 -1
- package/dist/doctor/project-identity.d.ts.map +1 -1
- package/dist/doctor/project-identity.js +237 -10
- package/dist/doctor/project-identity.js.map +1 -1
- package/dist/doctor/projects.d.ts +170 -0
- package/dist/doctor/projects.d.ts.map +1 -0
- package/dist/doctor/projects.js +1075 -0
- package/dist/doctor/projects.js.map +1 -0
- package/dist/doctor/twin-collapse.d.ts +97 -0
- package/dist/doctor/twin-collapse.d.ts.map +1 -0
- package/dist/doctor/twin-collapse.js +168 -0
- package/dist/doctor/twin-collapse.js.map +1 -0
- package/dist/doctor/worktree-orphans.d.ts.map +1 -1
- package/dist/doctor/worktree-orphans.js +13 -29
- package/dist/doctor/worktree-orphans.js.map +1 -1
- package/dist/doctor/worktree-stores.d.ts +128 -0
- package/dist/doctor/worktree-stores.d.ts.map +1 -0
- package/dist/doctor/worktree-stores.js +374 -0
- package/dist/doctor/worktree-stores.js.map +1 -0
- package/dist/error-catalog.d.ts.map +1 -1
- package/dist/error-catalog.js +21 -0
- package/dist/error-catalog.js.map +1 -1
- package/dist/error-registry.d.ts.map +1 -1
- package/dist/error-registry.js +40 -0
- package/dist/error-registry.js.map +1 -1
- package/dist/gc/cleanup.d.ts.map +1 -1
- package/dist/gc/cleanup.js +32 -19
- package/dist/gc/cleanup.js.map +1 -1
- package/dist/git/bounded-git.d.ts +170 -0
- package/dist/git/bounded-git.d.ts.map +1 -0
- package/dist/git/bounded-git.js +371 -0
- package/dist/git/bounded-git.js.map +1 -0
- package/dist/git/work-tree.d.ts +20 -0
- package/dist/git/work-tree.d.ts.map +1 -1
- package/dist/git/work-tree.js +20 -2
- package/dist/git/work-tree.js.map +1 -1
- package/dist/hooks/handlers/session-hooks.d.ts +11 -26
- package/dist/hooks/handlers/session-hooks.d.ts.map +1 -1
- package/dist/hooks/handlers/session-hooks.js +18 -47
- package/dist/hooks/handlers/session-hooks.js.map +1 -1
- package/dist/hooks/payload-schemas.d.ts +2 -2
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/init/engine-ops.d.ts.map +1 -1
- package/dist/init/engine-ops.js +23 -1
- package/dist/init/engine-ops.js.map +1 -1
- package/dist/init.d.ts +158 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +527 -42
- package/dist/init.js.map +1 -1
- package/dist/injection.d.ts +55 -0
- package/dist/injection.d.ts.map +1 -1
- package/dist/injection.js +102 -6
- package/dist/injection.js.map +1 -1
- package/dist/internal.d.ts +9 -5
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +8 -4
- package/dist/internal.js.map +1 -1
- package/dist/issue/diagnostics.d.ts.map +1 -1
- package/dist/issue/diagnostics.js +2 -1
- package/dist/issue/diagnostics.js.map +1 -1
- package/dist/lib/concurrency.d.ts +25 -0
- package/dist/lib/concurrency.d.ts.map +1 -0
- package/dist/lib/concurrency.js +43 -0
- package/dist/lib/concurrency.js.map +1 -0
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +1 -0
- package/dist/lib/index.js.map +1 -1
- package/dist/lifecycle/engine-ops.d.ts.map +1 -1
- package/dist/lifecycle/engine-ops.js +4 -2
- package/dist/lifecycle/engine-ops.js.map +1 -1
- package/dist/lifecycle/stage-guidance.d.ts +5 -0
- package/dist/lifecycle/stage-guidance.d.ts.map +1 -1
- package/dist/lifecycle/stage-guidance.js +14 -4
- package/dist/lifecycle/stage-guidance.js.map +1 -1
- package/dist/llm/catalog-cache.d.ts +3 -2
- package/dist/llm/catalog-cache.d.ts.map +1 -1
- package/dist/llm/catalog-cache.js +5 -5
- package/dist/llm/catalog-cache.js.map +1 -1
- package/dist/llm/credentials.d.ts +4 -4
- package/dist/llm/credentials.js +6 -6
- package/dist/llm/credentials.js.map +1 -1
- package/dist/llm/plugin-facade.js +4312 -1798
- package/dist/llm/plugin-facade.js.map +3 -3
- package/dist/llm/stable-device-id.d.ts.map +1 -1
- package/dist/llm/stable-device-id.js +3 -5
- package/dist/llm/stable-device-id.js.map +1 -1
- package/dist/memory/attention.d.ts.map +1 -1
- package/dist/memory/attention.js +30 -30
- package/dist/memory/attention.js.map +1 -1
- package/dist/memory/decision-contradiction.d.ts +152 -0
- package/dist/memory/decision-contradiction.d.ts.map +1 -0
- package/dist/memory/decision-contradiction.js +273 -0
- package/dist/memory/decision-contradiction.js.map +1 -0
- package/dist/memory/decisions.d.ts +42 -11
- package/dist/memory/decisions.d.ts.map +1 -1
- package/dist/memory/decisions.js +153 -56
- package/dist/memory/decisions.js.map +1 -1
- package/dist/memory/dialectic-evaluator.d.ts +7 -0
- package/dist/memory/dialectic-evaluator.d.ts.map +1 -1
- package/dist/memory/dialectic-evaluator.js +23 -8
- package/dist/memory/dialectic-evaluator.js.map +1 -1
- package/dist/memory/dispatch-trace-format.d.ts +39 -0
- package/dist/memory/dispatch-trace-format.d.ts.map +1 -0
- package/dist/memory/dispatch-trace-format.js +54 -0
- package/dist/memory/dispatch-trace-format.js.map +1 -0
- package/dist/memory/dispatch-trace.d.ts.map +1 -1
- package/dist/memory/dispatch-trace.js +1 -27
- package/dist/memory/dispatch-trace.js.map +1 -1
- 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 +1 -0
- package/dist/memory/engine-compat.js.map +1 -1
- package/dist/memory/import-from-provider.js +3 -3
- package/dist/memory/import-from-provider.js.map +1 -1
- package/dist/memory/learnings.d.ts +2 -2
- package/dist/memory/observation-type-decision.d.ts +96 -0
- package/dist/memory/observation-type-decision.d.ts.map +1 -0
- package/dist/memory/observation-type-decision.js +218 -0
- package/dist/memory/observation-type-decision.js.map +1 -0
- package/dist/memory/redaction.js +2 -0
- package/dist/memory/redaction.js.map +1 -1
- package/dist/memory/retrieval/build-retrieval-bundle.d.ts +9 -2
- package/dist/memory/retrieval/build-retrieval-bundle.d.ts.map +1 -1
- package/dist/memory/retrieval/build-retrieval-bundle.js +42 -11
- package/dist/memory/retrieval/build-retrieval-bundle.js.map +1 -1
- package/dist/memory/retrieval/get-current-session-id.d.ts +5 -0
- package/dist/memory/retrieval/get-current-session-id.d.ts.map +1 -1
- package/dist/memory/retrieval/get-current-session-id.js +7 -2
- package/dist/memory/retrieval/get-current-session-id.js.map +1 -1
- package/dist/memory/retrieval/observe.d.ts.map +1 -1
- package/dist/memory/retrieval/observe.js +30 -29
- package/dist/memory/retrieval/observe.js.map +1 -1
- package/dist/nexus/analyze-orchestrator.d.ts.map +1 -1
- package/dist/nexus/analyze-orchestrator.js +42 -29
- package/dist/nexus/analyze-orchestrator.js.map +1 -1
- package/dist/nexus/assessment-projection.d.ts +76 -0
- package/dist/nexus/assessment-projection.d.ts.map +1 -0
- package/dist/nexus/assessment-projection.js +143 -0
- package/dist/nexus/assessment-projection.js.map +1 -0
- package/dist/nexus/assessment-store.d.ts +14 -2
- package/dist/nexus/assessment-store.d.ts.map +1 -1
- package/dist/nexus/assessment-store.js +21 -3
- package/dist/nexus/assessment-store.js.map +1 -1
- package/dist/nexus/checkout-nonce.d.ts +48 -0
- package/dist/nexus/checkout-nonce.d.ts.map +1 -0
- package/dist/nexus/checkout-nonce.js +84 -0
- package/dist/nexus/checkout-nonce.js.map +1 -0
- package/dist/nexus/devices.d.ts +93 -0
- package/dist/nexus/devices.d.ts.map +1 -0
- package/dist/nexus/devices.js +141 -0
- package/dist/nexus/devices.js.map +1 -0
- package/dist/nexus/freshness.d.ts.map +1 -1
- package/dist/nexus/freshness.js +25 -6
- package/dist/nexus/freshness.js.map +1 -1
- package/dist/nexus/git-state.d.ts +225 -0
- package/dist/nexus/git-state.d.ts.map +1 -0
- package/dist/nexus/git-state.js +677 -0
- package/dist/nexus/git-state.js.map +1 -0
- package/dist/nexus/graph-manifest.d.ts +20 -4
- package/dist/nexus/graph-manifest.d.ts.map +1 -1
- package/dist/nexus/graph-manifest.js +40 -5
- package/dist/nexus/graph-manifest.js.map +1 -1
- package/dist/nexus/identity.d.ts +68 -23
- package/dist/nexus/identity.d.ts.map +1 -1
- package/dist/nexus/identity.js +99 -22
- package/dist/nexus/identity.js.map +1 -1
- package/dist/nexus/index.d.ts +5 -2
- package/dist/nexus/index.d.ts.map +1 -1
- package/dist/nexus/index.js +10 -4
- package/dist/nexus/index.js.map +1 -1
- package/dist/nexus/knowledge.d.ts +5 -0
- package/dist/nexus/knowledge.d.ts.map +1 -1
- package/dist/nexus/knowledge.js +26 -2
- package/dist/nexus/knowledge.js.map +1 -1
- package/dist/nexus/legacy-alias.d.ts +60 -0
- package/dist/nexus/legacy-alias.d.ts.map +1 -0
- package/dist/nexus/legacy-alias.js +68 -0
- package/dist/nexus/legacy-alias.js.map +1 -0
- package/dist/nexus/migrate-json-to-sqlite.js +2 -2
- package/dist/nexus/migrate-json-to-sqlite.js.map +1 -1
- package/dist/nexus/ops.d.ts +1 -0
- package/dist/nexus/ops.d.ts.map +1 -1
- package/dist/nexus/path-map.d.ts +264 -20
- package/dist/nexus/path-map.d.ts.map +1 -1
- package/dist/nexus/path-map.js +580 -44
- package/dist/nexus/path-map.js.map +1 -1
- package/dist/nexus/projects-clean.d.ts +9 -1
- package/dist/nexus/projects-clean.d.ts.map +1 -1
- package/dist/nexus/projects-clean.js +126 -14
- package/dist/nexus/projects-clean.js.map +1 -1
- package/dist/nexus/projects-scan.d.ts +56 -1
- package/dist/nexus/projects-scan.d.ts.map +1 -1
- package/dist/nexus/projects-scan.js +144 -3
- package/dist/nexus/projects-scan.js.map +1 -1
- package/dist/nexus/registry-hygiene.d.ts +18 -2
- package/dist/nexus/registry-hygiene.d.ts.map +1 -1
- package/dist/nexus/registry-hygiene.js +37 -11
- package/dist/nexus/registry-hygiene.js.map +1 -1
- package/dist/nexus/registry-roots.d.ts +47 -0
- package/dist/nexus/registry-roots.d.ts.map +1 -0
- package/dist/nexus/registry-roots.js +79 -0
- package/dist/nexus/registry-roots.js.map +1 -0
- package/dist/nexus/registry.d.ts +50 -9
- package/dist/nexus/registry.d.ts.map +1 -1
- package/dist/nexus/registry.js +311 -156
- package/dist/nexus/registry.js.map +1 -1
- package/dist/nexus/stored-roots.d.ts +106 -0
- package/dist/nexus/stored-roots.d.ts.map +1 -0
- package/dist/nexus/stored-roots.js +180 -0
- package/dist/nexus/stored-roots.js.map +1 -0
- package/dist/nexus/transfer.d.ts.map +1 -1
- package/dist/nexus/transfer.js +3 -0
- package/dist/nexus/transfer.js.map +1 -1
- package/dist/nexus/user-profile-hygiene.d.ts +168 -0
- package/dist/nexus/user-profile-hygiene.d.ts.map +1 -0
- package/dist/nexus/user-profile-hygiene.js +305 -0
- package/dist/nexus/user-profile-hygiene.js.map +1 -0
- package/dist/nexus/user-profile.d.ts +53 -2
- package/dist/nexus/user-profile.d.ts.map +1 -1
- package/dist/nexus/user-profile.js +106 -4
- package/dist/nexus/user-profile.js.map +1 -1
- package/dist/orchestrate/pivot.d.ts.map +1 -1
- package/dist/orchestrate/pivot.js +5 -1
- package/dist/orchestrate/pivot.js.map +1 -1
- package/dist/orchestrate/spawn-ops.d.ts +12 -0
- package/dist/orchestrate/spawn-ops.d.ts.map +1 -1
- package/dist/orchestrate/spawn-ops.js +152 -57
- package/dist/orchestrate/spawn-ops.js.map +1 -1
- package/dist/orchestration/classify-readiness.d.ts +37 -1
- package/dist/orchestration/classify-readiness.d.ts.map +1 -1
- package/dist/orchestration/classify-readiness.js +48 -19
- package/dist/orchestration/classify-readiness.js.map +1 -1
- package/dist/orchestration/index.d.ts +3 -2
- package/dist/orchestration/index.d.ts.map +1 -1
- package/dist/orchestration/index.js +2 -1
- package/dist/orchestration/index.js.map +1 -1
- package/dist/orchestration/owner-decision-readiness.d.ts +88 -0
- package/dist/orchestration/owner-decision-readiness.d.ts.map +1 -0
- package/dist/orchestration/owner-decision-readiness.js +152 -0
- package/dist/orchestration/owner-decision-readiness.js.map +1 -0
- package/dist/orchestration/psyche-memory-budget.d.ts +105 -0
- package/dist/orchestration/psyche-memory-budget.d.ts.map +1 -0
- package/dist/orchestration/psyche-memory-budget.js +383 -0
- package/dist/orchestration/psyche-memory-budget.js.map +1 -0
- package/dist/orchestration/spawn-prompt.d.ts +12 -1
- package/dist/orchestration/spawn-prompt.d.ts.map +1 -1
- package/dist/orchestration/spawn-prompt.js +141 -179
- package/dist/orchestration/spawn-prompt.js.map +1 -1
- package/dist/orchestration/spawn.d.ts +7 -0
- package/dist/orchestration/spawn.d.ts.map +1 -1
- package/dist/orchestration/spawn.js +1 -0
- package/dist/orchestration/spawn.js.map +1 -1
- package/dist/paths.d.ts +24 -8
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +135 -71
- package/dist/paths.js.map +1 -1
- package/dist/platform.d.ts +6 -1
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +8 -19
- package/dist/platform.js.map +1 -1
- package/dist/project-info.d.ts +18 -0
- package/dist/project-info.d.ts.map +1 -1
- package/dist/project-info.js +29 -1
- package/dist/project-info.js.map +1 -1
- package/dist/project-lifecycle.d.ts +91 -32
- package/dist/project-lifecycle.d.ts.map +1 -1
- package/dist/project-lifecycle.js +639 -75
- package/dist/project-lifecycle.js.map +1 -1
- package/dist/project-scope.d.ts +86 -4
- package/dist/project-scope.d.ts.map +1 -1
- package/dist/project-scope.js +226 -13
- package/dist/project-scope.js.map +1 -1
- package/dist/project-tombstone.d.ts +111 -0
- package/dist/project-tombstone.d.ts.map +1 -0
- package/dist/project-tombstone.js +220 -0
- package/dist/project-tombstone.js.map +1 -0
- package/dist/release/artifacts.d.ts.map +1 -1
- package/dist/release/artifacts.js +14 -9
- package/dist/release/artifacts.js.map +1 -1
- package/dist/release/ci-evidence.d.ts +223 -0
- package/dist/release/ci-evidence.d.ts.map +1 -0
- package/dist/release/ci-evidence.js +652 -0
- package/dist/release/ci-evidence.js.map +1 -0
- package/dist/release/engine-ops.d.ts.map +1 -1
- package/dist/release/engine-ops.js +3 -3
- package/dist/release/engine-ops.js.map +1 -1
- package/dist/release/plan.d.ts.map +1 -1
- package/dist/release/plan.js +7 -6
- package/dist/release/plan.js.map +1 -1
- package/dist/release/pr-evidence.d.ts +38 -0
- package/dist/release/pr-evidence.d.ts.map +1 -1
- package/dist/release/pr-evidence.js +67 -11
- package/dist/release/pr-evidence.js.map +1 -1
- package/dist/release/reconcile.d.ts.map +1 -1
- package/dist/release/reconcile.js +3 -2
- package/dist/release/reconcile.js.map +1 -1
- package/dist/release/release-manifest.d.ts +2 -1
- package/dist/release/release-manifest.d.ts.map +1 -1
- package/dist/release/release-manifest.js +6 -5
- package/dist/release/release-manifest.js.map +1 -1
- package/dist/render/nexus/graph/index.d.ts +4 -0
- package/dist/render/nexus/graph/index.d.ts.map +1 -1
- package/dist/render/nexus/graph/index.js +57 -0
- package/dist/render/nexus/graph/index.js.map +1 -1
- package/dist/resources/spawn-wrapper.d.ts +8 -1
- package/dist/resources/spawn-wrapper.d.ts.map +1 -1
- package/dist/resources/spawn-wrapper.js +42 -5
- package/dist/resources/spawn-wrapper.js.map +1 -1
- package/dist/routing/build-command-groups.d.ts.map +1 -1
- package/dist/routing/build-command-groups.js +1 -0
- package/dist/routing/build-command-groups.js.map +1 -1
- package/dist/sagas/index.d.ts +1 -1
- package/dist/sagas/index.d.ts.map +1 -1
- package/dist/sagas/index.js +1 -1
- package/dist/sagas/index.js.map +1 -1
- package/dist/sagas/reconcile.d.ts +24 -4
- package/dist/sagas/reconcile.d.ts.map +1 -1
- package/dist/sagas/reconcile.js +226 -100
- package/dist/sagas/reconcile.js.map +1 -1
- package/dist/scaffold/ensure-config.d.ts.map +1 -1
- package/dist/scaffold/ensure-config.js +31 -1
- package/dist/scaffold/ensure-config.js.map +1 -1
- package/dist/scaffold/project-identity.d.ts +2 -8
- package/dist/scaffold/project-identity.d.ts.map +1 -1
- package/dist/scaffold/project-identity.js +5 -21
- package/dist/scaffold/project-identity.js.map +1 -1
- package/dist/security/input-sanitization.d.ts +9 -1
- package/dist/security/input-sanitization.d.ts.map +1 -1
- package/dist/security/input-sanitization.js +12 -2
- package/dist/security/input-sanitization.js.map +1 -1
- package/dist/selfimprove/fix-gen.js +4321 -1807
- package/dist/selfimprove/fix-gen.js.map +3 -3
- package/dist/sentient/propose-tick.d.ts.map +1 -1
- package/dist/sentient/propose-tick.js +4 -2
- package/dist/sentient/propose-tick.js.map +1 -1
- package/dist/sequence/index.d.ts.map +1 -1
- package/dist/sequence/index.js +6 -23
- package/dist/sequence/index.js.map +1 -1
- package/dist/session/engine-ops.d.ts +9 -0
- package/dist/session/engine-ops.d.ts.map +1 -1
- package/dist/session/engine-ops.js +110 -18
- package/dist/session/engine-ops.js.map +1 -1
- package/dist/sessions/assumptions.d.ts.map +1 -1
- package/dist/sessions/assumptions.js +7 -4
- package/dist/sessions/assumptions.js.map +1 -1
- package/dist/sessions/briefing.d.ts +6 -0
- package/dist/sessions/briefing.d.ts.map +1 -1
- package/dist/sessions/briefing.js +12 -1
- package/dist/sessions/briefing.js.map +1 -1
- package/dist/sessions/decisions.d.ts +38 -3
- package/dist/sessions/decisions.d.ts.map +1 -1
- package/dist/sessions/decisions.js +235 -21
- package/dist/sessions/decisions.js.map +1 -1
- package/dist/sessions/drift-watchdog.d.ts.map +1 -1
- package/dist/sessions/drift-watchdog.js +4 -2
- package/dist/sessions/drift-watchdog.js.map +1 -1
- package/dist/sessions/index.d.ts.map +1 -1
- package/dist/sessions/index.js +33 -4
- package/dist/sessions/index.js.map +1 -1
- package/dist/sessions/session-end-snapshot-entry.d.ts +26 -0
- package/dist/sessions/session-end-snapshot-entry.d.ts.map +1 -0
- package/dist/sessions/session-end-snapshot-entry.js +59 -0
- package/dist/sessions/session-end-snapshot-entry.js.map +1 -0
- package/dist/sessions/session-end-snapshot.d.ts +114 -0
- package/dist/sessions/session-end-snapshot.d.ts.map +1 -0
- package/dist/sessions/session-end-snapshot.js +446 -0
- package/dist/sessions/session-end-snapshot.js.map +1 -0
- package/dist/sessions/session-manifest-mirror.d.ts.map +1 -1
- package/dist/sessions/session-manifest-mirror.js +10 -17
- package/dist/sessions/session-manifest-mirror.js.map +1 -1
- package/dist/sessions/session-switch.d.ts.map +1 -1
- package/dist/sessions/session-switch.js +5 -3
- package/dist/sessions/session-switch.js.map +1 -1
- package/dist/sessions/snapshot.d.ts.map +1 -1
- package/dist/sessions/snapshot.js +5 -4
- package/dist/sessions/snapshot.js.map +1 -1
- package/dist/sessions/terminal-identity.d.ts +169 -0
- package/dist/sessions/terminal-identity.d.ts.map +1 -0
- package/dist/sessions/terminal-identity.js +273 -0
- package/dist/sessions/terminal-identity.js.map +1 -0
- package/dist/setup/sections/verification.d.ts +1 -1
- package/dist/setup/sections/verification.d.ts.map +1 -1
- package/dist/setup/sections/verification.js +11 -15
- package/dist/setup/sections/verification.js.map +1 -1
- package/dist/skills/discovery.d.ts +8 -2
- package/dist/skills/discovery.d.ts.map +1 -1
- package/dist/skills/discovery.js +15 -3
- package/dist/skills/discovery.js.map +1 -1
- package/dist/skills/dispatch.d.ts +5 -2
- package/dist/skills/dispatch.d.ts.map +1 -1
- package/dist/skills/dispatch.js +5 -2
- package/dist/skills/dispatch.js.map +1 -1
- package/dist/skills/doctor.d.ts.map +1 -1
- package/dist/skills/doctor.js +5 -1
- package/dist/skills/doctor.js.map +1 -1
- package/dist/skills/federated-search.js +2 -2
- package/dist/skills/federated-search.js.map +1 -1
- package/dist/skills/index.d.ts +3 -3
- 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/migration.d.ts +5 -5
- package/dist/skills/migration.d.ts.map +1 -1
- package/dist/skills/migration.js +7 -9
- package/dist/skills/migration.js.map +1 -1
- package/dist/skills/orchestrator/startup.d.ts.map +1 -1
- package/dist/skills/orchestrator/startup.js +4 -2
- package/dist/skills/orchestrator/startup.js.map +1 -1
- package/dist/skills/skill-paths.d.ts +30 -3
- package/dist/skills/skill-paths.d.ts.map +1 -1
- package/dist/skills/skill-paths.js +28 -9
- package/dist/skills/skill-paths.js.map +1 -1
- package/dist/skills/skill-root.d.ts +60 -11
- package/dist/skills/skill-root.d.ts.map +1 -1
- package/dist/skills/skill-root.js +100 -14
- package/dist/skills/skill-root.js.map +1 -1
- package/dist/skills/skills-guard.js +5 -5
- package/dist/skills/skills-guard.js.map +1 -1
- package/dist/skills/types.d.ts +23 -0
- package/dist/skills/types.d.ts.map +1 -1
- package/dist/skills/types.js.map +1 -1
- package/dist/spawn/agent-identity.d.ts +51 -2
- package/dist/spawn/agent-identity.d.ts.map +1 -1
- package/dist/spawn/agent-identity.js +89 -26
- package/dist/spawn/agent-identity.js.map +1 -1
- package/dist/spawn/branch-lock.d.ts.map +1 -1
- package/dist/spawn/branch-lock.js +56 -79
- package/dist/spawn/branch-lock.js.map +1 -1
- package/dist/spawn/index.d.ts +2 -2
- package/dist/spawn/index.d.ts.map +1 -1
- package/dist/spawn/index.js +1 -1
- package/dist/spawn/index.js.map +1 -1
- package/dist/spawn/worktree-lock-holder.d.ts +37 -0
- package/dist/spawn/worktree-lock-holder.d.ts.map +1 -0
- package/dist/spawn/worktree-lock-holder.js +41 -0
- package/dist/spawn/worktree-lock-holder.js.map +1 -0
- package/dist/sticky/convert.d.ts.map +1 -1
- package/dist/sticky/convert.js +16 -4
- package/dist/sticky/convert.js.map +1 -1
- package/dist/store/attachment-store.d.ts +14 -0
- package/dist/store/attachment-store.d.ts.map +1 -1
- package/dist/store/attachment-store.js +11 -1
- package/dist/store/attachment-store.js.map +1 -1
- package/dist/store/backup-inspect.d.ts +7 -3
- package/dist/store/backup-inspect.d.ts.map +1 -1
- package/dist/store/backup-inspect.js +18 -7
- package/dist/store/backup-inspect.js.map +1 -1
- package/dist/store/backup-sidecar.d.ts +60 -0
- package/dist/store/backup-sidecar.d.ts.map +1 -0
- package/dist/store/backup-sidecar.js +96 -0
- package/dist/store/backup-sidecar.js.map +1 -0
- package/dist/store/data-accessor.d.ts +1 -1
- package/dist/store/data-accessor.d.ts.map +1 -1
- package/dist/store/data-accessor.js +6 -6
- package/dist/store/data-accessor.js.map +1 -1
- package/dist/store/data-safety-central.d.ts +13 -4
- package/dist/store/data-safety-central.d.ts.map +1 -1
- package/dist/store/data-safety-central.js +31 -4
- package/dist/store/data-safety-central.js.map +1 -1
- package/dist/store/dual-scope-db.d.ts.map +1 -1
- package/dist/store/dual-scope-db.js +10 -0
- package/dist/store/dual-scope-db.js.map +1 -1
- package/dist/store/exodus/__fixtures__/representative-fixture.d.ts.map +1 -1
- package/dist/store/exodus/__fixtures__/representative-fixture.js +4 -0
- package/dist/store/exodus/__fixtures__/representative-fixture.js.map +1 -1
- package/dist/store/exodus/migrate.js +1 -1
- package/dist/store/exodus/migrate.js.map +1 -1
- package/dist/store/exodus/reconcile.js +1 -1
- package/dist/store/exodus/reconcile.js.map +1 -1
- package/dist/store/exodus/runtime-targets.d.ts +4 -3
- package/dist/store/exodus/runtime-targets.d.ts.map +1 -1
- package/dist/store/exodus/runtime-targets.js +4 -3
- package/dist/store/exodus/runtime-targets.js.map +1 -1
- package/dist/store/import-logging.d.ts.map +1 -1
- package/dist/store/import-logging.js +5 -4
- package/dist/store/import-logging.js.map +1 -1
- package/dist/store/legacy-tasks-lineage.d.ts.map +1 -1
- package/dist/store/legacy-tasks-lineage.js +2 -7
- package/dist/store/legacy-tasks-lineage.js.map +1 -1
- package/dist/store/lock.d.ts +1 -0
- package/dist/store/lock.d.ts.map +1 -1
- package/dist/store/lock.js +1 -0
- package/dist/store/lock.js.map +1 -1
- package/dist/store/memory-accessor.d.ts +8 -3
- package/dist/store/memory-accessor.d.ts.map +1 -1
- package/dist/store/memory-accessor.js +29 -13
- package/dist/store/memory-accessor.js.map +1 -1
- package/dist/store/memory-sqlite.d.ts.map +1 -1
- package/dist/store/memory-sqlite.js +5 -0
- package/dist/store/memory-sqlite.js.map +1 -1
- package/dist/store/open-cleo-db.d.ts.map +1 -1
- package/dist/store/open-cleo-db.js +11 -6
- package/dist/store/open-cleo-db.js.map +1 -1
- package/dist/store/portable-bundle-relocate.d.ts +13 -8
- package/dist/store/portable-bundle-relocate.d.ts.map +1 -1
- package/dist/store/portable-bundle-relocate.js +75 -31
- package/dist/store/portable-bundle-relocate.js.map +1 -1
- package/dist/store/portable-bundle-scan.d.ts.map +1 -1
- package/dist/store/portable-bundle-scan.js +2 -1
- package/dist/store/portable-bundle-scan.js.map +1 -1
- package/dist/store/portable-bundle.d.ts.map +1 -1
- package/dist/store/portable-bundle.js +7 -3
- package/dist/store/portable-bundle.js.map +1 -1
- package/dist/store/pre-repair-snapshot.d.ts +77 -0
- package/dist/store/pre-repair-snapshot.d.ts.map +1 -0
- package/dist/store/pre-repair-snapshot.js +122 -0
- package/dist/store/pre-repair-snapshot.js.map +1 -0
- package/dist/store/regenerators.d.ts +2 -1
- package/dist/store/regenerators.d.ts.map +1 -1
- package/dist/store/regenerators.js +17 -3
- package/dist/store/regenerators.js.map +1 -1
- package/dist/store/relocated-store-guard.d.ts +71 -0
- package/dist/store/relocated-store-guard.d.ts.map +1 -0
- package/dist/store/relocated-store-guard.js +138 -0
- package/dist/store/relocated-store-guard.js.map +1 -0
- package/dist/store/safety-data-accessor.d.ts +2 -2
- package/dist/store/safety-data-accessor.d.ts.map +1 -1
- package/dist/store/safety-data-accessor.js +2 -2
- package/dist/store/safety-data-accessor.js.map +1 -1
- package/dist/store/schema/attachments.d.ts +2 -2
- package/dist/store/schema/audit.d.ts +5 -5
- package/dist/store/schema/background-jobs.d.ts +1 -1
- package/dist/store/schema/cleo-global/models-catalog.d.ts +1 -1
- package/dist/store/schema/cleo-global/nexus.d.ts +686 -0
- package/dist/store/schema/cleo-global/nexus.d.ts.map +1 -1
- package/dist/store/schema/cleo-global/nexus.js +175 -7
- package/dist/store/schema/cleo-global/nexus.js.map +1 -1
- package/dist/store/schema/cleo-global/skills.d.ts +2 -2
- package/dist/store/schema/cleo-project/audit.d.ts +5 -5
- package/dist/store/schema/cleo-project/docs.d.ts +3 -3
- package/dist/store/schema/cleo-project/lifecycle.d.ts +3 -3
- package/dist/store/schema/cleo-project/provenance-commits.d.ts +2 -2
- package/dist/store/schema/cleo-project/provenance-rest.d.ts +3 -3
- package/dist/store/schema/cleo-project/tasks-core-batch2.d.ts +1 -1
- package/dist/store/schema/cleo-project/tasks-core.d.ts +6 -6
- package/dist/store/schema/cleo-shared/brain.d.ts +26 -26
- package/dist/store/schema/lifecycle.d.ts +3 -3
- package/dist/store/schema/manifest.d.ts +1 -1
- package/dist/store/schema/memory-schema.d.ts +26 -26
- package/dist/store/schema/nexus-schema.d.ts +696 -2
- package/dist/store/schema/nexus-schema.d.ts.map +1 -1
- package/dist/store/schema/nexus-schema.js +175 -19
- package/dist/store/schema/nexus-schema.js.map +1 -1
- package/dist/store/schema/provenance/releases.d.ts +1 -1
- package/dist/store/schema/skills-schema.d.ts +2 -2
- package/dist/store/schema/tasks.d.ts +5 -5
- package/dist/store/session-binding-schema.d.ts +132 -0
- package/dist/store/session-binding-schema.d.ts.map +1 -0
- package/dist/store/session-binding-schema.js +53 -0
- package/dist/store/session-binding-schema.js.map +1 -0
- package/dist/store/session-store.d.ts +262 -4
- package/dist/store/session-store.d.ts.map +1 -1
- package/dist/store/session-store.js +486 -26
- package/dist/store/session-store.js.map +1 -1
- package/dist/store/snapshot-gate.d.ts +239 -0
- package/dist/store/snapshot-gate.d.ts.map +1 -0
- package/dist/store/snapshot-gate.js +398 -0
- package/dist/store/snapshot-gate.js.map +1 -0
- package/dist/store/split-brain-import.js +2 -2
- package/dist/store/split-brain-import.js.map +1 -1
- package/dist/store/sqlite-backup.d.ts +55 -13
- package/dist/store/sqlite-backup.d.ts.map +1 -1
- package/dist/store/sqlite-backup.js +414 -106
- package/dist/store/sqlite-backup.js.map +1 -1
- package/dist/store/sqlite-data-accessor.d.ts +15 -0
- package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
- package/dist/store/sqlite-data-accessor.js +63 -4
- package/dist/store/sqlite-data-accessor.js.map +1 -1
- package/dist/store/sqlite.d.ts +1 -1
- package/dist/store/sqlite.d.ts.map +1 -1
- package/dist/store/sqlite.js +53 -5
- package/dist/store/sqlite.js.map +1 -1
- package/dist/store/store-write-guard.d.ts +28 -0
- package/dist/store/store-write-guard.d.ts.map +1 -0
- package/dist/store/store-write-guard.js +50 -0
- package/dist/store/store-write-guard.js.map +1 -0
- package/dist/store/table-classification.d.ts +143 -0
- package/dist/store/table-classification.d.ts.map +1 -0
- package/dist/store/table-classification.js +1866 -0
- package/dist/store/table-classification.js.map +1 -0
- package/dist/store/task-version.d.ts +72 -0
- package/dist/store/task-version.d.ts.map +1 -0
- package/dist/store/task-version.js +93 -0
- package/dist/store/task-version.js.map +1 -0
- package/dist/store/tasks-schema.d.ts +1 -0
- package/dist/store/tasks-schema.d.ts.map +1 -1
- package/dist/store/tasks-schema.js +13 -0
- package/dist/store/tasks-schema.js.map +1 -1
- package/dist/store/tasks-sqlite.d.ts +10 -3
- package/dist/store/tasks-sqlite.d.ts.map +1 -1
- package/dist/store/tasks-sqlite.js +12 -3
- package/dist/store/tasks-sqlite.js.map +1 -1
- package/dist/store/twin-collapse.d.ts +275 -0
- package/dist/store/twin-collapse.d.ts.map +1 -0
- package/dist/store/twin-collapse.js +805 -0
- package/dist/store/twin-collapse.js.map +1 -0
- package/dist/store/umbrella-data-accessor.d.ts +2 -2
- package/dist/store/umbrella-data-accessor.d.ts.map +1 -1
- package/dist/store/umbrella-data-accessor.js +2 -2
- package/dist/store/umbrella-data-accessor.js.map +1 -1
- package/dist/store/validation-schemas.d.ts +63 -63
- package/dist/store/worktree-isolation-guard.d.ts +46 -24
- package/dist/store/worktree-isolation-guard.d.ts.map +1 -1
- package/dist/store/worktree-isolation-guard.js +69 -50
- package/dist/store/worktree-isolation-guard.js.map +1 -1
- package/dist/system/backup.d.ts.map +1 -1
- package/dist/system/backup.js +3 -67
- package/dist/system/backup.js.map +1 -1
- package/dist/system/cleo-link.d.ts +163 -0
- package/dist/system/cleo-link.d.ts.map +1 -0
- package/dist/system/cleo-link.js +246 -0
- package/dist/system/cleo-link.js.map +1 -0
- package/dist/system/dependencies.d.ts.map +1 -1
- package/dist/system/dependencies.js +3 -6
- package/dist/system/dependencies.js.map +1 -1
- package/dist/system/global-delivery.d.ts +205 -0
- package/dist/system/global-delivery.d.ts.map +1 -0
- package/dist/system/global-delivery.js +320 -0
- package/dist/system/global-delivery.js.map +1 -0
- package/dist/system/health.d.ts.map +1 -1
- package/dist/system/health.js +29 -6
- package/dist/system/health.js.map +1 -1
- package/dist/system/project-health.d.ts.map +1 -1
- package/dist/system/project-health.js +1 -20
- package/dist/system/project-health.js.map +1 -1
- package/dist/system/runtime.d.ts.map +1 -1
- package/dist/system/runtime.js +2 -12
- package/dist/system/runtime.js.map +1 -1
- package/dist/system/safestop.d.ts.map +1 -1
- package/dist/system/safestop.js +5 -2
- package/dist/system/safestop.js.map +1 -1
- package/dist/system/skill-fixtures.d.ts +200 -0
- package/dist/system/skill-fixtures.d.ts.map +1 -0
- package/dist/system/skill-fixtures.js +331 -0
- package/dist/system/skill-fixtures.js.map +1 -0
- package/dist/tasks/add.d.ts.map +1 -1
- package/dist/tasks/add.js +4 -2
- package/dist/tasks/add.js.map +1 -1
- package/dist/tasks/affected-packages.d.ts +173 -0
- package/dist/tasks/affected-packages.d.ts.map +1 -0
- package/dist/tasks/affected-packages.js +389 -0
- package/dist/tasks/affected-packages.js.map +1 -0
- package/dist/tasks/change-set.d.ts +151 -0
- package/dist/tasks/change-set.d.ts.map +1 -0
- package/dist/tasks/change-set.js +634 -0
- package/dist/tasks/change-set.js.map +1 -0
- package/dist/tasks/complete.d.ts.map +1 -1
- package/dist/tasks/complete.js +10 -5
- package/dist/tasks/complete.js.map +1 -1
- package/dist/tasks/done-plan.d.ts +103 -0
- package/dist/tasks/done-plan.d.ts.map +1 -0
- package/dist/tasks/done-plan.js +541 -0
- package/dist/tasks/done-plan.js.map +1 -0
- package/dist/tasks/done-record.d.ts +127 -0
- package/dist/tasks/done-record.d.ts.map +1 -0
- package/dist/tasks/done-record.js +373 -0
- package/dist/tasks/done-record.js.map +1 -0
- package/dist/tasks/duplicate-detector.d.ts +68 -11
- package/dist/tasks/duplicate-detector.d.ts.map +1 -1
- package/dist/tasks/duplicate-detector.js +314 -58
- package/dist/tasks/duplicate-detector.js.map +1 -1
- package/dist/tasks/evidence-paths.d.ts +78 -0
- package/dist/tasks/evidence-paths.d.ts.map +1 -0
- package/dist/tasks/evidence-paths.js +150 -0
- package/dist/tasks/evidence-paths.js.map +1 -0
- package/dist/tasks/evidence.d.ts +55 -0
- package/dist/tasks/evidence.d.ts.map +1 -1
- package/dist/tasks/evidence.js +223 -26
- package/dist/tasks/evidence.js.map +1 -1
- package/dist/tasks/gate-preview.d.ts +5 -0
- package/dist/tasks/gate-preview.d.ts.map +1 -1
- package/dist/tasks/gate-preview.js +25 -21
- package/dist/tasks/gate-preview.js.map +1 -1
- package/dist/tasks/gate-result-cache.d.ts +205 -0
- package/dist/tasks/gate-result-cache.d.ts.map +1 -0
- package/dist/tasks/gate-result-cache.js +285 -0
- package/dist/tasks/gate-result-cache.js.map +1 -0
- package/dist/tasks/gate-runner.d.ts +126 -3
- package/dist/tasks/gate-runner.d.ts.map +1 -1
- package/dist/tasks/gate-runner.js +483 -28
- package/dist/tasks/gate-runner.js.map +1 -1
- package/dist/tasks/session-scope.d.ts +3 -1
- package/dist/tasks/session-scope.d.ts.map +1 -1
- package/dist/tasks/session-scope.js +18 -3
- package/dist/tasks/session-scope.js.map +1 -1
- package/dist/tasks/tool-resolver.d.ts +23 -6
- package/dist/tasks/tool-resolver.d.ts.map +1 -1
- package/dist/tasks/tool-resolver.js +146 -8
- package/dist/tasks/tool-resolver.js.map +1 -1
- package/dist/tasks/tool-vacuity.d.ts +71 -0
- package/dist/tasks/tool-vacuity.d.ts.map +1 -0
- package/dist/tasks/tool-vacuity.js +334 -0
- package/dist/tasks/tool-vacuity.js.map +1 -0
- package/dist/tasks/update.d.ts +8 -0
- package/dist/tasks/update.d.ts.map +1 -1
- package/dist/tasks/update.js +159 -78
- package/dist/tasks/update.js.map +1 -1
- package/dist/upgrade.d.ts.map +1 -1
- package/dist/upgrade.js +18 -2
- package/dist/upgrade.js.map +1 -1
- package/dist/validation/doctor/checks.d.ts +20 -2
- package/dist/validation/doctor/checks.d.ts.map +1 -1
- package/dist/validation/doctor/checks.js +64 -4
- package/dist/validation/doctor/checks.js.map +1 -1
- package/dist/validation/doctor/index.d.ts +1 -1
- package/dist/validation/doctor/index.d.ts.map +1 -1
- package/dist/validation/doctor/index.js +1 -1
- package/dist/validation/doctor/index.js.map +1 -1
- package/dist/validation/doctor/utils.d.ts.map +1 -1
- package/dist/validation/doctor/utils.js +7 -2
- package/dist/validation/doctor/utils.js.map +1 -1
- package/dist/validation/engine-ops.d.ts +15 -0
- package/dist/validation/engine-ops.d.ts.map +1 -1
- package/dist/validation/engine-ops.js +249 -98
- package/dist/validation/engine-ops.js.map +1 -1
- package/migrations/drizzle-cleo-global/20260927000000_t12469-project-locations/migration.sql +121 -0
- package/migrations/drizzle-cleo-global/20260927010000_t12543-user-profile-project-scope/migration.sql +23 -0
- package/migrations/drizzle-cleo-global/20260928010000_t12470-location-candidates/migration.sql +72 -0
- package/migrations/drizzle-cleo-global/20260928020000_t12510-nexus-devices/migration.sql +34 -0
- package/migrations/drizzle-cleo-global/20260928030000_t12511-project-git-state/migration.sql +62 -0
- package/migrations/drizzle-cleo-project/20260927000000_t12499-session-terminal-bindings/migration.sql +34 -0
- package/migrations/drizzle-cleo-project/20260928000000_t12500-binding-provider-flag/migration.sql +15 -0
- package/package.json +23 -13
- package/schemas/config.schema.json +54 -0
- package/schemas/project-context.schema.json +51 -3
- package/schemas/project-info.schema.json +28 -1
- package/templates/CLEO-INJECTION.md +40 -332
- package/templates/CLEO-REFERENCE.md +303 -0
- package/templates/workflows/README.md +36 -14
|
@@ -12,20 +12,26 @@
|
|
|
12
12
|
*
|
|
13
13
|
* Design constraints:
|
|
14
14
|
* - Each gate is self-contained (no cross-gate state).
|
|
15
|
-
* - Gates run sequentially under
|
|
16
|
-
*
|
|
15
|
+
* - Gates run sequentially under ONE captured operation deadline. The caller admits it
|
|
16
|
+
* with {@link typedGateAdmissionMs}: the ADR-061 tool deadline of every executing gate
|
|
17
|
+
* plus {@link TYPED_GATE_BOOKKEEPING_MS} for the surrounding bookkeeping (T12516).
|
|
18
|
+
* - Per-gate timeouts can only tighten the captured deadline, never renew it.
|
|
19
|
+
* - Passing process gates can be served from the ADR-061 evidence cache
|
|
20
|
+
* (`options.cache`, see `gate-result-cache.ts`); failures are never cached (T12621).
|
|
17
21
|
* - Structured test-count evidence and HTTP service startup require separate capabilities.
|
|
18
22
|
* - Results are observations; this module does not persist completion authority.
|
|
19
23
|
*
|
|
20
24
|
* @epic T760
|
|
21
25
|
* @task T781
|
|
22
26
|
*/
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
27
|
+
import { execFileSync } from 'node:child_process';
|
|
28
|
+
import { createHash, randomBytes, randomUUID } from 'node:crypto';
|
|
29
|
+
import { constants, mkdirSync, readFileSync, realpathSync, renameSync, writeFileSync, } from 'node:fs';
|
|
25
30
|
import { lstat, open, realpath, stat } from 'node:fs/promises';
|
|
26
31
|
import { basename, dirname, isAbsolute, join, relative, resolve } from 'node:path';
|
|
27
32
|
import { isDeepStrictEqual } from 'node:util';
|
|
28
33
|
import { acceptanceGateResultSchema, acceptanceGateSchema, testCountReportSchema, } from '@cleocode/contracts';
|
|
34
|
+
import { gitToplevel } from '../git/work-tree.js';
|
|
29
35
|
import { getProjectRoot } from '../paths.js';
|
|
30
36
|
import { captureProjectScope, worktreeScope } from '../project-scope.js';
|
|
31
37
|
import { truncateString } from '../render/helpers.js';
|
|
@@ -33,14 +39,237 @@ import { captureWrapped } from '../resources/spawn-wrapper.js';
|
|
|
33
39
|
import { createAttachmentStore } from '../store/attachment-store.js';
|
|
34
40
|
import { registerTeardownAbort } from '../teardown-signal.js';
|
|
35
41
|
import { acItemToText, acTextHash } from './ac-table.js';
|
|
42
|
+
import { resolveCanonicalProjectRoot } from './evidence.js';
|
|
43
|
+
import { buildGateCacheEntryBody, captureGateCacheState, evidenceCacheKeyPath, gateCacheEntryPath, readGateCacheEntry, sealGateCacheEntry, } from './gate-result-cache.js';
|
|
36
44
|
import { heavyToolEnv } from './heavy-tool-env.js';
|
|
45
|
+
import { resolveSpawnTimeoutMs } from './tool-cache.js';
|
|
37
46
|
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
38
|
-
/**
|
|
39
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Shared budget for the bookkeeping around typed gates: task and criterion
|
|
49
|
+
* reads, input snapshots, result binding and the persisting transaction.
|
|
50
|
+
*
|
|
51
|
+
* It is the same two seconds the maintenance paths use, and it is ADDED to the
|
|
52
|
+
* tool deadlines rather than bounding them. Before T12516 it was the whole
|
|
53
|
+
* lifetime of a typed verification, so any gate whose tool ran longer than two
|
|
54
|
+
* seconds — every real test suite — stopped with `E_OPERATION_DEADLINE`.
|
|
55
|
+
*
|
|
56
|
+
* @task T12516
|
|
57
|
+
*/
|
|
58
|
+
export const TYPED_GATE_BOOKKEEPING_MS = 2000;
|
|
59
|
+
/** Gate kinds that execute a tool (a process or a request) and so carry an ADR-061 deadline. */
|
|
60
|
+
const TOOL_GATE_KINDS = new Set([
|
|
61
|
+
'test',
|
|
62
|
+
'command',
|
|
63
|
+
'lint',
|
|
64
|
+
'http',
|
|
65
|
+
]);
|
|
40
66
|
/** Maximum evidence string character count retained per gate result. */
|
|
41
67
|
const MAX_EVIDENCE_CHARS = 2_000;
|
|
42
68
|
/** Agent identifier written into `checkedBy`. */
|
|
43
69
|
const CHECKED_BY = process.env['CLEO_AGENT_ID'] ?? 'cleo-verify';
|
|
70
|
+
/**
|
|
71
|
+
* Resolve the wall-clock deadline for one gate's tool execution.
|
|
72
|
+
*
|
|
73
|
+
* Precedence: the gate's own `timeoutMs`; then the legacy blanket
|
|
74
|
+
* `CLEO_GATE_TIMEOUT_MS`; then the ADR-061 tool deadline for the gate kind,
|
|
75
|
+
* resolved by {@link resolveSpawnTimeoutMs} — `CLEO_TOOL_TIMEOUT_<KIND>`, else
|
|
76
|
+
* 1,800,000 ms for `test` and 300,000 ms for every other kind.
|
|
77
|
+
*
|
|
78
|
+
* @param gate - Gate whose tool deadline is needed.
|
|
79
|
+
* @param env - Environment to read the overrides from.
|
|
80
|
+
* @returns Deadline in milliseconds.
|
|
81
|
+
* @throws When a declared or configured deadline is not a positive safe integer.
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* resolveGateTimeoutMs({ kind: 'test', description: 'suite', command: 'npm', args: ['test'], expect: 'exit0' }); // 1_800_000
|
|
85
|
+
* ```
|
|
86
|
+
* @task T12516
|
|
87
|
+
*/
|
|
88
|
+
export function resolveGateTimeoutMs(gate, env = process.env) {
|
|
89
|
+
const legacy = env['CLEO_GATE_TIMEOUT_MS']?.trim();
|
|
90
|
+
const timeout = gate.timeoutMs ??
|
|
91
|
+
(legacy ? Number(legacy) : undefined) ??
|
|
92
|
+
resolveSpawnTimeoutMs(gate.kind, env);
|
|
93
|
+
if (!Number.isSafeInteger(timeout) || timeout < 1)
|
|
94
|
+
throw new Error('Gate timeout must be a positive safe integer');
|
|
95
|
+
return timeout;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Wall-clock lifetime to admit for running a set of typed gates.
|
|
99
|
+
*
|
|
100
|
+
* The sum of every tool-executing gate's ADR-061 deadline plus
|
|
101
|
+
* {@link TYPED_GATE_BOOKKEEPING_MS}. Callers that own the operation lifetime
|
|
102
|
+
* create it with this budget so the two-second shared budget covers the
|
|
103
|
+
* bookkeeping only and never bounds a tool (T12516).
|
|
104
|
+
*
|
|
105
|
+
* @param gates - Gates that will run.
|
|
106
|
+
* @param env - Environment to read deadline overrides from.
|
|
107
|
+
* @returns Budget in milliseconds, clamped to the safe-integer range.
|
|
108
|
+
* @throws When a gate deadline override is invalid (see {@link resolveGateTimeoutMs}).
|
|
109
|
+
* @example
|
|
110
|
+
* ```typescript
|
|
111
|
+
* const execution = createOperationExecutionContext(identity, { budgetMs: typedGateAdmissionMs(gates) });
|
|
112
|
+
* ```
|
|
113
|
+
* @task T12516
|
|
114
|
+
*/
|
|
115
|
+
export function typedGateAdmissionMs(gates, env = process.env) {
|
|
116
|
+
const total = gates.reduce((sum, gate) => sum + (TOOL_GATE_KINDS.has(gate.kind) ? resolveGateTimeoutMs(gate, env) : 0), TYPED_GATE_BOOKKEEPING_MS);
|
|
117
|
+
return Math.min(total, Number.MAX_SAFE_INTEGER);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Actionable refusal for `cache: 'only'` (`cleo verify --no-run`) when a gate
|
|
121
|
+
* would have to execute. Names the gate and the command that fills the cache.
|
|
122
|
+
*/
|
|
123
|
+
function gateNotCachedMessage(gate, cacheable, keyAvailable) {
|
|
124
|
+
const name = gate.req ?? gate.description;
|
|
125
|
+
if (gate.kind === 'http')
|
|
126
|
+
return `${GATE_NOT_CACHED_PREFIX} http gate "${name}" observes a live service and is never cached; drop --no-run to execute it`;
|
|
127
|
+
if (!cacheable)
|
|
128
|
+
return `${GATE_NOT_CACHED_PREFIX} gate "${name}" has no cached result because the project root is not a git checkout (results are keyed by HEAD + dirty-tree fingerprint); drop --no-run to execute it`;
|
|
129
|
+
if (!keyAvailable)
|
|
130
|
+
return `${GATE_NOT_CACHED_PREFIX} gate "${name}" cannot use the cache because the machine key ${evidenceCacheKeyPath()} is unreadable; drop --no-run to execute it`;
|
|
131
|
+
return (`${GATE_NOT_CACHED_PREFIX} gate "${name}" has no cached pass for the current HEAD, working tree and inputs. ` +
|
|
132
|
+
'Run `cleo verify <taskId> --run` first (it caches passing results), or drop --no-run to execute it now');
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Prefix of the `errorMessage` a gate carries when `cache: 'only'` refused to
|
|
136
|
+
* execute it. The verifier matches it to refuse the whole write with
|
|
137
|
+
* `E_GATE_NOT_CACHED` instead of recording an `error` result.
|
|
138
|
+
* @task T12621
|
|
139
|
+
*/
|
|
140
|
+
export const GATE_NOT_CACHED_PREFIX = '--no-run:';
|
|
141
|
+
/**
|
|
142
|
+
* Prefix of the `errorMessage` a gate carries when `cache: 'only'` found an
|
|
143
|
+
* entry that failed authentication. The verifier refuses the write with
|
|
144
|
+
* `E_GATE_CACHE_INVALID`: a forged or tampered pass is never recorded.
|
|
145
|
+
* @task T12621
|
|
146
|
+
*/
|
|
147
|
+
export const GATE_CACHE_INVALID_PREFIX = '--no-run [invalid cache entry]:';
|
|
148
|
+
/**
|
|
149
|
+
* Load (creating on first use, mode 0600) the per-machine key that seals
|
|
150
|
+
* evidence cache entries. Deliberately NOT exported: a caller that could load
|
|
151
|
+
* the key through core could seal any result it liked, which is the forgery
|
|
152
|
+
* this key exists to stop. Returns `null` when the key cannot be established;
|
|
153
|
+
* the cache is then simply not used.
|
|
154
|
+
*/
|
|
155
|
+
function loadEvidenceCacheKey() {
|
|
156
|
+
const path = evidenceCacheKeyPath();
|
|
157
|
+
try {
|
|
158
|
+
mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
|
|
159
|
+
try {
|
|
160
|
+
writeFileSync(path, randomBytes(32).toString('hex'), { flag: 'wx', mode: 0o600 });
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
if (error.code !== 'EEXIST')
|
|
164
|
+
throw error;
|
|
165
|
+
}
|
|
166
|
+
const hex = readFileSync(path, 'utf-8').trim();
|
|
167
|
+
return /^[0-9a-f]{64}$/.test(hex) ? Buffer.from(hex, 'hex') : null;
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Seal and store a pass this runner EXECUTED itself. Module-private for the same
|
|
175
|
+
* reason as {@link loadEvidenceCacheKey}: only an observed execution is cached.
|
|
176
|
+
*/
|
|
177
|
+
function writeExecutedGatePass(projectRoot, gate, state, inputsHash, observed, key) {
|
|
178
|
+
const body = buildGateCacheEntryBody(gate, state, inputsHash, observed);
|
|
179
|
+
if (!body)
|
|
180
|
+
return;
|
|
181
|
+
try {
|
|
182
|
+
const path = gateCacheEntryPath(projectRoot, gate, state, inputsHash);
|
|
183
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
184
|
+
const tmp = `${path}.${process.pid}.tmp`;
|
|
185
|
+
writeFileSync(tmp, JSON.stringify(sealGateCacheEntry(body, key), null, 2), 'utf-8');
|
|
186
|
+
renameSync(tmp, path);
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
// A cache is an optimisation: failing to persist one never fails the gate.
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Digest of a gate's captured invocation and input artifacts: the part of its
|
|
194
|
+
* cache key that the git fingerprint cannot see (untracked harness scripts,
|
|
195
|
+
* task files, the environment hash).
|
|
196
|
+
*/
|
|
197
|
+
function gateInputsHash(invocation, artifacts) {
|
|
198
|
+
return createHash('sha256')
|
|
199
|
+
.update(JSON.stringify({ invocation: invocation ?? null, artifacts }))
|
|
200
|
+
.digest('hex');
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Compute a gate's cache inputs digest the same way the attesting verifier does.
|
|
204
|
+
* @param task - Task that owns the gate; its `files` are verifier inputs.
|
|
205
|
+
* @param gate - Gate whose invocation and inputs are captured.
|
|
206
|
+
* @param execution - Admitted lifetime whose project root scopes the capture.
|
|
207
|
+
* @param env - Environment the gate will launch with.
|
|
208
|
+
* @returns Digest to pass as `cacheInputsHash` to {@link runGates}.
|
|
209
|
+
* @example
|
|
210
|
+
* ```typescript
|
|
211
|
+
* const cacheInputsHash = await captureGateInputsHash(task, gate, execution);
|
|
212
|
+
* ```
|
|
213
|
+
* @task T12621
|
|
214
|
+
*/
|
|
215
|
+
export async function captureGateInputsHash(task, gate, execution, env = process.env) {
|
|
216
|
+
const tree = resolveTypedGateRoot(resolve(execution.identity.projectRoot));
|
|
217
|
+
const invocation = executableInvocation(gate, tree, { ...env });
|
|
218
|
+
return gateInputsHash(invocation, await snapshotGateInputs(task, gate, invocation, execution, tree));
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* The tree a typed gate runs in and is fingerprinted against.
|
|
222
|
+
*
|
|
223
|
+
* `projectRoot` is the CLEO store root, which for a git worktree is the MAIN
|
|
224
|
+
* checkout (all worktrees share one `.cleo/`). Evidence tools already run in the
|
|
225
|
+
* caller's own worktree (gh#1220); typed gates ran in the store root, so from a
|
|
226
|
+
* worktree `cleo done` measured the task's code with its tools and the main
|
|
227
|
+
* checkout with its typed gates (T12625 review). The caller's git toplevel is
|
|
228
|
+
* used only when it is a linked worktree OF THIS project — any other cwd
|
|
229
|
+
* (an unrelated repo, a test harness, a declared child repo in a multi-repo
|
|
230
|
+
* root) keeps `projectRoot`, so typed-gate paths written against the CLEO root
|
|
231
|
+
* keep resolving exactly as before.
|
|
232
|
+
*
|
|
233
|
+
* Known limit (documented, accepted): "linked worktree of this project" is read
|
|
234
|
+
* from the `.git` gitlink, so a plain directory carrying a forged gitlink that
|
|
235
|
+
* points into this project's `.git/worktrees/` is treated as a worktree. That
|
|
236
|
+
* grants nothing a copy of the checkout would not: its typed results are only
|
|
237
|
+
* carried to another tree by content (tracked inputs must hash identically and
|
|
238
|
+
* the recorded HEAD must be merged there).
|
|
239
|
+
*
|
|
240
|
+
* @param projectRoot - CLEO store root (the typed gate's authority).
|
|
241
|
+
* @param cwd - Invocation directory. Defaults to `process.cwd()`.
|
|
242
|
+
* @returns The realpath of the tree typed gates execute in.
|
|
243
|
+
* @task T12625
|
|
244
|
+
*/
|
|
245
|
+
export function resolveTypedGateRoot(projectRoot, cwd = process.cwd()) {
|
|
246
|
+
const real = (p) => {
|
|
247
|
+
try {
|
|
248
|
+
return realpathSync(p);
|
|
249
|
+
}
|
|
250
|
+
catch {
|
|
251
|
+
return resolve(p);
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
const root = real(projectRoot);
|
|
255
|
+
const top = gitToplevel(cwd);
|
|
256
|
+
if (top === null || real(top) === root)
|
|
257
|
+
return projectRoot;
|
|
258
|
+
return real(resolveCanonicalProjectRoot(top)) === root ? real(top) : projectRoot;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Admission for a batch run without a caller-owned lifetime.
|
|
262
|
+
* An invalid deadline override is not swallowed: {@link runOneGate} resolves it
|
|
263
|
+
* again and reports it as that gate's `error` result, as it always has.
|
|
264
|
+
*/
|
|
265
|
+
function unownedAdmissionMs(gates, env) {
|
|
266
|
+
try {
|
|
267
|
+
return typedGateAdmissionMs(gates, env);
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
return TYPED_GATE_BOOKKEEPING_MS;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
44
273
|
/**
|
|
45
274
|
* Execute all typed `AcceptanceGate` entries and return results.
|
|
46
275
|
*
|
|
@@ -79,14 +308,16 @@ export async function runGates(gates, options = {}) {
|
|
|
79
308
|
const maxOutputBytes = options.maxOutputBytes ?? 1_048_576;
|
|
80
309
|
if (!Number.isSafeInteger(maxOutputBytes) || maxOutputBytes < 1)
|
|
81
310
|
throw new RangeError('Gate capture byte limit must be a positive safe integer');
|
|
311
|
+
// T12625: execute and fingerprint in the caller's worktree of this project.
|
|
312
|
+
const treeRoot = resolveTypedGateRoot(projectRoot);
|
|
82
313
|
const snapshot = structuredClone(gates);
|
|
83
314
|
const controller = new AbortController();
|
|
84
315
|
const deregister = registerTeardownAbort(controller);
|
|
85
316
|
const batch = {
|
|
86
|
-
cwd:
|
|
317
|
+
cwd: treeRoot,
|
|
87
318
|
env: { ...(options.env ?? process.env) },
|
|
88
319
|
execution: {
|
|
89
|
-
deadlineAt: execution?.deadlineAt ?? Date.now() +
|
|
320
|
+
deadlineAt: execution?.deadlineAt ?? Date.now() + unownedAdmissionMs(snapshot, options.env),
|
|
90
321
|
signal: execution
|
|
91
322
|
? AbortSignal.any([execution.signal, controller.signal])
|
|
92
323
|
: controller.signal,
|
|
@@ -97,6 +328,15 @@ export async function runGates(gates, options = {}) {
|
|
|
97
328
|
systemdControl: options.systemdControl,
|
|
98
329
|
};
|
|
99
330
|
const checkedBy = execution?.identity.actor ?? batch.env['CLEO_AGENT_ID'] ?? CHECKED_BY;
|
|
331
|
+
const cacheMode = options.cache ?? 'off';
|
|
332
|
+
const cacheInputsHash = options.cacheInputsHash;
|
|
333
|
+
if (cacheMode !== 'off' && (snapshot.length !== 1 || !cacheInputsHash))
|
|
334
|
+
throw new Error('Typed gate caching requires one gate per batch and its inputs digest');
|
|
335
|
+
// T12621: the repo state is captured only when the policy reads or writes.
|
|
336
|
+
const cacheState = cacheMode !== 'off' && TOOL_GATE_KINDS.has(snapshot[0].kind)
|
|
337
|
+
? await captureGateCacheState(treeRoot)
|
|
338
|
+
: null;
|
|
339
|
+
const cacheKey = cacheState ? loadEvidenceCacheKey() : null;
|
|
100
340
|
const results = [];
|
|
101
341
|
try {
|
|
102
342
|
return await worktreeScope.run(scope, async () => {
|
|
@@ -113,7 +353,34 @@ export async function runGates(gates, options = {}) {
|
|
|
113
353
|
const parsed = acceptanceGateSchema.parse(gate);
|
|
114
354
|
if (!isDeepStrictEqual(parsed, gate))
|
|
115
355
|
throw new Error('Gate includes unsupported or noncanonical fields');
|
|
116
|
-
|
|
356
|
+
if (cacheState && cacheKey && (cacheMode === 'use' || cacheMode === 'only')) {
|
|
357
|
+
const lookup = readGateCacheEntry(projectRoot, parsed, cacheState, cacheInputsHash, cacheKey);
|
|
358
|
+
if (lookup.status === 'hit') {
|
|
359
|
+
// Re-dated to now (the reuse is this run's check; a bound result
|
|
360
|
+
// may not precede its input capture) and marked, never disguised.
|
|
361
|
+
results.push({
|
|
362
|
+
...lookup.observation,
|
|
363
|
+
index: i,
|
|
364
|
+
checkedAt: new Date().toISOString(),
|
|
365
|
+
source: 'cache',
|
|
366
|
+
cachedAt: lookup.createdAt,
|
|
367
|
+
});
|
|
368
|
+
continue;
|
|
369
|
+
}
|
|
370
|
+
// `use` treats an unauthenticated entry as a miss and overwrites it.
|
|
371
|
+
if (lookup.status === 'invalid' && cacheMode === 'only')
|
|
372
|
+
throw new Error(`${GATE_CACHE_INVALID_PREFIX} gate "${parsed.req ?? parsed.description}": ${lookup.reason}. ` +
|
|
373
|
+
'It was not used. Drop --no-run to execute the gate (a pass replaces the entry)');
|
|
374
|
+
}
|
|
375
|
+
if (cacheMode === 'only' && TOOL_GATE_KINDS.has(parsed.kind))
|
|
376
|
+
throw new Error(gateNotCachedMessage(parsed, cacheState !== null, cacheKey !== null));
|
|
377
|
+
const observed = {
|
|
378
|
+
...(await runOneGate(parsed, i, treeRoot, options.skipManual ?? true, batch, projectRoot)),
|
|
379
|
+
source: 'executed',
|
|
380
|
+
};
|
|
381
|
+
if (cacheState && cacheKey && cacheMode !== 'only')
|
|
382
|
+
writeExecutedGatePass(projectRoot, parsed, cacheState, cacheInputsHash, observed, cacheKey);
|
|
383
|
+
results.push(observed);
|
|
117
384
|
}
|
|
118
385
|
catch (error) {
|
|
119
386
|
results.push(makeResult(i, gate, 'error', Date.now() - startMs, undefined, error instanceof Error ? error.message : String(error)));
|
|
@@ -126,6 +393,151 @@ export async function runGates(gates, options = {}) {
|
|
|
126
393
|
deregister();
|
|
127
394
|
}
|
|
128
395
|
}
|
|
396
|
+
/** `git` read in `cwd`; `null` on a non-zero exit or when git is unavailable. */
|
|
397
|
+
function gitOut(cwd, args) {
|
|
398
|
+
try {
|
|
399
|
+
return execFileSync('git', args, {
|
|
400
|
+
cwd,
|
|
401
|
+
encoding: 'utf-8',
|
|
402
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
403
|
+
}).trim();
|
|
404
|
+
}
|
|
405
|
+
catch {
|
|
406
|
+
return null;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
/** Digest of a gate's inputs with every path made relative to `tree` (T12625). */
|
|
410
|
+
function treeInputsHash(tree, invocation, artifacts) {
|
|
411
|
+
const rel = (path) => relative(tree, path) || '.';
|
|
412
|
+
return createHash('sha256')
|
|
413
|
+
.update(JSON.stringify({
|
|
414
|
+
invocation: invocation ? { ...invocation, cwd: rel(invocation.cwd) } : null,
|
|
415
|
+
artifacts: artifacts.map((a) => ({ ...a, path: rel(a.path) })),
|
|
416
|
+
}))
|
|
417
|
+
.digest('hex');
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Content binding for a result verified in `tree`, or `undefined` when the tree
|
|
421
|
+
* is not a git checkout (the result then keeps exact path-bound revalidation).
|
|
422
|
+
*/
|
|
423
|
+
function captureTreeBinding(tree, invocation, artifacts) {
|
|
424
|
+
const headSha = gitOut(tree, ['rev-parse', 'HEAD']);
|
|
425
|
+
if (headSha === null || !/^[0-9a-f]{40}$/.test(headSha))
|
|
426
|
+
return undefined;
|
|
427
|
+
const dirty = gitOut(tree, ['status', '--porcelain', '--untracked-files=no']);
|
|
428
|
+
const base = originDefault(tree);
|
|
429
|
+
const baseSha = base ? gitOut(tree, ['merge-base', base, headSha]) : null;
|
|
430
|
+
return {
|
|
431
|
+
headSha,
|
|
432
|
+
clean: dirty === '',
|
|
433
|
+
cwd: invocation ? relative(tree, invocation.cwd) || '.' : '.',
|
|
434
|
+
inputsHash: treeInputsHash(tree, invocation, artifacts),
|
|
435
|
+
...(baseSha && /^[0-9a-f]{40}$/.test(baseSha) ? { baseSha } : {}),
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
/** `origin/<default>` from `origin/HEAD`, else origin/main or origin/master. */
|
|
439
|
+
function originDefault(tree) {
|
|
440
|
+
const symbolic = gitOut(tree, ['symbolic-ref', '--quiet', 'refs/remotes/origin/HEAD']);
|
|
441
|
+
if (symbolic)
|
|
442
|
+
return symbolic.replace(/^refs\/remotes\//, '');
|
|
443
|
+
for (const ref of ['origin/main', 'origin/master']) {
|
|
444
|
+
if (gitOut(tree, ['rev-parse', '--verify', '--quiet', `refs/remotes/${ref}`]) !== null)
|
|
445
|
+
return ref;
|
|
446
|
+
}
|
|
447
|
+
return null;
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* A typed result was verified in another tree of this project and cannot be
|
|
451
|
+
* accepted from the completing tree. Carries the exact re-verify command.
|
|
452
|
+
*
|
|
453
|
+
* @task T12625
|
|
454
|
+
*/
|
|
455
|
+
export class TypedRevalidationError extends Error {
|
|
456
|
+
/** The command that re-verifies the task's typed gates in the completing tree. */
|
|
457
|
+
fix;
|
|
458
|
+
constructor(message, fix) {
|
|
459
|
+
super(message);
|
|
460
|
+
this.name = 'TypedRevalidationError';
|
|
461
|
+
this.fix = fix;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
/** Exact command that re-records testsPassed (re-running typed gates) in `tree`. */
|
|
465
|
+
function reverifyCommand(task, tree) {
|
|
466
|
+
const atoms = (task.verification?.evidence?.testsPassed?.atoms ?? []).flatMap((atom) => {
|
|
467
|
+
switch (atom.kind) {
|
|
468
|
+
case 'tool':
|
|
469
|
+
return [`tool:${atom.tool}`];
|
|
470
|
+
case 'test-run':
|
|
471
|
+
return [`test-run:${atom.path}`];
|
|
472
|
+
case 'satisfies':
|
|
473
|
+
return [
|
|
474
|
+
`satisfies:${atom.targetTaskId}#${atom.targetAcAlias ?? atom.resolvedAcUuid ?? ''}`,
|
|
475
|
+
];
|
|
476
|
+
default:
|
|
477
|
+
return [];
|
|
478
|
+
}
|
|
479
|
+
});
|
|
480
|
+
const evidence = atoms.length > 0 ? atoms.join(';') : 'tool:test';
|
|
481
|
+
return `cd '${tree.replace(/'/g, `'\\''`)}' && cleo verify ${task.id} --gate testsPassed --evidence '${evidence}'`;
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Accept a result bound in ANOTHER tree of this project (T12625): the verified
|
|
485
|
+
* tree was clean, its HEAD is an ancestor of the completing HEAD (the verified
|
|
486
|
+
* commit has been merged here), and the inputs recompute to the same
|
|
487
|
+
* tree-relative digest. The recorded tree itself is never entered — worktrees
|
|
488
|
+
* are auto-cleaned after merge.
|
|
489
|
+
*/
|
|
490
|
+
function assertTreeEquivalent(task, gateLabel, bound, tree, projectRoot, invocation, artifacts) {
|
|
491
|
+
const fix = reverifyCommand(task, tree);
|
|
492
|
+
const real = (p) => {
|
|
493
|
+
try {
|
|
494
|
+
return realpathSync(p);
|
|
495
|
+
}
|
|
496
|
+
catch {
|
|
497
|
+
return resolve(p);
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
if (real(resolveCanonicalProjectRoot(tree)) !== real(projectRoot))
|
|
501
|
+
throw new TypedRevalidationError(`Typed requirement ${gateLabel}: ${tree} is not a checkout of this project`, fix);
|
|
502
|
+
if (!bound.clean)
|
|
503
|
+
throw new TypedRevalidationError(`Typed requirement ${gateLabel} was verified on a dirty tree at ${bound.headSha.slice(0, 12)}; its result cannot be carried to ${tree}`, fix);
|
|
504
|
+
if (gitOut(tree, ['merge-base', '--is-ancestor', bound.headSha, 'HEAD']) === null)
|
|
505
|
+
throw new TypedRevalidationError(`Typed requirement ${gateLabel} was verified at ${bound.headSha.slice(0, 12)}, which is not in ${tree}'s HEAD — merge the verified commit first, or re-verify here`, fix);
|
|
506
|
+
if (treeInputsHash(tree, invocation, artifacts) !== bound.inputsHash)
|
|
507
|
+
throw new TypedRevalidationError(`Typed requirement ${gateLabel} inputs changed since verification (${tree})`, fix);
|
|
508
|
+
// Round 3: the merge being an ancestor proves the change ARRIVED, not that it
|
|
509
|
+
// is still there — a later revert leaves the ancestry and the declared gate
|
|
510
|
+
// inputs intact. Every path the verified change touched must still hold the
|
|
511
|
+
// verified bytes here. Without a recorded fork point the change set is
|
|
512
|
+
// unknown, so the result is not carried across trees at all.
|
|
513
|
+
if (!bound.baseSha)
|
|
514
|
+
throw new TypedRevalidationError(`Typed requirement ${gateLabel} has no recorded fork point, so the verified change cannot be compared in ${tree}`, fix);
|
|
515
|
+
// --no-renames: a rename is listed as the old path's deletion AND the new
|
|
516
|
+
// path's addition, so a renamed-away path later re-added here is caught.
|
|
517
|
+
const changed = gitOut(tree, [
|
|
518
|
+
'diff',
|
|
519
|
+
'--name-only',
|
|
520
|
+
'--no-renames',
|
|
521
|
+
bound.baseSha,
|
|
522
|
+
bound.headSha,
|
|
523
|
+
]);
|
|
524
|
+
if (changed === null)
|
|
525
|
+
throw new TypedRevalidationError(`Typed requirement ${gateLabel}: cannot read the verified change ${bound.baseSha.slice(0, 12)}..${bound.headSha.slice(0, 12)} in ${tree}`, fix);
|
|
526
|
+
const paths = changed.split('\n').filter(Boolean);
|
|
527
|
+
if (paths.length > 0) {
|
|
528
|
+
const drift = gitOut(tree, [
|
|
529
|
+
'diff',
|
|
530
|
+
'--name-only',
|
|
531
|
+
'--no-renames',
|
|
532
|
+
bound.headSha,
|
|
533
|
+
'HEAD',
|
|
534
|
+
'--',
|
|
535
|
+
...paths,
|
|
536
|
+
]);
|
|
537
|
+
if (drift === null || drift !== '')
|
|
538
|
+
throw new TypedRevalidationError(`Typed requirement ${gateLabel}: the verified change was changed on ${tree} since verification: ${(drift ?? 'unreadable').split('\n').join(', ')}`, fix);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
129
541
|
/**
|
|
130
542
|
* Run task requirements with their canonical AC and bounded input snapshots.
|
|
131
543
|
* @param task - Captured task, including its complete mixed acceptance array.
|
|
@@ -154,6 +566,7 @@ export async function runTaskGates(task, criteria, options) {
|
|
|
154
566
|
assertCriterionProjection(snapshot, rows);
|
|
155
567
|
const env = { ...(options.env ?? process.env) };
|
|
156
568
|
const verificationId = randomUUID();
|
|
569
|
+
const tree = resolveTypedGateRoot(root);
|
|
157
570
|
return worktreeScope.run(scope, async () => {
|
|
158
571
|
const results = [];
|
|
159
572
|
for (const [index, gate] of (snapshot.acceptance ?? []).entries()) {
|
|
@@ -161,8 +574,8 @@ export async function runTaskGates(task, criteria, options) {
|
|
|
161
574
|
continue;
|
|
162
575
|
execution.assertActive();
|
|
163
576
|
const capturedAt = new Date().toISOString();
|
|
164
|
-
const invocation = executableInvocation(gate,
|
|
165
|
-
const artifacts = await snapshotGateInputs(snapshot, gate, invocation, execution);
|
|
577
|
+
const invocation = executableInvocation(gate, tree, env);
|
|
578
|
+
const artifacts = await snapshotGateInputs(snapshot, gate, invocation, execution, tree);
|
|
166
579
|
const binding = {
|
|
167
580
|
version: 1,
|
|
168
581
|
verificationId,
|
|
@@ -176,10 +589,21 @@ export async function runTaskGates(task, criteria, options) {
|
|
|
176
589
|
...(invocation ? { invocation } : {}),
|
|
177
590
|
artifacts,
|
|
178
591
|
};
|
|
179
|
-
const
|
|
592
|
+
const treeBinding = captureTreeBinding(tree, invocation, artifacts);
|
|
593
|
+
if (treeBinding)
|
|
594
|
+
binding.tree = treeBinding;
|
|
595
|
+
const observed = (await runGates([gate], {
|
|
596
|
+
...options,
|
|
597
|
+
projectRoot: root,
|
|
598
|
+
env,
|
|
599
|
+
execution,
|
|
600
|
+
...(options.cache && options.cache !== 'off'
|
|
601
|
+
? { cacheInputsHash: gateInputsHash(invocation, artifacts) }
|
|
602
|
+
: {}),
|
|
603
|
+
}))[0];
|
|
180
604
|
let result = { ...observed, index, binding };
|
|
181
605
|
try {
|
|
182
|
-
const after = await snapshotGateInputs(snapshot, gate, invocation, execution);
|
|
606
|
+
const after = await snapshotGateInputs(snapshot, gate, invocation, execution, tree);
|
|
183
607
|
if (!isDeepStrictEqual(after, artifacts))
|
|
184
608
|
throw new Error('Verification inputs changed during execution');
|
|
185
609
|
}
|
|
@@ -229,11 +653,16 @@ export function createTaskGateReceipt(results, passed) {
|
|
|
229
653
|
indexes.add(result.index);
|
|
230
654
|
criteria.add(binding.criterionId);
|
|
231
655
|
}
|
|
656
|
+
const cached = results
|
|
657
|
+
.filter((result) => result.source === 'cache')
|
|
658
|
+
.map((result) => ({ index: result.index, cachedAt: result.cachedAt }));
|
|
232
659
|
return {
|
|
233
660
|
verificationId: first.verificationId,
|
|
234
661
|
resultHash: createHash('sha256').update(JSON.stringify(results)).digest('hex'),
|
|
235
662
|
operation: 'check.gate.verify',
|
|
236
663
|
passed,
|
|
664
|
+
// T12621: omitted when nothing was reused, so earlier receipts still match.
|
|
665
|
+
...(cached.length > 0 ? { cached } : {}),
|
|
237
666
|
};
|
|
238
667
|
}
|
|
239
668
|
/**
|
|
@@ -263,6 +692,7 @@ export async function revalidateTaskGateResults(task, criteria, results, options
|
|
|
263
692
|
const rows = [...criteria].sort((a, b) => a.ordinal - b.ordinal);
|
|
264
693
|
assertCriterionProjection(task, rows);
|
|
265
694
|
const env = { ...(options.env ?? process.env) };
|
|
695
|
+
const tree = resolveTypedGateRoot(root);
|
|
266
696
|
await worktreeScope.run(scope, async () => {
|
|
267
697
|
for (const [index, gate] of (task.acceptance ?? []).entries()) {
|
|
268
698
|
if (typeof gate === 'string' || (requirePassing && gate.advisory))
|
|
@@ -285,12 +715,22 @@ export async function revalidateTaskGateResults(task, criteria, results, options
|
|
|
285
715
|
binding.criterionHash !== acTextHash(rows[index].text) ||
|
|
286
716
|
binding.gateHash !== createHash('sha256').update(acItemToText(gate)).digest('hex'))
|
|
287
717
|
throw new Error(`Typed requirement ${gate.req ?? index} binding is stale or belongs to another owner`);
|
|
288
|
-
const invocation = executableInvocation(gate,
|
|
718
|
+
const invocation = executableInvocation(gate, tree, env);
|
|
719
|
+
const artifacts = await snapshotGateInputs(task, gate, invocation, execution, tree);
|
|
720
|
+
const exact = isDeepStrictEqual(binding.invocation, invocation) &&
|
|
721
|
+
isDeepStrictEqual(binding.artifacts, artifacts);
|
|
722
|
+
if (exact)
|
|
723
|
+
continue;
|
|
724
|
+
// T12625: a result bound in another tree of this project (a worker's
|
|
725
|
+
// worktree) is accepted by CONTENT, not by path. Pre-T12625 receipts carry
|
|
726
|
+
// no tree binding and keep the exact path-bound refusals below.
|
|
727
|
+
if (binding.tree) {
|
|
728
|
+
assertTreeEquivalent(task, gate.req ?? String(index), binding.tree, tree, root, invocation, artifacts);
|
|
729
|
+
continue;
|
|
730
|
+
}
|
|
289
731
|
if (!isDeepStrictEqual(binding.invocation, invocation))
|
|
290
732
|
throw new Error(`Typed requirement ${gate.req ?? index} invocation or environment changed`);
|
|
291
|
-
|
|
292
|
-
if (!isDeepStrictEqual(binding.artifacts, artifacts))
|
|
293
|
-
throw new Error(`Typed requirement ${gate.req ?? index} input bytes changed after verification`);
|
|
733
|
+
throw new Error(`Typed requirement ${gate.req ?? index} input bytes changed after verification`);
|
|
294
734
|
}
|
|
295
735
|
});
|
|
296
736
|
}
|
|
@@ -300,6 +740,7 @@ export async function revalidateTaskGateResults(task, criteria, results, options
|
|
|
300
740
|
* @param criteria - Normalized criteria from that same transaction.
|
|
301
741
|
* @param options - Captured original execution lifetime and project scope.
|
|
302
742
|
* @param accessor - Canonical receipt reader bound to the same project store.
|
|
743
|
+
* @param policy - Project evidence policy; `allowCachedGates: false` refuses cached passes (T12621).
|
|
303
744
|
* @returns Resolves only when every hard typed requirement has current authentic proof.
|
|
304
745
|
* @throws When typed representations, results, inputs or canonical receipts disagree.
|
|
305
746
|
* @remarks Callers retain transaction ownership and must check their execution context before
|
|
@@ -310,8 +751,20 @@ export async function revalidateTaskGateResults(task, criteria, results, options
|
|
|
310
751
|
* await validateTaskGateCompletion(task, rows, { execution }, accessor);
|
|
311
752
|
* ```
|
|
312
753
|
*/
|
|
313
|
-
export async function validateTaskGateCompletion(task, criteria, options, accessor) {
|
|
754
|
+
export async function validateTaskGateCompletion(task, criteria, options, accessor, policy = {}) {
|
|
314
755
|
const results = task.verification?.gateResults ?? [];
|
|
756
|
+
// T12621: `evidence.allowCachedGates: false` — a hard typed requirement must
|
|
757
|
+
// have been executed, not reused from the evidence cache.
|
|
758
|
+
if (policy.allowCachedGates === false) {
|
|
759
|
+
for (const [index, gate] of (task.acceptance ?? []).entries()) {
|
|
760
|
+
if (typeof gate === 'string' || gate.advisory)
|
|
761
|
+
continue;
|
|
762
|
+
const reused = results.find((result) => result.index === index && result.source === 'cache');
|
|
763
|
+
if (reused)
|
|
764
|
+
throw new Error(`Typed requirement ${gate.req ?? index} passed from the evidence cache (cached ${reused.cachedAt}) ` +
|
|
765
|
+
'and this project sets evidence.allowCachedGates to false; re-verify so the gate executes');
|
|
766
|
+
}
|
|
767
|
+
}
|
|
315
768
|
await revalidateTaskGateResults(task, criteria, results, options);
|
|
316
769
|
if (!(task.acceptance ?? []).some((item) => typeof item !== 'string' && !item.advisory))
|
|
317
770
|
return;
|
|
@@ -373,8 +826,10 @@ function executableInvocation(gate, root, env) {
|
|
|
373
826
|
};
|
|
374
827
|
}
|
|
375
828
|
/** Capture declared task inputs and an interpreter's explicit harness argument. */
|
|
376
|
-
async function snapshotGateInputs(task, gate, invocation, execution
|
|
377
|
-
|
|
829
|
+
async function snapshotGateInputs(task, gate, invocation, execution,
|
|
830
|
+
/** T12625: the tree the gate runs in ({@link resolveTypedGateRoot}). */
|
|
831
|
+
treeRoot = resolve(execution.identity.projectRoot)) {
|
|
832
|
+
const root = resolve(treeRoot);
|
|
378
833
|
if (invocation) {
|
|
379
834
|
const cwdRelative = relative(root, invocation.cwd);
|
|
380
835
|
if (cwdRelative === '..' || cwdRelative.startsWith('../') || isAbsolute(cwdRelative))
|
|
@@ -483,15 +938,15 @@ function assertGateActive(context) {
|
|
|
483
938
|
throw new Error('Gate did not finish: original shared deadline expired. This is NOT a failure verdict.');
|
|
484
939
|
}
|
|
485
940
|
// ─── Internal dispatcher ──────────────────────────────────────────────────────
|
|
486
|
-
async function runOneGate(gate, index, projectRoot, skipManual, context
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
941
|
+
async function runOneGate(gate, index, projectRoot, skipManual, context,
|
|
942
|
+
/** CLEO store root for attachment lookups; defaults to `projectRoot`. */
|
|
943
|
+
storeRoot = projectRoot) {
|
|
944
|
+
const timeout = resolveGateTimeoutMs(gate, context.env ?? process.env);
|
|
490
945
|
switch (gate.kind) {
|
|
491
946
|
case 'test':
|
|
492
947
|
return runTestGate(gate, index, projectRoot, timeout, context);
|
|
493
948
|
case 'file':
|
|
494
|
-
return runFileGate(gate, index, projectRoot, context);
|
|
949
|
+
return runFileGate(gate, index, projectRoot, context, storeRoot);
|
|
495
950
|
case 'command':
|
|
496
951
|
return runCommandGate(gate, index, projectRoot, timeout, context);
|
|
497
952
|
case 'lint':
|
|
@@ -671,13 +1126,13 @@ async function runTestGate(gate, index, projectRoot, timeoutMs, context) {
|
|
|
671
1126
|
: `Exit code ${captured.exitCode}`);
|
|
672
1127
|
}
|
|
673
1128
|
// ─── File gate ────────────────────────────────────────────────────────────────
|
|
674
|
-
async function runFileGate(gate, index, projectRoot, context) {
|
|
1129
|
+
async function runFileGate(gate, index, projectRoot, context, storeRoot = projectRoot) {
|
|
675
1130
|
const startMs = Date.now();
|
|
676
1131
|
let attachmentBytes;
|
|
677
1132
|
let filePath;
|
|
678
1133
|
if (gate.attachmentSha256) {
|
|
679
1134
|
const store = createAttachmentStore();
|
|
680
|
-
const metadata = await store.getMetadata(gate.attachmentSha256,
|
|
1135
|
+
const metadata = await store.getMetadata(gate.attachmentSha256, storeRoot);
|
|
681
1136
|
assertGateActive(context);
|
|
682
1137
|
if (!metadata)
|
|
683
1138
|
return makeResult(index, gate, 'fail', Date.now() - startMs, undefined, 'Attachment not found');
|
|
@@ -686,7 +1141,7 @@ async function runFileGate(gate, index, projectRoot, context) {
|
|
|
686
1141
|
throw new Error('Attachment gate requires declared byte size for bounded retrieval');
|
|
687
1142
|
if (attachment.size > (context.maxOutputBytes ?? 1_048_576))
|
|
688
1143
|
throw new Error('Attachment gate exceeds declared byte limit');
|
|
689
|
-
const result = await store.get(gate.attachmentSha256,
|
|
1144
|
+
const result = await store.get(gate.attachmentSha256, storeRoot);
|
|
690
1145
|
assertGateActive(context);
|
|
691
1146
|
if (!result)
|
|
692
1147
|
throw new Error('Attachment metadata exists but authenticated bytes are unavailable');
|