@sema-agent/server 1.322.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 +59 -3
- 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,9 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ForkRoutingSessionStore — the subRunner's session backing after core 1.350's fork 终修([1364]①/[1367]①).
|
|
3
|
+
*
|
|
4
|
+
* 问题形:core 的 `hostSessionFork` 在 HOST runner 的店里 fork,fork 子任务带 `requireExistingSession:true`
|
|
5
|
+
* 在 opts.runner(subRunner)上执行——subRunner 拆店时子任务查不到刚 fork 出的会话,响亮失败
|
|
6
|
+
* `resume.session_not_found`(cli 真机复现)。
|
|
7
|
+
*
|
|
8
|
+
* 但把 host durable 店**整个**给 subRunner(第一版修)被 codex 判两 high:普通子任务(council 镜头/
|
|
9
|
+
* team/子代理)会把每次运行都铸成 committed durable 会话——sweepStagingSessions 只扫**无 session_meta**
|
|
10
|
+
* 的 staging 弃置行,committed 子会话没有 reaper=无界增长;且进 owner 过滤的会话枚举(零 run 的内部
|
|
11
|
+
* 会话污染 /v1/sessions)。
|
|
12
|
+
*
|
|
13
|
+
* 此包装店按**会话的真居所**路由,两边语义都保住:
|
|
14
|
+
* - `acquire(id, {requireExisting})`(fork 子 + retained-child resume 的形)→ **host 店优先**,miss 落
|
|
15
|
+
* transient(retained 瞬态子的 resume 仍走私店);两边都 miss=抛 host 侧错误(fail-loud 原语义)。
|
|
16
|
+
* - `acquire()`(无 id=普通子任务铸新会话)→ **transient**(throwaway 姿势保留:council/team 子会话
|
|
17
|
+
* 不落 durable、不进枚举、TTL 自清)。
|
|
18
|
+
* - `acquire(id)`(带 id 不 requireExisting)→ 已有路由按路由走;未知 id 落 transient(claim-create
|
|
19
|
+
* 绝不打到 durable 店——那是 authorizer 的职权)。
|
|
20
|
+
* - `fork(sourceId)` → 源在哪店在哪店 fork(路由未知时 host 先试,null 再 transient);新 id 记路由。
|
|
21
|
+
* - `list`/`size`/`dispose` = transient 侧(host 店归 main runner 所有;不双列、不双清)。
|
|
22
|
+
*
|
|
23
|
+
* 路由表 LRU 上限 {@link ROUTE_MAX}:满额逐最老(refresh-on-use);被逐后下次 `acquire` 按上述规则重derive
|
|
24
|
+
* (requireExisting 的 host-first 重试仍落对店),中途 touch/noteTaskRun 缺路由=落 transient(no-op 级)。
|
|
25
|
+
*/
|
|
1
26
|
import type { SessionStore, AcquiredSession, SessionStoreSummary } from "@sema-agent/core";
|
|
2
27
|
export declare class ForkRoutingSessionStore implements SessionStore {
|
|
3
28
|
private readonly host;
|
|
4
29
|
private readonly transient;
|
|
5
30
|
private readonly route;
|
|
31
|
+
/** pin 时的店归属——unpin 恒回同店(LRU 逐出不拆对,见 pin/unpin)。 */
|
|
6
32
|
private readonly pinnedAt;
|
|
33
|
+
/** [1593] 晋升名册(探针 Finding A 修):已 promoteToHost 的 id **永久**钉 host——路由表会被 LRU
|
|
34
|
+
* 逐出,而私店的 forget 只清 entries 缓存行、底层 repo 行不清且 sweep 扫不到(core session-store.js
|
|
35
|
+
* 亲读),逐出后 transient-first 的 requireExisting 会把陈旧快照端回给 revive。本集不逐出(上界=
|
|
36
|
+
* parked 子代数,天然小);pick/acquire 首查。 */
|
|
7
37
|
private readonly promoted;
|
|
8
38
|
constructor(host: SessionStore, transient: SessionStore);
|
|
9
39
|
private remember;
|
|
@@ -18,6 +48,23 @@ export declare class ForkRoutingSessionStore implements SessionStore {
|
|
|
18
48
|
unpin(sessionId: string): void | Promise<void>;
|
|
19
49
|
noteTaskRun(sessionId: string, taskId: string): void | Promise<void>;
|
|
20
50
|
list(): Promise<SessionStoreSummary[]>;
|
|
51
|
+
/**
|
|
52
|
+
* [1593] 子代 park 晋升:把住在 transient(TTL)店的子会话**整树拷贝**进 host durable 店,然后
|
|
53
|
+
* 让该 id 从此路由到 host——`ensureChildSessionDurable` 的「主动晋升」半场(1.263 的只查不迁形在
|
|
54
|
+
* 拆店生产形下恒否决 park:子会话从不在 host 店,core 收 veto 即 expire checkpoint + settle failed,
|
|
55
|
+
* cli 真机 14ms~2s expired 即此)。
|
|
56
|
+
*
|
|
57
|
+
* 三步缺一不可:
|
|
58
|
+
* 1. 拷贝:transient 读整树(getEntries)+ 源 leaf → host 店 acquire(id)(durable 店的 acquire
|
|
59
|
+
* 缺行即建行)→ storage.appendEntry 逐条 verbatim(重复 id 容忍=幂等续迁:上次晋升半途崩的
|
|
60
|
+
* 残留行跳过)→ setLeafId(源 leaf)(分支树以源为准,不信 append 推进的 leaf)。
|
|
61
|
+
* 2. transient.forget(id):`requireExisting` 的 acquire 是 **transient-first**(F-7 裁定)——私店
|
|
62
|
+
* 副本不移除,revive 会续写进 1h TTL 副本,durable park 名存实亡。
|
|
63
|
+
* 3. 路由记 host(此后 touch/pin/release 全走 host;pinnedAt 若记着 transient 一并改写,
|
|
64
|
+
* unpin 不落错店)。
|
|
65
|
+
*
|
|
66
|
+
* 已在 host(路由或真行)⇒ 幂等直返。两店都无此会话 ⇒ 抛(调用方=park veto,诚实 fail-closed)。
|
|
67
|
+
*/
|
|
21
68
|
promoteToHost(sessionId: string): Promise<void>;
|
|
22
69
|
fork(sourceId: string, owner?: string | null): Promise<string | null>;
|
|
23
70
|
get size(): number;
|
|
@@ -3,11 +3,19 @@ export class ForkRoutingSessionStore {
|
|
|
3
3
|
host;
|
|
4
4
|
transient;
|
|
5
5
|
route = new Map();
|
|
6
|
+
/** pin 时的店归属——unpin 恒回同店(LRU 逐出不拆对,见 pin/unpin)。 */
|
|
6
7
|
pinnedAt = new Map();
|
|
8
|
+
/** [1593] 晋升名册(探针 Finding A 修):已 promoteToHost 的 id **永久**钉 host——路由表会被 LRU
|
|
9
|
+
* 逐出,而私店的 forget 只清 entries 缓存行、底层 repo 行不清且 sweep 扫不到(core session-store.js
|
|
10
|
+
* 亲读),逐出后 transient-first 的 requireExisting 会把陈旧快照端回给 revive。本集不逐出(上界=
|
|
11
|
+
* parked 子代数,天然小);pick/acquire 首查。 */
|
|
7
12
|
promoted = new Set();
|
|
8
13
|
constructor(host, transient) {
|
|
9
14
|
this.host = host;
|
|
10
15
|
this.transient = transient;
|
|
16
|
+
// backlog(hasSessionFork 恒真):两 backing 都无 fork 面时,包装店的 fork 方法**摘除**——core 的
|
|
17
|
+
// fork 门(hasSessionFork(opts.runner.sessions))才能诚实报 fork.unavailable,而不是放行后折叠成
|
|
18
|
+
// 误导性的「source not found」。现三 backing 均有 fork,此臂为接入无 fork durable backend 备。
|
|
11
19
|
if (host.fork === undefined && transient.fork === undefined) {
|
|
12
20
|
this.fork = undefined;
|
|
13
21
|
}
|
|
@@ -23,10 +31,10 @@ export class ForkRoutingSessionStore {
|
|
|
23
31
|
}
|
|
24
32
|
pick(id) {
|
|
25
33
|
if (this.promoted.has(id))
|
|
26
|
-
return this.host;
|
|
34
|
+
return this.host; // [1593] 晋升名册优先(路由可被 LRU 逐出,名册不逐)
|
|
27
35
|
const r = this.route.get(id);
|
|
28
36
|
if (r !== undefined)
|
|
29
|
-
this.remember(id, r);
|
|
37
|
+
this.remember(id, r); // refresh recency
|
|
30
38
|
return r === "host" ? this.host : this.transient;
|
|
31
39
|
}
|
|
32
40
|
async acquire(sessionId, opts) {
|
|
@@ -36,6 +44,8 @@ export class ForkRoutingSessionStore {
|
|
|
36
44
|
return a;
|
|
37
45
|
}
|
|
38
46
|
if (this.promoted.has(sessionId)) {
|
|
47
|
+
// [1593] 晋升名册:恒走 host——绝不能让 transient-first 把 forget 后仍活在私店 repo 里的陈旧
|
|
48
|
+
// 快照端给 revive(探针 Finding A)。
|
|
39
49
|
const a = await this.host.acquire(sessionId, opts);
|
|
40
50
|
this.remember(sessionId, "host");
|
|
41
51
|
return a;
|
|
@@ -46,6 +56,10 @@ export class ForkRoutingSessionStore {
|
|
|
46
56
|
return a;
|
|
47
57
|
}
|
|
48
58
|
if (opts?.requireExisting) {
|
|
59
|
+
// PAIR-REVIEW F-7(codex 过审):**transient-first**——retained 瞬态子 resume 直达私店;fork 子恒不在
|
|
60
|
+
// transient(miss)→ fallback host 命中,语义不变。顺序反转封住 F-7 组合链:同 id 在两店并存时
|
|
61
|
+
// (child uuid 被同租户误提交到主 API 而 host 店 claim-create 出空壳),真子会话(transient)赢,
|
|
62
|
+
// 空壳不遮蔽。双 miss 抛 host 侧错误(响亮,fail-closed 到「真不存在」)。
|
|
49
63
|
let transientErr;
|
|
50
64
|
try {
|
|
51
65
|
const a = await this.transient.acquire(sessionId, opts);
|
|
@@ -65,6 +79,7 @@ export class ForkRoutingSessionStore {
|
|
|
65
79
|
throw hostErr;
|
|
66
80
|
}
|
|
67
81
|
}
|
|
82
|
+
// 带 id 但不要求已存在:claim-create 只允许落 transient(durable 店的 claim-create 是 authorizer 的职权)。
|
|
68
83
|
const a = await this.transient.acquire(sessionId, opts);
|
|
69
84
|
this.remember(sessionId, "transient");
|
|
70
85
|
return a;
|
|
@@ -76,11 +91,16 @@ export class ForkRoutingSessionStore {
|
|
|
76
91
|
return this.pick(sessionId).release(sessionId);
|
|
77
92
|
}
|
|
78
93
|
forget(sessionId) {
|
|
94
|
+
// PAIR-REVIEW F-8:forget=显式移除 → 路由项同步清(死 id 不再占 LRU 槽挤活路由);release 保留
|
|
95
|
+
// 路由(retained 子 resume 会再 acquire,清了只是多付一次 derive)。
|
|
79
96
|
const target = this.pick(sessionId);
|
|
80
97
|
this.route.delete(sessionId);
|
|
81
98
|
return target.forget?.(sessionId);
|
|
82
99
|
}
|
|
83
100
|
pin(sessionId) {
|
|
101
|
+
// backlog 潜伏钉(pin/unpin 路由不对称):pin 时 refresh 路由近度(remember 已在 pick 内做)+把
|
|
102
|
+
// pinned id 记入独立集合——unpin 优先按 pin 时的店走,LRU 逐出不再能把 pin/unpin 拆到两家店
|
|
103
|
+
// (host 店永久 pinned 不可回收的潜伏形就此封死)。
|
|
84
104
|
const r = this.route.get(sessionId);
|
|
85
105
|
if (r !== undefined)
|
|
86
106
|
this.pinnedAt.set(sessionId, r);
|
|
@@ -100,6 +120,23 @@ export class ForkRoutingSessionStore {
|
|
|
100
120
|
list() {
|
|
101
121
|
return this.transient.list?.() ?? Promise.resolve([]);
|
|
102
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* [1593] 子代 park 晋升:把住在 transient(TTL)店的子会话**整树拷贝**进 host durable 店,然后
|
|
125
|
+
* 让该 id 从此路由到 host——`ensureChildSessionDurable` 的「主动晋升」半场(1.263 的只查不迁形在
|
|
126
|
+
* 拆店生产形下恒否决 park:子会话从不在 host 店,core 收 veto 即 expire checkpoint + settle failed,
|
|
127
|
+
* cli 真机 14ms~2s expired 即此)。
|
|
128
|
+
*
|
|
129
|
+
* 三步缺一不可:
|
|
130
|
+
* 1. 拷贝:transient 读整树(getEntries)+ 源 leaf → host 店 acquire(id)(durable 店的 acquire
|
|
131
|
+
* 缺行即建行)→ storage.appendEntry 逐条 verbatim(重复 id 容忍=幂等续迁:上次晋升半途崩的
|
|
132
|
+
* 残留行跳过)→ setLeafId(源 leaf)(分支树以源为准,不信 append 推进的 leaf)。
|
|
133
|
+
* 2. transient.forget(id):`requireExisting` 的 acquire 是 **transient-first**(F-7 裁定)——私店
|
|
134
|
+
* 副本不移除,revive 会续写进 1h TTL 副本,durable park 名存实亡。
|
|
135
|
+
* 3. 路由记 host(此后 touch/pin/release 全走 host;pinnedAt 若记着 transient 一并改写,
|
|
136
|
+
* unpin 不落错店)。
|
|
137
|
+
*
|
|
138
|
+
* 已在 host(路由或真行)⇒ 幂等直返。两店都无此会话 ⇒ 抛(调用方=park veto,诚实 fail-closed)。
|
|
139
|
+
*/
|
|
103
140
|
async promoteToHost(sessionId) {
|
|
104
141
|
if (this.promoted.has(sessionId))
|
|
105
142
|
return;
|
|
@@ -112,17 +149,24 @@ export class ForkRoutingSessionStore {
|
|
|
112
149
|
src = await this.transient.acquire(sessionId, { requireExisting: true });
|
|
113
150
|
}
|
|
114
151
|
catch {
|
|
152
|
+
// 私店无此会话:可能已在 host(直查确认=幂等),否则如实抛(host 侧错误响亮上浮)
|
|
115
153
|
const probe = await this.host.acquire(sessionId, { requireExisting: true });
|
|
116
154
|
await this.host.release(probe.sessionId);
|
|
117
155
|
this.promoted.add(sessionId);
|
|
118
156
|
this.remember(sessionId, "host");
|
|
119
157
|
return;
|
|
120
158
|
}
|
|
159
|
+
// ⚠️ 私店源在此**不 release**:TtlSessionStore.release 对非 pinned 会话=整删(F3 教训)——拷贝
|
|
160
|
+
// 失败时删源=毁掉仍在跑/仍可赎回的子会话。成功路径由下方 forget(纯 entries 移除,无 repo 删)收尾;
|
|
161
|
+
// 失败路径源原样留活,veto 如实上浮。
|
|
121
162
|
const entries = await src.session.getEntries();
|
|
122
163
|
const leaf = await src.session.getLeafId();
|
|
123
164
|
const dst = await this.host.acquire(sessionId);
|
|
124
165
|
try {
|
|
125
166
|
const storage = dst.session.getStorage();
|
|
167
|
+
// 探针 Finding B 修:core 各 storage 的 appendEntry 对重复 id **不抛不查**(storage-base 亲读)
|
|
168
|
+
// ——靠 try/catch 实现幂等是空想,断续晋升会把同 id 双写成脏树(且脏树会被 import-validate 的
|
|
169
|
+
// 重复 id 门拒)。真幂等 = 先读 dst 现存 id 集,set-diff 后只补缺。
|
|
126
170
|
const existing = new Set((await dst.session.getEntries()).map((e) => e.id));
|
|
127
171
|
for (const entry of entries) {
|
|
128
172
|
if (existing.has(entry.id))
|
|
@@ -141,6 +185,10 @@ export class ForkRoutingSessionStore {
|
|
|
141
185
|
await this.transient.forget?.(sessionId);
|
|
142
186
|
}
|
|
143
187
|
catch {
|
|
188
|
+
// forget 失败不阻断晋升。⚠️ forget 本就只清私店的 entries 缓存行——底层 repo 行不清、sweep 也
|
|
189
|
+
// 扫不到(探针 Finding A 取证),陈旧快照在私店**永生**;对 revive 的真防线是上面的晋升名册
|
|
190
|
+
// (promoted 集恒指 host,不随路由 LRU 逐出),forget 只是缩内存的 best-effort。transient.pinned
|
|
191
|
+
// 可能残留该 id(forget 不清 pin 集)——unpin 已随 pinnedAt 改写落 host,残留仅是空集合项。
|
|
144
192
|
}
|
|
145
193
|
if (this.pinnedAt.get(sessionId) === "transient")
|
|
146
194
|
this.pinnedAt.set(sessionId, "host");
|
|
@@ -167,7 +215,7 @@ export class ForkRoutingSessionStore {
|
|
|
167
215
|
return this.transient.size;
|
|
168
216
|
}
|
|
169
217
|
dispose() {
|
|
170
|
-
return this.transient.dispose();
|
|
218
|
+
return this.transient.dispose(); // host 店归 main runner 所有,绝不在此清
|
|
171
219
|
}
|
|
172
220
|
}
|
|
173
221
|
//# sourceMappingURL=fork-routing-session-store.js.map
|
|
@@ -1,19 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host-lane PLATFORM seam (DESIGN-windows-native.md, FINAL r3) — the ONE place the host exec adapter's
|
|
3
|
+
* POSIX/win32 differences live, so `remote-env-host.ts` stays a single code path with platform-gated leaves.
|
|
4
|
+
*
|
|
5
|
+
* 🔴 Iron invariant (design §4.1): the POSIX path is BYTE-IDENTICAL to the pre-Windows code — every helper is
|
|
6
|
+
* `win32 ? new : exactly-what-the-inline-code-did` (same syscall, same throw behavior). Never "improve" POSIX
|
|
7
|
+
* here; the existing full test suite is the regression net.
|
|
8
|
+
*
|
|
9
|
+
* win32 semantics (design D1-D4):
|
|
10
|
+
* - shell = Git Bash via core 1.224 `getShellConfig` (WSL-launcher-filtered — the `System32\bash.exe`
|
|
11
|
+
* trap). Fail-LOUD when absent; never silently degrade to cmd (D1).
|
|
12
|
+
* - kill = core 1.224 `signalProcessTree` (taskkill /T, /F for hard). Soft is a no-op for console trees
|
|
13
|
+
* (taskkill errors "can only be terminated forcefully") — the SIGTERM→grace→SIGKILL ladder is
|
|
14
|
+
* effectively delay→hard-kill on win32; accepted, CC-identical (D2).
|
|
15
|
+
* - spawn = `detached:false` + `windowsHide:true` (no console window; no POSIX process group — the kill
|
|
16
|
+
* side uses the tree, not the group) (D3).
|
|
17
|
+
* - env = case-insensitive key collapse before spawn (win32 env keys are case-insensitive; a `Path`+`PATH`
|
|
18
|
+
* pair from case-sensitive Object.assign reaches CreateProcess as ONE undefined-which
|
|
19
|
+
* entry). Canonical casing = the first-seen key (process.env's native casing wins since the
|
|
20
|
+
* inherit base is spread first).
|
|
21
|
+
*
|
|
22
|
+
* ⚠️ The win32 branches are UNVERIFIED on a real machine until S5 (Windows CI runner) — design D5 discipline:
|
|
23
|
+
* structural tests only on mac/Linux; behavior-level bite happens on the first Windows-runner green.
|
|
24
|
+
*/
|
|
1
25
|
import { killProcessTree } from "@sema-agent/core";
|
|
2
26
|
export declare const IS_WIN32: boolean;
|
|
3
27
|
export interface HostShell {
|
|
4
28
|
shell: string;
|
|
5
29
|
args: string[];
|
|
6
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Resolve the host shell ONCE per process (cached). POSIX resolves synchronously to `/bin/sh` — zero behavior
|
|
33
|
+
* change. win32 defers to core's `getShellConfig` (explicit `HOST_SHELL_PATH` override → Git-for-Windows
|
|
34
|
+
* install dirs → PATH `bash.exe` with the WSL-launcher filter) and THROWS a self-explaining error when no
|
|
35
|
+
* usable bash exists (design D1 fail-loud: "install Git for Windows", never a silent cmd fallback).
|
|
36
|
+
*
|
|
37
|
+
* Call sites: `shellReady()` awaits this once (all exec/bg/stream spawns are behind it), then the spawn sites
|
|
38
|
+
* read the cached value synchronously via {@link hostShell}.
|
|
39
|
+
*/
|
|
7
40
|
export declare function resolveHostShell(): Promise<HostShell>;
|
|
41
|
+
/** Synchronous read of the resolved shell — valid only AFTER {@link resolveHostShell} settled (the spawn sites
|
|
42
|
+
* are all behind `shellReady()`, which awaits it). POSIX never needs the async step. Throws on a mis-ordered
|
|
43
|
+
* call (a programming bug, not an operator condition — fail loud, not /bin/sh-on-windows). */
|
|
8
44
|
export declare function hostShell(): HostShell;
|
|
45
|
+
/** test-only: reset the shell caches (each test can re-drive resolution). */
|
|
9
46
|
export declare function resetHostShellCacheForTest(): void;
|
|
47
|
+
/** Per-platform spawn options for a group-killable child (design D3).
|
|
48
|
+
* POSIX: `detached:true` — child becomes its own process-group leader (pgid === pid) so `kill(-pid)` reaps the
|
|
49
|
+
* whole group. BYTE-IDENTICAL to the previous inline `detached: true`.
|
|
50
|
+
* win32: `detached:false` (a detached child opens a console; there is no killable POSIX group either way —
|
|
51
|
+
* the kill side uses taskkill's tree) + `windowsHide:true` (no flashing console window). */
|
|
10
52
|
export declare function spawnGroupOptions(): {
|
|
11
53
|
detached: boolean;
|
|
12
54
|
windowsHide?: boolean;
|
|
13
55
|
};
|
|
56
|
+
/**
|
|
57
|
+
* HARD kill of the child's whole tree (design D2). POSIX = `process.kill(-pid, "SIGKILL")` — byte-identical,
|
|
58
|
+
* INCLUDING the throw on a dead group (ESRCH): every call site already wraps in its own try/catch with its own
|
|
59
|
+
* fallback (e.g. `child.kill("SIGKILL")`), and that structure must not change.
|
|
60
|
+
* win32 = core `signalProcessTree(pid,"SIGKILL")` → `taskkill /F /T` (never throws — fire-and-forget spawn).
|
|
61
|
+
*/
|
|
14
62
|
export declare function killTreeHard(pid: number): void;
|
|
63
|
+
/**
|
|
64
|
+
* SOFT kill (design D2 — the bg KillShell/timeout-wall first rung; the caller owns the grace→hard escalation
|
|
65
|
+
* timer, unchanged). POSIX = `process.kill(-pid, "SIGTERM")` byte-identical (throws on dead group — the caller
|
|
66
|
+
* treats that as "already dead, skip escalation"). win32 = `taskkill /T` without /F — which for a typical
|
|
67
|
+
* all-console tree ERRORS AND KILLS NOTHING: the ladder degrades to delay→hard-kill there;
|
|
68
|
+
* accepted + documented (CC-identical). It never throws, so the caller's "already dead → return" branch never
|
|
69
|
+
* fires on win32 — the escalation timer always arms, which is exactly what we want given soft is a no-op.
|
|
70
|
+
*/
|
|
15
71
|
export declare function killTreeSoft(pid: number): void;
|
|
72
|
+
/** Graceful tree kill where the CALLER has no escalation timer of its own (currently unused by the host lane —
|
|
73
|
+
* exported for parity with core's surface; the bg driver keeps its own HOST_BG_KILL_GRACE_MS ladder). */
|
|
16
74
|
export { killProcessTree };
|
|
75
|
+
/**
|
|
76
|
+
* win32 env-key case collapse (design D1). Windows env keys are case-insensitive; Node hands the
|
|
77
|
+
* object to CreateProcess as-is, so a case-sensitive merge that produced BOTH `Path` (inherited) and `PATH`
|
|
78
|
+
* (caller override) yields one-of-them-undefined-which in the child. Collapse case-duplicate keys LAST-WRITE-WINS
|
|
79
|
+
* in iteration order — matching what `Object.assign` semantics promised the caller (per-command overrides beat
|
|
80
|
+
* config env beats inherited base) — while keeping the FIRST-SEEN casing (the inherited base is assigned first,
|
|
81
|
+
* so `Path=…` inherited + `PATH=x` override collapses to `Path=x`: native casing, override value).
|
|
82
|
+
* POSIX: returns the input UNTOUCHED (case-sensitive env is real there — `Path` and `PATH` are distinct).
|
|
83
|
+
*/
|
|
17
84
|
export declare function collapseWin32EnvKeys(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
|
85
|
+
/** The platform-free collapse algorithm (exported so the mac/Linux suite can pin the win32 behavior — design
|
|
86
|
+
* D5: structural verification everywhere, behavioral bite on the Windows runner). */
|
|
18
87
|
export declare function collapseEnvKeysCaseInsensitive(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
|
19
88
|
//# sourceMappingURL=host-platform.d.ts.map
|
|
@@ -1,12 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host-lane PLATFORM seam (DESIGN-windows-native.md, FINAL r3) — the ONE place the host exec adapter's
|
|
3
|
+
* POSIX/win32 differences live, so `remote-env-host.ts` stays a single code path with platform-gated leaves.
|
|
4
|
+
*
|
|
5
|
+
* 🔴 Iron invariant (design §4.1): the POSIX path is BYTE-IDENTICAL to the pre-Windows code — every helper is
|
|
6
|
+
* `win32 ? new : exactly-what-the-inline-code-did` (same syscall, same throw behavior). Never "improve" POSIX
|
|
7
|
+
* here; the existing full test suite is the regression net.
|
|
8
|
+
*
|
|
9
|
+
* win32 semantics (design D1-D4):
|
|
10
|
+
* - shell = Git Bash via core 1.224 `getShellConfig` (WSL-launcher-filtered — the `System32\bash.exe`
|
|
11
|
+
* trap). Fail-LOUD when absent; never silently degrade to cmd (D1).
|
|
12
|
+
* - kill = core 1.224 `signalProcessTree` (taskkill /T, /F for hard). Soft is a no-op for console trees
|
|
13
|
+
* (taskkill errors "can only be terminated forcefully") — the SIGTERM→grace→SIGKILL ladder is
|
|
14
|
+
* effectively delay→hard-kill on win32; accepted, CC-identical (D2).
|
|
15
|
+
* - spawn = `detached:false` + `windowsHide:true` (no console window; no POSIX process group — the kill
|
|
16
|
+
* side uses the tree, not the group) (D3).
|
|
17
|
+
* - env = case-insensitive key collapse before spawn (win32 env keys are case-insensitive; a `Path`+`PATH`
|
|
18
|
+
* pair from case-sensitive Object.assign reaches CreateProcess as ONE undefined-which
|
|
19
|
+
* entry). Canonical casing = the first-seen key (process.env's native casing wins since the
|
|
20
|
+
* inherit base is spread first).
|
|
21
|
+
*
|
|
22
|
+
* ⚠️ The win32 branches are UNVERIFIED on a real machine until S5 (Windows CI runner) — design D5 discipline:
|
|
23
|
+
* structural tests only on mac/Linux; behavior-level bite happens on the first Windows-runner green.
|
|
24
|
+
*/
|
|
1
25
|
import { getShellConfig, killProcessTree, signalProcessTree } from "@sema-agent/core";
|
|
2
26
|
export const IS_WIN32 = process.platform === "win32";
|
|
27
|
+
/** S1([1870] test AI 全归因,2026-07-27):POSIX 不再硬编码 `/bin/sh`——Debian/Ubuntu 的 /bin/sh 是
|
|
28
|
+
* dash,TB 实测三类病:`$'a\tb'` **静默错字节**(exit 0、输出字面 5 字节)、`[[ ]]` 127、进程替换
|
|
29
|
+
* 语法错;CC 对照从不用 /bin/sh。改为与 win32 同源:core `getShellConfig()`(/bin/bash → PATH bash
|
|
30
|
+
* → `sh` 诚实兜底,core 六版逐字节稳定被 test AI 洗清)。旧「POSIX byte-identical」铁律就此**有意**
|
|
31
|
+
* 打破——它防的是 Windows 改动误伤 POSIX,这次是带失分证据 + CC 对照的 POSIX 行为修正。
|
|
32
|
+
* 极罕的无 bash 宿主(alpine 裸机)拿 core 的 `sh` 兜底,行为=修前。 */
|
|
3
33
|
const POSIX_SH_FALLBACK = { shell: "/bin/sh", args: ["-c"] };
|
|
4
34
|
let cachedWinShell;
|
|
5
35
|
let cachedPosixShell;
|
|
36
|
+
/**
|
|
37
|
+
* Resolve the host shell ONCE per process (cached). POSIX resolves synchronously to `/bin/sh` — zero behavior
|
|
38
|
+
* change. win32 defers to core's `getShellConfig` (explicit `HOST_SHELL_PATH` override → Git-for-Windows
|
|
39
|
+
* install dirs → PATH `bash.exe` with the WSL-launcher filter) and THROWS a self-explaining error when no
|
|
40
|
+
* usable bash exists (design D1 fail-loud: "install Git for Windows", never a silent cmd fallback).
|
|
41
|
+
*
|
|
42
|
+
* Call sites: `shellReady()` awaits this once (all exec/bg/stream spawns are behind it), then the spawn sites
|
|
43
|
+
* read the cached value synchronously via {@link hostShell}.
|
|
44
|
+
*/
|
|
6
45
|
export async function resolveHostShell() {
|
|
7
46
|
if (!IS_WIN32) {
|
|
8
47
|
if (cachedPosixShell)
|
|
9
48
|
return cachedPosixShell;
|
|
49
|
+
// S1:POSIX 与 win32 同源(core getShellConfig:/bin/bash → PATH bash → sh 兜底;POSIX 分支
|
|
50
|
+
// 恒 ok——sh 兜底也是 ok 形,故这里不需要 win32 的 fail-loud 臂)。HOST_SHELL_PATH 同一覆写口。
|
|
10
51
|
const posixCfg = await getShellConfig(process.env.HOST_SHELL_PATH || undefined);
|
|
11
52
|
cachedPosixShell = posixCfg.ok ? { shell: posixCfg.value.shell, args: posixCfg.value.args } : POSIX_SH_FALLBACK;
|
|
12
53
|
return cachedPosixShell;
|
|
@@ -23,21 +64,38 @@ export async function resolveHostShell() {
|
|
|
23
64
|
cachedWinShell = { shell: cfg.value.shell, args: cfg.value.args };
|
|
24
65
|
return cachedWinShell;
|
|
25
66
|
}
|
|
67
|
+
/** Synchronous read of the resolved shell — valid only AFTER {@link resolveHostShell} settled (the spawn sites
|
|
68
|
+
* are all behind `shellReady()`, which awaits it). POSIX never needs the async step. Throws on a mis-ordered
|
|
69
|
+
* call (a programming bug, not an operator condition — fail loud, not /bin/sh-on-windows). */
|
|
26
70
|
export function hostShell() {
|
|
27
71
|
if (!IS_WIN32) {
|
|
72
|
+
// S1 后 POSIX 也走异步解析;未解析先到的同步读拿 sh 兜底(修前字节形)而非 throw——POSIX 的
|
|
73
|
+
// 病是 dash 语义不是缺 shell,这里降级无害且绝不把既有调用序变成崩溃。解析后即恒 bash。
|
|
28
74
|
return cachedPosixShell ?? POSIX_SH_FALLBACK;
|
|
29
75
|
}
|
|
30
76
|
if (!cachedWinShell)
|
|
31
77
|
throw new Error("host shell not resolved yet — resolveHostShell() must settle before any spawn (shellReady ordering bug)");
|
|
32
78
|
return cachedWinShell;
|
|
33
79
|
}
|
|
80
|
+
/** test-only: reset the shell caches (each test can re-drive resolution). */
|
|
34
81
|
export function resetHostShellCacheForTest() {
|
|
35
82
|
cachedWinShell = undefined;
|
|
36
83
|
cachedPosixShell = undefined;
|
|
37
84
|
}
|
|
85
|
+
/** Per-platform spawn options for a group-killable child (design D3).
|
|
86
|
+
* POSIX: `detached:true` — child becomes its own process-group leader (pgid === pid) so `kill(-pid)` reaps the
|
|
87
|
+
* whole group. BYTE-IDENTICAL to the previous inline `detached: true`.
|
|
88
|
+
* win32: `detached:false` (a detached child opens a console; there is no killable POSIX group either way —
|
|
89
|
+
* the kill side uses taskkill's tree) + `windowsHide:true` (no flashing console window). */
|
|
38
90
|
export function spawnGroupOptions() {
|
|
39
91
|
return IS_WIN32 ? { detached: false, windowsHide: true } : { detached: true };
|
|
40
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* HARD kill of the child's whole tree (design D2). POSIX = `process.kill(-pid, "SIGKILL")` — byte-identical,
|
|
95
|
+
* INCLUDING the throw on a dead group (ESRCH): every call site already wraps in its own try/catch with its own
|
|
96
|
+
* fallback (e.g. `child.kill("SIGKILL")`), and that structure must not change.
|
|
97
|
+
* win32 = core `signalProcessTree(pid,"SIGKILL")` → `taskkill /F /T` (never throws — fire-and-forget spawn).
|
|
98
|
+
*/
|
|
41
99
|
export function killTreeHard(pid) {
|
|
42
100
|
if (IS_WIN32) {
|
|
43
101
|
signalProcessTree(pid, "SIGKILL");
|
|
@@ -45,6 +103,14 @@ export function killTreeHard(pid) {
|
|
|
45
103
|
}
|
|
46
104
|
process.kill(-pid, "SIGKILL");
|
|
47
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* SOFT kill (design D2 — the bg KillShell/timeout-wall first rung; the caller owns the grace→hard escalation
|
|
108
|
+
* timer, unchanged). POSIX = `process.kill(-pid, "SIGTERM")` byte-identical (throws on dead group — the caller
|
|
109
|
+
* treats that as "already dead, skip escalation"). win32 = `taskkill /T` without /F — which for a typical
|
|
110
|
+
* all-console tree ERRORS AND KILLS NOTHING: the ladder degrades to delay→hard-kill there;
|
|
111
|
+
* accepted + documented (CC-identical). It never throws, so the caller's "already dead → return" branch never
|
|
112
|
+
* fires on win32 — the escalation timer always arms, which is exactly what we want given soft is a no-op.
|
|
113
|
+
*/
|
|
48
114
|
export function killTreeSoft(pid) {
|
|
49
115
|
if (IS_WIN32) {
|
|
50
116
|
signalProcessTree(pid, "SIGTERM");
|
|
@@ -52,14 +118,27 @@ export function killTreeSoft(pid) {
|
|
|
52
118
|
}
|
|
53
119
|
process.kill(-pid, "SIGTERM");
|
|
54
120
|
}
|
|
121
|
+
/** Graceful tree kill where the CALLER has no escalation timer of its own (currently unused by the host lane —
|
|
122
|
+
* exported for parity with core's surface; the bg driver keeps its own HOST_BG_KILL_GRACE_MS ladder). */
|
|
55
123
|
export { killProcessTree };
|
|
124
|
+
/**
|
|
125
|
+
* win32 env-key case collapse (design D1). Windows env keys are case-insensitive; Node hands the
|
|
126
|
+
* object to CreateProcess as-is, so a case-sensitive merge that produced BOTH `Path` (inherited) and `PATH`
|
|
127
|
+
* (caller override) yields one-of-them-undefined-which in the child. Collapse case-duplicate keys LAST-WRITE-WINS
|
|
128
|
+
* in iteration order — matching what `Object.assign` semantics promised the caller (per-command overrides beat
|
|
129
|
+
* config env beats inherited base) — while keeping the FIRST-SEEN casing (the inherited base is assigned first,
|
|
130
|
+
* so `Path=…` inherited + `PATH=x` override collapses to `Path=x`: native casing, override value).
|
|
131
|
+
* POSIX: returns the input UNTOUCHED (case-sensitive env is real there — `Path` and `PATH` are distinct).
|
|
132
|
+
*/
|
|
56
133
|
export function collapseWin32EnvKeys(env) {
|
|
57
134
|
if (!IS_WIN32)
|
|
58
135
|
return env;
|
|
59
136
|
return collapseEnvKeysCaseInsensitive(env);
|
|
60
137
|
}
|
|
138
|
+
/** The platform-free collapse algorithm (exported so the mac/Linux suite can pin the win32 behavior — design
|
|
139
|
+
* D5: structural verification everywhere, behavioral bite on the Windows runner). */
|
|
61
140
|
export function collapseEnvKeysCaseInsensitive(env) {
|
|
62
|
-
const canonical = new Map();
|
|
141
|
+
const canonical = new Map(); // lowercased key → first-seen casing
|
|
63
142
|
const out = {};
|
|
64
143
|
for (const [k, v] of Object.entries(env)) {
|
|
65
144
|
if (v === undefined)
|
|
@@ -71,7 +150,7 @@ export function collapseEnvKeysCaseInsensitive(env) {
|
|
|
71
150
|
out[k] = v;
|
|
72
151
|
}
|
|
73
152
|
else {
|
|
74
|
-
out[keep] = v;
|
|
153
|
+
out[keep] = v; // later (higher-precedence) value under the first-seen casing
|
|
75
154
|
}
|
|
76
155
|
}
|
|
77
156
|
return out;
|
|
@@ -2,51 +2,186 @@ import type { Pool as MySqlPool } from "mysql2/promise";
|
|
|
2
2
|
import type { Pool as PgPool, PoolClient } from "pg";
|
|
3
3
|
import { type SqlDriver } from "./sql-driver.js";
|
|
4
4
|
import { type BakeStatus, type BakeState, type BakeRecord, type BakeEvent, type CreateBakeInput, type BakeTerminal } from "./store-contracts.js";
|
|
5
|
+
/** PG translation of the image_bake / image_bake_event / image_bake_lease DDL in tidb-pool.ts SCHEMA_STATEMENTS
|
|
6
|
+
* (JSON→JSONB, TINYINT→SMALLINT, DATETIME(3)→TIMESTAMPTZ(3), inline UNIQUE/KEY→named CONSTRAINT + CREATE INDEX).
|
|
7
|
+
* TINYINT(1) 归一(clay 批 2026-07-26):布尔列的 PG 映射统一 SMALLINT 0/1(此前本家族用 BOOLEAN)——
|
|
8
|
+
* 两方言驱动读回同为 number ⇒ 不再存在「忘了配的适配器」这个病族;写入参与 SQL 字面量一律 0/1,
|
|
9
|
+
* 读侧 `!!`/`Boolean()` 保持,store 出口 JS 类型逐字节不变(真双库套件的严格值断言为证)。
|
|
10
|
+
* The uq_line UNIQUE is given an explicit name so a 23505 can be attributed to it via err.constraint. */
|
|
5
11
|
export declare const PG_IMAGE_BAKE_SCHEMA: string[];
|
|
12
|
+
/** Idempotent self-contained PG schema apply (for the integration test; central aggregation is done separately). */
|
|
6
13
|
export declare function ensurePgImageBakeSchema(pool: PgPool | PoolClient, poolName?: string): Promise<void>;
|
|
14
|
+
/** Dual-dialect BAKE store. See the file header for the dialect-delta ledger. */
|
|
7
15
|
export declare class SqlImageBake {
|
|
8
16
|
protected readonly db: SqlDriver;
|
|
17
|
+
/** The builder pool a lease serializes on (one docker daemon ⇒ one pool today). */
|
|
9
18
|
protected readonly poolName: string;
|
|
10
|
-
constructor(db: SqlDriver,
|
|
19
|
+
constructor(db: SqlDriver,
|
|
20
|
+
/** The builder pool a lease serializes on (one docker daemon ⇒ one pool today). */
|
|
21
|
+
poolName?: string);
|
|
22
|
+
/** Pick the dialect's SQL text. Both statements stay written out at the call site ON PURPOSE. */
|
|
11
23
|
private q;
|
|
24
|
+
/** The 12 bound values shared by both admission INSERTs (column order === INSERT_BAKE_COLS). */
|
|
12
25
|
private insertParams;
|
|
26
|
+
/**
|
|
27
|
+
* Create a bake, queued. Durable submit-idempotency mirrors createRun's CAS: `idem_key` is UNIQUE, so a
|
|
28
|
+
* re-submit with the same key races to INSERT and the loser catches the dup-key, then re-reads + returns the
|
|
29
|
+
* EXISTING row (the live bake) instead of a second job. A null `idemKey` always inserts (no dedupe requested).
|
|
30
|
+
* Returns `{ created, bake }` so the handler can answer 202 either way (idempotent dup ⇒ created:false).
|
|
31
|
+
*/
|
|
13
32
|
createBake(input: CreateBakeInput): Promise<{
|
|
14
33
|
created: boolean;
|
|
15
34
|
bake: BakeRecord;
|
|
16
35
|
}>;
|
|
36
|
+
/**
|
|
37
|
+
* M4 (§P2.1/§P2.7 — the 409-busy MUST): create a queued bake ATOMICALLY only when no other non-dryRun bake is
|
|
38
|
+
* in flight, so two concurrent keyless POSTs can NEVER both queue (the check-then-act in the submit handler —
|
|
39
|
+
* findActiveAny() then createBake() as two awaited round-trips — interleaves: both see null-busy, both insert).
|
|
40
|
+
* `uq_idem` only dedupes non-null idem_keys (a keyless submit is NULL = distinct), and the build lease is taken
|
|
41
|
+
* at CLAIM not submit, so neither backstops this — the admission itself must be serialized.
|
|
42
|
+
*
|
|
43
|
+
* A bare conditional INSERT (`INSERT … SELECT … WHERE NOT EXISTS(...)`) is NOT sufficient ON ITS OWN: under
|
|
44
|
+
* TiDB's default REPEATABLE READ (and PG's READ COMMITTED) two concurrent autocommit conditional inserts each
|
|
45
|
+
* evaluate NOT EXISTS against a snapshot that excludes the other's still-uncommitted row (PG takes no
|
|
46
|
+
* predicate/gap lock), so BOTH can pass and double-admit. The only backstop today is the build lease taken at
|
|
47
|
+
* CLAIM, so a double-admit degrades the 409-busy/202-attach contract rather than double-building — but the
|
|
48
|
+
* contract is the point.
|
|
49
|
+
*
|
|
50
|
+
* Fix: serialize the busy-check+insert on the per-pool admission sentinel (`image_bake_admit`) with
|
|
51
|
+
* `SELECT … FOR UPDATE` inside one transaction. The second admitter blocks on the sentinel row lock until the
|
|
52
|
+
* first commits, then sees the committed in-flight bake and inserts 0 → `created:false`, and the caller
|
|
53
|
+
* re-reads the active bake (findActiveByArgv for an idempotent attach, else findActiveAny) for the
|
|
54
|
+
* 202-attach / 409 body. A dryRun bypasses this path entirely (never takes the lease — parallel-safe) and uses
|
|
55
|
+
* plain createBake.
|
|
56
|
+
*
|
|
57
|
+
* 🔴 DIALECT DIVERGENCE (deliberate, both preserved verbatim — the real-DB suites are the oracle):
|
|
58
|
+
* - TiDB: `BEGIN PESSIMISTIC` + a separate `SELECT 1 … FOR UPDATE` busy-check, then a plain INSERT. The
|
|
59
|
+
* pessimistic txn is REQUIRED: TiDB's snapshot (REPEATABLE READ) txn would evaluate a NOT EXISTS against
|
|
60
|
+
* the txn-start snapshot and miss a rival's just-committed row EVEN under the sentinel lock.
|
|
61
|
+
* - PG: plain `BEGIN` + one `INSERT … SELECT … WHERE NOT EXISTS(...)`. READ COMMITTED takes a FRESH
|
|
62
|
+
* statement snapshot, so the NOT EXISTS run after the sentinel lock is granted already sees the committed
|
|
63
|
+
* rival — the conditional insert is atomic enough once serialized.
|
|
64
|
+
*/
|
|
17
65
|
createBakeIfIdle(input: CreateBakeInput): Promise<{
|
|
18
66
|
created: boolean;
|
|
19
67
|
bake: BakeRecord | null;
|
|
20
68
|
}>;
|
|
21
69
|
getBake(bakeId: string): Promise<BakeRecord | null>;
|
|
22
70
|
getBakeByIdem(idemKey: string): Promise<BakeRecord | null>;
|
|
71
|
+
/**
|
|
72
|
+
* Find an in-flight (queued/running) bake with the identical normalized argv — so a re-submit WITHOUT an
|
|
73
|
+
* idempotency key still returns the live bake rather than starting a duplicate build (P2.1 "an in-flight
|
|
74
|
+
* identical-input bake returns the EXISTING row"). argv is the canonical normalized vector, so a JSON
|
|
75
|
+
* equality is the dedupe key. Newest first (the live one).
|
|
76
|
+
*/
|
|
23
77
|
findActiveByArgv(argv: string[]): Promise<BakeRecord | null>;
|
|
78
|
+
/**
|
|
79
|
+
* The OLDEST in-flight (queued/running) NON-dry-run bake — the single-flight at-submit guard (P2.7). Concurrency
|
|
80
|
+
* is 1 (one docker daemon), so a new submit while ANY non-dry-run bake is in flight is `409 busy` UNLESS it is
|
|
81
|
+
* the identical-argv one (then the caller attaches to it, idempotent). dryRun bakes never take the lease, so they
|
|
82
|
+
* are excluded here. Oldest first = the one that holds/will-hold the lease (the build the UI should attach to).
|
|
83
|
+
*/
|
|
24
84
|
findActiveAny(): Promise<BakeRecord | null>;
|
|
85
|
+
/**
|
|
86
|
+
* The OLDEST queued bake id — the runner's long-poll claim target (P2.12). dryRun bakes never take the lease, so
|
|
87
|
+
* they are still discoverable here (the runner resolves them with no docker), but ordering oldest-first gives a
|
|
88
|
+
* stable FIFO. Returns null when the queue is empty. The actual claim is a CAS (`claimBake`), so two runners
|
|
89
|
+
* racing this both see the id but only one wins the conditional UPDATE — no double-build.
|
|
90
|
+
*/
|
|
25
91
|
findNextQueuedId(): Promise<string | null>;
|
|
92
|
+
/**
|
|
93
|
+
* Single-flight CLAIM (P2.7) — the runner leases the next queued bake. Two CASes in one transaction:
|
|
94
|
+
* 1. flip the bake row `queued → running` (conditional UPDATE `WHERE status='queued'`, 1 row affected wins);
|
|
95
|
+
* 2. take the single-row `image_bake_lease` for the pool (INSERT, or steal an EXPIRED lease via CAS).
|
|
96
|
+
* Only the runner that wins BOTH gets the bake; a loser (someone else already claimed, or the lease is held by
|
|
97
|
+
* a live build) gets null. Mints + stores the per-bake `ingest_secret` (so a stale/rogue runner can't inject
|
|
98
|
+
* frames into another bake) and the initial `lease_until`. Returns the claimed row (with the secret) or null.
|
|
99
|
+
*/
|
|
26
100
|
claimBake(bakeId: string, runnerId: string, leaseMs: number): Promise<BakeRecord | null>;
|
|
101
|
+
/**
|
|
102
|
+
* Append one event. image-api is the SOLE ++seq writer: `seq = maxSeq(bakeId)+1`. The `(bakeId,line_ord)`
|
|
103
|
+
* UNIQUE is the at-least-once ingest dedupe (P2.10) — a runner re-sending a line it already acked races to
|
|
104
|
+
* INSERT and the loser is a NO-OP (the frame is already stored at its seq). Returns the seq written, or null
|
|
105
|
+
* when the line was a duplicate (already stored). A null `lineOrd` (image-api-synthesized frame:
|
|
106
|
+
* register/done/heartbeat-derived) never collides on the line-unique (NULLs are distinct in a UNIQUE index).
|
|
107
|
+
*
|
|
108
|
+
* seq allocation + the INSERT are NOT one atomic statement, so two concurrent appends could pick the same
|
|
109
|
+
* seq+1; the (bakeId,seq) PK then rejects the loser with a dup-key. M2: that PK collision is DISTINGUISHED from
|
|
110
|
+
* a benign line re-send (by the dup-key attribution channel) and RETRIED in a bounded loop with a fresh
|
|
111
|
+
* maxSeq+1 — never silently swallowed (which would drop a frame, incl. the terminal `done`, at a clean HTTP
|
|
112
|
+
* 200). A line dup is the at-least-once re-send no-op (returns null). The runner also serializes its per-bake
|
|
113
|
+
* pump (runner.ts), so the same-seq race is the rare burst case, not the norm.
|
|
114
|
+
*/
|
|
27
115
|
appendEvent(bakeId: string, kind: string, data: unknown, opts?: {
|
|
28
116
|
lineOrd?: number | null;
|
|
29
117
|
level?: string | null;
|
|
30
118
|
}): Promise<number | null>;
|
|
31
119
|
private lineOrdExists;
|
|
120
|
+
/** Highest event seq for a bake (0 if none) — the ++seq allocator + the resume cursor head. */
|
|
32
121
|
maxSeq(bakeId: string): Promise<number>;
|
|
122
|
+
/** Earliest retained event seq (0 if none) → the SSE 416 boundary (a resume below this was evicted, P2.9). */
|
|
33
123
|
retainedFrom(bakeId: string): Promise<number>;
|
|
124
|
+
/** Events with seq strictly greater than `afterSeq` (0 for the whole stream), ascending. */
|
|
34
125
|
getEvents(bakeId: string, afterSeq: number): Promise<BakeEvent[]>;
|
|
126
|
+
/** Coarse 4-value lifecycle transition (the column the SSE reader polls for terminality). */
|
|
35
127
|
setStatus(bakeId: string, status: BakeStatus): Promise<void>;
|
|
128
|
+
/** Denormalize build.sh's 8-value `state` for the UI progress bar (NEVER drives terminality, P2.3). */
|
|
36
129
|
setState(bakeId: string, state: BakeState): Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* Terminal write (P2.10 step 4): flip the coarse `status` + persist all the terminal facts (digest/repo/ref/
|
|
132
|
+
* indexId/exitCode/error/errorCode/state/manifestSha/tag) the `done` frame and the poll row carry, AND release
|
|
133
|
+
* the pool lease in one transaction (a separate-statement release that failed would wedge the build host).
|
|
134
|
+
* Idempotent terminal write: only flips a NON-terminal row (`WHERE status IN ('queued','running')`) so a
|
|
135
|
+
* re-delivered terminal can't clobber the first outcome. Returns the UPDATE's affected count — 1 = THIS call won
|
|
136
|
+
* the queued/running→terminal transition; 0 = a terminal already exists (M3: the caller then SKIPS appending a
|
|
137
|
+
* contradictory second terminal `done` event, so at most one terminal `done` per bake matches the coarse row).
|
|
138
|
+
* 🔴 H3: null `ingest_secret` on the terminal flip so a terminal row can NEVER re-authenticate an ingest
|
|
139
|
+
* (a lagging/duplicate runner that still holds the secret can't inject frames into a settled bake).
|
|
140
|
+
*/
|
|
37
141
|
setTerminal(bakeId: string, t: BakeTerminal): Promise<number>;
|
|
142
|
+
/** TiDB stores the terminal facts VERBATIM (no protocol-byte class to defend against). */
|
|
38
143
|
private terminalParamsTidb;
|
|
144
|
+
/** PG-ONLY protocol-byte handling. R20/R21:身份位(digest/manifestSha/repo/ref)带不可存字节=帧无效——
|
|
145
|
+
* **单一谓词**统管状态折叠与全部身份绑位(R21:只查两位会放 dirty repo/ref 的假 COMPLETE 过——终态单赢,
|
|
146
|
+
* 假成功不可逆)。事务必须提交(lease 释放/secret 清理=单飞池活性底线)。codex R13/R17-H2:NUL 错误文案
|
|
147
|
+
* 或脏 tag 若让终态事务回滚,lease 保持 = bake 永占单飞池,故文本位走 sanitize 而非拒绝。 */
|
|
39
148
|
private terminalParamsPg;
|
|
149
|
+
/** Set the index_id once auto-register succeeds (P2.10 — kept distinct from the terminal flip so the `done`
|
|
150
|
+
* frame can carry indexId even when the terminal write retries). codex R24:non-terminal 门——并发 done
|
|
151
|
+
* 竞态下(本请求悬在 registerBuilding 时另一 done 已赢 setTerminal)绝不把 indexId 挂回终态行(R23 折叠
|
|
152
|
+
* 的 FAILED/null 身份行会被复写成「null 身份却带 index 绑定」的矛盾形)。返回是否真绑定。 */
|
|
40
153
|
setIndexId(bakeId: string, indexId: string): Promise<boolean>;
|
|
154
|
+
/** Heartbeat the lease forward (P2.7): the runner pushes `lease_until` (+ the lease row's `expires_at`) while
|
|
155
|
+
* its build child runs, so the reaper doesn't steal a LIVE build's lease. CAS on the runner owning the row +
|
|
156
|
+
* the bake still running. Returns whether it refreshed (false ⇒ lease lost/stolen — the runner should abort). */
|
|
41
157
|
heartbeatLease(bakeId: string, runnerId: string, leaseMs: number): Promise<boolean>;
|
|
158
|
+
/** Request cooperative cancel (P2.11) — durable + cross-replica; the runner's heartbeat tick polls it and kills
|
|
159
|
+
* the build.sh process group. Only flags a non-terminal row (terminal → 0 affected = no-op). Returns whether a
|
|
160
|
+
* live bake was flagged (false ⇒ already terminal → the caller answers a no-op 202). */
|
|
42
161
|
requestCancel(bakeId: string): Promise<boolean>;
|
|
162
|
+
/** Whether a cancel was requested (polled by the runner). */
|
|
43
163
|
isCancelRequested(bakeId: string): Promise<boolean>;
|
|
164
|
+
/**
|
|
165
|
+
* Reaper twin of TiDBRunStore.reapStale (P2.7/§P2.6): fail any `running` bake whose lease is STALE (a crashed
|
|
166
|
+
* runner stopped heartbeating), append a synthetic terminal `done{failed}` so SSE readers SETTLE (never hang),
|
|
167
|
+
* and force-release the pool lease. `olderThanMs` must exceed >2 lease-heartbeat intervals (≈3× the heartbeat)
|
|
168
|
+
* so a healthy slow build is not wrongly reaped. Returns the count reaped.
|
|
169
|
+
*
|
|
170
|
+
* M3: flip the row terminal FIRST (the CAS on `status='running'`), and append the synthetic `done{failed}` ONLY
|
|
171
|
+
* when the flip WON (1 row affected). A victim that recovered + COMPLETEd between the SELECT and the flip
|
|
172
|
+
* no-ops the CAS, so we leak NO contradictory `done{failed}` into its settled SSE log. A reader that polled the
|
|
173
|
+
* still-running row in the tiny pre-flip gap simply re-polls (streamSseLog re-fetches) and settles on the
|
|
174
|
+
* eventual terminal — the winner's `done` — rather than a spurious one.
|
|
175
|
+
*/
|
|
44
176
|
reapStaleBakes(olderThanMs: number): Promise<number>;
|
|
177
|
+
/** Run statements atomically; rolls back on failure (mirrors TiDBRunStore.tx). */
|
|
45
178
|
private tx;
|
|
46
179
|
}
|
|
180
|
+
/** MySQL-protocol (TiDB) binding — historical class name + ctor shape preserved. */
|
|
47
181
|
export declare class TiDBImageBake extends SqlImageBake {
|
|
48
182
|
constructor(pool: MySqlPool, poolName?: string);
|
|
49
183
|
}
|
|
184
|
+
/** PostgreSQL binding — historical class name + ctor shape preserved. */
|
|
50
185
|
export declare class PgImageBake extends SqlImageBake {
|
|
51
186
|
constructor(pool: PgPool, poolName?: string);
|
|
52
187
|
}
|