@sema-agent/server 1.323.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/approval-hmac.d.ts +40 -0
- package/dist/approval-hmac.js +67 -0
- package/dist/approval.d.ts +31 -0
- package/dist/approval.js +72 -4
- package/dist/audit.d.ts +26 -0
- package/dist/audit.js +40 -1
- package/dist/auth-bridge.d.ts +10 -0
- package/dist/auth-bridge.js +47 -4
- package/dist/auth-keys.d.ts +19 -0
- package/dist/auth-keys.js +13 -0
- package/dist/bake-runner/main.d.ts +5 -0
- package/dist/bake-runner/main.js +43 -4
- package/dist/bake-runner/protocol.d.ts +57 -0
- package/dist/bake-runner/protocol.js +58 -3
- package/dist/bake-runner/runner.d.ts +54 -0
- package/dist/bake-runner/runner.js +87 -5
- package/dist/bench/l8/artifact.d.ts +63 -0
- package/dist/bench/l8/artifact.js +61 -2
- package/dist/bench/l8/escape.d.ts +36 -0
- package/dist/bench/l8/escape.js +25 -0
- package/dist/bench/l8/index.d.ts +14 -0
- package/dist/bench/l8/index.js +14 -0
- package/dist/bench/l8/probes.d.ts +74 -0
- package/dist/bench/l8/probes.js +60 -0
- package/dist/bench/l8/run-probes.d.ts +43 -0
- package/dist/bench/l8/run-probes.js +45 -2
- package/dist/bench/s1/arms.d.ts +126 -0
- package/dist/bench/s1/arms.js +188 -13
- package/dist/bench/s1/live-deps.d.ts +66 -0
- package/dist/bench/s1/live-deps.js +249 -11
- package/dist/bench/s1/oracle.d.ts +49 -0
- package/dist/bench/s1/oracle.js +36 -1
- package/dist/bench/s1/repair-oracle-adapter.d.ts +33 -0
- package/dist/bench/s1/repair-oracle-adapter.js +30 -0
- package/dist/bench/s1/reviewer.d.ts +38 -0
- package/dist/bench/s1/reviewer.js +34 -0
- package/dist/bench/s1/row.d.ts +77 -0
- package/dist/bench/s1/row.js +62 -0
- package/dist/bench/s1/run-firm.d.ts +47 -0
- package/dist/bench/s1/run-firm.js +70 -4
- package/dist/bench/s1/runner-ctx.d.ts +71 -0
- package/dist/bench/s1/runner-ctx.js +36 -0
- package/dist/bench/s1/tasks.d.ts +108 -0
- package/dist/bench/s1/tasks.js +115 -0
- package/dist/boot-reclaim.d.ts +19 -0
- package/dist/boot-reclaim.js +20 -0
- package/dist/brain.d.ts +25 -0
- package/dist/brain.js +61 -1
- package/dist/budget.d.ts +66 -0
- package/dist/budget.js +128 -4
- package/dist/capabilities/builtin-tools.d.ts +3 -0
- package/dist/capabilities/builtin-tools.js +3 -0
- package/dist/capabilities/center-plugins.d.ts +17 -1
- package/dist/capabilities/center-plugins.js +45 -4
- package/dist/capabilities/center-prompts.d.ts +46 -0
- package/dist/capabilities/center-prompts.js +57 -3
- package/dist/capabilities/code-review-council.d.ts +28 -0
- package/dist/capabilities/code-review-council.js +40 -7
- package/dist/capabilities/collab-wire.d.ts +2 -0
- package/dist/capabilities/collab-workflows.d.ts +7 -0
- package/dist/capabilities/collab-workflows.js +44 -1
- package/dist/capabilities/oa-tools.d.ts +6 -0
- package/dist/capabilities/oa-tools.js +10 -0
- package/dist/capabilities/prompt.d.ts +14 -0
- package/dist/capabilities/prompt.js +14 -0
- package/dist/capabilities/prompts/code-review.d.ts +14 -0
- package/dist/capabilities/prompts/code-review.js +14 -0
- package/dist/capabilities/prompts/identity.d.ts +6 -0
- package/dist/capabilities/prompts/identity.js +6 -0
- package/dist/capabilities/prompts/team.d.ts +4 -0
- package/dist/capabilities/prompts/team.js +4 -0
- package/dist/capabilities/repo-tools.d.ts +11 -0
- package/dist/capabilities/repo-tools.js +8 -0
- package/dist/capabilities/sandbox-file-send.d.ts +95 -0
- package/dist/capabilities/sandbox-file-send.js +91 -3
- package/dist/capabilities/scenarios.d.ts +130 -0
- package/dist/capabilities/scenarios.js +180 -7
- package/dist/capabilities/select-environment-tool.d.ts +7 -0
- package/dist/capabilities/select-environment-tool.js +30 -0
- package/dist/capabilities/send-user-file-tool.d.ts +33 -0
- package/dist/capabilities/send-user-file-tool.js +65 -1
- package/dist/capabilities/skills.d.ts +29 -0
- package/dist/capabilities/skills.js +13 -2
- package/dist/capabilities/team.d.ts +22 -0
- package/dist/capabilities/team.js +22 -2
- package/dist/capabilities/tool-defer.d.ts +26 -0
- package/dist/capabilities/tool-defer.js +3 -0
- package/dist/config-center/apply-effective.d.ts +65 -0
- package/dist/config-center/apply-effective.js +204 -12
- package/dist/config-center/http-client.d.ts +34 -0
- package/dist/config-center/http-client.js +68 -0
- package/dist/config-center/restart-signal.d.ts +22 -0
- package/dist/config-center/restart-signal.js +39 -0
- package/dist/config-center/skills-mcp.d.ts +20 -1
- package/dist/config-center/skills-mcp.js +42 -7
- package/dist/config-center/types.d.ts +92 -1
- package/dist/config-lkg.d.ts +12 -0
- package/dist/config-lkg.js +41 -0
- package/dist/config-provider.d.ts +78 -0
- package/dist/config-provider.js +165 -2
- package/dist/config-types.d.ts +546 -0
- package/dist/config.d.ts +64 -0
- package/dist/config.js +455 -60
- package/dist/degenerate-instrument.d.ts +38 -0
- package/dist/degenerate-instrument.js +55 -3
- package/dist/elicitation.d.ts +39 -0
- package/dist/elicitation.js +87 -3
- package/dist/env-facts.d.ts +61 -0
- package/dist/env-facts.js +73 -7
- package/dist/fleet/fleet-bus.d.ts +185 -0
- package/dist/fleet/fleet-bus.js +333 -27
- package/dist/fleet/subagent-tail-bus.d.ts +11 -0
- package/dist/fleet/subagent-tail-bus.js +33 -2
- package/dist/fleet-client.d.ts +38 -0
- package/dist/fleet-client.js +44 -9
- package/dist/fleet-lease.d.ts +46 -0
- package/dist/fleet-lease.js +73 -5
- package/dist/hooks/branch-transcript.d.ts +8 -0
- package/dist/hooks/branch-transcript.js +33 -0
- package/dist/hooks/cc-stop-prompt.d.ts +42 -0
- package/dist/hooks/cc-stop-prompt.js +43 -1
- package/dist/hooks/hook-llm.d.ts +15 -0
- package/dist/hooks/hook-llm.js +47 -0
- package/dist/hooks/hook-runner.d.ts +89 -0
- package/dist/hooks/hook-runner.js +327 -18
- package/dist/http/idempotency.d.ts +31 -0
- package/dist/http/idempotency.js +34 -0
- package/dist/http/principal-gate.d.ts +17 -0
- package/dist/http/principal-gate.js +35 -3
- package/dist/http/route-ctx.d.ts +36 -0
- package/dist/http/routes/approvals-assistant.d.ts +25 -0
- package/dist/http/routes/approvals-assistant.js +253 -23
- package/dist/http/routes/attachments.js +22 -4
- package/dist/http/routes/capabilities.d.ts +7 -0
- package/dist/http/routes/capabilities.js +202 -1
- package/dist/http/routes/fleet.d.ts +6 -0
- package/dist/http/routes/fleet.js +94 -5
- package/dist/http/routes/images.d.ts +17 -0
- package/dist/http/routes/images.js +222 -14
- package/dist/http/routes/leader.d.ts +7 -0
- package/dist/http/routes/leader.js +10 -0
- package/dist/http/routes/memory-policy.d.ts +6 -0
- package/dist/http/routes/memory-policy.js +38 -6
- package/dist/http/routes/notify-wake.d.ts +10 -0
- package/dist/http/routes/notify-wake.js +19 -3
- package/dist/http/routes/observability.d.ts +6 -0
- package/dist/http/routes/observability.js +19 -2
- package/dist/http/routes/runs.d.ts +15 -0
- package/dist/http/routes/runs.js +464 -41
- package/dist/http/routes/session-sync.d.ts +15 -0
- package/dist/http/routes/session-sync.js +229 -19
- package/dist/http/routes/sessions-list.d.ts +6 -0
- package/dist/http/routes/sessions-list.js +35 -4
- package/dist/http/routes/sessions.d.ts +14 -0
- package/dist/http/routes/sessions.js +176 -31
- package/dist/http/routes/side-query.d.ts +8 -0
- package/dist/http/routes/side-query.js +26 -1
- package/dist/http/routes/tasks.d.ts +18 -0
- package/dist/http/routes/tasks.js +501 -38
- package/dist/http/routes/trace-usage.d.ts +10 -0
- package/dist/http/routes/trace-usage.js +66 -14
- package/dist/http/routes/workflows.d.ts +12 -0
- package/dist/http/routes/workflows.js +180 -19
- package/dist/http/run-meta.d.ts +11 -0
- package/dist/http/run-meta.js +6 -0
- package/dist/http/send.d.ts +19 -0
- package/dist/http/send.js +11 -0
- package/dist/http/server.d.ts +255 -0
- package/dist/http/server.js +921 -75
- package/dist/http/sse-log.d.ts +15 -0
- package/dist/http/sse-log.js +16 -0
- package/dist/http/tar.d.ts +9 -0
- package/dist/http/tar.js +21 -5
- package/dist/http/wire-gate.d.ts +9 -0
- package/dist/http/wire-gate.js +9 -0
- package/dist/http/wire-types.d.ts +187 -0
- package/dist/http/workspace-content.d.ts +8 -0
- package/dist/http/workspace-content.js +10 -0
- package/dist/images/bake-validate.d.ts +63 -0
- package/dist/images/bake-validate.js +71 -1
- package/dist/images/manifest.d.ts +19 -0
- package/dist/images/manifest.js +6 -1
- package/dist/index.d.ts +1 -5
- package/dist/index.js +10 -5
- package/dist/key-resolver.d.ts +23 -0
- package/dist/key-resolver.js +27 -2
- package/dist/leader/diffout.d.ts +23 -0
- package/dist/leader/diffout.js +8 -1
- package/dist/leader/diffup.d.ts +32 -0
- package/dist/leader/diffup.js +43 -0
- package/dist/leader/endpoint.d.ts +20 -0
- package/dist/leader/endpoint.js +25 -2
- package/dist/leader/fanout.d.ts +60 -0
- package/dist/leader/fanout.js +29 -3
- package/dist/leader/grader-env-factory.d.ts +74 -0
- package/dist/leader/grader-env-factory.js +62 -3
- package/dist/leader/leader.d.ts +97 -0
- package/dist/leader/leader.js +151 -4
- package/dist/leader/merge.d.ts +94 -0
- package/dist/leader/merge.js +112 -9
- package/dist/leader/planner.d.ts +52 -0
- package/dist/leader/planner.js +47 -3
- package/dist/leader/repair-oracle.d.ts +61 -0
- package/dist/leader/repair-oracle.js +59 -1
- package/dist/leader/repair-wire.d.ts +78 -0
- package/dist/leader/repair-wire.js +79 -2
- package/dist/leader/wire.d.ts +79 -0
- package/dist/leader/wire.js +255 -8
- package/dist/lsp/e2b-bridge.d.ts +16 -0
- package/dist/lsp/e2b-bridge.js +32 -4
- package/dist/lsp/e2b-manager.d.ts +10 -0
- package/dist/lsp/e2b-manager.js +18 -2
- package/dist/lsp/lsp-frames.d.ts +12 -0
- package/dist/lsp/lsp-frames.js +12 -0
- package/dist/lsp/manager.d.ts +12 -0
- package/dist/lsp/manager.js +35 -2
- package/dist/lsp/types.d.ts +10 -0
- package/dist/lsp/ws-transport.d.ts +12 -0
- package/dist/lsp/ws-transport.js +53 -5
- package/dist/lsp-evict.d.ts +14 -0
- package/dist/lsp-evict.js +15 -1
- package/dist/main.js +2132 -96
- package/dist/memory-export.d.ts +1 -0
- package/dist/memory-export.js +4 -0
- package/dist/memory-scope.d.ts +49 -0
- package/dist/memory-scope.js +87 -4
- package/dist/memory-sync-client.d.ts +24 -0
- package/dist/memory-sync-client.js +41 -2
- package/dist/memory-sync.d.ts +23 -0
- package/dist/memory-sync.js +70 -1
- package/dist/model-select.d.ts +39 -0
- package/dist/model-select.js +42 -1
- package/dist/observability/cost-quota.d.ts +20 -0
- package/dist/observability/cost-quota.js +4 -0
- package/dist/observability/cost-taxonomy.d.ts +45 -0
- package/dist/observability/cost-taxonomy.js +34 -0
- package/dist/observability/logger.d.ts +1 -0
- package/dist/observability/logger.js +6 -0
- package/dist/observability/metrics.d.ts +13 -0
- package/dist/observability/metrics.js +63 -0
- package/dist/observability/otel-exporter.d.ts +9 -0
- package/dist/observability/otel-exporter.js +11 -3
- package/dist/observability/principal-context.d.ts +9 -0
- package/dist/observability/principal-context.js +9 -0
- package/dist/observability/prompt-manifest.d.ts +37 -0
- package/dist/observability/prompt-manifest.js +35 -1
- package/dist/observability/rate-limit.d.ts +10 -0
- package/dist/observability/rate-limit.js +1 -0
- package/dist/observability/tool-trace.d.ts +24 -0
- package/dist/observability/tool-trace.js +41 -1
- package/dist/orchestration/hardened-vm-runner.d.ts +107 -0
- package/dist/orchestration/hardened-vm-runner.js +119 -4
- package/dist/orchestration/hardened-vm-worker-runner.d.ts +14 -0
- package/dist/orchestration/hardened-vm-worker-runner.js +26 -1
- package/dist/orchestration/hardened-vm-worker.js +27 -0
- package/dist/orchestration/subagent-steer.d.ts +44 -0
- package/dist/orchestration/subagent-steer.js +45 -1
- package/dist/orchestration/workflow-agent-steer.d.ts +54 -0
- package/dist/orchestration/workflow-agent-steer.js +80 -1
- package/dist/orchestration/workflow-completion-inbox.d.ts +189 -2
- package/dist/orchestration/workflow-completion-inbox.js +283 -32
- package/dist/orchestration/workflow-notify-journal.d.ts +132 -1
- package/dist/orchestration/workflow-notify-journal.js +187 -13
- package/dist/parked-decide.d.ts +61 -0
- package/dist/parked-decide.js +58 -1
- package/dist/per-task-image.d.ts +54 -0
- package/dist/per-task-image.js +41 -0
- package/dist/plan-cache-probe.d.ts +35 -0
- package/dist/plan-cache-probe.js +18 -3
- package/dist/plugins/approval-exemption-store.d.ts +7 -0
- package/dist/plugins/approval-exemption-store.js +28 -2
- package/dist/plugins/approval-store-sql.d.ts +64 -0
- package/dist/plugins/approval-store-sql.js +32 -0
- package/dist/plugins/background-agent-store-sql.d.ts +55 -0
- package/dist/plugins/background-agent-store-sql.js +91 -4
- package/dist/plugins/background-shell-support.d.ts +98 -0
- package/dist/plugins/background-shell-support.js +117 -13
- package/dist/plugins/blob-backend.d.ts +104 -0
- package/dist/plugins/blob-backend.js +163 -6
- package/dist/plugins/breaker-state-sql.d.ts +65 -1
- package/dist/plugins/breaker-state-sql.js +46 -8
- package/dist/plugins/caching-session-store.d.ts +42 -0
- package/dist/plugins/caching-session-store.js +63 -3
- package/dist/plugins/checkpoint-store-sql.d.ts +179 -0
- package/dist/plugins/checkpoint-store-sql.js +239 -11
- package/dist/plugins/file-outcome-sink.d.ts +4 -0
- package/dist/plugins/file-outcome-sink.js +9 -0
- package/dist/plugins/file-resume-anchor-store.d.ts +20 -0
- package/dist/plugins/file-resume-anchor-store.js +43 -4
- package/dist/plugins/file-run-store.d.ts +90 -0
- package/dist/plugins/file-run-store.js +145 -13
- package/dist/plugins/file-snapshot-store-sql.d.ts +133 -1
- package/dist/plugins/file-snapshot-store-sql.js +178 -10
- package/dist/plugins/file-workflow-journal-store.d.ts +10 -0
- package/dist/plugins/file-workflow-journal-store.js +10 -0
- package/dist/plugins/fork-routing-session-store.d.ts +47 -0
- package/dist/plugins/fork-routing-session-store.js +51 -3
- package/dist/plugins/host-platform.d.ts +69 -0
- package/dist/plugins/host-platform.js +81 -2
- package/dist/plugins/image-bake-store-sql.d.ts +136 -1
- package/dist/plugins/image-bake-store-sql.js +241 -7
- package/dist/plugins/image-index-sql.d.ts +46 -0
- package/dist/plugins/image-index-sql.js +113 -4
- package/dist/plugins/k8s-bg-scripts.d.ts +34 -0
- package/dist/plugins/k8s-bg-scripts.js +88 -4
- package/dist/plugins/k8s-exec-protocol.d.ts +33 -0
- package/dist/plugins/k8s-exec-protocol.js +41 -0
- package/dist/plugins/local-checkpoint-store.d.ts +40 -0
- package/dist/plugins/local-checkpoint-store.js +86 -7
- package/dist/plugins/local-session-store.d.ts +157 -0
- package/dist/plugins/local-session-store.js +289 -34
- package/dist/plugins/local-task-attachment-store.js +14 -2
- package/dist/plugins/mailbox-store-sql.d.ts +38 -0
- package/dist/plugins/mailbox-store-sql.js +39 -6
- package/dist/plugins/memory-engine-pg.d.ts +30 -0
- package/dist/plugins/memory-engine-pg.js +122 -4
- package/dist/plugins/memory-engine-tidb.d.ts +26 -0
- package/dist/plugins/memory-engine-tidb.js +115 -5
- package/dist/plugins/memory-engine-vector-util.d.ts +5 -0
- package/dist/plugins/memory-engine-vector-util.js +5 -0
- package/dist/plugins/memory-resume-anchor-store.d.ts +8 -0
- package/dist/plugins/memory-resume-anchor-store.js +17 -0
- package/dist/plugins/memory-run-store.d.ts +63 -0
- package/dist/plugins/memory-run-store.js +73 -8
- package/dist/plugins/memory-session-policy-store.d.ts +17 -0
- package/dist/plugins/memory-session-policy-store.js +17 -0
- package/dist/plugins/memory-sync-store-pg.d.ts +42 -0
- package/dist/plugins/memory-sync-store-pg.js +45 -2
- package/dist/plugins/memory-sync-store-tidb.d.ts +9 -0
- package/dist/plugins/memory-sync-store-tidb.js +31 -1
- package/dist/plugins/outcome-ledger-sql.d.ts +63 -0
- package/dist/plugins/outcome-ledger-sql.js +97 -3
- package/dist/plugins/pg-approval-store.d.ts +7 -0
- package/dist/plugins/pg-approval-store.js +7 -0
- package/dist/plugins/pg-breaker-state.d.ts +6 -0
- package/dist/plugins/pg-breaker-state.js +6 -0
- package/dist/plugins/pg-checkpoint-store.d.ts +8 -0
- package/dist/plugins/pg-checkpoint-store.js +8 -0
- package/dist/plugins/pg-cost-quota.d.ts +17 -0
- package/dist/plugins/pg-cost-quota.js +6 -0
- package/dist/plugins/pg-file-snapshot-store.d.ts +6 -0
- package/dist/plugins/pg-file-snapshot-store.js +6 -0
- package/dist/plugins/pg-image-bake.d.ts +9 -0
- package/dist/plugins/pg-image-bake.js +9 -0
- package/dist/plugins/pg-image-index.d.ts +9 -0
- package/dist/plugins/pg-image-index.js +9 -0
- package/dist/plugins/pg-outcome-ledger.d.ts +9 -0
- package/dist/plugins/pg-outcome-ledger.js +9 -0
- package/dist/plugins/pg-pool.d.ts +50 -0
- package/dist/plugins/pg-pool.js +78 -0
- package/dist/plugins/pg-query.d.ts +11 -0
- package/dist/plugins/pg-rate-limiter.d.ts +23 -0
- package/dist/plugins/pg-rate-limiter.js +12 -2
- package/dist/plugins/pg-resume-anchor-store.d.ts +5 -0
- package/dist/plugins/pg-resume-anchor-store.js +5 -0
- package/dist/plugins/pg-run-store.d.ts +7 -0
- package/dist/plugins/pg-run-store.js +7 -0
- package/dist/plugins/pg-safe-json.d.ts +13 -0
- package/dist/plugins/pg-safe-json.js +40 -4
- package/dist/plugins/pg-session-policy-store.d.ts +5 -0
- package/dist/plugins/pg-session-policy-store.js +5 -0
- package/dist/plugins/pg-session-storage.d.ts +72 -0
- package/dist/plugins/pg-session-storage.js +152 -20
- package/dist/plugins/pg-session-store.d.ts +10 -0
- package/dist/plugins/pg-session-store.js +10 -0
- package/dist/plugins/pg-tool-result-store.d.ts +7 -0
- package/dist/plugins/pg-tool-result-store.js +7 -0
- package/dist/plugins/pg-workflow-journal-store.d.ts +7 -0
- package/dist/plugins/pg-workflow-journal-store.js +7 -0
- package/dist/plugins/pg-workflow-run-store.d.ts +7 -0
- package/dist/plugins/pg-workflow-run-store.js +7 -0
- package/dist/plugins/posix-shell-fs.d.ts +3 -0
- package/dist/plugins/posix-shell-fs.js +31 -1
- package/dist/plugins/remote-env-adb.d.ts +25 -0
- package/dist/plugins/remote-env-adb.js +95 -12
- package/dist/plugins/remote-env-e2b.d.ts +146 -0
- package/dist/plugins/remote-env-e2b.js +371 -40
- package/dist/plugins/remote-env-file-error.d.ts +34 -0
- package/dist/plugins/remote-env-file-error.js +37 -0
- package/dist/plugins/remote-env-host.d.ts +151 -0
- package/dist/plugins/remote-env-host.js +468 -70
- package/dist/plugins/remote-env-k8s.d.ts +135 -0
- package/dist/plugins/remote-env-k8s.js +318 -32
- package/dist/plugins/remote-env-local-docker.d.ts +65 -0
- package/dist/plugins/remote-env-local-docker.js +149 -24
- package/dist/plugins/remote-env-ssh.d.ts +35 -0
- package/dist/plugins/remote-env-ssh.js +117 -20
- package/dist/plugins/remote-scratchpad.d.ts +38 -0
- package/dist/plugins/remote-scratchpad.js +32 -2
- package/dist/plugins/remote-shell.d.ts +22 -0
- package/dist/plugins/remote-shell.js +27 -1
- package/dist/plugins/resume-anchor-store-sql.d.ts +28 -0
- package/dist/plugins/resume-anchor-store-sql.js +11 -0
- package/dist/plugins/roster-store-sql.d.ts +27 -0
- package/dist/plugins/roster-store-sql.js +54 -0
- package/dist/plugins/run-store-sql.d.ts +194 -0
- package/dist/plugins/run-store-sql.js +210 -9
- package/dist/plugins/s3-presign.d.ts +20 -0
- package/dist/plugins/s3-presign.js +49 -2
- package/dist/plugins/scheduler-support.d.ts +12 -0
- package/dist/plugins/scheduler-support.js +75 -3
- package/dist/plugins/send-file-ledger.d.ts +15 -0
- package/dist/plugins/send-file-ledger.js +53 -4
- package/dist/plugins/send-user-file.d.ts +77 -0
- package/dist/plugins/send-user-file.js +92 -4
- package/dist/plugins/session-policy-store-sql.d.ts +15 -0
- package/dist/plugins/session-policy-store-sql.js +75 -3
- package/dist/plugins/session-store.d.ts +45 -0
- package/dist/plugins/session-store.js +51 -0
- package/dist/plugins/sql-driver.d.ts +77 -0
- package/dist/plugins/sql-driver.js +4 -0
- package/dist/plugins/sql-escape.d.ts +8 -0
- package/dist/plugins/sql-escape.js +8 -0
- package/dist/plugins/sql-row-helpers.d.ts +25 -0
- package/dist/plugins/sql-row-helpers.js +25 -0
- package/dist/plugins/store-backend.d.ts +103 -0
- package/dist/plugins/store-backend.js +120 -27
- package/dist/plugins/store-contracts.d.ts +62 -0
- package/dist/plugins/store-contracts.js +3 -0
- package/dist/plugins/task-attachment-store.d.ts +60 -0
- package/dist/plugins/task-attachment-store.js +49 -3
- package/dist/plugins/task-list-store-sql.d.ts +25 -0
- package/dist/plugins/task-list-store-sql.js +21 -0
- package/dist/plugins/tidb-approval-store.d.ts +6 -0
- package/dist/plugins/tidb-approval-store.js +6 -0
- package/dist/plugins/tidb-breaker-state.d.ts +5 -0
- package/dist/plugins/tidb-breaker-state.js +5 -0
- package/dist/plugins/tidb-checkpoint-store.d.ts +7 -0
- package/dist/plugins/tidb-checkpoint-store.js +7 -0
- package/dist/plugins/tidb-cost-quota.d.ts +6 -0
- package/dist/plugins/tidb-cost-quota.js +1 -0
- package/dist/plugins/tidb-file-snapshot-store.d.ts +6 -0
- package/dist/plugins/tidb-file-snapshot-store.js +6 -0
- package/dist/plugins/tidb-image-bake.d.ts +8 -0
- package/dist/plugins/tidb-image-bake.js +8 -0
- package/dist/plugins/tidb-image-index.d.ts +8 -0
- package/dist/plugins/tidb-image-index.js +8 -0
- package/dist/plugins/tidb-outcome-ledger.d.ts +10 -0
- package/dist/plugins/tidb-outcome-ledger.js +10 -0
- package/dist/plugins/tidb-pool.d.ts +56 -0
- package/dist/plugins/tidb-pool.js +181 -1
- package/dist/plugins/tidb-rate-limiter.d.ts +11 -0
- package/dist/plugins/tidb-rate-limiter.js +5 -2
- package/dist/plugins/tidb-resume-anchor-store.d.ts +5 -0
- package/dist/plugins/tidb-resume-anchor-store.js +5 -0
- package/dist/plugins/tidb-run-store.d.ts +7 -0
- package/dist/plugins/tidb-run-store.js +7 -0
- package/dist/plugins/tidb-session-policy-store.d.ts +5 -0
- package/dist/plugins/tidb-session-policy-store.js +5 -0
- package/dist/plugins/tidb-session-storage.d.ts +43 -0
- package/dist/plugins/tidb-session-storage.js +62 -3
- package/dist/plugins/tidb-session-store.d.ts +142 -0
- package/dist/plugins/tidb-session-store.js +264 -16
- package/dist/plugins/tidb-tool-result-store.d.ts +5 -0
- package/dist/plugins/tidb-tool-result-store.js +7 -0
- package/dist/plugins/tidb-workflow-journal-store.d.ts +7 -0
- package/dist/plugins/tidb-workflow-journal-store.js +7 -0
- package/dist/plugins/tidb-workflow-run-store.d.ts +8 -0
- package/dist/plugins/tidb-workflow-run-store.js +8 -0
- package/dist/plugins/tool-result-store-sql.d.ts +58 -0
- package/dist/plugins/tool-result-store-sql.js +38 -2
- package/dist/plugins/web-search.d.ts +35 -0
- package/dist/plugins/web-search.js +45 -9
- package/dist/plugins/workflow-journal-limits.d.ts +10 -0
- package/dist/plugins/workflow-journal-limits.js +10 -0
- package/dist/plugins/workflow-journal-store-sql.d.ts +78 -0
- package/dist/plugins/workflow-journal-store-sql.js +58 -2
- package/dist/plugins/workflow-run-store-sql.d.ts +84 -0
- package/dist/plugins/workflow-run-store-sql.js +84 -6
- package/dist/plugins/worktree-isolation.d.ts +45 -0
- package/dist/plugins/worktree-isolation.js +105 -6
- package/dist/plugins/write-behind-counter.d.ts +56 -1
- package/dist/plugins/write-behind-counter.js +53 -14
- package/dist/principal-jwt.d.ts +24 -0
- package/dist/principal-jwt.js +60 -5
- package/dist/project-memory.d.ts +22 -0
- package/dist/project-memory.js +144 -15
- package/dist/prompts-domain-validate.d.ts +28 -0
- package/dist/prompts-domain-validate.js +42 -1
- package/dist/question.d.ts +33 -0
- package/dist/question.js +69 -2
- package/dist/resource-suspend.d.ts +21 -0
- package/dist/resource-suspend.js +16 -0
- package/dist/router/route-orchestration.d.ts +78 -0
- package/dist/router/route-orchestration.js +77 -0
- package/dist/run-local.d.ts +32 -0
- package/dist/run-local.js +172 -8
- package/dist/runs.d.ts +189 -4
- package/dist/runs.js +465 -24
- package/dist/runtime-caps-resolver.d.ts +106 -0
- package/dist/runtime-caps-resolver.js +89 -4
- package/dist/runtime-governance.d.ts +84 -0
- package/dist/runtime-governance.js +127 -1
- package/dist/sandbox-pkg-source.d.ts +23 -0
- package/dist/sandbox-pkg-source.js +37 -0
- package/dist/sealed-key.d.ts +54 -0
- package/dist/sealed-key.js +68 -3
- package/dist/security.d.ts +108 -0
- package/dist/security.js +145 -6
- package/dist/sema-registry.d.ts +21 -0
- package/dist/sema-registry.js +21 -0
- package/dist/session-leaf-bus.d.ts +31 -0
- package/dist/session-leaf-bus.js +32 -0
- package/dist/session-sync-content.d.ts +46 -0
- package/dist/session-sync-content.js +47 -1
- package/dist/session-sync-kernel.d.ts +89 -0
- package/dist/session-sync-kernel.js +48 -3
- package/dist/session-sync.d.ts +125 -0
- package/dist/session-sync.js +181 -8
- package/dist/session-titler.d.ts +26 -0
- package/dist/session-titler.js +41 -7
- package/dist/session-watch.d.ts +53 -1
- package/dist/session-watch.js +73 -9
- package/dist/sighup-idle.d.ts +30 -0
- package/dist/sighup-idle.js +12 -1
- package/dist/spec-fields.d.ts +91 -3
- package/dist/spec-fields.js +116 -4
- package/dist/task-cwd.d.ts +50 -0
- package/dist/task-cwd.js +68 -1
- package/dist/task-mcp.d.ts +47 -0
- package/dist/task-mcp.js +29 -0
- package/dist/task-settings.d.ts +175 -0
- package/dist/task-settings.js +226 -11
- package/dist/task-workflow.d.ts +67 -0
- package/dist/task-workflow.js +75 -8
- package/dist/tool-approval.d.ts +91 -0
- package/dist/tool-approval.js +215 -0
- package/dist/trace/artifacts.d.ts +9 -0
- package/dist/trace/artifacts.js +30 -5
- package/dist/trace/core-keyset-guard.d.ts +18 -0
- package/dist/trace/ledger-sink.d.ts +43 -0
- package/dist/trace/ledger-sink.js +64 -5
- package/dist/trace/project.d.ts +133 -0
- package/dist/trace/project.js +189 -2
- package/dist/trace/redact.d.ts +19 -0
- package/dist/trace/redact.js +66 -9
- package/dist/usage-analytics.d.ts +26 -0
- package/dist/usage-analytics.js +26 -3
- package/package.json +1 -1
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable-store BACKEND seam (clay 2026-06-21 PG migration). One place that, given `config.dbBackend`, builds the
|
|
3
|
+
* SQL pool (TiDB/MySQL via mysql2 OR PostgreSQL via pg) and constructs the right store TWIN for every durable
|
|
4
|
+
* subsystem. main.ts wires through this instead of `new TiDB*(pool)` so `DB_BACKEND=pg` boots the whole service on
|
|
5
|
+
* PG with zero call-site churn. The twins are interchangeable behaviourally (one shared real-DB integration suite
|
|
6
|
+
* keeps them in lock-step); the unions below exist only because TS private fields make the concrete classes
|
|
7
|
+
* nominally distinct (run/approval/imageIndex/imageBake have no core interface — the rest implement one).
|
|
8
|
+
*/
|
|
1
9
|
import { homedir } from "node:os";
|
|
2
10
|
import { join } from "node:path";
|
|
3
11
|
import { FileStorageBackend, FileSessionRepo, DEFAULT_SNAPSHOT_BOUNDS } from "@sema-agent/core";
|
|
@@ -44,8 +52,15 @@ import { TiDBRateLimiter } from "./tidb-rate-limiter.js";
|
|
|
44
52
|
import { PgRateLimiter } from "./pg-rate-limiter.js";
|
|
45
53
|
import { TiDBSessionStore } from "./tidb-session-store.js";
|
|
46
54
|
import { PgSessionStore } from "./pg-session-storage.js";
|
|
55
|
+
/** Build the snapshot-BLOB object-store backend from config, or undefined to fall back to the SqlBlobBackend default.
|
|
56
|
+
* When `config.snapshotBlobStore` (MINIO_* env) is set, the E19/2c file-snapshot stores route ONLY the blob BYTES to
|
|
57
|
+
* MinIO; the MANIFEST stays in SQL (the transcript hot read never touches MinIO). The MinioBlobBackend is given the
|
|
58
|
+
* SAME pool+dialect so it keeps the bytes-NULL `snapshot_blob` INDEX in SQL (the orphan/grace reference-tracking +
|
|
59
|
+
* presence checks read it — see blob-backend.ts). Shared by the tidb + pg backends. */
|
|
47
60
|
function snapshotBlobBackend(config, dialect, pool) {
|
|
48
61
|
const s = config.snapshotBlobStore;
|
|
62
|
+
// (a): no MinIO ⇒ construct the SQL default EXPLICITLY so the per-blob cap (env override or the tidb
|
|
63
|
+
// packet-wall default) rides along — the stores' internal `?? new SqlBlobBackend(...)` fallback would lose it.
|
|
49
64
|
if (!s)
|
|
50
65
|
return new SqlBlobBackend(dialect, pool, config.snapshotBlobSqlMaxBytes);
|
|
51
66
|
return new MinioBlobBackend({
|
|
@@ -58,6 +73,11 @@ function snapshotBlobBackend(config, dialect, pool) {
|
|
|
58
73
|
...(s.presignTtlSec ? { presignTtlSec: s.presignTtlSec } : {}),
|
|
59
74
|
}, { dialect, pool });
|
|
60
75
|
}
|
|
76
|
+
/** (c)(clay 拍 a+c,2026-07-27)云形快照 blob 姿势门——boot 时调用(main.ts),纯函数可单测。
|
|
77
|
+
* SQL 后端(mysql|pg)把 blob 字节落 `snapshot_blob` 单行的形已被两役实证撞 mysql-协议包墙
|
|
78
|
+
* (D-1 附件 → 对象存储裁定;snapshot_blob >31MiB 同墙):大字节归对象存储。云形缺 MinIO ⇒
|
|
79
|
+
* fail-loud(启动了才是假安全);`SNAPSHOT_BLOB_ALLOW_SQL_BYTES=true` = 显式接受 SQL 店 +
|
|
80
|
+
* per-blob 帽(单机/测试台形)。local 后端不经此门(file/in-memory 快照店,无 SQL 包墙)。 */
|
|
61
81
|
export function assertCloudSnapshotBlobPosture(kind, config) {
|
|
62
82
|
if (kind === "local" || config.snapshotBlobStore || config.snapshotBlobAllowSql)
|
|
63
83
|
return;
|
|
@@ -67,6 +87,10 @@ export function assertCloudSnapshotBlobPosture(kind, config) {
|
|
|
67
87
|
"same ruling as the D-1 attachment store). Single-box/test rigs may explicitly opt out with " +
|
|
68
88
|
"SNAPSHOT_BLOB_ALLOW_SQL_BYTES=true (a per-blob cap then applies; oversized blobs are rejected 413).");
|
|
69
89
|
}
|
|
90
|
+
/** REWIND_SNAPSHOT_MAX_MB overrides ONLY the byte cap of core's DEFAULT_SNAPSHOT_BOUNDS (raise for
|
|
91
|
+
* big monorepos, lower for tight DBs). File-count / ignoreDirs stay core defaults — the knob answers the one
|
|
92
|
+
* field the 20G-workspace case needed; more knobs when a case shows up. Exported for tests
|
|
93
|
+
* (fractional-MB rounding + partial-merge semantics need a regression lock). */
|
|
70
94
|
export function snapshotBoundsFromConfig(config) {
|
|
71
95
|
const mb = config.rewindSnapshotMaxMb;
|
|
72
96
|
return mb !== undefined ? { ...DEFAULT_SNAPSHOT_BOUNDS, maxBytes: Math.round(mb * 1024 * 1024) } : DEFAULT_SNAPSHOT_BOUNDS;
|
|
@@ -88,10 +112,10 @@ class TiDBBackend {
|
|
|
88
112
|
sessionPolicy() { return new TiDBSessionPolicyStore(this.pool); }
|
|
89
113
|
fileSnapshot() { return new TiDBFileSnapshotStore(this.pool, snapshotBlobBackend(this.config, "tidb", this.pool), snapshotBoundsFromConfig(this.config)); }
|
|
90
114
|
workflowJournal() { return new TiDBWorkflowJournalStore(this.pool); }
|
|
91
|
-
outcomeSink() { return new TiDBOutcomeLedger(this.pool); }
|
|
92
|
-
workflowRun() { return new TiDBWorkflowRunStore(this.pool); }
|
|
93
|
-
completionInbox(onWarn) { return new TiDBWorkflowCompletionInbox(this.pool, onWarn); }
|
|
94
|
-
notifyJournal() { return new TiDBWorkflowNotifyJournalStore(this.pool); }
|
|
115
|
+
outcomeSink() { return new TiDBOutcomeLedger(this.pool); } // design/73 §1→§7 bridge (recordCore)
|
|
116
|
+
workflowRun() { return new TiDBWorkflowRunStore(this.pool); } // P1: cross-replica workflow record
|
|
117
|
+
completionInbox(onWarn) { return new TiDBWorkflowCompletionInbox(this.pool, onWarn); } // P1: cross-replica push half
|
|
118
|
+
notifyJournal() { return new TiDBWorkflowNotifyJournalStore(this.pool); } // 1.108: cross-replica at-least-once notify
|
|
95
119
|
checkpoint(logger) { return new TiDBCheckpointStore(this.pool, logger); }
|
|
96
120
|
approval() { return new TiDBApprovalStore(this.pool); }
|
|
97
121
|
toolResult() { return new TiDBToolResultStore(this.pool); }
|
|
@@ -103,7 +127,7 @@ class TiDBBackend {
|
|
|
103
127
|
session() { return new TiDBSessionStore(this.pool); }
|
|
104
128
|
mysqlPool() { return this.pool; }
|
|
105
129
|
pgPool() { return undefined; }
|
|
106
|
-
async dbNowMs() { const [rows] = await this.pool.query("SELECT ROUND(UNIX_TIMESTAMP(NOW(3))*1000) AS ms"); return Number(rows[0]?.ms); }
|
|
130
|
+
async dbNowMs() { const [rows] = await this.pool.query("SELECT ROUND(UNIX_TIMESTAMP(NOW(3))*1000) AS ms"); return Number(rows[0]?.ms); } // S10
|
|
107
131
|
}
|
|
108
132
|
class PgBackend {
|
|
109
133
|
pool;
|
|
@@ -122,10 +146,10 @@ class PgBackend {
|
|
|
122
146
|
sessionPolicy() { return new PgSessionPolicyStore(this.pool); }
|
|
123
147
|
fileSnapshot() { return new PgFileSnapshotStore(this.pool, snapshotBlobBackend(this.config, "pg", this.pool), snapshotBoundsFromConfig(this.config)); }
|
|
124
148
|
workflowJournal() { return new PgWorkflowJournalStore(this.pool); }
|
|
125
|
-
outcomeSink() { return new PgOutcomeLedger(this.pool); }
|
|
126
|
-
workflowRun() { return new PgWorkflowRunStore(this.pool); }
|
|
127
|
-
completionInbox(onWarn) { return new PgWorkflowCompletionInbox(this.pool, onWarn); }
|
|
128
|
-
notifyJournal() { return new PgWorkflowNotifyJournalStore(this.pool); }
|
|
149
|
+
outcomeSink() { return new PgOutcomeLedger(this.pool); } // design/73 §1→§7 bridge (recordCore)
|
|
150
|
+
workflowRun() { return new PgWorkflowRunStore(this.pool); } // P1: cross-replica workflow record
|
|
151
|
+
completionInbox(onWarn) { return new PgWorkflowCompletionInbox(this.pool, onWarn); } // P1: cross-replica push half
|
|
152
|
+
notifyJournal() { return new PgWorkflowNotifyJournalStore(this.pool); } // 1.108: cross-replica at-least-once notify
|
|
129
153
|
checkpoint(logger) { return new PgCheckpointStore(this.pool, logger); }
|
|
130
154
|
approval() { return new PgApprovalStore(this.pool); }
|
|
131
155
|
toolResult() { return new PgToolResultStore(this.pool); }
|
|
@@ -137,8 +161,30 @@ class PgBackend {
|
|
|
137
161
|
session() { return new PgSessionStore(this.pool); }
|
|
138
162
|
mysqlPool() { return undefined; }
|
|
139
163
|
pgPool() { return this.pool; }
|
|
140
|
-
async dbNowMs() { const res = await this.pool.query("SELECT ROUND(EXTRACT(EPOCH FROM now())*1000) AS ms"); return Number(res.rows[0]?.ms); }
|
|
164
|
+
async dbNowMs() { const res = await this.pool.query("SELECT ROUND(EXTRACT(EPOCH FROM now())*1000) AS ms"); return Number(res.rows[0]?.ms); } // S10
|
|
141
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* LOCAL backend (clay 2026-06-25 seamless local↔cloud; P0.5 variant-2 + variant-1 file-backed 2026-06-26): a DB-less StoreBackend
|
|
168
|
+
* so a locally-run HTTP service serves the SAME contract a cloud worker does (runs + trace + sessions + resume;
|
|
169
|
+
* long-term memory rides the design/138 memory ENGINE, not this backend). Sessions / per-session policy / file snapshots are
|
|
170
|
+
* FILE-BACKED via core's `FileStorageBackend` over `root`, so a session SURVIVES a process restart and the resume
|
|
171
|
+
* picker (GET /v1/sessions → LocalSessionStore.listSessions) is restart-visible — the 2c "first local, then sync"
|
|
172
|
+
* hard prerequisite.
|
|
173
|
+
*
|
|
174
|
+
* The session store stays the §0.5 owner-aware {@link LocalSessionStore} wrapper, but over a fresh `FileSessionRepo`
|
|
175
|
+
* (NOT `fileBackend.sessionStore`, which is core's bare `TtlSessionStore` lacking the §0.5 owner/list/fork/delete
|
|
176
|
+
* ops); policy/snapshot delegate to the fileBackend's own file stores. The fileBackend takes a coarse boot
|
|
177
|
+
* `flock` on `root/LOCK` (single-instance per data dir) — `close()` MUST `dispose()` it so a graceful restart can
|
|
178
|
+
* re-acquire (a stale lock from a dead PID is pruned by core, but graceful restart relies on the release).
|
|
179
|
+
*
|
|
180
|
+
* P0.5 variant-1 (clay 2026-06-26): `run()`/`resumeAnchor()` are now FILE-backed too (FileRunStore /
|
|
181
|
+
* FileResumeAnchorStore over core 1.138.0's crash-safe fs primitives — atomicWriteFile/writeThenLink/AppendLog), so the
|
|
182
|
+
* runs ledger + trace event log + E18 anchors SURVIVE a process restart, completing variant-2's promised follow-on. The
|
|
183
|
+
* picker still lists from the session abstraction (variant-2), but a restart now also re-reads run history + resume
|
|
184
|
+
* anchors. Owner identity is still process-local (single-user acceptable; durable owners = P1). The cloud-only stores
|
|
185
|
+
* (checkpoint/approval/toolResult/imageIndex/imageBake/breaker/costQuota/rateLimiter) are OMITTED → the consumers'
|
|
186
|
+
* `backend?.X?.()` gates degrade them exactly like a no-DB env.
|
|
187
|
+
*/
|
|
142
188
|
class LocalBackend {
|
|
143
189
|
kind = "local";
|
|
144
190
|
fileBackend;
|
|
@@ -147,17 +193,29 @@ class LocalBackend {
|
|
|
147
193
|
resumeAnchorStore;
|
|
148
194
|
approvalExemptionStore;
|
|
149
195
|
sendFileLedgerStore;
|
|
196
|
+
// SVC-2: FILE-backed durable journal (was core's InMemory — a TOC restart silently resolved
|
|
197
|
+
// resumeFromRunId to an empty journal → full live re-run). Now restart-durable on one box; crash-safe JSONL,
|
|
198
|
+
// scope-guarded, oversize skip-journal — byte-matched degrade with the SQL twins. Singleton: fds live here.
|
|
150
199
|
workflowJournalStore;
|
|
200
|
+
/** design/73 §1 — owner-only JSONL outcome-fact sink (stateless append; no fd held). */
|
|
151
201
|
outcomeSinkInst;
|
|
152
202
|
constructor(root, config) {
|
|
203
|
+
// The fileBackend ctor mkdirs `root` + takes the boot flock — a SECOND instance over the same dir FAILS FAST.
|
|
204
|
+
// Re-throw with a clear operator message (the raw core error is "another instance owns this data dir").
|
|
153
205
|
try {
|
|
154
|
-
this.fileBackend = new FileStorageBackend({ root, ...(config.rewindSnapshotMaxMb !== undefined ? { snapshotBounds: { maxBytes: Math.round(config.rewindSnapshotMaxMb * 1024 * 1024) } } : {}) });
|
|
206
|
+
this.fileBackend = new FileStorageBackend({ root, ...(config.rewindSnapshotMaxMb !== undefined ? { snapshotBounds: { maxBytes: Math.round(config.rewindSnapshotMaxMb * 1024 * 1024) } } : {}) }); // REWIND_SNAPSHOT_MAX_MB
|
|
155
207
|
}
|
|
156
208
|
catch (e) {
|
|
157
209
|
throw new Error(`DB_BACKEND=local cannot open data dir ${root}: ${e instanceof Error ? e.message : String(e)} ` +
|
|
158
210
|
"(another HTTP service / run-local instance may own it; stop it first or set LOCAL_DATA_ROOT to a free dir)");
|
|
159
211
|
}
|
|
212
|
+
// §0.5 owner-aware wrapper over a fresh FileSessionRepo on the SAME root (NOT fileBackend.sessionStore — that's
|
|
213
|
+
// the bare TtlSessionStore without the §0.5 owner/list/fork/delete ops). Both touch root/sessions/*.jsonl.
|
|
214
|
+
// Pass `root` as the lastActivity sidecar dir so the /resume picker's newest-first order survives a restart (TOC #10):
|
|
215
|
+
// without it the in-memory recency map starts empty on boot and every session degrades to createdAt ordering.
|
|
160
216
|
this.sessionStore = new LocalSessionStore(new FileSessionRepo(this.fileBackend.root), this.fileBackend.root);
|
|
217
|
+
// P0.5 variant-1: file-backed runs ledger + E18 anchors over the SAME canonical root (under root/runs + root/
|
|
218
|
+
// resume-anchors). Hydrate the in-memory index from disk on construction → restart-visible.
|
|
161
219
|
this.runStore = new FileRunStore(this.fileBackend.root);
|
|
162
220
|
this.resumeAnchorStore = new FileResumeAnchorStore(this.fileBackend.root);
|
|
163
221
|
this.approvalExemptionStore = new FileApprovalExemptionStore(this.fileBackend.root);
|
|
@@ -165,21 +223,23 @@ class LocalBackend {
|
|
|
165
223
|
this.workflowJournalStore = new FileWorkflowJournalStore(this.fileBackend.root);
|
|
166
224
|
this.outcomeSinkInst = new FileOutcomeSink(this.fileBackend.root);
|
|
167
225
|
}
|
|
168
|
-
async ensureSchema() { }
|
|
226
|
+
async ensureSchema() { } // FileStorageBackend ctor already created root + the boot lock → always "reachable"
|
|
169
227
|
async close() {
|
|
170
|
-
await this.sessionStore.dispose();
|
|
171
|
-
this.runStore.dispose();
|
|
172
|
-
this.resumeAnchorStore.dispose();
|
|
173
|
-
this.approvalExemptionStore.dispose();
|
|
174
|
-
this.sendFileLedgerStore.dispose();
|
|
175
|
-
this.workflowJournalStore.dispose();
|
|
176
|
-
this.checkpointStoreInst?.close();
|
|
177
|
-
await this.fileBackend.dispose();
|
|
228
|
+
await this.sessionStore.dispose(); // AWAIT the final lastActivity flush (bug C) BEFORE releasing the dir lock below
|
|
229
|
+
this.runStore.dispose(); // release the per-run event-log fds so a graceful restart can re-open the data dir
|
|
230
|
+
this.resumeAnchorStore.dispose(); // release the per-session anchor-log fds
|
|
231
|
+
this.approvalExemptionStore.dispose(); // release the per-session exemption-log fds
|
|
232
|
+
this.sendFileLedgerStore.dispose(); // release the sendfile-ledger append fd (lazy — may never have opened)
|
|
233
|
+
this.workflowJournalStore.dispose(); // release the per-run journal-ledger fds
|
|
234
|
+
this.checkpointStoreInst?.close(); // release the checkpoint ledger fd (lazy, may never have been built)
|
|
235
|
+
await this.fileBackend.dispose(); // MUST release root/LOCK so a graceful restart can re-acquire the data dir
|
|
178
236
|
}
|
|
179
237
|
run() { return this.runStore; }
|
|
180
|
-
resumeAnchor() { return this.resumeAnchorStore; }
|
|
181
|
-
approvalExemption() { return this.approvalExemptionStore; }
|
|
182
|
-
sendFileLedger() { return this.sendFileLedgerStore; }
|
|
238
|
+
resumeAnchor() { return this.resumeAnchorStore; } // singleton — state lives in the instance (mirrors run()/session())
|
|
239
|
+
approvalExemption() { return this.approvalExemptionStore; } // singleton — same posture
|
|
240
|
+
sendFileLedger() { return this.sendFileLedgerStore; } // singleton — append fd lives in the instance
|
|
241
|
+
/** Durable HITL / plan-review parking on the LOCAL lane. Lazy singleton (the inner core store holds
|
|
242
|
+
* an append fd). taskId join ← FileRunStore; E21 owner guard ← LocalSessionStore.ownerOf (same root). */
|
|
183
243
|
checkpoint() {
|
|
184
244
|
if (!this.checkpointStoreInst) {
|
|
185
245
|
const cs = new LocalCheckpointStore(this.fileBackend.root, {
|
|
@@ -187,6 +247,14 @@ class LocalBackend {
|
|
|
187
247
|
ownerOf: (sessionId) => this.sessionStore.ownerOf(sessionId),
|
|
188
248
|
});
|
|
189
249
|
this.checkpointStoreInst = cs;
|
|
250
|
+
// [868] the reverse join: FileRunStore's suspended-run reapers cannot JOIN the checkpoint plane (separate
|
|
251
|
+
// store), so they take the two EXISTS predicates as an injected probe — wired HERE because this is the one
|
|
252
|
+
// place both stores exist over the same root. Without it the reapers stay honest NO-OPs, and an abandoned
|
|
253
|
+
// durable HITL park (approval never answered) held its task_active claim forever (session locked; the
|
|
254
|
+
// [868] incident). NB the probe only tells the reaper what the SQL twins read via JOIN — the reaper's
|
|
255
|
+
// D-D NOT-pending guard still decides; and the APPROVAL_TIMEOUT_SEC=0 default still keeps the time-based
|
|
256
|
+
// leg OFF (durable HITL waits for a human indefinitely BY DESIGN; the checkpoint-expiry leg + the cancel
|
|
257
|
+
// verb are the recovery handles).
|
|
190
258
|
this.runStore.setCheckpointProbe({
|
|
191
259
|
hasPending: async (sessionId) => (await cs.findPendingTokenBySession(sessionId)) !== null,
|
|
192
260
|
hasExpired: (sessionId) => cs.hasExpiredBySession(sessionId),
|
|
@@ -195,21 +263,28 @@ class LocalBackend {
|
|
|
195
263
|
return this.checkpointStoreInst;
|
|
196
264
|
}
|
|
197
265
|
checkpointStoreInst;
|
|
198
|
-
sessionPolicy() { return this.fileBackend.sessionPolicyStore; }
|
|
199
|
-
fileSnapshot() { return this.fileBackend.fileSnapshotStore; }
|
|
200
|
-
workflowJournal() { return this.workflowJournalStore; }
|
|
201
|
-
outcomeSink() { return this.outcomeSinkInst; }
|
|
266
|
+
sessionPolicy() { return this.fileBackend.sessionPolicyStore; } // E6 — file-backed (survives restart)
|
|
267
|
+
fileSnapshot() { return this.fileBackend.fileSnapshotStore; } // E19 — file-backed content-addressed blobs (survive restart)
|
|
268
|
+
workflowJournal() { return this.workflowJournalStore; } // SVC-2 — FILE-backed (restart-durable on one box, see field doc)
|
|
269
|
+
outcomeSink() { return this.outcomeSinkInst; } // design/73 §1 — owner-only JSONL fact ledger
|
|
202
270
|
session() { return this.sessionStore; }
|
|
271
|
+
// core 1.219 (dogfood finding "ReadToolResult(ref) 恒空"): the TOC lane now has a DURABLE tool-result
|
|
272
|
+
// store — core's FileToolResultStore under the same data root (one file per ref, write-once, restart-durable).
|
|
273
|
+
// In-process cross-task deref was already fixed core-side (1.219 Runner-shared fallback); this adds the
|
|
274
|
+
// cross-RESTART half. No reapOlderThan/deleteBySession (optional extras) — single-user text previews, CC posture.
|
|
203
275
|
toolResult() { return this.fileBackend.toolResultStore; }
|
|
204
276
|
mysqlPool() { return undefined; }
|
|
205
277
|
pgPool() { return undefined; }
|
|
206
278
|
}
|
|
279
|
+
/** Build the durable-store backend for `config.dbBackend`. Does NOT connect (the pool connects lazily; the
|
|
280
|
+
* reachability probe is the caller's first `ensureSchema`). Returns undefined when no DB is configured. */
|
|
207
281
|
export function createStoreBackend(config) {
|
|
208
282
|
if (config.dbBackend === "local")
|
|
209
283
|
return new LocalBackend(config.localDataRoot ?? join(homedir(), ".ai-agent"), config);
|
|
210
284
|
if (config.dbBackend === "pg") {
|
|
211
285
|
if (!config.pg)
|
|
212
286
|
return undefined;
|
|
287
|
+
// pgPoolOptions also arms the DB_QUERY_TIMEOUT_MS pool-wide per-query ceiling (S9 deeper fix) when set.
|
|
213
288
|
const pool = createPgPool(pgPoolOptions(config.pg, config.dbQueryTimeoutMs));
|
|
214
289
|
return new PgBackend(pool, config);
|
|
215
290
|
}
|
|
@@ -217,17 +292,35 @@ export function createStoreBackend(config) {
|
|
|
217
292
|
return undefined;
|
|
218
293
|
return new TiDBBackend(createTidbPool(config), config);
|
|
219
294
|
}
|
|
295
|
+
/** boot 期打开 store 后端的**统一入口**:构造 + ensureSchema 同罩一层降级臂。
|
|
296
|
+
*
|
|
297
|
+
* 为什么必须把 `createStoreBackend()` 也罩进来(2026-07-28 修):clay 1.292 拍的口径是「裸 boot
|
|
298
|
+
* **默认推导**的 local 在只读文件系统/mkdir 失败时不得拒启」,但原先 try 只罩 `ensureSchema()`——
|
|
299
|
+
* 而 LocalBackend 的 `ensureSchema` 是**空实现**,真正会抛的 mkdir + 数据根 BootLock 在构造函数里、
|
|
300
|
+
* 落在 try 之外。于是那条降级臂对 local 形从来没生效过,注释宣称的行为与代码真做的事撕裂。
|
|
301
|
+
*
|
|
302
|
+
* 降级条件不变(两形同一姿势):`sessionBackend=auto`(配置的 DB 不可达,S5 原形)或**默认推导**的
|
|
303
|
+
* local(`dbBackend=local && !dbBackendExplicit`)。**显式** DB_BACKEND=local / tidb 仍 fail-loud——
|
|
304
|
+
* operator 要了 durable,静默丢=丢数据。 */
|
|
220
305
|
export async function openStoreBackendWithFallback(config, logger) {
|
|
306
|
+
// 判据按后端分岔(2026-07-28 同批修):原先写的是 `sessionBackend === "auto" || (local && !explicit)`,
|
|
307
|
+
// 而 `auto` 是 SESSION_BACKEND 的**默认值** ⇒ 显式 `DB_BACKEND=local` 的部署照样落进第一条臂被静默降级,
|
|
308
|
+
// 「显式仍 fail-loud」这句话同样从未生效。local 形只看 DB_BACKEND 是不是显式;SQL 形维持 S5 原义
|
|
309
|
+
// (auto=尽力而为可降级,显式 tidb/pg=fail-loud,静默丢持久化会丢 run)。
|
|
221
310
|
const mayFallback = config.dbBackend === "local" ? !config.dbBackendExplicit : config.sessionBackend === "auto";
|
|
222
311
|
let backend;
|
|
223
312
|
try {
|
|
224
313
|
backend = createStoreBackend(config);
|
|
314
|
+
// connects + creates schema (also the reachability probe).
|
|
225
315
|
if (backend)
|
|
226
316
|
await backend.ensureSchema();
|
|
227
317
|
}
|
|
228
318
|
catch (err) {
|
|
229
319
|
if (!mayFallback)
|
|
230
320
|
throw err;
|
|
321
|
+
// S5 (SILENT-FALLBACK P0-b): one boot warn was the ONLY trace of "this replica is not persisting".
|
|
322
|
+
// The caller renders the gauge + /health twin flag so a degraded replica is distinguishable from
|
|
323
|
+
// an in-memory-by-choice one.
|
|
231
324
|
logger.warn("store_db_unreachable_fallback_memory", {
|
|
232
325
|
backend: backend?.kind ?? config.dbBackend,
|
|
233
326
|
error: err instanceof Error ? err.message : String(err),
|
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backend-NEUTRAL store contracts (design/158 A3 沉底).
|
|
3
|
+
*
|
|
4
|
+
* The record/event/summary shapes (and the pure row-mapping helpers) shared by ALL store backends —
|
|
5
|
+
* TiDB/MySQL, PostgreSQL, file, memory — plus their non-store consumers (http wire, trace, images,
|
|
6
|
+
* capabilities). They used to live inside the TiDB adapters, which made every other backend (and the
|
|
7
|
+
* HTTP layer) import a TiDB module just to name a type; this file is the neutral home.
|
|
8
|
+
*
|
|
9
|
+
* Rules for this file:
|
|
10
|
+
* - ZERO dialect dependencies (no mysql2, no pg) — types + pure functions only. The only imports
|
|
11
|
+
* allowed are core contract types and the neutral sql-row-helpers leaf.
|
|
12
|
+
* - Adapters import their contracts from HERE; no adapter imports its twin (store-backend.ts, the
|
|
13
|
+
* composition root, is the one place that names every concrete adapter).
|
|
14
|
+
* - The TiDB adapters re-export these names for back-compat (the historical import surface), but new
|
|
15
|
+
* code should import from this file.
|
|
16
|
+
*/
|
|
1
17
|
import type { TaskResult, TaskStatus } from "@sema-agent/core";
|
|
2
18
|
export interface RunRecord {
|
|
3
19
|
taskId: string;
|
|
@@ -6,23 +22,42 @@ export interface RunRecord {
|
|
|
6
22
|
status: "running" | TaskStatus;
|
|
7
23
|
result: TaskResult | null;
|
|
8
24
|
error: string | null;
|
|
25
|
+
/** Structured failure code (1.36/1.37) denormalized from the result for SQL queryability. */
|
|
9
26
|
errorCode: string | null;
|
|
27
|
+
/** Work-view correlation id (optional): groups the runs of one logical task across both client doors
|
|
28
|
+
* (MCP façade / portal). null when the caller didn't supply one. */
|
|
10
29
|
jobId: string | null;
|
|
30
|
+
/** Which SYSTEM's credential submitted the run (oa/cc-mcp/portal…), derived at the auth gate — never
|
|
31
|
+
* self-declared. null = legacy single-token deployment (authenticated, no system identity). */
|
|
11
32
|
source: string | null;
|
|
33
|
+
/** The replica that OWNS this run (the instanceId that created it). Lets a preempt/cancel handler tell
|
|
34
|
+
* "this run is on MY replica" (consult the in-process inflight/preemptable map authoritatively) from "owned
|
|
35
|
+
* elsewhere" (fall back to the durable cross-replica flag). null for pre-column rows. */
|
|
12
36
|
instanceId: string | null;
|
|
37
|
+
/** First ~120 chars of the objective (secret-redacted at write) — the list's "what is this task" glance.
|
|
38
|
+
* null for rows predating the column. */
|
|
13
39
|
objectivePreview: string | null;
|
|
14
40
|
createdAt: string;
|
|
15
41
|
updatedAt: string;
|
|
16
42
|
}
|
|
43
|
+
/** One row of the GET /v1/sessions list (CC /resume picker): a DISTINCT session (sessionId) aggregated from its
|
|
44
|
+
* task_run rows — newest-first by last activity. The preview/status are the LATEST run's ("continue where I left
|
|
45
|
+
* off"); the counts/timestamps span the whole session. Owner included so a fleet-wide (ops) listing is attributable. */
|
|
17
46
|
export interface SessionSummary {
|
|
18
47
|
sessionId: string;
|
|
19
48
|
owner: string | null;
|
|
49
|
+
/** The most recent run's create time (the keyset sort key) and the session's first run's create time. */
|
|
20
50
|
lastActivityAt: string;
|
|
21
51
|
firstActivityAt: string;
|
|
22
52
|
runCount: number;
|
|
53
|
+
/** The LATEST run's objective preview + status — what the session was last doing. */
|
|
23
54
|
objectivePreview: string | null;
|
|
24
55
|
lastStatus: string;
|
|
56
|
+
/** K-5c (shell §K): the LATEST run's task_id — the anchor the shell uses to re-attach the live event tail in ONE
|
|
57
|
+
* hop (`GET /v1/runs/:lastRunId/events`) when resuming a picked session, instead of a second lookup. */
|
|
25
58
|
lastRunId: string | null;
|
|
59
|
+
/** The auto-generated session title (cheap-model one-liner, write-once). null = not (yet)
|
|
60
|
+
* titled OR the lister face has no session_meta (the legacy task_run aggregate / memory twins — honest degrade). */
|
|
26
61
|
title: string | null;
|
|
27
62
|
}
|
|
28
63
|
export interface RunEvent {
|
|
@@ -31,8 +66,11 @@ export interface RunEvent {
|
|
|
31
66
|
data: unknown;
|
|
32
67
|
ts: string;
|
|
33
68
|
}
|
|
69
|
+
/** Coarse 4-value lifecycle the SSE reader polls for terminality (run-store parity). */
|
|
34
70
|
export type BakeStatus = "queued" | "running" | "done" | "failed";
|
|
71
|
+
/** build.sh's 8-value ordered state — UI progress bar only, NEVER stream terminality (P2.3). */
|
|
35
72
|
export type BakeState = "PENDING" | "BUILDING" | "PUSHING" | "VERIFYING" | "REGISTERING" | "COMPLETE" | "FAILED" | "CANCELLED";
|
|
73
|
+
/** Structured terminal codes the center band-composer UI keys on (P2.14): null on success / uncategorized. */
|
|
36
74
|
export type BakeErrorCode = "band-conflict" | "duplicate" | "disk" | "timeout" | "cancelled" | null;
|
|
37
75
|
export interface BakeRecord {
|
|
38
76
|
bakeId: string;
|
|
@@ -65,12 +103,15 @@ export interface BakeRecord {
|
|
|
65
103
|
}
|
|
66
104
|
export interface BakeEvent {
|
|
67
105
|
seq: number;
|
|
106
|
+
/** Runner-supplied per-line ordinal (ingest dedupe key); null for image-api-synthesized frames. */
|
|
68
107
|
lineOrd: number | null;
|
|
69
108
|
kind: string;
|
|
109
|
+
/** 'raw' for opt-in build.log tail rows (evicted first); null for structured frames. */
|
|
70
110
|
level: string | null;
|
|
71
111
|
data: unknown;
|
|
72
112
|
ts: string;
|
|
73
113
|
}
|
|
114
|
+
/** The validated/normalized inputs a `POST /v1/images/bakes` produces (operator free-text never reaches here). */
|
|
74
115
|
export interface CreateBakeInput {
|
|
75
116
|
profile: string;
|
|
76
117
|
bands: string[] | null;
|
|
@@ -78,10 +119,12 @@ export interface CreateBakeInput {
|
|
|
78
119
|
push: boolean;
|
|
79
120
|
dryRun: boolean;
|
|
80
121
|
logs: boolean;
|
|
122
|
+
/** The VETTED, normalized build.sh argv the runner runs (and ONLY this). */
|
|
81
123
|
argv: string[];
|
|
82
124
|
idemKey: string | null;
|
|
83
125
|
requestedBy: string | null;
|
|
84
126
|
}
|
|
127
|
+
/** The terminal fields the auto-register / done path writes (P2.10). */
|
|
85
128
|
export interface BakeTerminal {
|
|
86
129
|
status: "done" | "failed";
|
|
87
130
|
state: BakeState;
|
|
@@ -95,6 +138,8 @@ export interface BakeTerminal {
|
|
|
95
138
|
manifestSha?: string | null;
|
|
96
139
|
tag?: string | null;
|
|
97
140
|
}
|
|
141
|
+
/** Raw SELECT row shape shared by BOTH SQL twins (design/158 S8 归位, A3 沉底 —
|
|
142
|
+
* node-pg reads BIGINT-ish `exit_code` back as a string, hence `number | string | null`). */
|
|
98
143
|
export interface BakeRow {
|
|
99
144
|
bake_id: string;
|
|
100
145
|
profile: string;
|
|
@@ -124,13 +169,18 @@ export interface BakeRow {
|
|
|
124
169
|
created_at: Date | string;
|
|
125
170
|
updated_at: Date | string;
|
|
126
171
|
}
|
|
172
|
+
/** SELECT row → {@link BakeRecord} — shared by BOTH SQL twins (design/158 S8 归位, A3 沉底). */
|
|
127
173
|
export declare function mapBakeRow(r: BakeRow): BakeRecord;
|
|
174
|
+
/** Column list mapBakeRow expects — shared by BOTH SQL twins (design/158 S8 归位, A3 沉底). */
|
|
128
175
|
export declare const BAKE_SELECT_COLS: string;
|
|
176
|
+
/** Nested-build security posture (the operator console shows rootless vs privileged-dind). */
|
|
129
177
|
export type ImageNestedBuildMode = "none" | "docker-cli-only" | "rootless-buildkit" | "privileged-dind";
|
|
130
178
|
export interface ImageCapabilities {
|
|
131
179
|
browser?: boolean;
|
|
132
180
|
db?: boolean;
|
|
181
|
+
/** Whether the image can build container images at all (bool — back-compat). */
|
|
133
182
|
nestedBuild?: boolean;
|
|
183
|
+
/** HOW it nests (the security posture). Additive over `nestedBuild`; absent ⇒ treat as `nestedBuild`. */
|
|
134
184
|
nestedBuildMode?: ImageNestedBuildMode;
|
|
135
185
|
}
|
|
136
186
|
export interface ImagePodContract {
|
|
@@ -165,19 +215,30 @@ export interface ImageIndexEntry {
|
|
|
165
215
|
createdAt: string;
|
|
166
216
|
updatedAt: string;
|
|
167
217
|
}
|
|
218
|
+
/** The fields an upsert supplies (id/createdAt/updatedAt are derived/managed). id is ALWAYS the deterministic
|
|
219
|
+
* idFor(repo,digest) — there is no explicit-id seam, so id-conflict ⟺ (repo,digest)-conflict in BOTH stores
|
|
220
|
+
* (PG's `ON CONFLICT (id)` and MySQL's `ON DUPLICATE KEY` are provably equivalent; no false-parity surface). */
|
|
168
221
|
export type ImageIndexUpsert = Omit<ImageIndexEntry, "id" | "createdAt" | "updatedAt">;
|
|
222
|
+
/** Who is asking — drives visibility scoping. */
|
|
169
223
|
export interface ImageViewer {
|
|
224
|
+
/** Operators see every row regardless of visibility/tenant. */
|
|
170
225
|
operator?: boolean;
|
|
226
|
+
/** A tenant principal additionally sees its own `tenant` rows. */
|
|
171
227
|
tenantId?: string | null;
|
|
172
228
|
}
|
|
173
229
|
export interface ImageListFilter extends ImageViewer {
|
|
174
230
|
profile?: string;
|
|
175
231
|
status?: ImageStatus;
|
|
232
|
+
/** Require a capability to be true (e.g. "browser"). */
|
|
176
233
|
capability?: keyof ImageCapabilities;
|
|
234
|
+
/** Only the newest published digest per profile. */
|
|
177
235
|
latestOnly?: boolean;
|
|
178
236
|
limit?: number;
|
|
237
|
+
/** Opaque keyset cursor from a prior page's `nextCursor`. */
|
|
179
238
|
cursor?: string;
|
|
180
239
|
}
|
|
240
|
+
/** Raw SELECT row shape shared by BOTH SQL twins (design/158 S8 归位, A3 沉底 —
|
|
241
|
+
* node-pg reads BIGINT `size_bytes` back as a string, hence `number | string | null`). */
|
|
181
242
|
export interface ImageRow {
|
|
182
243
|
id: string;
|
|
183
244
|
profile: string;
|
|
@@ -201,5 +262,6 @@ export interface ImageRow {
|
|
|
201
262
|
created_at: Date | string;
|
|
202
263
|
updated_at: Date | string;
|
|
203
264
|
}
|
|
265
|
+
/** SELECT row → {@link ImageIndexEntry} — shared by BOTH SQL twins (design/158 S8 归位, A3 沉底). */
|
|
204
266
|
export declare function mapImageRow(r: ImageRow): ImageIndexEntry;
|
|
205
267
|
//# sourceMappingURL=store-contracts.d.ts.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { parseJsonOr, toIso as iso, normalizeIsoOrNull as isoOrNull } from "./sql-row-helpers.js";
|
|
2
|
+
/** SELECT row → {@link BakeRecord} — shared by BOTH SQL twins (design/158 S8 归位, A3 沉底). */
|
|
2
3
|
export function mapBakeRow(r) {
|
|
3
4
|
return {
|
|
4
5
|
bakeId: r.bake_id,
|
|
@@ -30,9 +31,11 @@ export function mapBakeRow(r) {
|
|
|
30
31
|
updatedAt: iso(r.updated_at),
|
|
31
32
|
};
|
|
32
33
|
}
|
|
34
|
+
/** Column list mapBakeRow expects — shared by BOTH SQL twins (design/158 S8 归位, A3 沉底). */
|
|
33
35
|
export const BAKE_SELECT_COLS = "bake_id, profile, bands, base_ref, push, dry_run, logs, argv, status, state, digest, repo, ref, index_id, " +
|
|
34
36
|
"exit_code, error, error_code, manifest_sha, tag, idem_key, ingest_secret, runner_id, lease_until, " +
|
|
35
37
|
"cancel_requested, requested_by, created_at, updated_at";
|
|
38
|
+
/** SELECT row → {@link ImageIndexEntry} — shared by BOTH SQL twins (design/158 S8 归位, A3 沉底). */
|
|
36
39
|
export function mapImageRow(r) {
|
|
37
40
|
return {
|
|
38
41
|
id: r.id,
|
|
@@ -1,8 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TaskAttachmentStore —— D-1 通用文件上传的**独立附件 store**(clay 拍 2026-07-27:不复用 fileSnapshot
|
|
3
|
+
* 的 content-addressed blob 面,新建)。TiDB/PG 双方言 + local 文件店(local-task-attachment-store.ts)。
|
|
4
|
+
*
|
|
5
|
+
* 为什么独立而不是骑 SqlBlobBackend/snapshot_blob:那套的引用追踪=「manifest 里没有的即 orphan」,
|
|
6
|
+
* 附件不在任何 snapshot_manifest ⇒ 会被 sweepOrphanBlobs 在 1h grace 后误收。生命周期也不同:
|
|
7
|
+
* snapshot blob 跟 session 的工作树;**附件跟 task/session 的绑定**(上传先行、提交时绑定、E21 随会话
|
|
8
|
+
* 级联删、未绑定的按 TTL 收割)。
|
|
9
|
+
*
|
|
10
|
+
* 语义要点:
|
|
11
|
+
* - `owner` = auth principal ?? "default"(单库 tenant 轴;无 principal 部署全 default = 单用户语义)。
|
|
12
|
+
* 读/删门在 SQL WHERE 完成(filter-before-reduce,roster 语义条 1 同姿)——他人行连结果集都不进。
|
|
13
|
+
* - **字节本体在对象存储(clay 裁 2026-07-27:云形态对象存储必配,「现在就接」)**:SQL 只存 meta
|
|
14
|
+
* (索引/owner 门/生命周期),bytes 走 {@link AttachmentBytesStore}(生产=既有 MinioBlobBackend,
|
|
15
|
+
* 读侧内建 sha 校验)。对象键=**sha256**(同内容天然去重;跨 owner 共享对象 ⇒ 对象删除必须过
|
|
16
|
+
* 零引用检查)+ **附件专属 keyPrefix**(与快照 blob 命名空间隔离——同 sha 不同生命周期,混用会互删)。
|
|
17
|
+
* 删除次序:meta 先(E21 purge 永不被 MinIO 网络抖动卡死,blob-backend 异步删裁定同旨),对象删
|
|
18
|
+
* =零引用检查后 best-effort(失败只 log:无 meta 的对象经 API 不可达;彻底清收敛作 follow-up 记账)。
|
|
19
|
+
* ⚠️ 曾试过字节进 DB:真库连撞 max_allowed_packet(文本协议 2× 膨胀)与 TiDB 单 entry 6 MiB 限
|
|
20
|
+
* (txn-entry-size-limit)两道墙——分块版虽真库 5/5 跑通,被本裁定取代,教训留此。
|
|
21
|
+
* - 隔离键排序规则:TiDB 表级 utf8mb4_bin / PG owner 列 COLLATE "C"(bga F2 同姿,'=' 字节等价)。
|
|
22
|
+
* owner 值恒为 server 端从凭据推导(非用户输入),PAD SPACE 近撞面不可达,VARBINARY 键列不必要。
|
|
23
|
+
* - 布尔列:无(遵 1.287.0 归一约定,若未来加,PG 用 SMALLINT 0/1)。
|
|
24
|
+
* - 绑定:`bind` 把行钉到 sessionId(重复绑定=改绑,同 owner 内 last-wins;同 session 多 task 共享
|
|
25
|
+
* 自然成立——listBySession 是物化输入)。未绑定行 = 上传后从未被任何 task 引用 ⇒ reapUnbound(TTL)。
|
|
26
|
+
*/
|
|
1
27
|
import type { Pool } from "mysql2/promise";
|
|
2
28
|
import type { PgQueryFn } from "./pg-query.js";
|
|
3
29
|
export interface TaskAttachmentRecord {
|
|
4
30
|
id: string;
|
|
5
31
|
owner: string;
|
|
32
|
+
/** 消毒后的 basename(http 面用 core sanitizePathComponent 处理;store 只存不再消毒)。 */
|
|
6
33
|
name: string;
|
|
7
34
|
mime: string;
|
|
8
35
|
sha256: string;
|
|
@@ -15,16 +42,25 @@ export interface TaskAttachmentStore {
|
|
|
15
42
|
put(rec: TaskAttachmentRecord & {
|
|
16
43
|
content: Uint8Array;
|
|
17
44
|
}): Promise<void>;
|
|
45
|
+
/** meta(不带 bytes);owner 不匹配/不存在 → null(无 oracle)。 */
|
|
18
46
|
get(owner: string, id: string): Promise<TaskAttachmentRecord | null>;
|
|
19
47
|
getContent(owner: string, id: string): Promise<Uint8Array | null>;
|
|
48
|
+
/** 把 ids 钉到 sessionId(owner 门在 WHERE);返回真绑到的行数——调用方以 count===ids.length 判全成。 */
|
|
20
49
|
bind(owner: string, ids: string[], sessionId: string, boundAtMs: number): Promise<number>;
|
|
50
|
+
/** 物化输入(env 建立时)——按 session 单键查(绑定时已 owner 验过;session uuid 不可枚举)。 */
|
|
21
51
|
listBySession(sessionId: string): Promise<TaskAttachmentRecord[]>;
|
|
22
52
|
delete(owner: string, id: string): Promise<boolean>;
|
|
53
|
+
/** E21 会话删除级联(session_id 单键,路由已证会话所有权——resume-anchor 同理由)。 */
|
|
23
54
|
deleteBySession(sessionId: string): Promise<number>;
|
|
55
|
+
/** TTL 收割:未绑定且 created_at_ms < olderThanMs 的行。返回删除数。 */
|
|
24
56
|
reapUnbound(olderThanMs: number): Promise<number>;
|
|
57
|
+
/** D-1 孤儿**对象**彻底 GC(clay 拍 2026-07-28):列举对象存储 × meta 行对账,零行且过 grace 的对象删。
|
|
58
|
+
* 可选——local 店(meta+bytes 同盘同步删)无此孤儿类。 */
|
|
25
59
|
sweepOrphanObjects?(graceMs: number, nowMs?: number): Promise<number>;
|
|
26
60
|
}
|
|
27
61
|
export declare const TASK_ATTACHMENT_TABLE = "task_attachment";
|
|
62
|
+
/** 字节面 seam —— MinioBlobBackend 的结构子集(hash 键控;读侧 sha 校验在实现内)。`listObjects` 可选
|
|
63
|
+
* (D-1 孤儿对象 GC 的列举面;测试桩/无列举后端缺席=sweep 诚实 0,不装作扫过)。 */
|
|
28
64
|
export interface AttachmentBytesStore {
|
|
29
65
|
putBlob(hash: string, bytes: Uint8Array): Promise<void>;
|
|
30
66
|
getBlob(hash: string): Promise<Uint8Array | undefined>;
|
|
@@ -33,11 +69,19 @@ export interface AttachmentBytesStore {
|
|
|
33
69
|
hash: string;
|
|
34
70
|
lastModifiedMs: number;
|
|
35
71
|
}>;
|
|
72
|
+
/** 删前复查面(复审 B-F1):返回对象当前 LastModified(缺席=已不在)。缺此面 ⇒ sweep 保守**不删**
|
|
73
|
+
* (宁可留孤儿也不冒误删风险)——见 sweepOrphanObjects 的竞态注。 */
|
|
36
74
|
headObject?(hash: string): Promise<{
|
|
37
75
|
lastModifiedMs: number;
|
|
38
76
|
} | undefined>;
|
|
39
77
|
}
|
|
78
|
+
/** 物化相对路径(确定性,notice 与真实写盘共用一份推导——两处各算一遍会漂):按 listBySession 序
|
|
79
|
+
* (created_at_ms, id)分配 `attachments/<name>`;同名撞车时后者前缀 id 头 8 位。名字在上传时已
|
|
80
|
+
* 消毒为安全 basename([A-Za-z0-9._-]),拼接后仍是安全相对路径。 */
|
|
40
81
|
export declare function materializedRelPaths(atts: TaskAttachmentRecord[]): Map<string, string>;
|
|
82
|
+
/** 半场②(提交时绑定 + objective 告知)的可测核。fresh 腿硬验证(未知/他人 id → throw(mapTo400));
|
|
83
|
+
* resume 腿降级(warn+跳过——4xx 会砖存量 task;记录不可变 ⇒ 在场行的 notice 字节恒稳)。
|
|
84
|
+
* notice 路径从**绑定后的全 session 集**推导(与物化共用 materializedRelPaths),只罗列本次引用的文件。 */
|
|
41
85
|
export declare function bindAttachmentsForTask(opts: {
|
|
42
86
|
store: TaskAttachmentStore;
|
|
43
87
|
owner: string;
|
|
@@ -49,6 +93,8 @@ export declare function bindAttachmentsForTask(opts: {
|
|
|
49
93
|
}): Promise<{
|
|
50
94
|
notice: string | undefined;
|
|
51
95
|
}>;
|
|
96
|
+
/** 半场③(env 建立时物化)的可测核。**fail-loud**:objective 已宣告文件在场,静默缺文件=模型按幻影
|
|
97
|
+
* 文件行动,比 env 建立失败更糟 ⇒ 任一写失败即 throw。幂等:重建沙箱/resume 重写同路径同字节。 */
|
|
52
98
|
export declare function materializeAttachmentsInto(env: {
|
|
53
99
|
createDir(path: string, options?: {
|
|
54
100
|
recursive?: boolean;
|
|
@@ -71,6 +117,7 @@ export declare function materializeAttachmentsInto(env: {
|
|
|
71
117
|
}, store: TaskAttachmentStore, sessionId: string): Promise<number>;
|
|
72
118
|
export declare function ensureTiDBTaskAttachmentSchema(pool: Pool): Promise<void>;
|
|
73
119
|
export declare function ensurePgTaskAttachmentSchema(q: PgQueryFn): Promise<void>;
|
|
120
|
+
/** bytes → 4 MiB 块序列(共享切块器,两方言 + 完整性校验共用)。 */
|
|
74
121
|
export declare class TiDBTaskAttachmentStore implements TaskAttachmentStore {
|
|
75
122
|
private readonly pool;
|
|
76
123
|
private readonly bytes;
|
|
@@ -80,14 +127,24 @@ export declare class TiDBTaskAttachmentStore implements TaskAttachmentStore {
|
|
|
80
127
|
}): Promise<void>;
|
|
81
128
|
get(owner: string, id: string): Promise<TaskAttachmentRecord | null>;
|
|
82
129
|
getContent(owner: string, id: string): Promise<Uint8Array | null>;
|
|
130
|
+
/** 零引用对象删除(best-effort):meta 已删后,sha 仍被其他行引用则对象保留(跨行去重共享)。
|
|
131
|
+
* 失败只吞不抛——E21 purge 不被对象存储抖动卡死(blob-backend 异步删裁定同旨);无 meta 的对象
|
|
132
|
+
* 经 API 不可达,彻底清收敛记 follow-up。 */
|
|
83
133
|
private deleteBytesIfUnreferenced;
|
|
84
134
|
bind(owner: string, ids: string[], sessionId: string, boundAtMs: number): Promise<number>;
|
|
85
135
|
listBySession(sessionId: string): Promise<TaskAttachmentRecord[]>;
|
|
86
136
|
delete(owner: string, id: string): Promise<boolean>;
|
|
87
137
|
deleteBySession(sessionId: string): Promise<number>;
|
|
88
138
|
reapUnbound(olderThanMs: number): Promise<number>;
|
|
139
|
+
/** D-1 孤儿对象彻底 GC(clay 拍 2026-07-28):对象存储列举 × meta 行对账。判据保守三层:
|
|
140
|
+
* ①只删**真列举到**且 ②零 meta 行引用 且 ③LastModified 过 grace 的对象(上传先行窗口:对象先落、
|
|
141
|
+
* meta 行后写——grace 护住 put 竞态,宁漏勿误删,下轮再收);列举失败=整轮 throw(调用方 catch,
|
|
142
|
+
* 「列不出来」绝不当「没有孤儿」)。 */
|
|
89
143
|
sweepOrphanObjects(graceMs: number, nowMs?: number): Promise<number>;
|
|
144
|
+
/** sweep 的引用对账半场:批内 sha 中仍有 meta 行的子集(单 IN 查询;DISTINCT 免重复行膨胀)。 */
|
|
90
145
|
private referencedShas;
|
|
146
|
+
/** 删前复查(复审 B-F1):只保留「HEAD 仍在 且 LastModified 仍过 grace」的 hash。无 headObject
|
|
147
|
+
* 面 ⇒ 返回空集(保守不删);HEAD 抛错 ⇒ 该对象本轮跳过(下轮再收)。 */
|
|
91
148
|
private filterStillOrphan;
|
|
92
149
|
}
|
|
93
150
|
export declare class PgTaskAttachmentStore implements TaskAttachmentStore {
|
|
@@ -105,8 +162,11 @@ export declare class PgTaskAttachmentStore implements TaskAttachmentStore {
|
|
|
105
162
|
delete(owner: string, id: string): Promise<boolean>;
|
|
106
163
|
deleteBySession(sessionId: string): Promise<number>;
|
|
107
164
|
reapUnbound(olderThanMs: number): Promise<number>;
|
|
165
|
+
/** D-1 孤儿对象彻底 GC —— twin of the TiDB store(判据三层同注:真列举/零引用/过 grace)。 */
|
|
108
166
|
sweepOrphanObjects(graceMs: number, nowMs?: number): Promise<number>;
|
|
109
167
|
private referencedShas;
|
|
168
|
+
/** 删前复查(复审 B-F1):只保留「HEAD 仍在 且 LastModified 仍过 grace」的 hash。无 headObject
|
|
169
|
+
* 面 ⇒ 返回空集(保守不删);HEAD 抛错 ⇒ 该对象本轮跳过(下轮再收)。 */
|
|
110
170
|
private filterStillOrphan;
|
|
111
171
|
}
|
|
112
172
|
//# sourceMappingURL=task-attachment-store.d.ts.map
|