@sema-agent/server 7.146.0 → 7.147.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 +384 -0
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/USAGE.md +170 -66
- package/deploy/facts/lanes.json +7 -0
- package/deploy/sema-up/README.md +2 -2
- package/deploy/sema-up/chart/templates/_helpers.tpl +22 -0
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -4
- package/deploy/sema-up/chart/templates/server.yaml +5 -4
- package/deploy/sema-up/chart/values.yaml +1 -1
- package/deploy/sema-up/cluster-up.sh +2 -1
- package/deploy/sema-up/lib/flagshape.sh +4 -0
- package/deploy/sema-up/lib/lanes.json +2 -5
- package/deploy/sema-up/sema-up.sh +12 -9
- package/deploy/sema-up/stack/compose.yaml +5 -4
- package/deploy/sema-up/stack/sema-stack-cluster.yaml +4 -3
- package/dist/approval-card.d.ts +4 -4
- package/dist/approval.d.ts +3 -3
- package/dist/audit.js +2 -2
- package/dist/bench/s1/live-deps.js +3 -1
- package/dist/boot/crash-last.js +2 -1
- package/dist/boot/device-lane.js +5 -5
- package/dist/boot/engine-lease.d.ts +12 -11
- package/dist/boot/execution-env.d.ts +2 -1
- package/dist/boot/execution-env.js +45 -33
- package/dist/boot/execution-lane.d.ts +37 -9
- package/dist/boot/execution-lane.js +74 -20
- package/dist/boot/exit-boundary.d.ts +1 -1
- package/dist/boot/exit-last.js +2 -1
- package/dist/boot/governance-seams.d.ts +2 -2
- package/dist/boot/leader.js +1 -1
- package/dist/boot/memory-boundary.d.ts +11 -11
- package/dist/boot/memory-boundary.js +3 -3
- package/dist/boot/memory-consolidation.d.ts +13 -24
- package/dist/boot/memory-consolidation.js +0 -13
- package/dist/boot/org-memory.js +3 -2
- package/dist/boot/parked-revive-gate.d.ts +1 -1
- package/dist/boot/parked-revive-gate.js +1 -1
- package/dist/boot/reapers.js +1 -1
- package/dist/boot/resolve-spec.js +91 -111
- package/dist/boot/retention-lane.d.ts +4 -42
- package/dist/boot/session-faces.d.ts +1 -0
- package/dist/boot/session-faces.js +8 -2
- package/dist/boot/stage-01-config.d.ts +1 -1
- package/dist/boot/stage-01-config.js +6 -2
- package/dist/boot/stage-02-web-admin-pull.d.ts +1 -1
- package/dist/boot/stage-02-web-admin-pull.js +10 -8
- package/dist/boot/stage-03-store-backend.d.ts +1 -1
- package/dist/boot/stage-04-stores.d.ts +1 -1
- package/dist/boot/stage-05-execution-env.d.ts +2 -2
- package/dist/boot/stage-05-execution-env.js +3 -3
- package/dist/boot/stage-06-runners.d.ts +3 -3
- package/dist/boot/stage-06-runners.js +1 -3
- package/dist/boot/stage-07-capability-layer.d.ts +3 -3
- package/dist/boot/stage-07-capability-layer.js +4 -9
- package/dist/boot/stage-08-reapers.d.ts +3 -3
- package/dist/boot/stage-09-leader.d.ts +4 -3
- package/dist/boot/stage-10-http-server.d.ts +4 -3
- package/dist/boot/stage-10-http-server.js +2 -1
- package/dist/boot/stores.d.ts +9 -0
- package/dist/boot/stores.js +18 -7
- package/dist/boot/web-admin.js +3 -3
- package/dist/capabilities/center-plugins.d.ts +2 -0
- package/dist/capabilities/center-plugins.js +6 -2
- package/dist/capabilities/composite-members.d.ts +1 -0
- package/dist/capabilities/composite-members.js +1 -0
- package/dist/capabilities/execution-lane.d.ts +7 -7
- package/dist/capabilities/execution-lane.js +2 -2
- package/dist/capabilities/hands-lane.d.ts +1 -1
- package/dist/capabilities/scenarios.d.ts +32 -18
- package/dist/capabilities/scenarios.js +13 -9
- package/dist/capabilities/settings-contract.d.ts +29 -0
- package/dist/capabilities/settings-contract.js +14 -0
- package/dist/capabilities/skills.d.ts +5 -5
- package/dist/capability-facts.d.ts +38 -0
- package/dist/capability-facts.js +34 -1
- package/dist/center-credential-renewer.js +3 -2
- package/dist/config-catalog.js +6 -5
- package/dist/config-invariants.d.ts +18 -3
- package/dist/config-invariants.js +36 -19
- package/dist/config-lkg.d.ts +1 -1
- package/dist/config-lkg.js +5 -6
- package/dist/config-provider.js +2 -0
- package/dist/config-types.d.ts +190 -186
- package/dist/config.d.ts +68 -5
- package/dist/config.js +80 -54
- package/dist/degenerate-instrument.js +1 -1
- package/dist/deploy-facts.js +3 -2
- package/dist/deployment-shape.d.ts +21 -12
- package/dist/deployment-shape.js +24 -6
- package/dist/env-facts.d.ts +7 -5
- package/dist/env-facts.js +10 -6
- package/dist/execution-config-root.d.ts +5 -5
- package/dist/execution-config-root.js +5 -5
- package/dist/execution-env-purpose.d.ts +14 -0
- package/dist/execution-env-purpose.js +29 -0
- package/dist/execution-lane-caps.d.ts +49 -86
- package/dist/execution-lane-caps.js +52 -62
- package/dist/execution-placement.d.ts +18 -2
- package/dist/execution-placement.js +19 -0
- package/dist/file-history-disclosure.d.ts +2 -2
- package/dist/fleet/drain-entry.d.ts +17 -10
- package/dist/fleet/drain-entry.js +1 -1
- package/dist/fleet/serving-lease.js +3 -4
- package/dist/history-anchor.d.ts +22 -0
- package/dist/history-anchor.js +14 -0
- package/dist/hooks/command-spawn.d.ts +1 -4
- package/dist/hooks/command-spawn.js +0 -11
- package/dist/hooks/hook-runner.d.ts +52 -8
- package/dist/hooks/hook-runner.js +160 -36
- package/dist/http/approval-sweeps.d.ts +2 -5
- package/dist/http/approval-sweeps.js +3 -2
- package/dist/http/checkpoint-ctx.d.ts +17 -0
- package/dist/http/checkpoint-ctx.js +6 -0
- package/dist/http/claim-latency.d.ts +10 -0
- package/dist/http/claim-latency.js +12 -0
- package/dist/http/dispatch.js +1 -1
- package/dist/http/durable-run-leg.js +2 -1
- package/dist/http/execution-context.d.ts +3 -1
- package/dist/http/execution-context.js +4 -0
- package/dist/http/memory-compliance-failure-reply.d.ts +1 -1
- package/dist/http/memory-compliance-failure-reply.js +3 -0
- package/dist/http/memory-store-refusal-reply.d.ts +3 -3
- package/dist/http/memory-store-refusal-reply.js +3 -0
- package/dist/http/owner-access.d.ts +11 -0
- package/dist/http/owner-access.js +7 -4
- package/dist/http/principal-gate.d.ts +3 -14
- package/dist/http/principal-gate.js +0 -13
- package/dist/http/request-guards.d.ts +1 -1
- package/dist/http/resume-legs.d.ts +7 -10
- package/dist/http/resume-legs.js +79 -50
- package/dist/http/rewind-files-reply.d.ts +34 -0
- package/dist/http/rewind-files-reply.js +36 -0
- package/dist/http/route-ctx.d.ts +32 -16
- package/dist/http/route-table.js +2 -0
- package/dist/http/routes/approvals-assistant.js +5 -25
- package/dist/http/routes/capabilities.js +8 -2
- package/dist/http/routes/devices.js +1 -1
- package/dist/http/routes/memory-origin.d.ts +1 -1
- package/dist/http/routes/notify-wake.js +2 -1
- package/dist/http/routes/projects.d.ts +70 -0
- package/dist/http/routes/projects.js +86 -0
- package/dist/http/routes/rules.js +30 -2
- package/dist/http/routes/runs.js +8 -8
- package/dist/http/routes/session-sync.js +27 -10
- package/dist/http/routes/sessions.d.ts +7 -1
- package/dist/http/routes/sessions.js +104 -2
- package/dist/http/routes/tasks.js +9 -3
- package/dist/http/server.d.ts +24 -10
- package/dist/http/server.js +17 -6
- package/dist/http/stored-body-replay.d.ts +5 -3
- package/dist/http/stored-body-replay.js +10 -1
- package/dist/http/wire-types.d.ts +19 -10
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/instruction-source-notice.d.ts +1 -1
- package/dist/memory-embedder-reembed.d.ts +38 -0
- package/dist/memory-embedder-reembed.js +20 -0
- package/dist/memory-incident-sink.d.ts +0 -28
- package/dist/memory-incident-sink.js +5 -0
- package/dist/memory-scope.d.ts +2 -2
- package/dist/memory-scope.js +1 -1
- package/dist/memory-store-refusal.d.ts +17 -4
- package/dist/memory-store-refusal.js +1 -1
- package/dist/memory-sync-client.d.ts +2 -0
- package/dist/memory-sync-client.js +13 -11
- package/dist/memory-sync.js +1 -1
- package/dist/model-compat.d.ts +35 -21
- package/dist/model-compat.js +49 -21
- package/dist/model-entry-refusal.d.ts +11 -1
- package/dist/model-entry-refusal.js +7 -0
- package/dist/namespaced-rule-name.d.ts +18 -1
- package/dist/namespaced-rule-name.js +12 -0
- package/dist/observability/fail-open.d.ts +17 -9
- package/dist/observability/fail-open.js +17 -9
- package/dist/observability/metrics.d.ts +2 -0
- package/dist/observability/metrics.js +2 -0
- package/dist/observability/secret-env-scrub.d.ts +30 -4
- package/dist/observability/secret-env-scrub.js +15 -3
- package/dist/orchestration/workflow-agent-session-index.d.ts +7 -12
- package/dist/orchestration/workflow-agent-session-index.js +1 -6
- package/dist/orchestration/workflow-completion-inbox.d.ts +26 -6
- package/dist/orchestration/workflow-completion-inbox.js +63 -45
- package/dist/org-memory-admission.d.ts +5 -2
- package/dist/org-memory-admission.js +25 -10
- package/dist/parked-decide.d.ts +33 -26
- package/dist/parked-decide.js +36 -44
- package/dist/plugins/approval-ask-store-file.d.ts +10 -2
- package/dist/plugins/approval-ask-store-file.js +37 -4
- package/dist/plugins/approval-ask-store-memory.d.ts +5 -3
- package/dist/plugins/approval-ask-store-memory.js +11 -2
- package/dist/plugins/approval-ask-store-sql.d.ts +3 -0
- package/dist/plugins/approval-ask-store-sql.js +3 -1
- package/dist/plugins/blob-backend.d.ts +38 -195
- package/dist/plugins/blob-backend.js +33 -229
- package/dist/plugins/caching-session-store.d.ts +9 -4
- package/dist/plugins/checkpoint-index-columns.d.ts +1 -1
- package/dist/plugins/checkpoint-index-columns.js +3 -2
- package/dist/plugins/checkpoint-store-face.d.ts +1 -1
- package/dist/plugins/device-store-sql.d.ts +2 -2
- package/dist/plugins/device-store-sql.js +5 -10
- package/dist/plugins/execution-lane-rename-m40.d.ts +20 -0
- package/dist/plugins/execution-lane-rename-m40.js +10 -0
- package/dist/plugins/execution-placement-sql.d.ts +63 -88
- package/dist/plugins/execution-placement-sql.js +94 -54
- package/dist/plugins/file-run-store.d.ts +26 -12
- package/dist/plugins/file-run-store.js +63 -63
- package/dist/plugins/imported-layer-root-retirement.d.ts +17 -8
- package/dist/plugins/imported-layer-root-retirement.js +4 -8
- package/dist/plugins/inbox-payload-column.d.ts +14 -0
- package/dist/plugins/inbox-payload-column.js +13 -0
- package/dist/plugins/local-checkpoint-store.d.ts +5 -0
- package/dist/plugins/local-checkpoint-store.js +11 -7
- package/dist/plugins/local-data-dir-modes-m39.d.ts +48 -0
- package/dist/plugins/local-data-dir-modes-m39.js +182 -0
- package/dist/plugins/local-engine-high-water.d.ts +11 -0
- package/dist/plugins/local-engine-high-water.js +59 -0
- package/dist/plugins/local-session-store.d.ts +91 -25
- package/dist/plugins/local-session-store.js +124 -45
- package/dist/plugins/local-task-attachment-store.d.ts +2 -0
- package/dist/plugins/local-task-attachment-store.js +10 -11
- package/dist/plugins/memory-embedder-fingerprint.d.ts +33 -10
- package/dist/plugins/memory-embedder-fingerprint.js +52 -12
- package/dist/plugins/memory-embedder.d.ts +1 -1
- package/dist/plugins/memory-embedder.js +2 -2
- package/dist/plugins/memory-engine-pg.d.ts +4 -3
- package/dist/plugins/memory-engine-pg.js +4 -4
- package/dist/plugins/memory-engine-sql-apply.d.ts +13 -4
- package/dist/plugins/memory-engine-sql-apply.js +1 -1
- package/dist/plugins/memory-engine-tidb.d.ts +8 -5
- package/dist/plugins/memory-engine-tidb.js +7 -8
- package/dist/plugins/one-time-migrations.d.ts +145 -35
- package/dist/plugins/one-time-migrations.js +272 -120
- package/dist/plugins/owner-only-file-mode.d.ts +29 -0
- package/dist/plugins/owner-only-file-mode.js +141 -0
- package/dist/plugins/permission-rule-store-file.d.ts +8 -8
- package/dist/plugins/permission-rule-store-file.js +14 -2
- package/dist/plugins/pg-pool.d.ts +2 -1
- package/dist/plugins/pg-pool.js +11 -4
- package/dist/plugins/release-version.d.ts +20 -0
- package/dist/plugins/release-version.js +28 -0
- package/dist/plugins/remote-env-adb.d.ts +20 -4
- package/dist/plugins/remote-env-adb.js +39 -11
- package/dist/plugins/remote-env-e2b.d.ts +12 -3
- package/dist/plugins/remote-env-e2b.js +6 -4
- package/dist/plugins/remote-env-host.d.ts +9 -1
- package/dist/plugins/remote-env-host.js +6 -5
- package/dist/plugins/remote-env-k8s.d.ts +5 -2
- package/dist/plugins/remote-env-k8s.js +15 -4
- package/dist/plugins/remote-env-local-docker.d.ts +4 -1
- package/dist/plugins/remote-env-local-docker.js +3 -3
- package/dist/plugins/remote-env-ssh.d.ts +8 -2
- package/dist/plugins/remote-env-ssh.js +26 -24
- package/dist/plugins/remote-shell.d.ts +59 -30
- package/dist/plugins/remote-shell.js +175 -62
- package/dist/plugins/retention-declaration.d.ts +37 -0
- package/dist/plugins/retention-declaration.js +9 -0
- package/dist/plugins/retention-deployment.d.ts +126 -0
- package/dist/plugins/retention-deployment.js +88 -0
- package/dist/plugins/retention-lane-store-sql.d.ts +74 -4
- package/dist/plugins/retention-lane-store-sql.js +103 -1
- package/dist/plugins/retention-sql.d.ts +29 -0
- package/dist/plugins/retention-sql.js +8 -0
- package/dist/plugins/schema-consistency.d.ts +0 -6
- package/dist/plugins/schema-consistency.js +1 -2
- package/dist/plugins/schema-ensure-legs.d.ts +1 -1
- package/dist/plugins/schema-ensure-legs.js +11 -1
- package/dist/plugins/session-ext-table.d.ts +74 -0
- package/dist/plugins/session-ext-table.js +121 -0
- package/dist/plugins/session-fork.d.ts +1 -1
- package/dist/plugins/session-row-sql.d.ts +8 -7
- package/dist/plugins/session-row-sql.js +15 -7
- package/dist/plugins/session-store-sql.d.ts +131 -0
- package/dist/plugins/session-store-sql.js +298 -0
- package/dist/plugins/session-workspace-cell.d.ts +2 -2
- package/dist/plugins/session-workspace-cell.js +2 -2
- package/dist/plugins/shared-memory-store-sql.d.ts +10 -0
- package/dist/plugins/shared-memory-store-sql.js +13 -13
- package/dist/plugins/snapshot-bucket-presence.js +1 -1
- package/dist/plugins/sql-driver.d.ts +23 -7
- package/dist/plugins/sql-driver.js +41 -8
- package/dist/plugins/sql-errors.d.ts +5 -2
- package/dist/plugins/sql-errors.js +4 -0
- package/dist/plugins/store-backend.d.ts +35 -8
- package/dist/plugins/store-backend.js +184 -62
- package/dist/plugins/store-contracts.d.ts +9 -2
- package/dist/plugins/store-contracts.js +1 -0
- package/dist/plugins/task-attachment-store.d.ts +6 -8
- package/dist/plugins/task-attachment-store.js +15 -10
- package/dist/plugins/task-list-store-sql.d.ts +1 -1
- package/dist/plugins/text-column-capacity.d.ts +21 -0
- package/dist/plugins/text-column-capacity.js +5 -0
- package/dist/plugins/tidb-pool.d.ts +3 -2
- package/dist/plugins/tidb-pool.js +19 -31
- package/dist/plugins/user-input-ledger-sql.d.ts +1 -1
- package/dist/read-face-posture.d.ts +6 -6
- package/dist/read-face-posture.js +2 -2
- package/dist/request-value-closure.d.ts +5 -5
- package/dist/request-value-closure.js +1 -1
- package/dist/rules-consent.d.ts +41 -13
- package/dist/rules-consent.js +101 -53
- package/dist/run-local.js +17 -13
- package/dist/runs.d.ts +48 -30
- package/dist/runs.js +26 -16
- package/dist/runtime-caps-resolver.d.ts +15 -8
- package/dist/runtime-caps-resolver.js +14 -10
- package/dist/sealed-key-layout.d.ts +2 -3
- package/dist/sealed-key-layout.js +0 -1
- package/dist/sealed-key.js +7 -5
- package/dist/security.d.ts +5 -3
- package/dist/sema-config-dir.js +2 -2
- package/dist/server-secret-env.d.ts +2 -0
- package/dist/service-version.d.ts +2 -1
- package/dist/service-version.js +2 -2
- package/dist/session-error-wire.d.ts +1 -1
- package/dist/session-incarnation.d.ts +8 -5
- package/dist/session-resident-background.d.ts +85 -32
- package/dist/session-resident-background.js +75 -7
- package/dist/session-row.d.ts +1 -1
- package/dist/session-sync-kernel.d.ts +1 -1
- package/dist/session-workspace.d.ts +11 -2
- package/dist/session-workspace.js +5 -0
- package/dist/sighup-idle.d.ts +1 -1
- package/dist/store-posture.d.ts +2 -1
- package/dist/stored-request-hooks-m20.d.ts +3 -2
- package/dist/stored-request-hooks-m20.js +19 -14
- package/dist/stores-sql/blob-index-sql.d.ts +148 -0
- package/dist/stores-sql/blob-index-sql.js +154 -0
- package/dist/stores-sql/checkpoint-store-sql.d.ts +1 -1
- package/dist/stores-sql/checkpoint-store-sql.js +11 -27
- package/dist/{plugins → stores-sql}/file-history-store-sql.d.ts +23 -11
- package/dist/{plugins → stores-sql}/file-history-store-sql.js +23 -18
- package/dist/{plugins → stores-sql}/pg-session-storage.d.ts +23 -76
- package/dist/{plugins → stores-sql}/pg-session-storage.js +80 -209
- package/dist/{plugins → stores-sql}/retention-store-sql.d.ts +123 -217
- package/dist/{plugins → stores-sql}/retention-store-sql.js +66 -190
- package/dist/{plugins → stores-sql}/session-event-payload.d.ts +1 -1
- package/dist/{plugins → stores-sql}/session-event-payload.js +1 -1
- package/dist/stores-sql/session-policy-store-sql.d.ts +1 -1
- package/dist/stores-sql/session-write-hooks.d.ts +59 -0
- package/dist/stores-sql/session-write-hooks.js +2 -0
- package/dist/{plugins → stores-sql}/tidb-session-storage.d.ts +10 -11
- package/dist/{plugins → stores-sql}/tidb-session-storage.js +10 -21
- package/dist/{plugins → stores-sql}/tidb-session-store.d.ts +32 -122
- package/dist/{plugins → stores-sql}/tidb-session-store.js +71 -171
- package/dist/stores-sql/tool-result-store-sql.d.ts +1 -1
- package/dist/stores-sql/tool-result-store-sql.js +1 -1
- package/dist/stores-sql/windowed-session-storage.d.ts +56 -0
- package/dist/stores-sql/windowed-session-storage.js +61 -0
- package/dist/task-a2a.d.ts +7 -1
- package/dist/task-a2a.js +15 -14
- package/dist/task-cwd.d.ts +11 -3
- package/dist/task-cwd.js +17 -1
- package/dist/task-mcp.d.ts +10 -2
- package/dist/task-mcp.js +13 -16
- package/dist/task-settings.d.ts +9 -4
- package/dist/task-settings.js +17 -6
- package/dist/tool-approval.d.ts +21 -8
- package/dist/tool-approval.js +10 -6
- package/dist/trace/core-keyset-guard.d.ts +9 -3
- package/dist/trace/engine-notice-wire.d.ts +1 -1
- package/dist/trace/engine-notice-wire.js +2 -0
- package/dist/trace/exit-seat.d.ts +23 -1
- package/dist/trace/exit-seat.js +3 -0
- package/dist/trace/project.d.ts +33 -16
- package/dist/trace/project.js +12 -9
- package/dist/trace/redact.d.ts +1 -1
- package/dist/trace/redact.js +61 -73
- package/dist/trace/self-minted-wire.d.ts +263 -10
- package/dist/trace/self-minted-wire.js +90 -2
- package/dist/trace/sema-provenance.d.ts +45 -41
- package/dist/trace/sema-provenance.js +81 -10
- package/dist/trace/task-notification-facets.d.ts +70 -2
- package/dist/trace/task-notification-facets.js +71 -1
- package/dist/trace/wire-projection-faces.d.ts +38 -2
- package/dist/trace/wire-projection-faces.js +26 -1
- package/dist/unread-request-members.d.ts +66 -0
- package/dist/unread-request-members.js +41 -0
- package/dist/user-input-ledger.d.ts +2 -2
- package/dist/web-admin-client/apply-effective.js +22 -26
- package/dist/web-admin-client/candidate-gate.d.ts +35 -3
- package/dist/web-admin-client/candidate-gate.js +53 -5
- package/dist/web-admin-client/center-request.d.ts +4 -1
- package/dist/web-admin-client/center-request.js +2 -1
- package/dist/web-admin-client/effective-keys.js +0 -1
- package/dist/web-admin-client/facade.d.ts +1 -1
- package/dist/web-admin-client/http-client.d.ts +1 -0
- package/dist/web-admin-client/http-client.js +17 -9
- package/dist/web-admin-client/restart-signal.js +5 -2
- package/dist/web-admin-client/skills-mcp.d.ts +20 -6
- package/dist/web-admin-client/skills-mcp.js +26 -21
- package/dist/web-admin-client/types.d.ts +34 -49
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +2 -2
- package/package.json +13 -12
- package/scripts/drain-check-local.mjs +2 -28
- package/scripts/drain-check.mysql.sql +2 -18
- package/scripts/drain-check.pg.sql +2 -18
- package/wire-changes/server@7.147.0.json +813 -0
|
@@ -186,24 +186,13 @@ export type OperatorRoster = Pick<ServiceConfig, "operatorPrincipals" | "operato
|
|
|
186
186
|
* · 名单非空 ⇒ 验过的主体在名单里才是;
|
|
187
187
|
* · 单用户形显式声明 `OPERATOR_SINGLE_USER=true` ⇒ 这台部署的**每个调用方**都是(单用户形只有一位用户,能到这台部署的就是他;边界是部署自己的
|
|
188
188
|
* 凭据门 —— 没配凭据的部署上,能连上端口的都是)。声明只在单用户形成立(起服不变量)。
|
|
189
|
-
* `principal` 必须是验过的身份(`gatedPrincipal`),绝不是自述头。全部运维面(审批队列、steer
|
|
189
|
+
* `principal` 必须是验过的身份(`gatedPrincipal`),绝不是自述头。全部运维面(审批队列、steer / interrupt / wake 的属主门旁路、记忆运维口、bake 门……)读这一只 —— 只答授权;
|
|
190
|
+
* 送话口的文本框架(`trusted`)从不读它(调用方的话恒 `trusted: false`,见 `routes/runs.ts` steer 口的注);
|
|
190
191
|
* 🔴 SINGLE mint point (E1):不要再造兄弟。
|
|
191
192
|
*/
|
|
192
193
|
export declare function explicitOperatorOk(principal: string | undefined, roster: OperatorRoster): boolean;
|
|
193
|
-
/** 「这台部署**有没有**运维」的唯一读法(名单非空 ∨ 单用户声明在场)—— 能力事实 `operatorLane
|
|
194
|
+
/** 「这台部署**有没有**运维」的唯一读法(名单非空 ∨ 单用户声明在场)—— 能力事实 `operatorLane` 读这一只(整理阀门的可达性告警随本条退役)。单用户形上,装了运维面的进程里它恒真(`operator-declaration-required`:服务进程起服第 1 段、`createHttpServer` 对不声明的单用户形拒),多租形上空名单 ⇒ 假。 */
|
|
194
195
|
export declare function operatorRosterPresent(roster: OperatorRoster): boolean;
|
|
195
|
-
/**
|
|
196
|
-
* 起服提示([ref]):单用户形(`REQUIRE_PRINCIPAL` 未开)+ 没有运维名册 ⇒ 一行 warn。「空名单 = 人人是」那条读法退役之后这一形没有运维:
|
|
197
|
-
* 运维口(诊断 `GET /v1/diagnostics/wiring` —— 每台 main.ts 装起来的部署都挂着它 —— 、`GET /v1/outcomes`、管理与记忆治理口)对谁都答 501,
|
|
198
|
-
* 审批队列(挂着时)只给每个调用方看自己的;补回它们只要一行配置 —— 不拒启:升级那一拍打掉一台今天跑得好好的单用户机器比一条提示重。
|
|
199
|
-
* 多租形不提示(它另有拒启不变量)。
|
|
200
|
-
*/
|
|
201
|
-
export declare function buildOperatorUndeclaredNotice(config: OperatorRoster & Pick<ServiceConfig, "requirePrincipal">): {
|
|
202
|
-
event: "operator_undeclared_single_user";
|
|
203
|
-
fields: {
|
|
204
|
-
detail: string;
|
|
205
|
-
};
|
|
206
|
-
} | undefined;
|
|
207
196
|
/**
|
|
208
197
|
* 起服一行:部署声明 `SERVICE_TOKEN_ACTS_FOR_DEPLOYMENT=false` ⇒ `service_token_posture { actsForDeployment: false }`(info);缺省不打。
|
|
209
198
|
* 声明形让运维面板开位当天成片 401,而「位关了」与「token 错了」在 wire 上同体(反探测律),这一行是起服时唯一一处说清这台部署选了哪一读法的地方。
|
|
@@ -209,19 +209,6 @@ export function explicitOperatorOk(principal, roster) {
|
|
|
209
209
|
export function operatorRosterPresent(roster) {
|
|
210
210
|
return roster.operatorSingleUser === true || roster.operatorPrincipals.length > 0;
|
|
211
211
|
}
|
|
212
|
-
export function buildOperatorUndeclaredNotice(config) {
|
|
213
|
-
if (config.requirePrincipal === true || operatorRosterPresent(config))
|
|
214
|
-
return undefined;
|
|
215
|
-
return {
|
|
216
|
-
event: "operator_undeclared_single_user",
|
|
217
|
-
fields: {
|
|
218
|
-
detail: "this single-user deployment declares no operator: OPERATOR_PRINCIPALS is empty and OPERATOR_SINGLE_USER is not set, so no caller is an operator — " +
|
|
219
|
-
"operator-only endpoints such as GET /v1/diagnostics/wiring, GET /v1/outcomes and the admin and memory-governance endpoints answer 501 capability.operator_principals_required to every caller, and " +
|
|
220
|
-
"the approval queues (GET /v1/approvals, its stream, /v1/assistant/inbox and /v1/assistant/tasks, where mounted) show each caller only its own pending approvals (a caller that sends no principal sees only the anonymous ones - the cards and tasks that were submitted without a principal - never a named principal's) and ignore ?owner=. " +
|
|
221
|
-
"To act as this deployment's operator, add one line: OPERATOR_SINGLE_USER=true",
|
|
222
|
-
},
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
212
|
export function buildServiceTokenPostureNotice(config) {
|
|
226
213
|
if (serviceTokenDeclaredActsForDeployment(config))
|
|
227
214
|
return undefined;
|
|
@@ -23,7 +23,7 @@ import { type SqlWallSource, type SqlWallsReading } from "../plugins/sql-driver.
|
|
|
23
23
|
*
|
|
24
24
|
* 🔴 **包墙腿是同一只规则的提前一跑,不是第二套规则**([ref] 主会话裁定):包墙是物理连接的事实(会话值,连接建立时从全局拷一份、此后不变),
|
|
25
25
|
* 终判在将要执行写入的那条连接上 —— 那是库自己(续跑输入那一笔被拒 ⇒ 店的带码拒 ⇒ 同一个 413;会话日志那一笔走它既有的失败面);SQL 快照 blob 则由
|
|
26
|
-
* `blob-
|
|
26
|
+
* 店的 blob 索引(`stores-sql/blob-index-sql.ts`)经 `connectJudged` 在写入连接上判。受理时手里没有那条连接,判官 `sqlWallsOf` 读的 `facts` 是池里**最近一次初始化**的那条连接的读数
|
|
27
27
|
* (`SqlDriver.facts`:池见过的最新读数,只在有连接初始化时才更新),同一个折算 `packetWallStatementBytes`:拒 ⇒ 413 在任何副作用之前;收 ⇒ 写入那条连接上的判决仍是终判。
|
|
28
28
|
* 这个读数是**缓存**,DBA 调了全局值之后、下一条连接初始化之前,它与库此刻的值两个方向都可能不一致:调大 ⇒ 受理口仍按旧的小值拒(新墙本装得下的体也 413,
|
|
29
29
|
* 直到有连接按新值初始化 —— 快照 blob 的旧连接自换就会带来一条);调小 ⇒ 受理口按旧的大值放行,写入那条连接上的库再拒(续跑输入那一笔 = 同一个 413)。
|
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
* (`RunRegistry` / `RouteHelpers` / `RouteLegs` / `ReturnType<typeof createRequestGuards>`),不手抄签名 ⇒ 不会漂。
|
|
13
13
|
*/
|
|
14
14
|
import type { IncomingMessage } from "node:http";
|
|
15
|
-
import { CheckpointError, type QuestionAnswer, type CheckpointToken } from "@sema-agent/core";
|
|
15
|
+
import { CheckpointError, type QuestionAnswer, type CheckpointToken, type PendingSteerInput } from "@sema-agent/core";
|
|
16
16
|
import type { DecideBinding, DecidedAction } from "./wire-types.js";
|
|
17
17
|
import type { CheckpointStoreFull } from "../plugins/store-backend.js";
|
|
18
18
|
import type { HostDecision } from "../host-decision.js";
|
|
19
19
|
import { type GateSighting } from "../approval-gate-currency.js";
|
|
20
20
|
import { type PlanApprovePermissionModeAfter } from "../task-settings.js";
|
|
21
|
-
import type { RouteCtxBase, DriveResumeArgs, PreparedPlanReview, ResumeLegOutcome, WorkflowDecisionDelivery } from "./route-ctx.js";
|
|
21
|
+
import type { RouteCtxBase, DriveResumeArgs, PreparedPlanReview, RememberSessionRequest, ResumeCheckpointOutcome, ResumeLegOutcome, WorkflowDecisionDelivery } from "./route-ctx.js";
|
|
22
22
|
import type { RunRegistry, RouteHelpers, RouteLegs } from "./route-ctx.js";
|
|
23
23
|
import type { createRequestGuards } from "./request-guards.js";
|
|
24
24
|
import type { FlatServiceDeps } from "./server.js";
|
|
@@ -75,13 +75,10 @@ export declare function createResumeLegs(ctx: {
|
|
|
75
75
|
runnerFor: FlatServiceDeps["runnerFor"];
|
|
76
76
|
} & RunRegistry & RouteHelpers & Pick<RouteLegs, "prepareSpec" | "finalizeTaskResult"> & Pick<ReturnType<typeof createRequestGuards>, "ownerCostQuotaDenied" | "ownerFleetLeaseDenied" | "usageWindowDenialFor">): {
|
|
77
77
|
routeCtxBase: RouteCtxBase;
|
|
78
|
-
resumeCheckpoint: (sessionId: string, decision: "approve" | "deny", reason: string | undefined, hostDecision: HostDecision, req: IncomingMessage | undefined, answer: QuestionAnswer | undefined, binding: DecideBinding,
|
|
79
|
-
overrideSessionId?: string;
|
|
80
|
-
rememberableToolName: string | null;
|
|
81
|
-
}) => Promise<void>, acceptEarly?: boolean, decider?: {
|
|
78
|
+
resumeCheckpoint: (sessionId: string, decision: "approve" | "deny", reason: string | undefined, hostDecision: HostDecision, req: IncomingMessage | undefined, answer: QuestionAnswer | undefined, binding: DecideBinding, remember?: RememberSessionRequest, acceptEarly?: boolean, decider?: {
|
|
82
79
|
principal?: string;
|
|
83
80
|
explicitOperator: boolean;
|
|
84
|
-
}, restatement?: ResumeRestatement) => Promise<
|
|
81
|
+
}, restatement?: ResumeRestatement) => Promise<ResumeCheckpointOutcome>;
|
|
85
82
|
driveResumeIntoRunLog: (args: DriveResumeArgs) => Promise<ResumeLegOutcome>;
|
|
86
83
|
driveResumeLeg: (args: DriveResumeArgs, onAccepted?: (receipt: {
|
|
87
84
|
status: number;
|
|
@@ -96,14 +93,14 @@ export declare function createResumeLegs(ctx: {
|
|
|
96
93
|
explicitOperator: boolean;
|
|
97
94
|
}, restatement?: ResumeRestatement) => Promise<ResumeLegOutcome>;
|
|
98
95
|
startFreshHostTurn: (sessionId: string, objective: string, principal: string | undefined, req: IncomingMessage, workflowDecision: WorkflowDecisionDelivery, runId: string, restatement?: ResumeRestatement) => Promise<ResumeLegOutcome>;
|
|
99
|
-
resumeWake: (sessionId: string, message:
|
|
96
|
+
resumeWake: (sessionId: string, message: PendingSteerInput | undefined, caller: string | undefined, req: IncomingMessage | undefined, acceptEarly?: boolean, workflowDecision?: WorkflowDecisionDelivery, ownerLeaseAdmittedFor?: string, restatement?: ResumeRestatement) => Promise<ResumeLegOutcome>;
|
|
100
97
|
preparePlanReview: (sessionId: string, log?: {
|
|
101
98
|
taskId?: string;
|
|
102
99
|
principalPresent?: boolean;
|
|
103
100
|
}, decider?: {
|
|
104
101
|
principal?: string;
|
|
105
102
|
explicitOperator: boolean;
|
|
106
|
-
}, sighting?: GateSighting) => Promise<{
|
|
103
|
+
}, sighting?: GateSighting, restatement?: ResumeRestatement) => Promise<{
|
|
107
104
|
readonly ok: false;
|
|
108
105
|
readonly answer: {
|
|
109
106
|
status: number;
|
|
@@ -113,7 +110,7 @@ export declare function createResumeLegs(ctx: {
|
|
|
113
110
|
readonly ok: true;
|
|
114
111
|
readonly prepared: PreparedPlanReview;
|
|
115
112
|
}>;
|
|
116
|
-
drivePlanReview: (prepared: PreparedPlanReview, decision: "approve" | "edit" | "reject", editedPlan: string | undefined, reason: string | undefined, hostDecision: HostDecision, req: IncomingMessage | undefined, acceptEarly?: boolean, permissionModeAfter?: PlanApprovePermissionModeAfter
|
|
113
|
+
drivePlanReview: (prepared: PreparedPlanReview, decision: "approve" | "edit" | "reject", editedPlan: string | undefined, reason: string | undefined, hostDecision: HostDecision, req: IncomingMessage | undefined, acceptEarly?: boolean, permissionModeAfter?: PlanApprovePermissionModeAfter) => Promise<ResumeLegOutcome>;
|
|
117
114
|
sessionNotifyDoor: import("../session-notify-door.js").SessionNotifyDoor;
|
|
118
115
|
};
|
|
119
116
|
//# sourceMappingURL=resume-legs.d.ts.map
|
package/dist/http/resume-legs.js
CHANGED
|
@@ -27,7 +27,7 @@ import { withPrincipal } from "../observability/principal-context.js";
|
|
|
27
27
|
import { withModelReachScope } from "../model-reach-scope.js";
|
|
28
28
|
import { legFactsOf } from "../leg-facts.js";
|
|
29
29
|
import { createInstructionSelectionLeg } from "../instruction-selection.js";
|
|
30
|
-
import { modelTextEventData, appendParkRow, turnEndEventData, contextUsageEventData, toolStartEventData, toolEndEventData, taskProgressEventData, taskStartedEventData, taskNotificationEventData, compactedEventData, diagnosticsEventData, brainStatusEventData, steeringInjectedEventData, compactionOutcomeEventData, compactionStartedEventData, workspaceChangedEventData, wiringManifestEventData, toolRosterDeltaEventData, toolDisclosureEventData, humanInputEventData, appendModelUsageDelta,
|
|
30
|
+
import { modelTextEventData, appendParkRow, turnEndEventData, contextUsageEventData, toolStartEventData, toolEndEventData, taskProgressEventData, taskStartedEventData, taskNotificationEventData, compactedEventData, diagnosticsEventData, brainStatusEventData, steeringInjectedEventData, compactionOutcomeEventData, compactionStartedEventData, workspaceChangedEventData, wiringManifestEventData, toolRosterDeltaEventData, toolDisclosureEventData, humanInputEventData, appendModelUsageDelta, attachModelUsage, createPromptManifestSeat } from "../trace/project.js";
|
|
31
31
|
import { redactSecrets } from "../trace/redact.js";
|
|
32
32
|
import { buildRunObjectivePreview } from "../user-authored-text.js";
|
|
33
33
|
import { createForwardAppendFailedNote, createLedgerSink, createSerialLedgerAppend } from "../trace/ledger-sink.js";
|
|
@@ -49,13 +49,14 @@ import { createCapabilitiesLocal } from "./routes/capabilities.js";
|
|
|
49
49
|
import { gatedPrincipal, explicitOperatorOk, runIdentityOf } from "./principal-gate.js";
|
|
50
50
|
import { buildActiveRunConflict, resumeEntryForGate } from "./active-run-conflict.js";
|
|
51
51
|
import { commitExecutionContext, isRootSessionGoneError, resolveExecutionContext, rootSessionAbsentAnswer, stampSpecRoot } from "./execution-context.js";
|
|
52
|
+
import { timeClaim } from "./claim-latency.js";
|
|
52
53
|
import { commitSessionInheritEnv } from "./session-inherit-env.js";
|
|
53
54
|
import { ASK_USER_QUESTION_TOOL_NAME, isApprovalGateKind, isEngineQuestionRow } from "../approval-content-kind.js";
|
|
54
55
|
import { deploymentListAsks } from "../approval.js";
|
|
55
56
|
import { isParkLedgerEventType } from "../trace/ledger-events.js";
|
|
56
57
|
import { readResumeCtx, resumeCtxCorruptAnswer, resumeCtxUnsealableAnswer } from "./resume-ctx-read.js";
|
|
57
58
|
import { objectiveWithheldIn } from "./submit-ctx.js";
|
|
58
|
-
import { buildCheckpointVersionKeys,
|
|
59
|
+
import { buildCheckpointVersionKeys, resumeAssemblyRefusalAnswer, resumeRefusalWithCard, sealCheckpointCtx, storedBodyReplayAnswer, storedBodyReplayLogFields, withPermissionModeRewritten } from "./checkpoint-ctx.js";
|
|
59
60
|
import { refusalBody, resumeRefusalFacts } from "./refusal-body.js";
|
|
60
61
|
import { storedBodyReplayRefusal } from "./stored-body-replay.js";
|
|
61
62
|
import { restateResumeCtx } from "./resume-restatement.js";
|
|
@@ -184,13 +185,13 @@ const WIRE_CODE_OF_DECISION_REFUSAL = {
|
|
|
184
185
|
[APPROVAL_ENDING_CAUSES.ANSWER_INVALID]: "resume_outcome_invalid",
|
|
185
186
|
[APPROVAL_ENDING_CAUSES.OUTCOME_CELL_INVALID]: "resume_outcome_invalid",
|
|
186
187
|
};
|
|
187
|
-
const UNCLASSIFIED_INVALID_OUTCOME_CODE = WIRE_CODE_OF_DECISION_REFUSAL[APPROVAL_ENDING_CAUSES.BINDING_CHANGED];
|
|
188
188
|
function decisionRefusalCauseOf(e, gate) {
|
|
189
|
-
if (
|
|
190
|
-
return
|
|
189
|
+
if (e.detail?.reason !== undefined)
|
|
190
|
+
return undefined;
|
|
191
191
|
const field = e.detail?.field;
|
|
192
|
-
|
|
193
|
-
|
|
192
|
+
if (field !== undefined)
|
|
193
|
+
return Object.hasOwn(CHECKPOINT_ERROR_FIELD_ROLE, field) ? FIELD_ROLE_CAUSE[CHECKPOINT_ERROR_FIELD_ROLE[field]] : undefined;
|
|
194
|
+
return gate === "policy_ask" ? undefined : APPROVAL_ENDING_CAUSES.OUTCOME_CELL_INVALID;
|
|
194
195
|
}
|
|
195
196
|
function notResumableAnswer() {
|
|
196
197
|
return { status: 409, body: refusalBody({ errorCode: "conflict.not_resumable", message: "run is not in a resumable (suspended) state (already resumed, decided, or expired)" }) };
|
|
@@ -208,14 +209,12 @@ function approvalStaleAnswer(facts) {
|
|
|
208
209
|
}),
|
|
209
210
|
};
|
|
210
211
|
}
|
|
211
|
-
function
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
return diagnostic === undefined ? verdict.sentence : `${verdict.sentence} Diagnostic: ${diagnostic}`;
|
|
212
|
+
function rowRefusalAnswer(verdict, diagnostic, ctx) {
|
|
213
|
+
const refusal = new CheckpointError(verdict.code, diagnostic === undefined ? verdict.sentence : `${verdict.sentence} Diagnostic: ${diagnostic}`, verdict.reason === undefined ? undefined : { reason: verdict.reason });
|
|
214
|
+
return checkpointRefusalAnswer(refusal, { gate: "policy_ask", retriable: resumeRefusalDisposition(refusal) === "retriable", versionKeys: refusalVersionKeys(refusal, ctx) });
|
|
215
215
|
}
|
|
216
|
-
function
|
|
217
|
-
|
|
218
|
-
return (e instanceof UnreadableCheckpointRowError ? rowRefusalMessageOf(e.rowVerdict, text) : undefined) ?? text;
|
|
216
|
+
function refusalVersionKeys(e, ctx) {
|
|
217
|
+
return e.code === "checkpoint.unsupported_version" ? buildCheckpointVersionKeys(ctx.writerVersion, serviceVersion()) : {};
|
|
219
218
|
}
|
|
220
219
|
function acceptableFormFacts(detail) {
|
|
221
220
|
const rewritten = detail !== null && typeof detail === "object" ? detail.editRewritten : undefined;
|
|
@@ -231,7 +230,7 @@ export function checkpointRefusalAnswer(e, at) {
|
|
|
231
230
|
status: e.code === "checkpoint.not_found" ? 404 : 409,
|
|
232
231
|
body: refusalBody({
|
|
233
232
|
message: e.message,
|
|
234
|
-
errorCode:
|
|
233
|
+
errorCode: refusalCause === undefined ? e.code : WIRE_CODE_OF_DECISION_REFUSAL[refusalCause],
|
|
235
234
|
facts: {
|
|
236
235
|
...(at.taskId !== undefined ? { taskId: at.taskId } : {}),
|
|
237
236
|
...resumeRefusalFacts(detail),
|
|
@@ -253,8 +252,33 @@ export function createResumeLegs(ctx) {
|
|
|
253
252
|
const { deps, runnerFor, idemCache, inflightRuns, preemptableRuns, steerableRuns, wakeParkMints, counters, readJson, readRawBody, rateLimited, quotaExceeded, ownerQuotaDenied, leaseDenied, ownerLeaseDenied, usageWindowDenied, admitRun, safeDecode, runOwnerOk, sessionOwnerOk, runSessionAcceptOk, prepareSpec, finalizeTaskResult, ownerCostQuotaDenied, ownerFleetLeaseDenied, usageWindowDenialFor } = ctx;
|
|
254
253
|
const ctxOpening = (sessionId) => ({ sessionId, opener: deps.checkpointCtxSealing });
|
|
255
254
|
const resumeFleetScope = (req, auth) => req ? (gatedPrincipal(req, deps.config) ?? "default") : (auth.principal ?? "default");
|
|
256
|
-
|
|
255
|
+
function createRememberIntent(sessionId, remember) {
|
|
256
|
+
let pending;
|
|
257
|
+
return {
|
|
258
|
+
laneCannotRecord: remember.laneCannotRecord,
|
|
259
|
+
record: async (grant) => {
|
|
260
|
+
if (grant.rememberableToolName !== null)
|
|
261
|
+
pending = { sessionId: grant.overrideSessionId ?? sessionId, toolName: grant.rememberableToolName };
|
|
262
|
+
},
|
|
263
|
+
settle: async (committed) => {
|
|
264
|
+
const store = deps.approvalExemptionStore;
|
|
265
|
+
if (!committed || pending === undefined || store === undefined)
|
|
266
|
+
return false;
|
|
267
|
+
try {
|
|
268
|
+
await store.grant(pending.sessionId, pending.toolName, remember.grantedBy);
|
|
269
|
+
deps.logger?.info?.("approval_exemption_granted", { sessionId: pending.sessionId, toolName: pending.toolName, grantedBy: remember.grantedBy });
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
catch (e) {
|
|
273
|
+
deps.logger?.warn?.("approval_exemption_grant_failed", { sessionId: pending.sessionId, toolName: pending.toolName, error: String(e).slice(0, 200) });
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
async function resumeCheckpoint(sessionId, decision, reason, hostDecision, req, answer, binding, remember, acceptEarly, decider, restatement) {
|
|
257
280
|
const cs = deps.checkpointStore;
|
|
281
|
+
const intent = remember !== undefined ? createRememberIntent(sessionId, remember) : undefined;
|
|
258
282
|
const token = await currentApprovalGateToken(cs, sessionId);
|
|
259
283
|
if (binding.checkpointToken && !sightsCurrentGate({ face: "checkpointToken", value: binding.checkpointToken }, token ? { checkpointToken: token } : null)) {
|
|
260
284
|
let seenUnreadable = false;
|
|
@@ -302,6 +326,7 @@ export function createResumeLegs(ctx) {
|
|
|
302
326
|
const ctxPromise = cs.getCtx(sessionId);
|
|
303
327
|
void ctxPromise.catch(() => { });
|
|
304
328
|
const noApproval = { status: 404, body: refusalBody({ errorCode: "not_found.approval", message: "approval not found" }) };
|
|
329
|
+
const rowOwnRefusal = async (verdict, diagnostic) => rowRefusalAnswer(verdict, diagnostic, verdict.code === "checkpoint.unsupported_version" ? ((await ctxPromise.catch(() => null)) ?? {}) : {});
|
|
305
330
|
let cp;
|
|
306
331
|
try {
|
|
307
332
|
cp = await cpPromise;
|
|
@@ -312,7 +337,9 @@ export function createResumeLegs(ctx) {
|
|
|
312
337
|
deps.logger?.warn?.("approval_decide_unreadable_row_withheld", { sessionId, note: "row unreadable and the caller's ownership of THAT token is unproven — folded into the uniform 404" });
|
|
313
338
|
return noApproval;
|
|
314
339
|
}
|
|
315
|
-
|
|
340
|
+
if (e instanceof UnreadableCheckpointRowError && e.rowVerdict.kind !== "ok")
|
|
341
|
+
return rowOwnRefusal(e.rowVerdict, errorText(e));
|
|
342
|
+
return { status: 409, body: refusalBody({ errorCode: "conflict.checkpoint_unreadable", message: errorText(e) }) };
|
|
316
343
|
}
|
|
317
344
|
if (!cp) {
|
|
318
345
|
if (!(await mayDiscloseRowError(cs, token, decider)))
|
|
@@ -328,10 +355,10 @@ export function createResumeLegs(ctx) {
|
|
|
328
355
|
}
|
|
329
356
|
const decideGateKind = cp.gate?.kind;
|
|
330
357
|
if (!isApprovalGateKind(decideGateKind)) {
|
|
358
|
+
const verdict = judgeCheckpointRow(cp);
|
|
359
|
+
if (verdict.kind !== "ok")
|
|
360
|
+
return rowOwnRefusal(verdict);
|
|
331
361
|
if (typeof decideGateKind !== "string" || decideGateKind === "") {
|
|
332
|
-
const rowSentence = rowRefusalMessageOf(judgeCheckpointRow(cp));
|
|
333
|
-
if (rowSentence !== undefined)
|
|
334
|
-
return { status: 409, body: refusalBody({ errorCode: "gate_not_tool_approval", message: rowSentence }) };
|
|
335
362
|
return { status: 409, body: refusalBody({ errorCode: "gate_not_tool_approval", message: "task is suspended on a gate whose kind this engine cannot read, so it cannot say which endpoint resolves it" }) };
|
|
336
363
|
}
|
|
337
364
|
const activeForPath = await deps.runStore?.getActiveTaskId(sessionId).catch(() => undefined);
|
|
@@ -379,8 +406,8 @@ export function createResumeLegs(ctx) {
|
|
|
379
406
|
standingAnswerDurablyRecordable(parkRowStandingAnswerFacts(paForGrant, cp.gate, deps.config, deploymentListAsks(deps.config, { toolName: paForGrant.toolName })))
|
|
380
407
|
? paForGrant.toolName
|
|
381
408
|
: null;
|
|
382
|
-
const boundGrant =
|
|
383
|
-
? (overrideSessionId) =>
|
|
409
|
+
const boundGrant = intent
|
|
410
|
+
? (overrideSessionId) => intent.record({ ...(overrideSessionId !== undefined ? { overrideSessionId } : {}), rememberableToolName: rememberableTool })
|
|
384
411
|
: undefined;
|
|
385
412
|
const lateSettleSink = deps.approvalLateSettle;
|
|
386
413
|
const lateSettleAnchor = lateSettleSink !== undefined && req !== undefined && token
|
|
@@ -390,8 +417,8 @@ export function createResumeLegs(ctx) {
|
|
|
390
417
|
checkpointTokenHash: buildCheckpointAnchorHash(token),
|
|
391
418
|
}
|
|
392
419
|
: undefined;
|
|
393
|
-
const noteLateSettleIfAccepted = (
|
|
394
|
-
if (lateSettleSink === undefined || lateSettleAnchor === undefined
|
|
420
|
+
const noteLateSettleIfAccepted = (committed) => {
|
|
421
|
+
if (!committed || lateSettleSink === undefined || lateSettleAnchor === undefined)
|
|
395
422
|
return;
|
|
396
423
|
try {
|
|
397
424
|
lateSettleSink.recordLateSettle({ ...lateSettleAnchor, outcome: decision === "approve" ? "allowed" : "denied", decidedBy: hostDecision.decidedBy, ...(hostDecision.approver !== undefined ? { approver: hostDecision.approver } : {}), settledAtMs: Date.now() });
|
|
@@ -400,6 +427,11 @@ export function createResumeLegs(ctx) {
|
|
|
400
427
|
recordFailOpen("server.approval-ask-audit.append-failed", `kind=late_settle err=${e instanceof Error ? e.message : String(e)}`);
|
|
401
428
|
}
|
|
402
429
|
};
|
|
430
|
+
const landAfterCommit = async (out) => {
|
|
431
|
+
const committed = decisionCommittedOf(out);
|
|
432
|
+
noteLateSettleIfAccepted(committed);
|
|
433
|
+
return intent === undefined ? out : { ...out, rememberApplied: await intent.settle(committed) };
|
|
434
|
+
};
|
|
403
435
|
const parkedForkQuotaDenial = req !== undefined ? ownerCostQuotaDenied(decodeCheckpointScope(cp.scope)) : undefined;
|
|
404
436
|
if (parkedForkQuotaDenial)
|
|
405
437
|
return parkedForkQuotaDenial;
|
|
@@ -425,7 +457,7 @@ export function createResumeLegs(ctx) {
|
|
|
425
457
|
binding: { ...(({ checkpointToken: _staleGuardOnly, ...rest }) => rest)(binding), ...action },
|
|
426
458
|
...(answer !== undefined ? { answer } : {}),
|
|
427
459
|
...(restatement !== undefined ? { restatement } : {}),
|
|
428
|
-
...(boundGrant ? {
|
|
460
|
+
...(boundGrant && intent ? { remember: { anchor: (rootSessionId) => boundGrant(rootSessionId), laneCannotRecord: intent.laneCannotRecord } } : {}),
|
|
429
461
|
};
|
|
430
462
|
if (origin?.kind === "background" && parkedAgentStore !== undefined && parkedSurface !== undefined) {
|
|
431
463
|
const parked = await withPrincipal(decodeCheckpointScope(cp.scope), () => decideParkedAgent({
|
|
@@ -446,7 +478,7 @@ export function createResumeLegs(ctx) {
|
|
|
446
478
|
if (isRootSessionGoneError(e))
|
|
447
479
|
return { ok: false, gone: true };
|
|
448
480
|
if (e instanceof HttpError)
|
|
449
|
-
return { ok: false, gone: false, answer: resumeRefusalWithCard(
|
|
481
|
+
return { ok: false, gone: false, answer: resumeRefusalWithCard(resumeAssemblyRefusalAnswer(e.status, httpErrorRefusal(e)), true) };
|
|
450
482
|
throw e;
|
|
451
483
|
}
|
|
452
484
|
const occupant = ctx.occupant;
|
|
@@ -460,8 +492,7 @@ export function createResumeLegs(ctx) {
|
|
|
460
492
|
...(deps.logger ? { warn: parkWarn } : {}),
|
|
461
493
|
}, { ...parkedReq, selectedGate: captureSelectedGate() }, { handle: origin.handle, row: origin.row }));
|
|
462
494
|
void ctxPromise.catch(() => { });
|
|
463
|
-
|
|
464
|
-
return parked;
|
|
495
|
+
return await landAfterCommit(parked);
|
|
465
496
|
}
|
|
466
497
|
if (origin?.kind === "workflow_parks_unreadable") {
|
|
467
498
|
void ctxPromise.catch(() => { });
|
|
@@ -512,7 +543,7 @@ export function createResumeLegs(ctx) {
|
|
|
512
543
|
const admittedPayer = decodeCheckpointScope(cp.scope);
|
|
513
544
|
const out = hostToken
|
|
514
545
|
? await resumeWake(plan.hostSessionId, plan.message, decider?.principal, req, acceptEarly, delivery, admittedPayer, restatement)
|
|
515
|
-
: await startFreshHostTurn(plan.hostSessionId, plan.message, admittedPayer, req, delivery, plan.runId, restatement);
|
|
546
|
+
: await startFreshHostTurn(plan.hostSessionId, plan.message.text, admittedPayer, req, delivery, plan.runId, restatement);
|
|
516
547
|
if (recordFailure !== undefined)
|
|
517
548
|
throw recordFailure.err;
|
|
518
549
|
if (acceptedTaskIdOf(out) === undefined)
|
|
@@ -557,8 +588,7 @@ export function createResumeLegs(ctx) {
|
|
|
557
588
|
};
|
|
558
589
|
const verifyRounds = verifyRoundsFromBody(ctx.body);
|
|
559
590
|
const driven = await driveResumeIntoRunLog({ peerLease: resolved.peerLease, execution: resolved.execution, runner: resolved.runner, legFacts: resolved.legFacts, token, sessionId: cp.sessionId, principal: auth.principal, fleetScope: resumeFleetScope(req, auth), taskConfig, resumeObjective, outcome, commitment: { kind: "gate_resolved", ...captureSelectedGate() }, verifyRounds, resumeCtx: { sessionId, ctx }, ...(engineNotices.length > 0 ? { engineNotices } : {}), ...(boundGrant ? { onResumeCommitted: boundGrant } : {}), ...(acceptEarly === true ? { acceptEarly: true } : {}), ...(req !== undefined ? { callerInitiated: true } : {}), ...(ownerLeaseAdmittedHere ? { ownerLeaseAdmitted: true } : {}) });
|
|
560
|
-
|
|
561
|
-
return driven;
|
|
591
|
+
return await landAfterCommit(driven);
|
|
562
592
|
}
|
|
563
593
|
finally {
|
|
564
594
|
resolved.peerLease.release();
|
|
@@ -597,7 +627,7 @@ export function createResumeLegs(ctx) {
|
|
|
597
627
|
catch (e) {
|
|
598
628
|
lease.release();
|
|
599
629
|
if (e instanceof HttpError) {
|
|
600
|
-
return { ok: false, answer: resumeRefusalWithCard(
|
|
630
|
+
return { ok: false, answer: resumeRefusalWithCard(resumeAssemblyRefusalAnswer(e.status, httpErrorRefusal(e)), true) };
|
|
601
631
|
}
|
|
602
632
|
throw e;
|
|
603
633
|
}
|
|
@@ -661,11 +691,11 @@ export function createResumeLegs(ctx) {
|
|
|
661
691
|
}
|
|
662
692
|
if (!taskId && args.mintFreshRun && deps.runStore) {
|
|
663
693
|
const freshId = uuidv7();
|
|
664
|
-
const created = await deps.runStore.createRun(freshId, sessionId, principal ?? null, deps.instanceId ?? "default", {
|
|
694
|
+
const created = await timeClaim(deps.metrics, "run_claim", deps.runStore.createRun(freshId, sessionId, principal ?? null, deps.instanceId ?? "default", {
|
|
665
695
|
source: args.mintFreshRun.source,
|
|
666
696
|
identity: args.mintFreshRun.identity,
|
|
667
697
|
objectivePreview: heldObjective === undefined ? null : buildRunObjectivePreview(heldObjective),
|
|
668
|
-
});
|
|
698
|
+
}));
|
|
669
699
|
if (created.existing) {
|
|
670
700
|
throw new Error(`wake fresh run: createRun observed an existing row for the freshly minted taskId ${freshId} (no idempotency key was sent) — refusing to treat it as a busy session`);
|
|
671
701
|
}
|
|
@@ -751,7 +781,7 @@ export function createResumeLegs(ctx) {
|
|
|
751
781
|
return { reopened: pending, leg };
|
|
752
782
|
};
|
|
753
783
|
let resumeHeartbeat;
|
|
754
|
-
let
|
|
784
|
+
let resumeManifestSeat;
|
|
755
785
|
let resumeStreamRef;
|
|
756
786
|
let resumeLegLive = false;
|
|
757
787
|
const subagentHandleEvictions = [];
|
|
@@ -787,7 +817,7 @@ export function createResumeLegs(ctx) {
|
|
|
787
817
|
}, HEARTBEAT_MS);
|
|
788
818
|
resumeHeartbeat.unref?.();
|
|
789
819
|
deps.modelUsage?.register(taskId);
|
|
790
|
-
|
|
820
|
+
resumeManifestSeat = createPromptManifestSeat(deps.promptManifests, taskId);
|
|
791
821
|
}
|
|
792
822
|
if (args.workflowDecision !== undefined && taskId === undefined) {
|
|
793
823
|
throw new Error("workflow decision delivery: no run row was claimed for the delivering leg — refusing to start a delivery whose decision could not be recorded against it");
|
|
@@ -899,7 +929,7 @@ export function createResumeLegs(ctx) {
|
|
|
899
929
|
const rs2 = deps.runStore;
|
|
900
930
|
try {
|
|
901
931
|
const ap = vAppend;
|
|
902
|
-
await
|
|
932
|
+
await resumeManifestSeat?.drain(ap);
|
|
903
933
|
if (reSuspended || vrReopened) {
|
|
904
934
|
const vrParkCallId = reSuspended ? await parkToolCallId(vr, deps.checkpointStore) : undefined;
|
|
905
935
|
await appendParkRow(ap, { modelUsage: deps.modelUsage, taskId }, reParkEvent ?? reparkStatus, { terminal: vrPaused, ...(vrParkCallId !== undefined ? { toolCallId: vrParkCallId } : {}) }, vrReopened ? (failureCodeOf(vr.terminal) ?? null) : undefined);
|
|
@@ -947,7 +977,7 @@ export function createResumeLegs(ctx) {
|
|
|
947
977
|
? async (eventId) => { const leaf = (await headOf(sessionId))?.leafId; if (leaf)
|
|
948
978
|
await deps.resumeAnchorStore.put(sessionId, eventId, leaf, anchorOwner); }
|
|
949
979
|
: undefined;
|
|
950
|
-
const captureUserMessageAnchor = deps.resumeAnchorStore && taskId
|
|
980
|
+
const captureUserMessageAnchor = deps.resumeAnchorStore && taskId && freshRunClaimed
|
|
951
981
|
? async (entryId) => { await deps.resumeAnchorStore.put(sessionId, taskId, entryId, anchorOwner); }
|
|
952
982
|
: undefined;
|
|
953
983
|
const anchor = new TurnAnchorCapture(captureTurnAnchor, "resume", captureUserMessageAnchor);
|
|
@@ -1048,7 +1078,7 @@ export function createResumeLegs(ctx) {
|
|
|
1048
1078
|
fleetPub?.onEvent(ev);
|
|
1049
1079
|
await deps.userInputLedger?.observeLegEvent(stream, ev);
|
|
1050
1080
|
await resumeWorkspace.observe(ev);
|
|
1051
|
-
await
|
|
1081
|
+
await resumeManifestSeat?.drain(append);
|
|
1052
1082
|
switch (ev.type) {
|
|
1053
1083
|
case "text_delta":
|
|
1054
1084
|
block += ev.delta;
|
|
@@ -1256,7 +1286,7 @@ export function createResumeLegs(ctx) {
|
|
|
1256
1286
|
settleFleet("failed");
|
|
1257
1287
|
}
|
|
1258
1288
|
}
|
|
1259
|
-
return checkpointRefusalAnswer(e, { gate: outcome.gate, retriable, ...(taskId !== undefined ? { taskId } : {}), versionKeys: e
|
|
1289
|
+
return checkpointRefusalAnswer(e, { gate: outcome.gate, retriable, ...(taskId !== undefined ? { taskId } : {}), versionKeys: refusalVersionKeys(e, resumeCtx.ctx) });
|
|
1260
1290
|
}
|
|
1261
1291
|
const thrownCause = cancelCtrl.cause();
|
|
1262
1292
|
if (thrownCause !== undefined) {
|
|
@@ -1290,7 +1320,7 @@ export function createResumeLegs(ctx) {
|
|
|
1290
1320
|
for (const evict of subagentHandleEvictions)
|
|
1291
1321
|
evict();
|
|
1292
1322
|
deps.modelUsage?.clear(taskId);
|
|
1293
|
-
|
|
1323
|
+
resumeManifestSeat?.release();
|
|
1294
1324
|
}
|
|
1295
1325
|
if (resumeHeartbeat)
|
|
1296
1326
|
clearInterval(resumeHeartbeat);
|
|
@@ -1497,10 +1527,9 @@ export function createResumeLegs(ctx) {
|
|
|
1497
1527
|
if (gateKind !== "task_done") {
|
|
1498
1528
|
return { status: 409, body: refusalBody({ errorCode: "wake.gate_pending", message: `cannot wake: this session is waiting on a pending gate decision (gate "${gateKind ?? "unknown"}") — resolve it through its own decide entry` }) };
|
|
1499
1529
|
}
|
|
1500
|
-
const trusted = operator;
|
|
1501
1530
|
if (message !== undefined) {
|
|
1502
1531
|
try {
|
|
1503
|
-
validatePendingSteer(
|
|
1532
|
+
validatePendingSteer(message);
|
|
1504
1533
|
}
|
|
1505
1534
|
catch (e) {
|
|
1506
1535
|
if (e instanceof CheckpointError && e.code === "steering.invalid_content") {
|
|
@@ -1535,7 +1564,7 @@ export function createResumeLegs(ctx) {
|
|
|
1535
1564
|
fleetScope: resumeFleetScope(req, auth),
|
|
1536
1565
|
taskConfig,
|
|
1537
1566
|
resumeObjective,
|
|
1538
|
-
outcome: { gate: "wake", ...(message !== undefined ? { message
|
|
1567
|
+
outcome: { gate: "wake", ...(message !== undefined ? { message } : {}) },
|
|
1539
1568
|
commitment: { kind: "delivered" },
|
|
1540
1569
|
verifyRounds: undefined,
|
|
1541
1570
|
resumeCtx: { sessionId, ctx },
|
|
@@ -1551,7 +1580,7 @@ export function createResumeLegs(ctx) {
|
|
|
1551
1580
|
resolved.peerLease.release();
|
|
1552
1581
|
}
|
|
1553
1582
|
}
|
|
1554
|
-
async function preparePlanReview(sessionId, log, decider, sighting) {
|
|
1583
|
+
async function preparePlanReview(sessionId, log, decider, sighting, restatement) {
|
|
1555
1584
|
const cs = deps.checkpointStore;
|
|
1556
1585
|
const refuse = (answer) => ({ ok: false, answer });
|
|
1557
1586
|
const log404 = (r) => deps.logger?.info?.("decide_404", {
|
|
@@ -1623,14 +1652,14 @@ export function createResumeLegs(ctx) {
|
|
|
1623
1652
|
return refuse(resumeCtxUnsealableAnswer(ctxRead));
|
|
1624
1653
|
if (ctxRead.kind === "absent")
|
|
1625
1654
|
return refuse({ status: 409, body: refusalBody({ errorCode: "conflict.resume_context_unavailable", message: "resume context missing — cannot rebuild task config" }) });
|
|
1626
|
-
const
|
|
1655
|
+
const ctx = restateResumeCtx(ctxRead.ctx, restatement);
|
|
1656
|
+
const replay = storedBodyReplayRefusal(ctx, deps.config);
|
|
1627
1657
|
if (replay !== undefined)
|
|
1628
1658
|
return refuse(refuseStoredBodyReplay(sessionId, replay));
|
|
1629
|
-
return { ok: true, prepared: { sessionId, token, cp, ctx
|
|
1659
|
+
return { ok: true, prepared: { sessionId, token, cp, ctx } };
|
|
1630
1660
|
}
|
|
1631
|
-
async function drivePlanReview(prepared, decision, editedPlan, reason, hostDecision, req, acceptEarly, permissionModeAfter
|
|
1632
|
-
const { sessionId, token, cp } = prepared;
|
|
1633
|
-
const ctx = restateResumeCtx(prepared.ctx, restatement);
|
|
1661
|
+
async function drivePlanReview(prepared, decision, editedPlan, reason, hostDecision, req, acceptEarly, permissionModeAfter) {
|
|
1662
|
+
const { sessionId, token, cp, ctx } = prepared;
|
|
1634
1663
|
if ((await deps.checkpointStore.findPendingTokenBySession(sessionId, undefined, { gateKinds: ["plan_review"] })) !== token)
|
|
1635
1664
|
return notResumableAnswer();
|
|
1636
1665
|
const auth = { sessionId: cp.sessionId, principal: decodeCheckpointScope(cp.scope), memoryScope: ctx.memoryScope };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* run 外回退口 `POST /v1/sessions/:id/rewind-files` 的 200 体 —— 引擎 `Runner.rewindFiles` 的结果(`RewindFilesResult`)**原形**,文本叶经出口座出门。
|
|
3
|
+
*
|
|
4
|
+
* 规则一句:形照引擎(`dryRun:true` ⇒ `{ preview }`,`null` 仍是 `null`;`dryRun:false` ⇒ `{ restore }` 台账,空数组仍是空数组),每一片自由文本叶只经
|
|
5
|
+
* {@link seatText} 的一行 —— 被跟踪文件的路径(台账 `filesChanged` / `identicalSkipped` / `refused[].path` / `failed[].path`、预览 `filesChanged`;源头是模型交的
|
|
6
|
+
* 路径参数)走 `rewind-ledger-path`(不设界:截过的路径就不是那个文件了);拒因 / 故障句(`refused[].reason` / `failed[].reason` / `error.message`)走
|
|
7
|
+
* `rewind-ledger-reason`;闭集词 / 计数逐字。台账上的店故障(core `FileHistoryError`)按本仓错误体的唯一机读键律出门:引擎的 `code` 成员在 wire 上叫
|
|
8
|
+
* `errorCode`(值逐字),`message` 经座,`permanence` 逐字 —— 本仓的 wire 上没有叫 `code` 的错误键。两张叶表与故障的三键按 core 型的键穷举 ——
|
|
9
|
+
* core 给台账 / 统计 / 故障加一格而这里不表态 ⇒ tsc 红;表外的运行期键不出门(按表取键,不展开原对象)。唯一调用方 = `http/routes/sessions.ts` 的 `session-rewind-files` 臂。
|
|
10
|
+
*/
|
|
11
|
+
import type { FileHistoryDiffStats, FileHistoryError, FileHistoryRestoreResult, RewindFilesResult } from "@sema-agent/core";
|
|
12
|
+
/** 台账上的店故障在 wire 上的形:码键 = `errorCode`(本仓错误体的唯一机读键),其余两键同引擎。 */
|
|
13
|
+
export interface RewindLedgerError {
|
|
14
|
+
readonly errorCode: FileHistoryError["code"];
|
|
15
|
+
readonly message: string;
|
|
16
|
+
readonly permanence?: FileHistoryError["permanence"];
|
|
17
|
+
}
|
|
18
|
+
/** 台账在 wire 上的形 = 引擎台账,`error` 换成 {@link RewindLedgerError}。 */
|
|
19
|
+
export type RewindLedgerReply = Omit<FileHistoryRestoreResult, "error"> & {
|
|
20
|
+
readonly error?: RewindLedgerError;
|
|
21
|
+
};
|
|
22
|
+
/** 200 体在 wire 上的形(引擎 `RewindFilesResult`,台账的 `error` 按 {@link RewindLedgerError})。 */
|
|
23
|
+
export type RewindFilesReply = {
|
|
24
|
+
readonly dryRun: true;
|
|
25
|
+
readonly preview: FileHistoryDiffStats | null;
|
|
26
|
+
} | {
|
|
27
|
+
readonly dryRun: false;
|
|
28
|
+
readonly restore: RewindLedgerReply & {
|
|
29
|
+
readonly outcome: "complete" | "partial";
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
/** 200 体(纯数据)。 */
|
|
33
|
+
export declare function buildRewindFilesReply(result: RewindFilesResult): RewindFilesReply;
|
|
34
|
+
//# sourceMappingURL=rewind-files-reply.d.ts.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { seatText } from "../trace/exit-seat.js";
|
|
2
|
+
function applyLeafTable(obj, table) {
|
|
3
|
+
const out = {};
|
|
4
|
+
for (const key of Object.keys(table)) {
|
|
5
|
+
const v = obj[key];
|
|
6
|
+
if (v !== undefined && v !== null)
|
|
7
|
+
out[key] = table[key](v);
|
|
8
|
+
}
|
|
9
|
+
return out;
|
|
10
|
+
}
|
|
11
|
+
const pathLeaf = (p) => seatText("rewind-ledger-path", p);
|
|
12
|
+
const reasonLeaf = (t) => seatText("rewind-ledger-reason", t);
|
|
13
|
+
function ledgerErrorOf(e) {
|
|
14
|
+
return { errorCode: e.code, message: reasonLeaf(e.message), ...(e.permanence !== undefined ? { permanence: e.permanence } : {}) };
|
|
15
|
+
}
|
|
16
|
+
const RESTORE_LEDGER_LEAVES = {
|
|
17
|
+
outcome: (v) => v,
|
|
18
|
+
filesChanged: (v) => v.map(pathLeaf),
|
|
19
|
+
identicalSkipped: (v) => v.map(pathLeaf),
|
|
20
|
+
refused: (v) => v.map((f) => ({ path: pathLeaf(f.path), reason: reasonLeaf(f.reason), class: f.class })),
|
|
21
|
+
failed: (v) => v.map((f) => ({ path: pathLeaf(f.path), reason: reasonLeaf(f.reason) })),
|
|
22
|
+
modeNotPreserved: (v) => v,
|
|
23
|
+
};
|
|
24
|
+
const DIFF_STATS_LEAVES = {
|
|
25
|
+
filesChanged: (v) => v.map(pathLeaf),
|
|
26
|
+
insertions: (v) => v,
|
|
27
|
+
deletions: (v) => v,
|
|
28
|
+
};
|
|
29
|
+
export function buildRewindFilesReply(result) {
|
|
30
|
+
if (result.dryRun)
|
|
31
|
+
return { dryRun: true, preview: result.preview === null ? null : applyLeafTable(result.preview, DIFF_STATS_LEAVES) };
|
|
32
|
+
const { error, ...ledger } = result.restore;
|
|
33
|
+
const projected = applyLeafTable(ledger, RESTORE_LEDGER_LEAVES);
|
|
34
|
+
return { dryRun: false, restore: { ...projected, outcome: result.restore.outcome, ...(error !== undefined ? { error: ledgerErrorOf(error) } : {}) } };
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=rewind-files-reply.js.map
|