@sema-agent/server 7.148.0 → 7.150.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 +551 -9
- package/README.md +17 -2
- package/README.zh-CN.md +5 -1
- package/USAGE.md +126 -68
- package/dist/adoption/wire.d.ts +3 -3
- package/dist/approval-card.d.ts +33 -33
- package/dist/approval-gate-currency.d.ts +1 -1
- package/dist/approval-leg-origin.d.ts +33 -0
- package/dist/approval-leg-origin.js +4 -0
- package/dist/audit.d.ts +1 -1
- package/dist/audit.js +2 -2
- package/dist/auth-bridge.d.ts +9 -1
- package/dist/auth-bridge.js +4 -4
- package/dist/auth-keys.d.ts +10 -1
- package/dist/auth-keys.js +8 -0
- package/dist/background-session-reap.d.ts +1 -1
- package/dist/boot/deferred-sandbox-path-env.d.ts +5 -3
- package/dist/boot/deferred-sandbox-path-env.js +1 -2
- package/dist/boot/execution-env.js +10 -11
- package/dist/boot/execution-lane.d.ts +6 -4
- package/dist/boot/execution-lane.js +3 -1
- package/dist/boot/org-delivery.d.ts +3 -2
- package/dist/boot/parked-revive-gate.d.ts +5 -5
- package/dist/boot/parked-revive-gate.js +2 -3
- package/dist/boot/resolve-spec.d.ts +4 -5
- package/dist/boot/resolve-spec.js +66 -28
- package/dist/boot/retention-lane.d.ts +1 -1
- package/dist/boot/runner-deps.js +3 -1
- package/dist/boot/session-faces.js +21 -21
- package/dist/boot/stage-01-config.d.ts +1 -0
- package/dist/boot/stage-01-config.js +4 -3
- package/dist/boot/stage-02-web-admin-pull.d.ts +1 -0
- package/dist/boot/stage-02-web-admin-pull.js +10 -2
- package/dist/boot/stage-03-store-backend.d.ts +1 -0
- package/dist/boot/stage-03-store-backend.js +4 -4
- package/dist/boot/stage-04-stores.d.ts +1 -0
- package/dist/boot/stage-05-execution-env.d.ts +1 -0
- package/dist/boot/stage-06-runners.d.ts +2 -1
- package/dist/boot/stage-06-runners.js +1 -2
- package/dist/boot/stage-07-capability-layer.d.ts +2 -1
- package/dist/boot/stage-07-capability-layer.js +1 -1
- package/dist/boot/stage-08-reapers.d.ts +2 -1
- package/dist/boot/stage-09-leader.d.ts +2 -1
- package/dist/boot/stage-10-http-server.d.ts +35 -2
- package/dist/boot/stage-10-http-server.js +9 -4
- package/dist/boot/stores.d.ts +3 -0
- package/dist/boot/stores.js +22 -19
- package/dist/boot/web-admin.d.ts +1 -1
- package/dist/capabilities/tool-defer.d.ts +1 -1
- package/dist/capability-facts.d.ts +70 -60
- package/dist/capability-facts.js +45 -49
- package/dist/card-settle-stored-scope.d.ts +56 -0
- package/dist/card-settle-stored-scope.js +27 -0
- package/dist/card-void.d.ts +7 -12
- package/dist/card-void.js +2 -7
- package/dist/config-catalog.d.ts +12 -0
- package/dist/config-catalog.js +37 -33
- package/dist/config-invariants.d.ts +5 -4
- package/dist/config-invariants.js +4 -4
- package/dist/config-types.d.ts +49 -16
- package/dist/config.d.ts +6 -5
- package/dist/config.js +35 -24
- package/dist/context-window-notice.d.ts +31 -0
- package/dist/context-window-notice.js +28 -0
- package/dist/deployment-governance.d.ts +7 -28
- package/dist/deployment-governance.js +1 -14
- package/dist/deployment-shape.d.ts +20 -11
- package/dist/deployment-shape.js +1 -0
- package/dist/device-ws-hub.d.ts +1 -0
- package/dist/device-ws-hub.js +64 -28
- package/dist/device-ws-protocol.d.ts +20 -6
- package/dist/device-ws-protocol.js +9 -2
- package/dist/engine-identity.d.ts +7 -1
- package/dist/engine-identity.js +5 -0
- package/dist/env-name-allowlist-knobs.d.ts +6 -5
- package/dist/env-name-allowlist-knobs.js +5 -0
- package/dist/execution-lane-caps.d.ts +20 -5
- package/dist/execution-lane-caps.js +18 -4
- package/dist/field-conflict.d.ts +2 -2
- package/dist/fleet/engine-signal.d.ts +14 -1
- package/dist/fleet/engine-signal.js +5 -1
- package/dist/fleet/fleet-reconciler.d.ts +1 -1
- package/dist/fleet/serving-lease.d.ts +18 -3
- package/dist/fleet/serving-lease.js +81 -35
- package/dist/fleet-client.d.ts +13 -11
- package/dist/fleet-client.js +53 -33
- package/dist/history-anchor.js +1 -1
- package/dist/hitl-delivery.d.ts +1 -3
- package/dist/hitl-delivery.js +1 -1
- package/dist/hooks/command-spawn.d.ts +7 -2
- package/dist/hooks/command-spawn.js +13 -6
- package/dist/hooks/hook-runner.d.ts +5 -0
- package/dist/hooks/hook-runner.js +11 -7
- package/dist/http/active-run-conflict.d.ts +3 -7
- package/dist/http/active-run-conflict.js +2 -2
- package/dist/http/admission.js +5 -5
- package/dist/http/approval-sweeps.js +5 -3
- package/dist/http/caller-trust.d.ts +2 -2
- package/dist/http/caller-trust.js +3 -3
- package/dist/http/checkpoint-ctx.d.ts +18 -63
- package/dist/http/checkpoint-ctx.js +1 -24
- package/dist/http/claim-heartbeat.d.ts +6 -6
- package/dist/http/claim-heartbeat.js +6 -6
- package/dist/http/claimed-run.d.ts +16 -9
- package/dist/http/claimed-run.js +8 -0
- package/dist/http/dispatch.js +7 -5
- package/dist/http/durable-run-leg.d.ts +8 -1
- package/dist/http/durable-run-leg.js +34 -15
- package/dist/http/execution-context.d.ts +115 -14
- package/dist/http/execution-context.js +130 -40
- package/dist/http/owner-access.d.ts +246 -21
- package/dist/http/owner-access.js +186 -8
- package/dist/http/principal-gate.d.ts +18 -11
- package/dist/http/principal-gate.js +3 -1
- package/dist/http/readiness.d.ts +4 -2
- package/dist/http/resume-ctx-read.d.ts +14 -3
- package/dist/http/resume-ctx-read.js +24 -3
- package/dist/http/resume-legs.d.ts +35 -3
- package/dist/http/resume-legs.js +262 -106
- package/dist/http/route-ctx.d.ts +29 -11
- package/dist/http/routes/a2a-serve.js +17 -14
- package/dist/http/routes/approvals-assistant.d.ts +3 -2
- package/dist/http/routes/approvals-assistant.js +11 -11
- package/dist/http/routes/capabilities.js +5 -4
- package/dist/http/routes/config-catalog.d.ts +1 -1
- package/dist/http/routes/diagnostics.d.ts +3 -1
- package/dist/http/routes/diagnostics.js +30 -5
- package/dist/http/routes/mcp-reconnect.js +2 -2
- package/dist/http/routes/memory-origin.d.ts +1 -1
- package/dist/http/routes/notify-wake.js +2 -3
- package/dist/http/routes/principal-inbox.d.ts +3 -1
- package/dist/http/routes/principal-inbox.js +3 -2
- package/dist/http/routes/projects.d.ts +1 -0
- package/dist/http/routes/projects.js +5 -3
- package/dist/http/routes/retention-ops.d.ts +1 -1
- package/dist/http/routes/run-permission-mode.d.ts +1 -1
- package/dist/http/routes/run-permission-mode.js +2 -2
- package/dist/http/routes/runs.d.ts +1 -1
- package/dist/http/routes/runs.js +33 -37
- package/dist/http/routes/session-memory-sync.js +4 -5
- package/dist/http/routes/session-sync.d.ts +24 -5
- package/dist/http/routes/session-sync.js +45 -37
- package/dist/http/routes/sessions-list.d.ts +1 -1
- package/dist/http/routes/sessions.d.ts +1 -1
- package/dist/http/routes/sessions.js +18 -44
- package/dist/http/routes/tasks.js +136 -101
- package/dist/http/routes/trace-usage.js +14 -14
- package/dist/http/routes/workflows.d.ts +1 -0
- package/dist/http/routes/workflows.js +20 -38
- package/dist/http/server.d.ts +12 -9
- package/dist/http/server.js +35 -6
- package/dist/http/stored-body-replay.d.ts +3 -24
- package/dist/http/stored-body-replay.js +2 -12
- package/dist/http/submit-ctx.d.ts +2 -2
- package/dist/http/submit-ctx.js +5 -5
- package/dist/http/submit-replay.d.ts +15 -2
- package/dist/http/submit-replay.js +10 -4
- package/dist/http/wire-types.d.ts +6 -3
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -0
- package/dist/leader/endpoint.js +9 -8
- package/dist/leg-facts.d.ts +13 -2
- package/dist/leg-facts.js +2 -0
- package/dist/local-store-declaration.d.ts +54 -0
- package/dist/local-store-declaration.js +59 -0
- package/dist/mcp-assertion-header.d.ts +1 -1
- package/dist/mcp-assertion-header.js +1 -1
- package/dist/mcp-authorization-face.d.ts +18 -14
- package/dist/mcp-authorization-face.js +3 -2
- package/dist/memory-project-layer.js +1 -1
- package/dist/memory-scope.d.ts +4 -4
- package/dist/memory-scope.js +4 -4
- package/dist/memory-store-refusal.d.ts +1 -1
- package/dist/memory-sync-client.js +2 -2
- package/dist/model-context-window.d.ts +50 -11
- package/dist/model-context-window.js +20 -1
- package/dist/model-entry-refusal.d.ts +5 -4
- package/dist/model-entry-refusal.js +17 -3
- package/dist/model-reach-scope.d.ts +2 -1
- package/dist/observability/corrupt-read-seat.d.ts +1 -1
- package/dist/observability/fail-open.d.ts +19 -7
- package/dist/observability/fail-open.js +19 -7
- package/dist/observability/logger.d.ts +7 -0
- package/dist/observability/logger.js +3 -1
- package/dist/observability/metrics.js +1 -1
- package/dist/observability/run-terminal.d.ts +1 -1
- package/dist/observability/run-terminal.js +1 -0
- package/dist/observability/secret-env-scrub.d.ts +1 -1
- package/dist/observability/secret-env-scrub.js +1 -1
- package/dist/org-delivery-gate.d.ts +31 -6
- package/dist/org-delivery-gate.js +7 -4
- package/dist/owner-faces.d.ts +30 -5
- package/dist/owner-faces.js +2 -0
- package/dist/park-row-commit.d.ts +67 -0
- package/dist/park-row-commit.js +76 -0
- package/dist/parked-decide.d.ts +9 -7
- package/dist/parked-decide.js +25 -6
- package/dist/peer-directory.d.ts +1 -1
- package/dist/peer-seat.d.ts +1 -1
- package/dist/peer-seat.js +52 -59
- package/dist/plugins/adoption-log-sql.d.ts +3 -3
- package/dist/plugins/adoption-log-sql.js +19 -19
- package/dist/plugins/approval-ask-store-sql.d.ts +1 -1
- package/dist/plugins/approval-ask-store-sql.js +3 -5
- package/dist/plugins/approval-exemption-skill-cutoff.d.ts +64 -0
- package/dist/plugins/approval-exemption-skill-cutoff.js +122 -0
- package/dist/plugins/approval-exemption-skill-m46.d.ts +0 -6
- package/dist/plugins/approval-exemption-skill-m46.js +6 -10
- package/dist/plugins/approval-exemption-store.d.ts +26 -1
- package/dist/plugins/approval-exemption-store.js +28 -19
- package/dist/plugins/ensure-schema-lock-policy.d.ts +36 -3
- package/dist/plugins/ensure-schema-lock-policy.js +75 -9
- package/dist/plugins/exec-path-law.d.ts +34 -0
- package/dist/plugins/exec-path-law.js +13 -0
- package/dist/plugins/file-run-store.d.ts +22 -9
- package/dist/plugins/file-run-store.js +51 -23
- package/dist/plugins/local-checkpoint-store.d.ts +8 -1
- package/dist/plugins/local-checkpoint-store.js +5 -1
- package/dist/plugins/local-data-root-admission.d.ts +52 -0
- package/dist/plugins/local-data-root-admission.js +100 -0
- package/dist/plugins/local-engine-high-water.d.ts +28 -7
- package/dist/plugins/local-engine-high-water.js +27 -22
- package/dist/plugins/local-session-store.d.ts +134 -49
- package/dist/plugins/local-session-store.js +149 -108
- package/dist/plugins/memory-run-store.d.ts +14 -9
- package/dist/plugins/memory-run-store.js +48 -22
- package/dist/plugins/one-time-migration-marker.d.ts +19 -3
- package/dist/plugins/one-time-migration-marker.js +7 -1
- package/dist/plugins/one-time-migrations.d.ts +110 -59
- package/dist/plugins/one-time-migrations.js +224 -136
- package/dist/plugins/org-delivery-quota-store.d.ts +34 -11
- package/dist/plugins/org-delivery-quota-store.js +29 -14
- package/dist/plugins/permission-rule-store-sql.d.ts +1 -1
- package/dist/plugins/permission-rule-store-sql.js +5 -9
- package/dist/plugins/pg-pool.d.ts +1 -1
- package/dist/plugins/pg-pool.js +14 -12
- package/dist/plugins/posix-shell-fs.js +4 -2
- package/dist/plugins/remote-env-adb.js +3 -2
- package/dist/plugins/remote-env-device.d.ts +3 -2
- package/dist/plugins/remote-env-device.js +8 -6
- package/dist/plugins/remote-env-e2b.d.ts +4 -8
- package/dist/plugins/remote-env-e2b.js +21 -15
- package/dist/plugins/remote-env-host.d.ts +51 -10
- package/dist/plugins/remote-env-host.js +97 -31
- package/dist/plugins/remote-env-k8s.js +7 -4
- package/dist/plugins/remote-env-local-docker.d.ts +6 -3
- package/dist/plugins/remote-env-local-docker.js +11 -25
- package/dist/plugins/remote-env-ssh.js +4 -3
- package/dist/plugins/remote-shell.d.ts +3 -1
- package/dist/plugins/remote-shell.js +3 -3
- package/dist/plugins/replica-registration.d.ts +35 -0
- package/dist/plugins/replica-registration.js +48 -0
- package/dist/plugins/retention-lane-store-sql.d.ts +1 -1
- package/dist/plugins/run-store-sql.d.ts +27 -8
- package/dist/plugins/run-store-sql.js +46 -18
- package/dist/plugins/scenario-prefix-switch-m42.d.ts +8 -12
- package/dist/plugins/scenario-prefix-switch-m42.js +9 -6
- package/dist/plugins/schema-consistency.d.ts +91 -5
- package/dist/plugins/schema-consistency.js +189 -7
- package/dist/plugins/schema-drift-sentence.d.ts +6 -5
- package/dist/plugins/schema-drift-sentence.js +13 -5
- package/dist/plugins/serving-requirement.d.ts +49 -0
- package/dist/plugins/serving-requirement.js +53 -0
- package/dist/plugins/session-placement.d.ts +5 -4
- package/dist/plugins/shell-sentinel-owner-m48.d.ts +22 -0
- package/dist/plugins/shell-sentinel-owner-m48.js +6 -0
- package/dist/plugins/stop-then-start-sentence.d.ts +55 -0
- package/dist/plugins/stop-then-start-sentence.js +51 -0
- package/dist/plugins/store-backend.d.ts +23 -9
- package/dist/plugins/store-backend.js +58 -24
- package/dist/plugins/store-contracts.d.ts +45 -5
- package/dist/plugins/store-contracts.js +19 -0
- package/dist/plugins/tidb-pool.d.ts +11 -6
- package/dist/plugins/tidb-pool.js +22 -12
- package/dist/plugins/workspace-custody.d.ts +44 -0
- package/dist/plugins/workspace-custody.js +47 -0
- package/dist/process-instance.d.ts +3 -0
- package/dist/process-instance.js +7 -0
- package/dist/project-context.d.ts +66 -0
- package/dist/project-context.js +70 -0
- package/dist/project-identity.d.ts +8 -7
- package/dist/project-identity.js +40 -17
- package/dist/project-layer-key.d.ts +13 -2
- package/dist/project-layer-key.js +9 -1
- package/dist/question.d.ts +9 -21
- package/dist/question.js +28 -19
- package/dist/read-deny-floor-notice.d.ts +36 -0
- package/dist/read-deny-floor-notice.js +40 -0
- package/dist/{plain-string-record.d.ts → request-declaration-disposition.d.ts} +9 -23
- package/dist/request-declaration-disposition.js +39 -0
- package/dist/run-cancel-card.d.ts +28 -0
- package/dist/run-cancel-card.js +20 -0
- package/dist/run-cancel-context.d.ts +10 -0
- package/dist/run-cancel-context.js +1 -0
- package/dist/run-local.js +28 -13
- package/dist/runs.d.ts +31 -7
- package/dist/runs.js +34 -16
- package/dist/security.d.ts +3 -3
- package/dist/server-secret-env.d.ts +34 -20
- package/dist/server-secret-env.js +61 -18
- package/dist/session-agent.d.ts +4 -12
- package/dist/session-agent.js +0 -6
- package/dist/session-children-retire.d.ts +6 -3
- package/dist/session-children-retire.js +2 -5
- package/dist/session-incarnation.d.ts +18 -4
- package/dist/session-incarnation.js +4 -1
- package/dist/session-notify-door.d.ts +4 -4
- package/dist/session-notify-door.js +5 -6
- package/dist/session-rules-seat.d.ts +4 -3
- package/dist/session-rules-seat.js +3 -11
- package/dist/session-sync.js +3 -3
- package/dist/session-workspace.d.ts +3 -3
- package/dist/store-admission.d.ts +33 -0
- package/dist/store-admission.js +49 -0
- package/dist/store-posture.d.ts +5 -0
- package/dist/store-posture.js +18 -1
- package/dist/stores-sql/checkpoint-store-sql.d.ts +22 -3
- package/dist/stores-sql/checkpoint-store-sql.js +109 -23
- package/dist/stores-sql/file-history-store-sql.d.ts +1 -1
- package/dist/stores-sql/file-history-store-sql.js +3 -5
- package/dist/stores-sql/retention-store-sql.d.ts +1 -1
- package/dist/stores-sql/tool-result-store-sql.d.ts +1 -1
- package/dist/stores-sql/tool-result-store-sql.js +4 -6
- package/dist/task-a2a.d.ts +3 -8
- package/dist/task-a2a.js +25 -27
- package/dist/task-cwd.d.ts +27 -10
- package/dist/task-cwd.js +3 -0
- package/dist/task-mcp.d.ts +3 -3
- package/dist/task-mcp.js +1 -1
- package/dist/task-settings.d.ts +13 -0
- package/dist/task-settings.js +14 -7
- package/dist/terminal.d.ts +2 -0
- package/dist/terminal.js +21 -6
- package/dist/tool-approval.d.ts +50 -41
- package/dist/tool-approval.js +96 -73
- package/dist/trace/engine-notice-wire.d.ts +38 -21
- package/dist/trace/engine-notice-wire.js +25 -4
- package/dist/trace/ledger-sink.d.ts +3 -1
- package/dist/trace/project.d.ts +8 -5
- package/dist/trace/project.js +11 -9
- package/dist/trace/projection-table.d.ts +33 -2
- package/dist/trace/redact.d.ts +12 -0
- package/dist/trace/redact.js +5 -1
- package/dist/trace/self-minted-wire.d.ts +268 -56
- package/dist/trace/self-minted-wire.js +110 -40
- package/dist/trace/tool-card.d.ts +3 -0
- package/dist/trace/tool-card.js +24 -0
- package/dist/trace/tool-output-media.d.ts +2 -1
- package/dist/unattended-permission-mode.d.ts +1 -1
- package/dist/web-admin-client/apply-effective.d.ts +1 -1
- package/dist/web-admin-client/apply-effective.js +22 -9
- package/dist/web-admin-client/effective-keys.d.ts +1 -1
- package/dist/web-admin-client/skills-mcp.d.ts +1 -1
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +57 -29
- package/docs/error-text-lexicon.json +317 -0
- package/package.json +4 -2
- package/scripts/embed-minimal.mjs +183 -0
- package/wire-changes/server@7.149.0.json +372 -0
- package/wire-changes/server@7.150.0.json +335 -0
- package/dist/plain-string-record.js +0 -70
package/USAGE.md
CHANGED
|
@@ -58,6 +58,8 @@ docker compose up --build --scale service=4 # 4 个无状态 worker,nginx
|
|
|
58
58
|
> 显式带 `DB_BACKEND=mysql`。同版:`DB_BACKEND=mysql|pg` 显式而店打不开,拒句点名 `DB_BACKEND=<引擎>`(修前只有驱动的一句 `connect ECONNREFUSED …`)。
|
|
59
59
|
> 🔴 **7.119.0 起 `SESSION_BACKEND=auto` 配了坐标而库连不上同样拒启,不再有「auto 内存起服」这条出路**:`auto` = 「配了该引擎的坐标就是那只库(boot 期窗内重试、到窗拒启),没配就是内存」,
|
|
60
60
|
> 由配置决定、不由起库成败决定;内存部署写 `DB_BACKEND=memory` 或 `SESSION_BACKEND=memory`。`GET /health` 的 `sessionBackend` 如实说装好的后端种类(`pg` / `mysql` / `local` / `memory`)。持久化姿态读面:caps `store`(附录 B;`store.durability` 三态 = 店活不活得过容器 / Pod 替换,`/health.store.durability` 同值)。
|
|
61
|
+
> 它报的是**参与判定的根里最弱的那只**:数据根(会话店 + 检查点店)、封签钥匙目录(缺省 `<数据根>/sealed-key`)、file 记忆根(只在 file 记忆引擎真接了线时参与;`MEMORY_ENGINE_DIR`,缺省 `AGENT_DATA_DIR`,再缺省 `~/.ai-agent` —— **跟 HOME 走,不跟 `LOCAL_DATA_ROOT`**)。
|
|
62
|
+
> 拒启(`config.store_not_durable`)看数据根,与**独立的**封签钥匙目录(只在写了 `SEALED_KEY_DIR`、停驻审批耐久时:它易失 ⇒ 停驻行活过替换而封它凭据的钥匙不活,拒;出路 = 挂卷 / `DURABLE_APPROVAL=false`);缺省的钥匙目录与 file 记忆根只进读数与起服 warn:接了 file 记忆引擎时**只给数据根挂卷不够** —— HOME 在 emptyDir / 容器可写层上时起得来,但 `/health.store.durability` 报 `ephemeral`(记忆随替换而去);要它报 `durable`,参与判定的根都落到卷上。逐根明细:`GET /v1/diagnostics/wiring` 的 `storeDurability.roots`。
|
|
61
63
|
> 🔴 **显式 `DB_BACKEND=mysql|pg` 而该引擎的坐标一个都没配 ⇒ 配置期拒启,与 `SESSION_BACKEND` 怎么写无关**(未设 / `auto` / `mysql` / `memory` 同一句拒句,`REQUIRE_PRINCIPAL=true` 亦然):写下 `DB_BACKEND=pg` 就是要这只持久引擎,没有坐标它开不了店。修前 `SESSION_BACKEND=auto`(「坐标不在就不探测」)下这一形静默跑内存、`/health` 照样 200、姿态位照报 `declared: "pg"`。拒句点名缺的坐标键名(`PG_HOST` / `PG_USER` / `PG_DATABASE`;`MYSQL_*` 同形),不回显任何值;出路:补齐坐标;或要无 SQL 的部署写 `DB_BACKEND=local`(单用户文件店)/ `DB_BACKEND=memory`。坐标齐、`DB_BACKEND=local|memory`、不写 `DB_BACKEND` 的形零变化。同族:`MEMORY_ENGINE_BACKEND=pg|mysql` 要绑的池没开而 `DB_BACKEND` 已点名该引擎时,拒句改点名真正开店的条件(持久会话后端 + 必需坐标键),不再说「要 `DB_BACKEND=…`」。
|
|
62
64
|
|
|
63
65
|
> 🔴 7.96.0 起根 `docker-compose.yml` 的 `REMOTE_EXEC`(执行车道)是**必填**:不设 ⇒ `docker compose config` 当场失败(此前静默起成一个没有手的 worker)。单人自用 `REMOTE_EXEC=host`(手落在 worker 容器里);多人 / 生产选隔离车道 `e2b`(配 `E2B_API_KEY`)或 `k8s`(`K8S_SANDBOX_IMAGE`、`K8S_NAMESPACE`〔没有内置缺省〕都是必需件,未设、空串或只含空白一律按缺 ⇒ 起服拒;`K8S_API_URL` 与 `K8S_TOKEN` 也要设;根 compose 透传前两名〔空串透传 = 按缺,要填〕,后两名要在 compose override 里加进服务的 `environment`,或改走随包 chart `deploy/sema-up`)。
|
|
@@ -345,7 +347,7 @@ MODEL_DEGRADE_ON=rate_limit,breaker_open # 可选,反应式触发器子集;词
|
|
|
345
347
|
- **成本天花板要有价才咬得住**:`MAX_TASK_COST_USD` / `MAX_PRINCIPAL_COST_USD` 量的是 `costUsd`,未定价的模型算不出成本 ⇒ 这两道闸**永不触发**。目录里一只带价模型都没有却配了天花板时,boot 会打一条 `cost_ceiling_without_pricing` 告警(不拒启);token 轴的 `MAX_TASK_TOKENS` 不受影响。
|
|
346
348
|
- 成本计量**自动开**:从 config 的 `model.cost`(per-1M 绝对 USD)注入 `pricing`,core 算出权威的整数 `costMicroUsd`(避免浮点累计误差)。`/metrics` 新增:`model_cost_micro_usd_total{model}`(覆盖所有 brain 调用=主任务+异步+委派子任务的总花费)、`brain_first_token_ms`(网关 hang 早警)、`brain_call_latency_ms`、`tool_calls_total{name,ok}`、`budget_exceeded_total{code}`、`cost_quota_rejected_total`、`degraded_total{reason}`(1.40 降级)。
|
|
347
349
|
- **近预算降级 vs 硬闸**:降级(`MODEL_DEGRADE_TO`,到 `atCostFraction` 切便宜模型)是**撑长**预算、任务仍完成(出口质量下降、发 `task.degraded` 事件可告警);硬闸(`maxCostUsd` 全额)仍在,切了便宜模型还超全额 → `limits.max_cost_exceeded` 停。
|
|
348
|
-
- **`METRICS_TOKEN`**(可选,只读):设了它,`GET /metrics`+`/metrics/summary` 接受**它或** `SERVICE_AUTH_TOKEN`。都没配时 `/metrics` 族只在 dev-open
|
|
350
|
+
- **`METRICS_TOKEN`**(可选,只读):设了它,`GET /metrics`+`/metrics/summary` 接受**它或** `SERVICE_AUTH_TOKEN`。都没配时 `/metrics` 族只在 dev-open 部署上、对不带主体头的请求免凭据(见 §1 dev-open 那一段:
|
|
349
351
|
装了中心鉴权桥、配了 `TRACE_TOKEN` 或开了 `REQUIRE_PRINCIPAL` 的部署上匿名 `401` —— 7.132.0 起,此前前两形照开;`/metrics/plan-cache` 按主体分键,匿名可读 = 名册外泄)。**全 fleet 设同一个值** → 管理端(sema-web,规划名 sema-admin)用**一个** token 拉所有 worker 的指标,**无需持有各 worker 的全权 `SERVICE_AUTH_TOKEN`**(不破坏 secret 边界)。即使外泄也只暴露指标(只读)。
|
|
350
352
|
- **`GET /metrics/summary`**(token-gated,同 `/metrics`):`/metrics` 的**精炼 JSON**——`{model, runsActive, tasks{status}, tokensTotal, costUsd, costUsdByModel, taskDurationAvgSec, brainFirstTokenAvgMs, brainCallAvgMs, cacheHitRateAvg, rateLimited, costQuotaRejected, budgetExceeded, limitCeilingAfterAnswer, degraded, cascade, verifications, toolErrors, httpErrorsByClass, httpErrorsByRoute}`(**7.126.0 起没有 `councilRuns`** —— 它数的 code-review 多镜头评审团随引擎 7.49.0 删掉团队运行时一并删除,Prometheus 的 `council_runs_total` / `council_tokens` 同删;按 v1 形解析这张表的看板升级前先把这一键改成可缺)(`httpErrorsByClass` / `httpErrorsByRoute` 自 **7.87.0**,additive:窗内 HTTP **失败**请求按状态码类聚合(键只有 `4xx` / `5xx`,2xx/3xx 不进;⚠️ `4xx` 含本仓给「客户端提前断连」铸的 `499`,SSE 长连上是常态)+ 失败最多的前 10 条 route 标签(`routeLabel` 低基数形,id 折成 `:id`,未命中路由表的落 `other`)—— 这两格是**不装 Prometheus 的部署**看见一场 404 风暴的唯一地方;两键**恒在场**,零失败时是 `{}`,不用缺席表示零)(`limitCeilingAfterAnswer` 自 7.71.0,按 `origin` 分桶的「答后撞顶」计数;与 `budgetExceeded` **总体不同** —— 前者每条引擎 run 都过,后者只由 HTTP 提交腿递增 —— 不要无条件相加)。给**轻量 fleet 看板**用(管理端 sema-web 的 fleet 页按 worker 拉、渲染卡片、按轮询算速率;**不用 Prometheus/Grafana**)。counter 是累计值、histogram 报均值。
|
|
351
353
|
- 预算闸是 core 强制的:`maxCostUsd` pre-call 估算(没花钱就拒)+ 流中途取消 + turn 边界(`limits.max_cost_exceeded`);`maxTokens` 超 → `limits.max_tokens_exceeded`(core 5.8.0 起 `budget.*` 前缀退役)。**review 网关**建议设 `MAX_TASK_COST_USD` 防单任务烧掉共享云 key。
|
|
@@ -484,7 +486,7 @@ MODEL_ID=<your-model-name> MODEL_CHEAP_ID=<your-cheap-model-name>
|
|
|
484
486
|
存量中心配置里的 `roles.team` / `roles.synthesize` 由 settings-schema 的一次性迁移搬走,side query 带 `modelRole` 表外词(含 `advisor`)⇒ **400**
|
|
485
487
|
`request.field_invalid`(不再回落主模型;带了 `model` 也一样拒)。要给委派子代配模型就绑 `subagent`,主任务绑 `default`。
|
|
486
488
|
- 调用方可在 `objective` 里 `@<模型名>` 选模型,**只认已配置的名单**(`MODEL_ID` / `MODEL_CHEAP_ID`,或目录条目)——注入不了 `baseUrl`/`apiKey`;无 `@` → 默认模型;`@` 点中一条已发布但本部署不可用的目录条目 ⇒ 400 `request.model_unavailable`。
|
|
487
|
-
- **`GET /v1/models`**(带 Bearer)→ `{models:[{name,id,provider,reasoning,vision,…}],default,defaultModel,droppedEntries}`,只含名字/能力、**不含密钥** —— 消费方(如 OA)拿它做 `@` 自动补全下拉的数据源;`reasoning` / `vision` 两列是**三态**:声明了给布尔,**未声明 = 键缺席**(7.131.0 起;env 部署不设 `MODEL_REASONING` / `MODEL_VISION` 就是未声明,没有 `true` 缺省 —— 需要思考的模型显式写 `MODEL_REASONING=true`,纯文本模型写 `MODEL_VISION=false`;缺席时引擎对图收、对思考档不发),契约 §A.1d;`droppedEntries`(7.123.0 起恒在场,零条 = `[]`)是本代目录里被读腿逐条丢掉的条目(下标 + 闭集原因词 + 可披露身份),契约 §A.1d。 7.126.0 起另有**可选**顶层键 `candidateRejected: { domains, at, source }`:最近一次配置候选被候选判官整拒时在场(`domains` = 被判官整拒点名的配置域名 —— 判形失败的域、本机 `config.d` 里读不出的文档所在的域、带事实的退役域,`source` = `local` 本机 `config.d` / `remote` 中心,`at` = 判下它的时刻)—— 在场就说明这份目录是回落的那一份(整份候选没收,候选里的模型一个都不在),真因域在 `domains` 里;后来的候选被判 clean,或配置源回到已应用的那一代(`config.d` 原样改回 / 中心退回那一版,日志 `config_source_back_to_applied`)即缺席;dry-run 姿势(web-admin 腿 compare-only)恒缺席(拒判只走日志)。**缺席不等于配置一定干净**(也可能是更早的 server)。只含域名 / 时刻 / 源形态,拒因句与文件路径只在引擎日志 `config_candidate_rejected` 里,契约 §A.1d。 7.133.0 起另有**恒在场**的顶层键 `modelPlane: { servedTable, catalog, refusalCode?, gap? }` —— 壳问 server,不猜:`servedTable`(`"env"` | `"catalog"`)= 此刻服务哪张模型表;`catalog`(`"absent"` | `"adopted"` | `"refused"`)= 最近一份目录候选在两道判官手里的结局(`refused` = 候选判官整拒,或模型面组拒;`adopted` 说的是「没有被判官整拒」,不是「最新候选已落地」,后者问 `/health` 的世代账;没有 LKG 时服务的是 env 表,有 LKG 时目录表仍在服,谁在服归 `servedTable`;逐条被拒的条目不算整拒);`refusalCode` / `gap` 是起服路由判官(`judgeServedModelRoute`)对当前 config 的判决,通过 ⇒ 两键缺席(进程起来了,正常缺席;自建装配 / 不拒启的入口可能在场)
|
|
489
|
+
- **`GET /v1/models`**(带 Bearer)→ `{models:[{name,id,provider,reasoning,vision,…}],default,defaultModel,droppedEntries}`,只含名字/能力、**不含密钥** —— 消费方(如 OA)拿它做 `@` 自动补全下拉的数据源;`reasoning` / `vision` 两列是**三态**:声明了给布尔,**未声明 = 键缺席**(7.131.0 起;env 部署不设 `MODEL_REASONING` / `MODEL_VISION` 就是未声明,没有 `true` 缺省 —— 需要思考的模型显式写 `MODEL_REASONING=true`,纯文本模型写 `MODEL_VISION=false`;缺席时引擎对图收、对思考档不发),契约 §A.1d;`droppedEntries`(7.123.0 起恒在场,零条 = `[]`)是本代目录里被读腿逐条丢掉的条目(下标 + 闭集原因词 + 可披露身份),契约 §A.1d。 7.126.0 起另有**可选**顶层键 `candidateRejected: { domains, at, source }`:最近一次配置候选被候选判官整拒时在场(`domains` = 被判官整拒点名的配置域名 —— 判形失败的域、本机 `config.d` 里读不出的文档所在的域、带事实的退役域,`source` = `local` 本机 `config.d` / `remote` 中心,`at` = 判下它的时刻)—— 在场就说明这份目录是回落的那一份(整份候选没收,候选里的模型一个都不在),真因域在 `domains` 里;后来的候选被判 clean,或配置源回到已应用的那一代(`config.d` 原样改回 / 中心退回那一版,日志 `config_source_back_to_applied`)即缺席;dry-run 姿势(web-admin 腿 compare-only)恒缺席(拒判只走日志)。**缺席不等于配置一定干净**(也可能是更早的 server)。只含域名 / 时刻 / 源形态,拒因句与文件路径只在引擎日志 `config_candidate_rejected` 里,契约 §A.1d。 7.133.0 起另有**恒在场**的顶层键 `modelPlane: { servedTable, catalog, refusalCode?, gap? }` —— 壳问 server,不猜:`servedTable`(`"env"` | `"catalog"`)= 此刻服务哪张模型表;`catalog`(`"absent"` | `"adopted"` | `"refused"`)= 最近一份目录候选在两道判官手里的结局(`refused` = 候选判官整拒,或模型面组拒;`adopted` 说的是「没有被判官整拒」,不是「最新候选已落地」,后者问 `/health` 的世代账;没有 LKG 时服务的是 env 表,有 LKG 时目录表仍在服,谁在服归 `servedTable`;逐条被拒的条目不算整拒);`refusalCode` / `gap` 是起服路由判官(`judgeServedModelRoute`)对当前 config 的判决,通过 ⇒ 两键缺席(进程起来了,正常缺席;自建装配 / 不拒启的入口可能在场),不带拒因句。新键追加在应答最末。 7.149.0 起行上另有**可选** `contextWindowSource`(`"declared"` | `"assumed"`,与同一行 `contextWindow` 同进退):`assumed` = 这只模型的窗没人声明(目录条目没写 `contextWindow`,部署也没设 `MODEL_CONTEXT_WINDOW`;cheap 槽另看 `MODEL_CHEAP_CONTEXT_WINDOW`),本服务按假定值(131072)算压缩触发点 —— 真实窗口更小的模型会先撞上限,更大的模型压缩会提前;起服 / 目录落地时这样的模型各一行 warn `model_context_window_assumed`(点名模型、假定值、去哪声明;每个模型每进程一次)。要消掉它就声明真实窗口,契约 §A.1d。引擎起来之前要同一格:见下面「起服前的模型面读数」。契约 §A.1d。 7.143.0 起 `modelPlane` 段末多一个条件键 `planeRefusalCode` —— 最新到达的那份目录候选被模型面组拒时在场、值 = 那一拒的码(`catalog:"refused"` 而它缺席 ⇔ 最新到达的候选被候选判官整拒,看 `candidateRejected`);`catalog` 的 `refused` 读同一份事实:更新的候选到了、没走到模型面那一判(被整拒,或过了判官却在换装时被拒)时不再挂着旧候选的拒。契约 §A.1d。 7.135.0 起另有**恒在场**的顶层键 `aliases: [{ name, atMentionable? }]` —— `model` 被认、却不是 `models` 行名的每一个词:`default` 别名(服务表有缺省模型才在)、按部署档位绑定铸出的档位词 / CC 别名 / `best`、以及被认的上游 id 写法;成员资格由受理口的判官逐词定(服务端不写词表)。判受理一条:`model` 的值是某一行或某一别名的 `name`(大小写敏感),且那一项的 `atMentionable` 不是 `false` ⇒ 过模型门;其余 ⇒ 400(不要再拿行的 `id` 推)。`atMentionable` 与行同一只判定、同一条在场律(`atMention` 不是 `all` 才出键)。零条 = `[]`,缺席 = 更早的 server(档位词 / `default` 判「说不清」)。契约 §A.1d。
|
|
488
490
|
- **起服前的模型面读数**(7.148.0 起):引擎起来之前要 `modelPlane` 同一格(这份配置会服务哪张表、目录候选的结局),跑包里的无监听探针 ——
|
|
489
491
|
```bash
|
|
490
492
|
node <@sema-agent/server 包根>/dist/model-plane-probe.js # 子路径 @sema-agent/server/model-plane-probe;env 与工作目录 = 将要起的那只引擎的
|
|
@@ -605,6 +607,7 @@ MODEL_CODE_ROLES=default,subagent # 不设=全中立;仅这些角色在「
|
|
|
605
607
|
MODEL_CASCADE_LADDER=deepseek-flash,deepseek-pro # 目录里的模型名,cheapest→strongest;不设=cascade 不可用
|
|
606
608
|
```
|
|
607
609
|
- 结果带 `cascadeOutcome:"passed"|"exhausted"` + `escalated`/`finalRung`/`attempts[]`。`/metrics` 加 `cascade_total{outcome}`。
|
|
610
|
+
- 梯子的每一级在引擎为它现铸的会话里冷跑,不在提交的会话上取会话;提交的会话只是梯子的宿主(停驻卡记在它名下)。与 `requireExistingSession:true` 同体照跑(7.148.0 起;更早的版本这一形每一级都被拒):会话不在 ⇒ 受理即 404 `resume.session_not_found`(不登记这只 id);受理之后、执行之前被删 ⇒ 执行起点 404 同码,一级都没起(带 run 店的部署 —— 三种出厂后端都带;嵌入装配不带 run 店时执行起点不判)。
|
|
608
611
|
- **每档用自己的上游 key**:从配置控制面模型的 `apiKeyEnv`(env 变量**名**,非密钥值)或 `sealedApiKey`(密文,见 §9.10)解析——同一网关下不同模型/账号各用各的 key,两者都没配的模型回落到网关 key(`MODEL_API_KEY`;sealed 开不了的模型**不**回落,见 §9.10)。`baseUrl` 仍由 brain 层统一持有(非目标)。启动日志 `perModelKeys=N` 报有几个模型带了自己的 key。
|
|
609
612
|
|
|
610
613
|
**嵌入形契约(1.309+;桌面宿主把引擎作为依赖内嵌启动的正门)**
|
|
@@ -620,14 +623,25 @@ MODEL_CASCADE_LADDER=deepseek-flash,deepseek-pro # 目录里的模型名,cheap
|
|
|
620
623
|
= 你的装配这只入口:`runs` 是它跑得了的车道闭集(文件或 env 声明了表外的一条 ⇒ 拒),`declares` 可选(文件与 env 都没点名时由入口声明,排在二者之后;文件在场即终结选择 —— 文件点的车道取不到坐标 ⇒ 拒,不由 env 的另一条或入口声明顶上;
|
|
621
624
|
`run-local` 声明 `host`);自建 HTTP 装配递包根导出的 `HTTP_SERVICE_LANE_ENTRY`(全部车道、不替部署声明);不走文件覆写的装配直接调同一份判据 `assertExecutionLaneInvariants(config)`。
|
|
622
625
|
`ctx` 的型 `ExecutionLaneComposeCtx` 也从包根导出(自己的装配里要写它的签名 / 抽 helper 时直接 import,不必手抄一份形)。
|
|
623
|
-
读口场景门 `scenarioGate` 是 `createHttpServer` 的必填件(7.131.0+):用包根导出的 `createScenarioGate({ config, scenarios, principalCaps, logger }, "peek")` 铸(与任务提交腿同一个工厂,型 `ScenarioGate` / `ScenarioGateLeg` / `ScenarioGateSources` 一并导出),没递就是 tsc
|
|
626
|
+
读口场景门 `scenarioGate` 是 `createHttpServer` 的必填件(7.131.0+):用包根导出的 `createScenarioGate({ config, scenarios, principalCaps, logger }, "peek")` 铸(与任务提交腿同一个工厂,型 `ScenarioGate` / `ScenarioGateLeg` / `ScenarioGateSources` 一并导出),没递就是 tsc 红;绕过类型(JS 嵌入)没递或形不对,`createHttpServer` 构造即拒并点名这一席。
|
|
624
627
|
**模型路由端点的拒启同理判在目录应用之后**:`judgeServedModelRoute(config, { envTableIsPlaceholder })`(包根导出,HTTP 服务与 `run-local` 调的就是它)只判将要服务的那张表(目录表或 env 表,句子随视图);
|
|
625
628
|
只调 `loadConfig()` 的装配不再在读配置那一拍拿到路由拒启 —— 在**自己的**配置源应用之后调它一次,有判决就拒启(`reason` 是给运维的原句)。严格名册布防(env 表是占位)传 `envTableIsPlaceholder: true`,没有名册门的装配传 `false`。
|
|
629
|
+
随包的可运行参照:`node scripts/embed-minimal.mjs`(在包目录下跑)按上面这条链装一台最小服务 —— 包根工厂、引擎的 `Runner` 与自写的一行 `resolveSpec` 凑齐 `createHttpServer` 的九个必填席,
|
|
630
|
+
host 车道、一次性数据根、内核分口的回环口,起到监听就打一行 `EMBED-MINIMAL ok port=<n>`;`--omit <席名>` 少给一席,说清 `createHttpServer` 是构造即拒(`refused`,退 2)还是照收(`accepted`,退 3)。
|
|
631
|
+
构造期判且拒句点名席名的是 `runnerFor` / `authorize` / `deploymentMods` / `peerDesk` / `scenarioGate` 五席(省掉 `config` 抛一句不点名的 `TypeError`);`runner` / `sideQuery` / `resolveSpec` 只有型是提示,绕过类型的嵌入省掉它们构造期照收。
|
|
626
632
|
- **库形嵌入的 caps `store` 位**(7.106.0 起;7.106.0 合并复审 X9 补一句):`createHttpServer` 的 `storePosture` dep **不传** ⇒ `GET /v1/capabilities` 的
|
|
627
633
|
`store` 取诚实下限 `{declared: <config.dbBackend>, backend: "memory", durability: "ephemeral"}`(`/health.store.durability` 同值),且**没有 `store.sql`**(即使递了引擎读口 `sqlEngine`、真有 SQL 后端 ——
|
|
628
634
|
7.105.0 上这类嵌入方的顶层 `sql` 是有值的)。要 caps 说真话就把你装出来的后端事实经 `storePosture` 递进来(形 = `src/store-posture.ts` 的 `StorePosture`;7.148.0 起多两格必填 `durability` 三态与逐根明细 `roots`,自己判不了介质就写 `"unknown"`,不要写 `"durable"`)。
|
|
629
|
-
-
|
|
635
|
+
- **库形嵌入的 SQL 后端不跑列册对账**:嵌入方的公开序列(`createStoreBackend()` → `ensureSchema()` → `runOneTimeMigrations()`)不跑列册对账(`assertSchemaMatchesCode` / `projectPendingShape`),
|
|
636
|
+
一次性迁移的守卫尾因此保留;本服务的起服序才跑对账(排在一次性迁移段之前)。
|
|
637
|
+
- **库形嵌入的一次性迁移段头**:SQL 后端的 `runOneTimeMigrations()` 先在 `replica_registration` 登记本进程一行(身份 · 能力名单 · 发布线),再读 `serving_requirement`(锁外一次、取到迁移锁之后再一次):
|
|
638
|
+
库上记着本构建没有的能力 ⇒ 拒 `config.serving_requirement_unmet`,一步迁移不跑。两张表由 `ensureSchema()` 建 —— 跳过它直接调 `runOneTimeMigrations()` 的嵌入方拒启(`table_absent`)。
|
|
639
|
+
- **`PORT=0` = 让 OS 分口,口由引擎自己报**:引擎自己绑内核分给它的口,`listening` 启动行(stdout 一行 JSON,行上 `level` 是 info)的 `port` 与 `/health.port` 报**实际绑定口**
|
|
630
640
|
(`PORT` 非 0 时两者与配置值相等)。要用 OS 分的口起引擎的宿主:子进程以 `PORT=0` 起,读 stdout 那一行 `listening` 的 `port`,再用 `/health` 的 `pid` / `dataRoot` 验答话的是自己起的那个进程;
|
|
641
|
+
- **`listening` 是启动协议行(7.150.0+)**:**不随 `LOG_LEVEL`** —— 档位只滤诊断行,`LOG_LEVEL=warn` / `error` 下这一行照出(仍经同一只出口脱敏;行上 `level` 照写 info,按 `level` 字段筛日志的管道照旧筛得掉它)。
|
|
642
|
+
宿主不必、也不该替部署把档位压回 info。同一行带两格绑址,一格一个事实:`bindHost` = 本进程**请求**绑的地址(`BIND_HOST` 经无鉴权自收窄之后的那一只 —— 不设 `BIND_HOST` 而写面无鉴权时是 `127.0.0.1`,另带 `bindHostNote`;请求的是全接口时是 `"0.0.0.0/::(all interfaces)"` 这句说明),
|
|
643
|
+
`boundAddress` = 内核**实际**绑上的地址(`::` / `0.0.0.0` / `127.0.0.1` / `::1` 原样;`BIND_HOST=localhost` 时是解析出的那一只)。自起引擎的宿主要认「这个口上的是不是我起的那只」:
|
|
644
|
+
读同一行的 `boundAddress` + `port` 去连,再以 `/health` 的 `pid` / `dataRoot` 验身份;别拿配置值去推实绑地址。行上的顶层键集登记在 wire 变更清单(`selfMinted.listeningLineKey`)。
|
|
631
645
|
**不要**先在外面挑一个空闲口、关掉、再交给子进程去绑 —— 关与子进程真正 `listen` 之间有窗,并行负载下别的进程能抢走这个号。`configHash` 仍按**配置值**铸(配置指纹不随 OS 分的口漂)。
|
|
632
646
|
- `/health` 身份字段承诺:`pid`(= 引擎进程)、`startedAt`(**7.67.0+**,= 引擎进程起点的 epoch ms,
|
|
633
647
|
一次铸)与 `dataRoot`(= 生效数据根,解析恒回退 `~/.ai-agent`,与 DB_BACKEND 无关)**恒在**(**7.148.0+**:配了服务凭据的引擎上,
|
|
@@ -644,35 +658,43 @@ MODEL_CASCADE_LADDER=deepseek-flash,deepseek-pro # 目录里的模型名,cheap
|
|
|
644
658
|
- 在而读不出(I/O 错;悬空符号链接 —— 链接在、目标不在)/ 不是 JSON 对象 / 缺 `highWater` / 有别的键 / `highWater` 不是纯 `x.y.z` ⇒ **读不出**:引擎起服拒,**不当缺席**;有别的键 = 更新的引擎写下的形(数据根比本构建新);
|
|
645
659
|
- 读得出 ⇒ 与本端版本比:`highWater` 高于本端 ⇒ 本端引擎起服拒 `config.schema_mismatch`(拒句点名这只文件、高水位与本构建版本;
|
|
646
660
|
包根导出的 `LocalDataRootSchemaMismatchError.findings` 里一段 `problem: "newer-engine"`,同一段必带 `engineHighWater: { highWater, engine }` —— 读数类型 `LocalDataRootMismatch` 是以 `problem` 为判别位的联合),不必先起一只注定被拒的引擎再解析 stderr。
|
|
647
|
-
-
|
|
648
|
-
|
|
649
|
-
|
|
661
|
+
- **写者只有引擎**。**判**在数据根**准入**里(7.149.0 起):只读,在引擎进程对这只根的**第一笔写之前**(HTTP 服务起服第 1 段、`run-local` 同位置;
|
|
662
|
+
嵌入方的公开序列 `createStoreBackend()` 在打开时当场取)—— 判拒 ⇒ 数据根**一个字节都不动**:不抬 marker,不建保管店钥匙、店目录、空账本,不取锁(拒句末行就说这一件)。
|
|
663
|
+
**抬**在打开数据根的那一刻(数据根锁在手 = 单写者):锁内先核准入判过的每一只输入都没动(物理数据根是同一只;marker、会话元数据边档的字节,存档目录的会话 id,收令牌欠账标记在不在,都与准入那一次观察相同)
|
|
664
|
+
—— 动了 = 准入与取锁之间另一只引擎碰过这只根(不写 marker 的更早版本也算)⇒ 拒,拒句点名动的是哪一只、出路是重起再判
|
|
665
|
+
(这一只拒发生时本进程已落下准入之后的正常写,拒句不声称数据根没动;它是准入唯一的例外,因为引擎内核把取锁与它自己的建店放在同一步);
|
|
666
|
+
核过 ⇒ 先抬再写 —— 本构建高于记录(或缺席)⇒ tmp + rename 原子替换(属主独占 `0600`,目录项也要证落盘;并发读者只见整份旧值或整份新值),相等不写(只证它在盘上:fsync 文件与目录)。所以店构造里的自修、
|
|
667
|
+
起服对账、一次性迁移与任何服务写都在抬之后:写到一半进程死了,水位已是本构建,比它旧的引擎重开被拒,本构建重开续跑。抬之后的拒(快照消化、一次性迁移的前提)⇒ 水位留在本构建。
|
|
650
668
|
本构建版本按**发布线**读:`x.y.z`,可带 `-预发布` / `+构建` 后缀,后缀只剥不比(`7.147.0-rc.1` 按 `7.147.0` 判与抬,marker 恒写纯三段);读不出(例:读不出 `package.json` 时的 `unknown`)⇒ 引擎拒开这只根(marker 不读不写)。
|
|
651
669
|
宿主只读:不写、不删、不改。写不进(含目录项证不了落盘)⇒ 不以这只根服务(起服拒;缺省推导的 local 在起服时为空的根上按既有降级臂退内存)。
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
670
|
+
**拒启 = 零写(7.149.0 起)**:7.148.x 及更早判在「打开数据根」这一步,判之前已落下新文件 —— `sealed-key/exec-*.json` 两只(模型钥匙一只、停驻行封签的钥匙目录里一只;
|
|
671
|
+
被拒的构建自铸的新密钥对)、`checkpoints/checkpoints.jsonl` 与 `background-agents/agents.jsonl` 两只 0 B 账本、十余只店目录、`prompt-epoch/` 店目录,配置根与数据根合一时还有
|
|
672
|
+
`config.migration.SS-M11.json`;严格边档读不出那一形连 marker 首写与本服务各店目录都在拒之前。用 7.148.x 或更早的版本被拒过的根,多出来的就是这些新文件与空目录
|
|
673
|
+
(**旧构建重开这只根**:按 `publicKeyId` 读不到新钥匙文件 ⇒ 当缺席、重铸自己的,不读错);7.149.0 起这些都在准入之后,被拒的起服一个都不落。
|
|
656
674
|
- SQL 后端不读不写它(滚动升级窗内合法混跑,另有列册对账)。只有**旧的那一端**是 7.147.0 及以后才守得住(更早的引擎不读它)。
|
|
657
675
|
回滚的唯一支持形 = 恢复升级前的数据根备份(marker 随备份回到旧值);同一台机器要并行跑多个引擎版本 ⇒ 各给一个数据根(`LOCAL_DATA_ROOT`)。不设绕过旋钮。
|
|
658
|
-
- **两条入口同一只判与抬(7.148.0+)**:`run-local` 与 HTTP 服务的 local 臂经同一只打开函数打开数据根 —— 7.147.x 及更早的 `run-local` 不读不写这只 marker
|
|
659
|
-
|
|
676
|
+
- **两条入口同一只判与抬(7.148.0+)**:`run-local` 与 HTTP 服务的 local 臂经同一只打开函数打开数据根 —— 7.147.x 及更早的 `run-local` 不读不写这只 marker,7.148.0 起它同样判、同样抬;
|
|
677
|
+
7.149.0 起两条入口都在各自第一笔写之前取同一只准入。
|
|
678
|
+
- **跳版拒启(准入的一格,抬之前)**:数据根里有「会话存档在、会话元数据格缺」的会话(7.148.0 之前的 `run-local` 建的会话就是这一形),本构建已不带把它们收进行的那条一次性迁移,
|
|
660
679
|
而 ① 打开之前的高水位早于 7.148.0 或缺席(带那条迁移的版本从没打开过这只根),或 ② 带那条迁移的版本打开过、没收完(数据根顶层还留着 `archive-token-adoption.pending`)⇒ 起服拒
|
|
661
680
|
`config.schema_mismatch`,`findings` 里一段 `problem: "skipped-required-migration"`,必带 `skippedMigration: { highWater, requiredSince, sessions }`(`highWater` 为 `null` = 没有 marker)。
|
|
662
|
-
哪一种由这两格推出,不另带位:`highWater` 为 `null` 或早于 `requiredSince` ⇒ ①;不早于 `requiredSince` ⇒ ②(拒句点名那只标记文件,说「没收完」)
|
|
681
|
+
哪一种由这两格推出,不另带位:`highWater` 为 `null` 或早于 `requiredSince` ⇒ ①;不早于 `requiredSince` ⇒ ②(拒句点名那只标记文件,说「没收完」)。拒在准入里、数据根零写、marker 不动,所以出路那一版起得来 ——
|
|
663
682
|
出路 = 先用一个仍带那条迁移、**不低于 `requiredSince` 且不低于 `highWater`** 的版本(服务或 `run-local`)对这只根**完整**起一次,再起本构建(低于 `highWater` 的会被「高水位高于本端」拒在门外)。
|
|
664
683
|
`archive-token-adoption.pending` 是引擎内部的欠账记录,不是契约(宿主不读不写):带那条迁移的版本在抬高水位之前写下它(这只根还欠、存档目录里有存档),
|
|
665
684
|
收齐并证明之后删掉 —— 第一次起动被打断(进程被杀、迁移写失败、嵌入方不走 `ensureSchema()`、会话目录列不出 ……)它就留着;收完之前更新的版本拒开。
|
|
666
|
-
标记在而根里已没有「存档在、格缺」的会话(收齐之后、删之前停了)⇒
|
|
685
|
+
标记在而根里已没有「存档在、格缺」的会话(收齐之后、删之前停了)⇒ 无事可收:打开它的版本在锁内、抬高水位之前删掉它、照起。
|
|
667
686
|
带那条迁移的版本不判这一道:它在本次起服里收(没收完的那一次留下标记,见上);起动时会话存档目录读不出 ⇒ 打开即拒,不抬高水位。
|
|
668
687
|
钉:`test/local-engine-high-water.test.ts` · `test/local-root-one-row-store.test.ts`(跳版拒启臂)· `test/archive-token-adoption-duty.test.ts`(收令牌欠账)。
|
|
688
|
+
- **已知限制:停-迁-起守卫只认登记过的副本**:守卫判「库上还有不知道这条迁移的副本在服务吗」读的是判活窗内心跳过的 run 与持有者的能力登记;早于 7.150.0 的副本不登记,空闲时(没有在跑的 run)看不见,
|
|
689
|
+
登记也不是围栏(停顿 / 断连后迟到的写挡不住)。停光旧副本是运维的第一道 —— 动作与顺序见随包 MIGRATION.md 当前版段头的「停-迁-起」一行,这里不另写一份。
|
|
669
690
|
- **已知限制:混版回退 —— 7.147.0 起写下的会话行,在 ≤7.146.x 的版本上续跑不保证**:7.147.0 起会话行上本服务记的十二格搬出了引擎的座表(SQL 后端住旁表 `session_ext`、`session_meta` 只剩引擎的列,一次性迁移 M41 停-迁-起;local 数据根另有上面的引擎版本高水位 marker)。
|
|
670
691
|
把部署回退到 ≤7.146.x、再续跑升级之后写下或改写过的会话,结果**不保证**:可能照常续到终答(一次续跑返回 200),也可能被拒 —— 两种都不在支持范围内,本服务不承诺其中任何一种,也不为它加兼容读法(一条旧版读法就是第二份读法)。
|
|
671
692
|
**出路**:回退前先排空 —— 让待续跑的停驻 run 先收完(完成或取消),再回退;随包的排空检查(`scripts/drain-check-local.mjs`〔`DB_BACKEND=local`〕/ `scripts/drain-check.mysql.sql` / `scripts/drain-check.pg.sql`,只读)是读出停驻行存量的工具;或不跨版回退。回退的唯一支持形是恢复升级前的数据根 / 库备份。
|
|
672
|
-
- **已知限制:`REMOTE_EXEC=host` 车道上请求不带 `cwd`
|
|
673
|
-
父 run
|
|
674
|
-
|
|
675
|
-
|
|
693
|
+
- **已知限制:`REMOTE_EXEC=host` 车道上请求不带 `cwd` 时,进程重起之后才被批准的停驻后台子代,续跑的命令落在已删目录**:请求不带 `cwd` 时,host 车道为这条任务铸一个一次性的工作区 `<HOST_WORKSPACE_BASE,缺省 os.tmpdir()>/sema-host-<id>-<rand>`,
|
|
694
|
+
由落在里面的执行环境(父 run 与按父的工作目录落根的委派子代)共同持有,最后一只放手的删它 —— 同一进程里父 run 先收了场、停驻在审批门上的后台子代之后被批准,续跑接着在那只目录里跑,子代最后一条腿收场时目录才删。
|
|
695
|
+
**进程退出时**(正常退 / 未捕获异常 / 有处理器的信号)退出兜底删掉本进程铸的全部临时目录,含仍被停驻子代持有的;重起之后再批准,续跑的命令落在已删目录上 —— 命令没有运行,引擎的拒句是 `…the task root directory no longer exists (or is no longer a directory): <路径>`,
|
|
696
|
+
而续跑提醒仍写成命令已执行(以拒句为准)。停驻中被取消 / 过期的后台子代持有的临时目录活到进程退出、由退出兜底删。
|
|
697
|
+
**出路**:提交时带 `cwd` —— 带了 `cwd` 的请求不走一次性工作区,没有这个删除(`sema` CLI 恒带;SDK 只有 launch 助手默认传 `process.cwd()`,直接调提交接口的要自己带)。
|
|
676
698
|
- `/health` 活体 store 探测(5.14.0,SQL 后端专属 additive):后台探针(`STORE_PROBE_INTERVAL_MS`,
|
|
677
699
|
默认 15000;0=关;负/非数启动响亮拒)缓存一份 DB 真往返结果,`storeProbe:{live,ageMs,error?}` 在
|
|
678
700
|
探针接线时恒在,顶层告警键 `storeLive:false` 只在死时出现。**status 保持 "ok"**(liveness≠readiness
|
|
@@ -732,6 +754,10 @@ MODEL_CASCADE_LADDER=deepseek-flash,deepseek-pro # 目录里的模型名,cheap
|
|
|
732
754
|
- 数据驻留提示:`DB_BACKEND=local` 下显式 `SESSION_BACKEND=memory` 会被收编为 local 文件店
|
|
733
755
|
(1.292+ 裸 boot 默认 local;/health 的 `sessionBackend` 报 `local`)——session 行落盘在
|
|
734
756
|
数据根下,清数据/隐私预期要按「sessions 在 engine-data 里」来做,不要按「只在内存」。
|
|
757
|
+
- **`DB_BACKEND=local` 没有会话同步的文件历史 blob 交换组**:local 的文件历史店没有 blob 的取 / 放面(只有 SQL 两后端有),所以 `PUT /v1/sessions/:id/sync/blobs/:hash` 与
|
|
758
|
+
`GET /v1/sessions/:id/sync/history/blobs/:hash` 两口恒拒,答 `501 capability.snapshot_store_required`(句子点名 `capabilities.sessionSyncFileHistory` 在这里是 `false`)—— 这是设计,不是故障。
|
|
759
|
+
同一位在能力位上先说了「不」:推送端读到 `capabilities.sessionSyncFileHistory` 为 `false` 就别推带引用 blob 的 `fileHistory`、别 PUT blob,只同步对话(对话那一半的清单 / 条目 / 导入照常;
|
|
760
|
+
`MIGRATION.md` 的 7.116.0 节写同一读法);SQL 后端上同一位为真。
|
|
735
761
|
- **后台子代的转录住哪、活多久(按车道)**:规则一条 —— 一只后台子代的持久记录在,它的转录就是宿主会话店委派分区里的一只分区会话:活过重启、随记录同亡;
|
|
736
762
|
进程内短 TTL 店只装没有持久记录指着的会话(普通子任务、前台子代)。`subagent_type: "fork"` 的后台子代不在这条规则里(各车道同):它的转录是从父会话分叉出来、
|
|
737
763
|
住宿主会话店的一只普通会话,记录被收割时保留(归会话留存管),也不能经 `SendMessage` 复活(工具结果是错误,`revive.fork_unsupported`)—— 下表的居所与续话两列不适用于它。
|
|
@@ -756,7 +782,7 @@ MODEL_CASCADE_LADDER=deepseek-flash,deepseek-pro # 目录里的模型名,cheap
|
|
|
756
782
|
- **会话的行事实只住在数据根的 `session-incarnations.json`**(每只会话一格:属主 / 化身 / 执行放置 / 建档时刻 / fork 谱系);`sessions/*.jsonl` 是匿名的对话内容。
|
|
757
783
|
备份 / 迁数据根时两样一起搬;更早版本写下的带属主戳的存档由起服一次性迁移改写(改不了的点名,fork 与改日志推送答 409 `conflict.session_archive_stamped`;会话同步导入的第一阶段对 fork / stale 且没带同意的推送也直接答它,7.147.0 起干跑 `POST …/sync/plan` 对这两形同样),快照目录 `session-archive-m33/` 非空且消化不了 ⇒ 拒启(MIGRATION 写了出路)。
|
|
758
784
|
`session-incarnations.json` 本构建读不出(更新的引擎写过、格里多出不认得的键;或文件坏了 / 读不了)⇒ 起服拒 `config.schema_mismatch`(与 SQL 后端列册对账同一个码,拒句点名文件与键;
|
|
759
|
-
|
|
785
|
+
7.149.0 起这一判在数据根准入里,先于任何写 —— 拒启零写;出路 = 部署写下它的那一版,或恢复升级前的数据根备份;读不了 ⇒ 修好权限 / 盘再起);起服之后才读不出(违规共享的数据根上另一只引擎写了它)⇒ 同码拒,
|
|
760
786
|
形读不出则那只边档的每一读每一写拒到重启,盘上字节不被盖掉。
|
|
761
787
|
- 多实例边界:同一数据根同时只允许一个实例(BootLock 独占,第二个进程拒启;死主自愈含 SIGKILL)。
|
|
762
788
|
core 5.54.0 起拒启错误带**可分派 code**(`FileStoreLockError`,message 点名占用方 pid),运维按码
|
|
@@ -793,7 +819,7 @@ MODEL_CASCADE_LADDER=deepseek-flash,deepseek-pro # 目录里的模型名,cheap
|
|
|
793
819
|
同一只等待腿 —— **不为前台形留第二套语义**。前台形要「立刻告诉我谁占着」就设 `STORE_LOCK_WAIT_MS=0`,
|
|
794
820
|
那是文档化的通道,而不是两条路各有一套默认。
|
|
795
821
|
🔴 **7.148.0 起两条路是同一只打开函数、同一份装配**:`run-local` 不再自己构造引擎的文件后端、不再用引擎的裸会话店 ——
|
|
796
|
-
它与 HTTP 服务的 local
|
|
822
|
+
它与 HTTP 服务的 local 臂一样:数据根准入(只读,第一笔写之前)→ 取锁 → 引擎版本高水位(核与抬)→ 本服务的店 → 起服对账 → 一次性迁移 → 才读会话。
|
|
797
823
|
于是同一个数据根上**只有一只会话行店**:同一只会话在两条入口上是同一位住客(会话元数据边档那一格的化身),
|
|
798
824
|
一条入口上落下的记忆记录(`memory.capture:"off"` 的采集 opt-out、外部内容带来的污染标记)在另一条入口上照样生效;
|
|
799
825
|
`run-local` 新建的会话当场有会话元数据格(建档时刻真值;HTTP 服务列它时不再补铸另一只住客令牌)。
|
|
@@ -832,6 +858,14 @@ MODEL_CASCADE_LADDER=deepseek-flash,deepseek-pro # 目录里的模型名,cheap
|
|
|
832
858
|
`run.json` / `events.jsonl` / claim 文件与每会话块账本 `run-blobs/<会话>.jsonl` 的读取。目录里本来就没有的东西(`.DS_Store` 一类杂物、
|
|
833
859
|
尚未落盘的目录)照旧跳过 —— 拒的是「读不出来」,不是「没有」。
|
|
834
860
|
⚠️ 射程**不含**「文件读得出、里面有一条坏记录」:那一形在两档下都是跳过 + 披露 + 计数(下一条)。
|
|
861
|
+
- **`LOCAL_STORE_DURABILITY=ephemeral`(闭集只有这一个词,缺席 = 店型的设计声明;7.149.0 起)—— 运维声明 local 店易失**:
|
|
862
|
+
local 店对引擎的声明(会话店顶层、检查点店「两半」)只有一只读者:写了这一词 ⇒ 两半都声明 `process-local`;没写而店落在**调用方自己的盘**上
|
|
863
|
+
(`REMOTE_EXEC=host` ∧ 没开 `REQUIRE_PRINCIPAL`:壳自起的本机引擎、开发机)且数据根介质判 `ephemeral` ⇒ 同样 `process-local`;其余 ⇒ 设计声明 `durable`(活过进程重启)。
|
|
864
|
+
起服布线审计拒 `config.store_not_durable` 的条件是「声明 `durable` ∧ 会话店的介质(数据根)判 `ephemeral`」(容器可写层 overlay / tmpfs / k8s emptyDir)—— 声明是 `process-local` 就不拒。
|
|
865
|
+
**后果**:店里的会话、停驻审批与记忆不随容器 / Pod 替换保留(进程重启照旧活过);引擎静态装配读 `session.store = process_local`(接了检查点店〔`DURABLE_APPROVAL`〕时 `parkLane.checkpointDurability` 同读);起服一行 `wiring_static_warning`
|
|
866
|
+
写明依据、介质判定与挂卷出路。`/health.store.durability` 与 `GET /v1/capabilities` 的 `store.durability` 照旧按介质如实报 —— 挂了卷还写这一词,读面报 `durable`、声明照降。
|
|
867
|
+
别的任何值(`true` / `durable` / 大小写不同 …)拒启:声明只有「我就是易失」这一句。SQL / memory 后端不读它。`REMOTE_EXEC=device` 的部署要 SQL 后端(既有不变量),与本键无关。
|
|
868
|
+
🔴 **部署者自己设**:壳 / 编排器 / 安装器不替用户写这只键(替用户写 = 替他放弃这份承诺);壳自起的本机引擎不需要它。
|
|
835
869
|
- **local 车道 JSONL 店的坏记录(7.104.0 起)**:`DB_BACKEND=local` 的八本 JSONL 账(run 店四面、续跑锚、
|
|
836
870
|
发文件账本、流内审批 ask 账本、直连门 nonce 账、「本会话不再询问」豁免账、规则审批记录 / 导入票两本)重放时,
|
|
837
871
|
**中间**一条记录读不出(一行 `42`、缺本店必填键的对象、半截 JSON)不再静默:每条打一行 warn(事件名
|
|
@@ -1001,12 +1035,15 @@ FLEET_ADVERTISE_ADDRESS=http://<本机可达IP>:8090 # 可选:设了才启公
|
|
|
1001
1035
|
# FLEET_GENERATION=7 # 7.121.0:fleet 成员的代际(配置渲染器写,手配只在你自己就是渲染器时)。规范十进制串(空串 / 前导零 /
|
|
1002
1036
|
# 符号 / 空白拒启);缺席 = 非 fleet 成员(单机形:不续服务租约、不受围栏)。回声到心跳与 /health 的
|
|
1003
1037
|
# generation(连同 leaseState / leaseUntil);排空口按它比 expectedGeneration。
|
|
1004
|
-
#
|
|
1005
|
-
#
|
|
1038
|
+
# 成员起步即推定在服务租约围栏内:还没听到中心的任何声明 ⇒ leaseState expired,T_max 的钟从本进程起点走,
|
|
1039
|
+
# 推定期不续租。中心在心跳答复里宣告 capabilities.servingLease ⇒ 续租(钟起点不动);声明里不带位 ⇒
|
|
1040
|
+
# leaseState none,零续租零 503;位撤掉再宣告不重置 T_max 的钟(最后一次授予的到期 / 围栏在本进程第一次
|
|
1041
|
+
# 生效的时刻照算)。心跳 401 / 404 / 400 / 不可达 / 答复不是声明 = 没听到,推定照旧。
|
|
1006
1042
|
# 🔴 设了它就必须配齐中心三件(URL + 凭证 + SEMA_WEB_ADMIN_WORKER)与 FLEET_ADVERTISE_ADDRESS
|
|
1007
1043
|
# (不公告就听不到能力位),缺一 ⇒ 起服拒启 config.fleet_member_unfenced —— 成员不许悄悄脱离围栏。
|
|
1008
1044
|
# 续租打 POST /api/fleet/live/serving-lease(契约 FLEET_PATHS.servingLease;活性基址见 SEMA_WEB_ADMIN_LIVE_URL)。
|
|
1009
|
-
# 心跳答复体读不出 / 不是 JSON 对象 = 没有能力读数(
|
|
1045
|
+
# 心跳答复体读不出 / 不是 JSON 对象 / 没有 capabilities 键 = 没有能力读数(推定、位与租约钟原样,
|
|
1046
|
+
# warn fleet_announce_reply_unreadable)。只有显式的 capabilities 对象是中心的声明。
|
|
1010
1047
|
# FLEET_SCOPE=acme # 7.121.0:本引擎所在的**租户 scope**(配置渲染器对每台受管引擎写,缺省 scope 也写 = 它的 per-worker 令牌绑的 scope)。缺席 =
|
|
1011
1048
|
# 缺省 scope global;在场必须是 scope id 形(小写字母 / 数字 / 内部连字符,1–64;空串拒启
|
|
1012
1049
|
# config.fleet_scope_invalid)。与 FLEET_GENERATION 不联动。只进排空口的身份比对:请求的 scope 与它比,
|
|
@@ -1014,7 +1051,8 @@ FLEET_ADVERTISE_ADDRESS=http://<本机可达IP>:8090 # 可选:设了才启公
|
|
|
1014
1051
|
# FLEET_LEASE_OUTAGE_MAX_MS=86400000 # 7.121.0:一台实例**活着而不服务的最长时长**(缺省 24 h;< 60000 / 0 / 非整数拒启)。两处读它:
|
|
1015
1052
|
# ① 服务租约中心不可达的容忍上限 —— 租约过期(中心不可达 / 答 unknown)后照常服务,过期满这么久 ⇒
|
|
1016
1053
|
# 新工作 503 state.lease_expired(Retry-After 60;取消 / HITL 应答 / 续跑 / 读面照放行,在飞不动,
|
|
1017
|
-
# /readyz 不翻)
|
|
1054
|
+
# /readyz 不翻);中心恢复授予即恢复。从没被授予过的,从围栏在本进程生效那一刻起算 —— 一直没听到
|
|
1055
|
+
# 中心的成员(心跳不通 / 令牌被拒 / 答复不是声明)就是本进程起点,每个进程各一段(重启重计)。
|
|
1018
1056
|
# ② 7.122.0 起排空口 POST /v1/admin/drain 的期限上界:deadlineAt 离此刻超过它 ⇒ 400
|
|
1019
1057
|
# request.field_invalid(非 fleet 成员同样生效 —— 这一席无条件解析)。
|
|
1020
1058
|
# 中心以正面证据拒(被取代 / 已退役)不受它管:当拍排空、到期自停,数据根记一只
|
|
@@ -1074,19 +1112,24 @@ QUESTION_MAX_TOTAL_PER_RUN=20
|
|
|
1074
1112
|
QUESTION_TTL_MS=300000
|
|
1075
1113
|
```
|
|
1076
1114
|
- 三个值都有出厂缺省(即上面写的值),**不设=行为不变**;越界值**启动期响亮拒**(不静默夹取)。
|
|
1077
|
-
- 窗用尽 / 到期
|
|
1115
|
+
- 窗用尽 / 到期 **不是替人作答**:服务只报「这一问没拿到答」,落点只看**这一次投递有没有经这条腿的活面(直写 SSE)把卡呈出**(问被上游门放行、到达投递之后;`permissionMode: "dontAsk"` 的问在引擎模式表就被拒、到不了投递,见下面「`permissionMode: "dontAsk"`」一条;7.150.0 起;此前按「判决那一刻这条腿够不够得着人」分形:后台腿与连着的流上自答续跑,只有判决时够不着人的腿停驻):
|
|
1116
|
+
- **呈出过而窗走完没人答**(连着的 `/v1/tasks/stream`;`x-detach-on-disconnect` 流里卡出现时还连着、随后才断开):这是一次失败的问,**不停驻**(卡已经摆到连着的人面前过,同一问不再交给第二个决断者),run 接着跑;模型读到的工具结果说明「卡在活的流上呈出过、窗内无人答」(引本服务的原话)—— 连着的 `/v1/tasks/stream`(posture interactive,前提见下面那条「声明 interactive」)上是 coded 失败 `question.human_channel_failed`,其余(`x-detach-on-disconnect` 流、不声明 interactive 的连着的流)是「按你的判断继续」的续跑卡(`reason: callback_failed`);同步委派子代随父腿。durable 与无 durable 的部署同读。
|
|
1117
|
+
- **没呈出**(卡只进了 run 账本 —— 后台腿 `/v1/runs`、续跑腿、detach 流断开之后才问;没有问题上下文的腿;开帧投不出;撞并发帽 / 总量帽;窗先走完而开帧还悬着):**durable 部署**(`DURABLE_APPROVAL=true` + checkpoint 能力的 backend)把 run **停驻**(`done(suspended)` + `pendingGate`),运维随后经 `POST /v1/approvals/:sessionId/decide` 带 `answer` 补答;**无 durable 的部署**则让模型被告知"没人在"后按自己的判断继续(`declined_unavailable`;run 永不挂死)。后台腿与续跑腿是先投卡、窗内 `POST /v1/questions/:id/respond` 可答、窗走完才停驻;没有问题上下文的腿、投不出、撞帽当场停驻、不等窗。
|
|
1118
|
+
- 例外:run 被取消或非 detach 腿断连 ⇒ 腿中止,不停驻;verify / cascade 的续跑腿没有问题上下文(当场停驻、不投卡);同步委派子代没有停驻车道 —— 连着的流上随父腿读同一张卡(上面第一条),后台腿上窗到期子代收到引擎的拒、接着跑,不停驻。
|
|
1119
|
+
- **`permissionMode: "dontAsk"`**(上面各形之外 —— 问在引擎模式表就被拒,到不了投递):durable 部署上 ⇒ 零 `question` 行、零卡、不停驻,工具未执行,模型读到 dontAsk 拒句(7.149.x:卡照投、窗内可答);非 durable 部署今天卡照送,随引擎让 live 形也铸 ask 翻面后同答「拒」。要人答问换 `permissionMode: "default"` / `"acceptEdits"`;不要问题工具 ⇒ `interactiveTools: false`。
|
|
1120
|
+
- 不想让问题挡住 run(无人值守的提交方)⇒ 在请求体带 `interactiveTools: false`:这条 run 不挂 AskUserQuestion,模型根本不问(比「等一个窗再猜」更直接);部署级不要任何停驻 ⇒ `DURABLE_APPROVAL=false`。
|
|
1078
1121
|
- 想让人有更长时间答就调大 `QUESTION_TTL_MS`;想让 agent 少打扰人就调小 `QUESTION_MAX_TOTAL_PER_RUN`。
|
|
1079
1122
|
- **问题卡随 run 账本回放**:`question` / `question_complete` 在每条腿都落进 run 账本(`/v1/tasks/stream` 腿在有 durable run 行时先落账、再写 SSE;`/v1/runs` 腿本来就只有账本)。
|
|
1080
1123
|
页面重载 / 重连后,经 `GET /v1/runs/:id/events` 取回仍在等的卡(待答 = 没有同 `questionId` 的 `question_complete` 且 `expiresAtMs` 未到)。
|
|
1081
1124
|
**答题口不变**:`POST /v1/questions/:id/respond` 只在受理这一问的副本内、窗(`QUESTION_TTL_MS`)内有效;没有「列出待答问题」的读口。无 durable run 行的部署没有账本,仍只有 live 帧。
|
|
1082
|
-
- 🔴 **`/v1/tasks/stream` 的开帧投递失败是响亮的(
|
|
1125
|
+
- 🔴 **`/v1/tasks/stream` 的开帧投递失败是响亮的(逐腿,不是部署级;开帧投不出这一形只对无 durable 的部署起作用 —— durable 部署上没呈出的问停驻,见上;卡在活的流上呈出过、窗走完那一形两种部署同读,落失败臂:posture interactive 的流上是 coded `question.human_channel_failed`,其余是 `callback_failed` 自答指令卡)**:这条腿(**且仅这条腿**)向引擎
|
|
1083
1126
|
声明 `interactionPosture: "interactive"` —— 人就在这条 SSE 上,一次开帧投递失败(壳断连/流被撕裂)
|
|
1084
1127
|
不再合成「没有人可问,你自己判」的续跑卡,而是让那次工具调用返回 coded 失败
|
|
1085
1128
|
`question.human_unavailable`。**其余每一条腿行为字节不变**:`/v1/tasks`(非流)、`/v1/runs`、A2A、
|
|
1086
1129
|
resume、cron / wake、`verify` / `cascade` 一律**不声明** ⇒ 续跑 + 披露卡 + 既有计数照旧
|
|
1087
1130
|
(那些腿本来就没人可问,拒掉它们只会把无人值守任务打死)。
|
|
1088
1131
|
声明本身有前提:活体问答面与活体审批席**两个席位都在**、且调用方没有把 `interactiveTools` 声明成
|
|
1089
|
-
`false` —— 缺任何一项就不声明(引擎的 posture 门是**拒整条腿**的,声明一个够不着人的姿态会让每个
|
|
1132
|
+
`false`、没有把这条 run 的 `approvalReach` 声明成 `"none"` —— 缺任何一项就不声明(引擎的 posture 门是**拒整条腿**的,声明一个够不着人的姿态会让每个
|
|
1090
1133
|
任务在准备阶段当场失败)。**发了 `x-detach-on-disconnect: true` 的请求同样不声明** —— 那个头逐字是
|
|
1091
1134
|
「我可能随时走开,别杀 run」,正是 interactive 的反面。
|
|
1092
1135
|
⚠️ **射程如实**:引擎的姿态解析是三腿的,**从这条腿委派出去的子代会继承根腿的姿态**(引擎的设计,
|
|
@@ -1115,7 +1158,7 @@ QUESTION_TTL_MS=300000
|
|
|
1115
1158
|
|
|
1116
1159
|
```bash
|
|
1117
1160
|
# 协议总开关。默认 true;显式 =false 是**本协议面**的干净还原键(不发 approval_request / approval_complete、改发旧族帧、不落 ask 行、
|
|
1118
|
-
# 不起收敛器腿)。⚠️ 它**不**回滚 7.34.0
|
|
1161
|
+
# 不起收敛器腿)。⚠️ 它**不**回滚 7.34.0 的「窗到期走 park」语义——那一条的
|
|
1119
1162
|
# 回滚键是下面的 UNATTENDED_APPROVAL_POLICY=deny(两根旋钮正交,别当一根用);它也**不**再回滚窗长
|
|
1120
1163
|
# (窗是活卡件不是协议件,见下一键——缺省值与旧硬编码窗同为 300000,没配过就仍然字节不变)
|
|
1121
1164
|
STREAM_APPROVAL_ENABLED=true
|
|
@@ -1234,6 +1277,8 @@ UNATTENDED_APPROVAL_POLICY=park
|
|
|
1234
1277
|
```
|
|
1235
1278
|
- 管的是**同一个问题**:一只需要人批的 ask 到了,而此刻**没有任何人**能答(窗走完没人点、连接全断、
|
|
1236
1279
|
运维把窗关成 0、bg/headless 腿本来就没有活流、未决卡撞上准入帽)。
|
|
1280
|
+
- 只管**审批**问;AskUserQuestion 的问不读本旋钮 —— 落点只看卡有没有经这条腿的活面呈出(没呈出的 durable 部署停驻、呈出过而窗走完按失败结算,见上「AskUserQuestion 的裁量窗」;`deny` 部署也一样),
|
|
1281
|
+
不想让问题挡住 run 用请求体 `interactiveTools: false`(见上「AskUserQuestion 的裁量窗」)。
|
|
1237
1282
|
- `park`(缺省)⇒ 服务报「此刻无人可答」,**durable 部署**(`DURABLE_APPROVAL=true` + checkpoint 能力的
|
|
1238
1283
|
backend)把 run **挂起候人**(`done(suspended)` + `pendingGate`),人回来经审批面补批就接着跑;
|
|
1239
1284
|
没有 park 设施的部署由引擎 fail-closed 拒绝并告诉模型「没有可停靠的 durable 审批门」。
|
|
@@ -1254,9 +1299,9 @@ UNATTENDED_APPROVAL_POLICY=park
|
|
|
1254
1299
|
- 纯部署级:**不看**客户端的任何表态/权限模式。协调器整体关掉(`TOOL_APPROVAL_ENABLED` 关)时这个旋钮
|
|
1255
1300
|
没有施加对象。`APPROVAL_REQUIRE` 名单只决定「这只工具要不要审批」,与本旋钮无关;协调器在场时,名单工具的
|
|
1256
1301
|
审批与其余 ask 走同一条路、同一个政策(`deny` 部署上同样当场拒)。
|
|
1257
|
-
- 🔴 **与 `STREAM_APPROVAL_ENABLED` 正交**:把流内协议开关关掉**不会**回滚
|
|
1302
|
+
- 🔴 **与 `STREAM_APPROVAL_ENABLED` 正交**:把流内协议开关关掉**不会**回滚 7.34.0 的「窗到期走 park」—— 它只是不发
|
|
1258
1303
|
`approval_request`、不落 ask 行、不起收敛器腿,活卡窗到期照样走 park(park 的承载是引擎的 checkpoint,
|
|
1259
|
-
不是 server 的 ask 行,「有 durable
|
|
1304
|
+
不是 server 的 ask 行,「有 durable 设施但没开协议」正是「窗到期走 park」要救的那类部署)。要回到旧的「窗满即拒」
|
|
1260
1305
|
就配 `UNATTENDED_APPROVAL_POLICY=deny`。
|
|
1261
1306
|
|
|
1262
1307
|
**「本会话不再询问」对引擎的问也生效(7.106.0 起)**
|
|
@@ -1274,7 +1319,9 @@ UNATTENDED_APPROVAL_POLICY=park
|
|
|
1274
1319
|
实例上(local 车道换机 / 换数据根)⇒ 名单的问再问一次 —— 方向是多问一次,不是静默放行。名单靠别名命中的调用(嵌入方给工具挂了 `Bash` 别名)
|
|
1275
1320
|
按调用的 wire 名记、按 wire 名读;一张卡上同时有名单的问与别人的问(人写的 ask 规则、强制位、读会话目录外 ……)⇒ 那张卡的「本会话放行」不记。
|
|
1276
1321
|
- 已知边界(两只家并存):活卡上对**引擎的问**点的「本会话放行」记在审批席的进程内表(按副本、随进程;能力桶:`Write` 盖 `Edit` / `NotebookEdit`),**不在**上面那只豁免店里 ——
|
|
1277
|
-
`GET /v1/approvals/:sessionId/exemptions` 列不出它、`DELETE …/exemptions/:toolName` 撤不到它(回 `revoked:true` 只说耐久那一行没了)
|
|
1322
|
+
`GET /v1/approvals/:sessionId/exemptions` 列不出它、`DELETE …/exemptions/:toolName` 撤不到它(回 `revoked:true` 只说耐久那一行没了)、删会话与留存清理也清不掉它的表项,换副本 / 重启即失。
|
|
1323
|
+
它**绑会话这一位住客**(7.149.0 起):键含这条腿的会话此刻的住客令牌,所以会话删了(`DELETE /v1/sessions/:id`、留存清理、别的副本)再用同一个 id 重新登记之后,
|
|
1324
|
+
上一位住客点的放行读不中,新一位住客的第一次调用照样出卡;读不出住客令牌的腿(会话店不带执行席 —— 引擎缺省的内存会话店;SQL 与 local 后端恒带)上卡面带 `rememberRefused`(壳不渲「本会话放行」;7.150.0 起,与回执同一只判官),照样点了也只放行这一次(回执 `rememberApplied:false`,日志一行 `session_grant_refused_occupant_unreadable`)。
|
|
1278
1325
|
名单的问点的「本会话放行」与停驻之后 `remember:"session"` 记的放行在豁免店里,列表与撤销都管。读豁免店的两道策略层门(`APPROVAL_REQUIRE` 名单门、`run_workflow` 问句门)经同一只读口:
|
|
1279
1326
|
两秒内读不到(店慢 / 店坏)⇒ 照问;店答的不是布尔真值也不放行。命中时的审计行是 `approval_exempted`(字段 `seat`:`deployment_list` / `workflow_gate`;`run_workflow` 问句此前的事件名 `workflow_gate_exempted` 已退役,按它告警的运维改读这一条)。
|
|
1280
1327
|
|
|
@@ -1390,7 +1437,7 @@ READ_DENY_PATTERNS='[{"pattern":"**/secrets/**"},{"pattern":".ssh","caseSensitiv
|
|
|
1390
1437
|
升级后**读得到**根内的 `.npmrc` / `.ssh` / `.aws` / `.claude/settings.json` 这类名字,且整个递归读族
|
|
1391
1438
|
零卡执行。**要老姿态就显式写** `READ_DENY_BUILTIN_TIERS=credentials,browser,wallet,agent-config`。`open` 与这张表仍是**两个并列机制**:
|
|
1392
1439
|
`open` 放开的是「工作区外」那道围栏,内建表判的是名字。
|
|
1393
|
-
🔴 **7.106.0(core 7.34.0
|
|
1440
|
+
🔴 **7.106.0(core 7.34.0)再翻一次**:未设 = **`credentials` + 家目录锚定的 `agent-config` 两档在岗**(`browser` / `wallet` /
|
|
1394
1441
|
`shell-history` 仍是选装;显式 `READ_DENY_BUILTIN_TIERS=none` 仍是空姿态)⇒ 未配置的机器升级后**读不到**根内的 `.npmrc` / `.ssh` / `.aws` 这类名字
|
|
1395
1442
|
(每种模式都拒、不出卡)。agent-config 的十五行改写成 `~/…`(`~/.claude/settings.json`、`~/.sema/settings.json` …)、只在执行环境的 home 正下方
|
|
1396
1443
|
命中 —— 工作区里的 `.claude/settings.json` 不再是内建行;🔴 `READ_DENY_BUILTIN_EXCLUDE` 里写旧行名(`.claude/settings.json`)的部署**起服拒**
|
|
@@ -1597,11 +1644,11 @@ TASK_WRITE_FACE_ESCALATION=allow # 词表 allow|refuse;坏词启动期响亮
|
|
|
1597
1644
|
续跑重放升级前存下的请求体时与 `mcpServers[].toolAxes` 同一只一次性迁移 M19:窗内判官判不过的那一格按 7.131.x 的 A2A 读法重读一次(未知成员剔、三轴留,产物再过同一只判官),
|
|
1598
1645
|
对端照挂、一行运维 warn `a2a_tool_axes_read_as_before_upgrade`(`peer` / `migration` / `problem` / `note`);已知轴写坏(出词表、`egress` 非布尔、某只 skill 的值不是对象、
|
|
1599
1646
|
整份不是对象)的对端 7.131.x 当时就整条丢了,重读照旧整条不挂(`a2a_injection_dropped` 点名);窗关之后回到上面的读法(整条不挂)。
|
|
1600
|
-
- **请求体自带的 `mcpServers[].transport.env` / `transport.headers`**(「名 → 串」记录,与 `a2aPeers[].headers`
|
|
1601
|
-
整只不是纯数据 ⇒ 新提交 `400 request.field_invalid` 点名第一处(
|
|
1602
|
-
续跑重放存量请求体时,按 7.131.x 的读法会交不出去的成员 ——
|
|
1647
|
+
- **请求体自带的 `mcpServers[].transport.env` / `transport.headers`**(「名 → 串」记录,与 `a2aPeers[].headers` 同一只读法、同一张保留成员名表):名叫保留名(`__proto__` / `constructor` / `prototype`,大小写敏感)的成员、值不是串的成员、
|
|
1648
|
+
整只不是纯数据 ⇒ 新提交 `400 request.field_invalid` 点名第一处(保留名成员点名成员级路径如 `…headers.constructor`;值不是串 / 整只读不成点名那个键,原因句点名成员)。
|
|
1649
|
+
续跑重放存量请求体时,按 7.131.x 的读法会交不出去的成员 —— 保留名的成员、有值不是串的成员的整键、`transport.args` / `transport.principalHeader` —— 在本部署兑现请求 MCP 时**拒续跑**(名字被部署占住的条目不算:它整条输给部署):
|
|
1603
1650
|
`409 resume_blocked_by_policy`(`blockedBy: "request.field_invalid"`,`field` = 第一处成员坐标如 `mcpServers[1].transport.headers`;句子列出全部坐标,只给键名、不回显值),卡 / 任务仍待决、行不动;
|
|
1604
|
-
A2A 对端 `headers`
|
|
1651
|
+
A2A 对端 `headers` 在保留名的成员上同拒(`a2aPeers[i].headers.<保留名>`,本部署兑现请求 A2A 时);`headers` 里有值不是串的成员 ⇒ 那一条对端整条不挂(`a2a_injection_dropped` 点名)、任务照跑 —— 整条不进不在拒的射程里(MCP 一面同:整条不进的条目照旧 `mcp_injection_dropped`)。7.146.x 及以前续跑照挂、剔掉那几处,一行运维 warn `mcp_transport_members_dropped` / `a2a_peer_headers_members_dropped` ——
|
|
1605
1652
|
调用方只看到续跑成功,而 MCP 请求没带它写的鉴权头;这两行 warn 本版退役。出路:续跑请求带 `mcpServers` / `a2aPeers` 的合形整表(下一条「续跑时换表」;判的是盖过这张表之后的体),或取消那只任务、按本版的形重提。新提交上两形都 `400 request.field_invalid`(同一只判)。
|
|
1606
1653
|
- **续跑时换表(7.143.0 起)**:停着的任务续跑(`POST /v1/approvals/:sessionId/decide` · `POST /v1/assistant/tasks/:id/plan_review` · `POST /v1/assistant/tasks/:id/resume` · `POST /v1/sessions/:id/wake`,各续各的门:工具审批卡 / `plan_review` 门 / 资源限停驻 / `task_done` 停驻)默认重放提交时存下的 `mcpServers` / `a2aPeers`;续跑请求体带上同名键(与提交体同形、同一只判官)就以它为准,
|
|
1607
1654
|
并写回成之后续跑的表 —— 用户移除过一台 MCP 服务器之后,壳送此刻的整张表,续跑就不再重连那一台(停在那一台调用上的任务由引擎判:引擎 7.61.0 起三码各答各形,以 core 为准:那只工具不在了 ⇒ `resume.tool_unavailable`(引擎重开检查点:卡仍 pending、可再决);同名而已不是批准时那一只 ⇒ `resume.tool_contract_mismatch`(同样重开);还是那一只而它的面或声明变了 ⇒ `resume.target_moved`(这次调用不执行、批准用掉,须重新发起),本服务逐字过境);直连门部署的两道回决门拒收这两键(契约 §4e-bis)。
|
|
@@ -1623,7 +1670,7 @@ MCP_ELICITATION_TTL_MS=300000 # 一张没人填的表单挂多久后释放(
|
|
|
1623
1670
|
- 两帧同样**随 run 账本回放**(与上面的问题卡同一条规则:`/v1/tasks/stream` 腿有 durable run 行时先落账再直写,`/v1/runs` 腿只有账本),重载后经 `GET /v1/runs/:id/events` 取回表单卡;
|
|
1624
1671
|
`elicitation` 开帧带 `expiresInMs` / `expiresAtMs`,待答判法与问题卡同一把。**答题口不变**:`POST /v1/elicitations/:id/respond` 只在受理那一张表单的副本内、窗内有效。
|
|
1625
1672
|
|
|
1626
|
-
**可选 — 把这台 worker 挂进别人的 A2A 拓扑(server-as-peer
|
|
1673
|
+
**可选 — 把这台 worker 挂进别人的 A2A 拓扑(server-as-peer):默认关**
|
|
1627
1674
|
|
|
1628
1675
|
别家 orchestrator 把这台 sema-server 当成它拓扑里的一个 **A2A agent** 来调。开了才有两条对外路由;
|
|
1629
1676
|
关着(默认)它们**都不存在**(404)——不是「发卡但拒调」。
|
|
@@ -1652,7 +1699,7 @@ A2A_SERVE_BLOCKING_WAIT_MS=45000 # blocking:true 的服务端等待
|
|
|
1652
1699
|
主体头、直连门的 principal JWT、SSO 凭据;只带 service 凭据(含代部署本人)的请求没有人、只得公开技能;fleet 资格与运维名册不扩大投影(运维按他自己这个人投影)。
|
|
1653
1700
|
🔴 **发布 ≠ 授权**:`audience` 只管「谁看得见、谁能按 id 点名」,不管谁能跑背后的场景 —— 不带 `sema.skillId` 的消息、映射到同一场景的公开技能、
|
|
1654
1701
|
原生提交族(`POST /v1/runs` / `POST /v1/tasks` / `POST /v1/tasks/stream` 体里的 `scenario`)都不经过它,唯一的闸是场景门(中心白名单)。
|
|
1655
|
-
受限技能**不要**映射到部署缺省场景,也**不要**与公开技能共用场景。名单的强度 =
|
|
1702
|
+
受限技能**不要**映射到部署缺省场景,也**不要**与公开技能共用场景。名单的强度 = 这台部署的已验身份来源:没接任何已验身份来源的部署(没配服务凭据、没装鉴权桥、没开直连门;只设 trace 凭据或只开 `REQUIRE_PRINCIPAL` 不算)上写了 `audience` ⇒ 起服拒(拒句一行给两条出路:接一个已验身份来源 / 删掉 `audience`),故不存在该形;
|
|
1656
1703
|
卡与技能选择只认验过的身份来源(出示服务凭据之后的主体头 / SSO 凭据 / 直连门 JWT),不出示凭据、只自报主体头的调用方读成匿名(只看公开技能);BFF 形上,名单的强度等于「持共享 service 凭据的调用方够不到 worker」
|
|
1657
1704
|
(worker 对持凭据者直接可达时谁都能自报主体头);不想依赖网络隔离就用直连门或 SSO 凭据。完整读法见契约附录 C.7。
|
|
1658
1705
|
- 两条路由的**鉴权位置刻意不同**:`GET /.well-known/agent-card.json` 在服务凭据门**外**(公网匿名可
|
|
@@ -1897,7 +1944,7 @@ invalid_using_default` 警告 + 退回缺省值」这条臂随词表放宽一并
|
|
|
1897
1944
|
language server 就用,没有就优雅退回 grep / read;`LSP_HOST_ENABLED=false` 关掉。**其余车道没有 LSP**:e2b / k8s / local-docker / ssh / adb /
|
|
1898
1945
|
device / none 一律不挂,模型名册里没有 LSP 工具、`wiring_manifest` 上没有 `lsp` 段,代码导航用 grep / read。服务入口与 `run-local` 同一条律。
|
|
1899
1946
|
沙箱车道的 LSP 桥已删除(7.127.0 起它本来就挂不上:引擎只读执行环境「绑定持有」的那只文件,沙箱两车道不实现绑定读);它的开关 `LSP_ENABLED`
|
|
1900
|
-
是墓碑(上表),设了任一值都拒启,空串按未设。e2b
|
|
1947
|
+
是墓碑(上表),设了任一值都拒启,空串按未设。e2b 模板里烤的语言服务器只是工具链内容(模板的月检只验它们在不在,不验有没有谁在驱动它们)。
|
|
1901
1948
|
|
|
1902
1949
|
**host 腿语言服务器拿到的环境 + 点名放行 `LSP_ENV_ALLOW`(7.101.0 起)**:host 腿的语言服务器是本机子进程,它拿到的环境
|
|
1903
1950
|
= 服务进程环境**剥掉凭据形的键**(与模型可驱动的 host shell 同一只剥除:配置目录 `secret` 型键按名剥 ∘ 引擎按键名形状剥
|
|
@@ -1935,9 +1982,10 @@ device / none 一律不挂,模型名册里没有 LSP 工具、`wiring_manifest`
|
|
|
1935
1982
|
继承整份用户环境(CC 交互形,用户自己的凭据形变量在内)—— 🔴 **但不含本服务自己的凭据**(7.129.0 起,引擎 7.51.1):配置目录全部 `type:"secret"` 名
|
|
1936
1983
|
(`SERVICE_AUTH_TOKEN(S)` / `APPROVAL_HMAC_KEYS` / `MODEL_API_KEY` …)与名单型旋钮名起服已向引擎声明为本进程自有凭据,生效配置里每条模型条目的 `apiKeyEnv` 也在名单里
|
|
1937
1984
|
(中心热应用新增 / 改名条目时在模型目录换代前重声明,名单只随落地的世代增长 —— 改名后旧名照扣到重启,没落地的候选不留痕;条目的 `apiKeyEnv` 是引擎扣不住的名,或它点到的名正被某只名单型旋钮交给沙箱 / 语言服务器(见下文沙箱名单段)⇒ 该候选整拒),`"all"` = 整份环境**减**它们,任何继承词都不把它们
|
|
1938
|
-
交给模型 shell(能力位 `inherit_env.own_credentials_withheld` = 最近一次声明 ⊇ 当前生效配置应声明的集合;真要让模型 shell 持某枚令牌 ⇒ 放在引擎进程环境里一个不在配置目录、也不是任何模型条目 `apiKeyEnv` 的名下,配 `inheritEnv:"all"`;7.146.0 起请求 `settings.env` 不收凭据,见 9.5j)
|
|
1939
|
-
|
|
1940
|
-
(
|
|
1985
|
+
交给模型 shell(能力位 `inherit_env.own_credentials_withheld` = 最近一次声明 ⊇ 当前生效配置应声明的集合;真要让模型 shell 持某枚令牌 ⇒ 放在引擎进程环境里一个不在配置目录、也不是任何模型条目 `apiKeyEnv` 的名下,配 `inheritEnv:"all"`;7.146.0 起请求 `settings.env` 不收凭据,见 9.5j);这些变量此刻装着的**每一枚凭据**也交给引擎按值扣 —— 整值,列表形另加每一枚:`SERVICE_AUTH_TOKENS` 表里的每一枚令牌、`APPROVAL_HMAC_KEYS` 里的每一把钥(7.149.0 起;此前只交整张表的原文,表里一枚令牌换个变量名放着照进模型 shell)——
|
|
1986
|
+
同值换名的副本同样进不了模型 shell(整串比:`Bearer <令牌>`、令牌多一个字符 / 少一个字符、只是系统名的值都不是副本,照交),引擎判某一枚「不是凭据值」(空白 / 占位词 / 一个字符重复 / 不足 8 字符)⇒
|
|
1987
|
+
那一枚不按值扣(同一变量的其余几枚照扣,名照扣、不拒启,能力位 `inherit_env.own_credential_values_withheld` 答 false),起服与模型目录换代时每个这样的变量出**一条** warn 结构化行 `own_credential_value_not_withheld { name, reason }`
|
|
1988
|
+
(`reason` 是引擎的拒句原文,从不回显值;起服第一步 logger 还没建时,这一行当拍以同一行形写 stderr,不缓冲;logger 接上之后——模型目录换代并进的条目的值被拒——这一行受 `LOG_LEVEL` 约束,`error` 级读不到,机读事实读上面那个能力位)—— 按事件名告警,给该变量一个真值即可。值是**网关密钥**(`MODEL_API_KEY` / `ANTHROPIC_API_KEY`,起服交给模型适配器的那一个)时也只有这一行:引擎在适配器构造口收下同一个值,声明口拒过的值它不再说第二遍(此前这里写的「另有引擎自己的一行裸文本」已不成立);给密钥一个真值这一行消失。`"scrub"` / 缺席 = 上面的缺省剥除。🔴 **`"all"` 只在单用户部署兑现**:`REQUIRE_PRINCIPAL=true`
|
|
1941
1989
|
⇒ 422 `request.host_posture_refused`(射程与写容纳面那条腿同一只谓词,`TASK_WRITE_FACE_ESCALATION` 不管它);非 host 车道带 `"all"` ⇒ 400。词表外的值(`"ALL"` · `""` · 名单 `["PATH"]` · 布尔 · `null` …)、非 host 车道带 `"all"` 这两类都是 `400 request.field_invalid`,7.137.0 起体另带 `field: "inheritEnv"` 与 `reason`(`"unknown_word"` = 是字符串但不在词表;`"not_a_string"` = 根本不是字符串;`"lane_not_host"` = `"all"` 落在非 host 车道;7.147.0 起不再有第四词 `"no_authorizer_session"` —— 一次提交的根会话恒由 authorizer 交出),壳按这两位认拒因、不解析句子(句子 / 码 / 状态不变;续跑腿同判,折叠 409 随体带同一组)。托管部署的 `422 request.host_posture_refused` 不在这组:它说的是「这台部署的姿态不给」,不是这个键写错,按 `errorCode` 认、不带这两位。部署方
|
|
1942
1990
|
**没有**旋钮能替调用方打开它,也没有旋钮能在单用户部署上关掉它(单用户部署的用户把他自己的环境交给他自己驱动的 shell);起服一行 info
|
|
1943
1991
|
`task_inherit_env_honored {honored}` 告诉你这台机器认不认。上面「部署级名单不给模型驱动 shell」那条不变 —— 两件事是两条轴(部署名单 vs 调用方 × 单用户射程)。
|
|
@@ -1956,14 +2004,14 @@ oracle 门子进程,core 7.33.8):oracle 门若先于工具 shell 剥,通告只
|
|
|
1956
2004
|
旧拼法 `_SPAN_` / `_METRIC_HEADERS` 按名剥(值盲);`OTEL_EXPORTER_OTLP_HEADERS` 此前已由本服务的配置目录按名剥,另外六名此前原样交出。语言服务器 /
|
|
1957
2005
|
bake-runner 要用 ⇒ `LSP_ENV_ALLOW` / `BAKE_ENV_ALLOW` 点名放回。
|
|
1958
2006
|
|
|
1959
|
-
**「点名放行」只有一种意思**:本服务里凡是「一张名单点到哪些环境变量键」的地方(这里的 `LSP_ENV_ALLOW
|
|
2007
|
+
**「点名放行」只有一种意思**:本服务里凡是「一张名单点到哪些环境变量键」的地方(这里的 `LSP_ENV_ALLOW`、settings hook 环境的 `HOOK_ENV_ALLOW`(9.5c)、沙箱车道的
|
|
1960
2008
|
`E2B_SANDBOX_ENV` / `DOCKER_SANDBOX_ENV` / `K8S_SANDBOX_ENV`(见下表),与**嵌入方**构造 host shell 时的 `inheritEnv:[names]` —— 后者不是部署旋钮,见上一段)用的是同一只谓词 ——
|
|
1961
|
-
点到的键从服务进程环境原样交出去(空串值照交)
|
|
1962
|
-
`E2B_SANDBOX_ENV` / `DOCKER_SANDBOX_ENV` / `K8S_SANDBOX_ENV`)
|
|
2009
|
+
点到的键从服务进程环境原样交出去(空串值照交),密钥形也照交;源里没有的名什么也不产生。五只名单型旋钮(`LSP_ENV_ALLOW` / `HOOK_ENV_ALLOW` /
|
|
2010
|
+
`E2B_SANDBOX_ENV` / `DOCKER_SANDBOX_ENV` / `K8S_SANDBOX_ENV`)另走同一只名单解析:形错拒启点名第几段、不回显原值,点名任一只名单型旋钮或本服务自有凭据(名是,或值是本服务的某一枚凭据 —— 另一个名下的副本,7.149.0 起)拒启,
|
|
1963
2011
|
本进程环境里没有的名按序号一行 `config_env_entry_rejected`,旋钮原文按凭据类对待(配置目录只回在场位、不进任何子进程)。
|
|
1964
2012
|
几处只在**没点到的键**上不同:语言服务器在缺省剥除的结果之上放回点名键(没点到的照剥,非密钥键照常在);host shell 的
|
|
1965
2013
|
`inheritEnv:[names]` 与三只沙箱名单是 hermetic 的(没点到的一律不交,与引擎 `NodeExecutionEnv` 同名选项同义;7.129.0 起 host shell 的名单由引擎读 ——
|
|
1966
|
-
点到本服务自有凭据名 ⇒
|
|
2014
|
+
点到本服务自有凭据名 ⇒ 执行环境构造时即拒,拒句带名;点到的变量值是本服务某一枚凭据的副本 ⇒ 引擎扣下、不交)。
|
|
1967
2015
|
两处都不向对方看齐:host shell 改成「剥后放回」等于在模型可驱动的 shell 上放宽,语言服务器改成 hermetic 会让它当场找不到自己的工具链。
|
|
1968
2016
|
|
|
1969
2017
|
**沙箱带外 env 名单(`E2B_SANDBOX_ENV` / `DOCKER_SANDBOX_ENV` / `K8S_SANDBOX_ENV`,前两只 7.101.0 起、`K8S_SANDBOX_ENV` 7.126.0 起,同上一段的解析与谓词)**:沙箱里的工具要用本服务
|
|
@@ -1977,12 +2025,12 @@ bake-runner 要用 ⇒ `LSP_ENV_ALLOW` / `BAKE_ENV_ALLOW` 点名放回。
|
|
|
1977
2025
|
|
|
1978
2026
|
三只旋钮只在**自己的车道被选中时**才求值(别的车道上它们是无关配置,不校验、不告警)。未设 / 空串 = 不注入。**形错拒启**:空段
|
|
1979
2027
|
(`A,,B`、尾逗号)、非变量名形(`1BAD`、带空格、`NAME=value` 整段贴进来)、点名名单型旋钮(`E2B_SANDBOX_ENV=E2B_SANDBOX_ENV`,
|
|
1980
|
-
或 `LSP_ENV_ALLOW` / 另一只沙箱名单)⇒
|
|
1981
|
-
`SERVICE_AUTH_TOKEN(S)` / `APPROVAL_HMAC_KEYS` / `MODEL_API_KEY` / `E2B_API_KEY` / `K8S_TOKEN` / `GIT_API_TOKEN`)
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
`LSP_ENV_ALLOW`
|
|
2028
|
+
或 `LSP_ENV_ALLOW` / 另一只沙箱名单)⇒ 起服失败,拒句点名键与第几段,**不回显原值**。**点名本服务自有凭据** —— 配置目录里的 secret 型变量(如
|
|
2029
|
+
`SERVICE_AUTH_TOKEN(S)` / `APPROVAL_HMAC_KEYS` / `MODEL_API_KEY` / `E2B_API_KEY` / `K8S_TOKEN` / `GIT_API_TOKEN`),**或值等于本服务某一枚凭据的另一个变量**
|
|
2030
|
+
(换了名的副本,列表形凭据逐枚比,7.149.0 起)—— 同样起服失败:名单会把这枚凭据原样装进模型读得到的沙箱;
|
|
2031
|
+
与 `LSP_ENV_ALLOW` 同一条律、同一只判官(引擎此刻的自有凭据声明:名按平台比,值整串比),拒句同一个开头 `this deployment's own credential — `(副本那一形其后多半句 `a copy under another name …`),点名键与第几段(`entry #k of n`,k 从 1 起,就是你写的名单里的第 k 项;一句话里只有这一套序号),不回显名也不回显值。
|
|
2032
|
+
沙箱要凭据 ⇒ 给它铸一把自己的(名与值都不同于本服务的任何凭据),放进服务进程环境再点那个名。**中心 / config.d 模型条目后来点到同一枚凭据**:条目的 `apiKeyEnv` 在模型目录换代时才并进本服务自有凭据(名与值),那一刻对本表三只与
|
|
2033
|
+
`LSP_ENV_ALLOW` 此刻交出去的变量用同一只判官重判 —— 新并进的名正被某只名单交出去,或新并进的值正是某只名单交出去的变量的值 ⇒ 那份候选整拒、上一代照常服务,拒句点名旋钮、名与条目;出路二选一:给沙箱另铸一把并改名单
|
|
1986
2034
|
(名单起服读,改了要重启),或在中心把条目的 `apiKeyEnv` 改指别的变量(下一拍自愈)。形对但服务进程环境里**没有**这个名 ⇒ 不注入,
|
|
1987
2035
|
起服一行 `config_env_entry_rejected` 只报第几段。点到的键值为空串 ⇒ 照样注入一个空串(7.101.0 前跳过,见 CHANGELOG)。
|
|
1988
2036
|
`REQUIRE_PRINCIPAL=true` 下照常注入(与 `LSP_ENV_ALLOW` 不同:沙箱 env 是部署方给隔离沙箱显式配的);上面两类拒启不随姿态变。
|
|
@@ -2016,10 +2064,14 @@ bake-runner 要用 ⇒ `LSP_ENV_ALLOW` / `BAKE_ENV_ALLOW` 点名放回。
|
|
|
2016
2064
|
| `Authorization: Bearer <SERVICE_AUTH_TOKEN>` | 设了 `SERVICE_AUTH_TOKEN` 时,除 `/health` / `/readyz` 外的所有请求 | **谁有权调本服务**(OA 后端持有,服务到服务) |
|
|
2017
2065
|
| `x-agent-principal: user:42` | 设了 `REQUIRE_PRINCIPAL=true` 时 | **代表哪个终端用户**(决定 session 归属 + 记忆隔离;**绝不从 body 取**)。7.134.0 起也决定 fleet 面看得见什么:带了它的 service 凭据请求只看得到、动得到这位用户的(舰队流 / 列表 / 名册 / trace / 用量 / 删除 / fork / 同步);全舰队视图不带它(直连门部署上身份是签名的 principal 令牌,不是这个头) |
|
|
2018
2066
|
|
|
2019
|
-
> **dev-open
|
|
2020
|
-
> 也没配 `TRACE_TOKEN`、没开 `REQUIRE_PRINCIPAL` 的部署上,`x-agent-principal`
|
|
2021
|
-
>
|
|
2022
|
-
>
|
|
2067
|
+
> **dev-open 部署的主体头是自报的,不是隔离。** 没接任何身份来源(没配 `SERVICE_AUTH_TOKEN(S)`、没装中心鉴权桥、没开直连门 —— 即 `/health.auth.kinds` 为空)、
|
|
2068
|
+
> 也没配 `TRACE_TOKEN`、没开 `REQUIRE_PRINCIPAL` 的部署上,`x-agent-principal` 谁都能自报。它说的是「这次请求为谁」,每一口同读(7.149.0 起;与提交续用别人会话被拒同一读法):
|
|
2069
|
+
> 带了头的请求只看得到、动得到这位主体的会话与 run(会话列表 / 单会话读写口 / 规则口 `…/policy` / `…/notify` / fork / run 轮询 —— 别人的与不存在的同答 404;删除别人的会话答 `200 {"deleted":false}`,与删不存在的同),
|
|
2070
|
+
> `/metrics` 族对它答 `401`(配了 `METRICS_TOKEN` 时出示它照放);
|
|
2071
|
+
> `GET /v1/tasks/source-summary` 对它同样答 `401`(这一口认的是只读的 `TRACE_TOKEN` —— 配了才有,出示它照放;`METRICS_TOKEN` 在这一口不算);
|
|
2072
|
+
> **不带头**(也不带这台部署验不过的 Bearer —— 带了它的请求没有可信身份,不代部署本人)的请求代部署本人:列表与单会话读写口看得到、动得到全部会话,run 轮询看得到全部 run,
|
|
2073
|
+
> `/metrics` 族不要凭据(没配 `METRICS_TOKEN` 时);run 的驱动口(取消 / steer …)与提交续用别人的会话照旧按属主判,对它同样不开。它也决定新会话记在谁名下、记忆按谁的 scope 走。
|
|
2074
|
+
> 头谁都能自报 ⇒ 这给的是一致的视图,不是隔离;要按用户隔离,给部署设上面几者之一(典型:service token + 写主体头的网关)。≤7.148.x:带不带头都看得到全部会话(只有提交续用按头判)。
|
|
2023
2075
|
> **装了中心鉴权桥(`SEMA_WEB_ADMIN_URL` 在位即默认开,或 `AUTH_BRIDGE_ISSUER`)就不是 dev-open**(7.132.0 起;此前这一形被读成 dev-open):带登录令牌的调用方按令牌里的身份钉人,
|
|
2024
2076
|
> 不带任何凭据的列表 `401 auth.unauthorized`、`/metrics` 族 `401`(要 `METRICS_TOKEN`)。仍成立的边界:没配 service token 的部署上,不带登录令牌的请求自报的主体头仍按身份读
|
|
2025
2077
|
> (与 `REQUIRE_PRINCIPAL` 无 token 形同读)—— 要让「没令牌就没有身份」成立,配 `SERVICE_AUTH_TOKEN`(全局凭据门:每个请求要么带 service token、要么带登录令牌)。
|
|
@@ -2237,10 +2289,10 @@ curl -N http://<host>:8090/v1/tasks/stream -H 'content-type: application/json' \
|
|
|
2237
2289
|
| 端点 | 用途 |
|
|
2238
2290
|
|---|---|
|
|
2239
2291
|
| `GET /v1/sessions/<id>` | 审计回溯:当前上下文 + 摘要(owner 校验);消息里模型 / 工具产出的文本与 live 帧、账本帧同一只脱敏(密钥形换占位,其余字节不变);Read 图像 / PDF 的媒体卡(工具结果消息的 `details`)的 `file.base64` 是字节编码,逐字。**委派子代的转录**也走这一口:`<id>` = 子代帧 / fleet 子代行上的 `transcriptId`(未压缩过的子代首条用户消息是委派 prompt;子代跑过的工具是 assistant 消息里的 `toolCall` 段 + 同 `toolCallId` 的 `toolResult` 行;整段逐字条目走 `…/sync/entries`)。体顶层加性键 `agent: { id?, parentSessionId?, rootSessionId? }`(**7.133.0+**)说这是哪只子代:只投影会话行上存下来的委派元组,`id` 与 fleet 行的 `id`、`GET /v1/agents/roster` 的 `handle` 同一个串;键缺席 = 普通会话 / 老 server(`DB_BACKEND=local` 到 7.140.x 也是)/ 会话店不存元组(`DB_BACKEND=memory`;嵌入方自建、不声明委派分区的店),读作「没存」、回落 fleet 行 / 名册上的 id。子代会话的属主是引擎判的委派树属主(**7.144.0+**:没人派生的 run 读自己那一行的属主、按化身绑一次,原样带给每一层子代;三只持久会话店〔MySQL 协议 / PostgreSQL / local〕建行那一笔原样记引擎交来的属主,`null` = 根匿名;停驻挂点只比对宿主行属主与引擎交来的属主,不认领、不推断。**7.133.0–7.143.x** 是本服务在建行那一笔按根 / 父推断:根会话的行在 ⇒ 它的属主,根行已不在 ⇒ 它记录的父会话的,都不在 ⇒ 哨兵 `_orphan:<id>`;7.132.x 及更早的 SQL 后端上子代会话无主、谁都读得到)⇒ 用发起子代的那位主体读;别的主体与不存在的 id 同一个 `404 not_found.session`。属主为空的委派子代行(根会话本就无主,或升级前写下、还没回填)只有 fleet 调用方读得到(出示 service 凭据、不带主体头;dev-open 部署不钉人),任何具名主体、没有 service 凭据的无身份调用方同样 404(存量无主会话互认臂 —— 单用户形下 `default` 主对无主的普通会话放行,fork / 删除 / `/sync/*`(同步族自 7.134.0 起)同走这一只 —— 对这些 placed 行同样不放行,审批豁免、notify 同样不放行;fork / 删除 / `/sync/*` 的 fleet 调用方与此处同一个判据:出示 service 凭据、不带主体头,带主体头的 service 凭据请求是那位主体,7.134.0 起);SQL 后端两店每次起服由一次性迁移 M23 在它的窗内回填升级前写下的无主 placed 行(按 7.133.0 起的读法:根的属主,根行不在取记录的父的,都不在写 `_orphan:<id>`;起服读数行 `placedSessionOwnersRemaining` 非零 = 还有没定下的,再起直到为 0),local 后端没有回填臂(**7.145.0+** local 后端建子代行先记属主、再建转录存档,进程崩在两笔之间留下的是一只没有转录的属主格 —— 不是子代行,不再新生无主子代行;更早版本崩在两笔之间留下的无主子代行照旧无主、不回填,出路是取消 / 删掉那只后台子代)。属主 `_orphan:<id>` 由 7.133.0–7.143.x 的建行推断与 M23 回填写下(7.144.0 起本服务不再推哨兵,建行原样记引擎交来的属主 —— 已有的哨兵属主随引擎的树属主原样带到它下面新建的子代行上):任何主体都不匹配,只有 fleet-wide / operator 读得到,前缀永久保留。停驻时宿主行属主与引擎交来的不等 ⇒ 停驻否决(那张待批卡作废、那一只子代以失败收尾) |
|
|
2240
|
-
| `GET /v1/approvals?owner=user:42` | 高危写审批(durable,需 `DURABLE_APPROVAL=true`):**operator** 看待办队列(可按 owner 过滤);非 operator 只看自己的。队列里某一行的存储体读不出来、重试不会好时,答 `500` + `errorCode:"approvals.read_corrupt"`(**7.134.0+**;与订阅流同码、同一只判官;运维处置那一行后再读,别原样重试);此刻读不出队列(连接 / 超时 / 店抖动)⇒ `503` + `errorCode:"approvals.read_unavailable"`(**7.135.0+**,此前 500 `internal.error`;稍后重发,这一答不表示队列为空);本服务自己的程序错(代码缺陷 / 读腿漂移)⇒ `500` + `errorCode:"internal.error"`(**7.148.0+**,此前同落 503;重发不会好,看运维行 `request_error`)。`GET /v1/assistant/inbox` / `GET /v1/assistant/tasks` 读同一个队列,两种读失败同码同状态(**7.135.0+**)。一张停驻行的存储体读不出摘要(手改成 `{}`、整段缺 `state` 等)只坏它自己那一行(**7.145.0+**,MySQL 协议 / PostgreSQL 后端):收件箱与运维队列照列它、带引擎判官的 `rowVerdict`(只缺 `pendingAction` 的行判官答 `ok`,引擎侧已知缺口),任务视图照列那条 run,三个面都不再整张答 500 / 503;别的卡的决断照常,这张卡自己的决断答 409 带码拒,`error` 以行上 `rowVerdict.sentence` 开头(**7.146.0+**;此前存储体 `{}` 的卡被指向 plan_review 的口、存储体读不成检查点的卡只有店的诊断);`DB_BACKEND=local` 上列表面本版仍整张 503(决断已逐行)
|
|
2241
|
-
| `GET /v1/approvals/stream` | 同一队列的 SSE 推送(范围同上):首拍快照 → `pending` / `resolved` 增量(开了工具审批时另有 `live_pending` / `live_resolved`),空闲时心跳,15 分钟上限(`STREAM_MAX_DURATION` 帧后重连)。**心跳只表示流活着,不表示这一拍读过队列**:队列读不出时每次读失败发一帧 `error`(`approvals.read_unavailable`,流留着、下一拍再读,恢复后同一条流继续);某一行的存储体读不出来、重试不会好时发 `approvals.read_corrupt` 并收流(运维处置那一行后再重连);本服务自己的程序错发 `internal.error` 并收流(**7.148.0+**,此前同落 `approvals.read_unavailable`、流不收)。15 分钟上限对读失败的拍同样算数。`pending` 帧带的行与 `GET /v1/approvals` 同一只投影(含上面的技能卡三位,**7.136.0+**;含 `agent`,新订阅首拍补给的帧与之后推出的帧同值,**7.145.0+**) |
|
|
2292
|
+
| `GET /v1/approvals?owner=user:42` | 高危写审批(durable,需 `DURABLE_APPROVAL=true`):**operator** 看待办队列(可按 owner 过滤);非 operator 只看自己的。队列里某一行的存储体读不出来、重试不会好时,答 `500` + `errorCode:"approvals.read_corrupt"`(**7.134.0+**;与订阅流同码、同一只判官;运维处置那一行后再读,别原样重试);此刻读不出队列(连接 / 超时 / 店抖动)⇒ `503` + `errorCode:"approvals.read_unavailable"`(**7.135.0+**,此前 500 `internal.error`;稍后重发,这一答不表示队列为空);本服务自己的程序错(代码缺陷 / 读腿漂移)⇒ `500` + `errorCode:"internal.error"`(**7.148.0+**,此前同落 503;重发不会好,看运维行 `request_error`)。`GET /v1/assistant/inbox` / `GET /v1/assistant/tasks` 读同一个队列,两种读失败同码同状态(**7.135.0+**)。一张停驻行的存储体读不出摘要(手改成 `{}`、整段缺 `state` 等)只坏它自己那一行(**7.145.0+**,MySQL 协议 / PostgreSQL 后端):收件箱与运维队列照列它、带引擎判官的 `rowVerdict`(只缺 `pendingAction` 的行判官答 `ok`,引擎侧已知缺口),任务视图照列那条 run,三个面都不再整张答 500 / 503;别的卡的决断照常,这张卡自己的决断答 409 带码拒,`error` 以行上 `rowVerdict.sentence` 开头(**7.146.0+**;此前存储体 `{}` 的卡被指向 plan_review 的口、存储体读不成检查点的卡只有店的诊断);`DB_BACKEND=local` 上列表面本版仍整张 503(决断已逐行)。开了工具审批时响应另带 `livePending[]`(本副本上的活卡,决议走 `POST /v1/tool-approvals/<approvalId>/respond`):**7.149.0+** 它与下面的按问读口同一只读法 —— 列出的每一张,读口对同一调用方都答 `pending`(反过来不然:具名主体的列表不含无主的卡,运维列表含读口不放行的卡),店读不出某张卡的行 ⇒ 这张不列(读口同时答 404 `not_found.ask`;`livePending` 为空不等于没有待批,可能是此刻读不出),行已被别处收走 ⇒ 不列,属主取行上当下的那一位(此前按本副本登记列,店抖动期照列而读口 404);店恢复后重列即回,每次列表对每个有行的不同 ask 多一次按 id 的点读。停驻的**技能卡**(对引擎 `Skill` 工具的调用)的行带 `boundGrantDigest` / `boundGrants`(批准它还授予的东西:技能名 + 两只工具清单;清单只在哈希等于摘要时才有,是部署文本,渲染要按上下文转义),分类器没给判词的卡带 `classifierNoRuling`(`error` / `timeout` / `parse_error`)—— **7.136.0+**,与 `GET /v1/assistant/inbox` 行逐字同值(此前只有收件箱行与活卡帧带);普通卡三位都缺席。`GET /v1/assistant/inbox` 行的 `objective` 是门所属 run 的**目标预览**(写入时已脱敏、截到约 120 字符,与 `GET /v1/assistant/tasks` 读同一列;委派子代的门读派它的那条 run;没有 run 账本 ⇒ `null`;**7.136.0+**,此前原样回显存着的任务目标,运维 `?owner=` 跨看也是原文)。停驻行带 `agent`(**7.145.0+**):行的会话在委派树里的位置 `{ id?, parentSessionId?, rootSessionId? }`,与 `GET /v1/sessions/<sessionId>` 体顶层的 `agent` 同一只读口、逐值同答 —— 后台委派子代停驻的行(`taskId` 为 `null`、`sessionId` 是子代自己的会话)凭它连回发起委派的会话(`rootSessionId` / `parentSessionId` = 本端会话 ⇒ 本端的卡);缺席 = 这台 server 没有说(宿主会话自己的停驻、同步委派的子代、`subagent_type: "fork"` 的后台子代、不存委派元组的店、那一读没读成 —— 只这一行缺键、列表照出),按原读法判,不读作「不是子代」 |
|
|
2293
|
+
| `GET /v1/approvals/stream` | 同一队列的 SSE 推送(范围同上):首拍快照 → `pending` / `resolved` 增量(开了工具审批时另有 `live_pending` / `live_resolved`),空闲时心跳,15 分钟上限(`STREAM_MAX_DURATION` 帧后重连)。**心跳只表示流活着,不表示这一拍读过队列**:队列读不出时每次读失败发一帧 `error`(`approvals.read_unavailable`,流留着、下一拍再读,恢复后同一条流继续);某一行的存储体读不出来、重试不会好时发 `approvals.read_corrupt` 并收流(运维处置那一行后再重连);本服务自己的程序错发 `internal.error` 并收流(**7.148.0+**,此前同落 `approvals.read_unavailable`、流不收)。15 分钟上限对读失败的拍同样算数。`live_pending` / `live_resolved` 与 `GET /v1/approvals` 的 `livePending[]` 同一只读函数(**7.149.0+** 同按问读口读行:读不出行 ⇒ 这一拍离场、店恢复后再入场一帧,推流每拍对每个有行的不同 ask 多一次点读;问账读不出而队列读得出的拍才发这一对帧)。`pending` 帧带的行与 `GET /v1/approvals` 同一只投影(含上面的技能卡三位,**7.136.0+**;含 `agent`,新订阅首拍补给的帧与之后推出的帧同值,**7.145.0+**) |
|
|
2242
2294
|
| `POST /v1/approvals/<sessionId>/decide` `{"decision":"approve"|"deny","reason":"…"}` | 批/否并恢复挂起任务(CAS,重复决议 409);**仅 operator**(非 operator → 403)。5.0.0 起旧轮询腿 `POST /v1/approvals/<id>` 已退役。停驻的后台子代**复活不了**(行上没有根会话锚;未起名的后台子代不在此列 —— 引擎 7.57.0 起每只子代都有名字,升级前的无名行读作派生名,照常复活)⇒ `deny` 作废这张卡:`200 {taskId, status:"failed", decision:"deny"}`,卡离开待决队列、子代终局 `failed`;`approve` 答 `409 decide.row_unrevivable`、拒句指路 deny(**7.136.0+**;此前两个决定都 409,卡处理不掉)。有根会话锚的停驻子代卡上,`decide` 与删根会话 / 卡作废并发:写口放行之后卡已被作废 ⇒ `422 parked_resume.startup_failed`(卡已作废、什么都没复活;与 `409 decide.gate_moved` 并列为并发终局码,调用方须同时处理 409 / 422) |
|
|
2243
|
-
| `GET /v1/tool-approvals/<approvalId>` | 按问读口(**7.133.0+**;与 `POST …/respond` 同门同身份,不是你的 ask 与查无同形 404 —— **7.148.0+** 两口与耐久决断口同码 `not_found.ask`、不带状态位,`tool_approval.not_pending` 只对属主出;**7.136.0+** 两扇决议口 —— `POST …/respond` 与耐久决断口 `POST /v1/tasks/<taskId>/asks/<askId>/decision` —— 与本口同一只属主判据:有行的问读行上当下的属主,收编之后新属主三口都认、前属主三口都 404
|
|
2295
|
+
| `GET /v1/tool-approvals/<approvalId>` | 按问读口(**7.133.0+**;与 `POST …/respond` 同门同身份,不是你的 ask 与查无同形 404 —— **7.148.0+** 两口与耐久决断口同码 `not_found.ask`、不带状态位,`tool_approval.not_pending` 只对属主出;**7.136.0+** 两扇决议口 —— `POST …/respond` 与耐久决断口 `POST /v1/tasks/<taskId>/asks/<askId>/decision` —— 与本口同一只属主判据:有行的问读行上当下的属主,收编之后新属主三口都认、前属主三口都 404;此前本副本上的活卡读的是铸卡那一刻记下的属主;**7.149.0+** 本口在店读不出时看不见这只问,答 404 `not_found.ask`(与查无同体;活卡与起服接管的登记同答 —— 7.136.0–7.148.x 对本副本自己铸的活卡回落登记,登记属主认你 ⇒ `pending`),店恢复后重读即回):一只审批问此刻在哪一态,`state` ∈ `pending` / `decided` / `parked` / `void`(闭集)。停驻卡被答过 ⇒ `decided`、停驻 run 被取消 ⇒ `void`(**7.134.0+**;7.133.x 恒答 `parked`);停驻行的门已结算却读不出可用的决议(含坏行:状态词 / 种类 / 当事方不在闭集、结算记录过不了引擎的不变量筛、缺必填成员、时刻 / 方向读不出)⇒ 404 `tool_approval.not_pending`,运维日志一行 error(`defect` 首条缺陷句 · `defectCount`)。停驻行的 `decided` 可回到 `parked`:续跑腿在被批准的动作开跑前失败时,引擎重开同一张门 —— 读口答 `parked` + `decidePath` 并另带 `reopened`(**7.135.0+**):`reason` 是引擎的重开因由词(`env_failed` 按原决议经 `decidePath` 再交一次 —— 本副本还留着首次受理回执时(缺省 1 小时内)`…/respond` 回放那张回执、不驱续跑;`tool_unavailable` / `constraint_rejected` 重新决;`config_refused` 改好配置再交或重新决),`decision` / `decidedAtMs` / `decisionNote?` 是重开之前的那次决议(读不出 ⇒ 只带 `reason`);再决之后回到 `decided`。续跑被取消 ⇒ 重开的门被收掉,读作 `void`。全文见契约 §4a-bis-read |
|
|
2244
2296
|
| `GET /v1/agents/roster` | 后台 agent **名册**(7.29 起,需 durable background-agent store,否则 501 `capability.background_agent_store_required`):调用方自己 scope 的 `a…` 行,新→旧。行只带 `handle`/`name`/`agentType`/`status`/`spawnedAt`/`updatedAt`/`settledAt`(content-free;子代产物正文走 `GET /v1/runs/<id>/subagents/<handle>/output`)。查询:`?limit=`(1..100,默认 20)、`?before=`(上一页的 `nextBefore` 游标)、`?status=`(running\|parked\|completed\|failed\|killed)、`?session=`(按会话树窄化)、`?scope=`(**仅** fleet 调用方:不带主体头的 service 凭据 / 只读 `TRACE_TOKEN`(只在没配 service 凭据的部署上够得着这一口)/ dev-open;带主体头的调用方 —— 含带 service 凭据的 —— 锁定自己)。回体 `{agents,total,nextBefore?,truncated?}`;`truncated:true` = 租户行数超过名册窗(500),`total` 此时是窗内数。非属主的行**不出现也不计数**(无存在性 oracle) |
|
|
2245
2297
|
| `GET /v1/capabilities/scenarios/<name>` | 单个场景的只读详情:工具面、提示词概览、**本部署现在跑不跑得动**、附件供给、**技能清单**(见下) |
|
|
2246
2298
|
| `GET /v1/capabilities/mcp[?scenario=<场景名>]` | **无需先跑 run 的逐台 MCP 状态**(现连、列工具、关掉;按调用方限速 + 30 秒复用)。答的是**某个场景**会挂哪些中心声明的 MCP 服务器:不带参数 = 这位主体 run 时的场景(**7.131.0+**:中心按主体指派的场景胜出,否则部署缺省场景;此前恒读部署缺省场景;指派悬空 ⇒ `503 state.scenario_assignment_unknown`,与提交任务时同一句;**7.147.0+** 部署接了中心而中心答不出这位主体的裁定(不可达 / 超时 / 答复读不出 / 指派两键形不对)⇒ 点名与不点名同答 `503 state.scenario_assignment_unavailable`(体无 `detail`、带 `permanence: "transient"`),与提交任务时同一句,不再按「无治理」读部署缺省场景;`GET /v1/sessions/:id/mcp` 与 `…/a2a` 两张会话面板同读这位主体 run 时的场景:a2a 面板悬空时同样整面 503,而 mcp 面板另有「这个会话上一次真挂上了什么」那一半(`lastLegMcp`),悬空时答 `200`、`lastLegMcp` 照答、`servers` 缺席、拒因在 `scenarioRefusal: { errorCode, error, scenario, source }`(与状态面整面 503 的体是同一份成员,`scenario` · `source` 是门拒的机读事实、与 `errorCode` / `error` 同层 —— 7.148.0 起,此前嵌在 `detail` 里;`servers` 缺席 = 场景这一半没答,`servers: []` = 该场景没配 MCP));`?scenario=<名>`(**7.130.0+**)= 点名场景,可见集与同场景任务 run 时是同一只解析、过同一只场景门 —— 不在册 `400 scenario_unknown`(附在册词表;空串 `?scenario=` 同此,与提交 `scenario: ""` 同答)、这位 principal 的场景白名单集外 `400 scenario_not_allowed`(附 allowlist),两者的体与提交任务时的拒逐字同形;重复给出参数 `400 request.field_invalid`(提交腿没有这一形)。场景门接缝 `scenarioGate` 是 `createHttpServer` 的必填件:自建 `ServiceDeps` 的嵌入方用包根导出的 `createScenarioGate` 铸它(`"peek"` 腿给读面),没递就是 tsc 红。老 server 忽略这个参数、回缺省场景那一份,按 `GET /v1/capabilities` 的 `version` 判。`REQUIRE_PRINCIPAL` 下无身份 `401`(先于场景门)。每一行(两条口同形)在 §G.7 的行形之外多两个可选键(**7.133.0+**):`toolNames`(这台会挂上的工具名,引擎命名空间形 `mcp__<server>__<tool>`,读数序)+ `toolNamesTruncated: true`(名单超过 200 只时只截表,`toolCount` 仍是真数;读数用 `toolCount`,别用 `toolNames.length`);该台读数里没有名单 ⇒ 两键缺席(不编 `[]`),没连上的台是在场的 `[]`;老 server 没有这两键,按缺席读。中心声明里有两台归一后挂在同一个工具命名空间前缀下(`my.srv` / `my_srv` 同挂 `mcp__my_srv__`)⇒ **7.143.0+** `409 config.mcp_server_name_collision` + 引擎原句(点名两个原拼写;此前无码 `500`),与同一份声明集在 `POST /v1/tasks` 上的答复同码、同状态、同句 —— 出路 = 改配置里的名字。自带 `.mcp.json` 的探测口是 `POST /v1/capabilities/mcp/probe` |
|
|
@@ -2688,6 +2740,8 @@ curl -N http://<host>:8090/v1/tasks/stream -H 'content-type: application/json' \
|
|
|
2688
2740
|
程序分支的字段——**别锚 `error` 文案**。前缀族固定:`auth.` / `request.` / `not_found.` / `conflict.` /
|
|
2689
2741
|
`limit.` / `usage.`(部署级治理窗)/ `capability.`(本部署没接这个面)/ `feature.`(开关没开)/
|
|
2690
2742
|
`internal.` / `state.`;未知码按前缀兜底永远安全。完整码表在契约附录 A(内部记录,不随包;随包 `wire-changes/server@<版本>.json` 逐版记着 wire 键与闭集成员的增删)。
|
|
2743
|
+
`error` 文案里本服务自己写的部分有用词约束 —— 内部词闭集与内部编号形、按 `<状态码>:<errorCode>` 逐族的放行与理由 —— 随包在 `docs/error-text-lexicon.json`,
|
|
2744
|
+
本服务自己的文案检查读的就是这一份;要对拒句做用词验收,按它判(射程、匹配式与放行怎么读写在文件的 `description` 里:句中插进来的值,如调用方送来的名字,不在约束里)。
|
|
2691
2745
|
|
|
2692
2746
|
**进程警告面(日志采集方注意)**:引擎(core ≥5.16)在持久 agent 行的 org 判决写回被丢弃等场合走
|
|
2693
2747
|
Node `process.emitWarning`,警告文案前缀固定 `sema durable-agents:`——采集规则按该前缀匹配,别当噪音过滤掉。
|
|
@@ -3127,7 +3181,7 @@ armed ⟺ 本次请求 permissionMode 是 "auto" ∧ 本部署装配了分类
|
|
|
3127
3181
|
| `AUTO_MODE_CLASSIFIER_TIMEOUT_MS` | 未设(⇒ core 缺省) | 7.102.0 起:auto 分类器**一级梯子**的判决上限(整数 ms)→ core `RunnerDeps.autoMode.timeoutMs`。一级到点没裁 ⇒ 走下一级(`AUTO_MODE_CLASSIFIER_FALLBACK` 决定有没有下一级),走完仍没裁 ⇒ 这次门控调用**整条拒**、不出卡;最坏等待 ≈ 级数 × 本值 + 一次装配。**自托管慢网关**(排队 + prefill 以分钟计)在缺省上限内答不出 ⇒ auto 下工具一律被拒 —— 按后端实测留足(如 `180000`)。未设 / 空串 ⇒ 本仓**不铸键**,由引擎落它自己的缺省(不复制上游数字);合法域 `[1000, 2147483647]` 内的十进制整数,`0`(本座没有「关」)/ 亚秒 / 小数 / `1e5` 这类拼法 / 越 Node 定时器上界一律**拒启**。旋钮无条件(与 auto 是否武装无关);不影响 `permissionModeAuto` 读面。目录行见 `GET /v1/config/catalog`(approval 域) |
|
|
3128
3182
|
| `CROSS_SESSION_INBOUND` | 未设 | 跨终端会话设计线:CC settings 键名 `crossSessionInbound` 的**部署/组织层**(引擎层形的 `managed` 层,CC `policySettings` 对位)—— 本部署对**入站跨会话消息**的治理四态(词表取自引擎闭集,core 7.30.0 起):`wake` 投递且**宿主**可在收件箱增长时起一个 turn / `next-turn` 在下一个 turn 边界投递 / `hold` 停在收件会话的待审队列(模型看不见、不能据此行动)/ `refuse` 本部署整体退出这条车道。⚠️ 本服务宿主**不起 turn**,所以在本服务上 `wake` 按引擎契约的降级臂读作 `next-turn`。🔴 **旧词 `accept` 自 7.100.0(core 7.30.0 提货)起拒启** —— 它的原义就是 `next-turn`,改成那个词即可(零别名,拒启即通告)。🔴 **未设 ≠ `next-turn`**:未设 = 这一层不表态,由其余层与引擎的 mode-parity 判定决定。词表外的值**拒启**。⚠️ **生效前提**:引擎的 peer 目录席(`RunnerDeps.peerDirectory`)在场 —— 7.91.0 起已接线(会话枚举面 ∧ mailbox 店 ∧ 收件人生命周期面三合取),缺任一合取项的部署上本旋钮仍「就位待命」;目录行见 `GET /v1/config/catalog`(approval 域,security 轴) |
|
|
3129
3183
|
| `CROSS_SESSION_DIALOG_EXPIRY` | 未设(⇒ 引擎缺省 `5m`) | 同族:CC settings 键名 `dialogExpiry` 的部署层 —— 被 hold 的跨会话消息等待人审多久后按**安全缺省**结算(过期丢弃,**带回执**告知发送方,不静默吞)。词表 `60s`/`5m`/`10m`/`never`(`never` = 不设期限);未设 ⇒ 本仓**不铸键**,由引擎落它自己的缺省(不复制上游缺省值)。词表外拒启。⚠️ 生效前提同上。另注:CC 的同名键还有第二个消费面(转发到远端客户端的审批对话框停靠时长),本旋钮**今天不驱动**那一面 |
|
|
3130
|
-
| `PRINCIPAL_INBOX_ASSISTANT` | 未设 | 7.133.0 起:本部署 **principal 收件箱**的消费方声明 —— 独占读它的那只助理的 agent handle(→ 引擎 `RunnerDeps.principalInboxConsumer: { assistant }`)。**它就是跨主体投递的开关**:设了 ⇒ 挂上组织投递门与受理口 `POST /v1/principal-inbox/messages`(同一组织里给另一个用户投一封信,契约 §22;能力位 `principalInboxDelivery`),同时**要求**耐久 mailbox(`DB_BACKEND=mysql\|pg\|local`)、组织成员目录(中心,或 `MEMORY_ORG_DIRECTORY_JSON`)与配额店(SQL 后端起服时建三张配额表),缺一**拒启**并点名缺哪件;值必须是 agent handle 形(`a` 后跟 6–32 位小写十六进制,任务登记表铸的那一形;7.148.0 起由引擎判 —— `asst-1` 这类不透明串、带空白 / 大写 /
|
|
3184
|
+
| `PRINCIPAL_INBOX_ASSISTANT` | 未设 | 7.133.0 起:本部署 **principal 收件箱**的消费方声明 —— 独占读它的那只助理的 agent handle(→ 引擎 `RunnerDeps.principalInboxConsumer: { assistant }`)。**它就是跨主体投递的开关**:设了 ⇒ 挂上组织投递门与受理口 `POST /v1/principal-inbox/messages`(同一组织里给另一个用户投一封信,契约 §22;能力位 `principalInboxDelivery`),同时**要求**耐久 mailbox(`DB_BACKEND=mysql\|pg\|local`)、组织成员目录(中心,或 `MEMORY_ORG_DIRECTORY_JSON`)与配额店(SQL 后端起服时建三张配额表),缺一**拒启**并点名缺哪件;值必须是 agent handle 形(`a` 后跟 6–32 位小写十六进制,任务登记表铸的那一形;7.148.0 起由引擎判 —— `asst-1` 这类不透明串、带空白 / 大写 / 换行的值**拒启**,拒句头说清读法(关 = 未设或空串;空白串不是「空」)并带回被拒的原值(JSON 引号,至多 96 字符),后接引擎原句(引用值同样至多 96 字符);此前这类值照收,收件箱等一只永远不会来的读者);未设 / 空串 ⇒ 没有这条车道,一切与上一版逐字节同。额度写死在门里:发件人每个挂钟整点桶 60 次尝试(成没成都算)、同一对主体每个挂钟整点桶 10 封、一位收件人每个挂钟整点桶合计 30 封、收件箱上界 50 封;「桶」是对齐店钟整点的固定窗(窗宽一小时),不是滑动的「过去 60 分钟」(桶边界两侧各满额,跨边界的一小时里最多两倍)。额度拒的 429 带 `retryAfterSec`(到当前桶结束的整秒数)与同值 `Retry-After` 头,按它重投;本服务的配额状态文件(`DB_BACKEND=local`)读不出时一切投递都拒,答带因的 `500 internal.org_delivery_quota_unreadable`(运维修好或移走坏文件并**重启本服务**即恢复 —— 店只在起服时读这份文件,服务进程运行中把文件移走不会让它恢复;移走 = 当前桶计数清零)。⚠️ 本服务只有投递半:引擎(7.148.0 带的版本起)有读信的助理腿,但那条腿要以这只 handle 作任务 id 跑,本服务今天没有起它的入口(读法候引擎确认),在那之前信留在箱里没人读 |
|
|
3131
3185
|
|
|
3132
3186
|
**自查读面**(`GET /v1/capabilities.permissionModeAuto`,壳的 `sema doctor permissions` 消费;server 7.106.0 起引擎只剩一种武装极性,
|
|
3133
3187
|
7.107.0 起成员 `intentArming` 删除,见该条):
|
|
@@ -3345,11 +3399,15 @@ WebSearch 工具的 `tool_result` 错误文本,回到模型的对话里,**不是
|
|
|
3345
3399
|
|
|
3346
3400
|
`http` 条目 header **值**里的 `$NAME` / `${NAME}` 按条目的 `allowedEnvVars` 展开,读法是契约包 settings-schema 的 `interpolateHookEnvVars`(壳与本服务同调,同一份钩子定义到端点的字节相同):
|
|
3347
3401
|
- 名字只认大写 `[A-Z_][A-Z0-9_]*`;小写名(`$my_token`)是普通文字,原样发出。
|
|
3348
|
-
- 列在 `allowedEnvVars` 里 ⇒
|
|
3349
|
-
|
|
3402
|
+
- 列在 `allowedEnvVars` 里 ⇒ 展开成钩子环境里的值;钩子环境里没有这个名字 ⇒ 空串(不进置空留痕,与参照实现同)。**钩子环境**只有一份(命令钩子的子进程环境读同一份):
|
|
3403
|
+
十二名基础变量(`PATH` / `HOME` / `SHELL` / `USER` / `LOGNAME` / `TERM` / `TZ` / `LANG` / `LC_ALL` / `LC_CTYPE` / `LC_MESSAGES` / `TMPDIR`)∪ 部署方 `HOOK_ENV_ALLOW` 点名放回的服务进程变量,之上叠同请求 `settings.env` 与钩子自己的变量(后者赢)。
|
|
3404
|
+
服务进程的其余变量(含本服务的密钥)不在其中;请求层(条目 `allowedEnvVars`、下面的 `settings.httpHookAllowedEnvVars`)只收窄能插哪些名,**授予不了**任何服务进程变量。
|
|
3405
|
+
- 名单外的引用 ⇒ 空串;凭据名表里的名字(契约包 `HOOK_ENV_CREDENTIAL_NAMES`:`CLAUDE_CODE_OAUTH_TOKEN` 一类 27 个名字 × 裸名与 `INPUT_` 前缀;**不含** `ANTHROPIC_API_KEY` / `MODEL_API_KEY` 这类模型凭据名)一律空串,点进名单也一样。本服务自己的模型凭据不靠这张表护:它们从不进钩子环境(钩子环境 = 净化后的进程环境 allowlist + 同请求 `settings.env`,服务进程的密钥名在扣留名单里),所以 `${ANTHROPIC_API_KEY}` 在本服务上展开成空串是因为钩子环境里没有它,不是因为它在凭据名表里(`HOOK_ENV_ALLOW` 点名它 ⇒ 拒启);7.146.0 起调用方在 `settings.env` 里给这类名字(或任何秘密形的值)新提交即 `400 request.env_credential_refused`(9.5j)。
|
|
3350
3406
|
- 每个 header 值剥 CR / LF / NUL;header 名不展开。
|
|
3351
3407
|
- 置空(名单外 / 凭据名)时日志一行 `hook_http_header_env_blanked`(名字与原因,不带值)。
|
|
3352
|
-
例:`"headers": { "Authorization": "Bearer ${HOOK_TOKEN}" }`、`"allowedEnvVars": ["HOOK_TOKEN"]
|
|
3408
|
+
例:`"headers": { "Authorization": "Bearer ${HOOK_TOKEN}" }`、`"allowedEnvVars": ["HOOK_TOKEN"]`,`HOOK_TOKEN` 放在引擎进程的环境里,部署方写 `HOOK_ENV_ALLOW=HOOK_TOKEN`(值从不经请求体;壳自起的本机引擎由壳按钩子条目的 `allowedEnvVars` 写这只旋钮)。不是凭据的值也可以经同请求 `settings.env` 给。7.125.x 及更早的读法不同(升级见 MIGRATION)。
|
|
3409
|
+
**`HOOK_ENV_ALLOW`(部署旋钮,名单型;缺省空 = 不放回)**:`HOOK_ENV_ALLOW=NAME,NAME` 点到、且服务进程环境里在的变量原样放回钩子环境(同上面的「点名放行」一只谓词与一只解析:形错 / 点名名单型旋钮 / 点名本服务自有凭据名 ⇒ 拒启点名第几段、不回显值;环境里没有的名按序号一行 `config_env_entry_rejected`;点名值是本服务某一枚凭据的另一个变量(换了名的副本;列表形凭据逐枚比 —— `SERVICE_AUTH_TOKENS` 每一枚令牌、`APPROVAL_HMAC_KEYS` 每一把钥)同样拒启,组合这一刻引擎照样扣下这样的值)。
|
|
3410
|
+
点了名就是部署方显式承担:那几只变量对本引擎跑的**每一只** settings hook 可读(命令钩子的环境与 http 钩子的 header),http 钩子发往哪里由 `settings.allowedHttpHookUrls` 管。起服读一次,改名单要重起。`REQUIRE_PRINCIPAL=true` 下忽略(请求的 settings hooks 在该姿态不跑)并起服 warn 一次 `config_env_set_but_ineffective`。
|
|
3353
3411
|
**两张名单 `settings.allowedHttpHookUrls` / `settings.httpHookAllowedEnvVars`(7.142.0 起;CC settings 同名键)**:读法与判决都在契约包 settings-schema,本服务只在 http 条目**拨出之前**问一次(能力位 `taskSettings.httpHookAllowlists`,单用户车道为真):
|
|
3354
3412
|
- `allowedHttpHookUrls`(URL 模式的串数组,例 `["https://hooks.example.com/*"]`)在场 ⇒ 条目 `url` 必须命中其中一条才发出;不命中 / 名单是 `[]` / 名单不是串数组 ⇒ **一个字节都不发**。非托管组:这次 hook 算非阻断故障(fleet 流 `hook_notice` `url_not_allowed`,运维 warn `hook_http_withheld`);
|
|
3355
3413
|
托管组(`source: managedPolicy` / `managedPlugin:*`):失效关闭,`PreToolUse` 在没有否决时改问人。句子点名 `settings.hooks.<事件>` 与规则(`url` / `empty` / `malformed`)。出路:把地址的模式加进名单,或改 hook 的 `url`。
|
|
@@ -3641,7 +3699,7 @@ WebSearch 工具的 `tool_result` 错误文本,回到模型的对话里,**不是
|
|
|
3641
3699
|
- **出路**:把凭据挪进引擎进程的环境 —— 壳起的本机引擎由壳的凭据文件带入(还把凭据写进 `settings.json` 的老壳先升级),服务形部署放进进程环境 / 编排器的 secret 注入。
|
|
3642
3700
|
要让模型 shell 持一枚令牌(`GH_TOKEN` 一类):放在引擎进程环境里一个不在配置目录、也不是任何模型条目 `apiKeyEnv` 的名下,配请求级 `inheritEnv:"all"`(单用户 host 车道)。
|
|
3643
3701
|
值形扫描是粗判:一串不是凭据、却被判成秘密形的值同样要挪出 `settings.env`(改名不救值形)。
|
|
3644
|
-
-
|
|
3702
|
+
- **钩子要用的 token**:http 钩子 header 的 `$NAME` 插值只读钩子环境(9.5c)。秘密形的 webhook token 放进引擎进程的环境,部署方在 `HOOK_ENV_ALLOW` 点名、条目 `allowedEnvVars` 列它(9.5c);拒句里的「挪进引擎进程环境」对钩子就是指这一步。不像秘密的值照旧可以经 `settings.env` 给。
|
|
3645
3703
|
- **续跑**:升级前受理、停驻的任务,存体里带这类条目时,一次性迁移 M38 的窗(本版发布日 + 30 天;窗口见登记表)内续跑把它们从 shell / hooks 的环境里剥掉、任务照续
|
|
3646
3704
|
(运维 warn `settings_env_credentials_dropped`:`migration` / `sessionId` / `dropped: { name, value_shape }` —— 只计数,不带键名与值);窗关后续跑口答 409 `resume_blocked_by_policy`(`blockedBy: "request.env_credential_refused"`,同一组机读位),出路是取消那条 run 后挪走凭据重提。
|
|
3647
3705
|
|
|
@@ -3692,7 +3750,7 @@ WebSearch 工具的 `tool_result` 错误文本,回到模型的对话里,**不是
|
|
|
3692
3750
|
| env | 缺省 | 说明 |
|
|
3693
3751
|
|---|---|---|
|
|
3694
3752
|
| `IMAGE_API_BASE` | 必填 | image-api 根(尾斜杠去掉) |
|
|
3695
|
-
| `BAKE_RUNNER_TOKEN` | 必填 | claim / heartbeat 的运维主体 bearer
|
|
3753
|
+
| `BAKE_RUNNER_TOKEN` | 必填 | claim / heartbeat 的运维主体 bearer。不进日志;7.103.0 起缺省不进子进程(形状剥),但它不在 runner 的自有凭据声明里 —— 别在 `BAKE_ENV_ALLOW` 里点它,也别把同一个值换个名放进 runner 的环境(那两形照交给配方脚本;已知缺口) |
|
|
3696
3754
|
| `BAKE_RUNNER_ID` | `bake-runner-<HOSTNAME>` | 认领时报给 image-api 的 runner 名 |
|
|
3697
3755
|
| `RECIPE_REF` | `HEAD` | 配方 checkout 的 ref(`HEAD` = 用现成 checkout,不 fetch) |
|
|
3698
3756
|
| `RECIPE_DIR` | `/opt/recipes` | 配方仓 checkout 根(build.sh 的 cwd) |
|
|
@@ -3716,7 +3774,7 @@ docker 推送的鉴权走构建宿主上的 docker 凭据存储(`docker login`),
|
|
|
3716
3774
|
**`BAKE_ENV_ALLOW=NAME,NAME`。** 配方真要一枚密钥形 env(例如 build.sh 里自己做 registry 登录要 `REGISTRY_PASSWORD`,或
|
|
3717
3775
|
`git fetch` 的 askpass 读 `GIT_TOKEN`)⇒ 点名它,runner 把该键从本进程 env **原样**放回给每一只子进程组(部署方显式承担)。
|
|
3718
3776
|
与服务侧 `LSP_ENV_ALLOW` 同一只解析器、同一只放行谓词:
|
|
3719
|
-
- 形错(空段 / 尾逗号 / 非变量名形,如 `$NPM_TOKEN`、`a b`、`NAME=value` 整段贴入 / 点名任一只名单型旋钮 / 点名本服务自有凭据名,7.132.0 起)⇒ runner **拒启**,
|
|
3777
|
+
- 形错(空段 / 尾逗号 / 非变量名形,如 `$NPM_TOKEN`、`a b`、`NAME=value` 整段贴入 / 点名任一只名单型旋钮 / 点名本服务自有凭据名,7.132.0 起;点名值是本服务某一枚凭据的另一个变量,7.149.0 起)⇒ runner **拒启**,
|
|
3720
3778
|
`bake_runner_fatal` 那一行点名旋钮与第几段(`entry #k of n`,一句话只有这一套序号),**不回显值**(自有凭据那一形与服务侧同一句:说明这是本部署自己的凭据、给出路,并说明引擎拒它进任何名单);
|
|
3721
3779
|
- 本进程环境里没有的名 ⇒ 起服一行 `config_env_entry_rejected`(只报序号)、不放行;
|
|
3722
3780
|
- 旋钮原文本身按凭据类对待,不进子进程;
|
|
@@ -3884,7 +3942,7 @@ web-admin 拉取 / fleet 公告 / 凭证续签、WebSearch、对象存储、OTLP
|
|
|
3884
3942
|
持锁者或排队者进程没了,下一位读到 pid 不在就清;上行的硬时限(`GATE_SHIP_TIMEOUT_SEC`)在拿到锁之后才起,排队不计入。车不再往自己的命令里抄 `mkdir` 轮询片段。
|
|
3885
3943
|
- **容器的临时目录**(7.148.0 起):`remote-gate.sh` 起的每只容器 `TMPDIR=/wtmp`,挂车道目录旁边的宿主盘目录 `<车道目录>.tmp`(模式 1777;ship 重建、
|
|
3886
3944
|
每次 run 起容器前补建、`clean` 一并删),不挂进 `/w`(仓内的临时目录会让「夹具不在仓里」「裸仓」两类钉红)。容器自己的 /tmp 在可写层上:起真服的钉把
|
|
3887
|
-
local 店的数据根铸在 TMPDIR 下,落在可写层 ⇒ 店的持久性判 `ephemeral
|
|
3945
|
+
local 店的数据根铸在 TMPDIR 下,落在可写层 ⇒ 店的持久性判 `ephemeral`;测试基座部署的车道是 `none`(店在调用方看不见的 worker 盘上 ⇒ 设计声明 `durable`)⇒ 起服拒 `config.store_not_durable`(`REMOTE_EXEC=host` 的格两半声明降为 `process-local`、不拒、warn 一行)。
|
|
3888
3946
|
**Linux 开发机同一律**:/tmp 是 tmpfs 时,`npm test` 前把 `TMPDIR` 设到一只磁盘目录(仓外),否则起服类钉被 `config.store_not_durable` 拒;
|
|
3889
3947
|
macOS 没有挂载表,判 `unknown`、只 warn,不受影响。
|
|
3890
3948
|
- **core 提货门**(`node scripts/core-read-table-gate.mjs`)求交的是 **(当前钉, 目标]** 区间里 core 的**每一版**清单:从目标清单沿 `from`
|