@sema-agent/server 7.133.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 +221 -0
- package/README.md +2 -2
- package/README.zh-CN.md +2 -2
- package/USAGE.md +222 -36
- package/deploy/sema-up/README.md +16 -0
- package/deploy/sema-up/chart/Chart.yaml +1 -1
- package/deploy/sema-up/chart/templates/NOTES.txt +15 -0
- package/deploy/sema-up/chart/templates/_helpers.tpl +129 -0
- package/deploy/sema-up/chart/templates/sealed-key.yaml +24 -0
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +14 -0
- package/deploy/sema-up/chart/templates/server.yaml +14 -0
- package/deploy/sema-up/chart/values-full-single.yaml +5 -1
- package/deploy/sema-up/chart/values.yaml +34 -0
- package/dist/adoption/plan.d.ts +1 -1
- package/dist/approval-ask-audit-store.d.ts +25 -25
- package/dist/approval-ask-machine.d.ts +2 -2
- package/dist/approval-card.d.ts +66 -154
- package/dist/approval-card.js +33 -52
- package/dist/approval-content-kind.d.ts +26 -6
- package/dist/approval-content-kind.js +23 -3
- package/dist/approval-deny-reasons.d.ts +1 -1
- package/dist/approval-gate-currency.d.ts +91 -0
- package/dist/approval-gate-currency.js +120 -0
- 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 +14 -8
- package/dist/approval.js +35 -16
- 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 +7 -2
- package/dist/boot/coordinators.js +8 -5
- 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 +2 -0
- package/dist/boot/leader.js +2 -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/read-deny-anchor-audit.js +2 -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 +29 -16
- package/dist/boot/runner-deps.js +12 -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.d.ts +4 -3
- package/dist/boot/stage-06-runners.js +15 -4
- package/dist/boot/stage-07-capability-layer.d.ts +2 -1
- package/dist/boot/stage-08-reapers.d.ts +2 -1
- package/dist/boot/stage-09-leader.d.ts +2 -1
- package/dist/boot/stage-09-leader.js +2 -2
- package/dist/boot/stage-10-http-server.d.ts +2 -1
- package/dist/boot/stage-10-http-server.js +2 -1
- package/dist/boot/stores.d.ts +8 -0
- package/dist/boot/stores.js +10 -13
- package/dist/boot/web-admin.d.ts +21 -15
- package/dist/boot/web-admin.js +16 -12
- package/dist/boot/workflow-orchestration.js +2 -9
- package/dist/brain.d.ts +11 -11
- package/dist/budget.d.ts +4 -4
- package/dist/budget.js +5 -1
- package/dist/caller-text-echo.d.ts +2 -0
- package/dist/caller-text-echo.js +2 -1
- package/dist/canonical-json.d.ts +2 -41
- package/dist/canonical-json.js +2 -13
- 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 +2 -2
- package/dist/capabilities/composite-members.js +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/mcp-probe.js +2 -2
- 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 +27 -24
- package/dist/capability-facts.js +18 -20
- package/dist/center-config-tier.d.ts +1 -1
- package/dist/center-credential.d.ts +4 -4
- package/dist/checkpoint-ctx-seal-m28.d.ts +42 -0
- package/dist/checkpoint-ctx-seal-m28.js +19 -0
- 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/field-conflict.d.ts +2 -1
- package/dist/field-conflict.js +1 -0
- package/dist/file-history-capture.d.ts +9 -9
- package/dist/file-history-disclosure.d.ts +50 -9
- package/dist/file-history-disclosure.js +8 -13
- package/dist/fleet/drain-entry.d.ts +2 -2
- package/dist/fleet/fleet-bus.d.ts +26 -14
- package/dist/fleet/fleet-bus.js +6 -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 +38 -20
- 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 +28 -5
- package/dist/http/approval-sweeps.d.ts +1 -1
- package/dist/http/approval-sweeps.js +5 -2
- package/dist/http/checkpoint-ctx.d.ts +183 -2
- package/dist/http/checkpoint-ctx.js +197 -2
- package/dist/http/dispatch.d.ts +3 -3
- package/dist/http/dispatch.js +3 -3
- package/dist/http/durable-run-leg.js +7 -5
- package/dist/http/idempotency.d.ts +4 -4
- package/dist/http/idempotency.js +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 +39 -13
- package/dist/http/principal-gate.js +30 -6
- package/dist/http/readiness.d.ts +1 -1
- package/dist/http/refusal-body.d.ts +12 -0
- package/dist/http/refusal-body.js +11 -0
- package/dist/http/request-guards.d.ts +4 -13
- package/dist/http/request-guards.js +4 -17
- package/dist/http/resume-ctx-read.d.ts +53 -6
- package/dist/http/resume-ctx-read.js +26 -3
- package/dist/http/resume-legs.d.ts +5 -4
- package/dist/http/resume-legs.js +47 -29
- package/dist/http/route-ctx.d.ts +29 -38
- package/dist/http/route-table.d.ts +9 -9
- package/dist/http/routes/agents-roster.d.ts +1 -1
- package/dist/http/routes/agents-roster.js +2 -3
- package/dist/http/routes/approvals-assistant.d.ts +5 -5
- package/dist/http/routes/approvals-assistant.js +91 -17
- 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 +6 -6
- package/dist/http/routes/diagnostics.js +1 -1
- package/dist/http/routes/fleet.d.ts +1 -1
- package/dist/http/routes/fleet.js +5 -4
- 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/memory-origin.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/rules.js +4 -4
- package/dist/http/routes/runs.js +44 -11
- package/dist/http/routes/session-sync.d.ts +3 -2
- package/dist/http/routes/session-sync.js +109 -62
- package/dist/http/routes/sessions-list.d.ts +1 -1
- package/dist/http/routes/sessions-list.js +4 -5
- package/dist/http/routes/sessions.js +34 -48
- package/dist/http/routes/tasks.d.ts +1 -1
- package/dist/http/routes/tasks.js +21 -16
- package/dist/http/routes/trace-usage.d.ts +1 -1
- package/dist/http/routes/trace-usage.js +7 -9
- 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 +39 -33
- package/dist/http/server.js +5 -2
- 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.d.ts +4 -3
- package/dist/http/submit-ctx.js +19 -3
- 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 +35 -24
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- 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 +9 -5
- package/dist/leader/wire.js +8 -7
- package/dist/list-entry-display.d.ts +1 -1
- package/dist/lsp-evict.d.ts +1 -1
- package/dist/main.js +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-origin-fence.js +2 -2
- 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-compat.d.ts +1 -1
- 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/prompt-manifest.d.ts +19 -8
- package/dist/observability/prompt-manifest.js +9 -8
- 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/observability/tool-trace.js +8 -9
- 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/orchestration/workflow-park-decision.d.ts +1 -1
- package/dist/orchestration/workflow-park-decision.js +1 -0
- package/dist/outbound-dispatcher.d.ts +4 -4
- package/dist/parent-watch.d.ts +4 -4
- package/dist/parked-decide.d.ts +20 -20
- package/dist/parked-decide.js +8 -5
- 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 +3 -25
- package/dist/permission-rule-vocab.js +0 -13
- 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/approval-payload-fingerprint.d.ts +14 -6
- package/dist/plugins/approval-payload-fingerprint.js +1 -1
- 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 +24 -33
- package/dist/plugins/caching-session-store.js +8 -19
- 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 +66 -67
- package/dist/plugins/checkpoint-store-sql.js +100 -103
- 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 +23 -12
- package/dist/plugins/local-checkpoint-store.js +29 -4
- package/dist/plugins/local-session-store.d.ts +44 -45
- package/dist/plugins/local-session-store.js +42 -52
- package/dist/plugins/local-session-window.d.ts +12 -6
- package/dist/plugins/local-session-window.js +1 -17
- 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 +76 -39
- package/dist/plugins/one-time-migrations.js +127 -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 +16 -19
- package/dist/plugins/permission-rule-store-sql.d.ts +38 -4
- package/dist/plugins/permission-rule-store-sql.js +74 -31
- 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 +9 -21
- package/dist/plugins/pg-session-storage.js +51 -42
- package/dist/plugins/remote-env-adb.d.ts +10 -10
- package/dist/plugins/remote-env-device.d.ts +22 -14
- package/dist/plugins/remote-env-device.js +28 -16
- 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.d.ts +11 -0
- package/dist/plugins/session-ownership.js +11 -0
- package/dist/plugins/session-placement.d.ts +12 -14
- package/dist/plugins/session-placement.js +2 -15
- 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 +17 -27
- package/dist/plugins/tidb-session-store.js +52 -42
- 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-tool-axes.d.ts +12 -0
- package/dist/request-tool-axes.js +20 -0
- 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/run-local.js +1 -0
- package/dist/runs.d.ts +15 -12
- package/dist/runs.js +19 -4
- 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 +34 -2
- package/dist/sealed-key.js +55 -1
- package/dist/security.d.ts +31 -32
- 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 +19 -12
- package/dist/session-error-wire.js +4 -1
- 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 +38 -11
- package/dist/session-sync-kernel.js +10 -0
- 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 +38 -5
- package/dist/task-cwd.d.ts +7 -88
- package/dist/task-cwd.js +2 -15
- package/dist/task-mcp.d.ts +14 -10
- package/dist/task-mcp.js +39 -12
- package/dist/task-settings.d.ts +34 -18
- package/dist/task-settings.js +34 -4
- 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 +273 -228
- package/dist/tool-approval.js +125 -47
- package/dist/tool-rule-names.d.ts +7 -1
- package/dist/trace/core-keyset-guard.d.ts +15 -9
- 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 +40 -1
- package/dist/trace/exit-seat.js +46 -14
- package/dist/trace/ledger-events.d.ts +6 -4
- package/dist/trace/ledger-sink.d.ts +1 -1
- package/dist/trace/model-segment.d.ts +3 -3
- package/dist/trace/project.d.ts +65 -46
- package/dist/trace/project.js +49 -5
- package/dist/trace/redact.d.ts +44 -27
- package/dist/trace/redact.js +343 -73
- package/dist/trace/self-minted-wire.d.ts +39 -14
- package/dist/trace/self-minted-wire.js +9 -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 +9 -3
- package/dist/trace/wire-projection-faces.js +7 -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 +29 -4
- package/dist/web-admin-client/skills-mcp.js +31 -4
- package/dist/web-admin-client/types.d.ts +17 -10
- 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 +35 -2
- package/scripts/drain-check.mysql.sql +22 -2
- package/scripts/drain-check.pg.sql +22 -2
- package/skills/loop.md +1 -1
- package/dist/mcp-tool-faces.d.ts +0 -69
- package/dist/mcp-tool-faces.js +0 -104
- package/dist/orchestration/workflow-journal-entry.js +0 -27
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RuleBehavior } from "@sema-agent/core";
|
|
2
2
|
/**
|
|
3
3
|
* `PersistedRuleTool` **不再是闭词表**(core 7.9.0 / [ref]):工具名自 core 的**目录**派生
|
|
4
4
|
* (`pathTarget` 声明 ⇒ 路径文法;`Bash` ⇒ 命令文法),型是 `string`。于是本文件对它的处置从
|
|
@@ -10,16 +10,7 @@ import type { RuleApprovalRecord, RuleBehavior } from "@sema-agent/core";
|
|
|
10
10
|
*/
|
|
11
11
|
export declare function isPersistedRuleTool(name: string): boolean;
|
|
12
12
|
/**
|
|
13
|
-
* `
|
|
14
|
-
* 唯一拼写)/ `wildcard`([ref] 尾 space-star,单命令体上与 prefix **同一谓词**,建议面自此铸它)/
|
|
15
|
-
* `subpath`(Read 目录形,永不容纳任何命令)/ `path`(core 7.9.0 [ref]:路径族 deny/ask/allow 的模式文法
|
|
16
|
-
* —— `//abs`、`~/`、`/root-relative`、cwd 相对,段内 `*`、跨段 `**`)/ `name` / `name_prefix`(core 7.43.0 #1318:`Skill` 的名字文法 ——
|
|
17
|
-
* `Skill(<名>)` 精确、`Skill(<前缀>:*)` 名字前缀、无词界;技能卡的建议行 `match: "name"`)/ `host` / `subdomain`(core 7.49.0 #1365:
|
|
18
|
-
* `WebFetch(domain:<host>)` 精确主机、`WebFetch(domain:*.<域>)` 域下每个主机 —— 只有 allow 形)。
|
|
19
|
-
*/
|
|
20
|
-
export declare const PERSISTED_RULE_MATCHES: readonly ["exact", "prefix", "wildcard", "subpath", "path", "name", "name_prefix", "host", "subdomain"];
|
|
21
|
-
/**
|
|
22
|
-
* S-511 —— `RuleBehavior` 每一员在**无同意仪式的直接写口**(`POST /v1/rules`)上的逐员表态。
|
|
13
|
+
* [ref] —— `RuleBehavior` 每一员在**无同意仪式的直接写口**(`POST /v1/rules`)上的逐员表态。
|
|
23
14
|
*
|
|
24
15
|
* 为什么是一张**表**而不是一句 `behavior !== "allow"`:后者对 core 加员是**静默放行** —— 将来多一个
|
|
25
16
|
* 放宽方向的态,它会直接从这条收紧口写进店,而没有任何一行代码会红。`Record<RuleBehavior, boolean>`
|
|
@@ -44,26 +35,13 @@ export type DirectWritableRuleBehavior = {
|
|
|
44
35
|
}[RuleBehavior];
|
|
45
36
|
/** 判别式谓词(收窄到 {@link DirectWritableRuleBehavior}):端点判过之后,`allow` 在**类型上**到不了写家。 */
|
|
46
37
|
export declare function isDirectWritableRuleBehavior(behavior: RuleBehavior): behavior is DirectWritableRuleBehavior;
|
|
47
|
-
/** [ref] §2.3 B3:batch offer 成员的判别位(`command` = 历史逐段 Bash 规则;`directoryRead` = cd 段铸的目录只读授权)。 */
|
|
48
|
-
export declare const RULE_OFFER_BATCH_MEMBER_KINDS: readonly ["command", "directoryRead"];
|
|
49
|
-
/** [ref] §3.5:一段「为什么仍未被覆盖」的闭三词集(`redirection` 永久逐次 / `no_rule_form` 无可覆盖形 / `cap_overflow` 去重+帽挤出)。 */
|
|
50
|
-
export declare const UNCOVERED_SEGMENT_REASONS: readonly ["redirection", "no_rule_form", "cap_overflow"];
|
|
51
|
-
/** [ref] §3.3-5:卡编辑面的 breadth 警告码(记录 `edited.warnings` 存的就是这两个字面)。 */
|
|
52
|
-
export declare const EDITED_RULE_BREADTH_WARNING_CODES: readonly ["broad_prefix", "compound_prefix"];
|
|
53
|
-
/**
|
|
54
|
-
* [ref] §4.5 / [ref] §3.5 —— 审批记录的**形版本号**(core `RuleApprovalRecord.schema`,本批 3→4;[ref] 三态 behavior 进候选行)。
|
|
55
|
-
* 类型绑 core 的字面型:core 再升号 ⇒ 这里编译红,两只 durable 店(SQL 双方言 + File)的 stale 判别与写侧钉
|
|
56
|
-
* 同批随之;判别是**等式**(`!==`)不是下限 —— 旧号的行按 stale 信封交还(不迁移、不 widen、不丢行),
|
|
57
|
-
* pending 卡短命,重触发即取新卡(B7/B8 既诺)。
|
|
58
|
-
*/
|
|
59
|
-
export declare const RULE_APPROVAL_RECORD_SCHEMA: RuleApprovalRecord["schema"];
|
|
60
38
|
/**
|
|
61
39
|
* 一次撤销之后「这条规则还活着吗」的**三词闭集**(core 7.25.0 [ref]:`RemovalLiveness`)。
|
|
62
40
|
* `"yes"` = 店说它还在(add-wins:撤销期间又落了一次新批准);`"no"` = 店说它不在了;
|
|
63
41
|
* `"unknown"` = **回答这一问的那次读回没做成** —— 这个域唯一不肯说的那句话是「看不见 ⇒ 没有」,
|
|
64
42
|
* 第三个词就是它的反面。
|
|
65
43
|
*
|
|
66
|
-
* 🔴 **型从 core 的包根导出接过来,本仓零抄**(core 7.26.0
|
|
44
|
+
* 🔴 **型从 core 的包根导出接过来,本仓零抄**(core 7.26.0 [ref] ⓐ:`RemovalLiveness` 随请托上了导出面)。
|
|
67
45
|
* 上一版是 `Extract<RemoveResult, {status:"removed"}>["stillLive"]` —— 那是派生而非手抄(值不会漂),但它把
|
|
68
46
|
* 一只**独立的闭集**寄生在某一个臂的形状上:core 哪天给 `removed` 臂改名、或让这只词表先在别的臂上落地,
|
|
69
47
|
* 派生式就会指向一个与词表无关的东西。现在两者同名同源。
|
|
@@ -2,9 +2,6 @@ import { ruleToolGrammarOf } from "@sema-agent/core";
|
|
|
2
2
|
export function isPersistedRuleTool(name) {
|
|
3
3
|
return ruleToolGrammarOf(name) !== undefined;
|
|
4
4
|
}
|
|
5
|
-
export const PERSISTED_RULE_MATCHES = ["exact", "prefix", "wildcard", "subpath", "path", "name", "name_prefix", "host", "subdomain"];
|
|
6
|
-
const MATCHES_PIN = true;
|
|
7
|
-
void MATCHES_PIN;
|
|
8
5
|
export const DIRECT_RULE_WRITE_ADMITS = {
|
|
9
6
|
allow: false,
|
|
10
7
|
deny: true,
|
|
@@ -13,14 +10,4 @@ export const DIRECT_RULE_WRITE_ADMITS = {
|
|
|
13
10
|
export function isDirectWritableRuleBehavior(behavior) {
|
|
14
11
|
return DIRECT_RULE_WRITE_ADMITS[behavior];
|
|
15
12
|
}
|
|
16
|
-
export const RULE_OFFER_BATCH_MEMBER_KINDS = ["command", "directoryRead"];
|
|
17
|
-
const MEMBER_KINDS_PIN = true;
|
|
18
|
-
void MEMBER_KINDS_PIN;
|
|
19
|
-
export const UNCOVERED_SEGMENT_REASONS = ["redirection", "no_rule_form", "cap_overflow"];
|
|
20
|
-
const REASONS_PIN = true;
|
|
21
|
-
void REASONS_PIN;
|
|
22
|
-
export const EDITED_RULE_BREADTH_WARNING_CODES = ["broad_prefix", "compound_prefix"];
|
|
23
|
-
const WARNING_CODES_PIN = true;
|
|
24
|
-
void WARNING_CODES_PIN;
|
|
25
|
-
export const RULE_APPROVAL_RECORD_SCHEMA = 4;
|
|
26
13
|
//# sourceMappingURL=permission-rule-vocab.js.map
|
|
@@ -107,7 +107,7 @@ export interface AdoptionLogStore {
|
|
|
107
107
|
/** MySQL 协议方言的建表语句(展开进 tidb-pool 的中央 `SCHEMA_STATEMENTS`,与 approval-ask 同姿势:
|
|
108
108
|
* 跟着中央 ensureSchema 在 named-lock 的那条 conn 上建,不绕开 DDL 串行化)。 */
|
|
109
109
|
export declare const TIDB_ADOPTION_LOG_STATEMENTS: readonly string[];
|
|
110
|
-
/**
|
|
110
|
+
/** [ref]:本 store 的索引**声明**(两方言共用一份)。PG 侧由下面的 `ensurePgAdoptionLogSchema` 应用,MySQL 侧由 `tidb-pool.ts` 的中央 `ensureSchema` 应用(那里内联 `KEY` 已在 `CREATE TABLE` 里 ⇒ 新建库探到即零 DDL,存量库缺谁补谁)。加索引以外的 schema 变更仍归运维,见 `plugins/ensure-index.ts` 头注。 */
|
|
111
111
|
export declare const ADOPTION_LOG_INDEXES: readonly IndexSpec[];
|
|
112
112
|
/** PostgreSQL 孪生(由 `ensurePgSchema` 在 advisory lock 的那条 client 上调用)。 */
|
|
113
113
|
export declare function ensurePgAdoptionLogSchema(q: (text: string, params?: unknown[]) => Promise<unknown>): Promise<void>;
|
|
@@ -174,7 +174,14 @@ export declare class FileApprovalAskStore implements ApprovalAskStore {
|
|
|
174
174
|
* 「没带编辑」的记录,而活路径那一侧是抛。编码抛 ⇒ 账本一个字节没写、内核一个字节没动(与内核自己的
|
|
175
175
|
* 「先编码、编码成功才一次性提交」同一条原子性)。
|
|
176
176
|
*/
|
|
177
|
-
|
|
177
|
+
/**
|
|
178
|
+
* 🔴 [ref] —— **出域的一次决议不落账本**。作用域的属主维(`owner`,判据 {@link askRowCarriesOwner})不在记录上:行此刻不带着门判过的那位属主
|
|
179
|
+
* ⇒ 内核上这一笔必输、零写(读钟也在判定之后,不开账本窗)⇒ 没有要重放的东西,直调内核拿它的输者答案(与留存两动词「空的一次不落」同一条先例)。
|
|
180
|
+
* 判定、落账、内核调用都在同一个同步前缀里,其间行不可能换属主。于是**落了账的每一条决议都在域内**,重放按行自己的属主喂属主维
|
|
181
|
+
* ({@link FileApprovalAskStore.replayOp})—— 记录形一个字节不变:升级前写下的账本、升级后写下的账本、降级回老版本时老读者读新账本,三者同读,
|
|
182
|
+
* 零迁移、零双读。
|
|
183
|
+
*/
|
|
184
|
+
decideAsk(askId: string, batchId: string, owner: string | null, decision: DecideAskInput): Promise<DecideResult>;
|
|
178
185
|
claimTerminal(askId: string, batchId: string, intent: AskTerminalClaimIntent, opts?: AskTerminalClaimOpts): Promise<AskTerminalClaimOutcome>;
|
|
179
186
|
expireAsk(askId: string, batchId: string): Promise<ExpireResult>;
|
|
180
187
|
bindBatch(batchId: string, askId: string, gate: BindGateInput): Promise<BindResult>;
|
|
@@ -5,6 +5,7 @@ import { replayJsonlSkipping } from "../observability/corrupt-read-seat.js";
|
|
|
5
5
|
import { recordFailOpen } from "../observability/fail-open.js";
|
|
6
6
|
import { StoreBootRefusalError } from "./store-contracts.js";
|
|
7
7
|
import { InMemoryApprovalAskStore, encodeDecideUpdatedInput, encodeStoreJsonPayload } from "./approval-ask-store-memory.js";
|
|
8
|
+
import { askRowCarriesOwner } from "./approval-ask-store-sql.js";
|
|
8
9
|
export const APPROVAL_ASK_DIR = "approval-asks";
|
|
9
10
|
export const APPROVAL_ASK_JOURNAL_FILE = "asks.jsonl";
|
|
10
11
|
export const ASK_JOURNAL_COMPACT_MIN_RECORDS = 2_000;
|
|
@@ -187,7 +188,7 @@ export class FileApprovalAskStore {
|
|
|
187
188
|
case "transitionAsk":
|
|
188
189
|
return this.core.transitionAsk(rec.askId, rec.from, rec.to, rec.patch);
|
|
189
190
|
case "decideAsk":
|
|
190
|
-
return this.core.decideAsk(rec.askId, rec.batchId, rec.decision);
|
|
191
|
+
return this.core.decideAsk(rec.askId, rec.batchId, this.core.peekAsk(rec.askId)?.owner ?? null, rec.decision);
|
|
191
192
|
case "claimTerminal":
|
|
192
193
|
return this.core.claimTerminal(rec.askId, rec.batchId, rec.intent, rec.cause !== undefined ? { cause: rec.cause } : undefined);
|
|
193
194
|
case "claimTerminalRefuse":
|
|
@@ -220,9 +221,11 @@ export class FileApprovalAskStore {
|
|
|
220
221
|
async transitionAsk(askId, from, to, patch) {
|
|
221
222
|
return this.write({ op: "transitionAsk", askId, from, to, patch }, (c) => this.core.transitionAsk(c.askId, c.from, c.to, c.patch));
|
|
222
223
|
}
|
|
223
|
-
async decideAsk(askId, batchId, decision) {
|
|
224
|
+
async decideAsk(askId, batchId, owner, decision) {
|
|
224
225
|
const journalled = decision.updatedInput === undefined ? decision : { ...decision, updatedInput: encodeDecideUpdatedInput(decision.updatedInput) };
|
|
225
|
-
|
|
226
|
+
if (!askRowCarriesOwner(this.core.peekAsk(askId), owner))
|
|
227
|
+
return this.core.decideAsk(askId, batchId, owner, journalled);
|
|
228
|
+
return this.write({ op: "decideAsk", askId, batchId, decision: journalled }, (c) => this.core.decideAsk(c.askId, c.batchId, owner, c.decision));
|
|
226
229
|
}
|
|
227
230
|
async claimTerminal(askId, batchId, intent, opts) {
|
|
228
231
|
switch (intent) {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Node 单线程下这就是天然原子:`Promise.all` 发起的并发调用不会在方法体内部交错执行,与
|
|
5
5
|
* `approval-ask-store-sql.ts` 的 CAS UPDATE 语义逐字段一致(SQL twin 对拆套件的基准就是这份实现)。
|
|
6
6
|
*
|
|
7
|
-
* 🔴 **
|
|
7
|
+
* 🔴 **[ref]:本类同时是 `FileApprovalAskStore` 的内核**(local 车道的持久形不再是「第二份手抄」——
|
|
8
8
|
* 它把本类**原样**包起来,每次写前先把**调用本身**落 JSONL、重放时用同一只内核重放同一串调用)。
|
|
9
9
|
* 为此本类多了这几件、且**只**多这几件(全是数据面,零转移判定):
|
|
10
10
|
* · {@link InMemoryApprovalAskStore.constructor} 的可注入钟 `now` —— 五个动词(decideAsk / claimTerminal /
|
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
* File 形里另写一套「哪些行还算数」的判据 —— 那才是第二份手抄。
|
|
19
19
|
* · {@link InMemoryApprovalAskStore.planReapSettledAsks} / {@link InMemoryApprovalAskStore.planReapEmptyBatches} —— 两只留存动词的
|
|
20
20
|
* **纯读选择**(删哪些行)。File 形据它判「这一次有没有东西可删」,空的一次不落账本;删除本身仍是接口动词,与选择共用这一只。
|
|
21
|
+
* · {@link InMemoryApprovalAskStore.peekAsk} —— 一行的**同步**点读(纯读,零判定)。File 形在写口的同步前缀里据它判「这次决议在不在
|
|
22
|
+
* 属主域内」(出域的一次不落账本)、重放时据它喂行自己的属主([ref],理由在 File 形的 `decideAsk`)。
|
|
21
23
|
*
|
|
22
24
|
* 行为口径与 `SqlApprovalAskStore` 逐条对齐:
|
|
23
25
|
* - ensureAsk 幂等 upsert(ask_id 已在 ⇒ 返回既有行,不改写;batch 行若不存在则以 OPEN 补齐)。
|
|
@@ -35,7 +37,7 @@ import type { AskCallCoordinate, AskDecision, AskRow, AskTerminalClaimIntent, As
|
|
|
35
37
|
* 循环引用 ⇒ `JSON.stringify` 抛(两侧同抛);顶层函数 / `undefined` ⇒ `stringify` 交出 `undefined`
|
|
36
38
|
* (「编出来什么都不是」)⇒ 本函数**响亮拒**,而不是让它在库里变成 NULL、在内存里变成活函数。
|
|
37
39
|
*
|
|
38
|
-
* 🔴 为什么必须是一只**导出**函数而不是 `decideAsk` 里的内联段(
|
|
40
|
+
* 🔴 为什么必须是一只**导出**函数而不是 `decideAsk` 里的内联段([ref]):`FileApprovalAskStore` 要在
|
|
39
41
|
* **落日志之前**把这一步做掉 —— 它的日志本身就是 JSON,而 `JSON.stringify` 对顶层函数是**静默丢键**
|
|
40
42
|
* 不是抛。内联在 decideAsk 里的话,File 形只能在自己那侧再写一遍同样的判定(第二份手抄),或者
|
|
41
43
|
* 让「活路径抛 / 重放路径成功 DECIDE」这条真分岔活下来。
|
|
@@ -49,7 +51,7 @@ export declare function encodeStoreJsonPayload(what: string, value: unknown): un
|
|
|
49
51
|
/** [ref] `updatedInput` 的入店编码 = 上面那只的一次具名调用(词固定在一处,两 twin 与 File 形账本共用)。 */
|
|
50
52
|
export declare function encodeDecideUpdatedInput(updatedInput: unknown): unknown;
|
|
51
53
|
/** {@link InMemoryApprovalAskStore.exportRows} 的产出 / {@link InMemoryApprovalAskStore.importRows} 的入参
|
|
52
|
-
* —— **纯行**,零判定。压实(
|
|
54
|
+
* —— **纯行**,零判定。压实([ref] File 形)与测试的状态对拆共用。 */
|
|
53
55
|
export interface ApprovalAskRowsSnapshot {
|
|
54
56
|
asks: readonly AskRow[];
|
|
55
57
|
batches: readonly BatchRow[];
|
|
@@ -57,20 +59,22 @@ export interface ApprovalAskRowsSnapshot {
|
|
|
57
59
|
export declare class InMemoryApprovalAskStore implements ApprovalAskStore {
|
|
58
60
|
private readonly asks;
|
|
59
61
|
private readonly batches;
|
|
60
|
-
/** 店钟(
|
|
62
|
+
/** 店钟([ref])。缺省 = 本进程墙钟,与本类落地以来逐字同值;File 形注入一只**钉住的**钟,让
|
|
61
63
|
* 「同一串调用重放出同一份状态」成立。读钟纪律见类顶注(只许在同步前缀里读)。 */
|
|
62
64
|
private readonly now;
|
|
63
65
|
constructor(opts?: {
|
|
64
66
|
now?: () => number;
|
|
65
67
|
});
|
|
66
68
|
/**
|
|
67
|
-
*
|
|
69
|
+
* [ref]:整本行快照(压实用)。**深拷到行级**(与每个读口交出 `{ ...row }` 同一条纪律:交出去的行
|
|
68
70
|
* 不再是店内那一份,调用方改它碰不到店)。行内的 `cardJson`/`updatedInput`/`decisionActor` 仍是引用 ——
|
|
69
71
|
* 与 `getAsk`/`listByState` 逐字同宽,不在这一口上单独加深拷(那会让快照口与读口对同一份 blob 给出
|
|
70
72
|
* 两种可变性)。
|
|
71
73
|
*/
|
|
72
74
|
exportRows(): ApprovalAskRowsSnapshot;
|
|
73
|
-
/**
|
|
75
|
+
/** [ref]:一行的**同步**点读(拷贝;纯读,零判定)—— File 形在写口的同步前缀里用它(见类顶注)。 */
|
|
76
|
+
peekAsk(askId: string): AskRow | null;
|
|
77
|
+
/** [ref]:把快照里的行**原样**装回两张 Map(同键覆盖)。零谓词、零状态机 —— 它不是一条转移,是重放
|
|
74
78
|
* 的起手状态。压实产物与本口是一对:压实写出 {@link exportRows} 的行,启动时由本口装回。 */
|
|
75
79
|
importRows(snapshot: {
|
|
76
80
|
asks?: readonly AskRow[];
|
|
@@ -78,7 +82,7 @@ export declare class InMemoryApprovalAskStore implements ApprovalAskStore {
|
|
|
78
82
|
}): void;
|
|
79
83
|
ensureAsk(row: NewAskRow): Promise<EnsureAskResult>;
|
|
80
84
|
transitionAsk(askId: string, from: AskState, to: AskState, patch: AskTransitionPatch): Promise<boolean>;
|
|
81
|
-
decideAsk(askId: string, batchId: string, decision: DecideAskInput): Promise<DecideResult>;
|
|
85
|
+
decideAsk(askId: string, batchId: string, owner: string | null, decision: DecideAskInput): Promise<DecideResult>;
|
|
82
86
|
/**
|
|
83
87
|
* [ref] 原子终局 claim(接口契约见 SQL 侧 {@link ApprovalAskStore.claimTerminal})。**委托形**:CAS 走
|
|
84
88
|
* 既有 verb(expire ⇒ `this.expireAsk`;cancel ⇒ `this.transitionAsk(STREAM_PENDING→VOID)`)——律 2
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ASK_TERMINAL, canAskTransition } from "../approval-ask-machine.js";
|
|
2
2
|
import { APPROVAL_ENDING_CAUSES } from "../approval-deny-reasons.js";
|
|
3
|
-
import { askRowOnCall, assertDecideSettledBy, assertIdempotencyKeyShape, assertIntegralEpochMs, assertReapBounds, ApprovalAskReadAbortedError, claimTargetState, POLICY_REFUSAL_DECISION, projectAskTerminalClaimTruth } from "./approval-ask-store-sql.js";
|
|
3
|
+
import { askRowCarriesOwner, askRowOnCall, assertDecideSettledBy, assertIdempotencyKeyShape, assertIntegralEpochMs, assertReapBounds, ApprovalAskReadAbortedError, claimTargetState, POLICY_REFUSAL_DECISION, projectAskTerminalClaimTruth, projectDecideReading } from "./approval-ask-store-sql.js";
|
|
4
4
|
function applyPatch(row, patch) {
|
|
5
5
|
if (patch.decision !== undefined)
|
|
6
6
|
row.decision = patch.decision;
|
|
@@ -41,6 +41,10 @@ export class InMemoryApprovalAskStore {
|
|
|
41
41
|
exportRows() {
|
|
42
42
|
return { asks: [...this.asks.values()].map((r) => ({ ...r })), batches: [...this.batches.values()].map((b) => ({ ...b })) };
|
|
43
43
|
}
|
|
44
|
+
peekAsk(askId) {
|
|
45
|
+
const row = this.asks.get(askId);
|
|
46
|
+
return row ? { ...row } : null;
|
|
47
|
+
}
|
|
44
48
|
importRows(snapshot) {
|
|
45
49
|
for (const r of snapshot.asks ?? [])
|
|
46
50
|
this.asks.set(r.askId, { ...r, settledBy: r.settledBy ?? null });
|
|
@@ -112,19 +116,18 @@ export class InMemoryApprovalAskStore {
|
|
|
112
116
|
row.updatedAtMs = patch.updatedAtMs;
|
|
113
117
|
return true;
|
|
114
118
|
}
|
|
115
|
-
async decideAsk(askId, batchId, decision) {
|
|
119
|
+
async decideAsk(askId, batchId, owner, decision) {
|
|
116
120
|
if (decision.idempotencyKey != null)
|
|
117
121
|
assertIdempotencyKeyShape(decision.idempotencyKey);
|
|
118
122
|
assertDecideSettledBy(decision);
|
|
119
|
-
const
|
|
123
|
+
const reading = (row) => projectDecideReading(row ? { ...row } : null, owner);
|
|
120
124
|
const batch = this.batches.get(batchId);
|
|
121
125
|
if (!batch || batch.state !== "OPEN") {
|
|
122
|
-
|
|
123
|
-
return { ok: false, reason: "batch_closed", row: row ? { ...row } : null };
|
|
126
|
+
return { ok: false, reason: "batch_closed", row: reading(this.asks.get(askId)) };
|
|
124
127
|
}
|
|
125
128
|
const ask = this.asks.get(askId);
|
|
126
|
-
if (!ask || ask.state !== "STREAM_PENDING" || ask.batchId !== batchId) {
|
|
127
|
-
return { ok: false, reason: "ask_not_pending", row: ask
|
|
129
|
+
if (!ask || ask.state !== "STREAM_PENDING" || ask.batchId !== batchId || !askRowCarriesOwner(ask, owner)) {
|
|
130
|
+
return { ok: false, reason: "ask_not_pending", row: reading(ask) };
|
|
128
131
|
}
|
|
129
132
|
if (decision.idempotencyKey != null) {
|
|
130
133
|
for (const [id, r] of this.asks) {
|
|
@@ -136,6 +139,7 @@ export class InMemoryApprovalAskStore {
|
|
|
136
139
|
let encodedUpdatedInput;
|
|
137
140
|
if (decision.updatedInput !== undefined)
|
|
138
141
|
encodedUpdatedInput = encodeDecideUpdatedInput(decision.updatedInput);
|
|
142
|
+
const now = this.now();
|
|
139
143
|
batch.rev += 1;
|
|
140
144
|
batch.updatedAtMs = now;
|
|
141
145
|
ask.state = "DECIDED";
|
|
@@ -82,8 +82,8 @@ export interface AskRow {
|
|
|
82
82
|
decisionActor: unknown | null;
|
|
83
83
|
decisionNote: string | null;
|
|
84
84
|
/**
|
|
85
|
-
* 🔴
|
|
86
|
-
* 不带这一格的 outcome 逐字按 `"human"` 读),非 null = 宿主自报的那个词(
|
|
85
|
+
* 🔴 [ref]([ref] 的持久半场)—— 这条决议的**结算来源**:`null` = 一个人答的(= 缺席律,core 对
|
|
86
|
+
* 不带这一格的 outcome 逐字按 `"human"` 读),非 null = 宿主自报的那个词([ref] 起写进来的只有决定体出处位
|
|
87
87
|
* `decidedBy:"policy"` 经 `liveSettledBy` 映射来的 `"policy"`,allow 与 deny 两向都写;词表属主恒是 core —— 见 {@link HostSettledBy})。
|
|
88
88
|
*
|
|
89
89
|
* **为什么必须是行上的一格**(病灶,7.93.3 合并树 codex ① 验真):`settledBy` 此前只到达**当次**回决的
|
|
@@ -92,7 +92,7 @@ export interface AskRow {
|
|
|
92
92
|
* 在一条根本没有人的 run 里。不变量:**一条决议的来源在所有读回路径上是同一个事实**;唯一读回铸点 =
|
|
93
93
|
* `tool-approval.ts` 的 `outcomeOfDecidedRow`。
|
|
94
94
|
*
|
|
95
|
-
* 🔴 **为什么是自己一列,不是塞进 `decision_actor` 那只袋**(
|
|
95
|
+
* 🔴 **为什么是自己一列,不是塞进 `decision_actor` 那只袋**([ref] 取舍,亲读后定):
|
|
96
96
|
* · 那只袋是**自由载荷**——型是 `unknown`(见上一格),读回不过任何 schema(`parseJsonColumn` 返回
|
|
97
97
|
* `unknown`),schema 属主在别处([ref] ActorAssertion),`adoption/plan.ts` 的裁定 D2 把它连同
|
|
98
98
|
* `decision_note` 一起定为**史实字段,永不改写**。往一只没有属主、没有类型化读回的袋里塞一个
|
|
@@ -228,11 +228,11 @@ export interface DecideAskInput {
|
|
|
228
228
|
/** 车4 §12-E:回决幂等键,赢 CAS 时随决议一起落列(见 `AskRow.idempotencyKey`)。缺席 ⇒ 列保持 NULL。 */
|
|
229
229
|
idempotencyKey?: string | null;
|
|
230
230
|
/**
|
|
231
|
-
* 🔴
|
|
231
|
+
* 🔴 [ref]:本次回决的**结算来源**,与决议同一条 UPDATE 落列 `settled_by`(语义/两态读法/为什么是
|
|
232
232
|
* 自己一列,全在 {@link AskRow.settledBy})。缺席 ⇒ 列 NULL ⇒ 读回是「一个人答的」。
|
|
233
233
|
*
|
|
234
234
|
* 店**不判词**(词表属主是 core):写什么存什么。店只判**形** —— `assertDecideSettledBy` 的那一条
|
|
235
|
-
* (长度 ≤ 列宽;
|
|
235
|
+
* (长度 ≤ 列宽;[ref] 起 approve 行也可以带来源位),理由见那只门的顶注;三 twin 同判。
|
|
236
236
|
*/
|
|
237
237
|
settledBy?: HostSettledBy;
|
|
238
238
|
/** [ref]:ctrl+g 编辑实参,与决议同一条 UPDATE 落列(语义三态见 {@link AskRow.updatedInput})。
|
|
@@ -244,7 +244,8 @@ export interface DecideAskInput {
|
|
|
244
244
|
* `idempotency_conflict`(车4 §12-E):同一 (task_id, idempotency_key) 已被**另一条** ask 的回决占用。
|
|
245
245
|
* 🔴 方言错误的判别**收在店内**(TiDB `ER_DUP_ENTRY`/errno 1062 与 PG SQLSTATE 23505),端点只认这个
|
|
246
246
|
* typed 臂 —— 否则每个消费层都得自己认两套驱动的错误对象形状,方言就漏出了持久层。
|
|
247
|
-
* `row` = 判定时刻读到的本 ask
|
|
247
|
+
* `row` = 判定时刻读到的本 ask 行,经这次决议的属主维投影({@link projectDecideReading}):行不在(并发删)**或行已不带着
|
|
248
|
+
* 门判过的那位属主**(出域,[ref])⇒ `null` —— 两者同读,出域的输者拿不到别人的行。
|
|
248
249
|
*/
|
|
249
250
|
export type DecideResult = {
|
|
250
251
|
ok: true;
|
|
@@ -274,17 +275,17 @@ export declare function assertIdempotencyKeyShape(key: string): void;
|
|
|
274
275
|
/** `settled_by` 列宽 = 这一格的唯一尺(两方言 DDL 与下面的形门读同一个常量,不手抄第二份)。 */
|
|
275
276
|
export declare const MAX_SETTLED_BY_CHARS = 16;
|
|
276
277
|
/** `settled_by` 这一列装得下这个词吗(1..{@link MAX_SETTLED_BY_CHARS})—— 店门口形门({@link assertDecideSettledBy})的**谓词本身**。
|
|
277
|
-
*
|
|
278
|
+
* [ref] 起决定口不再读它:wire 上的出处位是闭集(`host-decision.ts` 的 `APPROVAL_DECIDED_BY`),映射到这一列的词恒在尺内。 */
|
|
278
279
|
export declare function settledByFitsColumn(v: string): boolean;
|
|
279
280
|
/**
|
|
280
|
-
*
|
|
281
|
+
* [ref] 的**入店卫生门**(三 twin 同判,与 {@link assertIdempotencyKeyShape} / {@link assertIntegralEpochMs} 同族)。
|
|
281
282
|
* 判的是**形**,不是**词** —— 词表属主恒是 core,本层一个词都不认识。一条:
|
|
282
283
|
*
|
|
283
284
|
* **长度 ≤ 列宽**。`settled_by` 是 `VARCHAR(16)` 的闭集词列。不拦的话:MySQL 协议侧非严格模式**静默截断**、PG 侧直接
|
|
284
285
|
* 报错 —— 同一份调用方代码在两个后端拿到两种答案(`assertIdempotencyKeyShape` 的 PAD SPACE 论证逐字同源),而**被截断过的
|
|
285
286
|
* 词与原词是两个词**:一条决议的来源在库里变成了另一件事。空串同拒(core 那边它不是词,存进去只会读成一个假的「非人」)。
|
|
286
287
|
*
|
|
287
|
-
* 🔴
|
|
288
|
+
* 🔴 [ref]:此前的第二条「只与 `deny` 同行」**删了** —— 它的前提(「只有人能批准一个要执行的动作,core 对 `{allow:true,settledBy}`
|
|
288
289
|
* 一律 fail-closed 拒」)自 core 7.39.0 起不成立:策略的放行铸 `policy_allowed`,决定体的出处位 `decidedBy:"policy"` 在 allow 与 deny
|
|
289
290
|
* 上都落这一列,approve 行带来源位是一条合法的行(读回铸点 `outcomeOfDecidedRow` 两向都读它)。今天写这一列的只有两条路:决定口经
|
|
290
291
|
* `liveSettledBy` 映射来的 `"policy"`,与 `claimTerminal(refuse)` 的 {@link POLICY_REFUSAL_DECISION} —— 都是 core 在两向上都收的词。
|
|
@@ -362,7 +363,7 @@ export type AskTerminalClaimCurrent = {
|
|
|
362
363
|
decision: AskDecision | null;
|
|
363
364
|
/** [ref] 三态读法照 {@link AskRow.updatedInput}:键缺席 = 没带编辑;`null` 是编辑成 null 的值。 */
|
|
364
365
|
updatedInput?: unknown;
|
|
365
|
-
/**
|
|
366
|
+
/** [ref]:赢家决议的**结算来源**(语义与两态读法见 {@link AskRow.settledBy})。**必填**(不是可选)——
|
|
366
367
|
* 可选会让投影漏挑这一列时静默编译过,而漏挑的后果恰是本批要修的病:CAS 输家把赢家的策略拒读成人拒。 */
|
|
367
368
|
settledBy: HostSettledBy | null;
|
|
368
369
|
/** 行上记着的成因,经问账行成因的唯一读口 `causeOfAskRow` 读出(`kind` 说它在这一行上的意思:VOID / DENIED = 终态成因,PARKING / PARKED = 转 park 的触发成因);
|
|
@@ -427,11 +428,29 @@ export interface BatchRow {
|
|
|
427
428
|
export type AskCallCoordinate = Pick<AskRow, "taskId" | "legKey" | "toolCallId" | "sourceTaskId">;
|
|
428
429
|
/** 「这一行在这次调用上」的唯一判据(四列逐字相等):InMemory twin 的筛子与 SQL twin 的出口对齐读同一只。 */
|
|
429
430
|
export declare function askRowOnCall(row: AskRow, call: AskCallCoordinate): boolean;
|
|
431
|
+
/**
|
|
432
|
+
* 🔴 [ref] —— **决议作用域的属主维**:这一行此刻带着的属主,是不是这次决议的门判过的那一位(逐字相等;`null` 只等于 `null`)。
|
|
433
|
+
*
|
|
434
|
+
* 律(一条):一次决议请求的作用域 = (ask, 批, **门判过的那位属主**)。属主的唯一来源是行上的 `owner` 列(铸行写定,只有 `/v1/adoption` 改写它);
|
|
435
|
+
* 门(耐久回决口 `owner ∨ operator`、live 应答口 `owner`)照旧在门里判授权,本谓词**不复判授权**,只绑「门判的那一份属主事实」——
|
|
436
|
+
* 门读行与 CAS 之间属主被改写,门的判断就不再是关于这一行的判断。于是这次请求拿到的**每一份**行读数(CAS 本身、CAS 输者的读数、
|
|
437
|
+
* 提交歧义的确认读、幂等回放的命中)都过这一只:出域 = 缺席,门按缺席答(与行不在同体同码)。
|
|
438
|
+
* InMemory twin 的判定、SQL twin 输者读数的投影、两扇门的确认读读同一只;SQL twin 的 UPDATE 谓词是它的方言镜像({@link decideOwnerWhere})。
|
|
439
|
+
*/
|
|
440
|
+
export declare function askRowCarriesOwner(row: AskRow | null, owner: string | null): row is AskRow;
|
|
441
|
+
/** [ref]:决议输者读数的投影(三 twin 共用一份):行出了这次决议的属主域 ⇒ 读作缺席,不交出别人的行。 */
|
|
442
|
+
export declare function projectDecideReading(row: AskRow | null, owner: string | null): AskRow | null;
|
|
430
443
|
export interface ApprovalAskStore {
|
|
431
444
|
/** 幂等 upsert。返回**行 + 本次是否真插入**(判别位语义见 {@link EnsureAskResult})。 */
|
|
432
445
|
ensureAsk(row: NewAskRow): Promise<EnsureAskResult>;
|
|
433
446
|
transitionAsk(askId: string, from: AskState, to: AskState, patch: AskTransitionPatch): Promise<boolean>;
|
|
434
|
-
|
|
447
|
+
/**
|
|
448
|
+
* 人答臂的单赢者 CAS。🔴 [ref]:`owner` = 这次决议的门**判过的**那位属主(门读到的行上 `owner` 列;活登记 = 铸卡时记下的那一份),
|
|
449
|
+
* **不是**调用方的主体 —— 运维代决别人的问,传的是那个别人。它是作用域的第三维(与 ask_id / batch_id 并列,判据 {@link askRowCarriesOwner}):
|
|
450
|
+
* 行此刻不带这位属主(门读之后被 `/v1/adoption` 改写)⇒ CAS 输、零写,`row` 读作 `null`(与行不在同读)。**必填**,不是可选:
|
|
451
|
+
* 缺省等于不绑属主,安全轴上那是静默放行。
|
|
452
|
+
*/
|
|
453
|
+
decideAsk(askId: string, batchId: string, owner: string | null, decision: DecideAskInput): Promise<DecideResult>;
|
|
435
454
|
/**
|
|
436
455
|
* [ref]:原子终局 claim —— 把「争终局」与「读真相」并成**一次**店往返(胜负判定与败方 `current` 读数
|
|
437
456
|
* 在同一原子单元内,语义见 {@link AskTerminalClaimOutcome})。[ref]-R1 的病根「CAS 与读真相是两次店
|
|
@@ -482,12 +501,12 @@ export interface ApprovalAskStore {
|
|
|
482
501
|
* 后续件。 */
|
|
483
502
|
listPendingBySession(sessionId: string, owner: string | null, signal?: AbortSignal): Promise<AskRow[]>;
|
|
484
503
|
/**
|
|
485
|
-
* 🔴
|
|
504
|
+
* 🔴 [ref] / SN-C1:**这次调用在这条腿上的全部行** —— 任意状态、任意 ask 身份(同一调用不同类集 = 不同 askId 的几只问、升级前按旧派生
|
|
486
505
|
* 写的行,都在其中)。坐标 = {@link AskCallCoordinate} 四列**精确**匹配;序 = `created_at_ms ASC, ask_id ASC`(确定性)。
|
|
487
506
|
*
|
|
488
507
|
* 唯一消费者 = 会话授权短路的争议判据(`tool-approval.ts` `sessionGrantUncontestedByRow`):「这次调用在腿内有行 ⇒ 一揽子放行不得代答」。
|
|
489
508
|
* 为什么按调用而不是按 askId 点读:争议的真源是**调用**(人对这次调用说过什么 / 这次调用还有一张卡挂着),ask 身份只是其中一问的主键;
|
|
490
|
-
* 身份可以加轴(
|
|
509
|
+
* 身份可以加轴([ref] 加了类集),争议判据不得依赖身份 —— 按身份点读在身份加轴的那一刻就把同调用的别的问、旧派生的行读成「不存在」。
|
|
491
510
|
*
|
|
492
511
|
* 三 twin 同答:SQL twin 读后按四列逐字再滤一遍 —— MySQL 协议的 VARCHAR 等值带 PAD SPACE(`'tc'` = `'tc '`),PG(`COLLATE "C"`)与
|
|
493
512
|
* InMemory 严格比较;不在入口拒(调用 id 是引擎铸的原值,首尾空白不归本店判),在出口对齐。索引:走 `idx_ask_task_state`
|
|
@@ -585,7 +604,7 @@ export declare const TIDB_APPROVAL_ASK_STATEMENTS: readonly string[];
|
|
|
585
604
|
/** {@link TIDB_APPROVAL_ASK_STATEMENTS} 的遍历壳——生产路径走 `tidb-pool.ts` 的中央 `ensureSchema`
|
|
586
605
|
* (那里展开了同一份数组),本函数留给只需要这两张表的集成测试。 */
|
|
587
606
|
export declare function ensureTiDBApprovalAskSchema(pool: MySqlPool): Promise<void>;
|
|
588
|
-
/**
|
|
607
|
+
/** [ref]:本 store 的索引**声明**(两方言共用一份)。PG 侧由下面的 `ensurePgApprovalAskSchema` 应用,MySQL 侧由 `tidb-pool.ts` 的中央 `ensureSchema` 应用(那里内联 `KEY` 已在 `CREATE TABLE` 里 ⇒ 新建库探到即零 DDL,存量库缺谁补谁)。加索引以外的 schema 变更仍归运维,见 `plugins/ensure-index.ts` 头注。 */
|
|
589
608
|
export declare const APPROVAL_ASK_INDEXES: readonly IndexSpec[];
|
|
590
609
|
export declare function ensurePgApprovalAskSchema(q: PgQueryFn): Promise<void>;
|
|
591
610
|
/**
|
|
@@ -638,7 +657,7 @@ export declare class SqlApprovalAskStore implements ApprovalAskStore {
|
|
|
638
657
|
private getBatchOn;
|
|
639
658
|
ensureAsk(row: NewAskRow): Promise<EnsureAskResult>;
|
|
640
659
|
transitionAsk(askId: string, from: AskState, to: AskState, patch: AskTransitionPatch): Promise<boolean>;
|
|
641
|
-
decideAsk(askId: string, batchId: string, decision: DecideAskInput): Promise<DecideResult>;
|
|
660
|
+
decideAsk(askId: string, batchId: string, owner: string | null, decision: DecideAskInput): Promise<DecideResult>;
|
|
642
661
|
/**
|
|
643
662
|
* [ref] 原子终局 claim(接口契约见 {@link ApprovalAskStore.claimTerminal};类型语义见
|
|
644
663
|
* {@link AskTerminalClaimOutcome})。expire 意图 = 既有 `expireAsk` 事务**原体**(步⓪-③ 逐字保留,
|
|
@@ -89,6 +89,12 @@ export function projectAskTerminalClaimTruth(row) {
|
|
|
89
89
|
export function askRowOnCall(row, call) {
|
|
90
90
|
return row.taskId === call.taskId && row.legKey === call.legKey && row.toolCallId === call.toolCallId && row.sourceTaskId === call.sourceTaskId;
|
|
91
91
|
}
|
|
92
|
+
export function askRowCarriesOwner(row, owner) {
|
|
93
|
+
return row !== null && row.owner === owner;
|
|
94
|
+
}
|
|
95
|
+
export function projectDecideReading(row, owner) {
|
|
96
|
+
return askRowCarriesOwner(row, owner) ? row : null;
|
|
97
|
+
}
|
|
92
98
|
export const APPROVAL_ASK_TABLE = "approval_ask";
|
|
93
99
|
export const APPROVAL_BATCH_TABLE = "approval_batch";
|
|
94
100
|
export const TIDB_APPROVAL_ASK_STATEMENTS = [
|
|
@@ -365,6 +371,11 @@ function ph(dialect, n) {
|
|
|
365
371
|
function pendingClaimWhere(dialect, firstParam) {
|
|
366
372
|
return `ask_id = ${ph(dialect, firstParam)} AND batch_id = ${ph(dialect, firstParam + 1)} AND state = 'STREAM_PENDING'`;
|
|
367
373
|
}
|
|
374
|
+
function decideOwnerWhere(dialect, owner, param) {
|
|
375
|
+
if (owner === null)
|
|
376
|
+
return { sql: "owner IS NULL", params: [] };
|
|
377
|
+
return dialect === "tidb" ? { sql: "CAST(owner AS BINARY) = CAST(? AS BINARY)", params: [owner] } : { sql: `owner = ${ph(dialect, param)}`, params: [owner] };
|
|
378
|
+
}
|
|
368
379
|
export class SqlApprovalAskStore {
|
|
369
380
|
db;
|
|
370
381
|
constructor(db) {
|
|
@@ -451,23 +462,24 @@ export class SqlApprovalAskStore {
|
|
|
451
462
|
const res = await this.db.query(`UPDATE ${APPROVAL_ASK_TABLE} SET ${setSql}, rev = rev + 1 WHERE ask_id = ${askIdPh} AND state = ${fromPh}`, [...vals, askId, from]);
|
|
452
463
|
return res.affected === 1;
|
|
453
464
|
}
|
|
454
|
-
async decideAsk(askId, batchId, decision) {
|
|
465
|
+
async decideAsk(askId, batchId, owner, decision) {
|
|
455
466
|
if (decision.idempotencyKey != null)
|
|
456
467
|
assertIdempotencyKeyShape(decision.idempotencyKey);
|
|
457
468
|
assertDecideSettledBy(decision);
|
|
458
469
|
const now = Date.now();
|
|
459
470
|
const dialect = this.db.dialect;
|
|
471
|
+
const ownerWhere = decideOwnerWhere(dialect, owner, 11);
|
|
460
472
|
const conn = await this.db.connect();
|
|
461
473
|
try {
|
|
462
474
|
await conn.begin();
|
|
463
475
|
const batchRes = await conn.query(this.q(`UPDATE ${APPROVAL_BATCH_TABLE} SET rev = rev + 1, updated_at_ms = ? WHERE batch_id = ? AND state = 'OPEN'`, `UPDATE ${APPROVAL_BATCH_TABLE} SET rev = rev + 1, updated_at_ms = $1 WHERE batch_id = $2 AND state = 'OPEN'`), [now, batchId]);
|
|
464
476
|
if (batchRes.affected !== 1) {
|
|
465
477
|
await conn.rollback();
|
|
466
|
-
return { ok: false, reason: "batch_closed", row: await this.getAskOn(conn, askId) };
|
|
478
|
+
return { ok: false, reason: "batch_closed", row: projectDecideReading(await this.getAskOn(conn, askId), owner) };
|
|
467
479
|
}
|
|
468
480
|
let askRes;
|
|
469
481
|
try {
|
|
470
|
-
askRes = await conn.query(`UPDATE ${APPROVAL_ASK_TABLE} SET state='DECIDED', decision=${ph(dialect, 1)}, decision_actor=${ph(dialect, 2)}, decision_note=${ph(dialect, 3)}, settled_by=${ph(dialect, 4)}, updated_input=${ph(dialect, 5)}, decided_at_ms=${ph(dialect, 6)}, idempotency_key=${ph(dialect, 7)}, rev=rev+1, updated_at_ms=${ph(dialect, 8)} WHERE ${pendingClaimWhere(dialect, 9)}`, [
|
|
482
|
+
askRes = await conn.query(`UPDATE ${APPROVAL_ASK_TABLE} SET state='DECIDED', decision=${ph(dialect, 1)}, decision_actor=${ph(dialect, 2)}, decision_note=${ph(dialect, 3)}, settled_by=${ph(dialect, 4)}, updated_input=${ph(dialect, 5)}, decided_at_ms=${ph(dialect, 6)}, idempotency_key=${ph(dialect, 7)}, rev=rev+1, updated_at_ms=${ph(dialect, 8)} WHERE ${pendingClaimWhere(dialect, 9)} AND ${ownerWhere.sql}`, [
|
|
471
483
|
decision.decision,
|
|
472
484
|
decision.decisionActor == null ? null : this.json(decision.decisionActor),
|
|
473
485
|
decision.decisionNote ?? null,
|
|
@@ -478,18 +490,19 @@ export class SqlApprovalAskStore {
|
|
|
478
490
|
now,
|
|
479
491
|
askId,
|
|
480
492
|
batchId,
|
|
493
|
+
...ownerWhere.params,
|
|
481
494
|
]);
|
|
482
495
|
}
|
|
483
496
|
catch (err) {
|
|
484
497
|
if (this.isDupKey(err)) {
|
|
485
498
|
await conn.rollback();
|
|
486
|
-
return { ok: false, reason: "idempotency_conflict", row: await this.getAskOn(conn, askId) };
|
|
499
|
+
return { ok: false, reason: "idempotency_conflict", row: projectDecideReading(await this.getAskOn(conn, askId), owner) };
|
|
487
500
|
}
|
|
488
501
|
throw err;
|
|
489
502
|
}
|
|
490
503
|
if (askRes.affected !== 1) {
|
|
491
504
|
await conn.rollback();
|
|
492
|
-
return { ok: false, reason: "ask_not_pending", row: await this.getAskOn(conn, askId) };
|
|
505
|
+
return { ok: false, reason: "ask_not_pending", row: projectDecideReading(await this.getAskOn(conn, askId), owner) };
|
|
493
506
|
}
|
|
494
507
|
await conn.commit();
|
|
495
508
|
}
|
|
@@ -49,7 +49,7 @@ export declare class MemoryApprovalExemptionStore implements ApprovalExemptionSt
|
|
|
49
49
|
deleteBySession(sessionId: string): Promise<number>;
|
|
50
50
|
}
|
|
51
51
|
/**
|
|
52
|
-
* 🔴
|
|
52
|
+
* 🔴 [ref] —— **fail-closed per session file.** A record in the MIDDLE of a session's log that cannot be read (bit rot,
|
|
53
53
|
* a hand edit, a line `42`, an object missing `toolName`) used to be skipped silently. When that line was a REVOKE
|
|
54
54
|
* tombstone, the grant before it survived the replay: a "don't ask again" the operator had revoked came back and the
|
|
55
55
|
* tool ran WITHOUT asking — the fail-open direction on the approval axis. We cannot tell which fact the line held, so
|
|
@@ -63,14 +63,14 @@ export declare class FileApprovalExemptionStore implements ApprovalExemptionStor
|
|
|
63
63
|
private readonly dir;
|
|
64
64
|
private readonly bySession;
|
|
65
65
|
private readonly logs;
|
|
66
|
-
/**
|
|
66
|
+
/** [ref]: sanitized session key → that session log's gate (only files that replayed a bad record are listed). */
|
|
67
67
|
private readonly corruptGates;
|
|
68
68
|
private readonly warn;
|
|
69
69
|
/** @param opts.warn corrupt-read disclosure seat (`LocalBackend` wires `discloseWarn`; absent ⇒ the owner falls back to `console.warn`, never to silence). */
|
|
70
70
|
constructor(root: string, opts?: {
|
|
71
71
|
warn?: Logger["warn"];
|
|
72
72
|
});
|
|
73
|
-
/**
|
|
73
|
+
/** [ref]: first line of every judging / appending method (see the class note). */
|
|
74
74
|
private assertUsable;
|
|
75
75
|
private pathFor;
|
|
76
76
|
/** Replay every session log (torn-tail-safe; last-wins with revoke tombstones). Index keyed by the SANITIZED id. */
|
|
@@ -74,9 +74,9 @@ export declare class MemoryApprovalNonceStore implements ApprovalNonceStore {
|
|
|
74
74
|
* 的既有暴露同级,且 SQL 车道不受此影响);**绝不**能出现的是反向 —— 记录还在却被读成不在,那要靠
|
|
75
75
|
* core JSONL 读法的断尾安全(半行丢弃)兜住。
|
|
76
76
|
*
|
|
77
|
-
* 🔴 **
|
|
77
|
+
* 🔴 **[ref]:中间一行读不出 ⇒ 整本拒用(fail-closed)**。撕尾是崩溃的正常形(core 丢弃且不报);而**中间**
|
|
78
78
|
* 那一行读不出(位腐 / 手改 / 一行 `42` / 缺键的对象)时,我们不知道它是哪一只 nonce —— 修前静默跳过它,等于
|
|
79
|
-
* 让那只已消费的证明再被受理一次(
|
|
79
|
+
* 让那只已消费的证明再被受理一次([ref] 要关的重放洞换了个入口)。现在由属主披露(`approval_nonce_corrupt_read`)
|
|
80
80
|
* 并合上 {@link gate}:`consume` / `reapExpired` 第一行即带码拒(`JsonlStoreCorruptError`,外层答 500);`nowMs` 不读账、
|
|
81
81
|
* 不经闸。清扫同样要拒:压实会把幸存者原样写回、把坏行连同证据一起抹掉,下一次重启读到的就是一本「干净」的账 ——
|
|
82
82
|
* 闸自己打开,而那只 nonce 仍然没被记住。出路在拒绝句里(移开文件的代价与安全时机)。
|
|
@@ -89,7 +89,7 @@ export declare class FileApprovalNonceStore implements ApprovalNonceStore {
|
|
|
89
89
|
* 从复合键里**解析**出来是一条没必要的反向铸形 —— 记录留着就不必解析。 */
|
|
90
90
|
private readonly rows;
|
|
91
91
|
private log;
|
|
92
|
-
/**
|
|
92
|
+
/** [ref]:本账的损坏闸(见类注)。 */
|
|
93
93
|
private readonly gate;
|
|
94
94
|
/** @param opts.warn 腐读披露座(`LocalBackend` 接 `discloseWarn`;缺席 ⇒ 属主退回 `console.warn`,不退回沉默)。 */
|
|
95
95
|
constructor(root: string, opts?: {
|
|
@@ -1,5 +1,17 @@
|
|
|
1
|
+
/** 决议载荷 —— 指纹的输入形(两条车道 + workflow 停驻决定共用一份;成员顺序见 {@link approvalPayloadFingerprint})。 */
|
|
2
|
+
export interface ApprovalPayload {
|
|
3
|
+
updatedInput?: unknown;
|
|
4
|
+
answer?: unknown;
|
|
5
|
+
reason?: string;
|
|
6
|
+
/** core 7.54.0:人写在卡上的话(引擎逐字记在赢家上,空白也记)。 */
|
|
7
|
+
feedback?: string;
|
|
8
|
+
}
|
|
1
9
|
/**
|
|
2
|
-
* [ref] 件1(codex R2-[high] 一)—— 决议载荷的比对指纹:`[updatedInput, answer, reason]`
|
|
10
|
+
* [ref] 件1(codex R2-[high] 一)—— 决议载荷的比对指纹:`[updatedInput, answer, reason]` 三件的规范串,其后**按在场追加**后来的成员(今天一员:`feedback`)。
|
|
11
|
+
*
|
|
12
|
+
* 🔴 成员律(一条):首发的三件恒占位(缺席折 `null`);之后加进来的成员**只在在场时**追加在尾部 —— workflow 停驻决定的同一性指纹
|
|
13
|
+
* ({@link parkDecisionFingerprint} 包它)是**落了库**的,新成员若恒占位,存量决定的指纹全部换字节、一次合法的重放被判成「另一个决定」;
|
|
14
|
+
* 按在场追加 ⇒ 不带新成员的决定字节不变,带了的与不带的不可能撞(串的元素个数不同)。
|
|
3
15
|
*
|
|
4
16
|
* 为什么是指纹而不是把三件原样交出来:`updatedInput` 可能携人写的命令原文/密钥形字节,而本读口的
|
|
5
17
|
* 契约是「窄读、非凭据面」—— 交指纹够比对,也不给任何调用点把它误投上 wire 的机会。
|
|
@@ -15,9 +27,5 @@
|
|
|
15
27
|
* 铸点丢掉的字节行上就没有,请求侧多喂一件会把一次合法重试误判成「不同的决议」。
|
|
16
28
|
* 序列化失败(循环引用/BigInt 等)⇒ `null` = 判别不出,调用方据此拒绝回放(fail-closed)。
|
|
17
29
|
*/
|
|
18
|
-
export declare function approvalPayloadFingerprint(v:
|
|
19
|
-
updatedInput?: unknown;
|
|
20
|
-
answer?: unknown;
|
|
21
|
-
reason?: string;
|
|
22
|
-
}): string | null;
|
|
30
|
+
export declare function approvalPayloadFingerprint(v: ApprovalPayload): string | null;
|
|
23
31
|
//# sourceMappingURL=approval-payload-fingerprint.d.ts.map
|
|
@@ -12,7 +12,7 @@ function canonicalFingerprintJson(v) {
|
|
|
12
12
|
}
|
|
13
13
|
export function approvalPayloadFingerprint(v) {
|
|
14
14
|
try {
|
|
15
|
-
const fp = canonicalFingerprintJson([v.updatedInput ?? null, v.answer ?? null, v.reason ?? null]);
|
|
15
|
+
const fp = canonicalFingerprintJson([v.updatedInput ?? null, v.answer ?? null, v.reason ?? null, ...(v.feedback !== undefined ? [v.feedback] : [])]);
|
|
16
16
|
return fp;
|
|
17
17
|
}
|
|
18
18
|
catch (e) {
|
|
@@ -44,7 +44,7 @@ type ListOpts = {
|
|
|
44
44
|
limit?: number;
|
|
45
45
|
};
|
|
46
46
|
export declare function ensureTiDBBackgroundAgentSchema(pool: Pool): Promise<void>;
|
|
47
|
-
/**
|
|
47
|
+
/** [ref]:本 store 的索引**声明**(两方言共用一份)。PG 侧由下面的 `ensurePgBackgroundAgentSchema` 应用,MySQL 侧由 `tidb-pool.ts` 的中央 `ensureSchema` 应用(那里内联 `KEY` 已在 `CREATE TABLE` 里 ⇒ 新建库探到即零 DDL,存量库缺谁补谁)。加索引以外的 schema 变更仍归运维,见 `plugins/ensure-index.ts` 头注。 */
|
|
48
48
|
export declare const BACKGROUND_AGENT_INDEXES: readonly IndexSpec[];
|
|
49
49
|
export declare function ensurePgBackgroundAgentSchema(q: PgQueryFn): Promise<void>;
|
|
50
50
|
export declare class TiDBBackgroundAgentStore implements BackgroundAgentStore {
|
|
@@ -106,7 +106,7 @@ export interface BackgroundShellDriver<S> {
|
|
|
106
106
|
/** Best-effort cleanup of ONE shell's transport resources (kill + remove temp dirs/handles). Should not throw. */
|
|
107
107
|
disposeOne(state: S): Promise<void>;
|
|
108
108
|
/**
|
|
109
|
-
*
|
|
109
|
+
* [ref](core 7.32.0 [ref])—— **可选**的同步硬收一枪(`BackgroundShellCapability.killBackgroundNow` 的 driver 半场)。
|
|
110
110
|
* 只有**本机有进程组可发**的 driver 实现它(今天只有 host 车道);远端 / 沙箱车道留空 ⇒ 座位根本不挂出来,core 对那些行
|
|
111
111
|
* 答 `no_pgid` 并派普通 kill。契约(core `docs/background-process-lifetime.md`):同步(无 TERM、无定时器、无 await)、
|
|
112
112
|
* 幂等、永不抛、只对**证明得了还是自己的** pid 发信号(观察到退出 ⇒ `already_gone`,一枪都不发)。
|
|
@@ -162,7 +162,7 @@ export declare class BackgroundShellManager<S> {
|
|
|
162
162
|
poll(shellId: BackgroundShellId): Promise<Result<BackgroundPoll, BackgroundShellError>>;
|
|
163
163
|
kill(shellId: BackgroundShellId): Promise<Result<void, BackgroundShellError>>;
|
|
164
164
|
/**
|
|
165
|
-
*
|
|
165
|
+
* [ref] —— 座位 `killBackgroundNow(shellId)` 的 manager 半场:**同步**、永不抛。
|
|
166
166
|
* · 不是本 env 的 shell(未知 / 伪造 / 已被驱逐的终态行)⇒ `already_gone`(core 契约「or not its shell」);
|
|
167
167
|
* · driver 不实现 {@link BackgroundShellDriver.killNow} ⇒ `no_pgid`(没有同步硬收可落;实现座位的 env 才会走到这里);
|
|
168
168
|
* · driver 答出三词之外 ⇒ `no_pgid`(没有落地,可重试)。driver 的座位按契约**永不抛**(host 的那只由构造保证:只读子进程句柄
|
|
@@ -121,7 +121,7 @@ export declare class SqlBlobBackend implements BlobBackend {
|
|
|
121
121
|
* (a): an over-cap blob is REJECTED (typed {@link BlobTooLargeError}) BEFORE the driver ever sees the bytes —
|
|
122
122
|
* the alternative is an inscrutable packet-limit error deep in the driver, and on the HTTP face a 502 that
|
|
123
123
|
* invites the peer to retry a blob that can never land.
|
|
124
|
-
* 🔴 The cap is judged ON THE CONNECTION THAT WRITES (
|
|
124
|
+
* 🔴 The cap is judged ON THE CONNECTION THAT WRITES ([ref]): `max_allowed_packet` is a session value, fixed per
|
|
125
125
|
* connection, so the write borrows one connection through {@link connectJudged}, which reads ITS walls, judges, and — when
|
|
126
126
|
* the refusal is that connection's packet wall and the server's global wall is higher — replaces the stale connection and
|
|
127
127
|
* judges once more; the INSERT runs on the connection that passed. Never a pool-level reading, never a bare `pool.query`. */
|