@cleocode/core 2026.9.20 → 2026.9.22
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/agents/scaffold.d.ts.map +1 -1
- package/dist/agents/scaffold.js +0 -1
- package/dist/agents/scaffold.js.map +1 -1
- package/dist/bootstrap.d.ts +5 -1
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +45 -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/dispatch/mutate-projection.d.ts.map +1 -1
- package/dist/dispatch/mutate-projection.js +5 -0
- package/dist/dispatch/mutate-projection.js.map +1 -1
- package/dist/docs/docs-update.d.ts.map +1 -1
- package/dist/docs/docs-update.js +25 -9
- package/dist/docs/docs-update.js.map +1 -1
- package/dist/docs/export-document.js +5963 -2406
- 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 +16 -1
- package/dist/doctor/knowledge.d.ts.map +1 -1
- package/dist/doctor/knowledge.js +58 -32
- 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/engine/engine-ops.d.ts +36 -6
- package/dist/engine/engine-ops.d.ts.map +1 -1
- package/dist/engine/engine-ops.js +115 -14
- package/dist/engine/engine-ops.js.map +1 -1
- 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/gateway-client/generated/types.gen.d.ts +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 +8 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -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 +578 -53
- package/dist/init.js.map +1 -1
- package/dist/inject/index.d.ts.map +1 -1
- package/dist/inject/index.js +8 -3
- package/dist/inject/index.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 +11 -7
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +9 -5
- 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 +4400 -1801
- 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.js +31 -31
- 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 +38 -0
- package/dist/nexus/analyze-orchestrator.d.ts.map +1 -1
- package/dist/nexus/analyze-orchestrator.js +136 -48
- 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 +40 -5
- 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 +171 -0
- package/dist/nexus/stored-roots.d.ts.map +1 -0
- package/dist/nexus/stored-roots.js +253 -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/lifecycle-ops.d.ts.map +1 -1
- package/dist/orchestrate/lifecycle-ops.js +4 -1
- package/dist/orchestrate/lifecycle-ops.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/plan.d.ts.map +1 -1
- package/dist/orchestrate/plan.js +5 -2
- package/dist/orchestrate/plan.js.map +1 -1
- package/dist/orchestrate/query-ops.d.ts +7 -2
- package/dist/orchestrate/query-ops.d.ts.map +1 -1
- package/dist/orchestrate/query-ops.js +17 -6
- package/dist/orchestrate/query-ops.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 +157 -71
- package/dist/orchestrate/spawn-ops.js.map +1 -1
- package/dist/orchestration/bootstrap.d.ts.map +1 -1
- package/dist/orchestration/bootstrap.js +4 -2
- package/dist/orchestration/bootstrap.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 +4 -2
- package/dist/orchestration/index.d.ts.map +1 -1
- package/dist/orchestration/index.js +6 -4
- package/dist/orchestration/index.js.map +1 -1
- package/dist/orchestration/lead-rollup.d.ts +8 -5
- package/dist/orchestration/lead-rollup.d.ts.map +1 -1
- package/dist/orchestration/lead-rollup.js +32 -15
- package/dist/orchestration/lead-rollup.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/parallel.d.ts.map +1 -1
- package/dist/orchestration/parallel.js +10 -17
- package/dist/orchestration/parallel.js.map +1 -1
- 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 +16 -2
- package/dist/orchestration/spawn-prompt.d.ts.map +1 -1
- package/dist/orchestration/spawn-prompt.js +144 -181
- 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/orchestration/status.d.ts +8 -3
- package/dist/orchestration/status.d.ts.map +1 -1
- package/dist/orchestration/status.js +9 -6
- package/dist/orchestration/status.js.map +1 -1
- package/dist/orchestration/wave-topic.d.ts +54 -0
- package/dist/orchestration/wave-topic.d.ts.map +1 -0
- package/dist/orchestration/wave-topic.js +68 -0
- package/dist/orchestration/wave-topic.js.map +1 -0
- package/dist/orchestration/waves.d.ts +47 -8
- package/dist/orchestration/waves.d.ts.map +1 -1
- package/dist/orchestration/waves.js +152 -43
- package/dist/orchestration/waves.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/phases/index.d.ts.map +1 -1
- package/dist/phases/index.js +6 -2
- package/dist/phases/index.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 +104 -4
- package/dist/project-scope.d.ts.map +1 -1
- package/dist/project-scope.js +263 -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 +233 -0
- package/dist/release/ci-evidence.d.ts.map +1 -0
- package/dist/release/ci-evidence.js +668 -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/github-pr.d.ts +30 -0
- package/dist/release/github-pr.d.ts.map +1 -1
- package/dist/release/github-pr.js +40 -0
- package/dist/release/github-pr.js.map +1 -1
- package/dist/release/plan.d.ts.map +1 -1
- package/dist/release/plan.js +11 -7
- 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 +79 -15
- 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 +20 -3
- package/dist/security/input-sanitization.js.map +1 -1
- package/dist/selfimprove/fix-gen.js +4409 -1810
- 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 +15 -0
- package/dist/session/engine-ops.d.ts.map +1 -1
- package/dist/session/engine-ops.js +146 -22
- 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 +23 -0
- package/dist/sessions/briefing.d.ts.map +1 -1
- package/dist/sessions/briefing.js +59 -9
- 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 +8 -5
- package/dist/sessions/drift-watchdog.js.map +1 -1
- package/dist/sessions/focus-state-store.d.ts +89 -1
- package/dist/sessions/focus-state-store.d.ts.map +1 -1
- package/dist/sessions/focus-state-store.js +97 -1
- package/dist/sessions/focus-state-store.js.map +1 -1
- package/dist/sessions/index.d.ts +2 -2
- package/dist/sessions/index.d.ts.map +1 -1
- package/dist/sessions/index.js +34 -5
- package/dist/sessions/index.js.map +1 -1
- package/dist/sessions/session-drift.d.ts.map +1 -1
- package/dist/sessions/session-drift.js +4 -3
- package/dist/sessions/session-drift.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 +20 -3
- package/dist/skills/discovery.d.ts.map +1 -1
- package/dist/skills/discovery.js +41 -4
- 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 +14 -7
- package/dist/skills/orchestrator/startup.js.map +1 -1
- package/dist/skills/prune-bundled.d.ts +267 -0
- package/dist/skills/prune-bundled.d.ts.map +1 -0
- package/dist/skills/prune-bundled.js +536 -0
- package/dist/skills/prune-bundled.js.map +1 -0
- 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 +32 -1
- package/dist/skills/types.d.ts.map +1 -1
- package/dist/skills/types.js +17 -34
- 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 +80 -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/stats/index.d.ts.map +1 -1
- package/dist/stats/index.js +4 -2
- package/dist/stats/index.js.map +1 -1
- 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/skills-db.d.ts +17 -0
- package/dist/store/skills-db.d.ts.map +1 -1
- package/dist/store/skills-db.js +30 -0
- package/dist/store/skills-db.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 +401 -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 +73 -4
- package/dist/store/sqlite-data-accessor.js.map +1 -1
- package/dist/store/sqlite.d.ts +15 -1
- package/dist/store/sqlite.d.ts.map +1 -1
- package/dist/store/sqlite.js +75 -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 +320 -0
- package/dist/store/twin-collapse.d.ts.map +1 -0
- package/dist/store/twin-collapse.js +931 -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 +71 -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/inject-generate.d.ts.map +1 -1
- package/dist/system/inject-generate.js +4 -4
- package/dist/system/inject-generate.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/task-work/index.d.ts +6 -0
- package/dist/task-work/index.d.ts.map +1 -1
- package/dist/task-work/index.js +6 -3
- package/dist/task-work/index.js.map +1 -1
- 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 +218 -0
- package/dist/tasks/affected-packages.d.ts.map +1 -0
- package/dist/tasks/affected-packages.js +496 -0
- package/dist/tasks/affected-packages.js.map +1 -0
- package/dist/tasks/affected-scope.d.ts +59 -0
- package/dist/tasks/affected-scope.d.ts.map +1 -0
- package/dist/tasks/affected-scope.js +81 -0
- package/dist/tasks/affected-scope.js.map +1 -0
- package/dist/tasks/analyze.d.ts.map +1 -1
- package/dist/tasks/analyze.js +7 -2
- package/dist/tasks/analyze.js.map +1 -1
- package/dist/tasks/change-set.d.ts +175 -0
- package/dist/tasks/change-set.d.ts.map +1 -0
- package/dist/tasks/change-set.js +753 -0
- package/dist/tasks/change-set.js.map +1 -0
- package/dist/tasks/complete.d.ts +10 -0
- package/dist/tasks/complete.d.ts.map +1 -1
- package/dist/tasks/complete.js +59 -5
- package/dist/tasks/complete.js.map +1 -1
- package/dist/tasks/component-pr.d.ts +106 -0
- package/dist/tasks/component-pr.d.ts.map +1 -0
- package/dist/tasks/component-pr.js +190 -0
- package/dist/tasks/component-pr.js.map +1 -0
- package/dist/tasks/done-plan.d.ts +123 -0
- package/dist/tasks/done-plan.d.ts.map +1 -0
- package/dist/tasks/done-plan.js +696 -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 +302 -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 +101 -1
- package/dist/tasks/evidence.d.ts.map +1 -1
- package/dist/tasks/evidence.js +278 -31
- 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/task-next.d.ts +4 -0
- package/dist/tasks/task-next.d.ts.map +1 -1
- package/dist/tasks/task-next.js +32 -28
- package/dist/tasks/task-next.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 +24 -1
- package/dist/validation/engine-ops.d.ts.map +1 -1
- package/dist/validation/engine-ops.js +272 -98
- package/dist/validation/engine-ops.js.map +1 -1
- package/dist/validation/validate-ops.d.ts.map +1 -1
- package/dist/validation/validate-ops.js +9 -3
- package/dist/validation/validate-ops.js.map +1 -1
- package/dist/worktree/worktree-adopt.d.ts.map +1 -1
- package/dist/worktree/worktree-adopt.js +5 -2
- package/dist/worktree/worktree-adopt.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
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import type { CreateDeviceRevocationRequest, DeviceTrust, PutDeviceWrappedKeyRequest, RevocationPins } from '@cleocode/contracts/cloud';
|
|
2
|
+
import { type KdfParams, type KeyPair } from './crypto.js';
|
|
3
|
+
/** What the server stores for a user (PutUserKeysRequest). Nothing here opens without a secret. */
|
|
4
|
+
export interface StoredUserKeys {
|
|
5
|
+
passphraseWrappedMasterKey: string;
|
|
6
|
+
kdf: KdfParams;
|
|
7
|
+
recoveryWrappedMasterKey: string;
|
|
8
|
+
masterKeyVerifier: string;
|
|
9
|
+
keyVersion: number;
|
|
10
|
+
}
|
|
11
|
+
export declare const masterKeyVerifier: (mk: Uint8Array) => string;
|
|
12
|
+
/**
|
|
13
|
+
* First-device setup: mint the master key and wrap it by passphrase and by a new recovery key.
|
|
14
|
+
* Show `recoveryKey` to the user exactly once.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createUserKeys(userId: string, passphrase: string, keyVersion?: number): Promise<{
|
|
17
|
+
masterKey: Buffer;
|
|
18
|
+
recoveryKey: string;
|
|
19
|
+
stored: StoredUserKeys;
|
|
20
|
+
}>;
|
|
21
|
+
export declare function unlockWithPassphrase(userId: string, stored: StoredUserKeys, passphrase: string): Promise<Buffer<ArrayBufferLike>>;
|
|
22
|
+
export declare function unlockWithRecoveryKey(userId: string, stored: StoredUserKeys, recoveryKey: string): Buffer;
|
|
23
|
+
/** Re-wrap the master key under a new passphrase (for example after a recovery-key unlock). */
|
|
24
|
+
export declare function rewrapPassphrase(userId: string, mk: Buffer, stored: StoredUserKeys, newPassphrase: string): Promise<StoredUserKeys>;
|
|
25
|
+
/** A device's public identity, as raw key bytes. */
|
|
26
|
+
export interface DevicePublicKeys {
|
|
27
|
+
deviceId: string;
|
|
28
|
+
encryptionPublicKey: Uint8Array;
|
|
29
|
+
signingPublicKey: Uint8Array;
|
|
30
|
+
}
|
|
31
|
+
/** A grant or certificate that does not come from a trusted master key holder. Never retry it blindly. */
|
|
32
|
+
export declare class KeyTrustError extends Error {
|
|
33
|
+
constructor(message: string);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Certify a device under the master key: HMAC-SHA256 keyed by HKDF(MK, "device-cert"). Only a holder of
|
|
37
|
+
* the master key can make one, so the server cannot add a device of its own to the set a client trusts.
|
|
38
|
+
*/
|
|
39
|
+
export declare function deviceCertificate(mk: Uint8Array, userId: string, device: DevicePublicKeys, keyVersion: number): Buffer<ArrayBufferLike>;
|
|
40
|
+
export declare function verifyDeviceCertificate(mk: Uint8Array, userId: string, device: DevicePublicKeys, keyVersion: number, certificate: Uint8Array): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* One signing key a client trusts for a device. `pin` is null for a live key. A revoked key keeps a pin:
|
|
43
|
+
* its signatures are accepted up to the pinned replicaSeq per replica and the pinned checkpoint coversSeq
|
|
44
|
+
* per stream, and refused past them. `pending` marks a certified key that is no longer live but has no
|
|
45
|
+
* revocation record yet (only returned with `includePending`, for writing that record).
|
|
46
|
+
*/
|
|
47
|
+
export interface SignerKey {
|
|
48
|
+
publicKey: Uint8Array;
|
|
49
|
+
pin: RevocationPins | null;
|
|
50
|
+
pending?: boolean;
|
|
51
|
+
}
|
|
52
|
+
/** Trusted signers by device id. A bare key stands for one live key (a device's own key, for example). */
|
|
53
|
+
export type TrustedSigners = ReadonlyMap<string, Uint8Array | readonly SignerKey[]>;
|
|
54
|
+
/** The keys trusted for `deviceId`, normalized. */
|
|
55
|
+
export declare function signerKeys(trusted: TrustedSigners, deviceId: string): readonly SignerKey[];
|
|
56
|
+
/** Keys that may vouch for new things (grants, endorsements): live and unpinned. */
|
|
57
|
+
export declare const liveKeys: (trusted: TrustedSigners, deviceId: string) => SignerKey[];
|
|
58
|
+
/** Master keys by key version. Certificates made under older versions verify under their own key. */
|
|
59
|
+
export type MasterKeys = ReadonlyMap<number, Uint8Array>;
|
|
60
|
+
/**
|
|
61
|
+
* What a client has learned about signer trust, persisted with the pull cursor (same local transaction)
|
|
62
|
+
* and passed back to every certifiedSigners call. Trust only ever tightens through it: the server can
|
|
63
|
+
* withhold a record or flip its `live` claims, but it cannot make the client forget what it has seen.
|
|
64
|
+
* Key ids are `${deviceId}/${hex of the Ed25519 public key}`.
|
|
65
|
+
*/
|
|
66
|
+
export interface TrustState {
|
|
67
|
+
/**
|
|
68
|
+
* The highest master key version this client holds or has proven (by unlocking it). Only such versions are
|
|
69
|
+
* persisted: a version the server merely declares is used for one call and never stored, so one bad
|
|
70
|
+
* response cannot brick the device. Live trust needs a certificate at the current version.
|
|
71
|
+
*/
|
|
72
|
+
keyVersion: number;
|
|
73
|
+
/** The last pins seen per revoked key. A key seen pinned is never live again. */
|
|
74
|
+
pins: Record<string, RevocationPins>;
|
|
75
|
+
/** Every key seen as the target of a valid revocation record. Never live again. Sorted. */
|
|
76
|
+
revoked: string[];
|
|
77
|
+
}
|
|
78
|
+
export declare const initialTrustState: () => TrustState;
|
|
79
|
+
/**
|
|
80
|
+
* How far a declared account key version may exceed the highest version this client holds or has proven.
|
|
81
|
+
* A rotation bumps the version by one, so an honest server is never more than one ahead of a device that
|
|
82
|
+
* has seen the previous rotation. A device that missed two rotations sees a server error (and fails closed);
|
|
83
|
+
* it needs a passphrase unlock anyway, to fetch the new master key.
|
|
84
|
+
*/
|
|
85
|
+
export declare const MAX_ROTATION_STEP = 1;
|
|
86
|
+
export interface TrustEvaluation {
|
|
87
|
+
signers: Map<string, SignerKey[]>;
|
|
88
|
+
/** Persist this with the pull cursor, in the same local transaction. */
|
|
89
|
+
state: TrustState;
|
|
90
|
+
/**
|
|
91
|
+
* The account's key version is ahead of every master key this client holds: nothing is live. Tell the
|
|
92
|
+
* user "the account key was rotated: unlock with your passphrase to fetch the new master key".
|
|
93
|
+
*/
|
|
94
|
+
keyRotated: boolean;
|
|
95
|
+
/**
|
|
96
|
+
* The server declared a key version no rotation can explain (more than MAX_ROTATION_STEP above what this
|
|
97
|
+
* client holds or has proven). Not a rotation: nothing is persisted, and nothing is live in this call.
|
|
98
|
+
*/
|
|
99
|
+
serverError?: 'implausible-key-version';
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Update TrustState after a successful passphrase or recovery-key unlock, the only proof of the account's
|
|
103
|
+
* real key version. It requires proof of possession: the unwrapped master key must match `stored`'s
|
|
104
|
+
* verifier (and the unwrap itself already checked the AAD, which binds the user and the version).
|
|
105
|
+
* - `keyVersion` becomes the proven version, if it is higher (an older genuine wrap never lowers it).
|
|
106
|
+
* - Seen pins are cleared **only** with `confirmedPinReset: true`, after the user explicitly confirms it (for
|
|
107
|
+
* example, when a thief's record narrowed a pin while the stolen device was still live). The confirmation
|
|
108
|
+
* prompt must tell the user to revoke the thief's device FIRST: while it is live, its records still count
|
|
109
|
+
* and would narrow the pins again. The next
|
|
110
|
+
* certifiedSigners call then takes pins from the records live devices have signed.
|
|
111
|
+
* - The seen-revoked set is never cleared: revocation is monotonic.
|
|
112
|
+
*/
|
|
113
|
+
export declare function resetTrustStateAfterUnlock(state: TrustState, proof: {
|
|
114
|
+
masterKey: Uint8Array;
|
|
115
|
+
stored: Pick<StoredUserKeys, 'masterKeyVerifier' | 'keyVersion'>;
|
|
116
|
+
}, opts?: {
|
|
117
|
+
confirmedPinReset?: boolean;
|
|
118
|
+
}): TrustState;
|
|
119
|
+
/**
|
|
120
|
+
* The trusted signer set, built from `GET /v1/devices/trust`, the master keys the client holds and its
|
|
121
|
+
* persisted TrustState. Build the set for pulls, checkpoints and grants from this, never from the server's
|
|
122
|
+
* device list alone. Persist the returned state. The rules (docs/security/e2e-keys.md, "Revocation"):
|
|
123
|
+
* - A key is certified if a certificate for it verifies under the master key of the certificate's own
|
|
124
|
+
* version (old history stays verifiable after rotation while the client keeps the old master keys).
|
|
125
|
+
* - **Current version only for liveness.** The current version is the highest the client holds or has
|
|
126
|
+
* seen. Only a certificate at that version can make a key live, so a thief with a pre-rotation master key
|
|
127
|
+
* cannot certify a fresh key into live trust. Older certificates carry pinned history only.
|
|
128
|
+
* - **Any valid record revokes its target.** A record whose signature verifies under a key certified at the
|
|
129
|
+
* current version, live, pinned or pending, makes its target non-live for good (TrustState.revoked),
|
|
130
|
+
* whatever the server claims. Records by old-version-only keys are ignored: such a key can never be live.
|
|
131
|
+
* - **Pins come only from live signers, and only ever narrow.** A record sets pins only if its signer is live
|
|
132
|
+
* (a server claim at the current version) and not itself revoked. Several such records: the narrowest pins.
|
|
133
|
+
* The result is always narrowed with the pins this client has seen (TrustState.pins), so neither a withheld
|
|
134
|
+
* record nor a wider record served later can widen or drop a pin. A revoked key with no pins, now or ever,
|
|
135
|
+
* is pending (untrusted; `includePending` returns it for the revocation flow).
|
|
136
|
+
* - **The current version** is the highest of: the versions the client has seen, the account version the
|
|
137
|
+
* server declares, and the master keys held. When it is above every held master key, nothing is live and
|
|
138
|
+
* `keyRotated` is true: tell the user "the account key was rotated: unlock with your passphrase to fetch
|
|
139
|
+
* the new master key".
|
|
140
|
+
*
|
|
141
|
+
* **The caller MUST persist the returned `state`** in the same local transaction as the pull cursor, and pass
|
|
142
|
+
* it back next time. Nothing in core does this yet (the `cleo cloud` commands will); without it the monotonic
|
|
143
|
+
* guarantees above do not hold.
|
|
144
|
+
* - A live key: certified at the current version, called live by the server, never revoked.
|
|
145
|
+
*/
|
|
146
|
+
export declare function certifiedSigners(masterKeys: MasterKeys, userId: string, trust: DeviceTrust, state: TrustState,
|
|
147
|
+
/**
|
|
148
|
+
* The account's key version as the server declares it (`keyVersion` of GET /v1/account/keys), or null
|
|
149
|
+
* when the account has no keys yet. Used for this call only, never persisted. It may raise the current
|
|
150
|
+
* version by at most MAX_ROTATION_STEP above the highest held or proven version: a rotation bumps the
|
|
151
|
+
* version by one. A higher value is a server error (`serverError`), not a rotation.
|
|
152
|
+
*/
|
|
153
|
+
accountKeyVersion: number | null, opts?: {
|
|
154
|
+
includePending?: boolean;
|
|
155
|
+
}): TrustEvaluation;
|
|
156
|
+
/**
|
|
157
|
+
* Revoke one signing key of a device and pin its history (the POST /v1/devices/:id/revocations body).
|
|
158
|
+
* The signer must hold a certified key: after losing every other device, the device that just unlocked
|
|
159
|
+
* with the passphrase certifies itself (a self-grant) and signs this. Compute `pins` from segments and
|
|
160
|
+
* checkpoints this client has itself verified (revocationPins), never from numbers the server supplies.
|
|
161
|
+
*/
|
|
162
|
+
export declare function createDeviceRevocation(args: {
|
|
163
|
+
userId: string;
|
|
164
|
+
revoked: {
|
|
165
|
+
deviceId: string;
|
|
166
|
+
signingPublicKey: Uint8Array;
|
|
167
|
+
};
|
|
168
|
+
pins: RevocationPins;
|
|
169
|
+
signer: {
|
|
170
|
+
deviceId: string;
|
|
171
|
+
signing: KeyPair;
|
|
172
|
+
};
|
|
173
|
+
}): CreateDeviceRevocationRequest;
|
|
174
|
+
/**
|
|
175
|
+
* Grant the master key to a device: seal it to the recipient's X25519 key, certify the recipient under
|
|
176
|
+
* the master key, and sign the whole grant with the signer's Ed25519 key. The signer must hold the
|
|
177
|
+
* master key legitimately: a device that unlocked by passphrase or recovery key grants to itself, and a
|
|
178
|
+
* trusted device grants to another (key rotation). The result is the PUT /v1/devices/:id/key body.
|
|
179
|
+
*/
|
|
180
|
+
export declare function createDeviceGrant(args: {
|
|
181
|
+
masterKey: Buffer;
|
|
182
|
+
userId: string;
|
|
183
|
+
keyVersion: number;
|
|
184
|
+
recipient: DevicePublicKeys;
|
|
185
|
+
signer: {
|
|
186
|
+
deviceId: string;
|
|
187
|
+
signing: KeyPair;
|
|
188
|
+
};
|
|
189
|
+
}): PutDeviceWrappedKeyRequest;
|
|
190
|
+
/**
|
|
191
|
+
* Open a master key grant made to this device, after checking it came from a trusted signer. The checks,
|
|
192
|
+
* in order: the signer is in `trustedSigners` (the device's own signing key for a self-grant, or devices
|
|
193
|
+
* certified under a master key this device already holds); the signature verifies over a message rebuilt
|
|
194
|
+
* from this device's OWN keys, so a grant made for other keys fails; the sealed box opens; and the key
|
|
195
|
+
* inside certifies this device, so the key and the signer's intent agree. The server's verifier is not
|
|
196
|
+
* consulted: it is server-supplied and proves nothing.
|
|
197
|
+
*/
|
|
198
|
+
export declare function openDeviceGrant(args: {
|
|
199
|
+
userId: string;
|
|
200
|
+
device: {
|
|
201
|
+
deviceId: string;
|
|
202
|
+
encryption: KeyPair;
|
|
203
|
+
signingPublicKey: Uint8Array;
|
|
204
|
+
};
|
|
205
|
+
grant: PutDeviceWrappedKeyRequest;
|
|
206
|
+
trustedSigners: TrustedSigners;
|
|
207
|
+
}): Buffer;
|
|
208
|
+
export declare const newProjectKey: () => Buffer;
|
|
209
|
+
export declare function wrapProjectKey(mk: Buffer, pdk: Buffer, projectId: string, keyVersion: number): string;
|
|
210
|
+
export declare function unwrapProjectKey(mk: Buffer, wrapped: string, projectId: string, keyVersion: number): Buffer;
|
|
211
|
+
/** Key for the personal home stream. It is derived, so it never needs storing or sharing. */
|
|
212
|
+
export declare const homeStreamKey: (mk: Buffer) => Buffer<ArrayBufferLike>;
|
|
213
|
+
//# sourceMappingURL=keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../src/cloud/keys.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import { constantTimeEqual, DecryptError, decodeRecoveryKey, deriveKey, encodeRecoveryKey, hmacSha256, newKdfParams, open, openSealed, passphraseKey, randomKey, seal, sealTo, sha256Hex, signEd25519, verifyEd25519, } from './crypto.js';
|
|
2
|
+
import { deviceCertificateMessage, deviceGrantMessage, deviceRevocationMessage, revocationPinsCanonical, } from './signing.js';
|
|
3
|
+
const mkContext = (userId, v) => `mk\n${userId}\n${v}`;
|
|
4
|
+
const pdkContext = (projectId, v) => `pdk\n${projectId}\n${v}`;
|
|
5
|
+
const deviceContext = (userId, deviceId, v) => `device-mk\n${userId}\n${deviceId}\n${v}`;
|
|
6
|
+
export const masterKeyVerifier = (mk) => sha256Hex(deriveKey(mk, 'verifier'));
|
|
7
|
+
/**
|
|
8
|
+
* First-device setup: mint the master key and wrap it by passphrase and by a new recovery key.
|
|
9
|
+
* Show `recoveryKey` to the user exactly once.
|
|
10
|
+
*/
|
|
11
|
+
export async function createUserKeys(userId, passphrase, keyVersion = 1) {
|
|
12
|
+
if (passphrase.length < 12)
|
|
13
|
+
throw new Error('passphrase must be at least 12 characters');
|
|
14
|
+
const masterKey = randomKey();
|
|
15
|
+
const recovery = randomKey();
|
|
16
|
+
const kdf = newKdfParams();
|
|
17
|
+
const pwk = await passphraseKey(passphrase, kdf);
|
|
18
|
+
const ctx = mkContext(userId, keyVersion);
|
|
19
|
+
return {
|
|
20
|
+
masterKey,
|
|
21
|
+
recoveryKey: encodeRecoveryKey(recovery),
|
|
22
|
+
stored: {
|
|
23
|
+
passphraseWrappedMasterKey: seal(pwk, masterKey, 'mk-wrap', ctx).toString('base64'),
|
|
24
|
+
kdf,
|
|
25
|
+
recoveryWrappedMasterKey: seal(recovery, masterKey, 'mk-wrap', ctx).toString('base64'),
|
|
26
|
+
masterKeyVerifier: masterKeyVerifier(masterKey),
|
|
27
|
+
keyVersion,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function checkVerifier(mk, stored) {
|
|
32
|
+
if (!constantTimeEqual(Buffer.from(masterKeyVerifier(mk)), Buffer.from(stored.masterKeyVerifier))) {
|
|
33
|
+
throw new DecryptError('master key does not match its verifier');
|
|
34
|
+
}
|
|
35
|
+
return mk;
|
|
36
|
+
}
|
|
37
|
+
export async function unlockWithPassphrase(userId, stored, passphrase) {
|
|
38
|
+
const pwk = await passphraseKey(passphrase, stored.kdf);
|
|
39
|
+
try {
|
|
40
|
+
const mk = open(pwk, Buffer.from(stored.passphraseWrappedMasterKey, 'base64'), 'mk-wrap', mkContext(userId, stored.keyVersion));
|
|
41
|
+
return checkVerifier(mk, stored);
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
if (err instanceof DecryptError)
|
|
45
|
+
throw new DecryptError('wrong passphrase');
|
|
46
|
+
throw err;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export function unlockWithRecoveryKey(userId, stored, recoveryKey) {
|
|
50
|
+
const rk = decodeRecoveryKey(recoveryKey);
|
|
51
|
+
const mk = open(rk, Buffer.from(stored.recoveryWrappedMasterKey, 'base64'), 'mk-wrap', mkContext(userId, stored.keyVersion));
|
|
52
|
+
return checkVerifier(mk, stored);
|
|
53
|
+
}
|
|
54
|
+
/** Re-wrap the master key under a new passphrase (for example after a recovery-key unlock). */
|
|
55
|
+
export async function rewrapPassphrase(userId, mk, stored, newPassphrase) {
|
|
56
|
+
const kdf = newKdfParams();
|
|
57
|
+
const pwk = await passphraseKey(newPassphrase, kdf);
|
|
58
|
+
return {
|
|
59
|
+
...stored,
|
|
60
|
+
kdf,
|
|
61
|
+
passphraseWrappedMasterKey: seal(pwk, mk, 'mk-wrap', mkContext(userId, stored.keyVersion)).toString('base64'),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** A grant or certificate that does not come from a trusted master key holder. Never retry it blindly. */
|
|
65
|
+
export class KeyTrustError extends Error {
|
|
66
|
+
constructor(message) {
|
|
67
|
+
super(message);
|
|
68
|
+
this.name = 'KeyTrustError';
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const hex = (b) => Buffer.from(b).toString('hex');
|
|
72
|
+
const certMessage = (userId, d, keyVersion) => deviceCertificateMessage({
|
|
73
|
+
userId,
|
|
74
|
+
deviceId: d.deviceId,
|
|
75
|
+
encryptionPublicKeyHex: hex(d.encryptionPublicKey),
|
|
76
|
+
signingPublicKeyHex: hex(d.signingPublicKey),
|
|
77
|
+
keyVersion,
|
|
78
|
+
});
|
|
79
|
+
/**
|
|
80
|
+
* Certify a device under the master key: HMAC-SHA256 keyed by HKDF(MK, "device-cert"). Only a holder of
|
|
81
|
+
* the master key can make one, so the server cannot add a device of its own to the set a client trusts.
|
|
82
|
+
*/
|
|
83
|
+
export function deviceCertificate(mk, userId, device, keyVersion) {
|
|
84
|
+
return hmacSha256(deriveKey(mk, 'device-cert'), certMessage(userId, device, keyVersion));
|
|
85
|
+
}
|
|
86
|
+
export function verifyDeviceCertificate(mk, userId, device, keyVersion, certificate) {
|
|
87
|
+
return constantTimeEqual(deviceCertificate(mk, userId, device, keyVersion), certificate);
|
|
88
|
+
}
|
|
89
|
+
/** The keys trusted for `deviceId`, normalized. */
|
|
90
|
+
export function signerKeys(trusted, deviceId) {
|
|
91
|
+
const v = trusted.get(deviceId);
|
|
92
|
+
if (!v)
|
|
93
|
+
return [];
|
|
94
|
+
return v instanceof Uint8Array ? [{ publicKey: v, pin: null }] : v;
|
|
95
|
+
}
|
|
96
|
+
/** Keys that may vouch for new things (grants, endorsements): live and unpinned. */
|
|
97
|
+
export const liveKeys = (trusted, deviceId) => signerKeys(trusted, deviceId).filter((k) => k.pin === null && !k.pending);
|
|
98
|
+
const utf8 = (s) => Buffer.from(s, 'utf8');
|
|
99
|
+
/** Where two pins agree: only entries in both, at the lower bound. Used when several records revoke one key. */
|
|
100
|
+
function narrowerPins(a, b) {
|
|
101
|
+
const both = (x, y) => Object.fromEntries(Object.keys(x)
|
|
102
|
+
.filter((k) => k in y)
|
|
103
|
+
.map((k) => [k, Math.min(x[k], y[k])]));
|
|
104
|
+
return {
|
|
105
|
+
replicas: both(a.replicas, b.replicas),
|
|
106
|
+
checkpoints: both(a.checkpoints, b.checkpoints),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
export const initialTrustState = () => ({ keyVersion: 0, pins: {}, revoked: [] });
|
|
110
|
+
/**
|
|
111
|
+
* How far a declared account key version may exceed the highest version this client holds or has proven.
|
|
112
|
+
* A rotation bumps the version by one, so an honest server is never more than one ahead of a device that
|
|
113
|
+
* has seen the previous rotation. A device that missed two rotations sees a server error (and fails closed);
|
|
114
|
+
* it needs a passphrase unlock anyway, to fetch the new master key.
|
|
115
|
+
*/
|
|
116
|
+
export const MAX_ROTATION_STEP = 1;
|
|
117
|
+
/**
|
|
118
|
+
* Update TrustState after a successful passphrase or recovery-key unlock, the only proof of the account's
|
|
119
|
+
* real key version. It requires proof of possession: the unwrapped master key must match `stored`'s
|
|
120
|
+
* verifier (and the unwrap itself already checked the AAD, which binds the user and the version).
|
|
121
|
+
* - `keyVersion` becomes the proven version, if it is higher (an older genuine wrap never lowers it).
|
|
122
|
+
* - Seen pins are cleared **only** with `confirmedPinReset: true`, after the user explicitly confirms it (for
|
|
123
|
+
* example, when a thief's record narrowed a pin while the stolen device was still live). The confirmation
|
|
124
|
+
* prompt must tell the user to revoke the thief's device FIRST: while it is live, its records still count
|
|
125
|
+
* and would narrow the pins again. The next
|
|
126
|
+
* certifiedSigners call then takes pins from the records live devices have signed.
|
|
127
|
+
* - The seen-revoked set is never cleared: revocation is monotonic.
|
|
128
|
+
*/
|
|
129
|
+
export function resetTrustStateAfterUnlock(state, proof, opts = {}) {
|
|
130
|
+
if (!constantTimeEqual(Buffer.from(masterKeyVerifier(proof.masterKey)), Buffer.from(proof.stored.masterKeyVerifier))) {
|
|
131
|
+
throw new KeyTrustError('the master key does not match its verifier: no proof of the key version');
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
// Never lower: an older genuine wrap (a replayed pre-rotation one) proves only that older version.
|
|
135
|
+
keyVersion: Math.max(state.keyVersion, proof.stored.keyVersion),
|
|
136
|
+
pins: opts.confirmedPinReset === true ? {} : { ...state.pins },
|
|
137
|
+
revoked: [...state.revoked],
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* The trusted signer set, built from `GET /v1/devices/trust`, the master keys the client holds and its
|
|
142
|
+
* persisted TrustState. Build the set for pulls, checkpoints and grants from this, never from the server's
|
|
143
|
+
* device list alone. Persist the returned state. The rules (docs/security/e2e-keys.md, "Revocation"):
|
|
144
|
+
* - A key is certified if a certificate for it verifies under the master key of the certificate's own
|
|
145
|
+
* version (old history stays verifiable after rotation while the client keeps the old master keys).
|
|
146
|
+
* - **Current version only for liveness.** The current version is the highest the client holds or has
|
|
147
|
+
* seen. Only a certificate at that version can make a key live, so a thief with a pre-rotation master key
|
|
148
|
+
* cannot certify a fresh key into live trust. Older certificates carry pinned history only.
|
|
149
|
+
* - **Any valid record revokes its target.** A record whose signature verifies under a key certified at the
|
|
150
|
+
* current version, live, pinned or pending, makes its target non-live for good (TrustState.revoked),
|
|
151
|
+
* whatever the server claims. Records by old-version-only keys are ignored: such a key can never be live.
|
|
152
|
+
* - **Pins come only from live signers, and only ever narrow.** A record sets pins only if its signer is live
|
|
153
|
+
* (a server claim at the current version) and not itself revoked. Several such records: the narrowest pins.
|
|
154
|
+
* The result is always narrowed with the pins this client has seen (TrustState.pins), so neither a withheld
|
|
155
|
+
* record nor a wider record served later can widen or drop a pin. A revoked key with no pins, now or ever,
|
|
156
|
+
* is pending (untrusted; `includePending` returns it for the revocation flow).
|
|
157
|
+
* - **The current version** is the highest of: the versions the client has seen, the account version the
|
|
158
|
+
* server declares, and the master keys held. When it is above every held master key, nothing is live and
|
|
159
|
+
* `keyRotated` is true: tell the user "the account key was rotated: unlock with your passphrase to fetch
|
|
160
|
+
* the new master key".
|
|
161
|
+
*
|
|
162
|
+
* **The caller MUST persist the returned `state`** in the same local transaction as the pull cursor, and pass
|
|
163
|
+
* it back next time. Nothing in core does this yet (the `cleo cloud` commands will); without it the monotonic
|
|
164
|
+
* guarantees above do not hold.
|
|
165
|
+
* - A live key: certified at the current version, called live by the server, never revoked.
|
|
166
|
+
*/
|
|
167
|
+
export function certifiedSigners(masterKeys, userId, trust, state,
|
|
168
|
+
/**
|
|
169
|
+
* The account's key version as the server declares it (`keyVersion` of GET /v1/account/keys), or null
|
|
170
|
+
* when the account has no keys yet. Used for this call only, never persisted. It may raise the current
|
|
171
|
+
* version by at most MAX_ROTATION_STEP above the highest held or proven version: a rotation bumps the
|
|
172
|
+
* version by one. A higher value is a server error (`serverError`), not a rotation.
|
|
173
|
+
*/
|
|
174
|
+
accountKeyVersion, opts = {}) {
|
|
175
|
+
const held = Math.max(0, ...masterKeys.keys());
|
|
176
|
+
const proven = Math.max(state.keyVersion, held);
|
|
177
|
+
const implausible = accountKeyVersion !== null && accountKeyVersion > proven + MAX_ROTATION_STEP;
|
|
178
|
+
const current = Math.max(proven, implausible ? 0 : (accountKeyVersion ?? 0));
|
|
179
|
+
const certified = new Map();
|
|
180
|
+
for (const c of trust.certificates) {
|
|
181
|
+
const mk = masterKeys.get(c.keyVersion);
|
|
182
|
+
if (!mk)
|
|
183
|
+
continue;
|
|
184
|
+
const keys = {
|
|
185
|
+
deviceId: c.deviceId,
|
|
186
|
+
encryptionPublicKey: Buffer.from(c.encryptionPublicKey, 'base64'),
|
|
187
|
+
signingPublicKey: Buffer.from(c.signingPublicKey, 'base64'),
|
|
188
|
+
};
|
|
189
|
+
if (!verifyDeviceCertificate(mk, userId, keys, c.keyVersion, Buffer.from(c.certificate, 'base64')))
|
|
190
|
+
continue;
|
|
191
|
+
const id = `${c.deviceId}/${hex(keys.signingPublicKey)}`;
|
|
192
|
+
const prev = certified.get(id);
|
|
193
|
+
const atCurrent = c.keyVersion === current;
|
|
194
|
+
certified.set(id, {
|
|
195
|
+
deviceId: c.deviceId,
|
|
196
|
+
publicKey: keys.signingPublicKey,
|
|
197
|
+
// An implausible declaration fails closed: nothing is live in this call (nothing is persisted either).
|
|
198
|
+
live: (prev?.live ?? false) || (c.live && atCurrent && !implausible),
|
|
199
|
+
atCurrent: (prev?.atCurrent ?? false) || atCurrent,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
// Every record whose signature verifies under a key of its signer that is certified at the current
|
|
203
|
+
// version, whatever that key's status (live, pinned or pending). An old-version-only key can never be
|
|
204
|
+
// live, and its records touch nothing: a thief with a pre-rotation master key cannot revoke live devices.
|
|
205
|
+
const valid = [];
|
|
206
|
+
for (const r of trust.revocations) {
|
|
207
|
+
const revokedKey = Buffer.from(r.signingPublicKey, 'base64');
|
|
208
|
+
const revokedId = `${r.deviceId}/${hex(revokedKey)}`;
|
|
209
|
+
if (!certified.has(revokedId))
|
|
210
|
+
continue;
|
|
211
|
+
const msg = revocationMessage(userId, r.deviceId, revokedKey, r.pins, r.signerDeviceId);
|
|
212
|
+
const signature = Buffer.from(r.signature, 'base64');
|
|
213
|
+
for (const [signerId, k] of certified) {
|
|
214
|
+
if (k.deviceId === r.signerDeviceId &&
|
|
215
|
+
k.atCurrent &&
|
|
216
|
+
verifyEd25519(k.publicKey, msg, signature)) {
|
|
217
|
+
valid.push({ signerId, revokedId, pins: r.pins });
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const revoked = new Set([
|
|
223
|
+
...state.revoked,
|
|
224
|
+
...Object.keys(state.pins),
|
|
225
|
+
...valid.map((x) => x.revokedId),
|
|
226
|
+
]);
|
|
227
|
+
const pins = new Map();
|
|
228
|
+
for (const x of valid) {
|
|
229
|
+
const signer = certified.get(x.signerId);
|
|
230
|
+
if (!signer?.live || revoked.has(x.signerId))
|
|
231
|
+
continue;
|
|
232
|
+
const prev = pins.get(x.revokedId);
|
|
233
|
+
pins.set(x.revokedId, prev ? narrowerPins(prev, x.pins) : x.pins);
|
|
234
|
+
}
|
|
235
|
+
// Pins only ever narrow: a record served now, even a genuine one by another live signer, can never
|
|
236
|
+
// widen a pin this client has seen, and a withheld record leaves the seen pin in force.
|
|
237
|
+
for (const [id, p] of Object.entries(state.pins)) {
|
|
238
|
+
const now = pins.get(id);
|
|
239
|
+
pins.set(id, now ? narrowerPins(now, p) : p);
|
|
240
|
+
}
|
|
241
|
+
const signers = new Map();
|
|
242
|
+
for (const [id, k] of certified) {
|
|
243
|
+
const pin = pins.get(id);
|
|
244
|
+
const key = pin
|
|
245
|
+
? { publicKey: k.publicKey, pin }
|
|
246
|
+
: k.live && !revoked.has(id)
|
|
247
|
+
? { publicKey: k.publicKey, pin: null }
|
|
248
|
+
: opts.includePending
|
|
249
|
+
? { publicKey: k.publicKey, pin: null, pending: true }
|
|
250
|
+
: null;
|
|
251
|
+
if (!key)
|
|
252
|
+
continue;
|
|
253
|
+
signers.set(k.deviceId, [...(signers.get(k.deviceId) ?? []), key]);
|
|
254
|
+
}
|
|
255
|
+
const next = {
|
|
256
|
+
keyVersion: proven,
|
|
257
|
+
pins: Object.fromEntries([...pins].sort(([a], [b]) => (a < b ? -1 : 1))),
|
|
258
|
+
revoked: [...revoked].sort(),
|
|
259
|
+
};
|
|
260
|
+
// The account moved to a key version this client has no master key for: nothing is live until it
|
|
261
|
+
// unlocks with the passphrase (or the recovery key) and fetches the new master key.
|
|
262
|
+
return {
|
|
263
|
+
signers,
|
|
264
|
+
state: next,
|
|
265
|
+
keyRotated: current > held,
|
|
266
|
+
...(implausible ? { serverError: 'implausible-key-version' } : {}),
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
const revocationMessage = (userId, deviceId, revokedKey, pins, signerDeviceId) => deviceRevocationMessage({
|
|
270
|
+
userId,
|
|
271
|
+
revokedDeviceId: deviceId,
|
|
272
|
+
revokedSigningPublicKeyHex: hex(revokedKey),
|
|
273
|
+
pinsHash: sha256Hex(utf8(revocationPinsCanonical(pins))),
|
|
274
|
+
signerDeviceId,
|
|
275
|
+
});
|
|
276
|
+
/**
|
|
277
|
+
* Revoke one signing key of a device and pin its history (the POST /v1/devices/:id/revocations body).
|
|
278
|
+
* The signer must hold a certified key: after losing every other device, the device that just unlocked
|
|
279
|
+
* with the passphrase certifies itself (a self-grant) and signs this. Compute `pins` from segments and
|
|
280
|
+
* checkpoints this client has itself verified (revocationPins), never from numbers the server supplies.
|
|
281
|
+
*/
|
|
282
|
+
export function createDeviceRevocation(args) {
|
|
283
|
+
const { userId, revoked, pins, signer } = args;
|
|
284
|
+
const msg = revocationMessage(userId, revoked.deviceId, revoked.signingPublicKey, pins, signer.deviceId);
|
|
285
|
+
return {
|
|
286
|
+
signingPublicKey: Buffer.from(revoked.signingPublicKey).toString('base64'),
|
|
287
|
+
pins,
|
|
288
|
+
signerDeviceId: signer.deviceId,
|
|
289
|
+
signature: signEd25519(signer.signing, msg).toString('base64'),
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
const grantMessage = (userId, recipient, keyVersion, sealed, certificate, signerDeviceId) => deviceGrantMessage({
|
|
293
|
+
userId,
|
|
294
|
+
recipientDeviceId: recipient.deviceId,
|
|
295
|
+
recipientEncryptionPublicKeyHex: hex(recipient.encryptionPublicKey),
|
|
296
|
+
recipientSigningPublicKeyHex: hex(recipient.signingPublicKey),
|
|
297
|
+
keyVersion,
|
|
298
|
+
sealedMasterKeyHash: sha256Hex(sealed),
|
|
299
|
+
certificateHex: hex(certificate),
|
|
300
|
+
signerDeviceId,
|
|
301
|
+
});
|
|
302
|
+
/**
|
|
303
|
+
* Grant the master key to a device: seal it to the recipient's X25519 key, certify the recipient under
|
|
304
|
+
* the master key, and sign the whole grant with the signer's Ed25519 key. The signer must hold the
|
|
305
|
+
* master key legitimately: a device that unlocked by passphrase or recovery key grants to itself, and a
|
|
306
|
+
* trusted device grants to another (key rotation). The result is the PUT /v1/devices/:id/key body.
|
|
307
|
+
*/
|
|
308
|
+
export function createDeviceGrant(args) {
|
|
309
|
+
const { masterKey, userId, keyVersion, recipient, signer } = args;
|
|
310
|
+
const sealed = sealTo(recipient.encryptionPublicKey, masterKey, deviceContext(userId, recipient.deviceId, keyVersion));
|
|
311
|
+
const certificate = deviceCertificate(masterKey, userId, recipient, keyVersion);
|
|
312
|
+
const signature = signEd25519(signer.signing, grantMessage(userId, recipient, keyVersion, sealed, certificate, signer.deviceId));
|
|
313
|
+
return {
|
|
314
|
+
sealedMasterKey: sealed.toString('base64'),
|
|
315
|
+
keyVersion,
|
|
316
|
+
certificate: certificate.toString('base64'),
|
|
317
|
+
signerDeviceId: signer.deviceId,
|
|
318
|
+
grantSignature: signature.toString('base64'),
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Open a master key grant made to this device, after checking it came from a trusted signer. The checks,
|
|
323
|
+
* in order: the signer is in `trustedSigners` (the device's own signing key for a self-grant, or devices
|
|
324
|
+
* certified under a master key this device already holds); the signature verifies over a message rebuilt
|
|
325
|
+
* from this device's OWN keys, so a grant made for other keys fails; the sealed box opens; and the key
|
|
326
|
+
* inside certifies this device, so the key and the signer's intent agree. The server's verifier is not
|
|
327
|
+
* consulted: it is server-supplied and proves nothing.
|
|
328
|
+
*/
|
|
329
|
+
export function openDeviceGrant(args) {
|
|
330
|
+
const { userId, device, grant, trustedSigners } = args;
|
|
331
|
+
// Only a live key vouches for a new grant: a revoked device's pin covers its history, not new keys.
|
|
332
|
+
const candidates = liveKeys(trustedSigners, grant.signerDeviceId);
|
|
333
|
+
if (candidates.length === 0)
|
|
334
|
+
throw new KeyTrustError(`key grant is signed by untrusted device ${grant.signerDeviceId}`);
|
|
335
|
+
const me = {
|
|
336
|
+
deviceId: device.deviceId,
|
|
337
|
+
encryptionPublicKey: device.encryption.publicKey,
|
|
338
|
+
signingPublicKey: device.signingPublicKey,
|
|
339
|
+
};
|
|
340
|
+
const sealed = Buffer.from(grant.sealedMasterKey, 'base64');
|
|
341
|
+
const certificate = Buffer.from(grant.certificate, 'base64');
|
|
342
|
+
const msg = grantMessage(userId, me, grant.keyVersion, sealed, certificate, grant.signerDeviceId);
|
|
343
|
+
const grantSignature = Buffer.from(grant.grantSignature, 'base64');
|
|
344
|
+
if (!candidates.some((k) => verifyEd25519(k.publicKey, msg, grantSignature))) {
|
|
345
|
+
throw new KeyTrustError('key grant signature does not verify');
|
|
346
|
+
}
|
|
347
|
+
const mk = openSealed(device.encryption, sealed, deviceContext(userId, device.deviceId, grant.keyVersion));
|
|
348
|
+
if (!verifyDeviceCertificate(mk, userId, me, grant.keyVersion, certificate)) {
|
|
349
|
+
throw new KeyTrustError('granted master key does not certify this device');
|
|
350
|
+
}
|
|
351
|
+
return mk;
|
|
352
|
+
}
|
|
353
|
+
export const newProjectKey = randomKey;
|
|
354
|
+
export function wrapProjectKey(mk, pdk, projectId, keyVersion) {
|
|
355
|
+
return seal(mk, pdk, 'pdk-wrap', pdkContext(projectId, keyVersion)).toString('base64');
|
|
356
|
+
}
|
|
357
|
+
export function unwrapProjectKey(mk, wrapped, projectId, keyVersion) {
|
|
358
|
+
return open(mk, Buffer.from(wrapped, 'base64'), 'pdk-wrap', pdkContext(projectId, keyVersion));
|
|
359
|
+
}
|
|
360
|
+
/** Key for the personal home stream. It is derived, so it never needs storing or sharing. */
|
|
361
|
+
export const homeStreamKey = (mk) => deriveKey(mk, 'home-stream');
|
|
362
|
+
//# sourceMappingURL=keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/cloud/keys.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Manifest, TableDeltas } from '@cleocode/contracts/cloud';
|
|
2
|
+
export type ManifestVerdict = {
|
|
3
|
+
ok: true;
|
|
4
|
+
} | {
|
|
5
|
+
ok: false;
|
|
6
|
+
code: 'E_REGRESSION';
|
|
7
|
+
tables: RegressionFinding[];
|
|
8
|
+
} | {
|
|
9
|
+
ok: false;
|
|
10
|
+
code: 'E_SCHEMA_AHEAD';
|
|
11
|
+
schemaVersion: number;
|
|
12
|
+
maxAccepted: number;
|
|
13
|
+
};
|
|
14
|
+
export interface RegressionFinding {
|
|
15
|
+
table: string;
|
|
16
|
+
parentRows: number;
|
|
17
|
+
created: number;
|
|
18
|
+
deleted: number;
|
|
19
|
+
expectedRows: number;
|
|
20
|
+
actualRows: number;
|
|
21
|
+
reason: 'missing-table' | 'count-mismatch';
|
|
22
|
+
}
|
|
23
|
+
/** Sum the per-table deltas of every segment folded into a checkpoint. */
|
|
24
|
+
export declare function sumDeltas(deltas: readonly TableDeltas[]): TableDeltas;
|
|
25
|
+
/**
|
|
26
|
+
* Decide whether a new checkpoint manifest may replace its parent.
|
|
27
|
+
*
|
|
28
|
+
* The rule is exact, not a heuristic: for every table,
|
|
29
|
+
* `next.rows === parent.rows + created - deleted`, summed over the segments between the two
|
|
30
|
+
* checkpoints. Every shrink therefore needs a tombstone op to back it. A table present in the
|
|
31
|
+
* parent must still be present, even with 0 rows.
|
|
32
|
+
*
|
|
33
|
+
* With no parent (genesis), only the schema version is checked.
|
|
34
|
+
*/
|
|
35
|
+
export declare function checkManifest(parent: Manifest | null, next: Manifest, between: TableDeltas, maxAcceptedSchemaVersion: number): ManifestVerdict;
|
|
36
|
+
//# sourceMappingURL=manifest-check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-check.d.ts","sourceRoot":"","sources":["../../src/cloud/manifest-check.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAEvE,MAAM,MAAM,eAAe,GACvB;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GACZ;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,iBAAiB,EAAE,CAAA;CAAE,GAChE;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtF,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,eAAe,GAAG,gBAAgB,CAAC;CAC5C;AAED,0EAA0E;AAC1E,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,WAAW,CASrE;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,QAAQ,GAAG,IAAI,EACvB,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,WAAW,EACpB,wBAAwB,EAAE,MAAM,GAC/B,eAAe,CA+CjB"}
|