@sema-agent/server 7.131.0 → 7.133.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 +575 -0
- package/README.md +12 -9
- package/README.zh-CN.md +9 -6
- package/USAGE.md +326 -98
- package/deploy/sema-up/README.md +19 -1
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -2
- package/deploy/sema-up/chart/templates/server.yaml +5 -2
- package/deploy/sema-up/stack/compose.yaml +3 -0
- package/deploy/sema-up/stack/sema-stack-cluster.yaml +4 -2
- package/dist/adoption/plan.d.ts +3 -2
- package/dist/adoption/plan.js +7 -5
- package/dist/adoption/runner.js +3 -10
- package/dist/adoption/sql.d.ts +3 -2
- package/dist/adoption/sql.js +3 -5
- package/dist/adoption/wire.d.ts +4 -1
- package/dist/adoption/wire.js +1 -0
- package/dist/approval-ask-audit-store.d.ts +31 -13
- package/dist/approval-ask-audit-store.js +272 -74
- package/dist/approval-ask-machine.d.ts +15 -0
- package/dist/approval-ask-machine.js +6 -0
- package/dist/approval-ask-retention.d.ts +136 -0
- package/dist/approval-ask-retention.js +102 -0
- package/dist/approval-card.d.ts +82 -20
- package/dist/approval-card.js +46 -16
- package/dist/approval-deny-reasons.d.ts +1 -1
- package/dist/approval.d.ts +9 -0
- package/dist/approval.js +24 -3
- package/dist/audit.d.ts +33 -19
- package/dist/audit.js +12 -16
- package/dist/auth-bridge.d.ts +4 -0
- package/dist/auth-bridge.js +10 -11
- package/dist/bake-runner/main.js +3 -2
- package/dist/boot/deferred-sandbox-path-env.js +1 -1
- package/dist/boot/deployment-mods.d.ts +31 -0
- package/dist/boot/deployment-mods.js +26 -0
- package/dist/boot/execution-env.d.ts +1 -1
- package/dist/boot/execution-env.js +27 -12
- package/dist/boot/execution-lane.js +11 -0
- package/dist/boot/leader.js +2 -0
- package/dist/boot/memory-boundary.d.ts +2 -2
- package/dist/boot/memory-boundary.js +2 -2
- package/dist/boot/memory-consolidation.d.ts +5 -4
- package/dist/boot/memory-consolidation.js +7 -6
- package/dist/boot/org-delivery.d.ts +28 -0
- package/dist/boot/org-delivery.js +20 -0
- package/dist/boot/read-deny-anchor-audit.d.ts +17 -0
- package/dist/boot/read-deny-anchor-audit.js +36 -0
- package/dist/boot/reapers.d.ts +3 -0
- package/dist/boot/reapers.js +21 -1
- package/dist/boot/resolve-spec.d.ts +4 -5
- package/dist/boot/resolve-spec.js +74 -123
- package/dist/boot/runner-deps.d.ts +19 -8
- package/dist/boot/runner-deps.js +15 -2
- package/dist/boot/session-faces.d.ts +2 -7
- package/dist/boot/session-faces.js +4 -2
- package/dist/boot/stage-02-web-admin-pull.js +4 -1
- package/dist/boot/stage-03-store-backend.d.ts +1 -1
- package/dist/boot/stage-03-store-backend.js +2 -2
- package/dist/boot/stage-04-stores.d.ts +1 -1
- package/dist/boot/stage-05-execution-env.d.ts +4 -4
- package/dist/boot/stage-05-execution-env.js +7 -10
- package/dist/boot/stage-06-runners.d.ts +4 -2
- package/dist/boot/stage-06-runners.js +11 -7
- package/dist/boot/stage-07-capability-layer.d.ts +4 -2
- package/dist/boot/stage-07-capability-layer.js +27 -6
- package/dist/boot/stage-08-reapers.d.ts +4 -2
- package/dist/boot/stage-08-reapers.js +2 -2
- package/dist/boot/stage-09-leader.d.ts +6 -9
- package/dist/boot/stage-10-http-server.d.ts +6 -9
- package/dist/boot/stage-10-http-server.js +7 -9
- package/dist/boot/stores.d.ts +1 -1
- package/dist/boot/stores.js +7 -8
- package/dist/boot/web-admin.d.ts +4 -3
- package/dist/boot/web-admin.js +186 -98
- package/dist/boot/workflow-orchestration.d.ts +2 -0
- package/dist/boot/workflow-orchestration.js +2 -1
- package/dist/brain.js +25 -25
- package/dist/breaker-key.d.ts +6 -0
- package/dist/breaker-key.js +29 -0
- package/dist/budget.js +5 -4
- package/dist/caller-text-echo.d.ts +23 -0
- package/dist/caller-text-echo.js +21 -0
- package/dist/capabilities/brand-identity.d.ts +26 -0
- package/dist/capabilities/brand-identity.js +27 -0
- package/dist/capabilities/center-plugins.d.ts +7 -0
- package/dist/capabilities/center-plugins.js +1 -1
- package/dist/capabilities/center-prompts.d.ts +32 -59
- package/dist/capabilities/center-prompts.js +18 -32
- package/dist/capabilities/composite-members.d.ts +1 -1
- package/dist/capabilities/composite-members.js +1 -1
- package/dist/capabilities/engine-capabilities.js +2 -1
- package/dist/capabilities/execution-lane.js +2 -2
- package/dist/capabilities/hands-lane.d.ts +30 -6
- package/dist/capabilities/hands-lane.js +11 -1
- package/dist/capabilities/mcp-probe.d.ts +48 -3
- package/dist/capabilities/mcp-probe.js +47 -135
- package/dist/capabilities/scenarios.d.ts +95 -45
- package/dist/capabilities/scenarios.js +53 -38
- package/dist/capabilities/skills.d.ts +19 -4
- package/dist/capabilities/skills.js +30 -10
- package/dist/capability-facts.d.ts +34 -4
- package/dist/capability-facts.js +28 -2
- package/dist/center-config-tier.d.ts +69 -0
- package/dist/center-config-tier.js +42 -0
- package/dist/checkpoint-identity.d.ts +16 -0
- package/dist/checkpoint-identity.js +19 -0
- package/dist/config-catalog.d.ts +17 -10
- package/dist/config-catalog.js +47 -32
- package/dist/config-d-migration.d.ts +3 -1
- package/dist/config-d-migration.js +2 -2
- package/dist/config-dir-trust.d.ts +114 -0
- package/dist/config-dir-trust.js +388 -0
- package/dist/config-invariants.d.ts +18 -5
- package/dist/config-invariants.js +35 -3
- package/dist/config-lkg.d.ts +9 -9
- package/dist/config-lkg.js +20 -4
- package/dist/config-provider.d.ts +9 -2
- package/dist/config-provider.js +18 -6
- package/dist/config-types.d.ts +75 -20
- package/dist/config-types.js +8 -0
- package/dist/config.d.ts +13 -0
- package/dist/config.js +137 -62
- package/dist/delegated-session-owner.d.ts +185 -0
- package/dist/delegated-session-owner.js +119 -0
- package/dist/device-protocol.d.ts +5 -3
- package/dist/device-protocol.js +1 -1
- package/dist/device-ws-hub.js +21 -2
- package/dist/device-ws-protocol.d.ts +70 -6
- package/dist/device-ws-protocol.js +50 -22
- package/dist/elicitation.js +3 -2
- package/dist/entry-problems.d.ts +34 -0
- package/dist/entry-problems.js +14 -0
- package/dist/env-name-allowlist-knobs.d.ts +12 -2
- package/dist/env-name-allowlist-knobs.js +5 -4
- package/dist/exec-bounds.d.ts +15 -3
- package/dist/exec-bounds.js +4 -0
- package/dist/execution-lane-caps.d.ts +56 -10
- package/dist/execution-lane-caps.js +50 -0
- package/dist/field-conflict.d.ts +43 -0
- package/dist/field-conflict.js +20 -0
- package/dist/fleet/fleet-bus.d.ts +80 -6
- package/dist/fleet/fleet-bus.js +41 -9
- package/dist/hooks/classic-stations.d.ts +91 -0
- package/dist/hooks/classic-stations.js +27 -0
- package/dist/hooks/command-spawn.d.ts +57 -0
- package/dist/hooks/command-spawn.js +139 -0
- package/dist/hooks/hook-llm.d.ts +8 -5
- package/dist/hooks/hook-llm.js +79 -36
- package/dist/hooks/hook-runner.d.ts +349 -95
- package/dist/hooks/hook-runner.js +855 -568
- package/dist/hooks/hook-source.d.ts +44 -0
- package/dist/hooks/hook-source.js +40 -0
- package/dist/http/active-run-conflict.d.ts +5 -13
- package/dist/http/active-run-conflict.js +17 -27
- package/dist/http/admission.d.ts +8 -2
- package/dist/http/admission.js +188 -101
- package/dist/http/approval-sweeps.js +99 -21
- package/dist/http/caller-trust.d.ts +77 -0
- package/dist/http/caller-trust.js +143 -0
- package/dist/http/checkpoint-ctx.d.ts +41 -24
- package/dist/http/checkpoint-ctx.js +23 -16
- package/dist/http/claimed-run.d.ts +14 -0
- package/dist/http/claimed-run.js +15 -0
- package/dist/http/device-placement.d.ts +2 -4
- package/dist/http/device-placement.js +7 -11
- package/dist/http/dispatch.d.ts +0 -4
- package/dist/http/dispatch.js +15 -13
- package/dist/http/durable-run-leg.d.ts +6 -33
- package/dist/http/durable-run-leg.js +36 -10
- package/dist/http/health-self-report.d.ts +7 -5
- package/dist/http/health-self-report.js +4 -18
- package/dist/http/owner-access.d.ts +56 -0
- package/dist/http/owner-access.js +42 -0
- package/dist/http/principal-gate.d.ts +70 -28
- package/dist/http/principal-gate.js +61 -15
- package/dist/http/readiness.d.ts +11 -5
- package/dist/http/readiness.js +10 -3
- package/dist/http/refusal-body.d.ts +21 -0
- package/dist/http/refusal-body.js +4 -0
- package/dist/http/request-guards.d.ts +43 -23
- package/dist/http/request-guards.js +53 -17
- package/dist/http/resume-ctx-read.d.ts +2 -5
- package/dist/http/resume-ctx-read.js +7 -4
- package/dist/http/resume-legs.d.ts +28 -4
- package/dist/http/resume-legs.js +169 -91
- package/dist/http/retired-service-deps.d.ts +43 -0
- package/dist/http/retired-service-deps.js +18 -0
- package/dist/http/route-ctx.d.ts +44 -28
- package/dist/http/route-ctx.js +4 -0
- package/dist/http/route-table.js +2 -0
- package/dist/http/routes/a2a-serve.js +3 -4
- package/dist/http/routes/admin-config-refresh.js +1 -1
- package/dist/http/routes/admin-drain.js +1 -1
- package/dist/http/routes/admin-memory-optout.js +5 -1
- package/dist/http/routes/adoption.js +2 -9
- package/dist/http/routes/approvals-assistant.js +49 -48
- package/dist/http/routes/background.js +3 -2
- package/dist/http/routes/capabilities.js +21 -5
- package/dist/http/routes/config-catalog.d.ts +3 -3
- package/dist/http/routes/config-catalog.js +1 -1
- package/dist/http/routes/devices.js +3 -17
- package/dist/http/routes/diagnostics.js +6 -2
- package/dist/http/routes/images.js +6 -7
- package/dist/http/routes/leader.js +1 -8
- package/dist/http/routes/mcp-reconnect.d.ts +1 -1
- package/dist/http/routes/mcp-reconnect.js +3 -2
- package/dist/http/routes/memory-bundle.js +1 -1
- package/dist/http/routes/memory-compliance.js +1 -1
- package/dist/http/routes/memory-consolidation.js +1 -1
- package/dist/http/routes/memory-origin.js +1 -1
- package/dist/http/routes/memory-policy.d.ts +1 -1
- package/dist/http/routes/memory-policy.js +3 -2
- package/dist/http/routes/notify-wake.js +8 -21
- package/dist/http/routes/observability.js +2 -2
- package/dist/http/routes/principal-inbox.d.ts +39 -0
- package/dist/http/routes/principal-inbox.js +76 -0
- package/dist/http/routes/retention-ops.js +2 -9
- package/dist/http/routes/rules.js +5 -18
- package/dist/http/routes/runs.d.ts +5 -0
- package/dist/http/routes/runs.js +34 -107
- package/dist/http/routes/session-sync.js +15 -26
- package/dist/http/routes/sessions.js +30 -40
- package/dist/http/routes/shared-memory.js +2 -13
- package/dist/http/routes/side-query.js +8 -7
- package/dist/http/routes/tasks.js +67 -21
- package/dist/http/routes/workflows.d.ts +351 -0
- package/dist/http/routes/workflows.js +153 -119
- package/dist/http/send.d.ts +33 -10
- package/dist/http/send.js +21 -4
- package/dist/http/server.d.ts +27 -18
- package/dist/http/server.js +34 -6
- package/dist/http/stored-body-replay.js +17 -4
- package/dist/http/submit-ctx.d.ts +25 -0
- package/dist/http/submit-ctx.js +40 -0
- package/dist/http/submit-replay.d.ts +4 -3
- package/dist/http/submit-replay.js +5 -4
- package/dist/http/wire-types.d.ts +11 -8
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -2
- package/dist/lane-home-probe.d.ts +112 -0
- package/dist/lane-home-probe.js +101 -0
- package/dist/leader/endpoint.d.ts +4 -1
- package/dist/leader/endpoint.js +11 -10
- package/dist/limit-refusal.d.ts +59 -0
- package/dist/limit-refusal.js +15 -0
- package/dist/main.js +1 -1
- package/dist/mcp-assertion-header.d.ts +32 -19
- package/dist/mcp-assertion-header.js +10 -9
- package/dist/mcp-tool-faces.d.ts +5 -0
- package/dist/mcp-tool-faces.js +6 -4
- package/dist/memory-project-layer.d.ts +37 -0
- package/dist/memory-project-layer.js +46 -0
- package/dist/memory-scope.d.ts +24 -17
- package/dist/memory-scope.js +24 -8
- package/dist/memory-sync-client.d.ts +27 -13
- package/dist/memory-sync-client.js +107 -18
- package/dist/model-entry-refusal.d.ts +9 -1
- package/dist/model-entry-refusal.js +6 -1
- package/dist/model-plane-face.d.ts +51 -0
- package/dist/model-plane-face.js +24 -0
- package/dist/model-provider.d.ts +44 -12
- package/dist/model-provider.js +21 -2
- package/dist/model-route-endpoint.d.ts +9 -12
- package/dist/model-route-endpoint.js +8 -11
- package/dist/model-route-env.d.ts +22 -0
- package/dist/model-route-env.js +2 -0
- package/dist/model-route-gap.d.ts +60 -30
- package/dist/model-route-gap.js +21 -15
- package/dist/observability/corrupt-read-seat.d.ts +7 -0
- package/dist/observability/corrupt-read-seat.js +9 -0
- package/dist/observability/cost-taxonomy.d.ts +7 -7
- package/dist/observability/err-text.d.ts +6 -0
- package/dist/observability/err-text.js +18 -4
- package/dist/observability/fail-open.d.ts +76 -14
- package/dist/observability/fail-open.js +76 -14
- package/dist/observability/metrics.js +4 -1
- package/dist/observability/prompt-manifest.d.ts +33 -82
- package/dist/observability/prompt-manifest.js +122 -17
- package/dist/observability/run-terminal.js +14 -6
- package/dist/observability/secret-env-scrub.d.ts +13 -1
- package/dist/observability/secret-env-scrub.js +13 -1
- package/dist/observability/tool-trace.d.ts +16 -21
- package/dist/observability/tool-trace.js +58 -49
- package/dist/operator-ask.d.ts +10 -0
- package/dist/operator-ask.js +3 -0
- package/dist/orchestration/workflow-agent-session-index.d.ts +12 -12
- package/dist/orchestration/workflow-agent-session-index.js +9 -13
- package/dist/orchestration/workflow-completion-inbox.d.ts +42 -15
- package/dist/orchestration/workflow-completion-inbox.js +13 -0
- package/dist/orchestration/workflow-notify-journal.d.ts +13 -32
- package/dist/orchestration/workflow-notify-journal.js +27 -34
- package/dist/orchestration/workflow-park-decision.d.ts +89 -0
- package/dist/orchestration/workflow-park-decision.js +118 -0
- package/dist/org-delivery-gate.d.ts +81 -0
- package/dist/org-delivery-gate.js +59 -0
- package/dist/panel-tool-names.d.ts +23 -0
- package/dist/panel-tool-names.js +8 -0
- package/dist/parked-decide.d.ts +39 -6
- package/dist/parked-decide.js +98 -51
- package/dist/parked-revive-surface.d.ts +9 -2
- package/dist/parked-revive-surface.js +11 -8
- package/dist/per-task-image.d.ts +7 -1
- package/dist/per-task-image.js +3 -3
- package/dist/permission-rule-list.d.ts +1 -1
- package/dist/permission-rule-list.js +2 -2
- package/dist/plain-string-record.d.ts +25 -0
- package/dist/plain-string-record.js +32 -0
- package/dist/plugins/approval-ask-store-file.d.ts +16 -1
- package/dist/plugins/approval-ask-store-file.js +21 -0
- package/dist/plugins/approval-ask-store-memory.d.ts +18 -1
- package/dist/plugins/approval-ask-store-memory.js +34 -2
- package/dist/plugins/approval-ask-store-sql.d.ts +25 -0
- package/dist/plugins/approval-ask-store-sql.js +37 -1
- package/dist/plugins/blob-backend.d.ts +83 -15
- package/dist/plugins/blob-backend.js +68 -15
- package/dist/plugins/breaker-state-sql.d.ts +2 -2
- package/dist/plugins/breaker-state-sql.js +4 -4
- package/dist/plugins/caching-session-store.d.ts +3 -0
- package/dist/plugins/caching-session-store.js +3 -0
- package/dist/plugins/checkpoint-store-sql.d.ts +28 -4
- package/dist/plugins/checkpoint-store-sql.js +59 -28
- package/dist/plugins/file-history-store-sql.d.ts +5 -2
- package/dist/plugins/file-history-store-sql.js +3 -1
- package/dist/plugins/file-run-store.d.ts +5 -13
- package/dist/plugins/file-run-store.js +9 -0
- package/dist/plugins/fork-routing-session-store.d.ts +9 -1
- package/dist/plugins/fork-routing-session-store.js +12 -1
- package/dist/plugins/host-platform.d.ts +2 -0
- package/dist/plugins/host-platform.js +2 -1
- package/dist/plugins/k8s-bg-scripts.d.ts +11 -0
- package/dist/plugins/k8s-bg-scripts.js +22 -0
- package/dist/plugins/local-checkpoint-store.d.ts +2 -0
- package/dist/plugins/local-checkpoint-store.js +11 -3
- package/dist/plugins/local-session-store.d.ts +1 -1
- package/dist/plugins/local-session-store.js +1 -1
- package/dist/plugins/local-session-window.d.ts +39 -0
- package/dist/plugins/local-session-window.js +54 -0
- package/dist/plugins/mailbox-recipient-lifecycle.d.ts +3 -2
- package/dist/plugins/mailbox-store-sql.d.ts +30 -48
- package/dist/plugins/mailbox-store-sql.js +77 -52
- package/dist/plugins/memory-embedder-fingerprint.js +2 -1
- package/dist/plugins/memory-run-store.d.ts +5 -13
- package/dist/plugins/memory-run-store.js +8 -0
- package/dist/plugins/one-time-migrations.d.ts +245 -93
- package/dist/plugins/one-time-migrations.js +668 -207
- package/dist/plugins/org-delivery-quota-store.d.ts +123 -0
- package/dist/plugins/org-delivery-quota-store.js +228 -0
- package/dist/plugins/permission-rule-store-sql.d.ts +13 -7
- package/dist/plugins/permission-rule-store-sql.js +4 -18
- package/dist/plugins/pg-pool.js +39 -7
- package/dist/plugins/pg-session-storage.d.ts +20 -8
- package/dist/plugins/pg-session-storage.js +34 -21
- package/dist/plugins/remote-env-adb.d.ts +12 -12
- package/dist/plugins/remote-env-adb.js +21 -6
- package/dist/plugins/remote-env-device.js +3 -0
- package/dist/plugins/remote-env-e2b.d.ts +1 -1
- package/dist/plugins/remote-env-e2b.js +21 -9
- package/dist/plugins/remote-env-host.d.ts +9 -9
- package/dist/plugins/remote-env-host.js +10 -32
- package/dist/plugins/remote-env-k8s.d.ts +103 -38
- package/dist/plugins/remote-env-k8s.js +288 -95
- package/dist/plugins/remote-env-local-docker.d.ts +27 -13
- package/dist/plugins/remote-env-local-docker.js +82 -11
- package/dist/plugins/remote-env-ssh.d.ts +21 -12
- package/dist/plugins/remote-env-ssh.js +117 -5
- package/dist/plugins/remote-shell.d.ts +0 -1
- package/dist/plugins/remote-shell.js +1 -2
- package/dist/plugins/retention-store-sql.js +6 -2
- package/dist/plugins/run-store-sql.d.ts +16 -14
- package/dist/plugins/run-store-sql.js +22 -2
- package/dist/plugins/schema-consistency.d.ts +54 -0
- package/dist/plugins/schema-consistency.js +52 -0
- package/dist/plugins/schema-indexes.js +2 -0
- package/dist/plugins/send-user-file.js +2 -2
- package/dist/plugins/session-epoch-anchor.d.ts +39 -0
- package/dist/plugins/session-epoch-anchor.js +22 -0
- package/dist/plugins/session-store.d.ts +18 -8
- package/dist/plugins/session-store.js +15 -4
- package/dist/plugins/shared-memory-store-sql.d.ts +9 -3
- package/dist/plugins/shared-memory-store-sql.js +5 -16
- package/dist/plugins/sql-driver.d.ts +205 -1
- package/dist/plugins/sql-driver.js +325 -13
- package/dist/plugins/sql-errors.d.ts +64 -0
- package/dist/plugins/sql-errors.js +57 -0
- package/dist/plugins/store-backend.d.ts +36 -1
- package/dist/plugins/store-backend.js +42 -15
- package/dist/plugins/store-contracts.d.ts +42 -0
- package/dist/plugins/store-contracts.js +1 -0
- package/dist/plugins/tidb-pool.d.ts +6 -1
- package/dist/plugins/tidb-pool.js +44 -10
- package/dist/plugins/tidb-session-storage.d.ts +8 -11
- package/dist/plugins/tidb-session-storage.js +6 -16
- package/dist/plugins/tidb-session-store.d.ts +24 -4
- package/dist/plugins/tidb-session-store.js +29 -5
- package/dist/plugins/workflow-journal-store-sql.d.ts +73 -19
- package/dist/plugins/workflow-journal-store-sql.js +19 -6
- package/dist/plugins/workflow-run-store-sql.d.ts +30 -8
- package/dist/plugins/workflow-run-store-sql.js +50 -9
- package/dist/posture-source.d.ts +18 -10
- package/dist/posture-source.js +4 -1
- package/dist/project-identity.d.ts +45 -6
- package/dist/project-identity.js +162 -8
- package/dist/project-layer-key.d.ts +28 -0
- package/dist/project-layer-key.js +29 -0
- package/dist/prompts-domain-validate.d.ts +17 -61
- package/dist/prompts-domain-validate.js +9 -119
- package/dist/question.js +3 -2
- package/dist/read-deny-entry.d.ts +25 -0
- package/dist/read-deny-entry.js +12 -0
- package/dist/read-face-posture.d.ts +37 -11
- package/dist/read-face-posture.js +32 -3
- package/dist/request-key-closure.d.ts +9 -2
- package/dist/request-key-closure.js +11 -5
- package/dist/request-value-closure.d.ts +5 -0
- package/dist/request-value-closure.js +11 -3
- package/dist/rule-entry-list.d.ts +38 -11
- package/dist/rule-entry-list.js +106 -30
- package/dist/rules-consent.js +3 -4
- package/dist/run-acceptance.d.ts +19 -3
- package/dist/run-acceptance.js +13 -1
- package/dist/run-local.js +54 -24
- package/dist/runs.d.ts +15 -8
- package/dist/runs.js +35 -1
- package/dist/runtime-caps-resolver.d.ts +16 -6
- package/dist/runtime-caps-resolver.js +18 -5
- package/dist/sandbox-pkg-source.d.ts +19 -1
- package/dist/sandbox-pkg-source.js +29 -7
- package/dist/security.d.ts +87 -9
- package/dist/security.js +52 -9
- package/dist/server-secret-env.d.ts +44 -18
- package/dist/server-secret-env.js +49 -8
- package/dist/session-error-wire.d.ts +19 -2
- package/dist/session-error-wire.js +5 -1
- package/dist/session-incarnation.d.ts +15 -5
- package/dist/session-incarnation.js +16 -9
- package/dist/session-titled-frame.d.ts +33 -0
- package/dist/session-titled-frame.js +4 -0
- package/dist/session-titler.d.ts +9 -1
- package/dist/session-titler.js +27 -6
- package/dist/spec-fields.d.ts +28 -16
- package/dist/spec-fields.js +66 -54
- package/dist/sql-engine-posture.d.ts +31 -4
- package/dist/sql-engine-posture.js +36 -1
- package/dist/stored-request-tool-axes-m19.d.ts +19 -4
- package/dist/stored-request-tool-axes-m19.js +30 -2
- package/dist/task-a2a.d.ts +9 -1
- package/dist/task-a2a.js +73 -47
- package/dist/task-cwd.d.ts +1 -1
- package/dist/task-mcp.d.ts +46 -58
- package/dist/task-mcp.js +82 -107
- package/dist/task-settings.d.ts +95 -108
- package/dist/task-settings.js +77 -98
- package/dist/text-bidi.d.ts +1 -48
- package/dist/text-bidi.js +3 -5
- package/dist/tighten-only-seats.d.ts +150 -0
- package/dist/tighten-only-seats.js +196 -0
- package/dist/tool-approval.d.ts +304 -88
- package/dist/tool-approval.js +623 -239
- package/dist/trace/core-keyset-guard.d.ts +122 -20
- package/dist/trace/engine-notice-wire.d.ts +11 -3
- package/dist/trace/engine-notice-wire.js +8 -1
- package/dist/trace/exit-seat.d.ts +28 -0
- package/dist/trace/exit-seat.js +76 -0
- package/dist/trace/ledger-events.d.ts +6 -3
- package/dist/trace/ledger-sink.js +4 -1
- package/dist/trace/model-segment.js +1 -1
- package/dist/trace/project.d.ts +98 -17
- package/dist/trace/project.js +98 -50
- package/dist/trace/projection-table.d.ts +100 -0
- package/dist/trace/projection-table.js +130 -0
- package/dist/trace/redact.d.ts +54 -0
- package/dist/trace/redact.js +778 -152
- package/dist/trace/self-minted-wire.d.ts +345 -1
- package/dist/trace/self-minted-wire.js +117 -1
- package/dist/trace/wire-projection-faces.d.ts +377 -3
- package/dist/trace/wire-projection-faces.js +164 -1
- package/dist/url-refusal.js +2 -0
- package/dist/web-admin-client/apply-effective.d.ts +12 -0
- package/dist/web-admin-client/apply-effective.js +56 -5
- package/dist/web-admin-client/candidate-gate.d.ts +6 -6
- package/dist/web-admin-client/candidate-gate.js +3 -3
- package/dist/web-admin-client/facade.d.ts +1 -1
- package/dist/web-admin-client/facade.js +1 -1
- package/dist/web-admin-client/http-client.js +0 -6
- package/dist/web-admin-client/read-face.js +5 -9
- package/dist/web-admin-client/read-warnings.d.ts +13 -0
- package/dist/web-admin-client/read-warnings.js +10 -0
- package/dist/web-admin-client/skills-mcp.d.ts +3 -0
- package/dist/web-admin-client/skills-mcp.js +11 -9
- package/dist/web-admin-client/types.d.ts +2 -3
- package/dist/workspace-cache.d.ts +35 -0
- package/dist/workspace-cache.js +36 -0
- package/dist/workspace-space.d.ts +3 -2
- package/dist/workspace-space.js +2 -0
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +65 -10
- package/package.json +8 -4
- package/scripts/drain-check-local.mjs +34 -1
- package/scripts/drain-check.mysql.sql +30 -2
- package/scripts/drain-check.pg.sql +29 -2
- package/dist/capabilities/memory-notice.d.ts +0 -138
- package/dist/capabilities/memory-notice.js +0 -64
- package/dist/capabilities/prompt.d.ts +0 -17
- package/dist/capabilities/prompt.js +0 -6
- package/dist/mcp-content-origin.d.ts +0 -34
- package/dist/mcp-content-origin.js +0 -10
- package/dist/tool-axis-words.d.ts +0 -27
- package/dist/tool-axis-words.js +0 -9
- package/dist/wire-name-bound.d.ts +0 -14
- package/dist/wire-name-bound.js +0 -13
package/dist/task-settings.d.ts
CHANGED
|
@@ -27,12 +27,12 @@
|
|
|
27
27
|
* `APPROVAL_REQUIRE` (an ask rule), `APPROVAL_NEVER_AUTO` (a person, mandated), `MANUAL_MODE_SHELL_GATE=always` (shell).
|
|
28
28
|
* A request-carried skill's `allowedTools` is the same member's twin (same grammar, same predicate, same admission judge
|
|
29
29
|
* `rule-entry-list.ts`). Pinned on the real assembly: `test/allow-layer-operator-knobs.test.ts`.
|
|
30
|
-
* - permissionMode
|
|
31
|
-
* (
|
|
32
|
-
*
|
|
33
|
-
*
|
|
30
|
+
* - permissionMode:`defaultMode` 收 core `PERMISSION_MODES` **全集**(default | acceptEdits | plan | auto | bypassPermissions | dontAsk),
|
|
31
|
+
* 生效词原样过境 `TaskSpec.permissionMode`,模式**做什么**只在引擎里答(core `modePolicyOf` / `arbitrateByMode`)。本模块的折叠
|
|
32
|
+
* **不读**模式词:deny / ask 两张表在每一个词下编出同一只策略,部署基线照压(tightenTaskSpec deny-wins);bypass 放行的只是引擎
|
|
33
|
+
* 能放行的那几类问,部署 / 请求的 deny 与 ask 规则它一条都掀不掉。
|
|
34
34
|
*
|
|
35
|
-
* 🔴 SYNC WITH sema-cli(壳仓)的 `src/sema/settings/seam.ts`: the permissions→toolPolicy
|
|
35
|
+
* 🔴 SYNC WITH sema-cli(壳仓)的 `src/sema/settings/seam.ts`: the permissions→toolPolicy compile MIRRORS
|
|
36
36
|
* the shell's LOCAL-Runner resolver — both compose the SAME core primitives (`createAllowDenyPolicy` /
|
|
37
37
|
* `combinePolicies` / `tightenTaskSpec`), so the deny-wins ENFORCEMENT is core-single-source. Only the COMPOSITION
|
|
38
38
|
* is duplicated for the remote path; a proposed follow-up extracts it to `@sema-agent/sdk` for true
|
|
@@ -47,27 +47,29 @@
|
|
|
47
47
|
* - (`hooks` NO LONGER deferred either — 轴B #2 注释保鲜:applied 形已接线(本文件 hooks 分片 +
|
|
48
48
|
* main.ts 单用户闸),仅 malformed 才报 deferred;旧「需要 remote hook-runner」是接线前拍照。)
|
|
49
49
|
*/
|
|
50
|
-
import { type PathRuleBases, type
|
|
50
|
+
import { type PathRuleBases, type TaskSpec, type ThinkingLevel, type ToolPolicy, type PermissionMode } from "@sema-agent/core";
|
|
51
|
+
import { type EntryProblem } from "./entry-problems.js";
|
|
51
52
|
import { type KeyClosureIssue } from "./request-key-closure.js";
|
|
52
53
|
import { type RunnableHooksConfig } from "./hooks/hook-runner.js";
|
|
53
54
|
import type { StoredHooksRereadM20 } from "./stored-request-hooks-m20.js";
|
|
54
55
|
import { type EntryPermissionMode } from "./runtime-governance.js";
|
|
56
|
+
import { type TightenOnlySeatValues } from "./tighten-only-seats.js";
|
|
55
57
|
/**
|
|
56
58
|
* 请求面 `permissionMode` 的闭集 = core `PERMISSION_MODES` **全集**(顶层 `permissionMode` / `settings.permissions.defaultMode` /
|
|
57
59
|
* `?permissionMode=` 查询串三处同读)。本仓不持有第二份词表,也不持有「收 / 不收」的表态:判据 = core 的 `isPermissionMode`,型 = core 的
|
|
58
|
-
* `PermissionMode`,wire 句子里的词表只从这里取词({@link PERMISSION_MODE_WORDS})。core 加一个词 ⇒
|
|
59
|
-
*
|
|
60
|
+
* `PermissionMode`,wire 句子里的词表只从这里取词({@link PERMISSION_MODE_WORDS})。core 加一个词 ⇒ 请求面自动收它、原样过境,本仓没有
|
|
61
|
+
* 按词分的臂要补;core 删 / 改名一个词 ⇒ 本仓按名写出它的地方(`PLAN_APPROVE_PERMISSION_MODES_AFTER` 等)编译红。
|
|
60
62
|
* 生效模式原样过境 `TaskSpec.permissionMode`(S-877):引擎自己解释模式 —— 含 `dontAsk`(CC 的「自动拒」档:凡是要问的一律由模式拒,零卡,
|
|
61
|
-
* 门记录 `deniedBy:"mode"`),本仓不另写判。
|
|
63
|
+
* 门记录 `deniedBy:"mode"`)与 acceptEdits 的免问写域(引擎的写根:任务根 + `additionalDirectories` + 宣告的可写目录),本仓不另写判。
|
|
62
64
|
*/
|
|
63
65
|
/** 请求面闭集的 wire 文案形(`"a" | "b" | …`,core 序)—— 三处 400(顶层 / bundle / 查询串)的句子从这里取词,不再各抄一份。 */
|
|
64
66
|
export declare const PERMISSION_MODE_WORDS: string;
|
|
65
67
|
/**
|
|
66
68
|
* R4: coerce a raw top-level `body.permissionMode` (the LIGHT per-turn wire — the shell sends
|
|
67
69
|
* the CC permission mode RAW, axis-agnostic; the service interprets) to a service-honored mode, or undefined.
|
|
68
|
-
* 🔴 TIGHTEN-ONLY vs the DEPLOYMENT baseline still holds for every value: the
|
|
69
|
-
*
|
|
70
|
-
* folds via tightenTaskSpec, deny-wins). The honored set is core's `PERMISSION_MODES` in full — every word passes
|
|
70
|
+
* 🔴 TIGHTEN-ONLY vs the DEPLOYMENT baseline still holds for every value: the word rides verbatim into `TaskSpec.permissionMode`
|
|
71
|
+
* and only the engine interprets it; no mode subtracts from the deployment/operator policy or from the request's own
|
|
72
|
+
* deny / ask rules (applyTaskSettings folds them via tightenTaskSpec, deny-wins, under every word alike). The honored set is core's `PERMISSION_MODES` in full — every word passes
|
|
71
73
|
* through verbatim (`dontAsk` included: folding the auto-deny mode to `default`, the asking mode, would turn a refusal
|
|
72
74
|
* into a card). An UNKNOWN string coerces to `default` (fail-safe: the most-asking mode).
|
|
73
75
|
* [ref]-②: fresh submits can no longer REACH the unknown-word arm — the HTTP gate 400s a non-member value
|
|
@@ -147,19 +149,13 @@ export declare function storedBodyPermissionMode(body: {
|
|
|
147
149
|
* (= "max"), never a hardcoded literal — so an explicit higher tier still wins (none exists above max today;
|
|
148
150
|
* future-proof). Awareness rides for free: core composes ORCHESTRATION_AWARENESS from thinking∈{xhigh,max}, no field. */
|
|
149
151
|
export declare function effectiveThinking(reasoningEffort: unknown, ultracode: boolean): ThinkingLevel | undefined;
|
|
150
|
-
/** R4: fold a top-level `body.permissionMode` onto the parsed settings as `permissions.defaultMode` (the top-level
|
|
151
|
-
* field is the explicit per-turn intent → it WINS over a bundle defaultMode). Creates a minimal settings object when
|
|
152
|
-
* no `body.settings` bundle was sent. The result flows through {@link applyTaskSettings} (tighten-only). */
|
|
153
|
-
export declare function withPermissionMode(settings: ParsedTaskSettings | undefined, mode: PermissionMode): ParsedTaskSettings;
|
|
154
152
|
/**
|
|
155
|
-
* [ref] §6-1 —— 本请求的**生效** permission mode
|
|
156
|
-
*
|
|
157
|
-
* 都没有 ⇒ `undefined` = **无表态**(调用点据此不写键,而不是替调用方选一个默认值)。
|
|
153
|
+
* [ref] §6-1 —— 本请求的**生效** permission mode,单点。优先序:顶层 `body.permissionMode`(本轮显式表态)赢过 bundle 的
|
|
154
|
+
* `settings.permissions.defaultMode`;两处都没有 ⇒ `undefined` = **无表态**(调用点据此不写键,而不是替调用方选一个默认值;引擎把缺席读成 `default`)。
|
|
158
155
|
*
|
|
159
|
-
* 🔴 为什么必须是一只函数:同一个「生效模式」此前在 resolve-spec
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
* 「壳发的 bundle bypass 在 A 面生效、在 B 面没生效」这种最难被外部发现的静默偏差。
|
|
156
|
+
* 🔴 为什么必须是一只函数:同一个「生效模式」此前在 resolve-spec 里被算过两次(hooks 腿的 `permission_mode` 载荷、settings 折叠腿),
|
|
157
|
+
* 两处各算各的,任何一次优先序修订都会让两面分家,而分家在这条轴上的形态是「壳发的 bundle bypass 在 A 面生效、在 B 面没生效」这种
|
|
158
|
+
* 最难被外部发现的静默偏差。settings 折叠今天不再读模式词,这只函数的读者是 spec 过境点、托管天花板与存储体读法。
|
|
163
159
|
*/
|
|
164
160
|
export declare function effectivePermissionMode(body: {
|
|
165
161
|
permissionMode?: unknown;
|
|
@@ -216,7 +212,7 @@ export interface ParsedTaskSettings {
|
|
|
216
212
|
ultracode?: boolean;
|
|
217
213
|
/** hooks hook-runner(阶段一):经 `parseHooksConfig`(契约包分类器 + 服务侧上限 + 本仓会跑的条目类型)判过的 hooks 配置。像 shellEnv 一样
|
|
218
214
|
* 这里只 PARSE;应用点(main.ts resolveSpec)按单用户闸(`requirePrincipal !== true`)决定翻不翻成
|
|
219
|
-
*
|
|
215
|
+
* 任务座 `TaskSpec.mods` 上的一张注册 `settings.hooks`——多租户 lane 收到只警告忽略(hook 命令跑在 worker host = class ② 能力授予)。 */
|
|
220
216
|
hooks?: RunnableHooksConfig;
|
|
221
217
|
/** [ref](7.77.0)—— CC settings 同名键:上下文窗口里**留给技能清单**的比例((0,1];CC 默认 0.01 = 1%)。
|
|
222
218
|
* 超预算时引擎把描述裁短、再不够退成 name-only(`cli259.js` 的清单渲染算法),**从不**拒掉一条技能 ——
|
|
@@ -225,6 +221,10 @@ export interface ParsedTaskSettings {
|
|
|
225
221
|
skillListingBudgetFraction?: number;
|
|
226
222
|
/** 同族第二键:每条技能描述在清单里的字符帽(正整数;CC 默认 1536)。超出由引擎**截断**,不是拒。 */
|
|
227
223
|
skillListingMaxDescChars?: number;
|
|
224
|
+
/** S-1351 —— 「只收紧」座位族(`tighten-only-seats.ts` 的四座:读拒模式 / 写保护名的加法 / 合规额外禁项 / 永不自动放行名单)的归一值,**一个键**而不是四个散字段:
|
|
225
|
+
* wire 位置由座位表说(三座在 `settings` 顶层,`neverAuto` 在 `settings.permissions`),解析后与位置无关。空数组 ≡ 缺席(不铸键)。
|
|
226
|
+
* 去处:三座经 {@link applyTaskSettings} 落 core 任务层席;`neverAuto` 经 {@link deriveSettingsPolicy} 落请求叶策略。 */
|
|
227
|
+
tightenOnly?: TightenOnlySeatValues;
|
|
228
228
|
}
|
|
229
229
|
/** The result of parsing an untrusted `body.settings`: the applied subset + the names of present-but-deferred
|
|
230
230
|
* fields (so the caller can log/advertise them — no silent drop). `null` settings ⇒ `{ settings: undefined }`. */
|
|
@@ -285,13 +285,17 @@ export declare function settingsPermissionBucketIssue(perms: unknown): SettingsP
|
|
|
285
285
|
* {@link parseTaskSettings};`webSearch` 在 `capabilities/scenarios.ts`(判决 `judgeRequestWebSearch`,单用户闸;形错在受理面 400,S-199)。
|
|
286
286
|
* 加键必须同时加消费点,否则就是往闭集里塞一个新的静默丢。
|
|
287
287
|
*
|
|
288
|
+
* 🔴 `readDenyPatterns` / `writeProtectedExtra` / `complianceAdditionalDenies` 与 `permissions.neverAuto`(S-1351)= **「只收紧」座位族**:消费点 = `tighten-only-seats.ts`
|
|
289
|
+
* 的座位表(位置、条目律、去处都由那张表说),读入在 {@link parseTaskSettings},投影在 {@link applyTaskSettings} / {@link deriveSettingsPolicy}。这四个键不是 CC settings 键
|
|
290
|
+
* (sdk 的 `SemaSettings` 尚未声明 —— 对账门 `test/task-settings-sdk-key-parity.test.ts` 的「server 先于 sdk」登记表记着它们)。
|
|
291
|
+
*
|
|
288
292
|
* 🔴 两个 `skillListing*`([ref],7.77.0)= **CC settings 同名键**,值域抄 CC 的 schema 声明
|
|
289
293
|
* (`skillListingBudgetFraction` 是 `gt(0).lte(1)`、`skillListingMaxDescChars` 是 `int().positive()`);
|
|
290
294
|
* 消费点 = 本文件的 parse + `boot/resolve-spec.ts` 的 `TaskSpec` 透传。语义(预算怎么花、描述怎么裁、
|
|
291
295
|
* 溢出怎么退成 name-only)整个归引擎,本仓一个字节都不渲染,也**不复刻默认值**——缺席即整键不写。 */
|
|
292
|
-
export declare const TASK_SETTINGS_KEYS: readonly ["env", "hooks", "model", "outputStyle", "permissions", "skillListingBudgetFraction", "skillListingMaxDescChars", "ultracode", "webSearch"];
|
|
296
|
+
export declare const TASK_SETTINGS_KEYS: readonly ["complianceAdditionalDenies", "env", "hooks", "model", "outputStyle", "permissions", "readDenyPatterns", "skillListingBudgetFraction", "skillListingMaxDescChars", "ultracode", "webSearch", "writeProtectedExtra"];
|
|
293
297
|
/** 本 service 消费的 `settings.permissions` 子键 —— 闭集(值形校验另有既有门,本门只判键名)。 */
|
|
294
|
-
export declare const TASK_SETTINGS_PERMISSION_KEYS: readonly ["allow", "ask", "defaultMode", "deny", "disableAutoMode"];
|
|
298
|
+
export declare const TASK_SETTINGS_PERMISSION_KEYS: readonly ["allow", "ask", "defaultMode", "deny", "disableAutoMode", "neverAuto"];
|
|
295
299
|
/** CC/SDK 合约里合法、本 service **不接线**的顶层键。词表外的 CC 键落 `unknown` —— 两列都是 400,标签只影响
|
|
296
300
|
* 文案,不影响判决。前三个的出处 = `@sema-agent/sdk` `SemaSettings` 尾注逐字点名的 deferred CC 键。
|
|
297
301
|
*
|
|
@@ -324,7 +328,7 @@ export declare function taskSettingsKeyIssue(raw: unknown): KeyClosureIssue | nu
|
|
|
324
328
|
* 🔒 **`settings.hooks` 会不会被采纳** —— 全仓**唯一**的车道谓词(S-995,主会话裁):hook 命令跑在 WORKER HOST([ref] class ② 能力授予),所以只有单用户车道
|
|
325
329
|
* (`requirePrincipal !== true`,与 scheduler / backgroundShell / lspHost / MCP 注入同一姿势)采纳;多租户车道收到 hooks **整只忽略**(`task_hooks_ignored`),绝不执行。
|
|
326
330
|
* 三处读它,谁也不许内联 `requirePrincipal`(各写各的 = 迟早漂):
|
|
327
|
-
* · `boot/resolve-spec.ts` —— 装配:不采纳 ⇒
|
|
331
|
+
* · `boot/resolve-spec.ts` —— 装配:不采纳 ⇒ 不铸 `TaskSpec.mods` 的 `settings.hooks` 注册 + 一条 `task_hooks_ignored`;
|
|
328
332
|
* · `http/routes/capabilities.ts` —— 能力位 `taskSettings.hooks`(「says yes ⟺ route works」);
|
|
329
333
|
* · `http/admission.ts` —— fresh 受理面的「别名 matcher 永不命中」判据的**求值深度**:采纳 ⇒ `"regex"`(运行期同一只匹配函数,带资源闸);不采纳 ⇒ `"literal"`
|
|
330
334
|
* (7.112.0 的字面判:零调用方正则执行 —— 受理面是所有车道,租户不能借一只灾难回溯的 matcher 占满事件循环)。
|
|
@@ -350,71 +354,39 @@ export declare function parseTaskSettings(raw: unknown, seats?: ParseTaskSetting
|
|
|
350
354
|
* value must not become active prompt content after rollout (context exhaustion / spend hole). Over-cap ⇒ dropped +
|
|
351
355
|
* warned — the rider was inert pre-upgrade, so dropping preserves the stored task's prior behavior; a 4xx here would
|
|
352
356
|
* permanently brick that task's resume instead (same defensive posture as parseTaskSettings' outputStyle drop).
|
|
353
|
-
* Cap value = the submit gate's (16384; MAX_SETTINGS_OUTPUT_STYLE_CHARS — both land in the same spec field).
|
|
354
|
-
|
|
355
|
-
*
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
* probe — one definition so the three gates can't drift. */
|
|
359
|
-
export declare function hasConstitutionAnchors(text: unknown): boolean;
|
|
360
|
-
/** codex R9 (provider-aware append-less detection): mirrors core's ACTUAL pass-through triggers instead of a raw
|
|
361
|
-
* body-text heuristic — the assembler's migration guard probes (a) `stableBlocks` identity declarations and
|
|
362
|
-
* (b) `stableSystem` OUTPUT for the three anchors; a plain `userSystemPrompt` under the DEFAULT provider (no
|
|
363
|
-
* scenario provider) never triggers it and `core/role.append` is retained, so an anchored systemPrompt there
|
|
364
|
-
* must NOT block/strip a rider (R9 false-positive: unbranded default / scan rejected valid combos). Probing
|
|
365
|
-
* calls the provider hooks with a minimal ctx — server providers (and centerPromptProvider) are pure functions
|
|
366
|
-
* of ctx, and the same hooks run again inside core's assembly; a hook throw = conservative false (core will
|
|
367
|
-
* fail the task loudly on its own). `replaceAll` owns the whole prompt(legacy free-form `system()` 腿已随 core 2.0.0 删除)
|
|
368
|
-
* (REPLACE_ALL_EXCLUDED strips role.append) → append-less true. */
|
|
369
|
-
export declare function providerDropsAppend(provider: PromptProvider | undefined, userSystemPrompt: string | undefined): boolean;
|
|
370
|
-
export declare function acceptAppendSystemPrompt(v: unknown, warn?: (detail: string) => void, packDropsAppend?: boolean): string | undefined;
|
|
357
|
+
* Cap value = the submit gate's (16384; MAX_SETTINGS_OUTPUT_STYLE_CHARS — both land in the same spec field).
|
|
358
|
+
* A well-formed rider always mounts: the engine (core 7.52.0) lands it in its own task-append band whatever the role
|
|
359
|
+
* text is — there is no "already-assembled" pass-through arm left that could drop it. */
|
|
360
|
+
export declare function acceptAppendSystemPrompt(v: unknown, warn?: (detail: string) => void): string | undefined;
|
|
361
|
+
export declare function createWorkflowAskPolicy(isExempt?: WorkflowGateWiring["isExempt"]): ToolPolicy;
|
|
371
362
|
/** [ref]②/codex F2 — what the workflow ask leg needs from the deployment, on EVERY lane. It is name-keyed and
|
|
372
|
-
* fs-independent
|
|
373
|
-
* since [ref] — the sandbox lanes wire a gate of their own shape instead of no gate). */
|
|
363
|
+
* fs-independent: one shape on every execution lane. */
|
|
374
364
|
export interface WorkflowGateWiring {
|
|
375
|
-
/** The session "don't ask again" probe (approvalExemptionStore.has,
|
|
376
|
-
*
|
|
365
|
+
/** The session "don't ask again" probe (approvalExemptionStore.has, raw toolName key) — the same store and key space the
|
|
366
|
+
* approval seat's standing grants read; one remember="session" grant serves them all. */
|
|
377
367
|
isExempt?: (toolName: string) => boolean | Promise<boolean>;
|
|
378
368
|
}
|
|
379
|
-
/**
|
|
380
|
-
*
|
|
381
|
-
*
|
|
382
|
-
* WHY the `env` matters: core's `createFsWriteGatePolicy` canonicalizes every target/dir through the given `env`
|
|
383
|
-
* (real `exists`/`canonicalPath`/`readLink` fs access — read in dist, fs-write-gate-policy.js), so on a
|
|
384
|
-
* HOST-SEMANTICS lane (`REMOTE_EXEC` unset or "host") the env MUST be the fs the hand tools write.
|
|
369
|
+
/**
|
|
370
|
+
* 请求的 deny / ask 两张表解析路径形规则用的**基**(`resolve-spec.ts` 每请求供)。只有这两件事:这条 task 的真根、执行环境的 home。
|
|
371
|
+
* 缺席 ⇒ 不声明(规则锚在装入这只策略的那条腿的真根,`~/` 形由 {@link rejectUnmatchableSettingsNames} 响亮拒)。
|
|
385
372
|
*
|
|
386
|
-
*
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
*
|
|
390
|
-
|
|
391
|
-
* REAL sandbox env at adjudication time (a per-session slot the factory decorator fills), keeping only
|
|
392
|
-
* `absolutePath` lexical so no relative path is resolved against the wrong base. Empty slot ⇒ fail-closed. */
|
|
373
|
+
* 修前本型还承运本仓自己的 acceptEdits cwd 域写门的四件(裁决 env / cwd / scratchpad 豁免域 / 会话豁免探针):acceptEdits 能免问写哪里
|
|
374
|
+
* 现在只由引擎的模式门答(写根 = 任务根 + `additionalDirectories` + 宣告的可写目录),本仓不再构造写门,那四件随之退役。
|
|
375
|
+
* 部署级旋钮(`SENSITIVE_WRITE_PATTERNS` 守卫集、`MANUAL_MODE_SHELL_GATE` 地板)早已不经本型:它们在治理层无条件施加
|
|
376
|
+
* (`runtime-governance.ts` `applyRuntimeGovernance`),client 表态掀不掉([ref] / [ref])。
|
|
377
|
+
*/
|
|
393
378
|
export interface FsWriteGateWiring {
|
|
394
|
-
/** The env the gate canonicalizes against — the worker host env on the host lane, the
|
|
395
|
-
* `DeferredSandboxPathEnv` proxy over the task's real sandbox env on the sandbox lanes ([ref]). */
|
|
396
|
-
env: ExecutionEnv;
|
|
397
|
-
/** The task's working directory: the factory's `rootPath` (relative-path base) AND the acceptEdits accept domain.
|
|
398
|
-
* ABSENT on the sandbox lanes ([ref]/[ref]): the sandbox cwd is the ENGINE's tracked cwd, not the env's own, so
|
|
399
|
-
* neither spec time nor the env proxy can supply the right base — inventing one would mint a bogus auto-allow
|
|
400
|
-
* domain. With it absent the gate gets no `rootPath` and no `acceptDirs`, so relative paths fail to resolve
|
|
401
|
-
* (⇒ ask) and `acceptEdits` degrades to the `default` arm — the same fail-safe direction as the host lane's
|
|
402
|
-
* never-created sentinel dir (resolve-spec 修5). */
|
|
403
|
-
cwd?: string;
|
|
404
379
|
/**
|
|
405
|
-
* 🔴 S-177 / codex r1 [high](验真后修)——
|
|
380
|
+
* 🔴 S-177 / codex r1 [high](验真后修)—— **权限规则**的路径基(core `PathRuleBases.root`),**只在真任务根已知时**在场。
|
|
406
381
|
*
|
|
407
|
-
*
|
|
408
|
-
*
|
|
409
|
-
*
|
|
410
|
-
*
|
|
411
|
-
* · `taskRoot` 是**规则模式**的基(core `PathRuleBases.root`)。规则编译器按**词法**匹配,不问目录
|
|
412
|
-
* 存不存在 ⇒ 把哨兵递给它,`deny Edit(src/**)` 会编译成功、指向一个谁也不会写的目录,对真实工作区
|
|
413
|
-
* 的 `<工作区>/src/secret.ts` 这类目标判 allow —— 一条运维亲手写下的收紧规则**静默失效**,方向与写门那条正相反。
|
|
382
|
+
* host 腿上「这条 session 还没登记工作目录」时,`resolve-spec` 的路径裁决 env 落在一个**永不创建的哨兵目录**上
|
|
383
|
+
* (`fs-write-gate-unrooted`,治理层守卫集的 cwd)。那对守卫是 fail-SAFE 的(相对目标在哨兵下解析不出真身);但规则编译器按**词法**匹配、
|
|
384
|
+
* 不问目录存不存在 ⇒ 把哨兵当根递进来,`deny Edit(src/**)` 会编译成功、指向一个谁也不会写的目录,对真实工作区的
|
|
385
|
+
* `<工作区>/src/secret.ts` 判 allow —— 一条亲手写下的收紧规则**静默失效**。所以哨兵从不被声明成基。
|
|
414
386
|
*
|
|
415
|
-
*
|
|
416
|
-
*
|
|
417
|
-
*
|
|
387
|
+
* 缺席 ⇒ 不声明根 ⇒ 需要该基的拼法(`Edit(src/**)` / `Edit(/etc/**)`)锚在**装入这只策略的那条腿**的真根(core 7.46.0 #1383 车 B:
|
|
388
|
+
* 锚装一次、在被装入处;`unsupported.path_base` 只剩「声明了一个用不了的基」)。修前(core ≤7.45)缺席 ⇒ 整表拒(→ 422):沙箱车道上
|
|
389
|
+
* 相对 / `/x` 形规则恒 422。绝对形(`//abs`)不需要基;`~/` 形见下一字段。
|
|
418
390
|
*/
|
|
419
391
|
taskRoot?: string;
|
|
420
392
|
/**
|
|
@@ -444,29 +416,20 @@ export interface FsWriteGateWiring {
|
|
|
444
416
|
* 运维在**下单那一刻**就知道这条规则这条车道读不了,而不是等到跑起来每次都弹一张 ask。
|
|
445
417
|
*/
|
|
446
418
|
taskHome?: string;
|
|
447
|
-
/** The session scratchpad dir (envFacts.scratchpadDir, [ref]③) — writes there are always auto-allowed. */
|
|
448
|
-
scratchpadDir?: string;
|
|
449
|
-
/** [ref]① / core 1.294 exemption seam: the session "don't ask again" probe (approvalExemptionStore.has),
|
|
450
|
-
* called by core as `(canonicalToolName, canonicalPath)`. The host arm ignores the second argument (the key
|
|
451
|
-
* comes from a real-fs canonicalize and the grant is deliberately name-keyed); the sandbox arm ([ref]) uses it
|
|
452
|
-
* to confine the exemption to POSIX-absolute canonical keys — core's `canonicalizeTarget` short-circuits
|
|
453
|
-
* backslash-UNC forms to `ok:true, key=raw` WITHOUT consulting the env, and an unconfined name-keyed grant
|
|
454
|
-
* would turn those unresolvable forms into an allow (codex review 2026-08-05).
|
|
455
|
-
* 🔴 **坐标刷新(7.74.0 / core 7.17.0 [ref];结论不变,前提收窄了)**:那条短路现在**只在 `win` 家族上**
|
|
456
|
-
* (`dist/tools/fs/safety.js` 的 `canonicalizeTarget`:`family === "win" && isUncSpelling(...)` 才折 UNC
|
|
457
|
-
* 并直接返回);在 `posix` 家族上,同一个反斜杠 UNC 拼法在更早一步的 `win32NamespaceScreen` 上就被
|
|
458
|
-
* **拒**(`unc_on_posix_tree`),压根到不了短路。⇒ 今日部署形(posix 树)这条腿的暴露面比当年更小,
|
|
459
|
-
* 而本臂的 POSIX-absolute 收敛**继续是对的**:它挡的是「未经 env 解析的 key 拿到 name-keyed 放行」,
|
|
460
|
-
* 在两个家族上都成立,且方向仍是 fail-closed。不改实现。
|
|
461
|
-
* The probe is consulted by the gate RIGHT BEFORE it would ask (after the exempt/accept dir layering — dist 亲读:true ⇒
|
|
462
|
-
* allow with decisionReason "rule", a THROWN probe ⇒ not exempt = fail-closed to ask). Same canonical
|
|
463
|
-
* toolName key space as the ask-policy layer's exemption probe — ONE grant serves both layers; the gate-level
|
|
464
|
-
* check is what makes "allow all session" bite SAME-TURN for the parent and inherited child tasks (the ask
|
|
465
|
-
* path is never re-entered). (codex M1 的边界注记:sensitive-path DENY 腿与本探针的「豁免越不过 deny」
|
|
466
|
-
* 保证仍成立——但那条腿已随 [ref] 搬到 governance 层,deny-wins 是 tightenTaskSpec 折叠给的,不再依赖
|
|
467
|
-
* 本 wiring 的组合点。) */
|
|
468
|
-
isExempt?: (toolName: string, canonicalPath: string) => boolean | Promise<boolean>;
|
|
469
419
|
}
|
|
420
|
+
/**
|
|
421
|
+
* 请求的 `settings.permissions.deny` / `ask` 有永远不生效的条目 ⇒ 拒点({@link rejectUnmatchableSettingsNames})抛的错:句子(`message`)与这一遍判下来的**全部**问题(`problems`,机读位的原料)。
|
|
422
|
+
* `resolveSpec` 的折叠口把它装成 422 体(句子照旧、码 {@link SETTINGS_RULE_REFUSAL_CODE}、体带 `field` + `detail.problems`);其余出口(收紧不得放宽)仍抛普通 `Error`。
|
|
423
|
+
*/
|
|
424
|
+
export declare class SettingsRuleRefusalError extends Error {
|
|
425
|
+
readonly problems: readonly EntryProblem[];
|
|
426
|
+
constructor(message: string, problems: readonly EntryProblem[]);
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* 请求设置里 deny / ask 规则拒的**码**:422 在折叠口上的状态派生粗码(`http/send.ts` 的 `httpErrorCode(422)`;`test/entry-problems.test.ts` 钉两者同值)。拒点铸 422 体、存体预判铸 409 的 `blockedBy`、
|
|
430
|
+
* 机读位每条问题的 `code` 三处读这一只常量,不各写一份字面量。
|
|
431
|
+
*/
|
|
432
|
+
export declare const SETTINGS_RULE_REFUSAL_CODE = "request.unprocessable";
|
|
470
433
|
/**
|
|
471
434
|
* deny / ask 两桶(core 规则编译器读的收紧表)的**问序,单表**:{@link rulePolicyBucketsRefusal} 的两段循环(名字层 + 文法 · `~/` 要 home)都迭代它 ——
|
|
472
435
|
* 两桶都有坏条目时,拒点与存体预判点名同一个桶、说同一句。表里每个词同时是 core 规则的 `behavior`。
|
|
@@ -475,7 +438,8 @@ export declare const RULE_POLICY_BUCKETS: readonly ["ask", "deny"];
|
|
|
475
438
|
export type RulePolicyBucket = (typeof RULE_POLICY_BUCKETS)[number];
|
|
476
439
|
/**
|
|
477
440
|
* deny / ask 两桶的**完整规则判**,唯一一只(拒点 {@link rejectUnmatchableSettingsNames} 与存体预判 `http/stored-body-replay.ts` 同调):
|
|
478
|
-
* ② 按 {@link RULE_POLICY_BUCKETS} 的序逐桶问 `
|
|
441
|
+
* ② 按 {@link RULE_POLICY_BUCKETS} 的序逐桶问 `judgeUnmatchableToolNames`(名字层 + core 规则文法);③ 再逐桶判 `~/` 形要 home 的那一拒。答 `{ bucket, message, problems }`:`bucket` 与 `message` 是**第一处**坏处的
|
|
442
|
+
* (句子冻结,先撞上的那一条),`problems` 是**两段、两只桶判下来的全部**坏条目(机读位的原料,形的属主 `entry-problems.ts`)。
|
|
479
443
|
* 入参:桶、{@link RulePolicyBases}。**home 同源**:拒点的 home 是 `resolve-spec.ts` 的 `laneHomeBase()` 经 `executionLaneHomeDir(config)` 算出的,预判传同一个函数对同一份部署配置算出的。
|
|
480
444
|
* **声明给文法的基**只有拒点有(根 + home 的并集,执行车道才知道根):core 的规则文法对**没声明**的基不下判词(见 `config.ts` `uncompilableRuleGuidance`),所以预判什么也不声明、两腿逐字同句;
|
|
481
445
|
* 预判不能把 home 当「半个基」声明给文法 —— core 的路径族只从根推,缺根时一个合法的 Windows 形 home 会按默认族被判 `unsupported.path_base`(V6-k)。
|
|
@@ -490,12 +454,35 @@ export interface RulePolicyBases {
|
|
|
490
454
|
export declare function rulePolicyBucketsRefusal(permissions: Readonly<Partial<Record<RulePolicyBucket, readonly string[]>>>, bases: RulePolicyBases): {
|
|
491
455
|
readonly bucket: RulePolicyBucket;
|
|
492
456
|
readonly message: string;
|
|
457
|
+
readonly problems: readonly EntryProblem[];
|
|
493
458
|
} | undefined;
|
|
494
459
|
/** 请求的 settings 编不成生效的规则 / 有永远不生效的条目 ⇒ 422 的句首(三只桶同一个出口;`resolveSpec` 的拒点与存体重放预判的 409 句子同用这一个,不各写一份)。 */
|
|
495
460
|
export declare const REQUEST_SETTINGS_REFUSAL_PREFIX = "request settings cannot be applied as written: ";
|
|
496
|
-
|
|
461
|
+
/**
|
|
462
|
+
* Build the per-request permission ToolPolicy from the parsed settings: the two **rule lists** (`deny` / `ask`) through ONE compiler
|
|
463
|
+
* ({@link createRuleListPolicy} → core `createPermissionRulePolicy`) — a `deny` rule hard-blocks, an `ask` rule forces an approval
|
|
464
|
+
* gate, `deny` > `ask` on overlap. 两表的 **covering 语义同源**([ref]):底下是 core 的同一只 `namespacedRuleNameCovers`,本仓不持第二套 glob。
|
|
465
|
+
* The `allow` bucket is not here: a policy says deny / ask only (core 7.42.0); the list rides into `TaskSpec.allowedTools` at
|
|
466
|
+
* {@link applyTaskSettings}, the one write point.
|
|
467
|
+
*
|
|
468
|
+
* 🔴 **本函数不读模式词**:两张表在六个词与缺席下编出同一只策略(`test/settings-fold-mode-arms.test.ts` A2)。模式做什么只在引擎里答 ——
|
|
469
|
+
* 写门(`default` / `auto` / `dontAsk`:每次写先问;`acceptEdits`:写根内免问;`plan`:写与非只读调用以计划句问;`bypassPermissions`:不设门)
|
|
470
|
+
* 是引擎的模式门,`Workflow` 的问句腿在 `resolve-spec.ts` 按「这条 run 挂不挂得出 Workflow」装、由引擎的仲裁按模式处置({@link createWorkflowAskPolicy})。
|
|
471
|
+
* 修前这里按模式分四臂(acceptEdits 另铸一只 cwd 域写门、bypass / 缺席不装问句腿):本仓对模式的第二份解释,随之退役。
|
|
472
|
+
* Returns `{}` when there is no permission rule (nothing to project).
|
|
473
|
+
*/
|
|
474
|
+
export declare function deriveSettingsPolicy(settings: ParsedTaskSettings, bases?: FsWriteGateWiring): {
|
|
497
475
|
toolPolicy?: ToolPolicy;
|
|
498
476
|
};
|
|
477
|
+
/**
|
|
478
|
+
* 请求的 `settings.permissions.neverAuto` 有永远不生效的名字 ⇒ 拒因(句子 + 机读位),与 {@link rulePolicyBucketsRefusal} 同形 —— 拒点({@link deriveSettingsPolicy},422)与存体预判
|
|
479
|
+
* (`http/stored-body-replay.ts`)调这一只。判据与部署 `APPROVAL_NEVER_AUTO` 的 env 腿是**同一只**(`unmatchableToolNamesRefusal` 的名表消费者:退役名 / 无协议前缀的短名 / 缺段协议名 /
|
|
480
|
+
* 近似名 …),一条规则一种读法;机读位的 `field` = 座位在体内的坐标。无名字 / 全合法 ⇒ `undefined`。
|
|
481
|
+
*/
|
|
482
|
+
export declare function neverAutoNamesRefusal(names: readonly string[]): {
|
|
483
|
+
readonly message: string;
|
|
484
|
+
readonly problems: readonly EntryProblem[];
|
|
485
|
+
} | undefined;
|
|
499
486
|
/**
|
|
500
487
|
* Apply a client's parsed per-request settings onto a base `TaskSpec`, TIGHTEN-ONLY, in a SINGLE {@link
|
|
501
488
|
* tightenTaskSpec} pass (so the permission override composes deny-wins onto the baseline — TRAP #1). `tightenTaskSpec`
|
|
@@ -506,5 +493,5 @@ export declare function deriveSettingsPolicy(settings: ParsedTaskSettings, gate?
|
|
|
506
493
|
*
|
|
507
494
|
* Returns `base` untouched when the parsed settings project nothing onto the spec.
|
|
508
495
|
*/
|
|
509
|
-
export declare function applyTaskSettings(base: TaskSpec, settings: ParsedTaskSettings,
|
|
496
|
+
export declare function applyTaskSettings(base: TaskSpec, settings: ParsedTaskSettings, bases?: FsWriteGateWiring): TaskSpec;
|
|
510
497
|
//# sourceMappingURL=task-settings.d.ts.map
|
package/dist/task-settings.js
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
import { combinePolicies,
|
|
2
|
-
import {
|
|
1
|
+
import { combinePolicies, parseRuleText, resolveReasoningProfile, rankOf, isThinkingLevel, RUN_WORKFLOW_TOOL_NAME, PERMISSION_MODES, isPermissionMode, ruleToolGrammarOf, } from "@sema-agent/core";
|
|
2
|
+
import { judgeUnmatchableToolNames } from "./config.js";
|
|
3
|
+
import { entryProblem } from "./entry-problems.js";
|
|
3
4
|
import { MAX_PERMISSION_RULES_PER_LIST, createRuleListPolicy } from "./permission-rule-list.js";
|
|
4
5
|
import { allowLayerEntryCountIssue, describeAllowLayerOverCap, ruleEntryListShapeOk } from "./rule-entry-list.js";
|
|
6
|
+
import { limitRefusal } from "./limit-refusal.js";
|
|
5
7
|
import { tightenGoverned } from "./governance-overrides.js";
|
|
6
8
|
import { MAX_KEY_ECHO, keyClosureClause, scanKeyClosure } from "./request-key-closure.js";
|
|
7
9
|
import { parseHooksConfig } from "./hooks/hook-runner.js";
|
|
8
10
|
import { heldRuleName } from "./tool-rule-names.js";
|
|
9
11
|
import { entryPermissionMode } from "./runtime-governance.js";
|
|
10
12
|
import { policyAskStandingAnswerFacts, standingAnswerDurablyRecordable } from "./tool-approval.js";
|
|
13
|
+
import { createRequestNeverAutoPolicy } from "./approval.js";
|
|
14
|
+
import { readTightenOnlySeats, tightenOnlySeatField, tightenOnlySpecSeats } from "./tighten-only-seats.js";
|
|
11
15
|
export const PERMISSION_MODE_WORDS = PERMISSION_MODES.map((m) => `"${m}"`).join(" | ");
|
|
12
16
|
export function coercePermissionMode(raw) {
|
|
13
17
|
const strict = coercePermissionModeStrict(raw);
|
|
@@ -47,10 +51,6 @@ export function effectiveThinking(reasoningEffort, ultracode) {
|
|
|
47
51
|
const ultra = resolveReasoningProfile("ultra").thinking;
|
|
48
52
|
return explicit && rankOf(explicit) > rankOf(ultra) ? explicit : ultra;
|
|
49
53
|
}
|
|
50
|
-
export function withPermissionMode(settings, mode) {
|
|
51
|
-
const base = settings ?? {};
|
|
52
|
-
return { ...base, permissions: { ...base.permissions, defaultMode: mode } };
|
|
53
|
-
}
|
|
54
54
|
export function effectivePermissionMode(body, settings) {
|
|
55
55
|
const requested = coercePermissionMode(body.permissionMode) ?? settings?.permissions?.defaultMode;
|
|
56
56
|
const kill = settings?.permissions?.disableAutoMode;
|
|
@@ -93,8 +93,9 @@ function bucketIssueMessage(f, rule) {
|
|
|
93
93
|
case "over_cap":
|
|
94
94
|
switch (rule) {
|
|
95
95
|
case "rule_policy":
|
|
96
|
-
return (
|
|
97
|
-
|
|
96
|
+
return limitRefusal(f.field, "entries", f.count, f.cap, {
|
|
97
|
+
tail: "Refused rather than truncated: a truncated list silently drops the rules past the cap, and a dropped deny / ask rule is a tightening that never happened. Merge rules into broader patterns or trim the list",
|
|
98
|
+
}).message;
|
|
98
99
|
case "allow_layer":
|
|
99
100
|
return describeAllowLayerOverCap(f.field, f.count);
|
|
100
101
|
}
|
|
@@ -138,7 +139,7 @@ export function settingsPermissionBucketIssue(perms) {
|
|
|
138
139
|
case "allow_layer": {
|
|
139
140
|
const over = allowLayerEntryCountIssue(field, v);
|
|
140
141
|
if (over !== undefined)
|
|
141
|
-
fields = { field, reason: "over_cap", count: over.count, cap: over.cap };
|
|
142
|
+
fields = { field, reason: "over_cap", count: over.facts.count, cap: over.facts.cap };
|
|
142
143
|
else if (!ruleEntryListShapeOk(v))
|
|
143
144
|
fields = { field, reason: "bad_entry", index: v.findIndex((x) => typeof x !== "string") };
|
|
144
145
|
break;
|
|
@@ -153,8 +154,8 @@ export function settingsPermissionBucketIssue(perms) {
|
|
|
153
154
|
function acceptedRuleList(v) {
|
|
154
155
|
return Array.isArray(v) && v.length > 0 ? v.slice() : undefined;
|
|
155
156
|
}
|
|
156
|
-
export const TASK_SETTINGS_KEYS = ["env", "hooks", "model", "outputStyle", "permissions", "skillListingBudgetFraction", "skillListingMaxDescChars", "ultracode", "webSearch"];
|
|
157
|
-
export const TASK_SETTINGS_PERMISSION_KEYS = ["allow", "ask", "defaultMode", "deny", "disableAutoMode"];
|
|
157
|
+
export const TASK_SETTINGS_KEYS = ["complianceAdditionalDenies", "env", "hooks", "model", "outputStyle", "permissions", "readDenyPatterns", "skillListingBudgetFraction", "skillListingMaxDescChars", "ultracode", "webSearch", "writeProtectedExtra"];
|
|
158
|
+
export const TASK_SETTINGS_PERMISSION_KEYS = ["allow", "ask", "defaultMode", "deny", "disableAutoMode", "neverAuto"];
|
|
158
159
|
export const TASK_SETTINGS_UNSUPPORTED_KEYS = ["apiKeyHelper", "crossSessionInbound", "dialogExpiry", "sandbox", "statusLine"];
|
|
159
160
|
export const TASK_SETTINGS_UNSUPPORTED_PERMISSION_KEYS = ["additionalDirectories", "disableBypassPermissionsMode"];
|
|
160
161
|
const ACCEPTED_TOP = new Set(TASK_SETTINGS_KEYS);
|
|
@@ -193,6 +194,9 @@ export function taskSettingsKeyIssue(raw) {
|
|
|
193
194
|
export function taskHooksHonored(config) {
|
|
194
195
|
return config.requirePrincipal !== true;
|
|
195
196
|
}
|
|
197
|
+
function tightenOnlySeatDeferredName(name) {
|
|
198
|
+
return tightenOnlySeatField(name).replace(/^settings\./, "");
|
|
199
|
+
}
|
|
196
200
|
export function parseTaskSettings(raw, seats = {}) {
|
|
197
201
|
if (raw === null || raw === undefined || typeof raw !== "object")
|
|
198
202
|
return { deferred: [] };
|
|
@@ -260,36 +264,14 @@ export function parseTaskSettings(raw, seats = {}) {
|
|
|
260
264
|
const maxDesc = s.skillListingMaxDescChars;
|
|
261
265
|
if (skillListingMaxDescOk(maxDesc))
|
|
262
266
|
out.skillListingMaxDescChars = maxDesc;
|
|
267
|
+
const tightenSeats = readTightenOnlySeats(raw);
|
|
268
|
+
for (const name of tightenSeats.rejected)
|
|
269
|
+
deferred.push(tightenOnlySeatDeferredName(name));
|
|
270
|
+
if (Object.keys(tightenSeats.values).length > 0)
|
|
271
|
+
out.tightenOnly = tightenSeats.values;
|
|
263
272
|
return { settings: Object.keys(out).length > 0 ? out : undefined, deferred, ...(hooksReread !== undefined ? { hooksReread } : {}) };
|
|
264
273
|
}
|
|
265
|
-
export function
|
|
266
|
-
return typeof text === "string" && text.includes(CYBER_RISK) && text.includes(URL_SAFETY) && text.includes(HARNESS_SECTION_ANCHOR);
|
|
267
|
-
}
|
|
268
|
-
export function providerDropsAppend(provider, userSystemPrompt) {
|
|
269
|
-
if (!provider)
|
|
270
|
-
return false;
|
|
271
|
-
if (provider.replaceAll === true)
|
|
272
|
-
return true;
|
|
273
|
-
const ctx = { userSystemPrompt, tools: [], memoryEnabled: false, consolidationEnabled: false };
|
|
274
|
-
if (provider.stableBlocks) {
|
|
275
|
-
try {
|
|
276
|
-
return provider.stableBlocks(ctx).some((d) => d.slot === "identity" && hasConstitutionAnchors(d.text));
|
|
277
|
-
}
|
|
278
|
-
catch {
|
|
279
|
-
return false;
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
if (provider.stableSystem) {
|
|
283
|
-
try {
|
|
284
|
-
return hasConstitutionAnchors(provider.stableSystem(ctx));
|
|
285
|
-
}
|
|
286
|
-
catch {
|
|
287
|
-
return false;
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
return false;
|
|
291
|
-
}
|
|
292
|
-
export function acceptAppendSystemPrompt(v, warn, packDropsAppend) {
|
|
274
|
+
export function acceptAppendSystemPrompt(v, warn) {
|
|
293
275
|
if (v === undefined)
|
|
294
276
|
return undefined;
|
|
295
277
|
if (typeof v !== "string" || v.length === 0) {
|
|
@@ -300,16 +282,12 @@ export function acceptAppendSystemPrompt(v, warn, packDropsAppend) {
|
|
|
300
282
|
warn?.(`appendSystemPrompt dropped: ${v.length} chars exceeds the ${MAX_SETTINGS_OUTPUT_STYLE_CHARS} cap (pre-cap stored body on a resume leg?)`);
|
|
301
283
|
return undefined;
|
|
302
284
|
}
|
|
303
|
-
if (packDropsAppend === true) {
|
|
304
|
-
warn?.("appendSystemPrompt dropped: the effective prompt pack cannot mount the append rider (assembled-identity/stableSystem pass-through, replaceAll, or legacy provider — no core/role.append section)");
|
|
305
|
-
return undefined;
|
|
306
|
-
}
|
|
307
285
|
return v;
|
|
308
286
|
}
|
|
309
287
|
const RULE_SOURCE_BY_BEHAVIOR = { ask: "settings.permissions.ask", deny: "settings.permissions.deny" };
|
|
310
288
|
const WORKFLOW_ASK_NAMES = [RUN_WORKFLOW_TOOL_NAME];
|
|
311
289
|
const isWorkflowName = (name) => name === RUN_WORKFLOW_TOOL_NAME;
|
|
312
|
-
function createWorkflowAskPolicy(isExempt) {
|
|
290
|
+
export function createWorkflowAskPolicy(isExempt) {
|
|
313
291
|
return {
|
|
314
292
|
async check(req) {
|
|
315
293
|
if (heldRuleName(req, isWorkflowName) === undefined)
|
|
@@ -331,17 +309,31 @@ function createWorkflowAskPolicy(isExempt) {
|
|
|
331
309
|
function rejectUnmatchableSettingsNames(perms, pathBases) {
|
|
332
310
|
const refused = rulePolicyBucketsRefusal(perms, { ...(pathBases !== undefined ? { declared: pathBases } : {}), ...(pathBases?.home !== undefined ? { home: pathBases.home } : {}) });
|
|
333
311
|
if (refused !== undefined)
|
|
334
|
-
throw new
|
|
312
|
+
throw new SettingsRuleRefusalError(refused.message, refused.problems);
|
|
313
|
+
}
|
|
314
|
+
export class SettingsRuleRefusalError extends Error {
|
|
315
|
+
problems;
|
|
316
|
+
constructor(message, problems) {
|
|
317
|
+
super(message);
|
|
318
|
+
this.problems = problems;
|
|
319
|
+
this.name = "SettingsRuleRefusalError";
|
|
320
|
+
}
|
|
335
321
|
}
|
|
322
|
+
export const SETTINGS_RULE_REFUSAL_CODE = "request.unprocessable";
|
|
336
323
|
export const RULE_POLICY_BUCKETS = ["ask", "deny"];
|
|
337
324
|
export function rulePolicyBucketsRefusal(permissions, bases) {
|
|
325
|
+
let first;
|
|
326
|
+
const problems = [];
|
|
338
327
|
for (const bucket of RULE_POLICY_BUCKETS) {
|
|
339
328
|
const names = permissions[bucket];
|
|
340
329
|
if (!names)
|
|
341
330
|
continue;
|
|
342
|
-
const
|
|
343
|
-
if (
|
|
344
|
-
|
|
331
|
+
const judged = judgeUnmatchableToolNames(`permissions.${bucket}`, names, { consumer: "rule-policy", behavior: bucket, ...(bases.declared !== undefined ? { pathBases: bases.declared } : {}) });
|
|
332
|
+
if (judged === undefined)
|
|
333
|
+
continue;
|
|
334
|
+
first ??= { bucket, message: judged.message };
|
|
335
|
+
for (const b of judged.bad)
|
|
336
|
+
problems.push(entryProblem(SETTINGS_RULE_REFUSAL_CODE, `settings.permissions.${bucket}`, b.name, b.reason));
|
|
345
337
|
}
|
|
346
338
|
if (bases.home === undefined) {
|
|
347
339
|
for (const bucket of RULE_POLICY_BUCKETS) {
|
|
@@ -349,73 +341,60 @@ export function rulePolicyBucketsRefusal(permissions, bases) {
|
|
|
349
341
|
for (const name of permissions[bucket] ?? []) {
|
|
350
342
|
const parsed = parseRuleText(name, bucket);
|
|
351
343
|
if ("rule" in parsed && ruleToolGrammarOf(parsed.rule.tool) === "path" && parsed.rule.command.startsWith("~/")) {
|
|
352
|
-
|
|
344
|
+
first ??= {
|
|
353
345
|
bucket,
|
|
354
346
|
message: `${field} has a home-relative path rule (${name}) but this deployment cannot resolve the EXECUTION environment's home directory — ` +
|
|
355
347
|
`the engine never guesses one: without a home base the rule resolves to "unreadable" and every matching call stops to ask, so it guards nothing. ` +
|
|
356
348
|
`Spell the path absolutely (${"Edit(//abs/path/**)"} form), declare the lane's home with REMOTE_EXEC_HOME_DIR, or run the task on a lane whose home this worker knows.`,
|
|
357
349
|
};
|
|
350
|
+
problems.push(entryProblem(SETTINGS_RULE_REFUSAL_CODE, `settings.${field}`, name, "home_unresolvable"));
|
|
358
351
|
}
|
|
359
352
|
}
|
|
360
353
|
}
|
|
361
354
|
}
|
|
362
|
-
return undefined;
|
|
355
|
+
return first === undefined ? undefined : { ...first, problems };
|
|
363
356
|
}
|
|
364
357
|
export const REQUEST_SETTINGS_REFUSAL_PREFIX = "request settings cannot be applied as written: ";
|
|
365
|
-
export function deriveSettingsPolicy(settings,
|
|
358
|
+
export function deriveSettingsPolicy(settings, bases) {
|
|
366
359
|
const perms = settings.permissions;
|
|
367
|
-
|
|
360
|
+
const neverAuto = settings.tightenOnly?.neverAuto;
|
|
361
|
+
if (!perms && neverAuto === undefined)
|
|
368
362
|
return {};
|
|
369
|
-
const { deny, ask, defaultMode } = perms;
|
|
370
|
-
const pathBases = gate?.taskRoot !== undefined || gate?.taskHome !== undefined
|
|
371
|
-
? { ...(gate.taskRoot !== undefined ? { root: gate.taskRoot } : {}), ...(gate.taskHome !== undefined ? { home: gate.taskHome } : {}) }
|
|
372
|
-
: undefined;
|
|
373
|
-
rejectUnmatchableSettingsNames(perms, pathBases);
|
|
374
363
|
const policies = [];
|
|
375
|
-
if (
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
};
|
|
392
|
-
const compose = (...extra) => {
|
|
393
|
-
const all = [...policies, ...extra.filter((p) => p !== undefined)];
|
|
394
|
-
return all.length === 0 ? undefined : all.length === 1 ? all[0] : combinePolicies(...all);
|
|
395
|
-
};
|
|
396
|
-
const basePolicy = compose();
|
|
397
|
-
switch (defaultMode) {
|
|
398
|
-
case "acceptEdits": {
|
|
399
|
-
const p = compose(fsWriteGate(true), createWorkflowAskPolicy(workflowGate?.isExempt));
|
|
400
|
-
return p ? { toolPolicy: p } : {};
|
|
401
|
-
}
|
|
402
|
-
case "default":
|
|
403
|
-
case "auto":
|
|
404
|
-
case "dontAsk":
|
|
405
|
-
case "plan": {
|
|
406
|
-
const p = compose(createWorkflowAskPolicy(workflowGate?.isExempt));
|
|
407
|
-
return p ? { toolPolicy: p } : {};
|
|
408
|
-
}
|
|
409
|
-
case "bypassPermissions":
|
|
410
|
-
case undefined:
|
|
411
|
-
return basePolicy ? { toolPolicy: basePolicy } : {};
|
|
364
|
+
if (perms) {
|
|
365
|
+
const { deny, ask } = perms;
|
|
366
|
+
const pathBases = bases?.taskRoot !== undefined || bases?.taskHome !== undefined
|
|
367
|
+
? { ...(bases.taskRoot !== undefined ? { root: bases.taskRoot } : {}), ...(bases.taskHome !== undefined ? { home: bases.taskHome } : {}) }
|
|
368
|
+
: undefined;
|
|
369
|
+
rejectUnmatchableSettingsNames(perms, pathBases);
|
|
370
|
+
if (deny)
|
|
371
|
+
policies.push(createRuleListPolicy(deny, "deny", RULE_SOURCE_BY_BEHAVIOR.deny, pathBases));
|
|
372
|
+
if (ask)
|
|
373
|
+
policies.push(createRuleListPolicy(ask, "ask", RULE_SOURCE_BY_BEHAVIOR.ask, pathBases));
|
|
374
|
+
}
|
|
375
|
+
if (neverAuto !== undefined) {
|
|
376
|
+
const refused = neverAutoNamesRefusal(neverAuto);
|
|
377
|
+
if (refused !== undefined)
|
|
378
|
+
throw new SettingsRuleRefusalError(refused.message, refused.problems);
|
|
379
|
+
policies.push(createRequestNeverAutoPolicy(neverAuto, tightenOnlySeatField("neverAuto")));
|
|
412
380
|
}
|
|
381
|
+
if (policies.length === 0)
|
|
382
|
+
return {};
|
|
383
|
+
return { toolPolicy: policies.length === 1 ? policies[0] : combinePolicies(...policies) };
|
|
384
|
+
}
|
|
385
|
+
export function neverAutoNamesRefusal(names) {
|
|
386
|
+
const field = tightenOnlySeatField("neverAuto");
|
|
387
|
+
const judged = judgeUnmatchableToolNames(field.replace(/^settings\./, ""), names, { consumer: "tool-name-table", behavior: "deny" });
|
|
388
|
+
if (judged === undefined)
|
|
389
|
+
return undefined;
|
|
390
|
+
return { message: judged.message, problems: judged.bad.map((b) => entryProblem(SETTINGS_RULE_REFUSAL_CODE, field, b.name, b.reason)) };
|
|
413
391
|
}
|
|
414
|
-
export function applyTaskSettings(base, settings,
|
|
415
|
-
const { toolPolicy } = deriveSettingsPolicy(settings,
|
|
392
|
+
export function applyTaskSettings(base, settings, bases) {
|
|
393
|
+
const { toolPolicy } = deriveSettingsPolicy(settings, bases);
|
|
394
|
+
const seatSpec = settings.tightenOnly !== undefined ? tightenOnlySpecSeats(settings.tightenOnly) : {};
|
|
416
395
|
let next = base;
|
|
417
|
-
if (toolPolicy !== undefined)
|
|
418
|
-
next = tightenGoverned(next, { toolPolicy });
|
|
396
|
+
if (toolPolicy !== undefined || Object.keys(seatSpec).length > 0)
|
|
397
|
+
next = tightenGoverned(next, { ...(toolPolicy !== undefined ? { toolPolicy } : {}), ...seatSpec });
|
|
419
398
|
const allow = settings.permissions?.allow;
|
|
420
399
|
if (allow !== undefined)
|
|
421
400
|
next = { ...next, allowedTools: allow };
|