@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
package/dist/rules-consent.js
CHANGED
|
@@ -114,8 +114,12 @@ function isCommandRuleMatch(match) {
|
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
const unknownReasonLogger = createLogger();
|
|
117
|
-
function confirmRefusalWord(
|
|
117
|
+
function confirmRefusalWord(confirmed) {
|
|
118
|
+
const { reason } = confirmed;
|
|
118
119
|
switch (reason) {
|
|
120
|
+
case "store_read":
|
|
121
|
+
case "store_write":
|
|
122
|
+
throw new RuleStoreFaultError({ code: reason, reason: confirmed.detail?.message ?? reason });
|
|
119
123
|
case "edit_disabled":
|
|
120
124
|
case "edit_binding_mismatch":
|
|
121
125
|
return "edit-unsupported";
|
|
@@ -137,7 +141,7 @@ function confirmRefusalWord(reason) {
|
|
|
137
141
|
}
|
|
138
142
|
}
|
|
139
143
|
}
|
|
140
|
-
function isRuleStoreFault(code) {
|
|
144
|
+
export function isRuleStoreFault(code) {
|
|
141
145
|
switch (code) {
|
|
142
146
|
case "store_read":
|
|
143
147
|
case "store_write":
|
|
@@ -158,8 +162,11 @@ function isRuleStoreFault(code) {
|
|
|
158
162
|
case "occ":
|
|
159
163
|
case "dot_removed":
|
|
160
164
|
return false;
|
|
161
|
-
default:
|
|
162
|
-
|
|
165
|
+
default: {
|
|
166
|
+
const unknown = code;
|
|
167
|
+
unknownReasonLogger.warn("isRuleStoreFault: unknown RuleRefusalCode from core (dist/core version skew?) — read as not a store failure", { code: String(unknown) });
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
163
170
|
}
|
|
164
171
|
}
|
|
165
172
|
class RuleStoreFaultError extends Error {
|
|
@@ -170,17 +177,37 @@ class RuleStoreFaultError extends Error {
|
|
|
170
177
|
this.code = refusal.code;
|
|
171
178
|
}
|
|
172
179
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
if (!
|
|
180
|
+
const retriableSkewLogger = createLogger();
|
|
181
|
+
function throwIfRetriable(refusal) {
|
|
182
|
+
if (!refusal.retriable)
|
|
176
183
|
return;
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
+
const { code } = refusal;
|
|
185
|
+
if (isRuleStoreFault(code))
|
|
186
|
+
throw new RuleStoreFaultError({ code, reason: refusal.reason });
|
|
187
|
+
retriableSkewLogger.warn("an engine refusal says retriable but its code is not a store failure (core/dist skew?) — not retried", { code });
|
|
188
|
+
}
|
|
189
|
+
export function confirmRefusalRetries(reason) {
|
|
190
|
+
switch (reason) {
|
|
191
|
+
case "conflict":
|
|
192
|
+
case "store_read":
|
|
193
|
+
case "store_write":
|
|
194
|
+
return true;
|
|
195
|
+
case "record_not_found":
|
|
196
|
+
case "record_schema_stale":
|
|
197
|
+
case "record_malformed":
|
|
198
|
+
case "selection_missing":
|
|
199
|
+
case "selection_invalid":
|
|
200
|
+
case "selection_mismatch":
|
|
201
|
+
case "not_pending":
|
|
202
|
+
case "edit_disabled":
|
|
203
|
+
case "edit_binding_mismatch":
|
|
204
|
+
case "edit_rejected":
|
|
205
|
+
return false;
|
|
206
|
+
default: {
|
|
207
|
+
const unknown = reason;
|
|
208
|
+
unknownReasonLogger.warn("confirmRefusalRetries: unknown ConfirmRefusalReason from core (dist/core version skew?) — read as not retriable", { reason: String(unknown) });
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
184
211
|
}
|
|
185
212
|
}
|
|
186
213
|
function refusedMembersOf(members) {
|
|
@@ -287,39 +314,51 @@ function buildLocalImportLayers(candidates) {
|
|
|
287
314
|
return root === "" ? { layer: "userSettings", path: LOCAL_IMPORT_LAYER_PATH, readFile } : { layer: "projectSettings", path: `${LOCAL_IMPORT_LAYER_PATH}:${root}`, root, readFile };
|
|
288
315
|
});
|
|
289
316
|
}
|
|
290
|
-
function
|
|
291
|
-
|
|
317
|
+
function settleImportWalk(members) {
|
|
318
|
+
const settled = [];
|
|
319
|
+
for (const m of members) {
|
|
292
320
|
const key = { behavior: m.behavior, rule: m.rule, scope: serializeRuleScope(m.scope) };
|
|
293
321
|
switch (m.status) {
|
|
294
322
|
case "persisted":
|
|
295
|
-
|
|
323
|
+
settled.push({ key, outcome: "persisted" });
|
|
324
|
+
break;
|
|
296
325
|
case "deduped":
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
326
|
+
settled.push({ key, outcome: "no-op" });
|
|
327
|
+
break;
|
|
328
|
+
case "refused": {
|
|
329
|
+
const open = openRefusalOf(m);
|
|
330
|
+
if (open !== undefined)
|
|
331
|
+
return { open: `the outcome of ${m.rule} is not settled (${m.code}, ${open}): ${m.reason}` };
|
|
332
|
+
settled.push({ key, outcome: "refused", reason: m.code, detail: m.reason });
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
300
335
|
default: {
|
|
301
336
|
const unknown = m;
|
|
302
337
|
throw new Error(`unknown redeemed-batch member status: ${JSON.stringify(unknown)}`);
|
|
303
338
|
}
|
|
304
339
|
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
function unsettledDetailOf(members) {
|
|
308
|
-
const open = members.find((m) => m.outcome === "indeterminate");
|
|
309
|
-
return open === undefined ? undefined : `the outcome of ${open.key.rule} is not known (${open.reason ?? "unknown"}): ${open.detail ?? ""}`;
|
|
340
|
+
}
|
|
341
|
+
return { settled };
|
|
310
342
|
}
|
|
311
|
-
function
|
|
312
|
-
|
|
343
|
+
function openRefusalOf(refusal) {
|
|
344
|
+
if (refusal.retriable)
|
|
345
|
+
return "retriable";
|
|
346
|
+
switch (refusal.committed) {
|
|
313
347
|
case "no":
|
|
314
|
-
return
|
|
348
|
+
return undefined;
|
|
315
349
|
case "unknown":
|
|
316
|
-
return "
|
|
350
|
+
return "committed unknown";
|
|
317
351
|
default: {
|
|
318
|
-
const unknown = committed;
|
|
352
|
+
const unknown = refusal.committed;
|
|
319
353
|
throw new Error(`unknown redeemed-batch member committed word: ${JSON.stringify(unknown)}`);
|
|
320
354
|
}
|
|
321
355
|
}
|
|
322
356
|
}
|
|
357
|
+
function importRecordRefusal(refusal) {
|
|
358
|
+
if (!refusal.retriable)
|
|
359
|
+
throw new Error(`the engine refused to prepare this import and says repeating will not help (${refusal.code}): ${refusal.reason}`);
|
|
360
|
+
return { ok: false, reason: "record-store-refused", committed: refusal.committed, detail: refusal.reason };
|
|
361
|
+
}
|
|
323
362
|
export function createRuleConsentLane(stores, opts) {
|
|
324
363
|
const deps = { provider: stores.provider, approvals: stores.approvals, cardEdits: true };
|
|
325
364
|
const ticketTtlMs = opts?.ticketTtlMs ?? RULE_IMPORT_TICKET_TTL_MS;
|
|
@@ -351,6 +390,10 @@ export function createRuleConsentLane(stores, opts) {
|
|
|
351
390
|
if (prepared === undefined) {
|
|
352
391
|
return { ok: false, reason: "no-candidates", detail: "the rule lane cannot speak for this command (compound / redirection / unsupported tool)" };
|
|
353
392
|
}
|
|
393
|
+
if ("status" in prepared) {
|
|
394
|
+
throwIfRetriable(prepared);
|
|
395
|
+
return { ok: false, reason: "redeem-refused", detail: prepared.reason };
|
|
396
|
+
}
|
|
354
397
|
const redemption = input.redemption;
|
|
355
398
|
if (redemption.kind === "batch") {
|
|
356
399
|
const wanted = new Set(redemption.offer.rules.map((r) => r.rule));
|
|
@@ -360,17 +403,17 @@ export function createRuleConsentLane(stores, opts) {
|
|
|
360
403
|
}
|
|
361
404
|
const confirmed = await confirmRuleApproval({ approvalId: prepared.approvalId, principal: input.principal, selectedOffer: offerIndex, deps });
|
|
362
405
|
if (!confirmed.ok)
|
|
363
|
-
return { ok: false, reason:
|
|
406
|
+
return { ok: false, reason: confirmRefusalWord(confirmed), detail: confirmed.detail?.message ?? confirmed.reason };
|
|
364
407
|
const result = await redeemRuleBatch({ approvalId: prepared.approvalId, principal: input.principal, deps });
|
|
365
408
|
if ("status" in result) {
|
|
366
|
-
|
|
409
|
+
throwIfRetriable(result);
|
|
367
410
|
return { ok: false, reason: "redeem-refused", detail: result.reason };
|
|
368
411
|
}
|
|
369
412
|
const refused = refusedMembersOf(result.members);
|
|
370
413
|
if (refused.length > 0) {
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
414
|
+
const first = refused[0];
|
|
415
|
+
if (first !== undefined && refused.length === result.members.length && refused.every((m) => m.retriable))
|
|
416
|
+
throwIfRetriable(first);
|
|
374
417
|
return { ok: false, reason: "redeem-refused", detail: `partial batch: ${refused.length} member(s) refused (${refused.map((x) => x.reason).join("; ")})` };
|
|
375
418
|
}
|
|
376
419
|
return { ok: true, ...anchorBatchMembers(result.members, redemption.offer), rev: result.rev };
|
|
@@ -385,7 +428,7 @@ export function createRuleConsentLane(stores, opts) {
|
|
|
385
428
|
}
|
|
386
429
|
const confirmed = await confirmRuleApproval({ approvalId: prepared.approvalId, principal: input.principal, selectedOffer: offerIndex, deps });
|
|
387
430
|
if (!confirmed.ok)
|
|
388
|
-
return { ok: false, reason:
|
|
431
|
+
return { ok: false, reason: confirmRefusalWord(confirmed), detail: confirmed.detail?.message ?? confirmed.reason };
|
|
389
432
|
ticket = offered;
|
|
390
433
|
}
|
|
391
434
|
else {
|
|
@@ -403,7 +446,7 @@ export function createRuleConsentLane(stores, opts) {
|
|
|
403
446
|
deps,
|
|
404
447
|
});
|
|
405
448
|
if (!confirmed.ok)
|
|
406
|
-
return { ok: false, reason: confirmRefusalWord(confirmed
|
|
449
|
+
return { ok: false, reason: confirmRefusalWord(confirmed), detail: confirmed.detail?.message ?? confirmed.reason };
|
|
407
450
|
const minted = confirmed.mintedCandidate;
|
|
408
451
|
if (minted === undefined) {
|
|
409
452
|
return { ok: false, reason: "confirm-refused", detail: "the edited confirmation landed without a minted candidate — nothing to redeem" };
|
|
@@ -419,7 +462,7 @@ export function createRuleConsentLane(stores, opts) {
|
|
|
419
462
|
}
|
|
420
463
|
const redeemed = await redeemRuleTicket({ ticket, principal: input.principal, deps });
|
|
421
464
|
if (redeemed.status !== "redeemed") {
|
|
422
|
-
|
|
465
|
+
throwIfRetriable(redeemed);
|
|
423
466
|
return { ok: false, reason: "redeem-refused", detail: redeemed.reason };
|
|
424
467
|
}
|
|
425
468
|
return { ok: true, kind: "single", rule: redeemed.rule, rev: redeemed.rev, alreadyRedeemed: redeemed.alreadyRedeemed };
|
|
@@ -429,7 +472,10 @@ export function createRuleConsentLane(stores, opts) {
|
|
|
429
472
|
const readFile = async () => l.content;
|
|
430
473
|
return l.layer === "userSettings" ? { layer: l.layer, path: l.path, readFile } : { layer: l.layer, path: l.path, root: l.root, readFile };
|
|
431
474
|
});
|
|
432
|
-
const
|
|
475
|
+
const prepared = await prepareCcImport({ layers: ccLayers, principal, deps });
|
|
476
|
+
if ("status" in prepared)
|
|
477
|
+
return importRecordRefusal(prepared);
|
|
478
|
+
const { preview, approvalId } = prepared;
|
|
433
479
|
if (approvalId === undefined) {
|
|
434
480
|
return { ok: true, preview };
|
|
435
481
|
}
|
|
@@ -509,8 +555,8 @@ export function createRuleConsentLane(stores, opts) {
|
|
|
509
555
|
if (record.state === "pending") {
|
|
510
556
|
const confirmed = await confirmRuleApproval({ approvalId: consumed.approvalId, principal, deps });
|
|
511
557
|
if (!confirmed.ok) {
|
|
512
|
-
if (confirmed.reason
|
|
513
|
-
return await indeterminate(confirmed.reason);
|
|
558
|
+
if (confirmRefusalRetries(confirmed.reason))
|
|
559
|
+
return await indeterminate(confirmed.detail?.message ?? confirmed.reason);
|
|
514
560
|
return { ok: false, reason: "record-unusable", detail: confirmed.reason };
|
|
515
561
|
}
|
|
516
562
|
}
|
|
@@ -518,11 +564,10 @@ export function createRuleConsentLane(stores, opts) {
|
|
|
518
564
|
if ("status" in result) {
|
|
519
565
|
return await indeterminate(result.reason);
|
|
520
566
|
}
|
|
521
|
-
const
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
return { ok: true, outcome: { members, rev: result.rev } };
|
|
567
|
+
const walk = settleImportWalk(result.members);
|
|
568
|
+
if ("open" in walk)
|
|
569
|
+
return await indeterminate(walk.open);
|
|
570
|
+
return { ok: true, outcome: { members: walk.settled, rev: result.rev } };
|
|
526
571
|
}
|
|
527
572
|
catch (err) {
|
|
528
573
|
return await indeterminate(err instanceof Error ? err.message : String(err));
|
|
@@ -580,7 +625,10 @@ export function createRuleConsentLane(stores, opts) {
|
|
|
580
625
|
}
|
|
581
626
|
if (allows.length === 0)
|
|
582
627
|
return { ok: true, preview: { members } };
|
|
583
|
-
const
|
|
628
|
+
const prepared = await prepareCcImport({ layers: buildLocalImportLayers(allows), principal, deps });
|
|
629
|
+
if ("status" in prepared)
|
|
630
|
+
return importRecordRefusal(prepared);
|
|
631
|
+
const { preview, approvalId } = prepared;
|
|
584
632
|
const engineKeys = new Set(preview.candidates.map((c) => `${c.behavior}${LOCAL_IMPORT_KEY_SEP}${serializeRuleScope(c.scope)}${LOCAL_IMPORT_KEY_SEP}${c.rule}`));
|
|
585
633
|
for (let i = 0; i < members.length; i++) {
|
|
586
634
|
const m = members[i];
|
|
@@ -669,8 +717,8 @@ export function createRuleConsentLane(stores, opts) {
|
|
|
669
717
|
if (record.state === "pending") {
|
|
670
718
|
const confirmed = await confirmRuleApproval({ approvalId, principal, deps });
|
|
671
719
|
if (!confirmed.ok) {
|
|
672
|
-
if (confirmed.reason
|
|
673
|
-
return await transient(confirmed.reason);
|
|
720
|
+
if (confirmRefusalRetries(confirmed.reason))
|
|
721
|
+
return await transient(confirmed.detail?.message ?? confirmed.reason);
|
|
674
722
|
return await verdict("record-unusable", confirmed.reason);
|
|
675
723
|
}
|
|
676
724
|
}
|
|
@@ -678,11 +726,11 @@ export function createRuleConsentLane(stores, opts) {
|
|
|
678
726
|
if ("status" in result) {
|
|
679
727
|
return await transient(result.reason);
|
|
680
728
|
}
|
|
681
|
-
|
|
729
|
+
const walk = settleImportWalk(result.members);
|
|
730
|
+
if ("open" in walk)
|
|
731
|
+
return await transient(walk.open);
|
|
732
|
+
members = walk.settled;
|
|
682
733
|
rev = result.rev;
|
|
683
|
-
const open = unsettledDetailOf(members);
|
|
684
|
-
if (open !== undefined)
|
|
685
|
-
return await transient(open);
|
|
686
734
|
}
|
|
687
735
|
catch (err) {
|
|
688
736
|
return await transient(err instanceof Error ? err.message : String(err));
|
package/dist/run-local.js
CHANGED
|
@@ -23,7 +23,7 @@ import { buildUnpricedCeilingNotice, isRosterGateArmed, loadConfig, logConfigDia
|
|
|
23
23
|
import { buildStoreOpenRefusalTail } from "./plugins/store-open-refusal.js";
|
|
24
24
|
import { acquireLocalBackendWithWait } from "./plugins/store-lock-wait.js";
|
|
25
25
|
import { configLocalRoot, createConfigProvider } from "./config-provider.js";
|
|
26
|
-
import { CONFIG_DOMAIN_INVALID_NOTE, buildCandidateRejectedFields, judgeConfigCandidate } from "./web-admin-client/candidate-gate.js";
|
|
26
|
+
import { CONFIG_DOMAIN_INVALID_NOTE, buildCandidateRejectedFields, buildCandidateRejectionNotes, judgeConfigCandidate } from "./web-admin-client/candidate-gate.js";
|
|
27
27
|
import { buildUnreadConfigFileFields, buildUnreadConfigKeyFields } from "./web-admin-client/read-warnings.js";
|
|
28
28
|
import { composeExecutionLane, settleHostLaneShell, warnReadDenyFloorUnkept } from "./boot/execution-lane.js";
|
|
29
29
|
import { judgeConsolidationValve } from "./boot/memory-consolidation.js";
|
|
@@ -316,6 +316,7 @@ function buildUnfinishedStopFooter(stop, sessionId) {
|
|
|
316
316
|
}
|
|
317
317
|
}
|
|
318
318
|
}
|
|
319
|
+
const RUN_LOCAL_LANE_ENTRY = { name: "run-local", runs: ["host", "none"], declares: "host" };
|
|
319
320
|
export const RUN_LOCAL_CONFIG_SOURCE_REFUSAL = "CONFIG_PROVIDER=remote: run-local reads its configuration from the local config directory only — it does not pull a web-admin center " +
|
|
320
321
|
"(center credential renewal, sealed model keys and the roster gate are assembled by the HTTP service). Unset CONFIG_PROVIDER or set " +
|
|
321
322
|
"CONFIG_PROVIDER=local for this command, or run the HTTP service to use the center.";
|
|
@@ -345,30 +346,31 @@ export async function runLocal(argv, deps = {}) {
|
|
|
345
346
|
if (args.root)
|
|
346
347
|
process.env.CONFIG_LOCAL_DIR = args.root;
|
|
347
348
|
declareServerWithheldEnv();
|
|
348
|
-
const
|
|
349
|
-
bindOwnCredentialsConfig(
|
|
350
|
-
const root = configLocalRoot(
|
|
351
|
-
const logger = deps.logger ?? createLogger(
|
|
349
|
+
const loaded = loadConfig();
|
|
350
|
+
bindOwnCredentialsConfig(loaded);
|
|
351
|
+
const root = configLocalRoot(loaded);
|
|
352
|
+
const logger = deps.logger ?? createLogger(loaded.logLevel);
|
|
352
353
|
const metrics = createMetrics();
|
|
353
354
|
const memoryEngineIncident = createMemoryEngineIncidentSink({ logger, metrics });
|
|
354
355
|
installSecretEnvScrubRecorder({ logger, metrics });
|
|
355
356
|
installDefaultEngineNoticeSeat(logger, metrics);
|
|
356
357
|
logConfigDiagnostics(logger);
|
|
357
|
-
provisionSemaConfigDir(
|
|
358
|
+
provisionSemaConfigDir(loaded, logger);
|
|
358
359
|
installOutboundDispatcher(logger);
|
|
359
|
-
const providerInput = { provider: "local", localDir: root, localOwnerUid:
|
|
360
|
+
const providerInput = { provider: "local", localDir: root, localOwnerUid: loaded.configLocalOwnerUid };
|
|
360
361
|
try {
|
|
361
|
-
await assertLocalConfigDirTrusted({ root, declaredOwnerUid:
|
|
362
|
+
await assertLocalConfigDirTrusted({ root, declaredOwnerUid: loaded.configLocalOwnerUid });
|
|
362
363
|
}
|
|
363
364
|
catch (err) {
|
|
364
365
|
printErr(err instanceof Error ? err.message : String(err));
|
|
365
366
|
return 2;
|
|
366
367
|
}
|
|
367
|
-
const envModelsMigration = { root, env: process.env, envTableIsPlaceholder: isRosterGateArmed(
|
|
368
|
+
const envModelsMigration = { root, env: process.env, envTableIsPlaceholder: isRosterGateArmed(loaded.webAdmin) };
|
|
368
369
|
logEnvModelsMigration(logger, envModelsMigration, await runEnvModelsMigration(envModelsMigration));
|
|
369
370
|
logConfigDirMigration(logger, await migrateLocalConfigDirectory(root));
|
|
371
|
+
let config;
|
|
370
372
|
try {
|
|
371
|
-
await composeExecutionLane(
|
|
373
|
+
config = await composeExecutionLane(loaded, { configSource: "local", localRoot: root, logger, entry: RUN_LOCAL_LANE_ENTRY });
|
|
372
374
|
}
|
|
373
375
|
catch (err) {
|
|
374
376
|
printErr(err instanceof Error ? err.message : String(err));
|
|
@@ -379,12 +381,14 @@ export async function runLocal(argv, deps = {}) {
|
|
|
379
381
|
const rosterLease = peerDesk.lease("roster");
|
|
380
382
|
let effective;
|
|
381
383
|
let candidatePrompts;
|
|
384
|
+
let candidateRejectionNotes;
|
|
382
385
|
let applying = false;
|
|
383
386
|
try {
|
|
384
387
|
const r = await configProvider.fetchEffective(undefined);
|
|
385
388
|
if (r) {
|
|
386
389
|
const verdict = judgeConfigCandidate(r);
|
|
387
390
|
if (verdict.verdict === "rejected") {
|
|
391
|
+
candidateRejectionNotes = buildCandidateRejectionNotes({ errors: verdict.errors, ...(configProvider.kind === "local" ? { dir: root } : {}) });
|
|
388
392
|
for (const de of r.domainErrors ?? [])
|
|
389
393
|
logger.warn("config_domain_invalid", { domain: de.domain, error: de.error, note: CONFIG_DOMAIN_INVALID_NOTE });
|
|
390
394
|
logger.warn("config_candidate_rejected", buildCandidateRejectedFields(r, verdict, "run-local", { lkgVersion: "(env)", ...(configProvider.kind === "local" ? { dir: root } : {}) }));
|
|
@@ -419,7 +423,7 @@ export async function runLocal(argv, deps = {}) {
|
|
|
419
423
|
else
|
|
420
424
|
logger.warn("config_source_unreachable_using_env", { source: configProvider.kind, err: String(err) });
|
|
421
425
|
}
|
|
422
|
-
const noDefaultModel = defaultModelRefusal(config, servedModelTableLeg(config));
|
|
426
|
+
const noDefaultModel = defaultModelRefusal({ models: config.models, modelRefusals: config.modelRefusals, candidateRejectionNotes }, servedModelTableLeg(config));
|
|
423
427
|
if (noDefaultModel !== undefined)
|
|
424
428
|
throw new Error(noDefaultModel);
|
|
425
429
|
const routeVerdict = judgeServedModelRoute(config, { envTableIsPlaceholder: false });
|
|
@@ -474,7 +478,7 @@ export async function runLocal(argv, deps = {}) {
|
|
|
474
478
|
}
|
|
475
479
|
const sessionStore = fileBackend.sessionStore;
|
|
476
480
|
const keyResolver = createKeyResolver(config.modelApiKeyEnv, process.env, config.modelApiKeys);
|
|
477
|
-
const hostRx = config.remoteExec
|
|
481
|
+
const hostRx = config.remoteExec.provider === "host" ? config.remoteExec : undefined;
|
|
478
482
|
const workspaceDir = args.workspace ?? hostRx?.workspaceBase ?? process.cwd();
|
|
479
483
|
await settleHostLaneShell(config, logger);
|
|
480
484
|
warnReadDenyFloorUnkept(config, logger);
|
|
@@ -720,7 +724,7 @@ export async function runLocal(argv, deps = {}) {
|
|
|
720
724
|
...(a2a ? { a2a } : {}),
|
|
721
725
|
...(Object.keys(limits).length > 0 ? { limits } : {}),
|
|
722
726
|
}, config, workspaceDir), onAsk);
|
|
723
|
-
logger.info("run_local_start", { scenario: scenarioName, model: spec.model, sessionId, exec:
|
|
727
|
+
logger.info("run_local_start", { scenario: scenarioName, model: spec.model, sessionId, exec: config.remoteExec.provider });
|
|
724
728
|
const settleSessionBackground = async () => {
|
|
725
729
|
const reaped = defaultTaskRegistry.reapSessionBackground(sessionId, scope);
|
|
726
730
|
if (reaped === 0)
|
package/dist/runs.d.ts
CHANGED
|
@@ -151,33 +151,40 @@ export declare function releaseKeyIfZeroWorkRefusal(runStore: {
|
|
|
151
151
|
* observable instead of a silent feature outage.
|
|
152
152
|
*/
|
|
153
153
|
/**
|
|
154
|
-
*
|
|
155
|
-
* 腿的 `userMsgEntryId`)
|
|
154
|
+
* 「这一次用户消息提交是不是这个 run 的**开场提示**」的唯一读法 —— 三处用户回退锚(后台腿与续跑腿的 {@link TurnAnchorCapture}、`/v1/tasks/stream`
|
|
155
|
+
* 腿的 `userMsgEntryId`)同调这一只;调用点零各自判、零按正文判,且都是「最后一次交出的赢」。
|
|
156
156
|
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
157
|
+
* **回退锚 = 该轮开场提示,一个 run 一个(开场窗 + 闩)**:run 一开始就开着一个**开场窗**,收集第一次模型输出之前的 user 提交;窗关上之后(闩上),同 run 的 user-role 提交 ——
|
|
158
|
+
* 用户打断时引擎收尾追加的「[Request interrupted by user]」、第一次模型调用前后排进来的 steer 正文、答完之后再来的 steer —— 一律不交。这是 CC「rewind to the message that started this turn」的
|
|
159
|
+
* 同义,与 core `resumeAt` 的 `before` 语义(叶 = 目标的 parent)配对:锚在开场提示上,切到它的 parent = 这一轮整个撤回;锚若漂到打断标记行上,
|
|
160
|
+
* parent 就是被撤回的那句提示本身,模型仍见它。同根:core 的文件历史边界按「本 run 第一条 user 提交」的 entry 键入(`rewindFilesTo` / `POST /v1/sessions/:id/rewind-files`
|
|
161
|
+
* 凭锚找边界),锚漂到没有自己边界的打断标记行上就解不到。打断标记行永远不是锚。
|
|
162
|
+
* 「一个 run」= 锚的键(`taskId`)的边界:读法实例每个 run 新建一只;续既有 run 的续跑腿不写用户锚(见 `resume-legs.ts`)。
|
|
163
163
|
*
|
|
164
|
-
*
|
|
165
|
-
* 落盘的行上有标记
|
|
166
|
-
*
|
|
167
|
-
*
|
|
164
|
+
* **窗里怎么认**。`message_committed` 上只有 `entryId / role / toolCallId?`:引擎排队在目标之前同批提交的消息(带图且工作区是 git 仓时单独排的 git 状态帧;会话空闲期间到的后台任务通知)、
|
|
165
|
+
* 目标、目标声明的附件帧、引擎收尾的中断标记,在事件上**不可辨认**(落盘的行上有标记 —— `attachment` 键、`provenance: "engine-note"` —— 但事件到手那一刻本仓读不到那一行:
|
|
166
|
+
* 会话店面没有按条目读的口,只有整日志导出),所以只能数。引擎的提交序(亲读 core `engine/harness/agent-harness.js` 的 `takePrompts`):排队消息 ⇒ 目标 ⇒ 附件帧;
|
|
167
|
+
* 中断标记只在打断收尾时追加(此时第一次模型输出没有出来,窗是被 `turn_end` 切断,不是被输出关上)。
|
|
168
|
+
* · **临时锚**:不带附件的提交,窗里**第一条** user 提交到手那一刻就交出 —— 打断 / 取消 / 断连常发生在第一次模型输出之前,那时窗还没关,锚必须已经在;
|
|
169
|
+
* 它也是 core 文件历史边界的键(本 run 第一条 user 提交)。
|
|
170
|
+
* · **校正**:窗被**非用户提交**(第一次助手消息 / 工具结果)关上 ⇒ 窗内共 k 条 user 提交、声明了 N 只附件帧:k ≥ N+1 时开场提示 = 倒数第 N+1 条(严格吻合)。
|
|
171
|
+
* 不带附件而 k > 1(目标之前有引擎排队的消息)⇒ 交出这一条,**盖过**临时锚(调用方「最后一次赢」,与修前同读:修前的读法就是『开场批里最后一条 user 提交』);k = 1 ⇒ 临时锚已是它,不再交。
|
|
172
|
+
* 带附件的提交没有临时锚(此刻还不知道哪几条是帧),只在关窗这一刻交一次;k < N+1(帧数不符)⇒ 不猜。
|
|
173
|
+
* · 窗被 `turn_end` 先切断 ⇒ 第一次模型调用没出任何输出就收了(halt / interrupt / cancel / 空失败):窗里可能夹着引擎收尾的中断标记,数 N 会落在帧或标记上 ⇒ **不校正**,
|
|
174
|
+
* 临时锚(不带附件)原样留着,带附件的提交不猜、不落锚。切断即闩上。
|
|
175
|
+
* · 带附件的提交,窗内又应用了一条别的输入(`human_input{applied}`,如第一次模型调用前排进来的 steer;事件先于它的正文提交到手)⇒ 窗里多了一条别人的消息,数 N 会落在帧后面的 steer 上 ⇒ 不猜。
|
|
176
|
+
* 不带附件的提交不看输入条数:多条 applied 输入可以合成一条提交(续跑把停驻的 steer 与 wake 文本并成一条续跑消息),按修前同读校正到窗内最后一条。排队未应用(`delivery: "queued"`)的输入不动窗。窗还开着时继续攒,直到被关上。
|
|
177
|
+
* · 「不猜」= 这个 run 不落(带附件)或不校正(不带附件),且窗关上之后闩上 —— 其后的 user 提交(steer 正文、打断标记)不是开场提示,不顶上来;拿这次 run 的 taskId 去 `resumeAt`
|
|
178
|
+
* 得 404 `resume_at.unknown_event`(文案点名带附件这一类成因)。
|
|
179
|
+
* 窗关上之前一个 user 提交都没有就关了(续跑腿里先到的是工具结果 / 助手消息)⇒ 窗照开着,不闩:那一条之后第一条 user 提交才是这个 run 里的第一条。
|
|
168
180
|
*
|
|
169
|
-
*
|
|
170
|
-
* · `
|
|
171
|
-
*
|
|
172
|
-
* ·
|
|
173
|
-
* · 窗内又应用了一条别的输入(`human_input{applied}`,如第一次模型调用前排进来的 steer;事件先于它的正文提交到手)⇒ 窗里多了一条别人的消息,数 N 会落在帧上 ⇒ 窗作废、不猜,
|
|
174
|
-
* 之后的用户提交(含那条 steer 正文)是窗口之外的提交,最后一次赢。排队未应用(`delivery: "queued"`)的输入不动窗。
|
|
175
|
-
* · 「不猜」= 返回 `undefined`、这次提交不落锚;拿这次 run 的 taskId 去 `resumeAt` 得 404 `resume_at.unknown_event`(文案点名这一类成因)。
|
|
176
|
-
* 窗口之外的用户提交(如 interrupt 带话的 steer 正文,在 `turn_end` 之后提交)照修前读法(是提问,最后一次赢)。
|
|
177
|
-
* 返回这次提交之后的提问 `entryId`(调用方照旧「最后一次赢」地落锚),不是提问相关的提交返回 `undefined`。
|
|
181
|
+
* 已知边界(引擎在 `message_committed` 上带来源标 / 输入标之日见下):
|
|
182
|
+
* · 被 `turn_end` 切断(第一次模型输出之前打断 / 取消)、不带附件、且由引擎排队的消息领头的 run —— 窗来不及校正,锚落在领头的那一条上(修前:取消 = 目标,halt / interrupt = 打断标记)。
|
|
183
|
+
* 它与 core 文件历史边界的键是同一条消息,`resumeAtMode:"before"` 的叶仍是整轮之前;含目标的 `resumeAt` 只留下领头那条。
|
|
184
|
+
* · 不带附件、第一次模型输出之前就应用了一条 steer:校正到窗内最后一条 = steer 正文(与修前同读)。
|
|
178
185
|
*
|
|
179
|
-
* 退役条件:引擎在落盘的帧上(`message_committed`)
|
|
180
|
-
* 窗口 / 严格吻合 / 不猜三臂与 `resume_at.unknown_event`
|
|
186
|
+
* 退役条件:引擎在落盘的帧上(`message_committed`)带上来源标(附件标记 / 引擎消息标)之日,本读法整体换成「第一条非引擎消息」(零计数、无窗口、无校正、无拒臂),
|
|
187
|
+
* 窗口 / 严格吻合 / 不猜三臂与 `resume_at.unknown_event` 文案里对应的那一句一并删除,领头排队消息的边界随之消失。
|
|
181
188
|
*/
|
|
182
189
|
export declare function createPromptCommitReader(): (ev: {
|
|
183
190
|
readonly type: string;
|
|
@@ -206,12 +213,17 @@ export declare class TurnAnchorCapture {
|
|
|
206
213
|
* assistant). This is the CC rewind target ("rewind to the prompt" = the code-restore parity path — a code
|
|
207
214
|
* change happens in a tool turn WITHIN a prompt's run, so rewinding to the prompt + rewindFiles undoes it).
|
|
208
215
|
* Keyed by the run's taskId (the handle the shell already holds from the POST response — no eventId→entryId
|
|
209
|
-
* side map / no leaf-read inference needed). The assistant-turn capture above stays as an additive bonus.
|
|
216
|
+
* side map / no leaf-read inference needed). The assistant-turn capture above stays as an additive bonus.
|
|
217
|
+
* The anchor is the run's OPENING prompt (the reader's opening window: provisional on the first user commit, corrected
|
|
218
|
+
* when the first model output closes the window, latched after); a later
|
|
219
|
+
* user-role commit in the same run — the interruption marker, a steer — never moves it. The capture instance is per
|
|
220
|
+
* run: a leg that CONTINUES an existing run (same taskId) wires no `captureUser` (its opening prompt was anchored
|
|
221
|
+
* by the first leg). */
|
|
210
222
|
private readonly captureUser?;
|
|
211
223
|
/** The turn's FIRST text_delta eventId = the message's stable resume handle (also stamped on the durable text event). */
|
|
212
224
|
firstTextEventId: string | undefined;
|
|
213
225
|
private turnHadTool;
|
|
214
|
-
/**
|
|
226
|
+
/** 用户提交是不是开场提示的唯一读法({@link createPromptCommitReader};开场窗 + 闩 —— 开场提示之后打断标记 / steer 不改锚;附件帧不是提问)。 */
|
|
215
227
|
private readonly promptCommit;
|
|
216
228
|
constructor(capture: ((eventId: string) => Promise<void>) | undefined,
|
|
217
229
|
/** 这只捕获器在哪条腿上(写失败的 fail-open 探针行带它)。 */
|
|
@@ -222,16 +234,22 @@ export declare class TurnAnchorCapture {
|
|
|
222
234
|
* assistant). This is the CC rewind target ("rewind to the prompt" = the code-restore parity path — a code
|
|
223
235
|
* change happens in a tool turn WITHIN a prompt's run, so rewinding to the prompt + rewindFiles undoes it).
|
|
224
236
|
* Keyed by the run's taskId (the handle the shell already holds from the POST response — no eventId→entryId
|
|
225
|
-
* side map / no leaf-read inference needed). The assistant-turn capture above stays as an additive bonus.
|
|
237
|
+
* side map / no leaf-read inference needed). The assistant-turn capture above stays as an additive bonus.
|
|
238
|
+
* The anchor is the run's OPENING prompt (the reader's opening window: provisional on the first user commit, corrected
|
|
239
|
+
* when the first model output closes the window, latched after); a later
|
|
240
|
+
* user-role commit in the same run — the interruption marker, a steer — never moves it. The capture instance is per
|
|
241
|
+
* run: a leg that CONTINUES an existing run (same taskId) wires no `captureUser` (its opening prompt was anchored
|
|
242
|
+
* by the first leg). */
|
|
226
243
|
captureUser?: ((entryId: string) => Promise<void>) | undefined);
|
|
227
|
-
/** A `human_input` arrived — the objective's declared attachments open the frame window of {@link createPromptCommitReader}. */
|
|
244
|
+
/** A `human_input` arrived — the objective's declared attachments open the frame window of {@link createPromptCommitReader} (another applied input inside the window voids it). */
|
|
228
245
|
onHumanInput(ev: {
|
|
229
246
|
readonly type: string;
|
|
230
247
|
}): void;
|
|
231
248
|
/** A `message_committed` arrived — capture a USER-message rewind anchor (CC parity). Best-effort (a failure only
|
|
232
|
-
* makes that one prompt non-rewindable). Only
|
|
233
|
-
*
|
|
234
|
-
*
|
|
249
|
+
* makes that one prompt non-rewindable). Only the run's OPENING prompt anchors (the opening window's user commit — not an
|
|
250
|
+
* attachment frame trailing the objective, not the interruption marker / a steer that follows it —
|
|
251
|
+
* {@link createPromptCommitReader}; an attachment window is decided when a non-user commit closes it, so the anchor of an
|
|
252
|
+
* attachment-carrying prompt lands on THAT call); assistant/toolResult committed entries are handled by
|
|
235
253
|
* the turn-text path (assistant) or deliberately not anchored (toolResult — `resumeAt` rejects them). */
|
|
236
254
|
onMessageCommitted(role: string | undefined, entryId: string | undefined): Promise<void>;
|
|
237
255
|
/** A text_delta arrived — latch the first DEFINED eventId as the message handle (eventId is optional on the stream). */
|
package/dist/runs.js
CHANGED
|
@@ -11,7 +11,7 @@ import { withPrincipal } from "./observability/principal-context.js";
|
|
|
11
11
|
import { withModelReachScope } from "./model-reach-scope.js";
|
|
12
12
|
import { createInstructionSelectionLeg } from "./instruction-selection.js";
|
|
13
13
|
import { redactSecrets } from "./trace/redact.js";
|
|
14
|
-
import { taskNotificationEventData, appendModelUsageDelta,
|
|
14
|
+
import { taskNotificationEventData, appendModelUsageDelta, attachModelUsage, createPromptManifestSeat } from "./trace/project.js";
|
|
15
15
|
import { createLedgerSink } from "./trace/ledger-sink.js";
|
|
16
16
|
import { registerEngineNoticeLeg } from "./trace/engine-notice-wire.js";
|
|
17
17
|
import { recordTurnActivity } from "./turn-activity.js";
|
|
@@ -78,6 +78,8 @@ const PREPARE_REFUSAL_HTTP_STATUS = {
|
|
|
78
78
|
"rewind.child_scope_unsupported": 422,
|
|
79
79
|
"rewind.capture_disabled": 422,
|
|
80
80
|
"rewind.store_unconfigured": 409,
|
|
81
|
+
"rewind.session_busy": 409,
|
|
82
|
+
"rewind.files_env_unsupported": 409,
|
|
81
83
|
"memory.capture_optout_unpersisted": 503,
|
|
82
84
|
"config.memory_capture_spelling": 400,
|
|
83
85
|
"config.invalid_checkpoint_store": 400,
|
|
@@ -174,17 +176,25 @@ export async function releaseKeyIfZeroWorkRefusal(runStore, taskId, result) {
|
|
|
174
176
|
await runStore.releaseIdemKey(taskId);
|
|
175
177
|
}
|
|
176
178
|
export function createPromptCommitReader() {
|
|
177
|
-
|
|
179
|
+
const commits = [];
|
|
180
|
+
let frames = 0;
|
|
181
|
+
let appliedInputs = 0;
|
|
182
|
+
let settled = false;
|
|
178
183
|
return (ev) => {
|
|
184
|
+
if (settled)
|
|
185
|
+
return undefined;
|
|
179
186
|
if (ev.type === "human_input") {
|
|
180
187
|
const h = ev;
|
|
181
188
|
if (h.delivery !== "applied")
|
|
182
189
|
return undefined;
|
|
183
|
-
|
|
190
|
+
appliedInputs += 1;
|
|
191
|
+
if (appliedInputs === 1)
|
|
192
|
+
frames = Array.isArray(h.attachments) ? h.attachments.length : 0;
|
|
184
193
|
return undefined;
|
|
185
194
|
}
|
|
186
195
|
if (ev.type === "turn_end") {
|
|
187
|
-
|
|
196
|
+
if (commits.length > 0)
|
|
197
|
+
settled = true;
|
|
188
198
|
return undefined;
|
|
189
199
|
}
|
|
190
200
|
if (ev.type !== "message_committed")
|
|
@@ -192,17 +202,17 @@ export function createPromptCommitReader() {
|
|
|
192
202
|
const c = ev;
|
|
193
203
|
const entryId = typeof c.entryId === "string" && c.entryId.length > 0 ? c.entryId : undefined;
|
|
194
204
|
if (c.role === "user") {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
return undefined;
|
|
198
|
-
}
|
|
199
|
-
return entryId;
|
|
205
|
+
commits.push(entryId);
|
|
206
|
+
return frames === 0 && commits.length === 1 ? entryId : undefined;
|
|
200
207
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
208
|
+
if (commits.length === 0)
|
|
209
|
+
return undefined;
|
|
210
|
+
settled = true;
|
|
211
|
+
if (frames === 0)
|
|
212
|
+
return commits.length > 1 ? commits[commits.length - 1] : undefined;
|
|
213
|
+
if (appliedInputs > 1 || commits.length < frames + 1)
|
|
204
214
|
return undefined;
|
|
205
|
-
return
|
|
215
|
+
return commits[commits.length - 1 - frames];
|
|
206
216
|
};
|
|
207
217
|
}
|
|
208
218
|
export async function settleResumeAnchor(write, where) {
|
|
@@ -385,8 +395,8 @@ export async function runInBackground(runner, spec, runStore, taskId, metrics, p
|
|
|
385
395
|
const flushModelUsage = () => appendModelUsageDelta(append, modelUsage, taskId);
|
|
386
396
|
const withModelUsage = (result) => attachModelUsage(result, { append, getEvents: (id, after) => runStore.getEvents(id, after), modelUsage, taskId });
|
|
387
397
|
modelUsage?.register(taskId);
|
|
388
|
-
const
|
|
389
|
-
const flushPromptManifest = () =>
|
|
398
|
+
const manifestSeat = createPromptManifestSeat(promptManifests, taskId);
|
|
399
|
+
const flushPromptManifest = () => manifestSeat.drain(append);
|
|
390
400
|
const elicitEmit = (frame) => {
|
|
391
401
|
const { type, ...rest } = frame;
|
|
392
402
|
return append(type, rest);
|
|
@@ -652,7 +662,7 @@ export async function runInBackground(runner, spec, runStore, taskId, metrics, p
|
|
|
652
662
|
for (const evict of subagentHandleEvictions)
|
|
653
663
|
evict();
|
|
654
664
|
modelUsage?.clear(taskId);
|
|
655
|
-
|
|
665
|
+
manifestSeat.release();
|
|
656
666
|
clearInterval(heartbeat);
|
|
657
667
|
}
|
|
658
668
|
}
|