@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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MAX_MINTED_TOOL_RESULT_REF_CHARS, assertSafeToolResultRef, assertToolResultProvenanceMatch, normalizeToolResultProvenance } from "@sema-agent/core";
|
|
2
2
|
import { pgSanitizeText } from "../plugins/pg-safe-json.js";
|
|
3
3
|
import { mysqlDriver, pgDriver } from "../plugins/sql-driver.js";
|
|
4
|
-
import { MANAGED_RETENTION, UNMANAGED_RETENTION } from "../plugins/retention-
|
|
4
|
+
import { MANAGED_RETENTION, UNMANAGED_RETENTION } from "../plugins/retention-declaration.js";
|
|
5
5
|
import { ensureIndexes } from "../plugins/ensure-index.js";
|
|
6
6
|
import { describeProbedTableDrift, schemaWaysOut } from "../plugins/schema-drift-sentence.js";
|
|
7
7
|
import { isMissingColumnError } from "../plugins/sql-errors.js";
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 两只 SQL 会话存储(`tidb-session-storage.ts` / `pg-session-storage.ts`)共用的**窗口视图** —— 一次唤醒读出的有界日志 `[floor .. leaf]`。
|
|
3
|
+
*
|
|
4
|
+
* ## 组合,不继承
|
|
5
|
+
* 会话树的读法(按 id 取、按类型找、标签、到根的路径、叶子、日志标记、地板、回放丢失)只有引擎那一份:本类把唤醒读出的窗口交给引擎的
|
|
6
|
+
* `InMemorySessionStorage`(组合),每个读都转给它;方言孪生只说两件 SQL 的事 —— 一笔写怎么落库({@link persist}),地板之下按 id 回读一条
|
|
7
|
+
* ({@link readBelowFloor})。不再 `extends` 引擎的存储基类:方言店继承引擎的店基类造第二份店,是依赖方向门 R5′ 拒的形。
|
|
8
|
+
*
|
|
9
|
+
* ## 写序
|
|
10
|
+
* 先落库(方言孪生在自己的事务里按叶子 CAS),落成才记进窗口 —— 与引擎存储「先判后记」同序;落库被拒(CAS 输)时窗口一个字节不动。
|
|
11
|
+
* 记进窗口走引擎存储的追加口(不带期望叶:CAS 已在库里判过,窗口只是跟上那一笔)。
|
|
12
|
+
*
|
|
13
|
+
* ## 叶子是行说的那一格
|
|
14
|
+
* 叶子 = 库里那一格(`session_meta.leaf_id`,引擎存储契约里「后端说出的头」),不是窗口末条之后的叶子(fork 拷整份日志带着别的分支时两者不同)。
|
|
15
|
+
* 窗口(引擎的存储)从条目推叶子、不收后端说的头 ⇒ 叶子由本类自己持有:唤醒时取行上那一格(它不在窗口里 ⇒ `corrupt_session`,与引擎存储基类同一判、同一句),
|
|
16
|
+
* 之后每落一笔前进到「这一笔之后的叶子」(与库里同一事务写下的值同一读法)。窗口里那只按条目推出的叶子不被读。
|
|
17
|
+
*/
|
|
18
|
+
import { InMemorySessionStorage, type SessionLogMark, type SessionMetadata, type SessionStorage, type SessionTreeEntry, type SessionWriteOptions } from "@sema-agent/core";
|
|
19
|
+
export declare abstract class WindowedSessionStorage implements SessionStorage {
|
|
20
|
+
/** 唤醒读出的窗口(引擎的存储;叶子以外的每个读都是它的读)。 */
|
|
21
|
+
private readonly view;
|
|
22
|
+
/** 叶子(头注「叶子是行说的那一格」)。 */
|
|
23
|
+
private leaf;
|
|
24
|
+
/**
|
|
25
|
+
* `entries` = 窗口(按 `seq` 升序);`statedLeafId` = 行上那一格叶子;`floorEntryId` = 窗口的地板(没有压缩 ⇒ `null`,整条日志都在窗口里)。
|
|
26
|
+
* 地板不在窗口里 ⇒ 引擎存储拒 `corrupt_session`;行上的叶子不在窗口里 ⇒ 本类拒 `corrupt_session`(引擎存储基类的同一判、同一句)。
|
|
27
|
+
*/
|
|
28
|
+
protected constructor(metadata: SessionMetadata, entries: SessionTreeEntry[], statedLeafId: string | null, floorEntryId: string | null);
|
|
29
|
+
/** 一笔写落库(方言孪生的事务:叶子 CAS + 追加事件)。抛 ⇒ 窗口不记。 */
|
|
30
|
+
protected abstract persist(entry: SessionTreeEntry, opts?: SessionWriteOptions): Promise<void>;
|
|
31
|
+
/** 地板之下按 id 回读一条(窗口里没有的;标签目标等)。没有 ⇒ `undefined`。 */
|
|
32
|
+
protected abstract readBelowFloor(id: string): Promise<SessionTreeEntry | undefined>;
|
|
33
|
+
getMetadata(): Promise<SessionMetadata>;
|
|
34
|
+
getLeafId(): Promise<string | null>;
|
|
35
|
+
createEntryId(): Promise<string>;
|
|
36
|
+
findEntries<TType extends SessionTreeEntry["type"]>(type: TType): Promise<Array<Extract<SessionTreeEntry, {
|
|
37
|
+
type: TType;
|
|
38
|
+
}>>>;
|
|
39
|
+
getLabel(id: string): Promise<string | undefined>;
|
|
40
|
+
getPathToRoot(leafId: string | null): Promise<SessionTreeEntry[]>;
|
|
41
|
+
getEntries(): Promise<SessionTreeEntry[]>;
|
|
42
|
+
/** 窗口的地板(没有压缩 ⇒ `null`)。 */
|
|
43
|
+
getFloorId(): string | null;
|
|
44
|
+
/** SQL 唤醒没有回放可丢(行是逐条读的):恒 `undefined`,经引擎存储原样答。 */
|
|
45
|
+
getReplayLoss(): ReturnType<InMemorySessionStorage["getReplayLoss"]>;
|
|
46
|
+
/** 窗口此刻的日志标记(同步读;引擎存储的读法)。 */
|
|
47
|
+
logMarkNow(): SessionLogMark;
|
|
48
|
+
/** 窗口里没有的 id(地板之下)回落到库。 */
|
|
49
|
+
getEntry(id: string): Promise<SessionTreeEntry | undefined>;
|
|
50
|
+
appendEntry(entry: SessionTreeEntry, opts?: SessionWriteOptions): Promise<void>;
|
|
51
|
+
/** 落成的一笔记进窗口,叶子前进到这一笔之后的叶子。 */
|
|
52
|
+
private record;
|
|
53
|
+
/** 叶子移动本身是一条落库的 `leaf` 条目,父 = 当前叶子(引擎存储的同一形:目标不在窗口里 ⇒ `not_found`,id 由引擎的铸法给)。 */
|
|
54
|
+
setLeafId(leafId: string | null, opts?: SessionWriteOptions): Promise<void>;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=windowed-session-storage.d.ts.map
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { InMemorySessionStorage, SessionError, leafIdAfterEntry } from "@sema-agent/core";
|
|
2
|
+
export class WindowedSessionStorage {
|
|
3
|
+
view;
|
|
4
|
+
leaf;
|
|
5
|
+
constructor(metadata, entries, statedLeafId, floorEntryId) {
|
|
6
|
+
this.view = new InMemorySessionStorage({ metadata, entries, floorEntryId });
|
|
7
|
+
if (statedLeafId !== null && !entries.some((e) => e.id === statedLeafId)) {
|
|
8
|
+
throw new SessionError("corrupt_session", `Entry ${statedLeafId} not found — the log's leaf names an entry the log does not hold`);
|
|
9
|
+
}
|
|
10
|
+
this.leaf = statedLeafId;
|
|
11
|
+
}
|
|
12
|
+
getMetadata() {
|
|
13
|
+
return this.view.getMetadata();
|
|
14
|
+
}
|
|
15
|
+
async getLeafId() {
|
|
16
|
+
return this.leaf;
|
|
17
|
+
}
|
|
18
|
+
createEntryId() {
|
|
19
|
+
return this.view.createEntryId();
|
|
20
|
+
}
|
|
21
|
+
findEntries(type) {
|
|
22
|
+
return this.view.findEntries(type);
|
|
23
|
+
}
|
|
24
|
+
getLabel(id) {
|
|
25
|
+
return this.view.getLabel(id);
|
|
26
|
+
}
|
|
27
|
+
getPathToRoot(leafId) {
|
|
28
|
+
return this.view.getPathToRoot(leafId);
|
|
29
|
+
}
|
|
30
|
+
getEntries() {
|
|
31
|
+
return this.view.getEntries();
|
|
32
|
+
}
|
|
33
|
+
getFloorId() {
|
|
34
|
+
return this.view.getFloorId();
|
|
35
|
+
}
|
|
36
|
+
getReplayLoss() {
|
|
37
|
+
return this.view.getReplayLoss();
|
|
38
|
+
}
|
|
39
|
+
logMarkNow() {
|
|
40
|
+
return this.view.logMarkNow();
|
|
41
|
+
}
|
|
42
|
+
async getEntry(id) {
|
|
43
|
+
return (await this.view.getEntry(id)) ?? (await this.readBelowFloor(id));
|
|
44
|
+
}
|
|
45
|
+
async appendEntry(entry, opts) {
|
|
46
|
+
await this.persist(entry, opts);
|
|
47
|
+
await this.record(entry);
|
|
48
|
+
}
|
|
49
|
+
async record(entry) {
|
|
50
|
+
await this.view.appendEntry(entry);
|
|
51
|
+
this.leaf = leafIdAfterEntry(entry);
|
|
52
|
+
}
|
|
53
|
+
async setLeafId(leafId, opts) {
|
|
54
|
+
if (leafId !== null && (await this.view.getEntry(leafId)) === undefined)
|
|
55
|
+
throw new SessionError("not_found", `Entry ${leafId} not found`);
|
|
56
|
+
const leafEntry = { type: "leaf", id: await this.view.createEntryId(), parentId: this.leaf, timestamp: new Date().toISOString(), targetId: leafId };
|
|
57
|
+
await this.persist(leafEntry, opts);
|
|
58
|
+
await this.record(leafEntry);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=windowed-session-storage.js.map
|
package/dist/task-a2a.d.ts
CHANGED
|
@@ -57,7 +57,7 @@ export declare const A2A_PEER_DISPOSITION: {
|
|
|
57
57
|
readonly toolAxes: "engine";
|
|
58
58
|
};
|
|
59
59
|
/** 请求体 `a2aPeers[i]` 的键闭集 = 处置表的键(书写序即判序)。 */
|
|
60
|
-
export declare const A2A_PEER_ENTRY_KEYS: readonly ("name" | "headers" | "url" | "
|
|
60
|
+
export declare const A2A_PEER_ENTRY_KEYS: readonly ("name" | "headers" | "url" | "cardUrl" | "principalHeader" | "allowSkills" | "toolAxes")[];
|
|
61
61
|
/**
|
|
62
62
|
* **请求入口的一次读**(`boot/resolve-spec.ts` 在腿首铸一份,受理门与读器——续跑重放腿只有读器——都吃这一份):`body.a2aPeers` 若是数组,返回同形数组
|
|
63
63
|
* (每个对象条目换成它的 {@link PeerSnapshot};非对象条目原样;长度保真 —— 界外的条数仍是受理门撞帽拒与读器丢弃留声的依据,只快照界内的条目);不是数组(缺席 / `null` / 别的形)原样返回。
|
|
@@ -80,6 +80,12 @@ export declare function validateRequestA2a(raw: unknown): {
|
|
|
80
80
|
ok: A2aDraft[];
|
|
81
81
|
dropped: A2aInjectionDrop[];
|
|
82
82
|
} | null;
|
|
83
|
+
/**
|
|
84
|
+
* 一份请求的 `a2aPeers` 里,读器挂得上、`headers` 却剔掉了成员的那些坐标(`a2aPeers[<下标>].headers.__proto__`:成员名过回显清洗,只会是读器的保留名,不带值、不带调用方写的对端名)——
|
|
85
|
+
* 「请求成员读不出」那一只判据(`unread-request-members.ts`)的 A2A 一座。读器与挂载同一只({@link normalizeA2aPeer},续跑重放腿的读法;新提交腿上同一形由判官表 400)。
|
|
86
|
+
* 挂不上的对端不算(整条不进,有自己的留声)。`storedToolAxes` = 续跑重放腿递的 M19 重读座。不是数组 ⇒ 空。
|
|
87
|
+
*/
|
|
88
|
+
export declare function requestA2aHeadersUnread(raw: unknown, storedToolAxes?: StoredToolAxesRereadM19): string[];
|
|
83
89
|
/**
|
|
84
90
|
* 请求体 `a2aPeers`「这份声明能不能原样用」的回答者(与 MCP 的 `requestMcpDeclarationRefusal` 同一副骨架、同一个拒形):
|
|
85
91
|
* ① **列表**:在场却不是数组 / 超过 {@link MAX_REQUEST_A2A_PEERS} 条(撞帽机读位一组键)/ 某一条不是对象 ⇒ `400 request.field_invalid`;
|
package/dist/task-a2a.js
CHANGED
|
@@ -244,21 +244,18 @@ export function validateRequestA2a(raw) {
|
|
|
244
244
|
}
|
|
245
245
|
function validateRequestA2aEntries(raw, leg, storedToolAxes) {
|
|
246
246
|
if (raw === undefined || raw === null)
|
|
247
|
-
return { ok: [], dropped: [], toolAxesReread: []
|
|
247
|
+
return { ok: [], dropped: [], toolAxesReread: [] };
|
|
248
248
|
if (!Array.isArray(raw))
|
|
249
249
|
return null;
|
|
250
250
|
const ok = [];
|
|
251
251
|
const dropped = [];
|
|
252
252
|
const toolAxesReread = [];
|
|
253
|
-
const headersLost = [];
|
|
254
253
|
for (const [i, e] of raw.slice(0, MAX_REQUEST_A2A_PEERS).entries()) {
|
|
255
254
|
const read = normalizeA2aPeer(e, leg, `${A2A_SEAT.list}[${i}]`, storedToolAxes);
|
|
256
255
|
if (read.draft !== null) {
|
|
257
256
|
ok.push(read.draft);
|
|
258
257
|
if (read.toolAxesReread !== undefined)
|
|
259
258
|
toolAxesReread.push({ peer: read.draft.spec.name, sentence: read.toolAxesReread });
|
|
260
|
-
if (read.headersLost !== undefined)
|
|
261
|
-
headersLost.push({ peer: read.draft.spec.name, lost: read.headersLost });
|
|
262
259
|
}
|
|
263
260
|
else
|
|
264
261
|
dropped.push({ peer: declaredName(e).slice(0, 128), ...read.because });
|
|
@@ -266,7 +263,20 @@ function validateRequestA2aEntries(raw, leg, storedToolAxes) {
|
|
|
266
263
|
if (raw.length > MAX_REQUEST_A2A_PEERS) {
|
|
267
264
|
dropped.push({ peer: `(+${raw.length - MAX_REQUEST_A2A_PEERS} over cap of ${MAX_REQUEST_A2A_PEERS})`, ...declarationOverCapFacts(A2A_SEAT, raw.length) });
|
|
268
265
|
}
|
|
269
|
-
return { ok, dropped, toolAxesReread
|
|
266
|
+
return { ok, dropped, toolAxesReread };
|
|
267
|
+
}
|
|
268
|
+
export function requestA2aHeadersUnread(raw, storedToolAxes) {
|
|
269
|
+
if (!Array.isArray(raw))
|
|
270
|
+
return [];
|
|
271
|
+
const out = [];
|
|
272
|
+
for (const [i, e] of raw.slice(0, MAX_REQUEST_A2A_PEERS).entries()) {
|
|
273
|
+
const at = `${A2A_SEAT.list}[${i}]`;
|
|
274
|
+
const read = normalizeA2aPeer(e, "resume", at, storedToolAxes);
|
|
275
|
+
if (read.draft !== null)
|
|
276
|
+
for (const member of read.headersLost ?? [])
|
|
277
|
+
out.push(`${at}.${member}`);
|
|
278
|
+
}
|
|
279
|
+
return out;
|
|
270
280
|
}
|
|
271
281
|
function requestA2aPeerRefusal(entry, at) {
|
|
272
282
|
const snapshot = snapshotPeer(entry, false);
|
|
@@ -323,15 +333,6 @@ export function resolveRequestA2a(baseline, bodyA2a, config, desk, lease, logger
|
|
|
323
333
|
note: "this replayed request was stored before the upgrade and the peer's toolAxes declaration does not pass the engine's reader; while one-time migration M19 is open it is read the way the pre-upgrade reader reads it (members that do not fit are dropped) and the peer stays mounted — once the window closes the same request leaves this peer unmounted",
|
|
324
334
|
});
|
|
325
335
|
}
|
|
326
|
-
for (const h of v.headersLost) {
|
|
327
|
-
if (baselineNames.has(h.peer))
|
|
328
|
-
continue;
|
|
329
|
-
logger?.warn("a2a_peer_headers_members_dropped", {
|
|
330
|
-
peer: h.peer,
|
|
331
|
-
lost: h.lost,
|
|
332
|
-
note: "this replayed request carries a headers member named \"__proto__\" for this peer (the engine refuses that name); the peer stays mounted with every other header as written, the named member left out. A new submission with the same peer leaves it unmounted",
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
336
|
return merged;
|
|
336
337
|
}
|
|
337
338
|
//# sourceMappingURL=task-a2a.js.map
|
package/dist/task-cwd.d.ts
CHANGED
|
@@ -32,9 +32,9 @@ export declare function dirCoversPath(dir: string, target: string): boolean;
|
|
|
32
32
|
* 刻意的单写者惯用法,不是疏漏:在消费端补第二道闸 = 把一条不变量拆给两个属主(同族消费者
|
|
33
33
|
* {@link effectiveHostWorkspace} 形状完全相同)。机器背书 = test/task-cwd.test.ts 的 [ref] 两格。
|
|
34
34
|
* 2. 🔴 **前瞻/防御臂,本仓当前装配下零命中**([ref],2026-08-19 合并重扫 partial,存活断言):
|
|
35
|
-
*
|
|
36
|
-
* 服务一个真部署形,其实到不了 —— 该 lane
|
|
37
|
-
*
|
|
35
|
+
* 无手(`none`)单用户 lane(部署形表行 `noHandsSingleUser`)取引擎自身 `process.cwd()`。它读起来像在
|
|
36
|
+
* 服务一个真部署形,其实到不了 —— 该 lane 声明没有执行环境 ⇒ boot/execution-env.ts 的工厂臂全
|
|
37
|
+
* 不命中、执行环境座也不给 ⇒ `handsEnabled=false` ⇒ 不挂 Bash ⇒ 未知工具在 agent-loop 走
|
|
38
38
|
* `tool.not_found`(**不进审批座**)⇒ 无 `ruleOffers` ⇒ 本函数在规则车道上根本不被调用;同 lane
|
|
39
39
|
* 第 1 臂也因写侧闸只在 `callerCwd` 下开而恒空。危害口径按 refuter **降级**:死枝 ≡ 落第 3 臂
|
|
40
40
|
* `undefined` ≡ core global 缺省 ≡ [ref] 修前行为,**今天零用户可见伤害**,不是「恒不命中」类缺陷。
|
|
@@ -102,4 +102,12 @@ export declare function effectiveHostWorkspace(sessionCwd: string | undefined, c
|
|
|
102
102
|
isolation?: string;
|
|
103
103
|
parentCwd?: string;
|
|
104
104
|
}): string | undefined;
|
|
105
|
+
/**
|
|
106
|
+
* run 外回退口问「host 工厂这一次会落在一只**实在的**目录上吗」:根 = {@link effectiveHostWorkspace}(引擎 run 外环境请求的上下文归约成 `{}` ⇒ 就是登记的 cwd),
|
|
107
|
+
* 且它此刻是盘上的一只目录 ⇒ 交回它;没有根,或那只目录**不在**(`ENOENT` / `ENOTDIR`,或在但不是目录)⇒ `undefined`(调用方答 409:根不可知)。
|
|
108
|
+
* 「看不到」不是「不在」:其余 errno(`EACCES` / `ELOOP` / `EIO`)原样抛 —— 路由未分类 500 + 运维 warn,与 `memory-store-refusal.ts` 的解析故障同读法;
|
|
109
|
+
* 把它读成 409 会把一只权限 / 环路故障遮成「用户把目录移走了」。三态读法同 `project-identity.ts` 的 statFact。
|
|
110
|
+
* 只读不建:工厂对一只消失的 cwd 会 `mkdir -p` 把它建回来(那是 run 的读法),回退不许替用户把移走的目录建回来再往里写。
|
|
111
|
+
*/
|
|
112
|
+
export declare function presentHostWorkspaceOf(sessionCwd: string | undefined): Promise<string | undefined>;
|
|
105
113
|
//# sourceMappingURL=task-cwd.d.ts.map
|
package/dist/task-cwd.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
+
import { stat } from "node:fs/promises";
|
|
3
|
+
import { errorCodeOf } from "./observability/err-text.js";
|
|
2
4
|
import { isAbsoluteHostPath } from "@sema-agent/settings-schema";
|
|
3
5
|
import { DEPLOYMENT_SHAPE_PREDICATES } from "./deployment-shape.js";
|
|
4
6
|
export function normalizeAbsolutePathLexically(p) {
|
|
@@ -11,7 +13,7 @@ export function dirCoversPath(dir, target) {
|
|
|
11
13
|
return p === root || p.startsWith(root.endsWith("/") ? root : `${root}/`);
|
|
12
14
|
}
|
|
13
15
|
export function cardRuleScopeRoot(registeredCwd, config, cwd = process.cwd) {
|
|
14
|
-
const raw = registeredCwd ?? (DEPLOYMENT_SHAPE_PREDICATES.
|
|
16
|
+
const raw = registeredCwd ?? (DEPLOYMENT_SHAPE_PREDICATES.noHandsSingleUser.holds(config) ? cwd() : undefined);
|
|
15
17
|
return raw === undefined ? undefined : path.resolve(raw);
|
|
16
18
|
}
|
|
17
19
|
export function satisfiedByProcessCwd(requested, realpath, cwd = process.cwd) {
|
|
@@ -44,4 +46,18 @@ export function parseAdditionalDirectories(raw) {
|
|
|
44
46
|
export function effectiveHostWorkspace(sessionCwd, ctx) {
|
|
45
47
|
return sessionCwd ?? (ctx.isolation !== "worktree" ? ctx.parentCwd : undefined);
|
|
46
48
|
}
|
|
49
|
+
export async function presentHostWorkspaceOf(sessionCwd) {
|
|
50
|
+
const root = effectiveHostWorkspace(sessionCwd, {});
|
|
51
|
+
if (root === undefined)
|
|
52
|
+
return undefined;
|
|
53
|
+
try {
|
|
54
|
+
return (await stat(root)).isDirectory() ? root : undefined;
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
const code = errorCodeOf(err);
|
|
58
|
+
if (code !== "ENOENT" && code !== "ENOTDIR")
|
|
59
|
+
throw err;
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
47
63
|
//# sourceMappingURL=task-cwd.js.map
|
package/dist/task-mcp.d.ts
CHANGED
|
@@ -121,6 +121,14 @@ type ValidatedRequestMcp = {
|
|
|
121
121
|
value: string;
|
|
122
122
|
}>;
|
|
123
123
|
};
|
|
124
|
+
/**
|
|
125
|
+
* 一份请求的 `mcpServers` 里,读器挂得上、transport 却有几处不交给引擎的那些坐标(`mcpServers[<下标>].transport.headers` / `….env.__proto__` 一类:只有键路径,
|
|
126
|
+
* 成员名只会是读器的保留名,不带值、不带调用方写的 server 名)—— 「请求成员读不出」那一只判据(`unread-request-members.ts`)的 MCP 一座。
|
|
127
|
+
* 读器与挂载同一只({@link normalizeServer},契约包 `readRequestMcpTransport` 报的 `lost`);挂不上的条目(硬坏形)不算 —— 它们整条不挂、有自己的通告;
|
|
128
|
+
* 名字在 `closed`(部署占住的名字,{@link deploymentClosedMcpNames})里的条目也不算 —— 合并时输给部署(`name_reserved_by_deployment`),它的 transport 一处都不会交给引擎。
|
|
129
|
+
* `storedToolAxes` = 续跑重放腿递的 M19 重读座(同一只条目在挂载时也经它判挂不挂得上)。不是数组 ⇒ 空(整只忽略那一臂,不是本判据的事)。
|
|
130
|
+
*/
|
|
131
|
+
export declare function requestMcpTransportUnread(raw: unknown, closed: ReadonlySet<string>, storedToolAxes?: StoredToolAxesRereadM19): string[];
|
|
124
132
|
/**
|
|
125
133
|
* [ref] 件C §4.3 —— **同步**拒面:部署锁了 `mcp` 而请求仍带 `mcpServers` ⇒ 400 `config.locked_key`。
|
|
126
134
|
*
|
|
@@ -181,8 +189,8 @@ export declare function requestMcpDeclarationRefusal(list: unknown): Declaration
|
|
|
181
189
|
* 重放腿走读器({@link normalizeServer} / {@link classifyRequestMcp}),处置:整只不是数组 ⇒ 整只忽略 + 运维 warn `mcp_injection_ignored`;条目不是对象 / 坏硬键
|
|
182
190
|
* (`name` / `transport` 硬字段 / `allowTools` / `toolAxes` / `toolFaces`)⇒ 这一条 server 整条不进 + 运维 warn `mcp_injection_dropped` + 用户面通告 `mcp.injection_dropped` 点名 `field`
|
|
183
191
|
* (`toolAxes` 在一次性迁移 M19 的窗开着时先按升级前读法重读一次,过了就挂,见读器的注);超上限的尾项 ⇒ `over_cap` 点名;坏软键(`contentOrigin` / `elicitation` / `source`)
|
|
184
|
-
* 与词表外的键 ⇒ 丢键、server 照挂(`contentOrigin` 另有 `mcp_content_class_dropped` 留声);`transport`
|
|
185
|
-
*
|
|
192
|
+
* 与词表外的键 ⇒ 丢键、server 照挂(`contentOrigin` 另有 `mcp_content_class_dropped` 留声);`transport` 软字段有几处读器不交(`env` / `headers` 不是纯数据的串记录、其中名叫 `__proto__` 的成员、
|
|
193
|
+
* `args` / `principalHeader` 坏形)⇒ 这份请求不重放(「请求成员读不出」那一只判据,`unread-request-members.ts`,经 {@link requestMcpTransportUnread} 读这一座;续跑腿折 409)。
|
|
186
194
|
*/
|
|
187
195
|
export declare function assertRequestMcpEntries(bodyMcp: unknown): void;
|
|
188
196
|
/** 一次发送从一份声明里带出的头:件头(调用方原样写的名 → 值,由对端座按原字节作答)与身份头名(引擎按主体写值)。 */
|
package/dist/task-mcp.js
CHANGED
|
@@ -93,22 +93,31 @@ function validateRequestMcpEntries(raw, storedToolAxes) {
|
|
|
93
93
|
const dropped = [];
|
|
94
94
|
const badContentOrigin = [];
|
|
95
95
|
const toolAxesReread = [];
|
|
96
|
-
const transportLost = [];
|
|
97
96
|
for (const e of raw.slice(0, MAX_REQUEST_MCP_SERVERS)) {
|
|
98
97
|
const v = normalizeServer(e, (server, value) => badContentOrigin.push({ server, value: describeBadContentOrigin(value) }), storedToolAxes);
|
|
99
98
|
if (v.ok) {
|
|
100
99
|
ok.push(v.spec);
|
|
101
100
|
if (v.toolAxesReread !== undefined)
|
|
102
101
|
toolAxesReread.push({ server: v.spec.name, sentence: v.toolAxesReread });
|
|
103
|
-
if (v.transportLost.length > 0)
|
|
104
|
-
transportLost.push({ server: v.spec.name, lost: v.transportLost.map((i) => i.path) });
|
|
105
102
|
}
|
|
106
103
|
else
|
|
107
104
|
dropped.push({ server: declaredName(e), reason: "malformed_entry", field: v.field });
|
|
108
105
|
}
|
|
109
106
|
for (const e of raw.slice(MAX_REQUEST_MCP_SERVERS, MAX_REQUEST_MCP_SERVERS + MAX_REQUEST_MCP_DROP_NAMES))
|
|
110
107
|
dropped.push({ server: declaredName(e), reason: "over_cap" });
|
|
111
|
-
return { ok, dropped, droppedTotal: Math.max(0, raw.length - ok.length), badContentOrigin, toolAxesReread
|
|
108
|
+
return { ok, dropped, droppedTotal: Math.max(0, raw.length - ok.length), badContentOrigin, toolAxesReread };
|
|
109
|
+
}
|
|
110
|
+
export function requestMcpTransportUnread(raw, closed, storedToolAxes) {
|
|
111
|
+
if (!Array.isArray(raw))
|
|
112
|
+
return [];
|
|
113
|
+
const out = [];
|
|
114
|
+
for (const [i, e] of raw.slice(0, MAX_REQUEST_MCP_SERVERS).entries()) {
|
|
115
|
+
const v = normalizeServer(e, () => undefined, storedToolAxes);
|
|
116
|
+
if (v.ok && !closed.has(v.spec.name))
|
|
117
|
+
for (const issue of v.transportLost)
|
|
118
|
+
out.push(`mcpServers[${i}].${issue.path}`);
|
|
119
|
+
}
|
|
120
|
+
return out;
|
|
112
121
|
}
|
|
113
122
|
export function assertRequestMcpUnlocked(bodyMcp, lockedKeys) {
|
|
114
123
|
if (!lockedKeys.has("mcp"))
|
|
@@ -324,18 +333,6 @@ function classifyHonored(baseline, entries, config, desk, lease, logger, storedT
|
|
|
324
333
|
note: "this replayed request was stored before the upgrade and its toolAxes declaration does not pass the engine's reader; while one-time migration M19 is open it is read the way the pre-upgrade server read it (members that did not fit are dropped, a declaration that is not an object counts as none) and the server stays mounted — once the window closes the same request leaves this server unmounted",
|
|
325
334
|
});
|
|
326
335
|
}
|
|
327
|
-
for (const t of v.transportLost) {
|
|
328
|
-
if (!mounted.has(t.server))
|
|
329
|
-
continue;
|
|
330
|
-
logger?.warn("mcp_transport_members_dropped", {
|
|
331
|
-
server: t.server,
|
|
332
|
-
lost: t.lost.slice(0, MAX_KEY_ECHO),
|
|
333
|
-
...(t.lost.length > MAX_KEY_ECHO ? { lostTotal: t.lost.length } : {}),
|
|
334
|
-
note: "this replayed request carries parts of this server's transport declaration that cannot be handed to the engine — an env / headers record that is not a plain object of string values (left out whole, as the pre-upgrade server read it), " +
|
|
335
|
-
"a member named \"__proto__\" in env / headers (only that member is left out: the engine refuses the name), args that are not a list of strings, a principalHeader that is not a string; " +
|
|
336
|
-
"the server mounts with the rest. A new submission with the same entry is refused (400)",
|
|
337
|
-
});
|
|
338
|
-
}
|
|
339
336
|
return {
|
|
340
337
|
mcp: mergeRequestMcp(baseline, v.ok.map(toMcpDraft), reservedNames, desk, lease),
|
|
341
338
|
drops: [...v.dropped, ...blocked.map((server) => ({ server, reason: "name_reserved_by_deployment" }))],
|
package/dist/task-settings.d.ts
CHANGED
|
@@ -309,6 +309,8 @@ export interface SettingsEnvCredentialIssue {
|
|
|
309
309
|
export interface SettingsEnvLayer {
|
|
310
310
|
readonly sent: boolean;
|
|
311
311
|
readonly reaching: Readonly<Record<string, string>> | undefined;
|
|
312
|
+
/** 送来的值里有读者不交出去的东西({@link settingsEnvUnreadable}:不是对象 / 过帽 / 有成员读不出;空记录不算)—— 解析层据它报 `deferred: ["env"]`。 */
|
|
313
|
+
readonly unreadable: boolean;
|
|
312
314
|
}
|
|
313
315
|
/** `settings.env` 的**唯一**读法:`settings` 不是对象 ⇒ 没送;否则 `env` 只取一次,形判与收取都对这一次的值做。判据、解析层与续跑腿的剥键都吃这一份。 */
|
|
314
316
|
export declare function readSettingsEnv(settings: unknown): SettingsEnvLayer;
|
|
@@ -358,11 +360,11 @@ export declare function settingsPermissionBucketIssue(perms: unknown): SettingsP
|
|
|
358
360
|
*
|
|
359
361
|
* 🔴 `readDenyPatterns` / `writeProtectedExtra` / `complianceAdditionalDenies` 与 `permissions.neverAuto`([ref])= **「只收紧」座位族**:消费点 = `tighten-only-seats.ts`
|
|
360
362
|
* 的座位表(位置、条目律、去处都由那张表说),读入在 {@link parseTaskSettings},投影在 {@link applyTaskSettings} / {@link deriveSettingsPolicy}。这四个键不是 CC settings 键
|
|
361
|
-
* (sdk 的 `SemaSettings`
|
|
363
|
+
* (sdk 的 `SemaSettings` 已声明这四个键 —— 对账门 `test/task-settings-sdk-key-parity.test.ts` 逐键咬 server 与 sdk 两面一致)。
|
|
362
364
|
*
|
|
363
365
|
* 🔴 `approvalFrameFamilies`([ref])= 这条 run 的客户端**声明**渲染得了哪些审批开卡帧族 —— 不进引擎,不是 CC settings 键。消费点 = 三条执行腿的审批装配
|
|
364
366
|
* (`tool-approval.ts` 的唯一读者 `declaredApprovalFrameFamilies` → `resolveApprovalLeg`),判官 `approvalFrameFamiliesIssue`(fresh 受理 400 与宽容读者同一只)。
|
|
365
|
-
* `parseTaskSettings` 刻意不读它(它管的是落到 `TaskSpec` 的设置)。sdk
|
|
367
|
+
* `parseTaskSettings` 刻意不读它(它管的是落到 `TaskSpec` 的设置)。sdk 型面已声明(同一只对账门咬)。
|
|
366
368
|
*
|
|
367
369
|
* 🔴 两个 `skillListing*`([ref],7.77.0)= **CC settings 同名键**,值域抄 CC 的 schema 声明
|
|
368
370
|
* (`skillListingBudgetFraction` 是 `gt(0).lte(1)`、`skillListingMaxDescChars` 是 `int().positive()`);
|
|
@@ -416,11 +418,14 @@ export declare function taskSettingsKeyIssue(raw: unknown): KeyClosureIssue | nu
|
|
|
416
418
|
* 一只匹配组 / 一个条目上**读者不携带**的键 ⇒ 返回拒体(调用方 400 `request.body_shape`);全部携带 ⇒ `null`。
|
|
417
419
|
*
|
|
418
420
|
* 词表 = **读者自己的答案**:`config` 是同一份 `raw` 经 {@link parseHooksConfig} 受理的产物,一只组 / 一个条目受理的键 = 可跑形在同一坐标上那只对象的键
|
|
419
|
-
* (契约分类器携带的字段 + 本仓 wire 键:组的 `source`、command 条目的 `plugin`
|
|
421
|
+
* (契约分类器携带的字段 + 本仓 wire 键:组的 `source`、command 条目的 `plugin`)。本函数不另立键表 —— 契约给某一型加字段、分类器开始携带它,这里随之受理
|
|
422
|
+
* (契约包 19.0.0 承运 command 的 `args` / `onFailure` 与 http 的 `onFailure`、20.0.0 承运 command 的 `rewakeMessage` / `rewakeSummary` / `cloud`、http 的 `cloud`、
|
|
423
|
+
* prompt 的 `continueOnBlock` 时,这里一行未改就受理了它们 —— 受理 = 读者携带;后四键本服务如实带、不执行,能力位与契约附录明写);
|
|
420
424
|
* 受理 ⇒ 分类器答 `loaded` ⇒ 组与条目的下标与原值逐位对齐。值为 `undefined` 的键与缺席同读(读者同一口径)。坐标经 {@link hooksCoordinate}(契约包出门形 + 回显口径;凭据形键段不原样回显)。
|
|
421
425
|
*
|
|
422
426
|
* 判据边界(与另两个实例同):只判**键名**(值形归读者);拒只在 FRESH 提交面 —— 续跑重放走 {@link parseTaskSettings},读者照旧剥掉它不携带的键,存量体按受理时的读法重放(4xx 打在重放腿上会砖死停驻任务)。
|
|
423
|
-
* 为什么必须拒:一只被剥掉的键对调用方读作「生效了」——
|
|
427
|
+
* 为什么必须拒:一只被剥掉的键对调用方读作「生效了」—— `plugin` 写在 http 条目上被剥掉,写的人以为插件上下文在;`args` 写在 http 条目上被剥掉,写的人以为不过 shell;
|
|
428
|
+
* `onFailure: "block"` 写在 prompt 条目上被剥掉(契约只在 command / http 上承运),写的人以为守卫起不来时失效关闭。
|
|
424
429
|
*/
|
|
425
430
|
export declare function hooksKeyIssue(raw: unknown, config: RunnableHooksConfig): KeyClosureIssue | null;
|
|
426
431
|
/**
|
package/dist/task-settings.js
CHANGED
|
@@ -78,6 +78,17 @@ export const MAX_SETTINGS_OUTPUT_STYLE_CHARS = 16_384;
|
|
|
78
78
|
export const MAX_SETTINGS_ENV_VARS = 256;
|
|
79
79
|
export const MAX_SETTINGS_ENV_VALUE_CHARS = 32_768;
|
|
80
80
|
export const MAX_SETTINGS_ENV_KEY_CHARS = 256;
|
|
81
|
+
function settingsEnvMemberReadable(k, val) {
|
|
82
|
+
return k.length > 0 && k.length <= MAX_SETTINGS_ENV_KEY_CHARS && typeof val === "string" && val.length <= MAX_SETTINGS_ENV_VALUE_CHARS;
|
|
83
|
+
}
|
|
84
|
+
function settingsEnvUnreadable(v) {
|
|
85
|
+
if (v === undefined || v === null)
|
|
86
|
+
return false;
|
|
87
|
+
if (typeof v !== "object" || Array.isArray(v))
|
|
88
|
+
return true;
|
|
89
|
+
const entries = Object.entries(v);
|
|
90
|
+
return entries.length > MAX_SETTINGS_ENV_VARS || entries.some(([k, val]) => !settingsEnvMemberReadable(k, val));
|
|
91
|
+
}
|
|
81
92
|
function cleanEnvMap(v) {
|
|
82
93
|
if (v === null || typeof v !== "object" || Array.isArray(v))
|
|
83
94
|
return undefined;
|
|
@@ -88,7 +99,7 @@ function cleanEnvMap(v) {
|
|
|
88
99
|
if (n >= MAX_SETTINGS_ENV_VARS || seen >= MAX_SETTINGS_ENV_VARS * 8)
|
|
89
100
|
break;
|
|
90
101
|
seen++;
|
|
91
|
-
if (
|
|
102
|
+
if (settingsEnvMemberReadable(k, val)) {
|
|
92
103
|
out[k] = val;
|
|
93
104
|
n++;
|
|
94
105
|
}
|
|
@@ -98,9 +109,9 @@ function cleanEnvMap(v) {
|
|
|
98
109
|
export const SETTINGS_ENV_CREDENTIAL_MATCHES = ["name", "value_shape"];
|
|
99
110
|
export function readSettingsEnv(settings) {
|
|
100
111
|
if (settings === null || typeof settings !== "object" || Array.isArray(settings))
|
|
101
|
-
return { sent: false, reaching: undefined };
|
|
112
|
+
return { sent: false, reaching: undefined, unreadable: false };
|
|
102
113
|
const env = settings.env;
|
|
103
|
-
return { sent: env !== undefined && env !== null, reaching: cleanEnvMap(env) };
|
|
114
|
+
return { sent: env !== undefined && env !== null, reaching: cleanEnvMap(env), unreadable: settingsEnvUnreadable(env) };
|
|
104
115
|
}
|
|
105
116
|
const MAX_CREDENTIAL_KEYS_NAMED = 8;
|
|
106
117
|
const MATCH_PHRASE = { name: "a credential variable of this engine", value_shape: "a value shaped like a secret" };
|
|
@@ -131,7 +142,7 @@ export function settingsEnvCredentialIssue(reaching, credentialNames) {
|
|
|
131
142
|
}
|
|
132
143
|
export function withoutKeys(layer, keys) {
|
|
133
144
|
const drop = new Set(keys);
|
|
134
|
-
return { sent: layer.sent, reaching: Object.fromEntries(Object.entries(layer.reaching ?? {}).filter(([k]) => !drop.has(k))) };
|
|
145
|
+
return { sent: layer.sent, reaching: Object.fromEntries(Object.entries(layer.reaching ?? {}).filter(([k]) => !drop.has(k))), unreadable: layer.unreadable };
|
|
135
146
|
}
|
|
136
147
|
export const SETTINGS_PERMISSION_BUCKETS = ["allow", "deny", "ask"];
|
|
137
148
|
export const SETTINGS_PERMISSION_BUCKET_REFUSALS = ["over_cap", "bad_entry"];
|
|
@@ -309,7 +320,7 @@ export function parseTaskSettings(raw, seats = {}) {
|
|
|
309
320
|
}
|
|
310
321
|
const envLayer = seats.settingsEnv ?? readSettingsEnv(s);
|
|
311
322
|
const shellEnv = envLayer.reaching;
|
|
312
|
-
if (envLayer.
|
|
323
|
+
if (envLayer.unreadable)
|
|
313
324
|
deferred.push("env");
|
|
314
325
|
const out = {};
|
|
315
326
|
const perms = s.permissions;
|
|
@@ -447,7 +458,7 @@ export function rulePolicyBucketsRefusal(permissions, bases) {
|
|
|
447
458
|
if (names.length === 0)
|
|
448
459
|
continue;
|
|
449
460
|
const declared = declaredFor(root);
|
|
450
|
-
const judged = judgeUnmatchableToolNames(`permissions.${bucket}`, names, { consumer: "rule-policy", behavior: bucket, ...(declared !== undefined ? { pathBases: declared } : {}) });
|
|
461
|
+
const judged = judgeUnmatchableToolNames(`permissions.${bucket}`, names, { consumer: "rule-policy", behavior: bucket, noticeSeat: "engine", ...(declared !== undefined ? { pathBases: declared } : {}) });
|
|
451
462
|
if (judged === undefined)
|
|
452
463
|
continue;
|
|
453
464
|
first ??= { bucket, message: judged.message };
|
package/dist/tool-approval.d.ts
CHANGED
|
@@ -145,6 +145,9 @@ export interface ParkedAskRedeemRequest {
|
|
|
145
145
|
decider: ApprovalDecider;
|
|
146
146
|
/** [ref] ctrl+g 编辑放行的实参整体替换(approve 才有意义)。 */
|
|
147
147
|
updatedInput?: unknown;
|
|
148
|
+
/** 卡上点的是 `allow_session` ⇒ `"session"`:与 `/decide` 体上的 `remember:"session"` 是**同一只**「本会话放行」请求,交同一个铸点
|
|
149
|
+
* (续跑腿 `resumeCheckpoint`;可记与否从同一条停驻行判、落同一只豁免店、只在结清之后落)。缺席 = 只放行这一次的那两个词。 */
|
|
150
|
+
remember?: "session";
|
|
148
151
|
/** 发起本次 respond 的**已验证**调用方(live 腿 `gatedPrincipal` 的那一把)。席在赎回之前拿它与
|
|
149
152
|
* **checkpoint 当下的 scope** 对一次(codex R1-[high] 一:收编改写身份之后,任何缓存的属主判据都
|
|
150
153
|
* 过期;门必须贴在当下的持久事实上)。 */
|
|
@@ -153,11 +156,15 @@ export interface ParkedAskRedeemRequest {
|
|
|
153
156
|
* 缺席 ⇒ 那条腿按「无请求」形处置(它自己的成文语义,本席不替它决定)。 */
|
|
154
157
|
httpReq?: IncomingMessage;
|
|
155
158
|
}
|
|
156
|
-
/** [ref]
|
|
157
|
-
|
|
159
|
+
/** [ref]:赎回席的结局 = 赎回腿的原始 HTTP 结果面 + 请求带了 `remember` 时铸点的真答(`rememberApplied`:落没落;不进 `body` —— 首次受理的回执挂它,
|
|
160
|
+
* 受理回执(幂等回放的那一份)不存它)。 */
|
|
161
|
+
export interface ParkedAskRedeemResult {
|
|
158
162
|
status: number;
|
|
159
163
|
body: Record<string, unknown>;
|
|
160
|
-
|
|
164
|
+
rememberApplied?: boolean;
|
|
165
|
+
}
|
|
166
|
+
/** [ref]:赎回席(装配层注入;缺席 ⇒ PARKED 臂逐字回落修前 404)。 */
|
|
167
|
+
export type ParkedAskRedeem = (req: ParkedAskRedeemRequest) => Promise<ParkedAskRedeemResult>;
|
|
161
168
|
/**
|
|
162
169
|
* 一张门被引擎**重开**过的停驻卡([ref]):决过之后,续跑腿在被批准的动作开跑之前失败,引擎把同一张门(同一把 token)翻回待决。
|
|
163
170
|
* `reason` = core 记在行上的重开因由词原样(闭集 `REOPEN_REASONS`:`env_failed` 同一个决议经耐久回决口(`decidePath`)再交一次即可续跑 —— 本副本还留着首次受理回执时(缺省 1 小时内、未被容量帽逐出)应答口回放那张回执、不驱续跑;`tool_unavailable` / `constraint_rejected` 要重新决;`config_refused` 改好部署配置后再交原决议,或重新决);
|
|
@@ -1291,8 +1298,9 @@ export declare function approvalPreambleReplays(input: Omit<ApprovalLegInput, "n
|
|
|
1291
1298
|
/** 一条 **DECIDED 行**能交还给引擎的全部形(`AskOutcome` 减掉 park 路由那一臂 —— 一条有决议的行
|
|
1292
1299
|
* 从定义上不是「投递面拿走了它」)。{@link ToolApprovalCoordinator.notifyExternalDecision} 收的就是它。 */
|
|
1293
1300
|
export type DecidedAskOutcome = Exclude<AskOutcome, "unavailable">;
|
|
1294
|
-
/** 铸点的入参形 =
|
|
1295
|
-
|
|
1301
|
+
/** 铸点的入参形 = 行上与**这条决议本身**有关的四格。整行(`AskRow`)与 claim 败方读数都满足。
|
|
1302
|
+
* `decisionNote` 与 `settledBy` / `decidedVia` 同律**必填**(可空)—— 可选会让一个漏挑这一列的投影静默编译过,而漏挑的后果正是把带说明的拒交成裸拒。 */
|
|
1303
|
+
type DecidedRowFacts = Pick<AskRow, "decision" | "settledBy" | "decidedVia" | "decisionNote"> & {
|
|
1296
1304
|
updatedInput?: unknown;
|
|
1297
1305
|
};
|
|
1298
1306
|
/**
|
|
@@ -1303,12 +1311,17 @@ type DecidedRowFacts = Pick<AskRow, "decision" | "settledBy" | "decidedVia"> & {
|
|
|
1303
1311
|
* 重放 / 兄弟广播 / 歧义提交恢复三条路上全都退化成裸 `false`,而裸 `false` 在 core 那边逐字是
|
|
1304
1312
|
* 「**一个人**拒绝了」。手抄投影全面下线([ref]):消费点交行,形由这里铸。
|
|
1305
1313
|
*
|
|
1306
|
-
*
|
|
1314
|
+
* 四条读法,每条的属主注在别处,这里只落笔:
|
|
1307
1315
|
* · **方向** —— `decision !== "approve"` 即拒(列的二值由店的 CAS 保证);
|
|
1308
1316
|
* · **编辑载荷**([ref])—— `updatedInput` 键缺席 = 没带编辑 ⇒ 裸 `true`;在场(**含 `null`**)= 编辑的
|
|
1309
1317
|
* 字面值 ⇒ 对象臂(语义三态的唯一属主 = `AskRow.updatedInput` 顶注);
|
|
1310
1318
|
* · **结算来源**([ref])—— 行上非 null 即宿主自报的那个词(`null` = 人决,与「不铸这个键」同义;
|
|
1311
|
-
* 语义属主 = `AskRow.settledBy` 顶注)
|
|
1319
|
+
* 语义属主 = `AskRow.settledBy` 顶注);
|
|
1320
|
+
* · **拒因**([ref] 的行派生半场)—— 拒行上**非空**的 `decisionNote` 铸成 `reason`(与应答口 `shapeDeny` 同键同形:core 以带说明的人拒句
|
|
1321
|
+
* 把它交给模型,围栏 `delimitUntrusted` 与长度上限 `REVIEWER_NOTE_MAX_BODY` 全在 core,本仓只透传不预判;空串按 core 契约的缺席读,不铸只装了
|
|
1322
|
+
* 空值的对象臂)。**allow 行的说明恒不铸**:core 对 allow 行的 `reason` 恒销毁,说明只走审计面(行的 `decisionNote` 列)。
|
|
1323
|
+
* 此前这一格不在铸点里 ⇒ 耐久决断口 / 重放 / 兄弟广播 / claim 败方 / 歧义提交恢复 / 悬挂轮询六条行派生的路,都把带说明的拒交成裸 `false`
|
|
1324
|
+
* (core 读作「一个人拒了、没说怎么办」:STOP 句 + 本轮收住),而同一段说明经应答口到达却带着 `reason` 进模型 —— 一扇门两种去向。
|
|
1312
1325
|
*
|
|
1313
1326
|
* 🔴 [ref]:来源位**两向都读**。决定体的出处位 `decidedBy:"policy"` 在 allow 与 deny 上都会落列(引擎 7.39.0 起铸
|
|
1314
1327
|
* `policy_allowed`),所以 approve 行带来源位是一条合法的行,它的每条读回路径交还 `{allow:true, settledBy:"policy", updatedInput?}`
|
|
@@ -1421,7 +1434,7 @@ export declare class ToolApprovalCoordinator {
|
|
|
1421
1434
|
* ask 的 `sessionId` 咨询一次——「这次授权是在**哪里**点的」在授权发生时捕获,不在回决时再猜。
|
|
1422
1435
|
* 回 `undefined` = 该部署形上 run 的 workspace root 不可知(远程沙箱/多租户等)⇒ 不铸 scope,落
|
|
1423
1436
|
* core 的 global 缺省(= 现行为,恒不更宽;也绝不错铸一个坐标系不对的 root)。装配见 main.ts:
|
|
1424
|
-
* registry cwd(host lane 显式注册的 launch dir)??
|
|
1437
|
+
* registry cwd(host lane 显式注册的 launch dir)?? 无手(`none`)单用户形的 `process.cwd()`。 */
|
|
1425
1438
|
private readonly ruleScopeRootFor;
|
|
1426
1439
|
/** [ref]:停驻行迟到决议的受理回执表(键 = 行的键 `askId`,插入序 = 逐出序)。语义与有界理由见
|
|
1427
1440
|
* {@link ParkRedemption} 顶注。 */
|
package/dist/tool-approval.js
CHANGED
|
@@ -512,7 +512,8 @@ export function outcomeOfDecidedRow(row) {
|
|
|
512
512
|
const allow = row.decision === "approve";
|
|
513
513
|
const source = row.settledBy !== null ? { settledBy: row.settledBy, ...(row.decidedVia !== null ? { decidedVia: row.decidedVia } : {}) } : {};
|
|
514
514
|
const edit = allow && row.updatedInput !== undefined ? { updatedInput: row.updatedInput } : {};
|
|
515
|
-
|
|
515
|
+
const denyReason = !allow && row.decisionNote ? { reason: row.decisionNote } : {};
|
|
516
|
+
return row.settledBy === null && !("updatedInput" in edit) && !("reason" in denyReason) ? allow : { allow, ...edit, ...denyReason, ...source };
|
|
516
517
|
}
|
|
517
518
|
function settleArgsOfDecided(outcome) {
|
|
518
519
|
if (typeof outcome === "boolean")
|
|
@@ -521,6 +522,7 @@ function settleArgsOfDecided(outcome) {
|
|
|
521
522
|
allowed: outcome.allow,
|
|
522
523
|
...(outcome.updatedInput !== undefined ? { updatedInput: outcome.updatedInput } : {}),
|
|
523
524
|
...(outcome.settledBy !== undefined ? { source: { settledBy: outcome.settledBy, ...(outcome.decidedVia !== undefined ? { decidedVia: outcome.decidedVia } : {}) } } : {}),
|
|
525
|
+
...(!outcome.allow && outcome.reason !== undefined ? { denyReason: outcome.reason } : {}),
|
|
524
526
|
};
|
|
525
527
|
}
|
|
526
528
|
function verdictOfDecided(args) {
|
|
@@ -529,6 +531,7 @@ function verdictOfDecided(args) {
|
|
|
529
531
|
allowed: args.allowed,
|
|
530
532
|
...(args.updatedInput !== undefined ? { updatedInput: args.updatedInput } : {}),
|
|
531
533
|
...(args.source !== undefined ? { hostSource: args.source } : {}),
|
|
534
|
+
...(args.denyReason !== undefined ? { denyReason: args.denyReason } : {}),
|
|
532
535
|
};
|
|
533
536
|
}
|
|
534
537
|
function settleArgsOf(outcome) {
|
|
@@ -2478,7 +2481,6 @@ export class ToolApprovalCoordinator {
|
|
|
2478
2481
|
askId: row.askId,
|
|
2479
2482
|
idempotent: true,
|
|
2480
2483
|
...decided,
|
|
2481
|
-
...(parsed.value === "allow_session" ? { rememberApplied: false } : {}),
|
|
2482
2484
|
...noteRecordedReceipt(parsed.note, noteLandedOnRow(parsed.note, row.decisionNote)),
|
|
2483
2485
|
...this.lateRuleRefusal(parsed),
|
|
2484
2486
|
},
|
|
@@ -2519,6 +2521,7 @@ export class ToolApprovalCoordinator {
|
|
|
2519
2521
|
...(parsed.note !== undefined ? { note: parsed.note } : {}),
|
|
2520
2522
|
decider: parsed.decider,
|
|
2521
2523
|
...(parsed.updatedInput !== undefined && parsed.value !== "deny" ? { updatedInput: parsed.updatedInput } : {}),
|
|
2524
|
+
...(parsed.value === "allow_session" ? { remember: "session" } : {}),
|
|
2522
2525
|
...(principal !== undefined ? { principal } : {}),
|
|
2523
2526
|
...(httpReq !== undefined ? { httpReq } : {}),
|
|
2524
2527
|
});
|
|
@@ -2555,7 +2558,7 @@ export class ToolApprovalCoordinator {
|
|
|
2555
2558
|
approvalId: id,
|
|
2556
2559
|
askId: row.askId,
|
|
2557
2560
|
accepted: "parked_redeemed",
|
|
2558
|
-
...(parsed.value === "allow_session" ? { rememberApplied:
|
|
2561
|
+
...(parsed.value === "allow_session" ? { rememberApplied: out.rememberApplied === true } : {}),
|
|
2559
2562
|
...(rule?.body ?? {}),
|
|
2560
2563
|
},
|
|
2561
2564
|
};
|
|
@@ -2667,7 +2670,6 @@ export class ToolApprovalCoordinator {
|
|
|
2667
2670
|
accepted: "parked_redeemed",
|
|
2668
2671
|
idempotent: true,
|
|
2669
2672
|
decision: receipt.decision === "approve" ? "allow" : "deny",
|
|
2670
|
-
...(parsed.value === "allow_session" ? { rememberApplied: false } : {}),
|
|
2671
2673
|
...(rule ?? {}),
|
|
2672
2674
|
},
|
|
2673
2675
|
};
|
|
@@ -2840,14 +2842,16 @@ export class ToolApprovalCoordinator {
|
|
|
2840
2842
|
this.allowAllSessions.add(sessionAllowKey(judgedOwner, entry.sessionId, sessionAllowCategory(entry.toolName), entry.grantBinding));
|
|
2841
2843
|
}
|
|
2842
2844
|
const allowed = parsed.value !== "deny";
|
|
2843
|
-
const settleArgs = opts?.settleOutcome !== undefined
|
|
2845
|
+
const settleArgs = opts?.settleOutcome !== undefined
|
|
2846
|
+
? settleArgsOfDecided(opts.settleOutcome)
|
|
2847
|
+
: { allowed, updatedInput: parsed.updatedInput, source: liveHostSource(parsed.decider), ...(!allowed && parsed.note !== undefined ? { denyReason: parsed.note } : {}) };
|
|
2844
2848
|
const readRootGrant = opts?.settleOutcome === undefined || opts.settleOutcomeIsThisRequest === true ? parsed.readRootGrant : undefined;
|
|
2845
2849
|
entry.settle({
|
|
2846
2850
|
by: "human",
|
|
2847
2851
|
allowed: settleArgs.allowed,
|
|
2848
2852
|
updatedInput: settleArgs.updatedInput,
|
|
2849
2853
|
...(settleArgs.source !== undefined ? { hostSource: settleArgs.source } : {}),
|
|
2850
|
-
...(
|
|
2854
|
+
...(settleArgs.denyReason !== undefined ? { denyReason: settleArgs.denyReason } : {}),
|
|
2851
2855
|
...(readRootGrant !== undefined ? { readRootGrant } : {}),
|
|
2852
2856
|
});
|
|
2853
2857
|
const updatedInputDelivered = opts?.updatedInputDelivered ?? true;
|