@sema-agent/server 7.134.0 → 7.135.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/MIGRATION.md +134 -0
- package/USAGE.md +98 -30
- package/dist/adoption/plan.d.ts +1 -1
- package/dist/approval-ask-audit-store.d.ts +24 -24
- package/dist/approval-ask-machine.d.ts +2 -2
- package/dist/approval-card.d.ts +62 -150
- package/dist/approval-card.js +33 -51
- package/dist/approval-content-kind.d.ts +22 -5
- package/dist/approval-content-kind.js +8 -1
- package/dist/approval-deny-reasons.d.ts +1 -1
- package/dist/approval-gate-currency.d.ts +22 -3
- package/dist/approval-gate-currency.js +44 -18
- package/dist/approval-hmac.d.ts +7 -7
- package/dist/approval-policy-settlement.d.ts +2 -2
- package/dist/approval-reconciler.d.ts +3 -3
- package/dist/approval.d.ts +8 -8
- package/dist/approval.js +4 -2
- package/dist/auth-bridge.d.ts +1 -1
- package/dist/auto-mode-face.d.ts +4 -4
- package/dist/background-session-reap.d.ts +2 -2
- package/dist/bake-runner/main.d.ts +2 -2
- package/dist/bake-runner/runner.d.ts +4 -4
- package/dist/bench/s1/live-deps.d.ts +1 -1
- package/dist/bench/s1/run-firm.d.ts +1 -1
- package/dist/boot/coordinators.d.ts +2 -2
- package/dist/boot/coordinators.js +2 -2
- package/dist/boot/deferred-sandbox-path-env.d.ts +0 -6
- package/dist/boot/deferred-sandbox-path-env.js +0 -5
- package/dist/boot/engine-lease.d.ts +5 -5
- package/dist/boot/execution-env.d.ts +16 -15
- package/dist/boot/execution-env.js +19 -21
- package/dist/boot/fatal-exit.d.ts +2 -2
- package/dist/boot/late-binds.d.ts +1 -1
- package/dist/boot/leader.d.ts +1 -1
- package/dist/boot/memory-boundary.d.ts +2 -2
- package/dist/boot/memory-consolidation.d.ts +15 -15
- package/dist/boot/parked-revive-gate.d.ts +3 -3
- package/dist/boot/parked-revive-gate.js +3 -2
- package/dist/boot/reapers.d.ts +4 -4
- package/dist/boot/resolve-spec.d.ts +1 -1
- package/dist/boot/resolve-spec.js +28 -24
- package/dist/boot/runner-deps.d.ts +11 -11
- package/dist/boot/runner-deps.js +3 -2
- package/dist/boot/session-faces.d.ts +3 -3
- package/dist/boot/session-faces.js +11 -30
- package/dist/boot/shutdown.d.ts +5 -5
- package/dist/boot/side-query-lane.d.ts +2 -2
- package/dist/boot/stage-05-execution-env.js +4 -4
- package/dist/boot/stage-06-runners.js +0 -2
- package/dist/boot/stores.js +2 -1
- package/dist/boot/web-admin.d.ts +17 -17
- package/dist/boot/web-admin.js +5 -10
- package/dist/boot/workflow-orchestration.js +2 -9
- package/dist/brain.d.ts +11 -11
- package/dist/budget.d.ts +4 -4
- package/dist/capabilities/approvals-push.d.ts +4 -4
- package/dist/capabilities/builtin-tools.d.ts +5 -5
- package/dist/capabilities/center-plugins.d.ts +5 -5
- package/dist/capabilities/center-plugins.js +1 -1
- package/dist/capabilities/center-prompts.d.ts +1 -1
- package/dist/capabilities/center-wiring.d.ts +1 -1
- package/dist/capabilities/composite-members.d.ts +1 -1
- package/dist/capabilities/execution-lane.d.ts +5 -5
- package/dist/capabilities/execution-lane.js +2 -2
- package/dist/capabilities/hands-lane.d.ts +5 -5
- package/dist/capabilities/mcp-probe.d.ts +10 -7
- package/dist/capabilities/sandbox-file-send.d.ts +1 -18
- package/dist/capabilities/sandbox-file-send.js +0 -7
- package/dist/capabilities/scenarios.d.ts +28 -10
- package/dist/capabilities/scenarios.js +15 -5
- package/dist/capabilities/send-user-file-tool.d.ts +1 -1
- package/dist/capabilities/skills.d.ts +31 -12
- package/dist/capabilities/skills.js +23 -17
- package/dist/capabilities/tool-defer.d.ts +1 -1
- package/dist/capability-facts.d.ts +26 -25
- package/dist/capability-facts.js +14 -16
- package/dist/center-config-tier.d.ts +1 -1
- package/dist/center-credential.d.ts +4 -4
- package/dist/checkpoint-identity.d.ts +5 -0
- package/dist/checkpoint-identity.js +14 -0
- package/dist/config-catalog.d.ts +12 -12
- package/dist/config-invariants.d.ts +4 -4
- package/dist/config-invariants.js +3 -2
- package/dist/config-lkg.d.ts +1 -1
- package/dist/config-provider.d.ts +13 -13
- package/dist/config-provider.js +2 -1
- package/dist/config-types.d.ts +83 -83
- package/dist/config.d.ts +26 -24
- package/dist/config.js +12 -10
- package/dist/cross-session-settings.d.ts +1 -1
- package/dist/delegated-session-owner.d.ts +16 -13
- package/dist/delegated-session-owner.js +9 -10
- package/dist/deployment-governance.d.ts +16 -16
- package/dist/deployment-shape.d.ts +127 -0
- package/dist/deployment-shape.js +72 -0
- package/dist/device-store.d.ts +1 -1
- package/dist/device-ws-hub.d.ts +1 -1
- package/dist/egress-redirect.d.ts +1 -1
- package/dist/entry-mode-clamp-notice.d.ts +2 -2
- package/dist/env-facts.d.ts +10 -9
- package/dist/env-facts.js +1 -1
- package/dist/env-name-allowlist-knobs.d.ts +5 -5
- package/dist/exec-bounds.d.ts +2 -2
- package/dist/execution-lane-caps.d.ts +31 -43
- package/dist/execution-lane-caps.js +0 -13
- package/dist/file-history-capture.d.ts +9 -9
- package/dist/file-history-disclosure.d.ts +23 -11
- package/dist/file-history-disclosure.js +7 -12
- package/dist/fleet/drain-entry.d.ts +2 -2
- package/dist/fleet/fleet-bus.d.ts +22 -14
- package/dist/fleet/fleet-bus.js +5 -5
- package/dist/fleet/fleet-reconciler.d.ts +9 -9
- package/dist/fleet/subagent-tail-bus.d.ts +4 -4
- package/dist/fleet-client.d.ts +13 -13
- package/dist/fleet-lease.d.ts +16 -16
- package/dist/governance-http-status.d.ts +2 -2
- package/dist/hooks/hook-llm.d.ts +7 -7
- package/dist/hooks/hook-runner.d.ts +57 -30
- package/dist/hooks/hook-runner.js +36 -18
- package/dist/host-decision.d.ts +5 -5
- package/dist/host-lsp-manager.d.ts +5 -5
- package/dist/hosted-posture.d.ts +23 -13
- package/dist/hosted-posture.js +4 -9
- package/dist/http/admission.d.ts +2 -2
- package/dist/http/admission.js +20 -5
- package/dist/http/approval-sweeps.d.ts +1 -1
- package/dist/http/approval-sweeps.js +2 -1
- package/dist/http/checkpoint-ctx.d.ts +39 -13
- package/dist/http/checkpoint-ctx.js +74 -35
- package/dist/http/dispatch.d.ts +3 -3
- package/dist/http/durable-run-leg.js +4 -3
- package/dist/http/idempotency.d.ts +2 -2
- package/dist/http/mcp-dial-deadline.d.ts +7 -5
- package/dist/http/memory-compliance-failure-reply.d.ts +4 -4
- package/dist/http/owner-access.d.ts +4 -6
- package/dist/http/owner-access.js +1 -1
- package/dist/http/principal-gate.d.ts +7 -7
- package/dist/http/principal-gate.js +3 -2
- package/dist/http/readiness.d.ts +1 -1
- package/dist/http/request-guards.d.ts +4 -4
- package/dist/http/request-guards.js +2 -1
- package/dist/http/resume-ctx-read.d.ts +7 -7
- package/dist/http/resume-ctx-read.js +1 -1
- package/dist/http/resume-legs.d.ts +3 -3
- package/dist/http/resume-legs.js +11 -8
- package/dist/http/route-ctx.d.ts +29 -29
- package/dist/http/route-table.d.ts +9 -9
- package/dist/http/routes/agents-roster.d.ts +1 -1
- package/dist/http/routes/approvals-assistant.d.ts +5 -5
- package/dist/http/routes/approvals-assistant.js +55 -15
- package/dist/http/routes/background.d.ts +3 -3
- package/dist/http/routes/background.js +2 -2
- package/dist/http/routes/capabilities.d.ts +1 -1
- package/dist/http/routes/capabilities.js +16 -8
- package/dist/http/routes/config-catalog.d.ts +1 -1
- package/dist/http/routes/devices.d.ts +1 -1
- package/dist/http/routes/diagnostics.d.ts +3 -3
- package/dist/http/routes/fleet.d.ts +1 -1
- package/dist/http/routes/fleet.js +2 -1
- package/dist/http/routes/mcp-reconnect.d.ts +4 -4
- package/dist/http/routes/mcp-reconnect.js +3 -3
- package/dist/http/routes/memory-consolidation.d.ts +1 -1
- package/dist/http/routes/notify-wake.d.ts +1 -1
- package/dist/http/routes/notify-wake.js +2 -2
- package/dist/http/routes/rules.d.ts +1 -1
- package/dist/http/routes/runs.js +22 -10
- package/dist/http/routes/session-sync.d.ts +1 -1
- package/dist/http/routes/session-sync.js +73 -44
- package/dist/http/routes/sessions-list.js +1 -1
- package/dist/http/routes/sessions.js +30 -44
- package/dist/http/routes/tasks.d.ts +1 -1
- package/dist/http/routes/trace-usage.d.ts +1 -1
- package/dist/http/routes/workflows.d.ts +3 -0
- package/dist/http/routes/workflows.js +31 -28
- package/dist/http/send.d.ts +5 -5
- package/dist/http/server.d.ts +34 -34
- package/dist/http/session-inherit-env.d.ts +3 -3
- package/dist/http/sse-lifecycle.d.ts +1 -1
- package/dist/http/sse-log.d.ts +2 -2
- package/dist/http/submit-ctx.js +1 -1
- package/dist/http/sync-submit-body.d.ts +1 -1
- package/dist/http/verify-rounds.d.ts +1 -1
- package/dist/http/wire-types.d.ts +28 -21
- package/dist/instruction-source-notice.d.ts +2 -2
- package/dist/key-resolver.d.ts +3 -3
- package/dist/lane-home-probe.d.ts +1 -1
- package/dist/leader/diffout.d.ts +1 -1
- package/dist/leader/diffup.d.ts +2 -2
- package/dist/leader/endpoint.d.ts +1 -1
- package/dist/leader/fanout.d.ts +1 -1
- package/dist/leader/leader.d.ts +4 -4
- package/dist/leader/merge.d.ts +3 -3
- package/dist/leader/repair-wire.d.ts +1 -1
- package/dist/leader/wire.d.ts +6 -6
- package/dist/list-entry-display.d.ts +1 -1
- package/dist/lsp-evict.d.ts +1 -1
- package/dist/mcp-assertion-header.d.ts +1 -1
- package/dist/memory-layer-legacy-lock.d.ts +1 -1
- package/dist/memory-operator-faces.d.ts +1 -1
- package/dist/memory-posture.js +4 -2
- package/dist/memory-project-layer.d.ts +1 -1
- package/dist/memory-scope.d.ts +19 -19
- package/dist/memory-store-refusal.d.ts +4 -4
- package/dist/model-entry-headers.d.ts +2 -2
- package/dist/model-entry-refusal.d.ts +17 -17
- package/dist/model-provider.d.ts +10 -10
- package/dist/model-reach-scope.d.ts +1 -1
- package/dist/model-route-endpoint.d.ts +6 -6
- package/dist/model-route-url.d.ts +5 -5
- package/dist/model-select.d.ts +15 -6
- package/dist/model-select.js +5 -0
- package/dist/model-unreachable-notice.d.ts +3 -3
- package/dist/namespaced-rule-name.d.ts +15 -5
- package/dist/namespaced-rule-name.js +3 -2
- package/dist/observability/corrupt-read-seat.d.ts +9 -9
- package/dist/observability/cost-taxonomy.d.ts +1 -1
- package/dist/observability/err-text.d.ts +1 -1
- package/dist/observability/fail-open.d.ts +12 -8
- package/dist/observability/fail-open.js +12 -8
- package/dist/observability/metrics.d.ts +3 -3
- package/dist/observability/run-terminal.d.ts +36 -36
- package/dist/observability/secret-env-scrub.d.ts +3 -3
- package/dist/observability/tool-trace.d.ts +1 -1
- package/dist/operator-ask.d.ts +4 -4
- package/dist/orchestration/workflow-agent-session-index.d.ts +3 -3
- package/dist/orchestration/workflow-completion-inbox.d.ts +20 -5
- package/dist/orchestration/workflow-completion-inbox.js +29 -7
- package/dist/orchestration/workflow-notify-journal.d.ts +43 -19
- package/dist/orchestration/workflow-notify-journal.js +17 -0
- package/dist/outbound-dispatcher.d.ts +4 -4
- package/dist/parent-watch.d.ts +4 -4
- package/dist/parked-decide.d.ts +16 -15
- package/dist/parked-decide.js +5 -4
- package/dist/parked-revive-surface.d.ts +7 -7
- package/dist/parked-revive-surface.js +2 -3
- package/dist/peer-directory.d.ts +3 -3
- package/dist/peer-directory.js +1 -1
- package/dist/permission-rule-list.d.ts +10 -1
- package/dist/permission-rule-list.js +7 -5
- package/dist/permission-rule-vocab.d.ts +2 -2
- package/dist/plugins/adoption-log-sql.d.ts +1 -1
- package/dist/plugins/approval-ask-store-file.d.ts +8 -1
- package/dist/plugins/approval-ask-store-file.js +6 -3
- package/dist/plugins/approval-ask-store-memory.d.ts +11 -7
- package/dist/plugins/approval-ask-store-memory.js +11 -7
- package/dist/plugins/approval-ask-store-sql.d.ts +34 -15
- package/dist/plugins/approval-ask-store-sql.js +18 -5
- package/dist/plugins/approval-exemption-store.d.ts +3 -3
- package/dist/plugins/approval-nonce-store.d.ts +3 -3
- package/dist/plugins/background-agent-store-sql.d.ts +1 -1
- package/dist/plugins/background-shell-support.d.ts +2 -2
- package/dist/plugins/blob-backend.d.ts +1 -1
- package/dist/plugins/caching-session-store.d.ts +23 -32
- package/dist/plugins/caching-session-store.js +5 -17
- package/dist/plugins/checkpoint-index-columns.d.ts +81 -0
- package/dist/plugins/checkpoint-index-columns.js +62 -0
- package/dist/plugins/checkpoint-store-sql.d.ts +44 -66
- package/dist/plugins/checkpoint-store-sql.js +55 -102
- package/dist/plugins/device-store-sql.d.ts +7 -6
- package/dist/plugins/e2b-orphan-reclaim.d.ts +1 -1
- package/dist/plugins/ensure-schema-lock-policy.d.ts +1 -1
- package/dist/plugins/file-history-store-sql.d.ts +9 -7
- package/dist/plugins/file-history-store-sql.js +27 -15
- package/dist/plugins/file-run-store.d.ts +8 -8
- package/dist/plugins/fork-routing-session-store.d.ts +2 -2
- package/dist/plugins/fork-routing-session-store.js +1 -1
- package/dist/plugins/host-platform.d.ts +10 -10
- package/dist/plugins/image-bake-store-sql.d.ts +1 -1
- package/dist/plugins/image-index-sql.d.ts +1 -1
- package/dist/plugins/leader-run-store-sql.d.ts +1 -1
- package/dist/plugins/local-checkpoint-store.d.ts +10 -10
- package/dist/plugins/local-checkpoint-store.js +3 -4
- package/dist/plugins/local-session-store.d.ts +34 -38
- package/dist/plugins/local-session-store.js +20 -39
- package/dist/plugins/local-session-window.d.ts +1 -1
- package/dist/plugins/mailbox-store-sql.d.ts +2 -2
- package/dist/plugins/memory-engine-pg.d.ts +1 -1
- package/dist/plugins/memory-run-store.d.ts +4 -4
- package/dist/plugins/memory-sync-store-pg.d.ts +3 -3
- package/dist/plugins/one-time-migrations.d.ts +66 -40
- package/dist/plugins/one-time-migrations.js +115 -34
- package/dist/plugins/outcome-ledger-sql.d.ts +1 -1
- package/dist/plugins/park-commit-watch.d.ts +3 -3
- package/dist/plugins/permission-rule-store-file.d.ts +5 -5
- package/dist/plugins/permission-rule-store-file.js +12 -19
- package/dist/plugins/permission-rule-store-sql.d.ts +38 -4
- package/dist/plugins/permission-rule-store-sql.js +67 -24
- package/dist/plugins/pg-cost-quota.d.ts +1 -1
- package/dist/plugins/pg-pool.d.ts +2 -2
- package/dist/plugins/pg-pool.js +5 -2
- package/dist/plugins/pg-rate-limiter.d.ts +1 -1
- package/dist/plugins/pg-session-storage.d.ts +8 -20
- package/dist/plugins/pg-session-storage.js +14 -27
- package/dist/plugins/remote-env-adb.d.ts +10 -10
- package/dist/plugins/remote-env-device.d.ts +10 -9
- package/dist/plugins/remote-env-device.js +6 -2
- package/dist/plugins/remote-env-e2b.d.ts +3 -3
- package/dist/plugins/remote-env-host.d.ts +16 -16
- package/dist/plugins/remote-env-k8s.d.ts +8 -8
- package/dist/plugins/remote-env-local-docker.d.ts +2 -2
- package/dist/plugins/remote-env-ssh.d.ts +4 -4
- package/dist/plugins/remote-scratchpad.d.ts +2 -3
- package/dist/plugins/remote-scratchpad.js +0 -4
- package/dist/plugins/remote-shell.d.ts +6 -6
- package/dist/plugins/retention-lane-store-sql.d.ts +4 -4
- package/dist/plugins/retention-store-sql.d.ts +4 -4
- package/dist/plugins/roster-store-sql.d.ts +1 -1
- package/dist/plugins/run-store-sql.d.ts +8 -8
- package/dist/plugins/schema-consistency.d.ts +2 -2
- package/dist/plugins/schema-ensure-legs.d.ts +3 -3
- package/dist/plugins/schema-indexes.d.ts +1 -1
- package/dist/plugins/schema-live-columns.d.ts +1 -1
- package/dist/plugins/session-event-payload.d.ts +4 -4
- package/dist/plugins/session-fork.d.ts +34 -0
- package/dist/plugins/session-fork.js +29 -0
- package/dist/plugins/session-ownership.js +1 -1
- package/dist/plugins/session-placement.d.ts +1 -1
- package/dist/plugins/session-policy-store-sql.d.ts +12 -12
- package/dist/plugins/session-store.d.ts +2 -2
- package/dist/plugins/session-store.js +2 -2
- package/dist/plugins/shared-memory-store-sql.d.ts +2 -2
- package/dist/plugins/sql-driver.d.ts +8 -8
- package/dist/plugins/sql-errors.d.ts +1 -1
- package/dist/plugins/sql-json-column.d.ts +21 -21
- package/dist/plugins/sql-row-helpers.d.ts +2 -2
- package/dist/plugins/store-backend.d.ts +17 -16
- package/dist/plugins/store-backend.js +3 -3
- package/dist/plugins/store-contracts.d.ts +21 -21
- package/dist/plugins/task-attachment-store.d.ts +2 -2
- package/dist/plugins/task-list-store-sql.d.ts +1 -1
- package/dist/plugins/tidb-pool.d.ts +2 -2
- package/dist/plugins/tidb-pool.js +9 -2
- package/dist/plugins/tidb-session-store.d.ts +16 -26
- package/dist/plugins/tidb-session-store.js +15 -27
- package/dist/plugins/tool-result-store-sql.d.ts +1 -1
- package/dist/plugins/usage-window-store-sql.d.ts +3 -3
- package/dist/plugins/user-input-ledger-file.d.ts +1 -1
- package/dist/plugins/user-input-ledger-sql.d.ts +3 -3
- package/dist/plugins/web-search.d.ts +19 -5
- package/dist/plugins/web-search.js +19 -4
- package/dist/{orchestration/workflow-journal-entry.d.ts → plugins/workflow-journal-payload.d.ts} +23 -32
- package/dist/plugins/workflow-journal-payload.js +32 -0
- package/dist/plugins/workflow-journal-store-sql.d.ts +28 -14
- package/dist/plugins/workflow-journal-store-sql.js +34 -15
- package/dist/plugins/workflow-run-store-sql.d.ts +4 -4
- package/dist/posture-source.d.ts +11 -11
- package/dist/principal-jwt.d.ts +6 -6
- package/dist/project-identity.d.ts +3 -3
- package/dist/project-memory.d.ts +4 -4
- package/dist/read-face-posture.d.ts +7 -7
- package/dist/request-key-closure.d.ts +1 -1
- package/dist/request-key-closure.js +1 -1
- package/dist/request-value-closure.d.ts +15 -8
- package/dist/request-value-closure.js +2 -0
- package/dist/router/route-orchestration.d.ts +11 -16
- package/dist/router/route-orchestration.js +2 -12
- package/dist/rule-entry-list.d.ts +8 -7
- package/dist/rule-entry-list.js +2 -9
- package/dist/rules-consent.d.ts +6 -6
- package/dist/rules-consent.js +2 -0
- package/dist/run-cancel-context.d.ts +5 -5
- package/dist/run-local.d.ts +10 -10
- package/dist/runs.d.ts +13 -11
- package/dist/runs.js +15 -1
- package/dist/runtime-caps-resolver.d.ts +6 -6
- package/dist/runtime-governance.d.ts +9 -9
- package/dist/sandbox-pkg-source.d.ts +9 -31
- package/dist/sandbox-pkg-source.js +14 -8
- package/dist/sealed-key.d.ts +3 -3
- package/dist/security.d.ts +23 -26
- package/dist/security.js +12 -9
- package/dist/server-secret-env.d.ts +10 -10
- package/dist/session-children-retire.d.ts +1 -1
- package/dist/session-error-wire.d.ts +7 -7
- package/dist/session-incarnation.d.ts +52 -35
- package/dist/session-incarnation.js +23 -8
- package/dist/session-policy-wire.d.ts +27 -5
- package/dist/session-policy-wire.js +15 -1
- package/dist/session-records-skipped-notice.d.ts +1 -1
- package/dist/session-sync-kernel.d.ts +4 -4
- package/dist/session-sync.d.ts +49 -6
- package/dist/session-sync.js +52 -10
- package/dist/session-titler.d.ts +7 -6
- package/dist/session-titler.js +8 -13
- package/dist/session-watch.d.ts +3 -3
- package/dist/session-watch.js +4 -4
- package/dist/sighup-idle.d.ts +2 -2
- package/dist/spec-fields.d.ts +4 -4
- package/dist/sql-engine-posture.d.ts +3 -3
- package/dist/store-posture.d.ts +2 -2
- package/dist/stored-request-tool-axes-m19.d.ts +1 -1
- package/dist/task-a2a.d.ts +3 -1
- package/dist/task-a2a.js +34 -2
- package/dist/task-cwd.d.ts +7 -88
- package/dist/task-cwd.js +2 -15
- package/dist/task-mcp.d.ts +12 -8
- package/dist/task-mcp.js +19 -4
- package/dist/task-settings.d.ts +30 -18
- package/dist/task-settings.js +33 -3
- package/dist/task-workflow.d.ts +0 -24
- package/dist/task-workflow.js +2 -1
- package/dist/terminal.d.ts +5 -5
- package/dist/tighten-only-seats.d.ts +7 -6
- package/dist/tighten-only-seats.js +1 -1
- package/dist/tool-approval.d.ts +143 -197
- package/dist/tool-approval.js +13 -28
- package/dist/tool-rule-names.d.ts +2 -2
- package/dist/trace/core-keyset-guard.d.ts +12 -7
- package/dist/trace/engine-notice-wire.d.ts +5 -5
- package/dist/trace/engine-notice-wire.js +1 -0
- package/dist/trace/exit-seat.d.ts +31 -4
- package/dist/trace/exit-seat.js +41 -63
- package/dist/trace/ledger-events.d.ts +3 -3
- package/dist/trace/ledger-sink.d.ts +1 -1
- package/dist/trace/model-segment.d.ts +3 -3
- package/dist/trace/project.d.ts +47 -45
- package/dist/trace/project.js +33 -1
- package/dist/trace/redact.d.ts +44 -30
- package/dist/trace/redact.js +191 -89
- package/dist/trace/self-minted-wire.d.ts +35 -14
- package/dist/trace/self-minted-wire.js +8 -0
- package/dist/trace/sema-provenance.d.ts +1 -1
- package/dist/trace/task-notification-facets.d.ts +4 -4
- package/dist/trace/wire-projection-faces.d.ts +3 -3
- package/dist/trace/wire-projection-faces.js +1 -1
- package/dist/unattended-permission-mode.d.ts +5 -5
- package/dist/url-credential.d.ts +52 -0
- package/dist/url-credential.js +49 -0
- package/dist/url-refusal.d.ts +6 -2
- package/dist/url-refusal.js +8 -1
- package/dist/usage-analytics.d.ts +2 -2
- package/dist/user-input-ledger.d.ts +23 -23
- package/dist/web-admin-client/apply-effective.d.ts +5 -5
- package/dist/web-admin-client/apply-effective.js +2 -1
- package/dist/web-admin-client/apply-ledger.d.ts +2 -2
- package/dist/web-admin-client/center-request.d.ts +2 -2
- package/dist/web-admin-client/facade.d.ts +5 -5
- package/dist/web-admin-client/facade.js +1 -1
- package/dist/web-admin-client/hot-keys-registry.d.ts +2 -2
- package/dist/web-admin-client/http-client.d.ts +4 -4
- package/dist/web-admin-client/mcp-revocation.d.ts +1 -1
- package/dist/web-admin-client/pull-state.d.ts +1 -1
- package/dist/web-admin-client/read-face.d.ts +2 -2
- package/dist/web-admin-client/read-warnings.d.ts +5 -5
- package/dist/web-admin-client/restart-signal.d.ts +6 -6
- package/dist/web-admin-client/skills-mcp.d.ts +28 -3
- package/dist/web-admin-client/skills-mcp.js +29 -1
- package/dist/web-admin-client/types.d.ts +16 -9
- package/dist/workspace-space.d.ts +5 -3
- package/dist/write-protection.d.ts +2 -2
- package/package.json +4 -3
- package/scripts/drain-check-local.mjs +2 -1
- package/scripts/drain-check.mysql.sql +4 -2
- package/scripts/drain-check.pg.sql +4 -2
- package/skills/loop.md +1 -1
- package/dist/http/run-declared-families.d.ts +0 -16
- package/dist/http/run-declared-families.js +0 -12
- package/dist/orchestration/workflow-journal-entry.js +0 -27
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { CARD_FACET_OVERRIDES, PAUSE_REGISTRY, checkpointIndexFacts } from "@sema-agent/core";
|
|
2
|
+
export const CHECKPOINT_INDEX_COLUMNS = {
|
|
3
|
+
token: "token",
|
|
4
|
+
scope: "scope",
|
|
5
|
+
sessionId: "session_id",
|
|
6
|
+
version: "version",
|
|
7
|
+
gateKind: "gate_kind",
|
|
8
|
+
approvalCard: "approval_card",
|
|
9
|
+
toolName: "tool_name",
|
|
10
|
+
toolCallId: "tool_call_id",
|
|
11
|
+
boundInputHash: "bound_input_hash",
|
|
12
|
+
deadline: "deadline",
|
|
13
|
+
createdAt: "created_at_ms",
|
|
14
|
+
riskDescriptor: "risk_descriptor",
|
|
15
|
+
hasBidiControls: "has_bidi_controls",
|
|
16
|
+
};
|
|
17
|
+
export function buildCheckpointIndexCells(cp) {
|
|
18
|
+
const f = checkpointIndexFacts(cp);
|
|
19
|
+
return {
|
|
20
|
+
token: f.token,
|
|
21
|
+
scope: f.scope,
|
|
22
|
+
session_id: f.sessionId,
|
|
23
|
+
version: f.version,
|
|
24
|
+
gate_kind: f.gateKind,
|
|
25
|
+
approval_card: f.approvalCard,
|
|
26
|
+
tool_name: f.toolName,
|
|
27
|
+
tool_call_id: f.toolCallId,
|
|
28
|
+
bound_input_hash: f.boundInputHash,
|
|
29
|
+
deadline: f.deadline,
|
|
30
|
+
created_at_ms: f.createdAt,
|
|
31
|
+
risk_descriptor: f.riskDescriptor,
|
|
32
|
+
has_bidi_controls: f.hasBidiControls === true ? 1 : null,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export const APPROVAL_CARD_COLUMN_MAX_BYTES = {
|
|
36
|
+
tidb: 65_535,
|
|
37
|
+
pg: Number.POSITIVE_INFINITY,
|
|
38
|
+
};
|
|
39
|
+
function groupByFacet(pairs, column) {
|
|
40
|
+
const groups = new Map();
|
|
41
|
+
for (const [word, facet] of pairs) {
|
|
42
|
+
const words = groups.get(facet);
|
|
43
|
+
if (words === undefined)
|
|
44
|
+
groups.set(facet, [word]);
|
|
45
|
+
else
|
|
46
|
+
words.push(word);
|
|
47
|
+
}
|
|
48
|
+
return [...groups].map(([facet, words]) => ({ column, words, facet }));
|
|
49
|
+
}
|
|
50
|
+
export const CHECKPOINT_FACET_CASES = [
|
|
51
|
+
...groupByFacet(Object.entries(CARD_FACET_OVERRIDES), CHECKPOINT_INDEX_COLUMNS.approvalCard),
|
|
52
|
+
...groupByFacet(Object.keys(PAUSE_REGISTRY).map((k) => [k, PAUSE_REGISTRY[k].facet]), CHECKPOINT_INDEX_COLUMNS.gateKind),
|
|
53
|
+
];
|
|
54
|
+
const literal = (word) => `'${word.replace(/'/g, "''")}'`;
|
|
55
|
+
function renderFacetCase(compared) {
|
|
56
|
+
return `CASE ${CHECKPOINT_FACET_CASES.map((c) => `WHEN ${compared(c.column)} IN (${c.words.map(literal).join(", ")}) THEN ${literal(c.facet)}`).join(" ")} END`;
|
|
57
|
+
}
|
|
58
|
+
export const CHECKPOINT_FACET_SQL = Object.freeze({
|
|
59
|
+
tidb: renderFacetCase((column) => `CAST(${column} AS BINARY)`),
|
|
60
|
+
pg: renderFacetCase((column) => column),
|
|
61
|
+
});
|
|
62
|
+
//# sourceMappingURL=checkpoint-index-columns.js.map
|
|
@@ -41,7 +41,7 @@ export declare const TERMINAL_GRACE_MS = 3600000;
|
|
|
41
41
|
export declare function tokenFingerprint(token: string): string;
|
|
42
42
|
/** Non-secret view of a pending checkpoint for the operator approval queue — deliberately NO token.
|
|
43
43
|
*
|
|
44
|
-
* 🔴
|
|
44
|
+
* 🔴 [ref]:行**顶层**另带 {@link ParkRowFacts}(`requiresRealApproval` / `ruleOffersAbsence`,真才带、缺席 ≠ false)——
|
|
45
45
|
* 型与值都只有一个来源:`approval-card.ts` 的 {@link parkRowFacts}(两只店各读自己手里的那只寄存行 `pendingAction`,
|
|
46
46
|
* 交给它、原样展开)。继承而不是在这里逐键再写一遍:core 给这一臂再加一位同类事实时,改的只有那张 Pick 表。 */
|
|
47
47
|
export interface PendingCheckpoint extends ParkRowFacts {
|
|
@@ -71,7 +71,7 @@ export interface PendingCheckpoint extends ParkRowFacts {
|
|
|
71
71
|
/** 🔴 [ref]③: the checkpoint's gate kind — the operator queue mixes tool approvals with
|
|
72
72
|
* plan_review / resource_limit / task_done parks (all of which carry `toolName: null`), so a durable-recovery
|
|
73
73
|
* consumer needs this to ROUTE a row to the right wire (`/decide` vs `/plan_review` vs `/resume`). ALWAYS present
|
|
74
|
-
* (
|
|
74
|
+
* ([ref], 7.132.0): every park stamps it, the one-time migration M21 filled any row without it from the row's gate,
|
|
75
75
|
* and a SQL row that still carries none is not listed by `listPending` (counted: `server.approvals.queue-row-gate-kind-missing`; no decide route binds it either). */
|
|
76
76
|
gateKind: CheckpointGate["kind"];
|
|
77
77
|
/** The suspended run's taskId (task_active join) — the key to the run/trace ("view task context"). */
|
|
@@ -131,7 +131,7 @@ export interface PendingCheckpoint extends ParkRowFacts {
|
|
|
131
131
|
* (`PendingAction.hasBidiControls`,core [ref]),`put()` 在铸行
|
|
132
132
|
* 这一刻反范式成 `checkpoint.has_bidi_controls` 列(同行 `tool_input` / `bound_input_hash` / `gate_kind` /
|
|
133
133
|
* `risk_descriptor` / `rule_suggestions` 五列同一条「铸行时一格、读口零 blob」先例),server 不重算。
|
|
134
|
-
* (
|
|
134
|
+
* ([ref] 起本读口**确实**逐行读 blob —— 只为 {@link ParkRowFacts} 那几位,且是按「本仓不发 ALTER TABLE、
|
|
135
135
|
* 加列 = 删库丢在飞 park」裁出来的代价,见 `listPending` 那一段;本位与五列的「铸行时一格」形不变。)
|
|
136
136
|
*
|
|
137
137
|
* 🔴 `true` **或缺席,恒不写 `false`/`null`**(core d.ts 的 OMIT 契约逐字点名 BFF:「never null, never
|
|
@@ -145,12 +145,12 @@ export interface PendingCheckpoint extends ParkRowFacts {
|
|
|
145
145
|
*/
|
|
146
146
|
hasBidiControls?: true;
|
|
147
147
|
/**
|
|
148
|
-
* core 7.49.0
|
|
148
|
+
* core 7.49.0 [ref]:**这一行渲在哪张卡上** —— 门上引擎铸的 `gate.approvalCard`(闭集 core `TOOL_APPROVAL_CARDS`;`question` = 问用户的
|
|
149
149
|
* 问题,不是副作用工具),即 core `summarizeCheckpoint` 投给 `CheckpointSummary.approvalCard` 的同一个词。读法单点 = `approval-content-kind.ts`
|
|
150
150
|
* 的 `parkedApprovalCard`(只在审批门型上读、闭集窄读;两只店同调它:SQL 孪生读 `checkpoint` 列的 `gate` 子树,LOCAL 孪生读 blob 上的门)。
|
|
151
151
|
* 🔴 缺席即缺席([ref]② OMIT 纪律):非审批门、7.49.0 之前停驻的存量行(门上无卡 —— core 的读法「无卡 = 不是一问」,本仓**不**从
|
|
152
152
|
* 工具名回推)。两条 durable 读面(`GET /v1/approvals` 行 + `/stream` `pending` 帧)经同一投影同时携带;live 腿的同名键在
|
|
153
|
-
* `LivePendingRow.approvalCard`。展示/分诊用,永不参与 resume / gate / CAS。(此前此处是按 `tool_name` 列派生的 `contentKind`,随
|
|
153
|
+
* `LivePendingRow.approvalCard`。展示/分诊用,永不参与 resume / gate / CAS。(此前此处是按 `tool_name` 列派生的 `contentKind`,随 [ref] 删。)
|
|
154
154
|
*/
|
|
155
155
|
approvalCard?: ToolApprovalCard;
|
|
156
156
|
}
|
|
@@ -221,7 +221,7 @@ export declare function pendingRowPrecedes(a: {
|
|
|
221
221
|
* 的唯一数据源。一行一列:列名 + 这一列不在时**运行期**先坏在哪(拒启文案逐字用它,所以运维读到的是
|
|
222
222
|
* 「我会先在哪里挂」,不是一句泛泛的 schema 不齐)。
|
|
223
223
|
*
|
|
224
|
-
* 🔴 为什么是一张表而不是每列一个 `assert*ColumnSchema` 函数(
|
|
224
|
+
* 🔴 为什么是一张表而不是每列一个 `assert*ColumnSchema` 函数([ref] 归一):[ref]① 那次是一列一函数,
|
|
225
225
|
* 本批 [ref] 又要加两列 —— 照抄就是第二、第三份三十行的同形代码,而它们**唯一的差别只有列名与那句话**。
|
|
226
226
|
* 探测法(恒空 `WHERE 1=0` 读 + 方言缺列码)、失败方向(只在**可证**缺列时才给删表指路)、恢复动作
|
|
227
227
|
* (DROP TABLE checkpoint 的代价交代)三者对整张表是同一条,所以规则只留一条,列变成数据:下一次加列
|
|
@@ -234,7 +234,7 @@ export declare const CHECKPOINT_ADDED_COLUMNS: ReadonlyArray<{
|
|
|
234
234
|
/**
|
|
235
235
|
* [ref]① 升级前置断言 —— **拒启**,不是 warn(形照 [ref] `assertApprovalAskRuleMaterialSchema` / [ref] /
|
|
236
236
|
* [ref] 三条先例;codex 店面轮 R1-[high] 采纳 —— 其引证的「MIGRATION.md 常设策略」经亲验不存在,采纳的
|
|
237
|
-
* 依据是本仓 assert*Schema 探针族的真先例与失败方向本身)。
|
|
237
|
+
* 依据是本仓 assert*Schema 探针族的真先例与失败方向本身)。[ref] 起判据对 {@link CHECKPOINT_ADDED_COLUMNS}
|
|
238
238
|
* **整张列册**跑(见那张表的头注:归一的理由)。
|
|
239
239
|
*
|
|
240
240
|
* 病:本仓不发 `ALTER TABLE`(SCHEMA POLICY:改列就改 CREATE + 删库重建)。一台**没删表**就升上来的
|
|
@@ -256,31 +256,26 @@ export declare function assertCheckpointColumnSchema(query: (sql: string) => Pro
|
|
|
256
256
|
/**
|
|
257
257
|
* `pendingAction.ruleOffers` 的**铸行侧**投影(mint 面,与 {@link boundedToolInput} 同位同待遇)。
|
|
258
258
|
*
|
|
259
|
-
*
|
|
260
|
-
* 1.
|
|
261
|
-
*
|
|
262
|
-
*
|
|
263
|
-
*
|
|
264
|
-
* 未知键会**留在** `parsed.data` 里,与「剥掉」相反)。上游 additive 加一键是 core 的常规做法,拿 strict 去窄读会让那一次加字段把整只
|
|
265
|
-
* offer 静默清零 —— 「有供给」当场变「无供给」,与本键的存在理由正相反(顶注第三段)。
|
|
259
|
+
* 四件事,一件都不能少:
|
|
260
|
+
* 1. **读**(宪法 [ref] 边界必判形 / 禁裸 as-cast):blob 里的这一格是 `unknown`(旧 core / 坏行 / 未来加字段都可能)。读者只有一只 =
|
|
261
|
+
* core `readRuleOffers`(经 `approval-card.ts` 的 {@link readRuleOfferList};core 7.55.0 [ref] P1 阶段二起,修前本仓自己一份 zod 形):读不出的**整条丢弃**
|
|
262
|
+
* (不是整只丢弃)——一条坏 offer 不该让另一条真 offer 消失;多余键逐级剥、不拒收(上游 additive 加一键是 core 的常规做法,拒收会把「有供给」静默变成「无供给」);
|
|
263
|
+
* 丢弃**响亮**(`server.rule-offers.offer-dropped`,修前这一腿静默)。
|
|
266
264
|
* 2. **脱敏**:offer 文本是从**命令原文**铸出来的(`Bash(curl -H "Authorization: Bearer …")` 这种 exact
|
|
267
265
|
* 形拼得出秘密),而 `GET /v1/approvals` 是**跨租户可见**的运维队列。落列前过 `redactSecrets` ——
|
|
268
|
-
* 与同行 `tool_input` 在 mint 就 `redactDeep` 是**同一条**纪律(
|
|
269
|
-
* 是因为那条路的行早已落库、改铸点救不了存量;本键是**新**列,没有存量行要救,修在铸点更彻底:
|
|
270
|
-
* 秘密从此连**落库**都不落,不是落了库再在两条读面各洗一遍)。
|
|
266
|
+
* 与同行 `tool_input` 在 mint 就 `redactDeep` 是**同一条**纪律(秘密从此连**落库**都不落,不是落了库再在两条读面各洗一遍)。
|
|
271
267
|
* 3. **脱敏之后**才截长(codex 交叉复审 [medium],验真后修):`redactSecrets` 会**变长**,先按限长校验
|
|
272
268
|
* 原文再脱敏会产出超限文本,而 SQL 腿有**回读**(列 → 本函数再跑一遍)、LOCAL 腿没有 ⇒ 同一份素材
|
|
273
|
-
*
|
|
274
|
-
* `RuleOfferRawSchema` 顶注。
|
|
269
|
+
* 两个后端给出不同卡面。顺序反过来之后本函数对自己的输出**幂等**,两条腿同形。
|
|
275
270
|
* 4. **限基数**:core 契约今天 ≤2,这里按 {@link MAX_RULE_OFFERS}(=4,server 侧容忍帽,两个数的
|
|
276
271
|
* 分工逐字见该常量顶注)截;`batch.rules` 成员另按 {@link MAX_RULE_OFFER_BATCH_MEMBERS}(=8)截 ——
|
|
277
272
|
* 一条被改坏/未来放宽的上游不该把运维队列的一行撑爆。两个截都是**前缀截**(保序)。
|
|
278
273
|
* ⚠️ **但本函数整体不保原始下标**:第 1 条的「坏的逐条丢」会压紧数组 ⇒ 中间剔除后下标前移。
|
|
279
274
|
* 本腿因此是**纯展示腿**,下标不得当选择键 —— 硬条款与它站得住的理由逐字见
|
|
280
275
|
* {@link PendingCheckpoint.ruleOffers} 顶注(同步腿相反:那侧零逐条丢弃,下标恒等于 core 的 offer index)。
|
|
281
|
-
* 🔴
|
|
276
|
+
* 🔴 **成员帽扣在读之前**(5.58 复审 F-2):见 {@link preboundBatchMembers} —— offer 条数那一维由
|
|
282
277
|
* {@link MAX_RULE_OFFER_SCAN} 管,成员那一维在那之前是**无界**的。
|
|
283
|
-
* 🔴
|
|
278
|
+
* 🔴 **扣预算在读出之后**(合并码重扫):旧序先 `slice` 再判形,于是 ≥MAX 条坏 offer 能把唯一的真
|
|
284
279
|
* offer 挤出预算,读数是 `undefined` —— 与上面第 1 条自证的不变量(坏的丢、好的照投)正相反。扫描窗
|
|
285
280
|
* {@link MAX_RULE_OFFER_SCAN} 仍是有界的:一条被改坏成上万条的行不该让每 3s 一拍的读路径去逐条判形。
|
|
286
281
|
*
|
|
@@ -291,13 +286,13 @@ export declare function assertCheckpointColumnSchema(query: (sql: string) => Pro
|
|
|
291
286
|
* 用来识别「过度脱敏 / pattern 从不触发」的指标灌成不可读。关掉的是**计数**:重扫仍在,手改过的行 /
|
|
292
287
|
* 将来某条写路径漏了脱敏,读面照样兜住(运维队列跨租户可见,少脱一次的代价永远不能省)。
|
|
293
288
|
*
|
|
294
|
-
* 返回 `undefined` = **无供给**(键不落列):core
|
|
289
|
+
* 返回 `undefined` = **无供给**(键不落列):core 没给、给了空数组、或整只读不出。
|
|
295
290
|
*/
|
|
296
291
|
export declare function boundedRuleOffers(raw: unknown, opts?: {
|
|
297
292
|
countRedactions?: boolean;
|
|
298
293
|
}): RuleOfferProjection[] | undefined;
|
|
299
294
|
/**
|
|
300
|
-
*
|
|
295
|
+
* [ref] —— 运维队列行的门型:**两只孪生同一只判官**(SQL 孪生读 `gate_kind` 列 —— put 时从同一只门反范式下来的那一格,每次停驻都盖,一次性迁移 M21 把没有它的
|
|
301
296
|
* 存量行从门子树补齐;local 孪生读快照上的门 `cp.gate.kind`)。
|
|
302
297
|
* 读到的值是 NULL / 缺席 / 不是 core 登记的门型 ⇒ `undefined`:这一行**不列**(响亮:计一次 `server.approvals.queue-row-gate-kind-missing`)—— 与每一条决断口同一个读法:
|
|
303
298
|
* 按门型绑定取行的读口对这种行本来就不命中(`pendingRowQuery` 的 `gate_kind IN (…)`,证不出门型就不当它是这道门),队列不再把一行谁也决不了的行投出去,
|
|
@@ -367,7 +362,7 @@ export interface DecidedApprovalRecord {
|
|
|
367
362
|
*/
|
|
368
363
|
payloadFp: string | null;
|
|
369
364
|
/**
|
|
370
|
-
*
|
|
365
|
+
* [ref](core 7.7.0 [ref])—— 这条已决行上**已决动作最后被怎么处置**的结算记录,`null` = **未知**。
|
|
371
366
|
*
|
|
372
367
|
* 🔴 缺席只有一个含义:未知,**绝不是**「放行过」。`decision` 说的是决定(人批了没有),这一格说的是
|
|
373
368
|
* 那次决定在 resume 腿上执行时的处置(部署自己的复核可能在 post-CAS 把人批过的、改过参数的调用否掉,
|
|
@@ -412,7 +407,7 @@ export declare function approvalDecisionOfWinner(winner: ResolvedOutcome | undef
|
|
|
412
407
|
*
|
|
413
408
|
* 逐层 `typeof` 收窄,不做裸 `as` 断言:blob 是持久层读回来的 `unknown`,是信任边界(宪法 [ref])。
|
|
414
409
|
*
|
|
415
|
-
* 🔴
|
|
410
|
+
* 🔴 [ref]:入参是**已经解过码的体**,不是一格列文本 —— 本函数不再自己 `JSON.parse`(SQL 车道的解码
|
|
416
411
|
* 唯一属主是 `sql-json-column.ts`,见 {@link pendingActionOfColumn};local 孪生本来就递一只对象进来)。
|
|
417
412
|
* 于是「串就再解一次」这条读法在这里按构造消失,两条车道递进来的东西同形。
|
|
418
413
|
*/
|
|
@@ -503,7 +498,7 @@ export declare class SqlCheckpointStore implements CheckpointStore {
|
|
|
503
498
|
readonly reopen: true;
|
|
504
499
|
};
|
|
505
500
|
/**
|
|
506
|
-
* `CheckpointStore.execution` 声明(core 7.7.0 [ref];
|
|
501
|
+
* `CheckpointStore.execution` 声明(core 7.7.0 [ref];[ref])——**必填**,且必须恰是 `{ outcome: true }`:
|
|
507
502
|
* 店在此承诺 {@link SqlCheckpointStore.recordExecutionOutcome} 是契约描述的那条真 CAS(谓词、四词、
|
|
508
503
|
* 冲突抛),且 {@link SqlCheckpointStore.reopen} 认这条记录。与 `durability`/`fidelity`/`redecision`
|
|
509
504
|
* 三格同一条「声明而非鸭子判」姿势,区别只在这一格**不可缺席**:缺席的店会被 core 在 store 席的
|
|
@@ -582,7 +577,7 @@ export declare class SqlCheckpointStore implements CheckpointStore {
|
|
|
582
577
|
*/
|
|
583
578
|
reopen(token: CheckpointToken, scope: string, reason: ReopenReason): Promise<boolean>;
|
|
584
579
|
/**
|
|
585
|
-
* core 7.7.0 [ref](
|
|
580
|
+
* core 7.7.0 [ref]([ref])—— 记录**已决动作在 resume 腿上最后被怎么处置**:那一次调用的 `tool_end` 帧
|
|
586
581
|
* 携带的 {@link GateOutcome}。契约(答案闭集四词 / 幂等 / 冲突抛 / 一个字都不碰 status·rev·outcome·
|
|
587
582
|
* reopen_reason)的**判词逻辑一行都不自铸**:全部消费 core 导出的
|
|
588
583
|
* {@link executionRecordDisposition} —— 它是每个后端共用的那一份「CAS 谓词 + 幂等/冲突两臂」,
|
|
@@ -645,53 +640,36 @@ export declare class SqlCheckpointStore implements CheckpointStore {
|
|
|
645
640
|
* whose per-approval `deadline` OR its [ref] D-1 §3-inv#3 `terminal_at_ms` crash-safe backstop has passed —
|
|
646
641
|
* the latter closes the forever-leak of a pending row with a NULL `deadline` (no approval TTL was configured).
|
|
647
642
|
*
|
|
648
|
-
*
|
|
649
|
-
*
|
|
650
|
-
*
|
|
651
|
-
*
|
|
652
|
-
* gate
|
|
653
|
-
*
|
|
654
|
-
*
|
|
655
|
-
*
|
|
656
|
-
*
|
|
657
|
-
*
|
|
658
|
-
* another replica wins cleanly). The card lives only in the `checkpoint` blob's `gate` subtree, so the split cannot be
|
|
659
|
-
* one SQL predicate without writing core's judgment a second time in SQL; the old `tool_name` literal arm is gone. A
|
|
660
|
-
* gate with no card (parked before 7.49.0) is no question — core's reading — and stays with the deny-sweep.
|
|
643
|
+
* The deadline-branch expires every row whose facet is NOT `A` (core 7.55.0 [ref] P1 stage two): the facet is
|
|
644
|
+
* {@link CHECKPOINT_FACET_SQL}, the expression generated from core's `CARD_FACET_OVERRIDES` and `PAUSE_REGISTRY` over the
|
|
645
|
+
* row's `approval_card` / `gate_kind` columns — row by row it answers what core `facetOf(gate)` answers. Facet `A` (an
|
|
646
|
+
* approval gate whose deadline is an SLA) is resolve-DENIED by the deny-sweep instead ({@link listExpiredApprovalGates});
|
|
647
|
+
* a question parked under an approval gate (card `question`, facet `B`) is voided here in the same statement; a row whose
|
|
648
|
+
* gate kind is NULL or not registered reads NULL and is voided (as before). The terminal_at_ms-branch is the crash-safe
|
|
649
|
+
* backstop for ANY kind (incl. a human gate whose deny-resume keeps failing) — STRICTLY after the deadline, so it never
|
|
650
|
+
* races the deny-sweep at the deadline instant. Before: a hand-written approval-kind list in SQL, then a second pass that
|
|
651
|
+
* read each overdue approval row's `gate` subtree out of the blob and voided the question rows one by one (bounded pages,
|
|
652
|
+
* a cross-tick cursor).
|
|
661
653
|
*/
|
|
662
654
|
reapExpired(cutoff: number): Promise<number>;
|
|
663
|
-
/**
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
*
|
|
667
|
-
*
|
|
668
|
-
*
|
|
669
|
-
*
|
|
670
|
-
*
|
|
671
|
-
* 🔴 core 7.49.0 #1414 / #1468 A-S4: a gate carrying the `question` card (facet `B`) is NOT deny-swept — core refuses
|
|
672
|
-
* `sla_timeout` on it pre-CAS — reapExpired voids it instead. The card lives only in the blob's `gate` subtree and the
|
|
673
|
-
* judge is core's (the split is not one SQL predicate — see {@link reapExpired}), so the filter runs on the rows read;
|
|
674
|
-
* the read is therefore PAGED, filter first and `limit` after: pages of {@link REAP_CLASSIFY_BATCH} rows in the stable
|
|
675
|
-
* (deadline, token) order, the cursor advancing, until `limit` rows are collected or the overdue rows run out — the same
|
|
676
|
-
* "filter, then take `limit`" the LOCAL twin does. A backlog of question rows ahead of the deny-sweep's rows costs extra
|
|
677
|
-
* bounded pages, never a hidden deny-sweep row (they used to hold slots of a `LIMIT limit` window until voided).
|
|
655
|
+
/**
|
|
656
|
+
* [ref] D-D (SLA-timer): the sessions of pending checkpoints past their `deadline` whose facet is `A` — approval gates
|
|
657
|
+
* whose deadline is an SLA ({@link CHECKPOINT_FACET_SQL}, generated from core's two tables; the LOCAL twin reads core
|
|
658
|
+
* `facetOf` through `denySweepOwns`) — the reaper resolve-DENIES each (re-resume with decision=deny → the model continues
|
|
659
|
+
* with the denial), graceful, vs the abort that {@link reapExpired} gives every other facet. A question parked under an
|
|
660
|
+
* approval gate (facet `B`) is not here: core refuses `sla_timeout` on it pre-CAS, and reapExpired voids it. The filter is
|
|
661
|
+
* in SQL, before the LIMIT: `limit` bounds the per-tick deny-resume work (each is a model run), never hides a row behind
|
|
662
|
+
* rows the sweep does not own.
|
|
678
663
|
*/
|
|
679
664
|
listExpiredApprovalGates(cutoff: number, limit?: number): Promise<Array<{
|
|
680
665
|
sessionId: string;
|
|
681
666
|
scope: string;
|
|
682
667
|
}>>;
|
|
683
|
-
/**
|
|
684
|
-
* core 7.49.0 #1414 / #1468 A-S4 —— 审批门型里过了 deadline 的 pending 行(deadline 升序),每行带 core 对它的到期读法
|
|
685
|
-
* (`denySweepOwns` = 审批门型 ∧ core `facetOf` 读作 `A`,门型取列、卡取 `gate` 子树)。到期两条腿(reapExpired 的 ②、拒扫腿的选行)读同一只:
|
|
686
|
-
* 对审批门型「谁拒扫、谁作废」本仓不写第二份判据。读恒有界(每次一页 `limit` 行),序 = (deadline, token) 稳定序;`after` = 从这一位置之后读
|
|
687
|
-
* (reapExpired 的跨拍游标;拒扫腿选行一次之内的翻页游标)。
|
|
688
|
-
*/
|
|
689
|
-
private overdueApprovalRows;
|
|
690
668
|
/** Pending checkpoints for the operator queue — NON-secret fields only (never the token). `taskId` is
|
|
691
669
|
* joined from task_active (the JOIN KEY to the run/trace — a suspended run KEEPS its
|
|
692
670
|
* session claim, so the join is live for every pending row; null only in pathological windows). */
|
|
693
671
|
/**
|
|
694
|
-
*
|
|
672
|
+
* [ref] 显式记账 —— **本口与 {@link SqlCheckpointStore.listByScope} 都不投执行判词,这是结构性的不是遗漏**:
|
|
695
673
|
* 两口的谓词都硬 `status='pending'`,而执行记录的 CAS 谓词是 `status='resolved' AND execution_outcome IS NULL`
|
|
696
674
|
* ⇒ 一条 pending 行**按构造**不可能带记录;反向也封死了(记过的行 `reopen` 拒,永远回不到 pending)。
|
|
697
675
|
* 所以这两条读面上「没有 `executionOutcome`」不是「缺席=未知」,而是「这一格在这条读面上不存在」。
|
|
@@ -811,11 +789,11 @@ export declare class SqlCheckpointStore implements CheckpointStore {
|
|
|
811
789
|
*/
|
|
812
790
|
peekScopeByToken(token: CheckpointToken): Promise<string | null | undefined>;
|
|
813
791
|
peekPendingScope(sessionId: string, binding?: PendingRowBinding): Promise<string | null | undefined>;
|
|
814
|
-
/** Upsert the resume rebuild inputs for a session — written at SUBMIT (durable mode on) and, since
|
|
792
|
+
/** Upsert the resume rebuild inputs for a session — written at SUBMIT (durable mode on) and, since [ref] F2,
|
|
815
793
|
* once per resume leg at its CAS win point (`DriveResumeArgs.resumeCtx`). Unconditional per `session_id`:
|
|
816
794
|
* the ordering fence lives at the CALLER's CAS win, not in a version column here.
|
|
817
795
|
*
|
|
818
|
-
* 🔴 `ctx: object`, not `unknown` (
|
|
796
|
+
* 🔴 `ctx: object`, not `unknown` ([ref]): the read leg judges this column as a JSON **object**
|
|
819
797
|
* ({@link decodeCtxColumn}), so a writer that took `unknown` would be the "writes fine, reads back
|
|
820
798
|
* refused" asymmetry this repo keeps paying for — and `putCtx(sessionId, null)` was exactly the
|
|
821
799
|
* reachable arm that made the JSON literal `null` (indistinguishable from "no such row" at every
|
|
@@ -847,7 +825,7 @@ export declare class SqlCheckpointStore implements CheckpointStore {
|
|
|
847
825
|
*
|
|
848
826
|
* The extra `task_active` guard closes a multi-gate window: between a resume's CAS (pending→resolved) and
|
|
849
827
|
* the task hitting its NEXT gate (writing a new pending checkpoint), the session has no pending checkpoint —
|
|
850
|
-
* yet `putCtx` stamps `updated_at_ms` at submit and — since
|
|
828
|
+
* yet `putCtx` stamps `updated_at_ms` at submit and — since [ref] F2 (server 7.86.0) — once more on EVERY
|
|
851
829
|
* resume leg, at the moment that leg wins the resume CAS (`DriveResumeArgs.resumeCtx`; before that fix only
|
|
852
830
|
* the plan approval's mode write-back re-stamped it, and it did so AFTER acceptance). Both extra writes only
|
|
853
831
|
* ever REFRESH the stamp, so they lengthen a ctx's life and touch none of the three guards — the direction is
|
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
import { parkedApprovalCard
|
|
1
|
+
import { parkedApprovalCard } from "../approval-content-kind.js";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
|
-
import {
|
|
4
|
-
import { CheckpointError, isGateKind, MAX_RULE_TEXT_CHARS, validatePendingSteer, appendPendingSteer,
|
|
3
|
+
import { CHECKPOINT_FACET_SQL, buildCheckpointIndexCells } from "./checkpoint-index-columns.js";
|
|
4
|
+
import { CheckpointError, isGateKind, MAX_RULE_TEXT_CHARS, validatePendingSteer, appendPendingSteer, winnerFromOutcome, summarizeCheckpoint, MAX_SUPPORTED_CHECKPOINT_VERSION, ExecutionOutcomeConflictError, executionRecordDisposition, executionVerdict, } from "@sema-agent/core";
|
|
5
5
|
import { redactDeep, redactSecrets } from "../trace/redact.js";
|
|
6
|
-
import { MAX_RULE_OFFERS, MAX_RULE_OFFER_BATCH_MEMBERS,
|
|
6
|
+
import { MAX_RULE_OFFERS, MAX_RULE_OFFER_BATCH_MEMBERS, parkRowFacts, readRuleOfferList } from "../approval-card.js";
|
|
7
7
|
import { assertJsonColumnWritable, createObjectColumnReader, decodeJsonColumn, decodeNullableJsonColumn, foldJsonColumn, isJsonColumnBodyProblem, jsonColumnText, readJsonArrayColumn, readJsonObjectColumn, readNonNullJsonValueColumn, } from "./sql-json-column.js";
|
|
8
8
|
import { recordFailOpen } from "../observability/fail-open.js";
|
|
9
|
-
import { durableRowIdentity } from "../checkpoint-identity.js";
|
|
9
|
+
import { durableRowIdentity, withoutCheckpointToken } from "../checkpoint-identity.js";
|
|
10
10
|
import { mysqlDriver, pgDriver, dialectProtocolJsonEncoder } from "./sql-driver.js";
|
|
11
11
|
import { isDupKeyError, isMissingColumnError, rowTooLargeOrSelf, StoreRowTooLargeError } from "./sql-errors.js";
|
|
12
12
|
import { MANAGED_RETENTION } from "./retention-store-sql.js";
|
|
13
13
|
import { approvalPayloadFingerprint } from "./approval-payload-fingerprint.js";
|
|
14
|
-
const REAP_CLASSIFY_BATCH = 200;
|
|
15
14
|
const CTX_REWRITE_PAGE = 500;
|
|
16
15
|
export { approvalPayloadFingerprint } from "./approval-payload-fingerprint.js";
|
|
17
16
|
const MAX_TOOL_INPUT_CHARS = 8192;
|
|
@@ -82,36 +81,36 @@ function preboundBatchMembers(item) {
|
|
|
82
81
|
return { ...candidate, rules: candidate.rules.slice(0, MAX_RULE_OFFER_BATCH_MEMBERS) };
|
|
83
82
|
}
|
|
84
83
|
export function boundedRuleOffers(raw, opts = {}) {
|
|
85
|
-
if (!Array.isArray(raw))
|
|
86
|
-
return undefined;
|
|
87
84
|
const observe = opts.countRedactions ?? true;
|
|
88
85
|
const scrub = (text) => redactSecrets(text, { observe }).slice(0, MAX_RULE_TEXT_CHARS);
|
|
86
|
+
const read = readRuleOfferList(Array.isArray(raw) ? raw.slice(0, MAX_RULE_OFFER_SCAN).map(preboundBatchMembers) : raw);
|
|
89
87
|
const out = [];
|
|
90
|
-
for (const
|
|
88
|
+
for (const { offer } of read) {
|
|
91
89
|
if (out.length >= MAX_RULE_OFFERS)
|
|
92
90
|
break;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
91
|
+
switch (offer.kind) {
|
|
92
|
+
case "single":
|
|
93
|
+
out.push({ kind: "single", rule: scrub(offer.rule), match: offer.match, command: scrub(offer.command) });
|
|
94
|
+
break;
|
|
95
|
+
case "batch":
|
|
96
|
+
out.push({
|
|
97
|
+
kind: "batch",
|
|
98
|
+
rules: offer.rules.slice(0, MAX_RULE_OFFER_BATCH_MEMBERS).map((r) => {
|
|
99
|
+
switch (r.kind) {
|
|
100
|
+
case "command":
|
|
101
|
+
return { kind: "command", rule: scrub(r.rule), match: r.match, command: scrub(r.command), segment: scrub(r.segment) };
|
|
102
|
+
case "directoryRead":
|
|
103
|
+
return { kind: "directoryRead", rule: scrub(r.rule), directory: scrub(r.directory), segment: scrub(r.segment) };
|
|
104
|
+
default:
|
|
105
|
+
throw new Error(`unknown rule-offer batch member kind: ${JSON.stringify(r)}`);
|
|
106
|
+
}
|
|
107
|
+
}),
|
|
108
|
+
uncoveredSegments: offer.uncoveredSegments,
|
|
109
|
+
...(offer.uncoveredDetail !== undefined ? { uncoveredDetail: offer.uncoveredDetail.map((d) => ({ segment: scrub(d.segment), reason: d.reason })) } : {}),
|
|
110
|
+
});
|
|
111
|
+
break;
|
|
112
|
+
default:
|
|
113
|
+
throw new Error(`unknown rule-offer kind: ${JSON.stringify(offer)}`);
|
|
115
114
|
}
|
|
116
115
|
}
|
|
117
116
|
return out.length > 0 ? out : undefined;
|
|
@@ -197,28 +196,12 @@ function readCheckpointIdCell(cell) {
|
|
|
197
196
|
return null;
|
|
198
197
|
}
|
|
199
198
|
}
|
|
200
|
-
const PARK_ROW_GATE = { key: "gate", as: "park_gate" };
|
|
201
|
-
function readParkGateCell(cell) {
|
|
202
|
-
try {
|
|
203
|
-
return decodeNullableJsonColumn(cell, readParkGateMemberBody, "checkpoint.checkpoint $.gate (approval card / expiry facet)");
|
|
204
|
-
}
|
|
205
|
-
catch (e) {
|
|
206
|
-
if (!isJsonColumnBodyProblem(e))
|
|
207
|
-
throw e;
|
|
208
|
-
recordFailOpen("server.approvals.park-row-blob-unreadable", "member=gate");
|
|
209
|
-
return undefined;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
const readParkGateMemberBody = createObjectColumnReader();
|
|
213
199
|
export function queueRowGateKind(kind) {
|
|
214
200
|
if (isGateKind(kind))
|
|
215
201
|
return kind;
|
|
216
202
|
recordFailOpen("server.approvals.queue-row-gate-kind-missing", `gate_kind=${kind === null || kind === undefined ? "NULL" : redactSecrets(String(kind)).slice(0, 40)}`);
|
|
217
203
|
return undefined;
|
|
218
204
|
}
|
|
219
|
-
function parkedGateOfRow(r) {
|
|
220
|
-
return { kind: r.gate_kind ?? undefined, approvalCard: readParkGateCell(r[PARK_ROW_GATE.as])?.approvalCard };
|
|
221
|
-
}
|
|
222
205
|
const readPendingActionMemberBody = createObjectColumnReader();
|
|
223
206
|
export function boundedToolInput(args) {
|
|
224
207
|
if (args === undefined)
|
|
@@ -400,34 +383,34 @@ export class SqlCheckpointStore {
|
|
|
400
383
|
return { sql: `SELECT ${select} FROM checkpoint WHERE ${where.join(" AND ")} ORDER BY created_at_ms ${dir}, token ${dir} LIMIT 1`, params };
|
|
401
384
|
}
|
|
402
385
|
async put(token, cp) {
|
|
386
|
+
const cells = buildCheckpointIndexCells(cp);
|
|
403
387
|
const pa = cp.pendingAction;
|
|
404
|
-
const version = checkpointVersionOf(cp);
|
|
405
388
|
const toolInput = boundedToolInput(pa?.args);
|
|
406
389
|
const ruleOffers = boundedRuleOffers(pa?.ruleOffers);
|
|
407
|
-
const hasBidiControls = pa?.hasBidiControls === true ? 1 : null;
|
|
408
390
|
const executionOutcome = cp.executionOutcome === undefined ? null : this.json(cp.executionOutcome, "execution outcome");
|
|
409
391
|
const executionAtMs = cp.executionOutcome === undefined ? null : (cp.executionAtMs ?? null);
|
|
410
392
|
try {
|
|
411
|
-
await this.db.query(this.q("INSERT INTO checkpoint (token, scope, session_id, version, status, tool_name, tool_call_id, tool_input, checkpoint, deadline, created_at_ms, terminal_at_ms, gate_kind, bound_input_hash, risk_descriptor, rule_suggestions, has_bidi_controls, rev, reopen_reason, execution_outcome, execution_at_ms) " +
|
|
412
|
-
"VALUES (
|
|
413
|
-
"VALUES ($1,$2,$3,$4,$5,$6,$7,$8::jsonb,$9::jsonb,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20::jsonb,$
|
|
393
|
+
await this.db.query(this.q("INSERT INTO checkpoint (token, scope, session_id, version, status, tool_name, tool_call_id, tool_input, checkpoint, deadline, created_at_ms, terminal_at_ms, gate_kind, approval_card, bound_input_hash, risk_descriptor, rule_suggestions, has_bidi_controls, rev, reopen_reason, execution_outcome, execution_at_ms) " +
|
|
394
|
+
"VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", "INSERT INTO checkpoint (token, scope, session_id, version, status, tool_name, tool_call_id, tool_input, checkpoint, deadline, created_at_ms, terminal_at_ms, gate_kind, approval_card, bound_input_hash, risk_descriptor, rule_suggestions, has_bidi_controls, rev, reopen_reason, execution_outcome, execution_at_ms) " +
|
|
395
|
+
"VALUES ($1,$2,$3,$4,$5,$6,$7,$8::jsonb,$9::jsonb,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21::jsonb,$22)"), [
|
|
414
396
|
token,
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
version,
|
|
397
|
+
cells.scope,
|
|
398
|
+
cells.session_id,
|
|
399
|
+
cells.version,
|
|
418
400
|
cp.status,
|
|
419
|
-
|
|
420
|
-
|
|
401
|
+
cells.tool_name,
|
|
402
|
+
cells.tool_call_id,
|
|
421
403
|
toolInput === null ? null : this.json(toolInput, "approval tool_input"),
|
|
422
404
|
this.json(cp, "checkpoint"),
|
|
423
|
-
|
|
424
|
-
|
|
405
|
+
cells.deadline,
|
|
406
|
+
cells.created_at_ms,
|
|
425
407
|
Math.max(cp.createdAt + TERMINAL_BACKSTOP_MS, (cp.deadline ?? 0) + TERMINAL_GRACE_MS),
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
408
|
+
cells.gate_kind,
|
|
409
|
+
cells.approval_card,
|
|
410
|
+
cells.bound_input_hash,
|
|
411
|
+
cells.risk_descriptor === null ? null : this.json(cells.risk_descriptor, "risk descriptor"),
|
|
429
412
|
ruleOffers === undefined ? null : this.json(ruleOffers, "rule offers"),
|
|
430
|
-
|
|
413
|
+
cells.has_bidi_controls,
|
|
431
414
|
cp.rev ?? 0,
|
|
432
415
|
cp.reopenReason ?? null,
|
|
433
416
|
executionOutcome,
|
|
@@ -555,49 +538,19 @@ export class SqlCheckpointStore {
|
|
|
555
538
|
}
|
|
556
539
|
async reapExpired(cutoff) {
|
|
557
540
|
const res = await this.db.query(this.q("UPDATE checkpoint SET status = 'expired', decided_at_ms = ? " +
|
|
558
|
-
`WHERE status = 'pending' AND ((deadline IS NOT NULL AND deadline <= ? AND (
|
|
559
|
-
`WHERE status = 'pending' AND ((deadline IS NOT NULL AND deadline <= $2 AND (
|
|
560
|
-
|
|
561
|
-
const batch = await this.overdueApprovalRows(cutoff, REAP_CLASSIFY_BATCH, this.reapCursor);
|
|
562
|
-
for (const row of batch) {
|
|
563
|
-
if (!row.denySweeps && (await this.expire(row.token, row.scope)))
|
|
564
|
-
n++;
|
|
565
|
-
}
|
|
566
|
-
const last = batch.at(-1);
|
|
567
|
-
this.reapCursor = batch.length < REAP_CLASSIFY_BATCH || last === undefined ? undefined : { deadline: last.deadline, token: last.token };
|
|
568
|
-
return n;
|
|
541
|
+
`WHERE status = 'pending' AND ((deadline IS NOT NULL AND deadline <= ? AND COALESCE(${CHECKPOINT_FACET_SQL.tidb}, '') <> 'A') OR (terminal_at_ms IS NOT NULL AND terminal_at_ms <= ?))`, "UPDATE checkpoint SET status = 'expired', decided_at_ms = $1 " +
|
|
542
|
+
`WHERE status = 'pending' AND ((deadline IS NOT NULL AND deadline <= $2 AND COALESCE(${CHECKPOINT_FACET_SQL.pg}, '') <> 'A') OR (terminal_at_ms IS NOT NULL AND terminal_at_ms <= $3))`), [Date.now(), cutoff, cutoff]);
|
|
543
|
+
return res.affected;
|
|
569
544
|
}
|
|
570
|
-
reapCursor;
|
|
571
545
|
async listExpiredApprovalGates(cutoff, limit = 100) {
|
|
572
|
-
const
|
|
573
|
-
|
|
574
|
-
while (hits.length < limit) {
|
|
575
|
-
const page = await this.overdueApprovalRows(cutoff, REAP_CLASSIFY_BATCH, after);
|
|
576
|
-
for (const r of page) {
|
|
577
|
-
if (hits.length < limit && r.denySweeps)
|
|
578
|
-
hits.push({ sessionId: r.sessionId, scope: r.scope });
|
|
579
|
-
}
|
|
580
|
-
const last = page.at(-1);
|
|
581
|
-
if (page.length < REAP_CLASSIFY_BATCH || last === undefined)
|
|
582
|
-
break;
|
|
583
|
-
after = { deadline: last.deadline, token: last.token };
|
|
584
|
-
}
|
|
585
|
-
return hits;
|
|
586
|
-
}
|
|
587
|
-
async overdueApprovalRows(cutoff, limit, after) {
|
|
588
|
-
const head = `SELECT c.token, c.session_id, c.scope, c.gate_kind, c.deadline, ${jsonColumnText(this.db.dialect, "checkpoint", PARK_ROW_GATE)} FROM checkpoint c ` +
|
|
589
|
-
`WHERE c.status = 'pending' AND c.gate_kind IN ${APPROVAL_GATE_KINDS_SQL_IN} AND c.deadline IS NOT NULL AND `;
|
|
590
|
-
const { rows } = await this.db.query(after === undefined
|
|
591
|
-
? head + this.q("c.deadline <= ? ORDER BY c.deadline ASC, c.token ASC LIMIT ?", "c.deadline <= $1 ORDER BY c.deadline ASC, c.token ASC LIMIT $2")
|
|
592
|
-
: head +
|
|
593
|
-
this.q("c.deadline <= ? AND (c.deadline > ? OR (c.deadline = ? AND c.token > ?)) ORDER BY c.deadline ASC, c.token ASC LIMIT ?", "c.deadline <= $1 AND (c.deadline > $2 OR (c.deadline = $3 AND c.token > $4)) ORDER BY c.deadline ASC, c.token ASC LIMIT $5"), after === undefined ? [cutoff, limit] : [cutoff, after.deadline, after.deadline, after.token, limit]);
|
|
594
|
-
return rows.map((r) => ({ token: String(r.token), sessionId: String(r.session_id), scope: String(r.scope), deadline: Number(r.deadline), denySweeps: denySweepOwns(parkedGateOfRow(r)) }));
|
|
546
|
+
const { rows } = await this.db.query(this.q(`SELECT session_id, scope FROM checkpoint WHERE status = 'pending' AND deadline IS NOT NULL AND deadline <= ? AND ${CHECKPOINT_FACET_SQL.tidb} = 'A' ORDER BY deadline ASC, token ASC LIMIT ?`, `SELECT session_id, scope FROM checkpoint WHERE status = 'pending' AND deadline IS NOT NULL AND deadline <= $1 AND ${CHECKPOINT_FACET_SQL.pg} = 'A' ORDER BY deadline ASC, token ASC LIMIT $2`), [cutoff, limit]);
|
|
547
|
+
return rows.map((r) => ({ sessionId: String(r.session_id), scope: String(r.scope) }));
|
|
595
548
|
}
|
|
596
549
|
async listPending(scope) {
|
|
597
550
|
const d = this.db.dialect;
|
|
598
551
|
const base = `SELECT c.session_id, c.token, c.scope, c.tool_name, c.tool_call_id, ${jsonColumnText(d, "tool_input")}, c.bound_input_hash, ` +
|
|
599
|
-
`${jsonColumnText(d, "risk_descriptor")}, ${jsonColumnText(d, "rule_suggestions")}, c.has_bidi_controls, c.created_at_ms, c.deadline, c.gate_kind, ta.task_id, ` +
|
|
600
|
-
`${jsonColumnText(d, "checkpoint", PARK_ROW_PENDING_ACTION)}, ${jsonColumnText(d, "checkpoint",
|
|
552
|
+
`${jsonColumnText(d, "risk_descriptor")}, ${jsonColumnText(d, "rule_suggestions")}, c.has_bidi_controls, c.created_at_ms, c.deadline, c.gate_kind, c.approval_card, ta.task_id, ` +
|
|
553
|
+
`${jsonColumnText(d, "checkpoint", PARK_ROW_PENDING_ACTION)}, ${jsonColumnText(d, "checkpoint", PARK_ROW_CHECKPOINT_ID)} ` +
|
|
601
554
|
"FROM checkpoint c LEFT JOIN task_active ta ON ta.session_id = c.session_id WHERE c.status='pending'";
|
|
602
555
|
const { rows } = scope
|
|
603
556
|
? await this.db.query(`${base}${this.q(" AND c.scope=?", " AND c.scope=$1")} ORDER BY c.created_at_ms ASC`, [scope])
|
|
@@ -610,7 +563,7 @@ export class SqlCheckpointStore {
|
|
|
610
563
|
const toolCallId = r.tool_call_id ?? null;
|
|
611
564
|
const boundInputHash = r.bound_input_hash ?? null;
|
|
612
565
|
const ruleOffers = readRuleOffersCell(r.rule_suggestions);
|
|
613
|
-
const approvalCard = parkedApprovalCard(
|
|
566
|
+
const approvalCard = parkedApprovalCard({ kind: gateKind, approvalCard: r.approval_card ?? undefined });
|
|
614
567
|
return [{
|
|
615
568
|
sessionId: String(r.session_id),
|
|
616
569
|
...durableRowIdentity("approvals-queue", readCheckpointIdCell(r[PARK_ROW_CHECKPOINT_ID.as]), r.token),
|
|
@@ -639,7 +592,7 @@ export class SqlCheckpointStore {
|
|
|
639
592
|
for (const r of rows) {
|
|
640
593
|
const cp = refusing("a checkpoint nobody can resume", () => decodeCheckpointColumn(r.checkpoint, `in the ${scope} scheduler view`));
|
|
641
594
|
cp.status = r.status;
|
|
642
|
-
out.push(summarizeCheckpoint(cp));
|
|
595
|
+
out.push(summarizeCheckpoint(cp, (sentence) => recordFailOpen("server.checkpoint.inbox-risk-axes-damaged", withoutCheckpointToken(sentence, cp.token))));
|
|
643
596
|
}
|
|
644
597
|
return out;
|
|
645
598
|
}
|
|
@@ -64,7 +64,7 @@ export declare const TIDB_DEVICE_STATEMENTS: readonly string[];
|
|
|
64
64
|
/** {@link TIDB_DEVICE_STATEMENTS} 的遍历壳(集成测试用;生产装配由中央 ensureSchema 展开同一份数组)。 */
|
|
65
65
|
export declare function ensureTiDBDeviceSchema(pool: MySqlPool): Promise<void>;
|
|
66
66
|
type PgQuery = (sql: string, params?: unknown[]) => Promise<unknown>;
|
|
67
|
-
/**
|
|
67
|
+
/** [ref]:本 store 的索引**声明**(两方言共用一份)。PG 侧由下面的 `ensurePgDeviceSchema` 应用,MySQL 侧由 `tidb-pool.ts` 的中央 `ensureSchema` 应用(那里内联 `KEY` 已在 `CREATE TABLE` 里 ⇒ 新建库探到即零 DDL,存量库缺谁补谁)。加索引以外的 schema 变更仍归运维,见 `plugins/ensure-index.ts` 头注。 */
|
|
68
68
|
export declare const DEVICE_INDEXES: readonly IndexSpec[];
|
|
69
69
|
export declare function ensurePgDeviceSchema(q: PgQuery): Promise<void>;
|
|
70
70
|
/**
|
|
@@ -141,7 +141,7 @@ export declare class SqlDeviceStore implements DeviceStore {
|
|
|
141
141
|
* 前提写在 {@link SqlTxConn.begin} 的 @contract txn.read-semantics。这把锁在 `devices` 表上,与下面
|
|
142
142
|
* 被插入的 `device_session` 行不是同一行。
|
|
143
143
|
*
|
|
144
|
-
* 🔴 形 B · cas-insert(
|
|
144
|
+
* 🔴 形 B · cas-insert([ref] / [ref])—— 本站点是全仓 `INSERT IGNORE` 的**正当用法**:
|
|
145
145
|
* `INSERT IGNORE` / `ON CONFLICT DO NOTHING` 的 affected(1/0)是引擎对「谁赢」的**权威**回答,而
|
|
146
146
|
* `ON DUPLICATE KEY UPDATE pk = pk` 的 affected 新行/既有行都是 1、分不出赢家 ⇒ 这里换不得动词。
|
|
147
147
|
* 代价必须付清:**同一事务此后不得对被插入的那一行做加锁读**。InnoDB 下撞重复键的 IGNORE 在既有行
|
|
@@ -156,13 +156,13 @@ export declare class SqlDeviceStore implements DeviceStore {
|
|
|
156
156
|
*/
|
|
157
157
|
bindSession(input: BindSessionInput): Promise<BindSessionResult>;
|
|
158
158
|
/**
|
|
159
|
-
* 首绑 CAS 的**输家观察**(形 B 的后半,
|
|
159
|
+
* 首绑 CAS 的**输家观察**(形 B 的后半,[ref])—— 独立事务,与那次 `INSERT IGNORE` 无锁关系。
|
|
160
160
|
*
|
|
161
161
|
* 🔴 `FOR UPDATE`(**真库红修**,2026-08-28 双库跑当场抓到,mock 抓不到):TiDB 的悲观事务里**普通
|
|
162
162
|
* SELECT 仍是快照读**(读的是本事务 start_ts 的视图),只有加锁读才是当前读。放在新事务里读同样要
|
|
163
163
|
* 这把锁 —— 新事务的 start_ts 虽在赢家提交之后,但「读的是不是当前」这条判据不该靠时序巧合来满足。
|
|
164
164
|
* 与旧形的**唯一**差别:此刻我们手上没有那一行的 S 锁,于是这把 X 是**直接取**的,不是升级 ⇒ 两个
|
|
165
|
-
* 并发输家不会互等(
|
|
165
|
+
* 并发输家不会互等([ref] 的死锁形正是那次升级)。
|
|
166
166
|
*
|
|
167
167
|
* 行不在 = 赢家的绑定在这一瞬被 `unbindSession` 删了(真实可能,不是不变量破)。这仍然是**响亮**的:
|
|
168
168
|
* 首绑既没成、也说不出冲突对象,折成任何一种业务回执都是撒谎([ref]:未知失败不伪装成正常拒绝)。
|
|
@@ -189,12 +189,13 @@ export declare class SqlDeviceStore implements DeviceStore {
|
|
|
189
189
|
/**
|
|
190
190
|
* 审计列表。
|
|
191
191
|
*
|
|
192
|
-
* 🔴 **一行读不出形 ⇒ 整页拒,刻意不做逐行隔离**(
|
|
192
|
+
* 🔴 **一行读不出形 ⇒ 整页拒,刻意不做逐行隔离**([ref] 修复验证轮,主会话裁定后入档):方向由设计
|
|
193
193
|
* §2「失败方向 = 拒(fail-closed),全店同向」定。逐行隔离(坏行跳过 / 占位)在**审计**面上尤其危险 ——
|
|
194
194
|
* 它把「这一页少了一条」变得和「本来就没有那一条」同形,而审计面的全部意义就是「发生过的事都在」。
|
|
195
195
|
* 一页 5xx 是响亮的运维事件,一条静默消失不是。
|
|
196
196
|
*
|
|
197
|
-
* ⇒
|
|
197
|
+
* ⇒ 存量库里旧写腿留下的坏字节(JSON 文本 `null`)7.93.5 起由启动期一次性迁移清过、窗关后已删码,读侧不容忍:
|
|
198
|
+
* 跳过了那些版本直接升的库,含这种行的那一页读不出来,拒句点名行 id,出路是运维把那些行的 `detail` 置成 SQL NULL(MIGRATION 写了语句)。
|
|
198
199
|
*/
|
|
199
200
|
listAudit(filter?: ListAuditFilter): Promise<DeviceAuditRow[]>;
|
|
200
201
|
}
|