@sema-agent/server 7.134.0 → 7.135.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MIGRATION.md +134 -0
- package/USAGE.md +98 -30
- package/dist/adoption/plan.d.ts +1 -1
- package/dist/approval-ask-audit-store.d.ts +24 -24
- package/dist/approval-ask-machine.d.ts +2 -2
- package/dist/approval-card.d.ts +62 -150
- package/dist/approval-card.js +33 -51
- package/dist/approval-content-kind.d.ts +22 -5
- package/dist/approval-content-kind.js +8 -1
- package/dist/approval-deny-reasons.d.ts +1 -1
- package/dist/approval-gate-currency.d.ts +22 -3
- package/dist/approval-gate-currency.js +44 -18
- package/dist/approval-hmac.d.ts +7 -7
- package/dist/approval-policy-settlement.d.ts +2 -2
- package/dist/approval-reconciler.d.ts +3 -3
- package/dist/approval.d.ts +8 -8
- package/dist/approval.js +4 -2
- package/dist/auth-bridge.d.ts +1 -1
- package/dist/auto-mode-face.d.ts +4 -4
- package/dist/background-session-reap.d.ts +2 -2
- package/dist/bake-runner/main.d.ts +2 -2
- package/dist/bake-runner/runner.d.ts +4 -4
- package/dist/bench/s1/live-deps.d.ts +1 -1
- package/dist/bench/s1/run-firm.d.ts +1 -1
- package/dist/boot/coordinators.d.ts +2 -2
- package/dist/boot/coordinators.js +2 -2
- package/dist/boot/deferred-sandbox-path-env.d.ts +0 -6
- package/dist/boot/deferred-sandbox-path-env.js +0 -5
- package/dist/boot/engine-lease.d.ts +5 -5
- package/dist/boot/execution-env.d.ts +16 -15
- package/dist/boot/execution-env.js +19 -21
- package/dist/boot/fatal-exit.d.ts +2 -2
- package/dist/boot/late-binds.d.ts +1 -1
- package/dist/boot/leader.d.ts +1 -1
- package/dist/boot/memory-boundary.d.ts +2 -2
- package/dist/boot/memory-consolidation.d.ts +15 -15
- package/dist/boot/parked-revive-gate.d.ts +3 -3
- package/dist/boot/parked-revive-gate.js +3 -2
- package/dist/boot/reapers.d.ts +4 -4
- package/dist/boot/resolve-spec.d.ts +1 -1
- package/dist/boot/resolve-spec.js +28 -24
- package/dist/boot/runner-deps.d.ts +11 -11
- package/dist/boot/runner-deps.js +3 -2
- package/dist/boot/session-faces.d.ts +3 -3
- package/dist/boot/session-faces.js +11 -30
- package/dist/boot/shutdown.d.ts +5 -5
- package/dist/boot/side-query-lane.d.ts +2 -2
- package/dist/boot/stage-05-execution-env.js +4 -4
- package/dist/boot/stage-06-runners.js +0 -2
- package/dist/boot/stores.js +2 -1
- package/dist/boot/web-admin.d.ts +17 -17
- package/dist/boot/web-admin.js +5 -10
- package/dist/boot/workflow-orchestration.js +2 -9
- package/dist/brain.d.ts +11 -11
- package/dist/budget.d.ts +4 -4
- package/dist/capabilities/approvals-push.d.ts +4 -4
- package/dist/capabilities/builtin-tools.d.ts +5 -5
- package/dist/capabilities/center-plugins.d.ts +5 -5
- package/dist/capabilities/center-plugins.js +1 -1
- package/dist/capabilities/center-prompts.d.ts +1 -1
- package/dist/capabilities/center-wiring.d.ts +1 -1
- package/dist/capabilities/composite-members.d.ts +1 -1
- package/dist/capabilities/execution-lane.d.ts +5 -5
- package/dist/capabilities/execution-lane.js +2 -2
- package/dist/capabilities/hands-lane.d.ts +5 -5
- package/dist/capabilities/mcp-probe.d.ts +10 -7
- package/dist/capabilities/sandbox-file-send.d.ts +1 -18
- package/dist/capabilities/sandbox-file-send.js +0 -7
- package/dist/capabilities/scenarios.d.ts +28 -10
- package/dist/capabilities/scenarios.js +15 -5
- package/dist/capabilities/send-user-file-tool.d.ts +1 -1
- package/dist/capabilities/skills.d.ts +31 -12
- package/dist/capabilities/skills.js +23 -17
- package/dist/capabilities/tool-defer.d.ts +1 -1
- package/dist/capability-facts.d.ts +26 -25
- package/dist/capability-facts.js +14 -16
- package/dist/center-config-tier.d.ts +1 -1
- package/dist/center-credential.d.ts +4 -4
- package/dist/checkpoint-identity.d.ts +5 -0
- package/dist/checkpoint-identity.js +14 -0
- package/dist/config-catalog.d.ts +12 -12
- package/dist/config-invariants.d.ts +4 -4
- package/dist/config-invariants.js +3 -2
- package/dist/config-lkg.d.ts +1 -1
- package/dist/config-provider.d.ts +13 -13
- package/dist/config-provider.js +2 -1
- package/dist/config-types.d.ts +83 -83
- package/dist/config.d.ts +26 -24
- package/dist/config.js +12 -10
- package/dist/cross-session-settings.d.ts +1 -1
- package/dist/delegated-session-owner.d.ts +16 -13
- package/dist/delegated-session-owner.js +9 -10
- package/dist/deployment-governance.d.ts +16 -16
- package/dist/deployment-shape.d.ts +127 -0
- package/dist/deployment-shape.js +72 -0
- package/dist/device-store.d.ts +1 -1
- package/dist/device-ws-hub.d.ts +1 -1
- package/dist/egress-redirect.d.ts +1 -1
- package/dist/entry-mode-clamp-notice.d.ts +2 -2
- package/dist/env-facts.d.ts +10 -9
- package/dist/env-facts.js +1 -1
- package/dist/env-name-allowlist-knobs.d.ts +5 -5
- package/dist/exec-bounds.d.ts +2 -2
- package/dist/execution-lane-caps.d.ts +31 -43
- package/dist/execution-lane-caps.js +0 -13
- package/dist/file-history-capture.d.ts +9 -9
- package/dist/file-history-disclosure.d.ts +23 -11
- package/dist/file-history-disclosure.js +7 -12
- package/dist/fleet/drain-entry.d.ts +2 -2
- package/dist/fleet/fleet-bus.d.ts +22 -14
- package/dist/fleet/fleet-bus.js +5 -5
- package/dist/fleet/fleet-reconciler.d.ts +9 -9
- package/dist/fleet/subagent-tail-bus.d.ts +4 -4
- package/dist/fleet-client.d.ts +13 -13
- package/dist/fleet-lease.d.ts +16 -16
- package/dist/governance-http-status.d.ts +2 -2
- package/dist/hooks/hook-llm.d.ts +7 -7
- package/dist/hooks/hook-runner.d.ts +57 -30
- package/dist/hooks/hook-runner.js +36 -18
- package/dist/host-decision.d.ts +5 -5
- package/dist/host-lsp-manager.d.ts +5 -5
- package/dist/hosted-posture.d.ts +23 -13
- package/dist/hosted-posture.js +4 -9
- package/dist/http/admission.d.ts +2 -2
- package/dist/http/admission.js +20 -5
- package/dist/http/approval-sweeps.d.ts +1 -1
- package/dist/http/approval-sweeps.js +2 -1
- package/dist/http/checkpoint-ctx.d.ts +39 -13
- package/dist/http/checkpoint-ctx.js +74 -35
- package/dist/http/dispatch.d.ts +3 -3
- package/dist/http/durable-run-leg.js +4 -3
- package/dist/http/idempotency.d.ts +2 -2
- package/dist/http/mcp-dial-deadline.d.ts +7 -5
- package/dist/http/memory-compliance-failure-reply.d.ts +4 -4
- package/dist/http/owner-access.d.ts +4 -6
- package/dist/http/owner-access.js +1 -1
- package/dist/http/principal-gate.d.ts +7 -7
- package/dist/http/principal-gate.js +3 -2
- package/dist/http/readiness.d.ts +1 -1
- package/dist/http/request-guards.d.ts +4 -4
- package/dist/http/request-guards.js +2 -1
- package/dist/http/resume-ctx-read.d.ts +7 -7
- package/dist/http/resume-ctx-read.js +1 -1
- package/dist/http/resume-legs.d.ts +3 -3
- package/dist/http/resume-legs.js +11 -8
- package/dist/http/route-ctx.d.ts +29 -29
- package/dist/http/route-table.d.ts +9 -9
- package/dist/http/routes/agents-roster.d.ts +1 -1
- package/dist/http/routes/approvals-assistant.d.ts +5 -5
- package/dist/http/routes/approvals-assistant.js +55 -15
- package/dist/http/routes/background.d.ts +3 -3
- package/dist/http/routes/background.js +2 -2
- package/dist/http/routes/capabilities.d.ts +1 -1
- package/dist/http/routes/capabilities.js +16 -8
- package/dist/http/routes/config-catalog.d.ts +1 -1
- package/dist/http/routes/devices.d.ts +1 -1
- package/dist/http/routes/diagnostics.d.ts +3 -3
- package/dist/http/routes/fleet.d.ts +1 -1
- package/dist/http/routes/fleet.js +2 -1
- package/dist/http/routes/mcp-reconnect.d.ts +4 -4
- package/dist/http/routes/mcp-reconnect.js +3 -3
- package/dist/http/routes/memory-consolidation.d.ts +1 -1
- package/dist/http/routes/notify-wake.d.ts +1 -1
- package/dist/http/routes/notify-wake.js +2 -2
- package/dist/http/routes/rules.d.ts +1 -1
- package/dist/http/routes/runs.js +22 -10
- package/dist/http/routes/session-sync.d.ts +1 -1
- package/dist/http/routes/session-sync.js +73 -44
- package/dist/http/routes/sessions-list.js +1 -1
- package/dist/http/routes/sessions.js +30 -44
- package/dist/http/routes/tasks.d.ts +1 -1
- package/dist/http/routes/trace-usage.d.ts +1 -1
- package/dist/http/routes/workflows.d.ts +3 -0
- package/dist/http/routes/workflows.js +31 -28
- package/dist/http/send.d.ts +5 -5
- package/dist/http/server.d.ts +34 -34
- package/dist/http/session-inherit-env.d.ts +3 -3
- package/dist/http/sse-lifecycle.d.ts +1 -1
- package/dist/http/sse-log.d.ts +2 -2
- package/dist/http/submit-ctx.js +1 -1
- package/dist/http/sync-submit-body.d.ts +1 -1
- package/dist/http/verify-rounds.d.ts +1 -1
- package/dist/http/wire-types.d.ts +28 -21
- package/dist/instruction-source-notice.d.ts +2 -2
- package/dist/key-resolver.d.ts +3 -3
- package/dist/lane-home-probe.d.ts +1 -1
- package/dist/leader/diffout.d.ts +1 -1
- package/dist/leader/diffup.d.ts +2 -2
- package/dist/leader/endpoint.d.ts +1 -1
- package/dist/leader/fanout.d.ts +1 -1
- package/dist/leader/leader.d.ts +4 -4
- package/dist/leader/merge.d.ts +3 -3
- package/dist/leader/repair-wire.d.ts +1 -1
- package/dist/leader/wire.d.ts +6 -6
- package/dist/list-entry-display.d.ts +1 -1
- package/dist/lsp-evict.d.ts +1 -1
- package/dist/mcp-assertion-header.d.ts +1 -1
- package/dist/memory-layer-legacy-lock.d.ts +1 -1
- package/dist/memory-operator-faces.d.ts +1 -1
- package/dist/memory-posture.js +4 -2
- package/dist/memory-project-layer.d.ts +1 -1
- package/dist/memory-scope.d.ts +19 -19
- package/dist/memory-store-refusal.d.ts +4 -4
- package/dist/model-entry-headers.d.ts +2 -2
- package/dist/model-entry-refusal.d.ts +17 -17
- package/dist/model-provider.d.ts +10 -10
- package/dist/model-reach-scope.d.ts +1 -1
- package/dist/model-route-endpoint.d.ts +6 -6
- package/dist/model-route-url.d.ts +5 -5
- package/dist/model-select.d.ts +15 -6
- package/dist/model-select.js +5 -0
- package/dist/model-unreachable-notice.d.ts +3 -3
- package/dist/namespaced-rule-name.d.ts +15 -5
- package/dist/namespaced-rule-name.js +3 -2
- package/dist/observability/corrupt-read-seat.d.ts +9 -9
- package/dist/observability/cost-taxonomy.d.ts +1 -1
- package/dist/observability/err-text.d.ts +1 -1
- package/dist/observability/fail-open.d.ts +12 -8
- package/dist/observability/fail-open.js +12 -8
- package/dist/observability/metrics.d.ts +3 -3
- package/dist/observability/run-terminal.d.ts +36 -36
- package/dist/observability/secret-env-scrub.d.ts +3 -3
- package/dist/observability/tool-trace.d.ts +1 -1
- package/dist/operator-ask.d.ts +4 -4
- package/dist/orchestration/workflow-agent-session-index.d.ts +3 -3
- package/dist/orchestration/workflow-completion-inbox.d.ts +20 -5
- package/dist/orchestration/workflow-completion-inbox.js +29 -7
- package/dist/orchestration/workflow-notify-journal.d.ts +43 -19
- package/dist/orchestration/workflow-notify-journal.js +17 -0
- package/dist/outbound-dispatcher.d.ts +4 -4
- package/dist/parent-watch.d.ts +4 -4
- package/dist/parked-decide.d.ts +16 -15
- package/dist/parked-decide.js +5 -4
- package/dist/parked-revive-surface.d.ts +7 -7
- package/dist/parked-revive-surface.js +2 -3
- package/dist/peer-directory.d.ts +3 -3
- package/dist/peer-directory.js +1 -1
- package/dist/permission-rule-list.d.ts +10 -1
- package/dist/permission-rule-list.js +7 -5
- package/dist/permission-rule-vocab.d.ts +2 -2
- package/dist/plugins/adoption-log-sql.d.ts +1 -1
- package/dist/plugins/approval-ask-store-file.d.ts +8 -1
- package/dist/plugins/approval-ask-store-file.js +6 -3
- package/dist/plugins/approval-ask-store-memory.d.ts +11 -7
- package/dist/plugins/approval-ask-store-memory.js +11 -7
- package/dist/plugins/approval-ask-store-sql.d.ts +34 -15
- package/dist/plugins/approval-ask-store-sql.js +18 -5
- package/dist/plugins/approval-exemption-store.d.ts +3 -3
- package/dist/plugins/approval-nonce-store.d.ts +3 -3
- package/dist/plugins/background-agent-store-sql.d.ts +1 -1
- package/dist/plugins/background-shell-support.d.ts +2 -2
- package/dist/plugins/blob-backend.d.ts +1 -1
- package/dist/plugins/caching-session-store.d.ts +23 -32
- package/dist/plugins/caching-session-store.js +5 -17
- package/dist/plugins/checkpoint-index-columns.d.ts +81 -0
- package/dist/plugins/checkpoint-index-columns.js +62 -0
- package/dist/plugins/checkpoint-store-sql.d.ts +44 -66
- package/dist/plugins/checkpoint-store-sql.js +55 -102
- package/dist/plugins/device-store-sql.d.ts +7 -6
- package/dist/plugins/e2b-orphan-reclaim.d.ts +1 -1
- package/dist/plugins/ensure-schema-lock-policy.d.ts +1 -1
- package/dist/plugins/file-history-store-sql.d.ts +9 -7
- package/dist/plugins/file-history-store-sql.js +27 -15
- package/dist/plugins/file-run-store.d.ts +8 -8
- package/dist/plugins/fork-routing-session-store.d.ts +2 -2
- package/dist/plugins/fork-routing-session-store.js +1 -1
- package/dist/plugins/host-platform.d.ts +10 -10
- package/dist/plugins/image-bake-store-sql.d.ts +1 -1
- package/dist/plugins/image-index-sql.d.ts +1 -1
- package/dist/plugins/leader-run-store-sql.d.ts +1 -1
- package/dist/plugins/local-checkpoint-store.d.ts +10 -10
- package/dist/plugins/local-checkpoint-store.js +3 -4
- package/dist/plugins/local-session-store.d.ts +34 -38
- package/dist/plugins/local-session-store.js +20 -39
- package/dist/plugins/local-session-window.d.ts +1 -1
- package/dist/plugins/mailbox-store-sql.d.ts +2 -2
- package/dist/plugins/memory-engine-pg.d.ts +1 -1
- package/dist/plugins/memory-run-store.d.ts +4 -4
- package/dist/plugins/memory-sync-store-pg.d.ts +3 -3
- package/dist/plugins/one-time-migrations.d.ts +66 -40
- package/dist/plugins/one-time-migrations.js +115 -34
- package/dist/plugins/outcome-ledger-sql.d.ts +1 -1
- package/dist/plugins/park-commit-watch.d.ts +3 -3
- package/dist/plugins/permission-rule-store-file.d.ts +5 -5
- package/dist/plugins/permission-rule-store-file.js +12 -19
- package/dist/plugins/permission-rule-store-sql.d.ts +38 -4
- package/dist/plugins/permission-rule-store-sql.js +67 -24
- package/dist/plugins/pg-cost-quota.d.ts +1 -1
- package/dist/plugins/pg-pool.d.ts +2 -2
- package/dist/plugins/pg-pool.js +5 -2
- package/dist/plugins/pg-rate-limiter.d.ts +1 -1
- package/dist/plugins/pg-session-storage.d.ts +8 -20
- package/dist/plugins/pg-session-storage.js +14 -27
- package/dist/plugins/remote-env-adb.d.ts +10 -10
- package/dist/plugins/remote-env-device.d.ts +10 -9
- package/dist/plugins/remote-env-device.js +6 -2
- package/dist/plugins/remote-env-e2b.d.ts +3 -3
- package/dist/plugins/remote-env-host.d.ts +16 -16
- package/dist/plugins/remote-env-k8s.d.ts +8 -8
- package/dist/plugins/remote-env-local-docker.d.ts +2 -2
- package/dist/plugins/remote-env-ssh.d.ts +4 -4
- package/dist/plugins/remote-scratchpad.d.ts +2 -3
- package/dist/plugins/remote-scratchpad.js +0 -4
- package/dist/plugins/remote-shell.d.ts +6 -6
- package/dist/plugins/retention-lane-store-sql.d.ts +4 -4
- package/dist/plugins/retention-store-sql.d.ts +4 -4
- package/dist/plugins/roster-store-sql.d.ts +1 -1
- package/dist/plugins/run-store-sql.d.ts +8 -8
- package/dist/plugins/schema-consistency.d.ts +2 -2
- package/dist/plugins/schema-ensure-legs.d.ts +3 -3
- package/dist/plugins/schema-indexes.d.ts +1 -1
- package/dist/plugins/schema-live-columns.d.ts +1 -1
- package/dist/plugins/session-event-payload.d.ts +4 -4
- package/dist/plugins/session-fork.d.ts +34 -0
- package/dist/plugins/session-fork.js +29 -0
- package/dist/plugins/session-ownership.js +1 -1
- package/dist/plugins/session-placement.d.ts +1 -1
- package/dist/plugins/session-policy-store-sql.d.ts +12 -12
- package/dist/plugins/session-store.d.ts +2 -2
- package/dist/plugins/session-store.js +2 -2
- package/dist/plugins/shared-memory-store-sql.d.ts +2 -2
- package/dist/plugins/sql-driver.d.ts +8 -8
- package/dist/plugins/sql-errors.d.ts +1 -1
- package/dist/plugins/sql-json-column.d.ts +21 -21
- package/dist/plugins/sql-row-helpers.d.ts +2 -2
- package/dist/plugins/store-backend.d.ts +17 -16
- package/dist/plugins/store-backend.js +3 -3
- package/dist/plugins/store-contracts.d.ts +21 -21
- package/dist/plugins/task-attachment-store.d.ts +2 -2
- package/dist/plugins/task-list-store-sql.d.ts +1 -1
- package/dist/plugins/tidb-pool.d.ts +2 -2
- package/dist/plugins/tidb-pool.js +9 -2
- package/dist/plugins/tidb-session-store.d.ts +16 -26
- package/dist/plugins/tidb-session-store.js +15 -27
- package/dist/plugins/tool-result-store-sql.d.ts +1 -1
- package/dist/plugins/usage-window-store-sql.d.ts +3 -3
- package/dist/plugins/user-input-ledger-file.d.ts +1 -1
- package/dist/plugins/user-input-ledger-sql.d.ts +3 -3
- package/dist/plugins/web-search.d.ts +19 -5
- package/dist/plugins/web-search.js +19 -4
- package/dist/{orchestration/workflow-journal-entry.d.ts → plugins/workflow-journal-payload.d.ts} +23 -32
- package/dist/plugins/workflow-journal-payload.js +32 -0
- package/dist/plugins/workflow-journal-store-sql.d.ts +28 -14
- package/dist/plugins/workflow-journal-store-sql.js +34 -15
- package/dist/plugins/workflow-run-store-sql.d.ts +4 -4
- package/dist/posture-source.d.ts +11 -11
- package/dist/principal-jwt.d.ts +6 -6
- package/dist/project-identity.d.ts +3 -3
- package/dist/project-memory.d.ts +4 -4
- package/dist/read-face-posture.d.ts +7 -7
- package/dist/request-key-closure.d.ts +1 -1
- package/dist/request-key-closure.js +1 -1
- package/dist/request-value-closure.d.ts +15 -8
- package/dist/request-value-closure.js +2 -0
- package/dist/router/route-orchestration.d.ts +11 -16
- package/dist/router/route-orchestration.js +2 -12
- package/dist/rule-entry-list.d.ts +8 -7
- package/dist/rule-entry-list.js +2 -9
- package/dist/rules-consent.d.ts +6 -6
- package/dist/rules-consent.js +2 -0
- package/dist/run-cancel-context.d.ts +5 -5
- package/dist/run-local.d.ts +10 -10
- package/dist/runs.d.ts +13 -11
- package/dist/runs.js +15 -1
- package/dist/runtime-caps-resolver.d.ts +6 -6
- package/dist/runtime-governance.d.ts +9 -9
- package/dist/sandbox-pkg-source.d.ts +9 -31
- package/dist/sandbox-pkg-source.js +14 -8
- package/dist/sealed-key.d.ts +3 -3
- package/dist/security.d.ts +23 -26
- package/dist/security.js +12 -9
- package/dist/server-secret-env.d.ts +10 -10
- package/dist/session-children-retire.d.ts +1 -1
- package/dist/session-error-wire.d.ts +7 -7
- package/dist/session-incarnation.d.ts +52 -35
- package/dist/session-incarnation.js +23 -8
- package/dist/session-policy-wire.d.ts +27 -5
- package/dist/session-policy-wire.js +15 -1
- package/dist/session-records-skipped-notice.d.ts +1 -1
- package/dist/session-sync-kernel.d.ts +4 -4
- package/dist/session-sync.d.ts +49 -6
- package/dist/session-sync.js +52 -10
- package/dist/session-titler.d.ts +7 -6
- package/dist/session-titler.js +8 -13
- package/dist/session-watch.d.ts +3 -3
- package/dist/session-watch.js +4 -4
- package/dist/sighup-idle.d.ts +2 -2
- package/dist/spec-fields.d.ts +4 -4
- package/dist/sql-engine-posture.d.ts +3 -3
- package/dist/store-posture.d.ts +2 -2
- package/dist/stored-request-tool-axes-m19.d.ts +1 -1
- package/dist/task-a2a.d.ts +3 -1
- package/dist/task-a2a.js +34 -2
- package/dist/task-cwd.d.ts +7 -88
- package/dist/task-cwd.js +2 -15
- package/dist/task-mcp.d.ts +12 -8
- package/dist/task-mcp.js +19 -4
- package/dist/task-settings.d.ts +30 -18
- package/dist/task-settings.js +33 -3
- package/dist/task-workflow.d.ts +0 -24
- package/dist/task-workflow.js +2 -1
- package/dist/terminal.d.ts +5 -5
- package/dist/tighten-only-seats.d.ts +7 -6
- package/dist/tighten-only-seats.js +1 -1
- package/dist/tool-approval.d.ts +143 -197
- package/dist/tool-approval.js +13 -28
- package/dist/tool-rule-names.d.ts +2 -2
- package/dist/trace/core-keyset-guard.d.ts +12 -7
- package/dist/trace/engine-notice-wire.d.ts +5 -5
- package/dist/trace/engine-notice-wire.js +1 -0
- package/dist/trace/exit-seat.d.ts +31 -4
- package/dist/trace/exit-seat.js +41 -63
- package/dist/trace/ledger-events.d.ts +3 -3
- package/dist/trace/ledger-sink.d.ts +1 -1
- package/dist/trace/model-segment.d.ts +3 -3
- package/dist/trace/project.d.ts +47 -45
- package/dist/trace/project.js +33 -1
- package/dist/trace/redact.d.ts +44 -30
- package/dist/trace/redact.js +191 -89
- package/dist/trace/self-minted-wire.d.ts +35 -14
- package/dist/trace/self-minted-wire.js +8 -0
- package/dist/trace/sema-provenance.d.ts +1 -1
- package/dist/trace/task-notification-facets.d.ts +4 -4
- package/dist/trace/wire-projection-faces.d.ts +3 -3
- package/dist/trace/wire-projection-faces.js +1 -1
- package/dist/unattended-permission-mode.d.ts +5 -5
- package/dist/url-credential.d.ts +52 -0
- package/dist/url-credential.js +49 -0
- package/dist/url-refusal.d.ts +6 -2
- package/dist/url-refusal.js +8 -1
- package/dist/usage-analytics.d.ts +2 -2
- package/dist/user-input-ledger.d.ts +23 -23
- package/dist/web-admin-client/apply-effective.d.ts +5 -5
- package/dist/web-admin-client/apply-effective.js +2 -1
- package/dist/web-admin-client/apply-ledger.d.ts +2 -2
- package/dist/web-admin-client/center-request.d.ts +2 -2
- package/dist/web-admin-client/facade.d.ts +5 -5
- package/dist/web-admin-client/facade.js +1 -1
- package/dist/web-admin-client/hot-keys-registry.d.ts +2 -2
- package/dist/web-admin-client/http-client.d.ts +4 -4
- package/dist/web-admin-client/mcp-revocation.d.ts +1 -1
- package/dist/web-admin-client/pull-state.d.ts +1 -1
- package/dist/web-admin-client/read-face.d.ts +2 -2
- package/dist/web-admin-client/read-warnings.d.ts +5 -5
- package/dist/web-admin-client/restart-signal.d.ts +6 -6
- package/dist/web-admin-client/skills-mcp.d.ts +28 -3
- package/dist/web-admin-client/skills-mcp.js +29 -1
- package/dist/web-admin-client/types.d.ts +16 -9
- package/dist/workspace-space.d.ts +5 -3
- package/dist/write-protection.d.ts +2 -2
- package/package.json +4 -3
- package/scripts/drain-check-local.mjs +2 -1
- package/scripts/drain-check.mysql.sql +4 -2
- package/scripts/drain-check.pg.sql +4 -2
- package/skills/loop.md +1 -1
- package/dist/http/run-declared-families.d.ts +0 -16
- package/dist/http/run-declared-families.js +0 -12
- package/dist/orchestration/workflow-journal-entry.js +0 -27
package/dist/task-cwd.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { type DeploymentShapeInput } from "./deployment-shape.js";
|
|
1
2
|
/**
|
|
2
3
|
* 词法归一:纯字符串运算,折 `.` / `..` / 重复分隔符,**不碰 fs**。
|
|
3
4
|
* `posix.normalize` 把 `..` 在根部截断(`/../x` → `/x`),与「根之上没有东西」的语义一致;尾部分隔符
|
|
4
5
|
* 统一剥掉(根 `/` 除外),让同一目标只有一个 key —— 前缀判域(见 {@link dirCoversPath})靠的就是
|
|
5
6
|
* key 的唯一性。
|
|
6
7
|
*
|
|
7
|
-
* 🔴 **单点**(
|
|
8
|
+
* 🔴 **单点**([ref] 起):此前它的一份私有副本住在 `boot/deferred-sandbox-path-env.ts`(沙箱代理的
|
|
8
9
|
* `absolutePath` 词法臂),而写门豁免域与任务根的判域现在读的是同一条律 —— 两份各自归一就是两个 key
|
|
9
10
|
* 空间,而「豁免域盖没盖住任务根」这种判断在两个 key 空间里可以同时答是和否。
|
|
10
11
|
* (core 内部有同形的 `normalizeAbsPathLexically`,但未从包根导出;此处是 Node 标准库的等价运算,
|
|
@@ -22,97 +23,20 @@ export declare function normalizeAbsolutePathLexically(p: string): string;
|
|
|
22
23
|
* 段感知由「归一后 + 分隔符前缀」保证:`/a/bc` **不在** `/a/b` 域内。
|
|
23
24
|
*/
|
|
24
25
|
export declare function dirCoversPath(dir: string, target: string): boolean;
|
|
25
|
-
/**
|
|
26
|
-
* The deployment-level gate: does THIS deployment honor a caller-supplied `cwd`? TRUE only for the single-user
|
|
27
|
-
* `host` lane (see module header). All cloud/container lanes + any multi-tenant deployment → FALSE (cwd ignored).
|
|
28
|
-
*/
|
|
29
|
-
export declare function cwdHonored(config: {
|
|
30
|
-
remoteExec?: {
|
|
31
|
-
provider?: string;
|
|
32
|
-
};
|
|
33
|
-
requirePrincipal?: boolean;
|
|
34
|
-
}): boolean;
|
|
35
|
-
/**
|
|
36
|
-
* S-377 —— 「**工具跑的那台机器**就是本进程这台吗」。回答的是一个**文件系统同一性**问题,不是权限问题:
|
|
37
|
-
* server 盘上的一条绝对路径(出厂 `SKILLS_DIR` 下、或中心 plugin 缓存里某个技能自己的目录)对模型的工具**有没有意义**。
|
|
38
|
-
*
|
|
39
|
-
* 判据 = 能力表两位的合取 {@link handsOnWorkerFilePlane}(`coreRemoteExecutionEnv ∧ hostFilePlane`,都读表,
|
|
40
|
-
* 本函数不手写任何车道词):
|
|
41
|
-
* · `host`(run-on-this-machine,无容器)⇒ 真;
|
|
42
|
-
* · `in-process`(`REMOTE_EXEC` 未设)⇒ **假**(S-602,clay 裁 [ref] A 翻面;改前判真)—— 该 lane 根本
|
|
43
|
-
* 没挂手(core 落 `StubExecutionEnv`),「工具的盘」这句话在这里没有指称对象。改前的理由「文件系统同一性
|
|
44
|
-
* 这条轴上确实是同一台机器,判真让规则只剩一条」把**缺席折成了邻居**:wire 上的 `toolsOnThisHost` 因此
|
|
45
|
-
* 对无手部署说真,消费端的 doctor 据此说「工具在本机」。代价如实记:出厂目录形技能在 in-process 上不再带
|
|
46
|
-
* `baseDir` —— core 律:缺席 ⇒ 结果逐字节同 baseDir 到货之前,而那条 lane 上本来也没有能读它的工具;
|
|
47
|
-
* · 其余每一条(`k8s` / `e2b` / `ssh` / `adb` / `device` / `local-docker`)⇒ 假:工具的盘在别处,
|
|
48
|
-
* server 自己的路径在那边**不存在**,声明它等于给模型一条指向不存在文件的线索,还顺带把本机目录
|
|
49
|
-
* 布局说了出去;
|
|
50
|
-
* · 认不出的词 ⇒ 假(fail-closed:没认出来的车道不许被当成「本机」)。
|
|
51
|
-
*
|
|
52
|
-
* 🔴 **为什么不复用 {@link cwdHonored}**:那一只是**权限**判据(单用户 ∧ host),它的 `requirePrincipal`
|
|
53
|
-
* 那一半防的是「一个租户的输入把 agent 指向另一个租户的文件」。本谓词判的路径不是调用方给的,是**运维
|
|
54
|
-
* 自己烤进镜像**的出厂内容 —— 每个租户拿到的是同一份,没有跨租户面。把租户判据搭进来会让多租户 host
|
|
55
|
-
* 部署平白失去这条线索,那是**用错轴**(与 `deviceCwdHonored` 拒绝并进 `cwdHonored` 同一条理由)。
|
|
56
|
-
*/
|
|
57
|
-
export declare function toolsRunOnThisHost(config: {
|
|
58
|
-
remoteExec?: {
|
|
59
|
-
provider?: string;
|
|
60
|
-
};
|
|
61
|
-
}): boolean;
|
|
62
|
-
/**
|
|
63
|
-
* device lane 的**平行**判别式(device-executor-lane-v2 §4.3.3,车A-4)——「员工在自己设备的项目目录
|
|
64
|
-
* 里干活」是这条车道的存在理由,所以 caller cwd 必须被尊重。
|
|
65
|
-
*
|
|
66
|
-
* 🔴 **为什么不合并进 {@link cwdHonored}**:两闸语义不同,合并会把 host 的单用户约束**放松**。
|
|
67
|
-
* · `cwdHonored` 的 `requirePrincipal !== true` 防的是「一个租户的输入把 agent 指向 **worker 宿主**上
|
|
68
|
-
* 另一个租户/运维的目录」—— 那是一台共享机器上的跨租户穿越;
|
|
69
|
-
* · device lane 上那个穿越面**结构性不存在**:路径落在**发起者自己的设备**上,而设备归属已由
|
|
70
|
-
* `device_session` 绑定行(提交期用验证过的 principal 写下)+ 准入链的 owner 谓词验过。所以本闸
|
|
71
|
-
* **不要求**单用户 —— 多租户部署里每个员工各连各的设备,正是这条车道的正常形态。
|
|
72
|
-
* 合并两者 = 让 host 车道在多租户下也开始尊重 cwd,那是一条真实的超范围面。
|
|
73
|
-
*
|
|
74
|
-
* 消费者:写侧 = `boot/resolve-spec.ts`(**单写者**,与 cwdHonored 同一处);读侧 =
|
|
75
|
-
* `plugins/remote-env-device.ts` 的工厂(`effectiveDeviceCwd`)。两侧必须同批落 —— 只开写侧会留下一个
|
|
76
|
-
* 没有消费者的登记项(这正是 A-1 把它登记进 `PLANNED_LANE_DIVERGENCES` 而不是当场开的理由)。
|
|
77
|
-
*
|
|
78
|
-
* ⚠️ 刻意**不**连带放开 `additionalDirectories`:那一位在 device v1 上诚实缺席(v2 §4.1 capability
|
|
79
|
-
* projectContext 行:「拆精确字段,device v1 对 unsupported 项显式 false,不打包沿用」)。
|
|
80
|
-
*/
|
|
81
|
-
export declare function deviceCwdHonored(config: {
|
|
82
|
-
remoteExec?: {
|
|
83
|
-
provider?: string;
|
|
84
|
-
};
|
|
85
|
-
requirePrincipal?: boolean;
|
|
86
|
-
}): boolean;
|
|
87
|
-
/**
|
|
88
|
-
* [ref]P3a — the OTHER host-semantics lane: provider UNSET = the in-process single-user lane. It has NO shell
|
|
89
|
-
* hands (core prepare-task: no factory/executionEnv ⇒ StubExecutionEnv), so the perSession cwd/env registries
|
|
90
|
-
* have no consumer there — but PROCESS-level consumers (hooks commands, the C4 projectContext local read) still
|
|
91
|
-
* see the engine's own `process.cwd()`/`process.env`. When the shell spawned the engine in the caller's own
|
|
92
|
-
* dir/env, a caller override is often ALREADY satisfied by that process state, and a per-task "ignored" warn
|
|
93
|
-
* contradicts it (飞轮双平台观测). Signal-truth split: satisfied ⇒ debug, real mismatch ⇒ warn. True per-session
|
|
94
|
-
* honoring remains `REMOTE_EXEC=host`. Multi-tenant excluded for the same reason as {@link cwdHonored}.
|
|
95
|
-
*/
|
|
96
|
-
export declare function inProcessSingleUserLane(config: {
|
|
97
|
-
remoteExec?: {
|
|
98
|
-
provider?: string;
|
|
99
|
-
};
|
|
100
|
-
requirePrincipal?: boolean;
|
|
101
|
-
}): boolean;
|
|
102
26
|
/**
|
|
103
27
|
* [ref](F-1,[ref] 修向 (b')):卡批「不再询问」落盘规则的 **project root** —— 「这次授权是在哪个
|
|
104
28
|
* 工作目录里点的」。取值与既有 cwd 语义同源,不新造坐标系:
|
|
105
29
|
* 1. session 显式注册的 cwd(cwd seam,host lane;与 {@link effectiveHostWorkspace} 第 1 优先级同源)
|
|
106
30
|
* —— **今天唯一真的会命中的那一臂**;⚠️ 它**不含 lane 判据**,lane 语义完全依赖「`perSessionCwd`
|
|
107
|
-
*
|
|
31
|
+
* 只在部署形表行 `callerCwd` 为真时被写」这条跨文件外部不变量(写侧唯一入口 boot/resolve-spec.ts)。这是
|
|
108
32
|
* 刻意的单写者惯用法,不是疏漏:在消费端补第二道闸 = 把一条不变量拆给两个属主(同族消费者
|
|
109
33
|
* {@link effectiveHostWorkspace} 形状完全相同)。机器背书 = test/task-cwd.test.ts 的 [ref] 两格。
|
|
110
34
|
* 2. 🔴 **前瞻/防御臂,本仓当前装配下零命中**([ref],2026-08-19 合并重扫 partial,存活断言):
|
|
111
|
-
* in-process 单用户 lane(
|
|
35
|
+
* in-process 单用户 lane(部署形表行 `inProcessSingleUser`)取引擎自身 `process.cwd()`。它读起来像在
|
|
112
36
|
* 服务一个真部署形,其实到不了 —— 该 lane 的 `remoteExec` 未设 ⇒ boot/execution-env.ts 六条工厂臂全
|
|
113
37
|
* 不命中 ⇒ core 落 `StubExecutionEnv` ⇒ `handsEnabled=false` ⇒ 不挂 Bash ⇒ 未知工具在 agent-loop 走
|
|
114
38
|
* `tool.not_found`(**不进审批座**)⇒ 无 `ruleOffers` ⇒ 本函数在规则车道上根本不被调用;同 lane
|
|
115
|
-
* 第 1 臂也因写侧闸只在 `
|
|
39
|
+
* 第 1 臂也因写侧闸只在 `callerCwd` 下开而恒空。危害口径按 refuter **降级**:死枝 ≡ 落第 3 臂
|
|
116
40
|
* `undefined` ≡ core global 缺省 ≡ [ref] 修前行为,**今天零用户可见伤害**,不是「恒不命中」类缺陷。
|
|
117
41
|
* 🚧 **给将来接手的人的红线**:这条 lane 若哪天真接上 hands,root 必须取 `executionEnv.cwd`(core 的
|
|
118
42
|
* `taskRootFinal` 就是它),**不是** `process.cwd()` —— 两者在静态 env 装配形下可以完全不同,照现注
|
|
@@ -134,12 +58,7 @@ export declare function inProcessSingleUserLane(config: {
|
|
|
134
58
|
* `path.resolve` 不抛 ⇒ 初版的 realpath 失败 F 类兜底臂(`rule-scope-root-unresolvable`)随之退役
|
|
135
59
|
* (census 行同批销,fail-open.ts)。
|
|
136
60
|
*/
|
|
137
|
-
export declare function cardRuleScopeRoot(registeredCwd: string | undefined, config:
|
|
138
|
-
remoteExec?: {
|
|
139
|
-
provider?: string;
|
|
140
|
-
};
|
|
141
|
-
requirePrincipal?: boolean;
|
|
142
|
-
}, cwd?: () => string): string | undefined;
|
|
61
|
+
export declare function cardRuleScopeRoot(registeredCwd: string | undefined, config: DeploymentShapeInput<"lane" | "principal">, cwd?: () => string): string | undefined;
|
|
143
62
|
/** Is a requested cwd ALREADY the engine process's working dir? realpath BOTH sides (macOS `/tmp` →
|
|
144
63
|
* `/private/tmp`-class symlinks); either side failing to resolve ⇒ treated as a mismatch (warn — never a
|
|
145
64
|
* false downgrade). `realpath`/`cwd` are parameters for testability; production passes `fs.realpathSync`. */
|
|
@@ -153,7 +72,7 @@ export declare const MAX_ADDITIONAL_DIRS = 64;
|
|
|
153
72
|
/**
|
|
154
73
|
* [ref] (CC `--add-dir` parity): validate an untrusted `body.additionalDirectories` — extra host dirs the
|
|
155
74
|
* FILE tools may access beyond the containment root (core canonicalizes each into its allowlist + lists them in the
|
|
156
|
-
* `# Environment` block). Gated
|
|
75
|
+
* `# Environment` block). Gated by the deployment-shape row `callerOwnsWorkerDisk` (hands on this worker's disk ∧ one owner): these are the caller's OWN-machine paths, so they
|
|
157
76
|
* only make sense — and are only safe — on the single-user host lane (on a cloud/container lane a file-tool root is
|
|
158
77
|
* the sandbox fs, and a multi-tenant lane must never let one caller widen containment onto operator/other-tenant
|
|
159
78
|
* host paths). Each element gets the SAME structural check as `cwd` (absolute, no `..` traversal, no NUL, capped);
|
package/dist/task-cwd.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { isAbsoluteHostPath } from "@sema-agent/settings-schema";
|
|
3
|
-
import {
|
|
3
|
+
import { DEPLOYMENT_SHAPE_PREDICATES } from "./deployment-shape.js";
|
|
4
4
|
export function normalizeAbsolutePathLexically(p) {
|
|
5
5
|
const collapsed = path.posix.normalize(p.replace(/^\/+/, "/"));
|
|
6
6
|
return collapsed.length > 1 ? collapsed.replace(/\/+$/, "") : collapsed;
|
|
@@ -10,21 +10,8 @@ export function dirCoversPath(dir, target) {
|
|
|
10
10
|
const p = normalizeAbsolutePathLexically(target);
|
|
11
11
|
return p === root || p.startsWith(root.endsWith("/") ? root : `${root}/`);
|
|
12
12
|
}
|
|
13
|
-
export function cwdHonored(config) {
|
|
14
|
-
return config.remoteExec?.provider === "host" && config.requirePrincipal !== true;
|
|
15
|
-
}
|
|
16
|
-
export function toolsRunOnThisHost(config) {
|
|
17
|
-
const lane = executionLaneOf(config.remoteExec?.provider);
|
|
18
|
-
return lane !== undefined && handsOnWorkerFilePlane(lane);
|
|
19
|
-
}
|
|
20
|
-
export function deviceCwdHonored(config) {
|
|
21
|
-
return config.remoteExec?.provider === "device";
|
|
22
|
-
}
|
|
23
|
-
export function inProcessSingleUserLane(config) {
|
|
24
|
-
return config.remoteExec === undefined && config.requirePrincipal !== true;
|
|
25
|
-
}
|
|
26
13
|
export function cardRuleScopeRoot(registeredCwd, config, cwd = process.cwd) {
|
|
27
|
-
const raw = registeredCwd ?? (
|
|
14
|
+
const raw = registeredCwd ?? (DEPLOYMENT_SHAPE_PREDICATES.inProcessSingleUser.holds(config) ? cwd() : undefined);
|
|
28
15
|
return raw === undefined ? undefined : path.resolve(raw);
|
|
29
16
|
}
|
|
30
17
|
export function satisfiedByProcessCwd(requested, realpath, cwd = process.cwd) {
|
package/dist/task-mcp.d.ts
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
*/
|
|
25
25
|
import { type CompliancePosture, type EngineNotice, type LockedKey, type McpInjectionDropReason, type McpServerSpec } from "@sema-agent/core";
|
|
26
26
|
import { type McpIdentityHeadersIssue, type RequestMcpServerSpec } from "./mcp-assertion-header.js";
|
|
27
|
+
import { type UrlCredentialFacts } from "./url-credential.js";
|
|
27
28
|
import type { StoredToolAxesRereadM19 } from "./stored-request-tool-axes-m19.js";
|
|
28
29
|
/** Bound on caller-supplied servers (anti-DoS; a real local `.mcp.json` has a handful). */
|
|
29
30
|
export declare const MAX_REQUEST_MCP_SERVERS = 32;
|
|
@@ -43,10 +44,10 @@ export declare const MAX_REQUEST_MCP_SERVERS = 32;
|
|
|
43
44
|
*/
|
|
44
45
|
export declare const MAX_REQUEST_MCP_DROP_NAMES = 32;
|
|
45
46
|
/**
|
|
46
|
-
*
|
|
47
|
+
* [ref] —— 一条 `mcpServers[]` 条目在 wire 上的**键闭集**,与它两种传输各自的键闭集。
|
|
47
48
|
*
|
|
48
49
|
* ## 属主为什么在这里
|
|
49
|
-
* 这个文件就是「请求腿的 MCP 条目形」的家({@link normalizeServer} 逐键读的正是这些)。
|
|
50
|
+
* 这个文件就是「请求腿的 MCP 条目形」的家({@link normalizeServer} 逐键读的正是这些)。[ref] 的探测口
|
|
50
51
|
* ({@link import("./capabilities/mcp-probe.js").readMcpProbeBody})要的是**同一个**词表 —— 它在自己那边
|
|
51
52
|
* 再写一份就是一份手抄投影([ref]:任何仓第一排查点),而两份哪天分岔,窄的那一份会把**合法**的键当成
|
|
52
53
|
* 拼写错误 400 掉。
|
|
@@ -73,7 +74,7 @@ export declare const STDIO_MCP_TRANSPORT_KEYS: readonly ["args", "command", "env
|
|
|
73
74
|
export declare const HTTP_MCP_TRANSPORT_KEYS: readonly ["assertionHeader", "headers", "kind", "principalHeader", "url"];
|
|
74
75
|
/**
|
|
75
76
|
* Does THIS deployment honor caller-supplied per-request MCP servers? TRUE for a SINGLE-USER deployment
|
|
76
|
-
* (`
|
|
77
|
+
* (deployment-shape row `multiTenant` does not hold) — the requester is the super-admin of their own worker, so their `.mcp.json` is
|
|
77
78
|
* authoritative (CC-parity), on ANY execution lane (the stdio command runs on the worker, not the exec env, so the
|
|
78
79
|
* lane is irrelevant — see module header). FALSE on a multi-tenant deployment (a tenant can't make the shared worker
|
|
79
80
|
* run an arbitrary command / connect to an arbitrary URL).
|
|
@@ -84,7 +85,7 @@ export declare function mcpInjectionHonored(config: {
|
|
|
84
85
|
compliancePosture?: CompliancePosture;
|
|
85
86
|
}): boolean;
|
|
86
87
|
/**
|
|
87
|
-
*
|
|
88
|
+
* [ref](core 7.9.1)—— 一条**没有被挂上**的请求腿 MCP 条目的**事实**。宿主报事实,core 铸词:
|
|
88
89
|
* `reason` 的词表属主是 core(`McpInjectionDropReason` = malformed_entry / name_reserved_by_deployment /
|
|
89
90
|
* gate_closed / over_cap),本仓一个词都不枚举,通告的码/受众/句子一个字都不拼。
|
|
90
91
|
*
|
|
@@ -97,7 +98,7 @@ export interface McpInjectionDrop {
|
|
|
97
98
|
/** `malformed_entry` 专用:**哪个键**判不出形。结构性给出(读器在拒的那一行就知道),不从文案里 parse。 */
|
|
98
99
|
readonly field?: string;
|
|
99
100
|
}
|
|
100
|
-
/**
|
|
101
|
+
/** [ref]:本条腿的用户面通告席。`sessionId` = 路由半场(`auth.sessionId`,与 `spec.sessionId` 同源);
|
|
101
102
|
* `emit` = 收下 core 铸好的 `EngineNotice`。**本模块不知道**它最后落在 SSE、账本还是日志上 —— 那是
|
|
102
103
|
* 投递腿的事,本模块只负责「事实 → core 工厂 → 一条通告」。 */
|
|
103
104
|
export interface McpInjectionDropSeat {
|
|
@@ -141,12 +142,14 @@ export declare function assertRequestMcpUnlocked(bodyMcp: unknown, lockedKeys: R
|
|
|
141
142
|
/** 一条**原始**请求条目上两个身份头的问题类(没有问题 / 不是对象 / 不是 http 传输 ⇒ `undefined`)—— 提交腿的门、探测口、重放腿的披露三处共读,
|
|
142
143
|
* 判据本体在 `mcp-assertion-header.ts`;这里只负责把「条目 → 传输对象」那一步读出来。 */
|
|
143
144
|
export declare function requestEntryIdentityIssue(entry: unknown): McpIdentityHeadersIssue | undefined;
|
|
144
|
-
/** 请求面 `mcpServers` 的一次拒:码 + 句 + 词表外的键名表(只在闭集那一形上在场)。两扇门(fresh 提交腿 / 探测口)同一份,状态恒 400。 */
|
|
145
|
+
/** 请求面 `mcpServers` 的一次拒:码 + 句 + 词表外的键名表(只在闭集那一形上在场)+ 机读位(只在「url 带凭据」那一形上在场)。两扇门(fresh 提交腿 / 探测口)同一份,状态恒 400。 */
|
|
145
146
|
export interface RequestMcpRefusal {
|
|
146
147
|
readonly errorCode: "request.body_shape" | "request.field_invalid";
|
|
147
148
|
readonly message: string;
|
|
148
149
|
/** 词表外的键,全路径形(`mcpServers[0].transport.header`;已清洗 + 截长 + 排序 + 封顶)。 */
|
|
149
150
|
readonly unknownKeys?: readonly string[];
|
|
151
|
+
/** [ref]:`transport.url` 带凭据 ⇒ 拒体顶层的 `field`(`mcpServers[i].transport.url`)+ `reason`(判官的拒因词,闭集)—— 与 `request.field_invalid` 上既有的 `field` / `reason` 同名同读。 */
|
|
152
|
+
readonly facts?: UrlCredentialFacts;
|
|
150
153
|
}
|
|
151
154
|
/**
|
|
152
155
|
* 请求面 `mcpServers`「这份声明能不能原样用」的**唯一回答者** —— fresh 提交腿({@link assertRequestMcpEntries})与探测口
|
|
@@ -161,7 +164,8 @@ export interface RequestMcpRefusal {
|
|
|
161
164
|
* 判官**就是读器用的那一只**,不是第二份:`toolAxes` = {@link readRequestToolAxes}(引擎根导出的 `readToolAxes` + 请求腿不收 `boundaryFlow`);`toolFaces` = 引擎根导出的 `readToolFaces`;
|
|
162
165
|
* `startupTimeoutMs` = 引擎根导出的 `mcpStartupTimeoutMs`(坏值抛 `config.mcp_startup_timeout_invalid`,本门把那一句作原因句);`contentOrigin` = `isContentOriginWord`;`source` = `isMcpSourceLabel`;
|
|
163
166
|
* `name` = `isUsableWireName`;`allowTools` / `transport.args` = {@link isStringArray};`transport.env` / `headers` = 契约包读器 {@link readRequestMcpTransport} 的纯数据记录读法;`elicitation` = {@link isElicitationFlag};
|
|
164
|
-
* `transport` 的硬字段(`kind` / `command` / `url`)与软字段(`args` / `env` / `headers` / `principalHeader`)= {@link readRequestMcpTransport}(读器投影 transport 的那一只函数,门读它报的 `lost`;读器在契约包,本仓只据 `lost[0]` 拒、据 `lost` 在重放腿逐处点名)
|
|
167
|
+
* `transport` 的硬字段(`kind` / `command` / `url`)与软字段(`args` / `env` / `headers` / `principalHeader`)= {@link readRequestMcpTransport}(读器投影 transport 的那一只函数,门读它报的 `lost`;读器在契约包,本仓只据 `lost[0]` 拒、据 `lost` 在重放腿逐处点名);
|
|
168
|
+
* 读器交回的 http `url` 再问「带不带凭据」= `url-credential.ts` 的 `findUrlCredential`([ref];拒体另带机读 `field` + `reason`,见 {@link transportUrlCredentialIssue})。
|
|
165
169
|
* 于是判官受理的条目,读器({@link normalizeServer})交回的就是申报本身(只差判官自己的合法归一:空容器 / `skillScopeEligible:false` 折成缺席、`toolAxes` 取引擎的拷贝)——
|
|
166
170
|
* 探测口拨的那一份因此就是提交腿会挂的那一份,不另比一遍(另比就是第二只回答者)。唯一按门分的后果是「声明了 `assertionHeader`」这一个事实(引擎尚无座,
|
|
167
171
|
* 承载、不发送):新提交照挂 + 运维 info,探测口整条拒 —— 判据是同一只谓词 `specWithholdsMcpAssertionHeader`(开关 `MCP_ASSERTION_HEADER_SENT` 假时「声明了」即「被扣下」),不是第二份判法(见 `readMcpProbeBody`)。
|
|
@@ -224,7 +228,7 @@ export declare function resolveRequestMcp(baseline: McpServerSpec[] | undefined,
|
|
|
224
228
|
info?(m: string, meta?: unknown): void;
|
|
225
229
|
warn(m: string, meta?: unknown): void;
|
|
226
230
|
},
|
|
227
|
-
/**
|
|
231
|
+
/** [ref]:本条腿的**用户面**投递口。`sessionId` = 通告的路由半场(缺席 ⇒ 一条都不铸,见
|
|
228
232
|
* {@link mintInjectionDropNotices});`emit` 收下 core 铸好的通告,由调用腿决定投到哪(见 `boot/resolve-spec.ts`)。
|
|
229
233
|
* 整段缺席(桩、单测、非 HTTP 腿)⇒ 只走日志终点,行为逐字与本件之前相同。 */
|
|
230
234
|
notice?: McpInjectionDropSeat,
|
package/dist/task-mcp.js
CHANGED
|
@@ -2,10 +2,12 @@ import { mcpInjectionDroppedNotice, mcpStartupTimeoutMs, readToolFaces, resolveC
|
|
|
2
2
|
import { MCP_CONTENT_ORIGINS, describeBadContentOrigin, describeBadWireName, describeNotStringArray, describeValueShape, isContentOriginWord, isStringArray, isUsableWireName, readRequestMcpTransport, stripControlAndBidi, } from "@sema-agent/settings-schema";
|
|
3
3
|
import { HttpError, createCodedHttpError } from "./security.js";
|
|
4
4
|
import { GOVERNANCE_HTTP_STATUS } from "./governance-http-status.js";
|
|
5
|
+
import { DEPLOYMENT_SHAPE_PREDICATES } from "./deployment-shape.js";
|
|
5
6
|
import { MCP_SOURCE_LABEL_MAX, isMcpSourceLabel, readMcpSourceLabel } from "./mcp-source-label.js";
|
|
6
7
|
import { describeMcpAssertionHeaderNotAString, describeMcpIdentityHeadersConflict, mcpIdentityHeadersIssue, noteMcpAssertionHeaderIgnored, noteMcpAssertionHeaderNotSent, specWithholdsMcpAssertionHeader, toCoreMcpServerSpec } from "./mcp-assertion-header.js";
|
|
7
8
|
import { MAX_KEY_ECHO, echoKeyName, keyClosureClause, scanKeyClosure } from "./request-key-closure.js";
|
|
8
9
|
import { readRequestToolAxes } from "./request-tool-axes.js";
|
|
10
|
+
import { findUrlCredential, urlCredentialFacts, urlCredentialHeaderExit, urlCredentialRefusalReason } from "./url-credential.js";
|
|
9
11
|
export const MAX_REQUEST_MCP_SERVERS = 32;
|
|
10
12
|
export const MAX_REQUEST_MCP_DROP_NAMES = MAX_REQUEST_MCP_SERVERS;
|
|
11
13
|
export const MCP_SERVER_ENTRY_KEYS = ["allowTools", "contentOrigin", "elicitation", "name", "source", "startupTimeoutMs", "toolAxes", "toolFaces", "transport"];
|
|
@@ -16,7 +18,7 @@ export function mcpInjectionHonored(config) {
|
|
|
16
18
|
return false;
|
|
17
19
|
if (config.compliancePosture !== undefined && resolveComplianceDenies(config.compliancePosture).has("mcp_servers"))
|
|
18
20
|
return false;
|
|
19
|
-
return config
|
|
21
|
+
return !DEPLOYMENT_SHAPE_PREDICATES.multiTenant.holds(config);
|
|
20
22
|
}
|
|
21
23
|
function isRecord(v) {
|
|
22
24
|
return v !== null && typeof v === "object" && !Array.isArray(v);
|
|
@@ -149,8 +151,10 @@ export function requestMcpDeclarationRefusal(list) {
|
|
|
149
151
|
}
|
|
150
152
|
export function assertRequestMcpEntries(bodyMcp) {
|
|
151
153
|
const refusal = requestMcpDeclarationRefusal(bodyMcp);
|
|
152
|
-
if (refusal
|
|
153
|
-
|
|
154
|
+
if (refusal === undefined)
|
|
155
|
+
return;
|
|
156
|
+
const extra = { ...(refusal.unknownKeys === undefined ? {} : { unknownKeys: [...refusal.unknownKeys] }), ...(refusal.facts ?? {}) };
|
|
157
|
+
throw createCodedHttpError(400, refusal.errorCode, refusal.message, Object.keys(extra).length === 0 ? undefined : extra);
|
|
154
158
|
}
|
|
155
159
|
const LIST_REFUSAL_TAIL = "The request is refused rather than acting on part of the list: declarations that silently did not apply would read as in effect to whoever sent them. " +
|
|
156
160
|
"Fix the list (an empty list declares none).";
|
|
@@ -172,6 +176,12 @@ function entryUnknownKeys(entry, at) {
|
|
|
172
176
|
}
|
|
173
177
|
return buckets.unknown.sort();
|
|
174
178
|
}
|
|
179
|
+
function transportUrlCredentialIssue(url) {
|
|
180
|
+
const found = findUrlCredential(url);
|
|
181
|
+
if (found === undefined)
|
|
182
|
+
return undefined;
|
|
183
|
+
return { path: "transport.url", reason: urlCredentialRefusalReason(found, urlCredentialHeaderExit("transport.headers")), credential: found };
|
|
184
|
+
}
|
|
175
185
|
const ENTRY_KEY_JUDGES = {
|
|
176
186
|
allowTools: (o) => o.allowTools === undefined || isStringArray(o.allowTools)
|
|
177
187
|
? undefined
|
|
@@ -211,7 +221,11 @@ const ENTRY_KEY_JUDGES = {
|
|
|
211
221
|
},
|
|
212
222
|
transport: (o) => {
|
|
213
223
|
const read = readRequestMcpTransport(o.transport);
|
|
214
|
-
|
|
224
|
+
if (!read.ok)
|
|
225
|
+
return read.issue;
|
|
226
|
+
if (read.lost[0] !== undefined)
|
|
227
|
+
return read.lost[0];
|
|
228
|
+
return read.transport.kind === "http" ? transportUrlCredentialIssue(read.transport.url) : undefined;
|
|
215
229
|
},
|
|
216
230
|
};
|
|
217
231
|
const ENTRY_REFUSAL_TAIL = "The request is refused rather than mounting the server without it: a declaration that silently did not apply would leave the server running differently from what you declared. " +
|
|
@@ -221,6 +235,7 @@ function entryFieldRefusal(entry, at, issue) {
|
|
|
221
235
|
return {
|
|
222
236
|
errorCode: "request.field_invalid",
|
|
223
237
|
message: `${at}.${issue.path} (server "${server}") is not a usable declaration — ${stripControlAndBidi(issue.reason)}. ${ENTRY_REFUSAL_TAIL}`,
|
|
238
|
+
...(issue.credential === undefined ? {} : { facts: urlCredentialFacts(`${at}.${issue.path}`, issue.credential) }),
|
|
224
239
|
};
|
|
225
240
|
}
|
|
226
241
|
function requestEntryRefusal(entry, at) {
|
package/dist/task-settings.d.ts
CHANGED
|
@@ -59,7 +59,7 @@ import { type TightenOnlySeatValues } from "./tighten-only-seats.js";
|
|
|
59
59
|
* `?permissionMode=` 查询串三处同读)。本仓不持有第二份词表,也不持有「收 / 不收」的表态:判据 = core 的 `isPermissionMode`,型 = core 的
|
|
60
60
|
* `PermissionMode`,wire 句子里的词表只从这里取词({@link PERMISSION_MODE_WORDS})。core 加一个词 ⇒ 请求面自动收它、原样过境,本仓没有
|
|
61
61
|
* 按词分的臂要补;core 删 / 改名一个词 ⇒ 本仓按名写出它的地方(`PLAN_APPROVE_PERMISSION_MODES_AFTER` 等)编译红。
|
|
62
|
-
* 生效模式原样过境 `TaskSpec.permissionMode`(
|
|
62
|
+
* 生效模式原样过境 `TaskSpec.permissionMode`([ref]):引擎自己解释模式 —— 含 `dontAsk`(CC 的「自动拒」档:凡是要问的一律由模式拒,零卡,
|
|
63
63
|
* 门记录 `deniedBy:"mode"`)与 acceptEdits 的免问写域(引擎的写根:任务根 + `additionalDirectories` + 宣告的可写目录),本仓不另写判。
|
|
64
64
|
*/
|
|
65
65
|
/** 请求面闭集的 wire 文案形(`"a" | "b" | …`,core 序)—— 三处 400(顶层 / bundle / 查询串)的句子从这里取词,不再各抄一份。 */
|
|
@@ -82,7 +82,7 @@ export declare function coercePermissionMode(raw: unknown): PermissionMode | und
|
|
|
82
82
|
* 上面的宽读只是本函数外再包一层折叠;词表只有 core 的 `PERMISSION_MODES`(判据 `isPermissionMode`)。 */
|
|
83
83
|
export declare function coercePermissionModeStrict(raw: unknown): PermissionMode | undefined;
|
|
84
84
|
/**
|
|
85
|
-
*
|
|
85
|
+
* [ref] —— 一份**被批准的计划**之后,这条会话继续用的 permission mode(`plan_review` 决裁体的
|
|
86
86
|
* `permissionModeAfter`)。core 的契约句是 `present-plan-tool.js`:「If the plan is approved, the run
|
|
87
87
|
* continues (and any read-only restriction is lifted)」—— 而 core 顶层 resume 把宿主的续跑配置**整体**
|
|
88
88
|
* 展开成新一段 spec、读的是那段 spec 上的模式词(`TaskSpec.permissionMode`),所以「松开」这件事的属主在
|
|
@@ -99,7 +99,7 @@ export declare function coercePermissionModeStrict(raw: unknown): PermissionMode
|
|
|
99
99
|
export declare const PLAN_APPROVE_PERMISSION_MODES_AFTER: readonly ["default", "acceptEdits"];
|
|
100
100
|
/** {@link PLAN_APPROVE_PERMISSION_MODES_AFTER} 的类型形(值表单点,类型从值派生 —— 两处各写一份就会漂)。 */
|
|
101
101
|
export type PlanApprovePermissionModeAfter = (typeof PLAN_APPROVE_PERMISSION_MODES_AFTER)[number];
|
|
102
|
-
/**
|
|
102
|
+
/** [ref] 值闭集判据(wire 门用)。**宽臂一个都没有**:词表外的值 400 响亮拒 —— 这一位选的是批准之后
|
|
103
103
|
* 模型有没有手,把一个拼错的词折成任何一档都是安全轴上的静默降级([ref]「无静默 fail-open」)。 */
|
|
104
104
|
export declare function isPlanApprovePermissionModeAfter(raw: unknown): raw is PlanApprovePermissionModeAfter;
|
|
105
105
|
/**
|
|
@@ -130,7 +130,7 @@ export declare function stampEntryPermissionMode<B extends {
|
|
|
130
130
|
readonly entry: EntryPermissionMode;
|
|
131
131
|
};
|
|
132
132
|
/**
|
|
133
|
-
*
|
|
133
|
+
* [ref] —— **一条已持久化的提交体的生效 permission mode**,单点。
|
|
134
134
|
*
|
|
135
135
|
* 它只是把 {@link effectivePermissionMode} 与「拿哪一份 settings 去问」这**一对**绑在一起:后者是
|
|
136
136
|
* `parseTaskSettings(body.settings)`(resume 重放共用的宽容解析层)。两处各写一遍这一对,就会在
|
|
@@ -161,7 +161,7 @@ export declare function effectivePermissionMode(body: {
|
|
|
161
161
|
permissionMode?: unknown;
|
|
162
162
|
}, settings: ParsedTaskSettings | undefined): PermissionMode | undefined;
|
|
163
163
|
/**
|
|
164
|
-
*
|
|
164
|
+
* [ref] —— [ref] 技能清单预算两旋钮的**值域谓词**(一对具名单铸点)。
|
|
165
165
|
*
|
|
166
166
|
* 两层同问这一只:FRESH 提交面的 400 门(`http/server.ts`)问「合不合法」,RESUME 宽容层
|
|
167
167
|
* ({@link parseTaskSettings})问「收不收下」—— 这两句话在这两个键上是**同一个问题的正反面**
|
|
@@ -204,7 +204,7 @@ export interface ParsedTaskSettings {
|
|
|
204
204
|
/** `settings.env` → per-task shell env. core deliberately keeps NO
|
|
205
205
|
* `TaskSpec.env` (an untrusted caller must not swap the sandbox — [ref] §7 Q4); per-session shell env rides
|
|
206
206
|
* the TRUSTED `executionEnvFactory` seam (`shellEnv`) instead. [ref] "env = capability axis": HONORED only on
|
|
207
|
-
* the single-user host
|
|
207
|
+
* the lanes of deployment-shape row `callerCwd` (single-user host, or device), IGNORED on any cloud/multi-tenant lane. Parsed here; gated at apply. */
|
|
208
208
|
shellEnv?: Record<string, string>;
|
|
209
209
|
/** L2 ultracode preset ([ref]): a CC-parity `settings.ultracode` boolean that EXPANDS to the two existing
|
|
210
210
|
* orthogonal axes — `thinking:"max"` (the reasoning axis) + `selfOrchestration:true` (the orchestration axis,
|
|
@@ -221,7 +221,7 @@ export interface ParsedTaskSettings {
|
|
|
221
221
|
skillListingBudgetFraction?: number;
|
|
222
222
|
/** 同族第二键:每条技能描述在清单里的字符帽(正整数;CC 默认 1536)。超出由引擎**截断**,不是拒。 */
|
|
223
223
|
skillListingMaxDescChars?: number;
|
|
224
|
-
/**
|
|
224
|
+
/** [ref] —— 「只收紧」座位族(`tighten-only-seats.ts` 的四座:读拒模式 / 写保护名的加法 / 合规额外禁项 / 永不自动放行名单)的归一值,**一个键**而不是四个散字段:
|
|
225
225
|
* wire 位置由座位表说(三座在 `settings` 顶层,`neverAuto` 在 `settings.permissions`),解析后与位置无关。空数组 ≡ 缺席(不铸键)。
|
|
226
226
|
* 去处:三座经 {@link applyTaskSettings} 落 core 任务层席;`neverAuto` 经 {@link deriveSettingsPolicy} 落请求叶策略。 */
|
|
227
227
|
tightenOnly?: TightenOnlySeatValues;
|
|
@@ -282,14 +282,14 @@ export interface SettingsPermissionBucketIssue {
|
|
|
282
282
|
export declare function settingsPermissionBucketIssue(perms: unknown): SettingsPermissionBucketIssue | null;
|
|
283
283
|
/** 本 service 真正**消费**的 `settings` 顶层键 —— 闭集。每一个都有消费点:
|
|
284
284
|
* `env`/`hooks`/`model`/`outputStyle`/`permissions`/`ultracode` 与两个 `skillListing*` 在
|
|
285
|
-
* {@link parseTaskSettings};`webSearch` 在 `capabilities/scenarios.ts`(判决 `judgeRequestWebSearch`,单用户闸;形错在受理面 400,
|
|
285
|
+
* {@link parseTaskSettings};`webSearch` 在 `capabilities/scenarios.ts`(判决 `judgeRequestWebSearch`,单用户闸;形错在受理面 400,[ref])。
|
|
286
286
|
* 加键必须同时加消费点,否则就是往闭集里塞一个新的静默丢。
|
|
287
287
|
*
|
|
288
|
-
* 🔴 `readDenyPatterns` / `writeProtectedExtra` / `complianceAdditionalDenies` 与 `permissions.neverAuto`(
|
|
288
|
+
* 🔴 `readDenyPatterns` / `writeProtectedExtra` / `complianceAdditionalDenies` 与 `permissions.neverAuto`([ref])= **「只收紧」座位族**:消费点 = `tighten-only-seats.ts`
|
|
289
289
|
* 的座位表(位置、条目律、去处都由那张表说),读入在 {@link parseTaskSettings},投影在 {@link applyTaskSettings} / {@link deriveSettingsPolicy}。这四个键不是 CC settings 键
|
|
290
290
|
* (sdk 的 `SemaSettings` 尚未声明 —— 对账门 `test/task-settings-sdk-key-parity.test.ts` 的「server 先于 sdk」登记表记着它们)。
|
|
291
291
|
*
|
|
292
|
-
* 🔴 `approvalFrameFamilies`(
|
|
292
|
+
* 🔴 `approvalFrameFamilies`([ref])= 这条 run 的客户端**声明**渲染得了哪些审批开卡帧族 —— 不进引擎,不是 CC settings 键。消费点 = 三条执行腿的审批装配
|
|
293
293
|
* (`tool-approval.ts` 的唯一读者 `declaredApprovalFrameFamilies` → `resolveApprovalLeg`),判官 `approvalFrameFamiliesIssue`(fresh 受理 400 与宽容读者同一只)。
|
|
294
294
|
* `parseTaskSettings` 刻意不读它(它管的是落到 `TaskSpec` 的设置)。sdk 型面待声明(对账门的「server 先于 sdk」登记表记着)。
|
|
295
295
|
*
|
|
@@ -303,7 +303,7 @@ export declare const TASK_SETTINGS_PERMISSION_KEYS: readonly ["allow", "ask", "d
|
|
|
303
303
|
/** CC/SDK 合约里合法、本 service **不接线**的顶层键。词表外的 CC 键落 `unknown` —— 两列都是 400,标签只影响
|
|
304
304
|
* 文案,不影响判决。前三个的出处 = `@sema-agent/sdk` `SemaSettings` 尾注逐字点名的 deferred CC 键。
|
|
305
305
|
*
|
|
306
|
-
* 🔴 `crossSessionInbound` / `dialogExpiry`(
|
|
306
|
+
* 🔴 `crossSessionInbound` / `dialogExpiry`([ref])为什么在**这一列**而不是受理列:它们是**每会话**的
|
|
307
307
|
* 保护型设置(`refuse` = 本会话退出入站跨会话车道),而引擎只给了**部署级**座位(一个 Runner 单例,
|
|
308
308
|
* getter 无会话上下文)。受理它们只能做到「解析 + 记一行运维日志」——调用方拿到 202、以为自己的
|
|
309
309
|
* opt-out 生效了,而实际没有任何 per-session 生效点。**在保护型配置上,「受理但不执行」比「响亮拒」
|
|
@@ -329,8 +329,20 @@ export declare const TASK_SETTINGS_UNSUPPORTED_PERMISSION_KEYS: readonly ["addit
|
|
|
329
329
|
*/
|
|
330
330
|
export declare function taskSettingsKeyIssue(raw: unknown): KeyClosureIssue | null;
|
|
331
331
|
/**
|
|
332
|
-
*
|
|
333
|
-
*
|
|
332
|
+
* FRESH 提交面 `settings.hooks` 子树的键闭集裁决 —— 键闭集门的**第三个实例**(类与另两个实例见 `request-key-closure.ts` 头注;判决、机器面、文案骨架同一只):
|
|
333
|
+
* 一只匹配组 / 一个条目上**读者不携带**的键 ⇒ 返回拒体(调用方 400 `request.body_shape`);全部携带 ⇒ `null`。
|
|
334
|
+
*
|
|
335
|
+
* 词表 = **读者自己的答案**:`config` 是同一份 `raw` 经 {@link parseHooksConfig} 受理的产物,一只组 / 一个条目受理的键 = 可跑形在同一坐标上那只对象的键
|
|
336
|
+
* (契约分类器携带的字段 + 本仓 wire 键:组的 `source`、command 条目的 `plugin` / `args`)。本函数不另立键表 —— 契约给某一型加字段、分类器开始携带它,这里随之受理;
|
|
337
|
+
* 受理 ⇒ 分类器答 `loaded` ⇒ 组与条目的下标与原值逐位对齐。值为 `undefined` 的键与缺席同读(读者同一口径)。坐标经 {@link hooksCoordinate}(契约包出门形 + 回显口径;凭据形键段不原样回显)。
|
|
338
|
+
*
|
|
339
|
+
* 判据边界(与另两个实例同):只判**键名**(值形归读者);拒只在 FRESH 提交面 —— 续跑重放走 {@link parseTaskSettings},读者照旧剥掉它不携带的键,存量体按受理时的读法重放(4xx 打在重放腿上会砖死停驻任务)。
|
|
340
|
+
* 为什么必须拒:一只被剥掉的键对调用方读作「生效了」—— 守卫条目上的 `onFailure: "block"` 被剥掉,守卫起不来时照放行;`plugin` / `args` 写在 http 条目上被剥掉,写的人以为插件上下文在。
|
|
341
|
+
*/
|
|
342
|
+
export declare function hooksKeyIssue(raw: unknown, config: RunnableHooksConfig): KeyClosureIssue | null;
|
|
343
|
+
/**
|
|
344
|
+
* 🔒 **`settings.hooks` 会不会被采纳** —— 全仓**唯一**的属主([ref],主会话裁):hook 命令跑在 WORKER HOST([ref] class ② 能力授予),所以只有单主部署
|
|
345
|
+
* (部署形表行 `multiTenant` 不成立,与 scheduler / backgroundShell / lspHost / MCP 注入同一姿势)采纳;多租户车道收到 hooks **整只忽略**(`task_hooks_ignored`),绝不执行。
|
|
334
346
|
* 三处读它,谁也不许内联 `requirePrincipal`(各写各的 = 迟早漂):
|
|
335
347
|
* · `boot/resolve-spec.ts` —— 装配:不采纳 ⇒ 不铸 `TaskSpec.mods` 的 `settings.hooks` 注册 + 一条 `task_hooks_ignored`;
|
|
336
348
|
* · `http/routes/capabilities.ts` —— 能力位 `taskSettings.hooks`(「says yes ⟺ route works」);
|
|
@@ -381,29 +393,29 @@ export interface WorkflowGateWiring {
|
|
|
381
393
|
*/
|
|
382
394
|
export interface FsWriteGateWiring {
|
|
383
395
|
/**
|
|
384
|
-
* 🔴
|
|
396
|
+
* 🔴 [ref] / codex r1 [high](验真后修)—— **权限规则**的路径基(core `PathRuleBases.root`),**只在真任务根已知时**在场。
|
|
385
397
|
*
|
|
386
398
|
* host 腿上「这条 session 还没登记工作目录」时,`resolve-spec` 的路径裁决 env 落在一个**永不创建的哨兵目录**上
|
|
387
399
|
* (`fs-write-gate-unrooted`,治理层守卫集的 cwd)。那对守卫是 fail-SAFE 的(相对目标在哨兵下解析不出真身);但规则编译器按**词法**匹配、
|
|
388
400
|
* 不问目录存不存在 ⇒ 把哨兵当根递进来,`deny Edit(src/**)` 会编译成功、指向一个谁也不会写的目录,对真实工作区的
|
|
389
401
|
* `<工作区>/src/secret.ts` 判 allow —— 一条亲手写下的收紧规则**静默失效**。所以哨兵从不被声明成基。
|
|
390
402
|
*
|
|
391
|
-
* 缺席 ⇒ 不声明根 ⇒ 需要该基的拼法(`Edit(src/**)` / `Edit(/etc/**)`)锚在**装入这只策略的那条腿**的真根(core 7.46.0
|
|
403
|
+
* 缺席 ⇒ 不声明根 ⇒ 需要该基的拼法(`Edit(src/**)` / `Edit(/etc/**)`)锚在**装入这只策略的那条腿**的真根(core 7.46.0 [ref] 车 B:
|
|
392
404
|
* 锚装一次、在被装入处;`unsupported.path_base` 只剩「声明了一个用不了的基」)。修前(core ≤7.45)缺席 ⇒ 整表拒(→ 422):沙箱车道上
|
|
393
405
|
* 相对 / `/x` 形规则恒 422。绝对形(`//abs`)不需要基;`~/` 形见下一字段。
|
|
394
406
|
*/
|
|
395
407
|
taskRoot?: string;
|
|
396
408
|
/**
|
|
397
|
-
* 🔴
|
|
409
|
+
* 🔴 [ref] / codex r2 [high](验真后修)—— **执行环境的 home**(core `PathRuleBases.home`,`~/…` 形的基)。
|
|
398
410
|
*
|
|
399
|
-
* 🔴 **
|
|
411
|
+
* 🔴 **[ref]④ 起本字段在远端车道上也可以有值**:四只远端 adapter 此前一个都不声明 `ExecutionEnv.homeDir`,
|
|
400
412
|
* 而本字段那时只在 `remoteExec` 整个缺席时才铸 —— 于是**每一条远端部署的 `~/` 规则都恒 422**(接入审计
|
|
401
413
|
* M13)。修法不是放松下面那道门,而是让部署**真的知道** home:`execution-lane-caps.ts` 的
|
|
402
414
|
* `executionLaneHomeDir` 是唯一属主,`boot/execution-env.ts` 把它递给 adapter 的 `homeDir` 座、
|
|
403
415
|
* `boot/resolve-spec.ts` / `boot/parked-revive-gate.ts` 把**同一个值**递成本字段。两处同源是承重的:
|
|
404
416
|
* 各算一份就会出现「422 门放行而引擎判 unreadable」或反过来。
|
|
405
417
|
*
|
|
406
|
-
* 🔴 **
|
|
418
|
+
* 🔴 **[ref]⑦ 改真话**(亲读 core 7.12.0 `dist/core/permission-rule-model.js` /
|
|
407
419
|
* 的 `resolvePathPattern`,推翻本注此前的两句):
|
|
408
420
|
* · core 对缺席的 `home` **不**回落 `os.homedir()` —— `resolvePathPattern` 走
|
|
409
421
|
* `lexicalNormalAbsolutePathOf(baseValueOf("home", bases) ?? "")`,base 缺席 ⇒ `undefined` ⇒ 直接回
|
package/dist/task-settings.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import { combinePolicies, parseRuleText, resolveReasoningProfile, rankOf, isThinkingLevel, RUN_WORKFLOW_TOOL_NAME, PERMISSION_MODES, isPermissionMode, ruleToolGrammarOf, } from "@sema-agent/core";
|
|
2
2
|
import { judgeUnmatchableToolNames } from "./config.js";
|
|
3
|
+
import { NAME_TABLE_BEHAVIOR } from "./namespaced-rule-name.js";
|
|
3
4
|
import { entryProblem } from "./entry-problems.js";
|
|
4
5
|
import { MAX_PERMISSION_RULES_PER_LIST, createRuleListPolicy } from "./permission-rule-list.js";
|
|
5
6
|
import { allowLayerEntryCountIssue, describeAllowLayerOverCap, ruleEntryListShapeOk } from "./rule-entry-list.js";
|
|
6
7
|
import { limitRefusal } from "./limit-refusal.js";
|
|
7
8
|
import { tightenGoverned } from "./governance-overrides.js";
|
|
8
9
|
import { MAX_KEY_ECHO, keyClosureClause, scanKeyClosure } from "./request-key-closure.js";
|
|
9
|
-
import { parseHooksConfig } from "./hooks/hook-runner.js";
|
|
10
|
+
import { hooksCoordinate, parseHooksConfig } from "./hooks/hook-runner.js";
|
|
10
11
|
import { heldRuleName } from "./tool-rule-names.js";
|
|
11
12
|
import { entryPermissionMode } from "./runtime-governance.js";
|
|
12
13
|
import { policyAskStandingAnswerFacts, standingAnswerDurablyRecordable } from "./tool-approval.js";
|
|
13
14
|
import { createRequestNeverAutoPolicy } from "./approval.js";
|
|
14
15
|
import { readTightenOnlySeats, tightenOnlySeatField, tightenOnlySpecSeats } from "./tighten-only-seats.js";
|
|
16
|
+
import { DEPLOYMENT_SHAPE_PREDICATES } from "./deployment-shape.js";
|
|
15
17
|
export const PERMISSION_MODE_WORDS = PERMISSION_MODES.map((m) => `"${m}"`).join(" | ");
|
|
16
18
|
export function coercePermissionMode(raw) {
|
|
17
19
|
const strict = coercePermissionModeStrict(raw);
|
|
@@ -191,8 +193,36 @@ export function taskSettingsKeyIssue(raw) {
|
|
|
191
193
|
unsupportedKeys: unsupported.slice(0, MAX_KEY_ECHO),
|
|
192
194
|
};
|
|
193
195
|
}
|
|
196
|
+
export function hooksKeyIssue(raw, config) {
|
|
197
|
+
const unknown = [];
|
|
198
|
+
const member = (node, key) => node !== null && typeof node === "object" && Object.hasOwn(node, key) ? node[key] : undefined;
|
|
199
|
+
const scan = (rawNode, carried, at) => {
|
|
200
|
+
if (rawNode === null || typeof rawNode !== "object" || Array.isArray(rawNode))
|
|
201
|
+
return;
|
|
202
|
+
for (const [key, value] of Object.entries(rawNode))
|
|
203
|
+
if (value !== undefined && !Object.hasOwn(carried, key))
|
|
204
|
+
unknown.push(hooksCoordinate([...at, key]));
|
|
205
|
+
};
|
|
206
|
+
for (const [event, groups] of Object.entries(config)) {
|
|
207
|
+
for (const [groupIndex, group] of (groups ?? []).entries()) {
|
|
208
|
+
const rawGroup = member(member(raw, event), groupIndex);
|
|
209
|
+
scan(rawGroup, group, ["hooks", event, groupIndex]);
|
|
210
|
+
for (const [entryIndex, entry] of group.hooks.entries())
|
|
211
|
+
scan(member(member(rawGroup, "hooks"), entryIndex), entry, ["hooks", event, groupIndex, "hooks", entryIndex]);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (unknown.length === 0)
|
|
215
|
+
return null;
|
|
216
|
+
unknown.sort();
|
|
217
|
+
const label = "unknown (not read on that matcher group or hook entry by this server — a misspelling, a key of another entry type (plugin / args are read on command entries only), or a hook key this server does not run)";
|
|
218
|
+
return {
|
|
219
|
+
message: `settings.hooks: unrecognized key(s) — refused rather than dropped, because a dropped key reads as "in effect" to the caller. ${keyClosureClause(unknown, label)}.`,
|
|
220
|
+
unknownKeys: unknown.slice(0, MAX_KEY_ECHO),
|
|
221
|
+
unsupportedKeys: [],
|
|
222
|
+
};
|
|
223
|
+
}
|
|
194
224
|
export function taskHooksHonored(config) {
|
|
195
|
-
return config
|
|
225
|
+
return !DEPLOYMENT_SHAPE_PREDICATES.multiTenant.holds(config);
|
|
196
226
|
}
|
|
197
227
|
function tightenOnlySeatDeferredName(name) {
|
|
198
228
|
return tightenOnlySeatField(name).replace(/^settings\./, "");
|
|
@@ -384,7 +414,7 @@ export function deriveSettingsPolicy(settings, bases) {
|
|
|
384
414
|
}
|
|
385
415
|
export function neverAutoNamesRefusal(names) {
|
|
386
416
|
const field = tightenOnlySeatField("neverAuto");
|
|
387
|
-
const judged = judgeUnmatchableToolNames(field.replace(/^settings\./, ""), names, { consumer: "tool-name-table", behavior:
|
|
417
|
+
const judged = judgeUnmatchableToolNames(field.replace(/^settings\./, ""), names, { consumer: "tool-name-table", behavior: NAME_TABLE_BEHAVIOR });
|
|
388
418
|
if (judged === undefined)
|
|
389
419
|
return undefined;
|
|
390
420
|
return { message: judged.message, problems: judged.bad.map((b) => entryProblem(SETTINGS_RULE_REFUSAL_CODE, field, b.name, b.reason)) };
|
package/dist/task-workflow.d.ts
CHANGED
|
@@ -1,27 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Workflow super-set unlock — map the per-task `body.selfOrchestration` intent onto
|
|
3
|
-
* `TaskSpec.selfOrchestration`, the gate that mounts core's LLM-authored `run_workflow` engine (the workflow.ts
|
|
4
|
-
* agent/parallel/pipeline orchestrator). Same shape as the rank-1 roster gap: the engine (core run_workflow +
|
|
5
|
-
* workflow.ts) is BUILT, but nothing mapped a body field to the per-task spec flag, so it was unreachable over HTTP
|
|
6
|
-
* (capabilities advertised `workflows:true` but the LLM could never call run_workflow).
|
|
7
|
-
*
|
|
8
|
-
* Gating:
|
|
9
|
-
* - DEPLOYMENT: `selfOrchestrationEnabled` must be on (the workflowScriptRunner + stores are wired). Otherwise a set
|
|
10
|
-
* flag is a harmless no-op (core fail-closes run_workflow without the sandbox runner), so it's dropped for clarity.
|
|
11
|
-
* - MULTI-TENANT: honored ONLY when a per-principal entitlement RESOLVER is wired (`hasEntitlementResolver`). 🔴 core's
|
|
12
|
-
* `allowWorkflows` (RuntimeCaps) is TIGHTEN-ONLY — a resolver can only DENY; `undefined` = NO restriction, so the
|
|
13
|
-
* deployment capability governs. Therefore WITHOUT a resolver the engine would mount run_workflow UNGATED for every
|
|
14
|
-
* tenant. So we fail-closed here (defense-in-depth: a misconfigured multi-tenant deployment with no entitlement
|
|
15
|
-
* source must NOT leak the LLM-authored workflow engine). WITH a resolver, core enforces `allowWorkflows`
|
|
16
|
-
* per-principal (deny → fail-closed). Single-user (owns its own worker) honors directly. Three-gate: engine-can ∧
|
|
17
|
-
* center-may(allowWorkflows) ∧ shell-show.
|
|
18
|
-
*
|
|
19
|
-
* 🔴 [ref](2026-09-03):fail-closed 的**方向**从来是对的,错的是它**没人说**。多租户 + 无 entitlement 源
|
|
20
|
-
* 的部署上,这条腿把 `body.selfOrchestration:true`(以及 `settings.ultracode` 展开出来的同一个意图)静默
|
|
21
|
-
* 折成 `undefined`,而 `/v1/capabilities` 照报 `workflows:true` ⇒ 「壳显示支持、引擎按普通 run 跑」。修法
|
|
22
|
-
* 是把部署级半场抽成下面的 {@link selfOrchestrationDenial}(能力位与准入**同一只**谓词),提交面在拒因
|
|
23
|
-
* 在场时**响亮**拒(`routes` 的 501 `capability.self_orchestration_required`),不再静默折。
|
|
24
|
-
*/
|
|
25
1
|
export declare function selfOrchestrationFromBody(body: {
|
|
26
2
|
selfOrchestration?: unknown;
|
|
27
3
|
}, config: SelfOrchestrationGateConfig, hasEntitlementResolver: boolean): true | undefined;
|
package/dist/task-workflow.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DEPLOYMENT_SHAPE_PREDICATES } from "./deployment-shape.js";
|
|
1
2
|
export function selfOrchestrationFromBody(body, config, hasEntitlementResolver) {
|
|
2
3
|
if (body.selfOrchestration !== true || config.selfOrchestrationEnabled !== true)
|
|
3
4
|
return undefined;
|
|
@@ -15,7 +16,7 @@ export function enableForkFromBody(body, config, hasEntitlementResolver) {
|
|
|
15
16
|
return false;
|
|
16
17
|
if (body.enableFork === false)
|
|
17
18
|
return false;
|
|
18
|
-
if (config
|
|
19
|
+
if (!DEPLOYMENT_SHAPE_PREDICATES.multiTenant.holds(config))
|
|
19
20
|
return true;
|
|
20
21
|
return hasEntitlementResolver;
|
|
21
22
|
}
|