@sema-agent/server 7.150.0 → 7.151.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 +185 -0
- package/USAGE.md +53 -25
- package/deploy/sema-up/README.md +7 -1
- package/deploy/sema-up/chart/Chart.yaml +1 -1
- package/deploy/sema-up/chart/templates/NOTES.txt +5 -0
- package/deploy/sema-up/chart/templates/_helpers.tpl +15 -16
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -3
- package/deploy/sema-up/chart/templates/server.yaml +5 -3
- package/deploy/sema-up/chart/values-full-single.yaml +3 -1
- package/deploy/sema-up/chart/values.yaml +8 -1
- package/deploy/sema-up/cluster-up.sh +1 -0
- package/deploy/sema-up/kube-up.sh +1 -1
- package/deploy/sema-up/lib/flagshape.sh +1 -1
- package/deploy/sema-up/lib/helm-values-cluster.py +2 -0
- package/deploy/sema-up/lib/helm-values-kube.py +2 -0
- package/dist/adoption/import.js +3 -3
- package/dist/approval-ask-machine.d.ts +1 -1
- package/dist/approval-card.d.ts +2 -2
- package/dist/approval-gate-currency.d.ts +1 -1
- package/dist/auth-bridge.d.ts +20 -0
- package/dist/auth-bridge.js +9 -0
- package/dist/background-session-reap.d.ts +1 -1
- package/dist/bake-runner/main.d.ts +4 -2
- package/dist/bind-host.d.ts +2 -3
- package/dist/bind-host.js +2 -4
- package/dist/boot/budget-tracing.js +1 -1
- package/dist/boot/engine-lease.d.ts +5 -0
- package/dist/boot/engine-lease.js +1 -0
- package/dist/boot/execution-env.d.ts +8 -14
- package/dist/boot/execution-env.js +54 -17
- package/dist/boot/execution-lane.js +32 -5
- package/dist/boot/late-binds.d.ts +8 -4
- package/dist/boot/late-binds.js +7 -1
- package/dist/boot/memory-consolidation.d.ts +3 -2
- package/dist/boot/memory-consolidation.js +6 -6
- package/dist/boot/reapers.d.ts +5 -0
- package/dist/boot/reapers.js +12 -1
- package/dist/boot/resolve-spec.d.ts +3 -3
- package/dist/boot/resolve-spec.js +31 -22
- package/dist/boot/runner-deps.d.ts +9 -2
- package/dist/boot/runner-deps.js +3 -3
- package/dist/boot/session-age-out.d.ts +36 -0
- package/dist/boot/session-age-out.js +101 -0
- package/dist/boot/session-faces.d.ts +5 -14
- package/dist/boot/session-faces.js +9 -5
- package/dist/boot/stage-01-config.js +2 -0
- package/dist/boot/stage-05-execution-env.d.ts +5 -3
- package/dist/boot/stage-05-execution-env.js +2 -2
- package/dist/boot/stage-06-runners.d.ts +7 -4
- package/dist/boot/stage-06-runners.js +15 -6
- package/dist/boot/stage-07-capability-layer.d.ts +7 -4
- package/dist/boot/stage-07-capability-layer.js +2 -1
- package/dist/boot/stage-08-reapers.d.ts +7 -4
- package/dist/boot/stage-08-reapers.js +4 -2
- package/dist/boot/stage-09-leader.d.ts +11 -5
- package/dist/boot/stage-09-leader.js +12 -3
- package/dist/boot/stage-10-http-server.d.ts +11 -5
- package/dist/boot/stage-10-http-server.js +3 -6
- package/dist/boot/web-admin.js +3 -1
- package/dist/boot/workflow-orchestration.d.ts +7 -2
- package/dist/boot/workflow-orchestration.js +24 -7
- package/dist/bounded-rotation.d.ts +29 -0
- package/dist/bounded-rotation.js +24 -0
- package/dist/capability-facts.d.ts +22 -13
- package/dist/capability-facts.js +28 -18
- package/dist/center-credential.d.ts +25 -6
- package/dist/center-credential.js +25 -5
- package/dist/config-catalog.d.ts +26 -7
- package/dist/config-catalog.js +14 -11
- package/dist/config-invariants.d.ts +2 -1
- package/dist/config-invariants.js +4 -4
- package/dist/config-types.d.ts +10 -4
- package/dist/config.d.ts +51 -2
- package/dist/config.js +35 -24
- package/dist/deployment-shape.d.ts +9 -1
- package/dist/deployment-shape.js +2 -1
- package/dist/device-protocol.d.ts +5 -4
- package/dist/device-protocol.js +1 -1
- package/dist/device-ws-hub.js +3 -2
- package/dist/device-ws-protocol.d.ts +63 -10
- package/dist/device-ws-protocol.js +56 -25
- package/dist/engine-identity.d.ts +19 -7
- package/dist/engine-identity.js +10 -2
- package/dist/entry-mode-clamp-notice.d.ts +2 -1
- package/dist/execution-env-refusal.d.ts +23 -0
- package/dist/execution-env-refusal.js +5 -0
- package/dist/execution-lane-caps.d.ts +3 -1
- package/dist/field-conflict.d.ts +1 -1
- package/dist/file-history-capture.d.ts +11 -4
- package/dist/file-history-capture.js +9 -6
- package/dist/file-history-disclosure.d.ts +7 -5
- package/dist/file-history-disclosure.js +7 -5
- package/dist/fleet/drain-entry.d.ts +4 -0
- package/dist/hooks/hook-runner.js +2 -2
- package/dist/host-lsp-manager.d.ts +2 -2
- package/dist/http/admission.js +17 -2
- package/dist/http/approval-sweeps.js +5 -5
- package/dist/http/checkpoint-ctx.d.ts +2 -0
- package/dist/http/checkpoint-ctx.js +1 -0
- package/dist/http/dispatch.d.ts +2 -1
- package/dist/http/dispatch.js +34 -27
- package/dist/http/durable-run-leg.js +16 -16
- package/dist/http/health-self-report.d.ts +9 -1
- package/dist/http/health-self-report.js +2 -0
- package/dist/http/owner-access.d.ts +31 -11
- package/dist/http/owner-access.js +37 -6
- package/dist/http/resume-ctx-read.js +25 -3
- package/dist/http/resume-legs.d.ts +2 -1
- package/dist/http/resume-legs.js +259 -79
- package/dist/http/route-ctx.d.ts +18 -8
- package/dist/http/route-table.d.ts +1 -1
- package/dist/http/routes/admin-memory-optout.d.ts +1 -1
- package/dist/http/routes/agents-roster.js +2 -3
- package/dist/http/routes/approvals-assistant.js +4 -3
- package/dist/http/routes/background.d.ts +3 -3
- package/dist/http/routes/capabilities.js +8 -5
- package/dist/http/routes/fleet.js +10 -8
- package/dist/http/routes/projects.d.ts +3 -2
- package/dist/http/routes/projects.js +4 -5
- package/dist/http/routes/runs.js +102 -36
- package/dist/http/routes/session-sync.d.ts +4 -3
- package/dist/http/routes/session-sync.js +172 -77
- package/dist/http/routes/sessions-list.js +13 -7
- package/dist/http/routes/sessions.js +10 -6
- package/dist/http/routes/tasks.js +30 -16
- package/dist/http/routes/trace-usage.js +2 -2
- package/dist/http/server.d.ts +21 -27
- package/dist/http/server.js +2 -2
- package/dist/http/submit-ctx.js +5 -4
- package/dist/http/wire-types.d.ts +14 -4
- package/dist/identity-source.d.ts +20 -3
- package/dist/identity-source.js +14 -0
- package/dist/index.d.ts +4 -0
- package/dist/lane-home-probe.d.ts +3 -7
- package/dist/lane-home-probe.js +0 -1
- package/dist/leader/leader.d.ts +2 -1
- package/dist/leg-facts.d.ts +13 -5
- package/dist/leg-facts.js +2 -1
- package/dist/memory-scope.d.ts +5 -4
- package/dist/memory-scope.js +4 -4
- package/dist/memory-sync-client.d.ts +30 -2
- package/dist/memory-sync-client.js +16 -9
- package/dist/observability/err-text.d.ts +7 -0
- package/dist/observability/err-text.js +5 -0
- package/dist/observability/fail-open.d.ts +7 -3
- package/dist/observability/fail-open.js +7 -3
- package/dist/observability/metrics.js +1 -0
- package/dist/orchestration/workflow-notify-journal.d.ts +18 -1
- package/dist/orchestration/workflow-notify-journal.js +12 -1
- package/dist/orchestration/workflow-park-decision.d.ts +70 -18
- package/dist/orchestration/workflow-park-decision.js +49 -10
- package/dist/orchestration/workflow-park-holder.d.ts +65 -0
- package/dist/orchestration/workflow-park-holder.js +98 -0
- package/dist/orchestration/workflow-record-fence.d.ts +36 -0
- package/dist/orchestration/workflow-record-fence.js +42 -0
- package/dist/owner-faces.d.ts +1 -1
- package/dist/parked-decide.d.ts +104 -53
- package/dist/parked-decide.js +153 -117
- package/dist/peer-directory.d.ts +2 -2
- package/dist/peer-inbound-face.d.ts +2 -6
- package/dist/peer-inbound-face.js +0 -3
- package/dist/permission-mode-admission.d.ts +41 -5
- package/dist/permission-mode-admission.js +29 -3
- package/dist/plugins/adoption-log-sql.d.ts +3 -1
- package/dist/plugins/adoption-log-sql.js +7 -1
- package/dist/plugins/approval-ask-store-file.d.ts +10 -2
- package/dist/plugins/approval-ask-store-file.js +8 -0
- package/dist/plugins/approval-ask-store-memory.d.ts +6 -1
- package/dist/plugins/approval-ask-store-memory.js +28 -9
- package/dist/plugins/approval-ask-store-sql.d.ts +43 -2
- package/dist/plugins/approval-ask-store-sql.js +34 -5
- package/dist/plugins/approval-exemption-store.js +3 -0
- package/dist/plugins/approval-nonce-store.js +2 -0
- package/dist/plugins/breaker-state-sql.js +2 -0
- package/dist/plugins/caching-session-store.d.ts +9 -15
- package/dist/plugins/caching-session-store.js +6 -0
- package/dist/plugins/device-store-sql.js +6 -0
- package/dist/plugins/error-origin.d.ts +18 -0
- package/dist/plugins/error-origin.js +10 -0
- package/dist/plugins/execution-placement-sql.js +6 -6
- package/dist/plugins/image-bake-store-sql.js +6 -0
- package/dist/plugins/image-index-sql.js +4 -0
- package/dist/plugins/landed-attendants.d.ts +212 -0
- package/dist/plugins/landed-attendants.js +161 -0
- package/dist/plugins/leader-run-store-sql.js +4 -0
- package/dist/plugins/local-session-live-reference.d.ts +40 -0
- package/dist/plugins/local-session-live-reference.js +39 -0
- package/dist/plugins/local-session-store.d.ts +71 -33
- package/dist/plugins/local-session-store.js +129 -27
- package/dist/plugins/memory-engine-pg.js +4 -0
- package/dist/plugins/memory-engine-sql-apply.js +5 -2
- package/dist/plugins/memory-engine-tidb.js +4 -0
- package/dist/plugins/memory-optout-grant-store-sql.js +4 -0
- package/dist/plugins/memory-sync-store-pg.js +5 -0
- package/dist/plugins/memory-sync-store-tidb.js +5 -0
- package/dist/plugins/one-time-migrations.d.ts +57 -63
- package/dist/plugins/one-time-migrations.js +162 -90
- package/dist/plugins/org-delivery-quota-store.js +4 -1
- package/dist/plugins/outcome-ledger-sql.js +2 -0
- package/dist/plugins/permission-rule-store-sql.js +11 -4
- package/dist/plugins/pg-cost-quota.js +4 -0
- package/dist/plugins/pg-pool.js +24 -1
- package/dist/plugins/pg-rate-limiter.js +2 -0
- package/dist/plugins/posix-shell-fs.d.ts +6 -1
- package/dist/plugins/posix-shell-fs.js +4 -1
- package/dist/plugins/remote-env-adb.d.ts +19 -15
- package/dist/plugins/remote-env-adb.js +41 -15
- package/dist/plugins/remote-env-connect-seat.d.ts +105 -0
- package/dist/plugins/remote-env-connect-seat.js +72 -0
- package/dist/plugins/remote-env-device.d.ts +22 -5
- package/dist/plugins/remote-env-device.js +106 -8
- package/dist/plugins/remote-env-e2b.d.ts +15 -6
- package/dist/plugins/remote-env-e2b.js +42 -32
- package/dist/plugins/remote-env-file-error.js +6 -2
- package/dist/plugins/remote-env-host.d.ts +17 -0
- package/dist/plugins/remote-env-host.js +30 -38
- package/dist/plugins/remote-env-k8s.d.ts +41 -39
- package/dist/plugins/remote-env-k8s.js +53 -30
- package/dist/plugins/remote-env-local-docker.d.ts +13 -8
- package/dist/plugins/remote-env-local-docker.js +34 -41
- package/dist/plugins/remote-env-ssh.d.ts +18 -12
- package/dist/plugins/remote-env-ssh.js +60 -59
- package/dist/plugins/remote-shell.d.ts +98 -1
- package/dist/plugins/remote-shell.js +218 -0
- package/dist/plugins/resume-anchor-store-sql.d.ts +11 -2
- package/dist/plugins/resume-anchor-store-sql.js +12 -5
- package/dist/plugins/retention-lane-store-sql.js +4 -0
- package/dist/plugins/retention-sql.d.ts +20 -2
- package/dist/plugins/retention-sql.js +11 -0
- package/dist/plugins/run-store-sql.d.ts +21 -2
- package/dist/plugins/run-store-sql.js +31 -7
- package/dist/plugins/scenario-prefix-switch-m42.d.ts +1 -1
- package/dist/plugins/scenario-prefix-switch-m42.js +2 -2
- package/dist/plugins/schema-consistency.d.ts +4 -2
- package/dist/plugins/schema-consistency.js +19 -2
- package/dist/plugins/send-file-ledger.js +3 -0
- package/dist/plugins/serving-requirement.d.ts +26 -7
- package/dist/plugins/serving-requirement.js +11 -4
- package/dist/plugins/session-birth.d.ts +6 -2
- package/dist/plugins/session-capture-record-store-sql.js +2 -0
- package/dist/plugins/session-ext-table.d.ts +14 -1
- package/dist/plugins/session-ext-table.js +5 -1
- package/dist/plugins/session-row-sql.d.ts +49 -2
- package/dist/plugins/session-row-sql.js +56 -13
- package/dist/plugins/session-store-sql.d.ts +34 -18
- package/dist/plugins/session-store-sql.js +98 -17
- package/dist/plugins/shared-memory-store-sql.d.ts +1 -0
- package/dist/plugins/shared-memory-store-sql.js +6 -2
- package/dist/plugins/sql-driver.d.ts +2 -1
- package/dist/plugins/sql-driver.js +18 -3
- package/dist/plugins/sql-errors.d.ts +11 -6
- package/dist/plugins/sql-errors.js +5 -6
- package/dist/plugins/stop-then-start-sentence.d.ts +10 -4
- package/dist/plugins/stop-then-start-sentence.js +14 -10
- package/dist/plugins/stop-then-start.d.ts +109 -0
- package/dist/plugins/stop-then-start.js +104 -0
- package/dist/plugins/store-backend.d.ts +40 -13
- package/dist/plugins/store-backend.js +169 -27
- package/dist/plugins/store-boundary.d.ts +57 -0
- package/dist/plugins/store-boundary.js +139 -0
- package/dist/plugins/store-contracts.d.ts +17 -0
- package/dist/plugins/store-fault-sentence-m53.d.ts +7 -0
- package/dist/plugins/store-fault-sentence-m53.js +25 -0
- package/dist/plugins/store-fault.d.ts +26 -7
- package/dist/plugins/store-fault.js +18 -2
- package/dist/plugins/task-attachment-store.js +9 -0
- package/dist/plugins/task-list-store-sql.d.ts +2 -2
- package/dist/plugins/task-list-store-sql.js +10 -8
- package/dist/plugins/tidb-cost-quota.js +4 -0
- package/dist/plugins/tidb-pool.js +2 -1
- package/dist/plugins/tidb-rate-limiter.js +4 -0
- package/dist/plugins/user-input-ledger-sql.js +4 -0
- package/dist/plugins/workflow-run-store-sql.d.ts +28 -10
- package/dist/plugins/workflow-run-store-sql.js +64 -4
- package/dist/plugins/workspace-fill.d.ts +4 -7
- package/dist/plugins/workspace-fill.js +2 -1
- package/dist/plugins/write-behind-counter.js +5 -0
- package/dist/project-context.d.ts +0 -2
- package/dist/project-context.js +4 -8
- package/dist/project-registry.d.ts +46 -0
- package/dist/project-registry.js +44 -0
- package/dist/request-key-closure.js +1 -1
- package/dist/request-value-closure.d.ts +4 -0
- package/dist/request-value-closure.js +10 -0
- package/dist/run-acceptance.d.ts +3 -2
- package/dist/run-acceptance.js +4 -6
- package/dist/run-local.js +1 -0
- package/dist/runs.d.ts +37 -8
- package/dist/runs.js +53 -12
- package/dist/runtime-governance.d.ts +5 -4
- package/dist/security.d.ts +30 -32
- package/dist/security.js +41 -7
- package/dist/server-secret-env.d.ts +12 -10
- package/dist/server-secret-env.js +24 -15
- package/dist/session-bindings.d.ts +82 -0
- package/dist/session-bindings.js +18 -0
- package/dist/session-children-retire.d.ts +2 -2
- package/dist/session-children-retire.js +2 -6
- package/dist/session-deletion.d.ts +16 -1
- package/dist/session-error-wire.d.ts +3 -3
- package/dist/session-error-wire.js +3 -3
- package/dist/session-incarnation.d.ts +10 -0
- package/dist/session-incarnation.js +10 -1
- package/dist/session-kind.d.ts +57 -0
- package/dist/session-kind.js +22 -0
- package/dist/session-row.d.ts +21 -1
- package/dist/session-row.js +7 -1
- package/dist/session-sync-kernel.d.ts +24 -14
- package/dist/session-sync-kernel.js +3 -6
- package/dist/session-sync.d.ts +4 -98
- package/dist/session-sync.js +1 -71
- package/dist/session-titler.d.ts +10 -3
- package/dist/session-titler.js +19 -6
- package/dist/ssh-host-key.d.ts +5 -0
- package/dist/ssh-host-key.js +3 -0
- package/dist/stores-sql/file-history-store-sql.d.ts +52 -2
- package/dist/stores-sql/file-history-store-sql.js +108 -70
- package/dist/stores-sql/pg-session-storage.d.ts +34 -7
- package/dist/stores-sql/pg-session-storage.js +37 -13
- package/dist/stores-sql/retention-store-sql.d.ts +1 -9
- package/dist/stores-sql/retention-store-sql.js +2 -10
- package/dist/stores-sql/session-policy-store-sql.d.ts +30 -7
- package/dist/stores-sql/session-policy-store-sql.js +61 -44
- package/dist/stores-sql/session-write-hooks.d.ts +11 -0
- package/dist/stores-sql/tidb-session-store.d.ts +58 -7
- package/dist/stores-sql/tidb-session-store.js +37 -13
- package/dist/submission-exit.d.ts +3 -2
- package/dist/submission-exit.js +9 -1
- package/dist/task-cwd.d.ts +2 -2
- package/dist/task-settings.d.ts +6 -5
- package/dist/terminal.d.ts +33 -2
- package/dist/terminal.js +139 -9
- package/dist/tool-approval.d.ts +140 -6
- package/dist/tool-approval.js +165 -72
- package/dist/trace/self-minted-wire.d.ts +290 -27
- package/dist/trace/self-minted-wire.js +101 -13
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +78 -27
- package/package.json +2 -2
- package/wire-changes/server@7.151.0.json +762 -0
- package/dist/http/session-inherit-env.d.ts +0 -36
- package/dist/http/session-inherit-env.js +0 -6
package/USAGE.md
CHANGED
|
@@ -580,7 +580,9 @@ MODEL_CODE_ROLES=default,subagent # 不设=全中立;仅这些角色在「
|
|
|
580
580
|
- **org 记忆准入(7.0.0 起 BREAKING)**:`org:*` 记忆 scope 分**两个来源**——部署自证
|
|
581
581
|
(env `MEMORY_SCOPE` 的 org 形 + **单用户部署**的 `projects[].defaultScopes` org 键)直通;**多租户**
|
|
582
582
|
部署里由调用方 `projectId` 选中的登记簿 org 键算 **request 来源**,必须拿到授权目录的逐 principal
|
|
583
|
-
授予才准入,拿不到一律 fail-closed
|
|
583
|
+
授予才准入,拿不到一律 fail-closed 拒。登记簿默认读层只取提交者**看得见**的登记(与 `GET /v1/projects/:id`
|
|
584
|
+
同一只判:fleet 调用方看全部,带主体的调用方只看 `registeredBy` 是自己的)—— 提交一只看不见的项目 id
|
|
585
|
+
与提交一只未登记 id 同答(没有默认读层、不拒、拒句不点名)。目录源**三态单选,
|
|
584
586
|
授权面不双源合并**:web-admin 远程腿(per-principal `orgMemory` 段)> `MEMORY_ORG_DIRECTORY_JSON`
|
|
585
587
|
静态表 > 缺席(request 来源的 org scope 恒拒)。同一个目录也是 `GET /v1/memory/export` /
|
|
586
588
|
`POST /v2/memory/sync/:scope` 的 `org:` 属主门真源(写面另需条目 `write:true`);拒绝形 = 终局
|
|
@@ -771,6 +773,13 @@ MODEL_CASCADE_LADDER=deepseek-flash,deepseek-pro # 目录里的模型名,cheap
|
|
|
771
773
|
分区会话不进会话列表(`GET /v1/sessions`、`/resume`);属主按帧上的 `transcriptId` 读 `GET /v1/sessions/<transcriptId>`(体上带 `agent` 键)。记录被收割时转录一并删除(`BG_AGENT_RETENTION_MS`,缺省 7 天;
|
|
772
774
|
记录已不在的分区会话由分区孤儿腿按同一视界收);删根会话不连带删子代转录。会话同步往子代 id 上写 ⇒ `409 conflict.session_placed`。
|
|
773
775
|
本机形升级前停驻时被拷进宿主店的旧子代转录是普通会话(进列表、不随记录删),要清就 `DELETE /v1/sessions/<id>`。
|
|
776
|
+
- **客户端放置的子代会话(会话种类 `sessionKind`,server ≥7.151.0;能力位 `sessionKinds`)**:壳自己起的子代对话(Agent 子代、serve 每次对话一只新会话)在**建这只会话的那一笔提交**里带
|
|
777
|
+
`sessionKind: "sidechain"`。这种会话不进 `GET /v1/sessions` 的缺省视图与 `ListAgents`(`GET /v1/sessions?sessionKind=sidechain` 单列它们;列表行与 `GET /v1/sessions/:id` 体上带 `sessionKind`),
|
|
778
|
+
不能作 `SendMessage` 的跨会话收件人;按 id 的读写(视图 / 头 / 事件流 / 改名 / 删除 / fork / 同步)与普通会话相同。种类终身不改:带键提交到种类不同的既有会话 ⇒ `409 conflict.session_kind_mismatch`;
|
|
779
|
+
续轮不带键照常。fork / 同步导入建的会话无种类(「先在本地建 sidechain 再同步上云」到云上是普通会话)。**老化**:最后活动(run / 追加 / 收场推它;**读不是活动**)之后过
|
|
780
|
+
`BG_AGENT_RETENTION_MS`(缺省 7 天,与后台子代行同一根旋钮)、且没有在跑的 run / 待决的审批 / 在跑的子代或 workflow 挂着它、所在域不在托管留存的保全中 ⇒ 维护拍(`REAP_INTERVAL_SEC`)经删除协调器删除
|
|
781
|
+
(每拍至多 64 只 / 5 s,跨拍轮转;每删一只一行 `session_aged_out`,计数 `sidechain_sessions_aged_out_total`,跳过按理由计 `sidechain_age_out_skipped_total{reason}`)。之后按 id 读 404。
|
|
782
|
+
`DB_BACKEND=memory` 记不了种类:能力位 `[]`,带键提交 `400 request.precondition_unmet`。⚠️ SQL 两后端的活引用判(老化与托管留存同一句)读 `workflow_run` 表:显式 `WORKFLOW_RUN_STORE=file` / `memory` 的 SQL 部署上,workflow 记录不在那张表里,会话发起的在跑 workflow 护不住它(缺省 `auto` 用 SQL 孪生,不受影响)。
|
|
774
783
|
- **任务清单(TaskCreate/TaskList 家族)的持久边界**:清单按**会话**分区,同一会话
|
|
775
784
|
跨 turn/跨 resume 连续,跨会话互不可见。配了 SQL 后端(`SESSION_BACKEND=mysql` / `DB_BACKEND=pg`)
|
|
776
785
|
时落 `task_list_meta`/`task_list_item` 两表 ⇒ **跨副本、跨重启都续得上**;**没有 SQL 后端的形态
|
|
@@ -940,7 +949,7 @@ MODEL_CASCADE_LADDER=deepseek-flash,deepseek-pro # 目录里的模型名,cheap
|
|
|
940
949
|
- `WORKSPACE_FILE_MAX_BYTES` 随面转 INERT(值仍收下并校验,center 推送兼容;不再有任何效果)。
|
|
941
950
|
- rewind 的新姿势:提交带 `resumeAt` + `restoreFiles: true`(或 code-only 的 `rewindFilesTo`)⇒
|
|
942
951
|
引擎把**本会话跟踪集**收敛到该消息时刻的边界;`acceptPartialRestore: true` 容忍部分恢复
|
|
943
|
-
(缺省=响亮失败带逐文件账本)
|
|
952
|
+
(缺省=响亮失败带逐文件账本)。`rewindFilesTo` 不与 `cascade: true` 同体(梯级每一级在现铸的会话里跑、没有这只会话的历史)⇒ 受理时 400 `request.field_conflict`,梯子一级都不起;去掉其一重提。旧键 `rewindFiles` 已不在提交面上:fresh 提交带它 ⇒ 400 `request.body_shape`
|
|
944
953
|
(`unknownKeys` 点名它;捕获不需要请求,还原写 `resumeAt` + `restoreFiles: true`);盘上旧任务体里的它零读者。
|
|
945
954
|
- rewind 与设备车道(`REMOTE_EXEC=device`):带 `resumeAt` 的那一发是**根提交**(不是续跑一族),`deviceId` 照收、按根提交的规矩判 —— 已绑:缺席 = 沿用 / 同 = 幂等 /
|
|
946
955
|
异 = 403 `device.identity_mismatch`(rewind 不换设备,换设备走显式换绑);未绑:携 = 首绑、缺席 = 409 `device.not_bound`;非 device 车道携它 = 400 `request.precondition_unmet`。
|
|
@@ -993,6 +1002,9 @@ SEMA_WEB_ADMIN_TOKEN=<SERVICE_PULL_TOKEN 的值> # 取自配置控制面主机
|
|
|
993
1002
|
# 🔴 拒启两形:内容读不成([config.center_credential_malformed]:`{` 开头坏 JSON / 信封多键缺键 /
|
|
994
1003
|
# issuer 非 http(s) / 裸行不是令牌)、多租户(REQUIRE_PRINCIPAL=true)读到信封
|
|
995
1004
|
# ([config.center_credential_user_session_multi_tenant])。运行期同形 = 该次取值 fail-closed + 一次 warn。
|
|
1005
|
+
# SEMA_WEB_ADMIN_ASSERTION_TOKEN=<wat_…> # 7.151.0:web-admin 断言令牌(编排器给配了凭据库的受管引擎注入;手接引擎改用 SEMA_WEB_ADMIN_ASSERTION_TOKEN_FILE,
|
|
1006
|
+
# 两键二选一、都设=拒启,与上面那一对同一只判官)。本版只读声明:GET /health 的 center.assertionToken 答 declared / absent,
|
|
1007
|
+
# 起服一行 center_assertion_token;不读文件内容、不向中心出示。它是本服务自有凭据,宿主子进程环境里扣掉。
|
|
996
1008
|
# CENTER_CREDENTIAL_RENEW_LEAD_MS=300000 # 续签提前量(ms;缺省 5 min)。0 = 关续签、只读信封(壳负责续);其余须为 [8000, 1800000] 内整数,
|
|
997
1009
|
# 坏值拒启。续签成功 info center_credential_renewed;真失效(refresh token 已作废)warn
|
|
998
1010
|
# center_credential_renew_failed 一次 + /health.centerCredential.renewal.state=failed,到期后中心请求
|
|
@@ -1046,8 +1058,9 @@ FLEET_ADVERTISE_ADDRESS=http://<本机可达IP>:8090 # 可选:设了才启公
|
|
|
1046
1058
|
# warn fleet_announce_reply_unreadable)。只有显式的 capabilities 对象是中心的声明。
|
|
1047
1059
|
# FLEET_SCOPE=acme # 7.121.0:本引擎所在的**租户 scope**(配置渲染器对每台受管引擎写,缺省 scope 也写 = 它的 per-worker 令牌绑的 scope)。缺席 =
|
|
1048
1060
|
# 缺省 scope global;在场必须是 scope id 形(小写字母 / 数字 / 内部连字符,1–64;空串拒启
|
|
1049
|
-
# config.fleet_scope_invalid)。与 FLEET_GENERATION
|
|
1050
|
-
# 请求不带 scope 读成 global
|
|
1061
|
+
# config.fleet_scope_invalid)。与 FLEET_GENERATION 不联动。两处读同一个值:① 排空口的身份比对(请求的 scope 与它比,
|
|
1062
|
+
# 请求不带 scope 读成 global);② 7.151.0 起 fleet 成员(设了 FLEET_GENERATION)上的登录令牌准入 —— 令牌验过签而
|
|
1063
|
+
# scope 不等于它 ⇒ 整次请求 403 auth.scope_mismatch(/health 不拒;非成员不比对;没有旋钮)。续租体与心跳不带它(scope 由中心凭证绑定)。
|
|
1051
1064
|
# FLEET_LEASE_OUTAGE_MAX_MS=86400000 # 7.121.0:一台实例**活着而不服务的最长时长**(缺省 24 h;< 60000 / 0 / 非整数拒启)。两处读它:
|
|
1052
1065
|
# ① 服务租约中心不可达的容忍上限 —— 租约过期(中心不可达 / 答 unknown)后照常服务,过期满这么久 ⇒
|
|
1053
1066
|
# 新工作 503 state.lease_expired(Retry-After 60;取消 / HITL 应答 / 续跑 / 读面照放行,在飞不动,
|
|
@@ -1247,6 +1260,7 @@ UNREACHED_ASK_TTL_MS=3600000
|
|
|
1247
1260
|
(代价是超限的 ask 走 park,要有人去审批队列捞);库压大 → 调小 `STREAM_APPROVAL_RECONCILE_BATCH`
|
|
1248
1261
|
(代价是收敛变慢,靠队列轮转保证下轮接着扫)。
|
|
1249
1262
|
- **停驻行最长活多久(local 文件后端与 SQL 店同一公式)**:一张 pending 的 checkpoint 行在 `max(createdAt + APPROVAL_TERMINAL_BACKSTOP_MS, deadline + 1h)` 到点后由后台 reaper(每 `REAP_INTERVAL_SEC`,缺省 60 s 一拍)expire;`deadline` 只在配了审批 SLA / TTL 时有,没配就是 `createdAt + 后备上限`。旋钮缺省 30 天、下钳 60 s、非有限值落缺省。到点的行先 expire,挂起的 run 行随后由 reaper 翻成 `failed`(`errorCode: approval.expired`)。所以「老停驻行在 local 后端最长活多久」= 后备上限(缺省 30 天)+ 最多一拍;要缩短就调 `APPROVAL_TERMINAL_BACKSTOP_MS`(两店同辖)。
|
|
1263
|
+
- **workflow 停驻卡在多副本上的决断(7.151.0 起;`REAP_INTERVAL_SEC` 是它的跨副本生效延迟)**:持有这张卡的 run 读作 `running` 期间,任一副本上的 `/decide` 先把决定落成一条耐久决定行(落在那条 run 的记录行锁里,同一张卡先受理的决定立住,另一个决定答 409 `decide.claim_lost`),答 200 `{taskId: <workflow run id>, status: "resuming"}`,不起宿主一跑;跑那条 run 的进程恰是受理的那一只 ⇒ 当场交给引擎,否则跑它的进程在下一个维护拍(每 `REAP_INTERVAL_SEC`,缺省 60 s;每拍至多 64 条、墙钟预算 5 s,超出的轮到下一拍)把行交给 run。run 先收场 ⇒ run 的完成送达把行交给宿主会话的下一跑(服务端起的一跑:以卡属主为主体,宿主停在 `task_done` 卡上时那张卡的属主必须是同一个,付费方两门照判、拒即不起(中心不可达 ⇒ 下一拍重投);一行 `workflow_park_handoff_refused` + `workflow_park_handoff_total{result}` 计数,行留着、卡可再决)。没有新旋钮:要更短的跨副本生效延迟就调低 `REAP_INTERVAL_SEC`(同一拍的其余各腿一起变快,库读一起变多)。持有进程死掉而记录仍读作 `running` ⇒ 要等孤儿窗(`WORKFLOW_ORPHAN_GRACE_MS`,缺省 24 h)翻 `failed` 后才交出;记录收场了而终态记录没写进去同等(完成留着待恢复扫);`WORKFLOW_RUN_STORE=memory` 没有完成日志 —— 要重投的转交不重投,一行 `workflow_park_handoff_not_redelivered`,决定由宿主会话的下一跑带或再决。
|
|
1250
1264
|
- **SQL 店写停驻行的预判与 SLA 拒扫的取行序(7.136.0 起)**:`put` 先看这份检查点放不放得进索引列 —— 没有 `gate` / `pendingAction` 对象,或门上卡词的 UTF-8 **字节**数超过 `approval_card` 列的容量(MySQL 协议 `TEXT` 65,535 字节;PG 无上限),抛 `CheckpointIndexRefusedError`(`err.refusal.kind` 为 `unreadable` / `card_too_long`),一句 SQL 都不发 —— 严格与非严格 sql_mode 的库都一样,不会落成半只卡词;引擎自己铸的检查点不会触发。SLA 拒扫每拍至多取一页(100 行),取行序是到期时刻(同刻按行键);拒扫按页**轮转**走全部到期审批 —— 每拍从上一拍取到的最后一行之后接着取,一页取不满就回到队首(local 文件后端同律)。所以一页每拍都被拒的行(引擎认领前拒、停驻子代、本版不重放的存量体、混跑窗里旧副本停驻的问答行……)挡不住排在后面的到期审批:到期审批数为 N 时一圈走 ⌊N/100⌋ + 1 拍(最后一拍取到的不满一页),每一张每圈被试一次;一行的存体读法抛出只让这一行这一拍不续(运维日志 `deny_sweep_row_failed`)。
|
|
1251
1265
|
- **审批账本保留多久(`APPROVAL_ASK_RETENTION_MS`,缺省 `2592000000` = 30 天;local 文件后端与 SQL 店同一条律)**:审批在盘上有三本账 —— 问账(SQL 的 `approval_ask` / `approval_batch`,local 的
|
|
1252
1266
|
`<数据根>/approval-asks/asks.jsonl`)与 local 审计账(`<数据根>/approval-ask-audit/ledger.jsonl`,`GET /v1/approvals` 的 `crashConverged` 读它)。一问**结了**且它最后一次动静早于
|
|
@@ -1943,7 +1957,8 @@ invalid_using_default` 警告 + 退回缺省值」这条臂随词表放宽一并
|
|
|
1943
1957
|
所以它只在「worker 盘就是调用方的盘」时挂 —— host 车道、未设 `REQUIRE_PRINCIPAL=true`(多主的 host 部署本来就拒启)。PATH 上有对应的
|
|
1944
1958
|
language server 就用,没有就优雅退回 grep / read;`LSP_HOST_ENABLED=false` 关掉。**其余车道没有 LSP**:e2b / k8s / local-docker / ssh / adb /
|
|
1945
1959
|
device / none 一律不挂,模型名册里没有 LSP 工具、`wiring_manifest` 上没有 `lsp` 段,代码导航用 grep / read。服务入口与 `run-local` 同一条律。
|
|
1946
|
-
沙箱车道的 LSP 桥已删除(7.127.0
|
|
1960
|
+
沙箱车道的 LSP 桥已删除(7.127.0 起它本来就挂不上:引擎只读执行环境「绑定」的那只文件,当时沙箱车道不实现绑定读;今天沙箱车道的绑定读是逐答重绑,
|
|
1961
|
+
LSP 挂不挂照旧只看上面那一条律,沙箱里的语言服务器要另一条传输);它的开关 `LSP_ENABLED`
|
|
1947
1962
|
是墓碑(上表),设了任一值都拒启,空串按未设。e2b 模板里烤的语言服务器只是工具链内容(模板的月检只验它们在不在,不验有没有谁在驱动它们)。
|
|
1948
1963
|
|
|
1949
1964
|
**host 腿语言服务器拿到的环境 + 点名放行 `LSP_ENV_ALLOW`(7.101.0 起)**:host 腿的语言服务器是本机子进程,它拿到的环境
|
|
@@ -1980,9 +1995,9 @@ device / none 一律不挂,模型名册里没有 LSP 工具、`wiring_manifest`
|
|
|
1980
1995
|
|
|
1981
1996
|
**请求级 `inheritEnv`(7.106.0 起)—— 调用方声明,不是部署旋钮**:提交体顶层键 `inheritEnv:"all"` 让**这一条请求**的模型驱动 host shell
|
|
1982
1997
|
继承整份用户环境(CC 交互形,用户自己的凭据形变量在内)—— 🔴 **但不含本服务自己的凭据**(7.129.0 起,引擎 7.51.1):配置目录全部 `type:"secret"` 名
|
|
1983
|
-
(`SERVICE_AUTH_TOKEN(S)` / `APPROVAL_HMAC_KEYS` / `MODEL_API_KEY` …)与名单型旋钮名起服已向引擎声明为本进程自有凭据,生效配置里每条模型条目的 `apiKeyEnv` 也在名单里
|
|
1998
|
+
(`SERVICE_AUTH_TOKEN(S)` / `APPROVAL_HMAC_KEYS` / `MODEL_API_KEY` …)、bake-runner 的 bearer `BAKE_RUNNER_TOKEN`(7.151.0 起;runner 进程自己的凭据,不是配置目录行,三个进程同一份声明)与名单型旋钮名起服已向引擎声明为本进程自有凭据,生效配置里每条模型条目的 `apiKeyEnv` 也在名单里
|
|
1984
1999
|
(中心热应用新增 / 改名条目时在模型目录换代前重声明,名单只随落地的世代增长 —— 改名后旧名照扣到重启,没落地的候选不留痕;条目的 `apiKeyEnv` 是引擎扣不住的名,或它点到的名正被某只名单型旋钮交给沙箱 / 语言服务器(见下文沙箱名单段)⇒ 该候选整拒),`"all"` = 整份环境**减**它们,任何继承词都不把它们
|
|
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)——
|
|
2000
|
+
交给模型 shell(能力位 `inherit_env.own_credentials_withheld` = 最近一次声明 ⊇ 当前生效配置应声明的集合;真要让模型 shell 持某枚令牌 ⇒ 放在引擎进程环境里一个不在配置目录、也不是任何模型条目 `apiKeyEnv` 的名下,配 `inheritEnv:"all"`;7.146.0 起请求 `settings.env` 不收凭据,见 9.5j);这些变量此刻装着的**每一枚凭据**也交给引擎按值扣(名单型旋钮除外:它们的原文是一张变量名单,不是凭据,只按名扣、原文不交引擎比值 —— 7.151.0 起;此前名单原文也被当一枚凭据比值,`LSP_ENV_ALLOW=GOPATH` 这类短名单因此冒下面那行告警、把值能力位翻 false)—— 整值,列表形另加每一枚:`SERVICE_AUTH_TOKENS` 表里的每一枚令牌、`APPROVAL_HMAC_KEYS` 里的每一把钥(7.149.0 起;此前只交整张表的原文,表里一枚令牌换个变量名放着照进模型 shell)——
|
|
1986
2001
|
同值换名的副本同样进不了模型 shell(整串比:`Bearer <令牌>`、令牌多一个字符 / 少一个字符、只是系统名的值都不是副本,照交),引擎判某一枚「不是凭据值」(空白 / 占位词 / 一个字符重复 / 不足 8 字符)⇒
|
|
1987
2002
|
那一枚不按值扣(同一变量的其余几枚照扣,名照扣、不拒启,能力位 `inherit_env.own_credential_values_withheld` 答 false),起服与模型目录换代时每个这样的变量出**一条** warn 结构化行 `own_credential_value_not_withheld { name, reason }`
|
|
1988
2003
|
(`reason` 是引擎的拒句原文,从不回显值;起服第一步 logger 还没建时,这一行当拍以同一行形写 stderr,不缓冲;logger 接上之后——模型目录换代并进的条目的值被拒——这一行受 `LOG_LEVEL` 约束,`error` 级读不到,机读事实读上面那个能力位)—— 按事件名告警,给该变量一个真值即可。值是**网关密钥**(`MODEL_API_KEY` / `ANTHROPIC_API_KEY`,起服交给模型适配器的那一个)时也只有这一行:引擎在适配器构造口收下同一个值,声明口拒过的值它不再说第二遍(此前这里写的「另有引擎自己的一行裸文本」已不成立);给密钥一个真值这一行消失。`"scrub"` / 缺席 = 上面的缺省剥除。🔴 **`"all"` 只在单用户部署兑现**:`REQUIRE_PRINCIPAL=true`
|
|
@@ -2075,6 +2090,10 @@ bake-runner 要用 ⇒ `LSP_ENV_ALLOW` / `BAKE_ENV_ALLOW` 点名放回。
|
|
|
2075
2090
|
> **装了中心鉴权桥(`SEMA_WEB_ADMIN_URL` 在位即默认开,或 `AUTH_BRIDGE_ISSUER`)就不是 dev-open**(7.132.0 起;此前这一形被读成 dev-open):带登录令牌的调用方按令牌里的身份钉人,
|
|
2076
2091
|
> 不带任何凭据的列表 `401 auth.unauthorized`、`/metrics` 族 `401`(要 `METRICS_TOKEN`)。仍成立的边界:没配 service token 的部署上,不带登录令牌的请求自报的主体头仍按身份读
|
|
2077
2092
|
> (与 `REQUIRE_PRINCIPAL` 无 token 形同读)—— 要让「没令牌就没有身份」成立,配 `SERVICE_AUTH_TOKEN`(全局凭据门:每个请求要么带 service token、要么带登录令牌)。
|
|
2093
|
+
>
|
|
2094
|
+
> **写门问请求(7.151.0+;契约 §0.13)**:计费提交、改写门、破坏性会话写只收带**过门凭据**的请求 —— service token,或鉴权桥验过的登录令牌(直连门的审批令牌不算);
|
|
2095
|
+
> 都没带 ⇒ 503 `auth.service_token_required`(`ALLOW_UNAUTHED_WRITES=true` 照旧放行;配了 service token 的部署上这样的请求先吃全局凭据门的 401)。所以只装了鉴权桥、没配 service token 的部署上,带登录令牌的用户提交得了任务
|
|
2096
|
+
> (≤ 7.150.x 一律 503),不带的照旧 503;只开 `REQUIRE_PRINCIPAL` / 只配 `TRACE_TOKEN` 的部署上谁都过不了这道门。
|
|
2078
2097
|
|
|
2079
2098
|
> **不报主体的 service token 是谁(`SERVICE_TOKEN_ACTS_FOR_DEPLOYMENT`,7.146.0+)**:出示这台部署的 service token 而**不带主体头**的请求,缺省(不设 = `true`)代部署本人说话 ——
|
|
2080
2099
|
> fleet 读面(舰队流 / 会话列表 / 发件链接 / 名册 / trace / 用量)看全舰队、运维聚合口(`/metrics*`、`GET /v1/tasks/source-summary`)照放、删除 / fork / 同步对任何会话照开。
|
|
@@ -2120,9 +2139,15 @@ PostgreSQL 仍只有 8 MiB。这一窗的 413 句子说是假定(`the database's
|
|
|
2120
2139
|
事实在场、但这一堵墙读失败退了文档缺省(TiDB < 7.6 又无 `CONFIG` 权限读不到单行上限;`max_allowed_packet` 读不出)的不会自己变真,请运维让库账号读得到那个上限(`GET /v1/diagnostics/wiring` 的 `sqlEngine.wallSources` 逐堵说出处)。
|
|
2121
2140
|
`PUT /v1/sessions/:id/sync/blobs/:hash` 超 SQL 快照 blob 帽的 `413 blob_too_large_for_sql` 同样带 `wallSource`,词多一个 `"operator"`(帽是你设的 `SNAPSHOT_BLOB_SQL_MAX_BYTES`),句子按三形分:旋钮 / 库报的墙 / 没读到的假定墙。
|
|
2122
2141
|
受理口放行、写续跑输入那一笔被库以「一行装不下」拒时(开了 durable 审批的部署)答同一个 413,出路按拒它的那堵墙给(TiDB 单行墙 ⇒ 抬 `txn-entry-size-limit`;语句墙 ⇒ 抬 `max_allowed_packet`;
|
|
2123
|
-
PostgreSQL 硬上限 ⇒
|
|
2142
|
+
PostgreSQL 硬上限 ⇒ 只有缩小;7.151.0 起 413 句与错误本身不再括号带库的原句,库的那句在店边界那一行 `at=store` 里),运维日志一行 `submit_ctx_row_too_large`(`wall` 点名那堵墙);刚认领的 run 当场撤掉,撤认领的库写自己也失败时一行 `submit_ctx_run_release_failed`(带步名)
|
|
2124
2143
|
并计 `submit_ctx_run_release_failed_total{step}`,会话到 `REAP_RUN_STALE_SEC` 才放。
|
|
2125
2144
|
|
|
2145
|
+
**SQL 店失败时库的原话在哪(7.151.0 起)**:任何一只 SQL 店的失败越过店边界时只带驱动的原码与一句对外句(类别句 + `[original code: <码>]`)—— run 终局、子代结算卡、后台子代通告、
|
|
2146
|
+
`GET /v1/runs/:id/subagents/:handle/output`、文件历史与记忆补丁的失败句都是这一句。要库的原话读 worker 日志的店边界那一行:
|
|
2147
|
+
`[terminal] outward_failure_code_folded original=<码 | <uncoded>> outward=<internal.store_error | -> messageBytes=<n> at=store site=<店>.<方法> class=<类别> message=<JSON 串>`
|
|
2148
|
+
(`message=` 是原错与其 `cause` 链各层的句子,经出口座:凭据形换记号、剥控制字符、有界;`class` 是店故障判官的词:`connection` / `deployment` / `corrupt` / `defect` / `unclassified`),
|
|
2149
|
+
计数 `store_boundary_fault_total{site,class}`。run 终局离开引擎时的 `at=exit` 那一行照旧出,`message=` 已是对外句;按 `original=` 与时间对两行(与 `request_error` 行同)。
|
|
2150
|
+
|
|
2126
2151
|
**请求体字段(常用;受理**闭集**以契约 §1 为准(内部记录)—— 本表不再重抄一份):**
|
|
2127
2152
|
| 字段 | 必填 | 说明 |
|
|
2128
2153
|
|---|---|---|
|
|
@@ -2332,7 +2357,7 @@ curl -N http://<host>:8090/v1/tasks/stream -H 'content-type: application/json' \
|
|
|
2332
2357
|
> 部署形不是输入:单用户部署上 `GET /v1/diagnostics/wiring` 与 `GET /v1/outcomes` 也只认运维,具名名单在单用户部署上同样生效。
|
|
2333
2358
|
> 🔴 **单用户部署必须声明谁是运维**:`REQUIRE_PRINCIPAL` 未开、`OPERATOR_PRINCIPALS` 为空、`OPERATOR_SINGLE_USER` 不是 `true` ⇒ 装配运维面时拒(服务进程起服拒;直接调 `createHttpServer` 的嵌入方同拒;不变量 `operator-declaration-required`),
|
|
2334
2359
|
> stderr 一行拒句点名两条出路 —— `OPERATOR_SINGLE_USER=true`(每个调用方都是运维)或 `OPERATOR_PRINCIPALS=<主体,…>`(只有点名的主体);不止一个人调用的 worker 是多租,设 `REQUIRE_PRINCIPAL=true`。
|
|
2335
|
-
> 没有旋钮、没有宽限、没有缺省;`OPERATOR_SINGLE_USER=false` 与没写同判。`sema-up --users=single`
|
|
2360
|
+
> 没有旋钮、没有宽限、没有缺省;`OPERATOR_SINGLE_USER=false` 与没写同判。`sema-up --users=single` 按租户词渲 `OPERATOR_SINGLE_USER=true`(kube 两条 helm 路径写进 values 的 `server.operatorSingleUser`);直接 `helm` 的部署由你写显式 values 键 `server.operatorSingleUser=true`(单人)或 `server.requirePrincipal=true`(多人),图表不从租户词派生它,两键都没设渲染即拒。
|
|
2336
2361
|
> 不挂 HTTP 面的 `run-local` 不判这一条;运维面 501 `capability.operator_principals_required` 从此只出现在「多租 + 空名单」上。
|
|
2337
2362
|
> ⚠️ **多租户形拒启**:`DURABLE_APPROVAL=true` + `REQUIRE_PRINCIPAL=true` 而 `OPERATOR_PRINCIPALS` 空 ⇒ 进程启动失败并点名修法(空名单下没人能当这台多租 worker 审批队列的 operator)。设名单,或确属单租户则不设 `REQUIRE_PRINCIPAL`。
|
|
2338
2363
|
> 🔒 **停驻任务续跑上下文里的凭据是密封的(7.134.0 起)**:任务停驻时存下的提交体里,请求自带的凭据(`mcpServers[].transport.headers` / `.env` 的值、`a2aPeers[].headers` 的值、`settings.env` 的值、
|
|
@@ -2488,8 +2513,8 @@ curl -N http://<host>:8090/v1/tasks/stream -H 'content-type: application/json' \
|
|
|
2488
2513
|
> ⚠️ **分钟级持久作业**:客户端超时后**原样重发**是安全的 —— 同副本上在飞的那一轮会被并入(单飞),
|
|
2489
2514
|
> 落定之后的重发走 core 的 durable run 行续跑(零新 mint)。**跨副本**仍是 at-least-once,别从两个地方
|
|
2490
2515
|
> 同时打同一个 scope。
|
|
2491
|
-
> ⚠️ 它**真的烧模型** ⇒ 与 `/v1/tasks` 同吃三道 503 门(drain / roster 未落 /
|
|
2492
|
-
> 🔴 因此:**没配 `SERVICE_AUTH_TOKEN
|
|
2516
|
+
> ⚠️ 它**真的烧模型** ⇒ 与 `/v1/tasks` 同吃三道 503 门(drain / roster 未落 / 请求没带过门凭据)。
|
|
2517
|
+
> 🔴 因此:**没配 `SERVICE_AUTH_TOKEN`、也没装鉴权桥且未开 `ALLOW_UNAUTHED_WRITES` 的 worker 上这一口恒 503**(装了鉴权桥的只收带登录令牌的请求),
|
|
2493
2518
|
> 而能力位仍报 true(本族共有缺口,附录 B.1 已如实登记)。启动日志为此打一条
|
|
2494
2519
|
> `memory_consolidation_run_credential_gated`;状态读那一口不受影响(它不烧模型)。
|
|
2495
2520
|
> 谁是运维:阀门开得起来的只有单用户 + file 记忆后端的部署,而单用户部署起服就得声明运维(`OPERATOR_SINGLE_USER=true` 或具名 `OPERATOR_PRINCIPALS`,
|
|
@@ -2584,7 +2609,7 @@ curl -N http://<host>:8090/v1/tasks/stream -H 'content-type: application/json' \
|
|
|
2584
2609
|
> 与主张(`REMOTE_EXEC_HOME_DIR`,或 host 的本进程家目录 / e2b 的 `/home/user`)不一致(去掉尾斜杠后逐字比)或问不出 ⇒ 那只执行环境不开,拒句点名两个值与改法
|
|
2585
2610
|
> (把 `REMOTE_EXEC_HOME_DIR` 设成实测值、删掉错的声明,或让环境的 `HOME` 读主张那个值)。host 车道的读数在铸环境时就到手 ⇒ 环境不铸,run 在开跑前失败
|
|
2586
2611
|
> (码 `env.home_unconfirmed`,同步腿 409;一条命令没跑、模型一次没调,命令带不带路径都是这一句;7.144.0 起,此前拒句落在工具结果里);远端五车道的环境也在开跑前打开、拒在那一拍判出,但 run 照样开跑 ⇒
|
|
2587
|
-
> 拒句落在工具结果里(带路径的命令可能先撞读边界、ssh / adb 上带附件的会话开跑前就失败、从快照恢复的续跑腿答 `resume.env_failed`,逐形见 §9 的 `env.home_unconfirmed` 行),环境答了的不一致记在那只环境上(
|
|
2612
|
+
> 拒句落在工具结果里(带路径的命令可能先撞读边界、ssh / adb 上带附件的会话开跑前就失败、从快照恢复的续跑腿答 `resume.env_failed`,逐形见 §9 的 `env.home_unconfirmed` 行),环境答了的不一致记在那只环境上(码 `env.home_unconfirmed`,与 host 车道同一码;此后每次回同一句,不再起容器 / pod / 沙箱、不再问),问不出的那一次不记(`connect_failed`)、下一次重问。e2b 恢复出来的沙箱对不上时尝试重新挂起(挂起成功快照留着;挂起失败只记一行 warn,沙箱按自己的寿命到期),不杀。
|
|
2588
2613
|
> e2b 的出厂答案 `/home/user` 已于 2026-10-29 在真沙箱上实测一致(缺省模板:用户 `user`、`$HOME` = `/home/user`);自定义模板换了用户的,`$HOME` 若不是它,没声明 `REMOTE_EXEC_HOME_DIR` 的 e2b 部署的每只沙箱建起来就拒,把声明设成沙箱里 `echo $HOME` 的结果(声明同样被对证)。
|
|
2589
2614
|
> device 车道读不了家目录:声明即座,起服响一行 `execution_lane_home_unmeasured`(点名声明值与「未实测」)。
|
|
2590
2615
|
>
|
|
@@ -2877,13 +2902,13 @@ k8s 车道每条 run 一只新 pod(pod 寿命 = 泄漏护栏,不跨 run 复用)
|
|
|
2877
2902
|
|
|
2878
2903
|
- **没配快照存储**(`MINIO_ENDPOINT` / `MINIO_ACCESS_KEY` / `MINIO_SECRET_KEY` 缺任一)⇒ 工作区每轮为空,`GET /v1/capabilities` 不带 `workspaceSync`;起服一行 `workspace_persist_unavailable`(`missing` 点名缺的键;缺省 `space` 也出,设 `WORKSPACE_PERSIST=off` 即不出)。
|
|
2879
2904
|
- **没有存储后端**(`DB_BACKEND=memory`;配了 SQL 的 `DB_BACKEND` 却显式 `SESSION_BACKEND=memory` 时库不开,同一形)× `space`(含缺省,且配了快照存储)⇒ **拒启**,拒句一行点名 `WORKSPACE_PERSIST=space`、缺的存储后端、会话店种类(与 `/health.sessionBackend` 同一读法)与可用的后端。出路:`DB_BACKEND=local`,或 SQL(`DB_BACKEND=mysql|pg`,`SESSION_BACKEND` 不设 `memory`),或设 `WORKSPACE_PERSIST=off`。`SESSION_BACKEND=memory` 配 `DB_BACKEND=local` 不在此列:被收编成 local 店,照起。拒启而不是降级:否则能力位报 `space`、每条 run 却一份都不存。
|
|
2880
|
-
- **快照桶不存在**(`WORKSPACE_SNAPSHOT_BUCKET` 指的桶没建):**起服拒启**(k8s 车道配了快照存储时,server 在打开任何店之前核这只桶;拒句点名桶名、`MINIO_ENDPOINT` 的显示安全形与出路 —— 建桶,或把 `WORKSPACE_SNAPSHOT_BUCKET` 指向已有的桶;建桶晚于 server 起是编排里的常态,所以缺桶在 `STORE_LOCK_WAIT_MS` 窗内重试、到窗才拒);连不上 / 403 / 5xx 这些证明不了桶缺的答复不拒启,走 fail-open 兜底口 `server.snapshot-bucket.presence-unproven`。起服之后桶才没的(被删),或起服核证明不了的部署:读 `latest` 得 `404 NoSuchBucket` ⇒ 这条 run **连沙箱失败**(`
|
|
2881
|
-
- **读 `latest` 失败**(非 404 的 HTTP 错、网络错)、**读或弃提交围栏那一行失败**或**读会话住客失败**(会话店报错、答出的不是住客令牌,或没在 `rpcTimeoutMs`〔30 秒,与读围栏行、读 `latest` 同一只墙〕内答 —— 挂住的会话店不再让 run 的起步永挂)⇒ 这条 run 连沙箱失败(`connect_failed`,工具调用报沙箱不可用;停驻 run
|
|
2905
|
+
- **快照桶不存在**(`WORKSPACE_SNAPSHOT_BUCKET` 指的桶没建):**起服拒启**(k8s 车道配了快照存储时,server 在打开任何店之前核这只桶;拒句点名桶名、`MINIO_ENDPOINT` 的显示安全形与出路 —— 建桶,或把 `WORKSPACE_SNAPSHOT_BUCKET` 指向已有的桶;建桶晚于 server 起是编排里的常态,所以缺桶在 `STORE_LOCK_WAIT_MS` 窗内重试、到窗才拒);连不上 / 403 / 5xx 这些证明不了桶缺的答复不拒启,走 fail-open 兜底口 `server.snapshot-bucket.presence-unproven`。起服之后桶才没的(被删),或起服核证明不了的部署:读 `latest` 得 `404 NoSuchBucket` ⇒ 这条 run **连沙箱失败**(`env.snapshot_bucket_missing`,句子带 `snapshot_bucket_missing`、桶名与出路;码在引擎的可重试表之外 —— 再问也是同一个答),一只 pod 都不建,另有一行 `workspace_snapshot_bucket_missing`(`space` / `bucket` / `code` / `effect`),每只执行环境至多一次;**不再**读成「空间第一条 run」而给一个空目录、每轮只留下一条不点名桶的存失败。无 `NoSuchBucket` 的 404(桶在、键不在;代理的 404)仍是「空间第一条 run」。**恢复归档那一发**(停驻续跑;或 `latest` 读之后、取归档之前桶没了)得 `404 NoSuchBucket` 同一读法:pod 把存储的答复原样交回、由 worker 用同一只判据读 ⇒ 同拒(句子带 `snapshot_bucket_missing`、桶名与出路)、同一行(停驻车道带 `sessionId`,不带 `space`)、刚建的 pod 释放,这只执行环境此后每次连接答同一拒;此前读成悬空恢复点(`workspace_latest_dangling`),续跑在空目录上照跑。无 `NoSuchBucket` 的 404 仍是悬空恢复点。
|
|
2906
|
+
- **读 `latest` 失败**(非 404 的 HTTP 错、网络错)、**读或弃提交围栏那一行失败**或**读会话住客失败**(会话店报错、答出的不是住客令牌,或没在 `rpcTimeoutMs`〔30 秒,与读围栏行、读 `latest` 同一只墙〕内答 —— 挂住的会话店不再让 run 的起步永挂)⇒ 这条 run 连沙箱失败(`connect_failed`,工具调用报沙箱不可用;停驻 run 续跑时的恢复同样失败;会话行在而**不带住客令牌**那一形是存储数据缺陷、再读也是同一个答 ⇒ `env.occupant_missing`,出路给行补令牌或删会话),**不会**悄悄给一个空目录、也不猜「没有提交在飞」—— 「以为恢复了其实没有」比失败更坏。读住客失败时一只 pod 都不建,另有一行 `workspace_space_unreadable_occupant`(`sessionId` / `code`:会话店错误的码,不带正文;读超时的码是 `incarnation_read_timeout`),每条 run 至多一次。修好存储 / 数据库后重跑,或设 `WORKSPACE_PERSIST=off` 即恢复。
|
|
2882
2907
|
- **`latest` 指向的快照对象不在了**(被删 / 被只盖 `.tar.gz` 的生命周期规则清掉)⇒ 沙箱**照常起**:一行 `workspace_latest_dangling`(`lane: "space"` / `space` / `key` / `deleted`),删掉悬空的 `latest`,这条 run 从空目录开始,它的 run 末快照成为新的 `latest`(数据已被运维规则清走:响亮、可继续)。指针删不掉 ⇒ 同一行 `deleted: false` + `error`,下一条 run 再说一次。**打包过的停驻快照对象不在了**(`kata-…` 形,同样被清走)⇒ 同一条规则、同一行名:续跑**照常起**,一行 `workspace_latest_dangling`(`lane: "park"` / `key` / `sessionId`),这条腿从空目录开始(停驻车道没有指针可删;空间开着时它的 run 末快照成为新的 `latest`)。7.142.x 及以前这一形不出任何行。
|
|
2883
|
-
- **`latest` 指向的快照在、却拿不回来**(桶答了却不是 200 / 解压失败 / 超过快照时限 / 传输中断)⇒ 这条 run **仍然连沙箱失败**(`
|
|
2908
|
+
- **`latest` 指向的快照在、却拿不回来**(桶答了却不是 200 / 解压失败 / 超过快照时限 / 传输中断)⇒ 这条 run **仍然连沙箱失败**(`env.sandbox_refused`:这只执行环境记住的拒)、**不**退到空目录 —— 用户的改动还在桶里,静默空目录 = 让人以为丢了。**一条 run 只恢复一次**(同一只执行环境上并发的连沙箱 —— 显式 `connect()` 与首个工具调用的懒连接 —— 共用同一次建连:一只 pod、一次恢复、一个终局,被拒也是同一个拒;恢复还没完成时才到的工具调用和 `reconnect` 也等这一次建连 —— pod 先于它的工作区存在,不在半恢复的 `/workspace` 上先跑):瞬时类(`timeout` 超过快照时限 / `transport` 传输中断:执行通道断了,或 pod 取包的 GET 没拿到完整应答 —— 连不上、被重置、传到一半被截)在恢复这一步里换一只新 pod 再试一次(约 1 秒后),再试成了 ⇒ 照常起、不出行;`store_busy`(桶答 `408` / `429` / `500` / `502` / `503` / `504` —— 「现在不行」,同一请求再发可能换答案)同属瞬时类;非瞬时类(`download` 桶答了、答的是其余非 200 —— 如 `401` / `403` / `501`;`untar` 包完整下来了却解不开)不重试。每次没成的尝试,新起的 pod 当场删掉(残缺目录既不给工具用,也不会在 run 末被快照回去覆盖 `latest`)。恢复终局是拒 ⇒ **恰一行** `workspace_restore_failed`(`space` / `snapshotId` / `class` = `store_busy` \| `download` \| `untar` \| `timeout` \| `transport` / `attempts` = 这次恢复的尝试次数(`1` 或 `2`)/ `boundMs` = 每次尝试的时限 / `error`,预签 URL 已脱敏),这条 run 之后的每次沙箱操作都答**同一句**拒(不再建 pod、不再读 `latest`、不再出行);建 pod 本身失败不是恢复的结局(不出这行,下一次操作重来)。拒句写明类别与尝试次数,点名两条出路:**调大 `WORKSPACE_SNAPSHOT_TIMEOUT_MS`**(大工作区撞上界),或 **`WORKSPACE_PERSIST=off` 跑一轮**(空目录起,不删任何快照;改回 `space` 后下一条 run 照常恢复那一份)。没有「删指针」的接口:丢弃这份快照 = 丢弃用户数据,要做就由运维在对象存储侧有意识地删 `<前缀>/<化身>/space/latest`(下一条 run 从空目录起)。与上一条「悬空」分开:那是对象**不在**(没东西可恢复 ⇒ 空目录 + 响亮),这是对象**在**而拿不回来(⇒ 拒)。
|
|
2884
2909
|
- **run 末提交围栏失守、上传失败或 `latest` 写失败** ⇒ 一行 `workspace_snapshot_failed`(`space` / `stage` = `fence` \| `upload` \| `pointer` / `code` / `error`,预签 URL 已脱敏),这条 run 在 `GET /v1/fleet/stream` 上的终态 task 帧带 `workspaceSnapshot: "failed"`;pod 照删;`latest` 不动 ⇒ 下一条 run 恢复的是**上一份**。`latest` 只指向真写出的对象:run 末保存走到上传那一步时沙箱 pod 已不在(它在提交围栏认领期间消失)也按上传失败处理(`stage: upload`、`code: connect_failed`),不铸一个没有对象的 snapshotId 去改指针。**上传成没成只看 worker 对那只对象的回读**(预签 `HEAD`,2xx = 在;两条车道同一判据,停驻挂起也只在回读之后才把 snapshotId 交给引擎):pod 里 curl 报的退出码与 HTTP 状态只用来解释失败 —— curl 拿到 3xx(不跟随)退出 0 而对象不在 ⇒ 上传失败(`error` 里点名回读结果与 pod 报的状态);对象已经落下、curl 才丢了应答(非零退出)⇒ 算存成。`latest` 在回读之后才动。**`latest` 写(以及悬空恢复点删 `latest`)的应答没回到 worker**(请求抛出:连接重置、时限到点、被拒的重定向)⇒ 回读一次指针定结局:指着这一份(删:已不在)⇒ 算成;否则 / 回读失败 ⇒ 失败(`stage: pointer`)。回读只在那一写的期限之内作数(run 末那一写的期限 = 提交围栏的期限;过了期限才答 / 来不及回读 ⇒ 失败,`error` 写「deadline passed」,不删旧份)。存储答了非 2xx ⇒ 照旧直接算失败。上传与对象回读共用这次保存的数据界(`WORKSPACE_SNAPSHOT_TIMEOUT_MS` 减去提交前等待的时长),回读不另开一只时限。
|
|
2885
2910
|
- **run 末快照保存前一律先停 pod 里的进程并确认**(与那一刻有没有命令在飞无关)。命令「结束」(自己退出、被取消、超时)不等于它起的进程结束(断开 exec 套接字不会让 pod 里的进程停),在飞登记里已经没有命令也不能证明 pod 静了,所以保存前都先杀掉 pod 里除 init 与容器保活进程外的全部进程并确认;没连过沙箱的 run 没有可存的工作区,不走这一步。**run 结束时还有命令在跑**(取消 / 超时结束的 run 的命令没来得及停)⇒ 杀之前**先等**它们结束:最长一只 `rpcTimeoutMs` 墙(缺省 30 秒;等待算在这次提交的快照时限里,上传拿到的是剩下的);等不到的还要断开仍开着的 exec 套接字(那条命令的调用方读到 `aborted`),**照样保存**,并出一行 `workspace_snapshot_commands_cut`(`space` / `inFlight` / `waitedMs` / `killed`)。**没能确认进程停下**(杀进程那一步失败,或几次复查后仍有活进程;有没有命令在飞、等到与否都一样)⇒ **不保存**:一行 `workspace_snapshot_failed`(`stage: upload`、`code: command_in_flight`),`latest` 不动 —— 可能还在变的工作区不当 `latest`。**确认不了的四种形**(工作区不存,下一轮恢复的是上一份 —— 本轮的工作在下一轮看不到;7.131.x 在「run 结束时没有命令在飞」时照存):镜像里经 `sudo` / setuid 程序起的、以别的 uid 跑的进程(`kill -9` 没有权限,例如 `sudo -u postgres` 起的库进程)· 不可中断睡眠(D 态)的进程 · `podSpecPatch` 打开了 `shareProcessNamespace`(同 pod 别的容器的进程也在 `/proc` 里)· 镜像里没有 `tr`、而容器保活进程不是 1 号进程(pod 起动先跑包源钩子的那一形:认不出保活进程、把它杀掉,容器随之结束)。**出路**:k8s 车道镜像以一个非 root 用户跑、不经 sudo / setuid 起常驻进程,带 `tr`,不开 `shareProcessNamespace`;按 `workspace_snapshot_failed{stage: upload, code: command_in_flight}` 告警;不需要跨轮保留的部署设 `WORKSPACE_PERSIST=off`。杀进程脚本只在「该杀的都不活了」时退出 0(僵尸进程算死:容器保活进程不收尸)。从 destroy 开始起这只执行环境不再收新命令(工具调用报沙箱已销毁)。`command_in_flight` 的拒只留给停驻挂起(run 还活着,撕裂的归档才是真风险)。此前 run 结束时只要还有命令在飞,快照就整份被拒(`workspace_snapshot_failed`,`stage: upload`),`latest` 不动,下一轮恢复上一份 —— 取消 = 丢掉这一轮的工作。
|
|
2886
|
-
- **pod 被集群在准入时拒**(pod 建出来后、跑起来之前就到了 `Failed`:如 `K8S_SANDBOX_IPV6=disabled` 而 kubelet 没放开那两只 sysctl 时的 `SysctlForbidden`、节点亲和不符、节点放不下)⇒ 这只执行环境**记住这次拒**直到销毁:这条 run
|
|
2911
|
+
- **pod 被集群在准入时拒**(pod 建出来后、跑起来之前就到了 `Failed`:如 `K8S_SANDBOX_IPV6=disabled` 而 kubelet 没放开那两只 sysctl 时的 `SysctlForbidden`、节点亲和不符、节点放不下)⇒ 这只执行环境**记住这次拒**直到销毁:这条 run 的每次操作答同一句,码 `env.sandbox_refused`(沙箱不可用;句子点名 pod 的阶段与 kubelet 的原因),**不再每次操作重建 pod**(此前一条 run 里可建出几十只 `Failed` pod),与「恢复被拒」同一只记住的槽、同一个写口;一行 `sandbox_pod_refused`(`pod` / `phase` / `reason` / `detail`:kubelet 的原话,截断 / `sessionId`),每只执行环境至多一次。重跑这条 run 是一只新的执行环境,重新问集群。API 拒建 pod(HTTP 非 2xx)不在此列,仍是那一次尝试的失败:命名空间配额(403 `exceeded quota`)⇒ `connect_failed`(别的 pod 结束就有额度,车道在自己的重试界内再建),其余 401 / 403 ⇒ `auth_failed`(沙箱 Role 不许)。
|
|
2887
2912
|
- **删最老的失败** ⇒ 一行 `workspace_snapshot_prune_failed`,不影响本轮(空间里只是多留几份)。
|
|
2888
2913
|
- **空间结束时回收快照对象失败**(列举失败、列举被截断〔分区里超过 1000 个对象〕、某个对象删失败)⇒ 会话照删,每个失败的分区 / 阶段一行 `workspace_space_reclaim_failed`(`space` 前缀 / `sessionId` / `lane` = `space` \| `park` / `stage` = `list` \| `delete` \| `budget` \| `seat_threw`(回收座违约抛了,响亮接住、不炸进程)/ `count` / `error`,预签 URL 不进行;**一次调用里同类(分区 × 阶段)的失败合成一行**:`count` = 撞上它的空间数,`space` / `sessionId` / `error` 是调用里排第一的那个 —— sweep 一拍几百个空间遇上同一个 RBAC 漂移只出一行;卷那一行 `workspace_cache_reclaim_failed` 同形)+ 计数 `server.workspace-space.reclaim-failed`(仍逐空间计);
|
|
2889
2914
|
`budget` = 回收座这一次调用的绝对截止(= 快照时限;会话删除 = 一个空间,托管留存 sweep = 每个域每拍一次;卷回收也在内)到点,这个空间余下的列举与删除没做 —— 截止在轮到这个空间之前就过了 ⇒ 它一个请求都没发,同样记进 `budget` 那一类(配了缓存卷的,它的卷记进 `workspace_cache_reclaim_failed{reason: "budget"}` 那一类)—— `budget` 类行里的 `count` 就是被截止留下的空间数。截止之前的失败互不牵连(另一个分区、构建缓存卷照收)。对象留在桶里,按行里的空间前缀 / 会话 id 去桶里手清,或等桶的生命周期规则;到期会话已删、不会被下一拍重新列出;一拍最长 = 有结束空间的域数 × 快照时限,超过 sweep 间隔时中间的拍被跳过(防重入守卫照旧);**快照时限 ≥ 2 × sweep 间隔(= 租约 TTL)时,一个域内的回收可把本副本的租约耗过期 ⇒ 这一拍余下的域不跑、下一拍再起(一行 `retention_sweep_lease_lost`)—— 配法:快照时限要明显小于租约 TTL,即 `WORKSPACE_SNAPSHOT_TIMEOUT_MS`(毫秒)< 2 × `RETENTION_SWEEP_INTERVAL_SEC` × 1000 再留出该域 SQL 步骤的余量;缺省时限 300 000 ms 对 sweep 间隔 ≥ 300 s 的部署成立,间隔更短的部署调大间隔或调小时限(时限下限 30 000 ms)**。
|
|
@@ -2943,7 +2968,7 @@ k8s 车道每条 run 一只新 pod(pod 寿命 = 泄漏护栏,不跨 run 复用)
|
|
|
2943
2968
|
供给器不在,`claim_unbound`)、卷绑上了而挂着它的 pod 起不来(挂载失败 / 卷所在节点没了,`claim_unmountable`)—— 后两种把等它的那只 pod 删掉、换一只不挂卷的 —— 、没有这只会话(会话店答「没有」,`incarnation_unknown`)⇒ run **照常起**:不挂卷、不注入缓存 env,
|
|
2944
2969
|
计数 `server.workspace-cache.unavailable`(fail-open 登记表第 129 行)+ 一行 `workspace_cache_unavailable`(`space` / `claim` / `reason` / `error`),每条 run 至多一次。
|
|
2945
2970
|
**没绑上 / 没挂上(`claim_unbound` / `claim_unmountable`)按空间记一个快照时限**:这个空间的后续 run 在窗内直接不挂卷 —— 不发 claim 请求、不起等卷的 pod(此前每条 run 都等满一个快照时限、删掉第一只 pod 再起第二只),照样计数 + 一行(`error` 点名「记着的」);窗过了再问一次(运维补上缺省 StorageClass 后,窗后第一条 run 就挂上)。记忆放在部署的 per-run 绑定里(进程内、不跨副本、不落盘)。
|
|
2946
|
-
- **读住客失败 ⇒ 拒这一轮**:会话店报错(或答出的不是住客令牌)不是「没有空间」—— 与 9.3b
|
|
2971
|
+
- **读住客失败 ⇒ 拒这一轮**:会话店报错(或答出的不是住客令牌)不是「没有空间」—— 与 9.3b 同一只拒(店报错 / 读超时 `connect_failed`;会话行不带住客令牌 `env.occupant_missing`)(一只 pod 都不建,一行 `workspace_space_unreadable_occupant`,不计数);拒句点名开着的旋钮
|
|
2947
2972
|
(只开卷时是 `WORKSPACE_CACHE=off`)。重跑即重新读。
|
|
2948
2973
|
- **委派子代 / 后台代理不挂卷**(与不开空间同一条法:它们与父并发,不共享父的空间)—— 不计数、不出行。
|
|
2949
2974
|
- **卷的寿命 = 空间的寿命**:pod 删卷留;**空间结束时随之回收** —— `DELETE /v1/sessions/:id` 的删除协调器与托管留存 sweep 删掉会话树之后,都按标签
|
|
@@ -3218,6 +3243,7 @@ GET /v1/capabilities?permissionMode=auto (AUTONOMY=plan 的部署)
|
|
|
3218
3243
|
`{ requested, effective:"default", foldedBy:"operator_deny" }`。auto 的两键任一为 `false` 即拒,另一键的 `true` 翻不回;`true` / 缺席 = 不拒。
|
|
3219
3244
|
两键的值不是布尔 ⇒ 当作契约破损,这个 principal 的放大面整份 fail-closed。center 取数硬失败的降级窗(最长约 10 秒,之后整份重抓)里
|
|
3220
3245
|
bypass 与 auto 同样折回。7.132.x 及更早这两键被服务端丢掉:组织关了 bypass,引擎照放。
|
|
3246
|
+
委派子代腿(同步 / 后台 / fork / 复活;主体从父腿继承)按同一个主体同样执行,父腿跑着时中心才收回的也落在此后派的子代上(7.151.0 起;此前子腿不问,只靠父腿出生那一刻的模式天花板)。
|
|
3221
3247
|
部署级的 `TASK_WRITE_FACE_ESCALATION` 管「这台部署给不给任务层掀写围栏」,本条管「组织给不给这个人」—— 两道都过才是 bypass;
|
|
3222
3248
|
能力位 `taskWriteFaceOpen` 只答前一道(部署级,看不到 per-principal 的拒),实际模式读回执。
|
|
3223
3249
|
|
|
@@ -3231,9 +3257,11 @@ bypass 与 auto 同样折回。7.132.x 及更早这两键被服务端丢掉:组
|
|
|
3231
3257
|
|
|
3232
3258
|
**plan 只有一个判官 —— 引擎的 plan 模式(7.122.0 起)**:请求顶层 `permissionMode:"plan"`、`settings.permissions.defaultMode:"plan"`、
|
|
3233
3259
|
运维 `AUTONOMY=plan` 与模型自己调 `EnterPlanMode`,落到的都是同一个模式词。提交之后,一条 run 的模式词只有一个源 —— 存储的提交体顶层
|
|
3234
|
-
`permissionMode
|
|
3235
|
-
(请求不带模式词 ⇒ `plan`;带任何词 ⇒ 钳成 `plan`;bundle 的 `defaultMode` 不动,顶层赢)
|
|
3236
|
-
|
|
3260
|
+
`permissionMode`;写它的是提交入口、在飞切档(`POST /v1/runs/:id/permission-mode`)、下面的 `plan_review` 写回与续跑重放。运维 `AUTONOMY=plan` 是**提交入口的模式词地板**:受理时盖进提交体
|
|
3261
|
+
(请求不带模式词 ⇒ `plan`;带任何词 ⇒ 钳成 `plan`;bundle 的 `defaultMode` 不动,顶层赢);不按段续跑重钳 —— 停驻的 run 被续跑之前(`/decide` · `/resume` · `/wake` · `plan_review`)
|
|
3262
|
+
体上的词过一次**现**地板(与受理同一步、读此刻的配置):事后(热改或重启时)改成 `AUTONOMY=plan`,停驻 run 体上的 `bypassPermissions` / `auto` / `dontAsk` / 无词在下一次续跑
|
|
3263
|
+
钳成 `plan`(钳过的词随续跑写回,之后照它读;人批了它的计划再出 plan),`plan_review` 批准写在体顶层的 `default` / `acceptEdits` 原样(顶层同字的提交原词读不出是谁写的,同样原样;只在 bundle `defaultMode` 里的照钳);
|
|
3264
|
+
那一腿的生效词看 `wiring_manifest.permissionMode`(钳制通告 `permission.entry_mode_clamped` 只在受理门发)。请求的词真被折了(带了比 `plan` 松的词)⇒ 7.129.0 起这条会话的流(`POST /v1/tasks/stream` / `POST /v1/runs` 的事件账)
|
|
3237
3265
|
在开口那一拍多一帧 `engine_notice` `permission.entry_mode_clamped`,`detail: { requested, effective, ceiling, sessionId }`;没带词、带的就是 `plan` ⇒ 不发。工具表与 `default` 同面(写手、委派工具 `Agent` 都在),
|
|
3238
3266
|
写与非只读调用在**调用时**由引擎的 plan 门问(有人可答)/ 拒(无人可答)—— 问是一张审批卡,人批了就写,
|
|
3239
3267
|
**射程是写面根围栏之内**(任务 `cwd`、引擎宣告的可写目录〔记忆目录、会话 scratchpad〕、请求的 `additionalDirectories`):批准只清模式门,引擎文件工具自己的根围栏不受批准影响,
|
|
@@ -3750,7 +3778,7 @@ WebSearch 工具的 `tool_result` 错误文本,回到模型的对话里,**不是
|
|
|
3750
3778
|
| env | 缺省 | 说明 |
|
|
3751
3779
|
|---|---|---|
|
|
3752
3780
|
| `IMAGE_API_BASE` | 必填 | image-api 根(尾斜杠去掉) |
|
|
3753
|
-
| `BAKE_RUNNER_TOKEN` | 必填 | claim / heartbeat 的运维主体 bearer
|
|
3781
|
+
| `BAKE_RUNNER_TOKEN` | 必填 | claim / heartbeat 的运维主体 bearer。不进日志、不进任何子进程:7.151.0 起它是本包的自有凭据(起服第一步按名与按值向引擎声明,与服务进程同一份)⇒ `BAKE_ENV_ALLOW` 点到它 ⇒ 拒启;同值换名的副本同样不交给配方脚本与主机命令,`BAKE_ENV_ALLOW` 点到副本也拒启(此前只靠形状剥:点名放回与换名副本照交)。按值那一半只对引擎收作凭据的值成立:令牌不足 8 字符 / 是占位词 / 一个字符重复 ⇒ 起服一行 `own_credential_value_not_withheld { name: "BAKE_RUNNER_TOKEN" }`,只按名扣,副本照交 —— 给它一个真随机串 |
|
|
3754
3782
|
| `BAKE_RUNNER_ID` | `bake-runner-<HOSTNAME>` | 认领时报给 image-api 的 runner 名 |
|
|
3755
3783
|
| `RECIPE_REF` | `HEAD` | 配方 checkout 的 ref(`HEAD` = 用现成 checkout,不 fetch) |
|
|
3756
3784
|
| `RECIPE_DIR` | `/opt/recipes` | 配方仓 checkout 根(build.sh 的 cwd) |
|
|
@@ -3762,7 +3790,7 @@ WebSearch 工具的 `tool_result` 错误文本,回到模型的对话里,**不是
|
|
|
3762
3790
|
|
|
3763
3791
|
**子进程 env(7.103.0,剥密收口的残余面)。** runner 起的每一只子进程组 —— `build.sh`,以及主机命令 `git fetch` / `docker push` /
|
|
3764
3792
|
`docker image inspect` / `df` —— 拿到的 env = 本进程 env **剥密**:core 的一变量一判(7.106.0 起 = core 7.35.0,参照实现 CC 2.1.280 的形:
|
|
3765
|
-
凭据名表 / `OTEL_*` 前缀 / `SEMA_` 命名空间 / 名字形状 / 值里带凭据,动作恒为整只删)∘ 服务配置目录里的 secret 名 ∘ 名单型旋钮原文。runner 自己的
|
|
3793
|
+
凭据名表 / `OTEL_*` 前缀 / `SEMA_` 命名空间 / 名字形状 / 值里带凭据,动作恒为整只删)∘ 本包自有凭据(服务配置目录里的 secret 名 ∪ runner 自己的 `BAKE_RUNNER_TOKEN`,按名,并按值扣同值换名的副本)∘ 名单型旋钮原文。runner 自己的
|
|
3766
3794
|
`BAKE_RUNNER_TOKEN` 在内。剥了什么在第一次起组时记一行 `secret_env_scrubbed`(warn,site = `server.bake-runner.spawn-env`,带 `allowed` 与出路句;只键名,
|
|
3767
3795
|
不带值)。`PATH` / `HOME` / `NO_PROXY` / `DOCKER_CONFIG` / `BAKE_IMAGE_REGISTRY` / `RECIPE_GITSHA` 这类非密钥键照常传。
|
|
3768
3796
|
docker 推送的鉴权走构建宿主上的 docker 凭据存储(`docker login`),不走 env,不受影响。
|
|
@@ -3774,7 +3802,7 @@ docker 推送的鉴权走构建宿主上的 docker 凭据存储(`docker login`),
|
|
|
3774
3802
|
**`BAKE_ENV_ALLOW=NAME,NAME`。** 配方真要一枚密钥形 env(例如 build.sh 里自己做 registry 登录要 `REGISTRY_PASSWORD`,或
|
|
3775
3803
|
`git fetch` 的 askpass 读 `GIT_TOKEN`)⇒ 点名它,runner 把该键从本进程 env **原样**放回给每一只子进程组(部署方显式承担)。
|
|
3776
3804
|
与服务侧 `LSP_ENV_ALLOW` 同一只解析器、同一只放行谓词:
|
|
3777
|
-
- 形错(空段 / 尾逗号 / 非变量名形,如 `$NPM_TOKEN`、`a b`、`NAME=value` 整段贴入 / 点名任一只名单型旋钮 / 点名本服务自有凭据名,7.132.0 起;点名值是本服务某一枚凭据的另一个变量,7.149.0 起)⇒ runner **拒启**,
|
|
3805
|
+
- 形错(空段 / 尾逗号 / 非变量名形,如 `$NPM_TOKEN`、`a b`、`NAME=value` 整段贴入 / 点名任一只名单型旋钮 / 点名本服务自有凭据名,7.132.0 起;点名值是本服务某一枚凭据的另一个变量,7.149.0 起;点名 runner 自己的 `BAKE_RUNNER_TOKEN` 或装着同一个值的另一个变量,7.151.0 起)⇒ runner **拒启**,
|
|
3778
3806
|
`bake_runner_fatal` 那一行点名旋钮与第几段(`entry #k of n`,一句话只有这一套序号),**不回显值**(自有凭据那一形与服务侧同一句:说明这是本部署自己的凭据、给出路,并说明引擎拒它进任何名单);
|
|
3779
3807
|
- 本进程环境里没有的名 ⇒ 起服一行 `config_env_entry_rejected`(只报序号)、不放行;
|
|
3780
3808
|
- 旋钮原文本身按凭据类对待,不进子进程;
|
|
@@ -4008,7 +4036,7 @@ web-admin 拉取 / fleet 公告 / 凭证续签、WebSearch、对象存储、OTLP
|
|
|
4008
4036
|
(`GATE_INNODB_TEST_URL=""` 想关掉那条腿)⇒ `REMOTE_GATE_DSN_EMPTY` 红停;**缺席** ⇒ `REMOTE_GATE_DSN_ABSENT` 红停。脚本不再有共享库缺省
|
|
4009
4037
|
(旧形把空串 / 缺席回落到共享的 `sema_server_test` 等库,车QC 的锁形套在共享库上整表 DELETE 了别车的行)。要关一条腿:别在 `--dsn` 里点它;
|
|
4010
4038
|
要用:给按车库(`eval "$(node scripts/db-lane.mjs <车>)"` 建 `aiagent_test_<车>` / `sema_server_test_<车>`;起它时 shell 里已有的
|
|
4011
|
-
`GATE_*_TEST_URL` 跟着换成同一只车道库,没有就自己显式 export 三条指 k3s8 上那几只库)
|
|
4039
|
+
`GATE_*_TEST_URL` 跟着换成同一只车道库,没有就自己显式 export 三条指 k3s8 上那几只库);发车链的三台引擎坐标由起链者经环境交给启动器 `scripts/chain-launch.sh`(六个变量,缺席 / 为空 ⇒ 启动器退出码 11),
|
|
4012
4040
|
门 2 的真库组进组时各自换成自己的车道库(下一条)。
|
|
4013
4041
|
值**不进任何 argv**:经 ssh 的 stdin 送到远端 shell,再以 `docker run -e <名>`(只有名字)交给容器 —— 本机与 k3s8 的 `ps` 都看不见口令,
|
|
4014
4042
|
值里带 `&` / 空格也不会切断远端命令;值里有换行 ⇒ 红停。远端先 unset 点了名的每一条、只收点了名的名,核每一条都收到且解得开才起容器
|
|
@@ -4312,7 +4340,7 @@ docker run -d --name sema-server -p 8090:8090 \
|
|
|
4312
4340
|
-e MODEL_GATEWAY_BASEURL=https://<your-gateway>/v1 -e MODEL_ID=<your-model-name> -e MODEL_API_KEY=… \
|
|
4313
4341
|
-e SERVICE_AUTH_TOKEN=<随机长串> \
|
|
4314
4342
|
sema-server:<版本>
|
|
4315
|
-
# SERVICE_AUTH_TOKEN 不是起服必需,但没有它(
|
|
4343
|
+
# SERVICE_AUTH_TOKEN 不是起服必需,但没有它(也没接鉴权桥、没开 ALLOW_UNAUTHED_WRITES)提交任务一律 503 auth.service_token_required —— 第 5 步只验就绪,交任务前先配它。另一形是显式 ALLOW_UNAUTHED_WRITES=1:那时没有 service 令牌的 worker 只绑 127.0.0.1(自收窄),容器外经 -p 访问不到;7.148.0 起单用户部署(没设 REQUIRE_PRINCIPAL)上再写 BIND_HOST=0.0.0.0 把无鉴权写面暴露出去 ⇒ 起服拒(不变量 single-user-anonymous-boundary;进程看不见宿主把端口只发布到回环)—— 容器形一律配 SERVICE_AUTH_TOKEN。两形的取舍见 §0「监听绑址」段。
|
|
4316
4344
|
# 5. 验收 —— 就绪 + 版本
|
|
4317
4345
|
curl -fsS http://127.0.0.1:8090/readyz # {"ready":true}
|
|
4318
4346
|
curl -s -H "Authorization: Bearer <SERVICE_AUTH_TOKEN>" http://127.0.0.1:8090/health # "version" 应等于你构建的 <版本>
|
package/deploy/sema-up/README.md
CHANGED
|
@@ -51,7 +51,7 @@ summary 会打印手动接法。
|
|
|
51
51
|
| flag | 默认 | 说明 |
|
|
52
52
|
|---|---|---|
|
|
53
53
|
| `--profile=P` | 交互问 | `full-single`/`data-center`/`local-plus`/`full-cluster` |
|
|
54
|
-
| `--users=U` | `single` | `single`(超管 turnkey;落 `OPERATOR_SINGLE_USER=true` = 每个调用方都是运维,server 单用户形起服要这一行)/`multi`(身份隔离 REQUIRE_PRINCIPAL=true;`OPERATOR_SINGLE_USER=false`)
|
|
54
|
+
| `--users=U` | `single` | `single`(超管 turnkey;落 `OPERATOR_SINGLE_USER=true` = 每个调用方都是运维,server 单用户形起服要这一行)/`multi`(身份隔离 REQUIRE_PRINCIPAL=true;`OPERATOR_SINGLE_USER=false`)。两根键由同一个租户词派生,重跑即按租户词重写(kube 两条 helm 路径把声明写进 values 的 `server.operatorSingleUser`,图表自己不派生,见下「运维声明」);具名运维名单(`OPERATOR_PRINCIPALS`)本脚本不渲 |
|
|
55
55
|
| `--region=R` | `auto` | `cn`/`global`;auto=对 aliyun/npmjs 探测延迟 |
|
|
56
56
|
| `--project=NAME` | `sema` | compose project 名;并行试验/多套共存用。也是工作目录 `~/.sema-up/<名>` 与自动数据根 `<盘>/sema-data/<名>` 的一段 ⇒ 只收小写字母 / 数字 / `-` / `_`,首字符是字母或数字(别的写法在建任何目录之前拒) |
|
|
57
57
|
| `--dry-run` | — | 只打印执行计划,不写 .env、不起容器 |
|
|
@@ -154,6 +154,12 @@ data-center:2c/2G/20G)以下 BLOCK——确实无法稳定部署,提前警告不
|
|
|
154
154
|
- **MinIO**:钉死的 tag(`minio/minio:RELEASE.…`,chart / cluster 静态清单 / compose 三份同值;k8s `imagePullPolicy: IfNotPresent`,不再 `:latest` + `Always`)。换源 = 换整条引用:
|
|
155
155
|
compose 与 kube-up 读环境变量 `MINIO_IMAGE`(kube-up 给了才递给 chart),chart 直接 `--set minio.image=<源>/minio/minio:<tag>`(预灌镜像的节点 `--set minio.pullPolicy=Never`)。
|
|
156
156
|
|
|
157
|
+
## 运维声明(helm 图表的 `server.operatorSingleUser` / `server.requirePrincipal`)
|
|
158
|
+
|
|
159
|
+
「谁是运维」是部署写的声明,图表不替你派生:单人部署写 `server.operatorSingleUser=true`(每个调用方都是运维,env `OPERATOR_SINGLE_USER`),被不止一个人调用的部署写 `server.requirePrincipal=true`(多租;运维由具名名单另给,本图表不渲 `OPERATOR_PRINCIPALS`)。
|
|
160
|
+
两把键都没设 ⇒ `helm template` / `helm upgrade` 渲染即拒,句子就是出路;`server.operatorSingleUser` 只收布尔,字符串渲染即拒;只有 `operatorSingleUser=true` 与 `requirePrincipal=true` 同写才互斥,由服务端起服拒(图表不抄那一判);要用自己 env 补的具名运维名单 `OPERATOR_PRINCIPALS`(本图表不渲它)而不声明单人,写 `server.operatorSingleUser=false`。
|
|
161
|
+
`sema-up` 的 kube 两条 helm 路径(`--kube=existing` / `--kube=k3s`,`--kube=machines` 下 `STACK_ENGINE=helm`)按 `--users` 把 `operatorSingleUser` 写进它生成的 values;自己拼 values 的部署照上面写。
|
|
162
|
+
|
|
157
163
|
## 停驻钥匙的持久卷(三条交付路径同形;helm 图表的 `sealedKey` 块)
|
|
158
164
|
|
|
159
165
|
server 的钥匙保管目录存着停驻任务续跑上下文里请求凭据的封签钥匙(子目录 `checkpoint-ctx-keys/`)和模型钥匙 —— 私钥只在这个目录里、不进库。
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
{{- with (include "sema.operatorSingleUser" .) }}
|
|
2
|
+
运维声明:server.operatorSingleUser={{ . }} 已原样渲给每只 worker(env OPERATOR_SINGLE_USER);图表不从 server.requirePrincipal 派生它 —— 这是你写下的部署声明。
|
|
3
|
+
{{- else }}
|
|
4
|
+
运维声明:server.operatorSingleUser 未设,图表没有渲 OPERATOR_SINGLE_USER(不从 server.requirePrincipal 派生);单人部署缺这一行、又没有你自己补的具名运维名单 OPERATOR_PRINCIPALS ⇒ 服务端起服拒 —— 补一行 server.operatorSingleUser=true(或补名单)。
|
|
5
|
+
{{- end }}
|
|
1
6
|
{{- $persist := eq (include "sema.sealedKey.enabled" .) "true" }}
|
|
2
7
|
{{- if $persist }}
|
|
3
8
|
停驻封签钥匙:server 的 <数据根>/sealed-key/ 在持久卷 {{ include "sema.sealedKey.claimName" . }}(挂在容器内 {{ include "sema.sealedKey.mountPath" . }},{{ include "sema.sealedKey.accessMode" . }}),重启与换副本都不丢钥匙,停驻的任务照常续跑。PVC 带 helm.sh/resource-policy: keep(helm uninstall 与把 sealedKey.persistence.enabled 改成 false 的 upgrade 都不删它)。
|
|
@@ -113,25 +113,24 @@ false
|
|
|
113
113
|
{{- end -}}
|
|
114
114
|
|
|
115
115
|
{{- /*
|
|
116
|
-
单用户运维声明(env OPERATOR_SINGLE_USER)渲给 worker 的值 =
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
116
|
+
单用户运维声明(env OPERATOR_SINGLE_USER)渲给 worker 的值 = 部署写的显式键 `server.operatorSingleUser`(只收布尔),原样渲:`true` / `false` 逐字,不设 ⇒ 交回空(调用处不出这一行)。
|
|
117
|
+
**图表不替部署派生它**:「谁是运维」是部署的声明;从租户词 `server.requirePrincipal` 推出它(修前:未开 ⇒ `"true"`)会让忘设 `requirePrincipal` 的团队集群升级之后每个调用方都成运维 ——
|
|
118
|
+
服务端拒句里「不止一个人调用 ⇒ 设 REQUIRE_PRINCIPAL」那一道人判,对用模板的人永远不出现。两键都没设 ⇒ 渲染即拒(句子照服务端拒句的两条出路:单人 ⇒ operatorSingleUser;多人 ⇒ requirePrincipal),不静默二选一。
|
|
119
|
+
`requirePrincipal` 在这里只读「设没设」(nil 或空串 = 没设),不读它的值、不抄服务端的布尔词表(两条规则读同一个词表是第二份真源);单人声明与多租的互斥由服务端起服拒(唯一的判官)。
|
|
120
|
+
非布尔 ⇒ 渲染即拒:字符串 "false" 在模板里恒为真,会静默声明人人运维。两只 worker 都调这一只。
|
|
121
121
|
*/ -}}
|
|
122
122
|
{{- define "sema.operatorSingleUser" -}}
|
|
123
|
-
{{- $raw := .Values.server.
|
|
124
|
-
{{- $rp :=
|
|
125
|
-
{{- if
|
|
126
|
-
{{- $rp
|
|
127
|
-
{{-
|
|
128
|
-
{{-
|
|
129
|
-
{{-
|
|
130
|
-
{{-
|
|
131
|
-
{{-
|
|
132
|
-
{{- fail (printf "server.
|
|
123
|
+
{{- $raw := .Values.server.operatorSingleUser -}}
|
|
124
|
+
{{- $rp := .Values.server.requirePrincipal -}}
|
|
125
|
+
{{- if kindIs "invalid" $raw -}}
|
|
126
|
+
{{- if or (kindIs "invalid" $rp) (eq (toString $rp) "") -}}
|
|
127
|
+
{{- fail "neither server.operatorSingleUser nor server.requirePrincipal is set — the chart does not derive the operator declaration from the tenancy setting (a team cluster that forgot requirePrincipal would silently make every caller an operator). Declare it in one line: a deployment used by one person: set server.operatorSingleUser=true (every caller of this deployment is its operator); a deployment called by more than one person is multi-tenant: set server.requirePrincipal=true instead (its operators are then named in OPERATOR_PRINCIPALS); a deployment that names its operators in OPERATOR_PRINCIPALS through its own env (this chart does not render that list) states so with server.operatorSingleUser=false" -}}
|
|
128
|
+
{{- end -}}
|
|
129
|
+
{{- else if kindIs "bool" $raw -}}
|
|
130
|
+
{{- $raw -}}
|
|
131
|
+
{{- else -}}
|
|
132
|
+
{{- fail (printf "server.operatorSingleUser must be a boolean (true or false) or unset, got %s %q — a string such as \"false\" is truthy in a template and would silently declare every caller an operator" (kindOf $raw) (toString $raw)) -}}
|
|
133
133
|
{{- end -}}
|
|
134
|
-
{{- ternary "false" "true" (eq $rp "true") -}}
|
|
135
134
|
{{- end -}}
|
|
136
135
|
|
|
137
136
|
{{- /*
|
|
@@ -61,9 +61,11 @@ spec:
|
|
|
61
61
|
- { name: MODEL_VISION, value: {{ .Values.server.modelVision | quote }} }
|
|
62
62
|
{{/* 租户姿态与主 worker 同值(文件头「同 env 面」的承诺;修前缺席 ⇒ 主 worker 多租时本只仍单用户)。 */}}
|
|
63
63
|
- { name: REQUIRE_PRINCIPAL, value: {{ .Values.server.requirePrincipal | default "false" | quote }} }
|
|
64
|
-
{{/* 单用户运维声明 =
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
{{/* 单用户运维声明 = 部署写的显式键 server.operatorSingleUser(只收布尔),原样渲;不设 ⇒ 不出这一行。图表不从租户词派生它;
|
|
65
|
+
两键(operatorSingleUser / requirePrincipal)都没设 ⇒ 渲染即拒。判与句子见 _helpers.tpl 的 sema.operatorSingleUser。 */}}
|
|
66
|
+
{{- with (include "sema.operatorSingleUser" .) }}
|
|
67
|
+
- { name: OPERATOR_SINGLE_USER, value: {{ . | quote }} }
|
|
68
|
+
{{- end }}
|
|
67
69
|
- { name: SANDBOX_PKG_SOURCE, value: {{ .Values.server.sandboxPkgSource | quote }} }
|
|
68
70
|
{{/* 车道显式点名(REMOTE_EXEC)。REQUIRE_EXECUTION_LANE 是退役 env(设了即起服拒,拒句指向 REMOTE_EXEC),不再渲。
|
|
69
71
|
下面圈起来的一行取自车道表(lanes.json 的 kube 行),由生成器渲出,不要手改。 */}}
|
|
@@ -72,9 +72,11 @@ spec:
|
|
|
72
72
|
- { name: MODEL_API_KEY, valueFrom: { secretKeyRef: { name: sema-server-env, key: MODEL_API_KEY } } }
|
|
73
73
|
- { name: MODEL_VISION, value: {{ .Values.server.modelVision | quote }} }
|
|
74
74
|
- { name: REQUIRE_PRINCIPAL, value: {{ .Values.server.requirePrincipal | default "false" | quote }} }
|
|
75
|
-
{{/* 单用户运维声明 =
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
{{/* 单用户运维声明 = 部署写的显式键 server.operatorSingleUser(只收布尔),原样渲;不设 ⇒ 不出这一行。图表不从租户词派生它;
|
|
76
|
+
两键(operatorSingleUser / requirePrincipal)都没设 ⇒ 渲染即拒。判与句子见 _helpers.tpl 的 sema.operatorSingleUser。 */}}
|
|
77
|
+
{{- with (include "sema.operatorSingleUser" .) }}
|
|
78
|
+
- { name: OPERATOR_SINGLE_USER, value: {{ . | quote }} }
|
|
79
|
+
{{- end }}
|
|
78
80
|
- { name: SANDBOX_PKG_SOURCE, value: {{ .Values.server.sandboxPkgSource | quote }} }
|
|
79
81
|
{{/* 车道显式点名(REMOTE_EXEC)。REQUIRE_EXECUTION_LANE 是退役 env(设了即起服拒,拒句指向 REMOTE_EXEC),不再渲。
|
|
80
82
|
下面圈起来的一行取自车道表(lanes.json 的 kube 行),由生成器渲出,不要手改。 */}}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# full-single(单节点 k3s dev/测试)覆盖:1 实例 PG、preferred 反亲和(required 在单机=永久
|
|
2
2
|
# Pending——真踩)、2 副本 server(钥匙卷 RWO,见文末)。用法:
|
|
3
3
|
# helm upgrade --install sema-stack ./chart -n sema --create-namespace \
|
|
4
|
-
# -f chart/values-full-single.yaml --set server.image=… --set …(凭据)
|
|
4
|
+
# -f chart/values-full-single.yaml --set server.image=… --set …(凭据) --set server.operatorSingleUser=true
|
|
5
|
+
# 末尾那一键是运维声明:单节点不等于单用户,本覆盖文件不替你写。只给一个人用 ⇒ server.operatorSingleUser=true;被不止一个人调用 ⇒ 改成 --set server.requirePrincipal=true;
|
|
6
|
+
# 两键都不写渲染即拒(见 values.yaml 的 server 块)。
|
|
5
7
|
pg:
|
|
6
8
|
instances: 1
|
|
7
9
|
antiAffinity: preferred
|
|
@@ -48,7 +48,14 @@ server:
|
|
|
48
48
|
modelId: "" # REQUIRED
|
|
49
49
|
modelApiKey: "" # REQUIRED
|
|
50
50
|
modelVision: "false"
|
|
51
|
-
|
|
51
|
+
# 两把「谁是运维」的键 —— 部署自己写,图表不替部署派生、不给缺省:**两把都没设 ⇒ 渲染即拒**(一句话说清两条出路,不静默二选一)。
|
|
52
|
+
# operatorSingleUser(布尔 true / false;不设 ⇒ 不渲)= 单人部署:这台的每个调用方都是运维(env OPERATOR_SINGLE_USER);只给一个人用的部署写 true。
|
|
53
|
+
# requirePrincipal(env REQUIRE_PRINCIPAL;不设 ⇒ 渲服务端缺省 "false")= 多人部署:身份隔离,运维由具名名单另给(env OPERATOR_PRINCIPALS,本图表不渲);
|
|
54
|
+
# 被不止一个人调用的部署写 true(compose 路径同名 env)。值原样递给服务端读,图表不判词。
|
|
55
|
+
# 只有 operatorSingleUser=true 与 requirePrincipal=true 同写才互斥,由服务端起服拒,图表不抄那一判。operatorSingleUser=false 逐字渲(服务端读 false 与缺席同判):
|
|
56
|
+
# 给自己 env 补了具名运维名单 OPERATOR_PRINCIPALS 的部署用它表态「我不声明单人」。kube-up / cluster-up 按 --users 把 operatorSingleUser 写进 values。
|
|
57
|
+
operatorSingleUser: null
|
|
58
|
+
requirePrincipal: null
|
|
52
59
|
# 耐久审批(env DURABLE_APPROVAL;停驻 / 续跑 / /v1/approvals 整条路由)。留空 = 图表不渲这个 env,开关归引擎按姿态定
|
|
53
60
|
# (单用户 + 有耐久店 ⇒ 开;requirePrincipal=true 的多用户形 ⇒ 关);"true" / "false" = 显式表态,原样渲给每只 worker。
|
|
54
61
|
# sealedKey.persistence.enabled=false 时图表固定渲 "false"(钥匙跨不过重启,停驻行就续不了);此处再写 "true" ⇒ 渲染即拒。
|
|
@@ -316,6 +316,7 @@ if [ "$STACK_ENGINE" = "helm" ]; then
|
|
|
316
316
|
V_PKG_SOURCE="$([ "$REGION" = "global" ] && echo global || echo '')" \
|
|
317
317
|
V_PG_INSTANCES="$PG_INSTANCES" V_PG_AA="$PG_AA" V_REPLICAS="$SERVER_REPLICAS" \
|
|
318
318
|
V_REQ_PRINCIPAL="$(principal_of_users "$USERS")" \
|
|
319
|
+
V_OPERATOR_SINGLE_USER="$(operator_single_user_of_users "$USERS")" \
|
|
319
320
|
python3 - > "$VALSF" < "$HERE/lib/helm-values-cluster.py"
|
|
320
321
|
)
|
|
321
322
|
[ -s "$VALSF" ] || die "helm values 生成失败"
|
|
@@ -222,7 +222,7 @@ helm_values() { # helm_values <giteaBaseUrl> <oauthId> <oauthSecret>
|
|
|
222
222
|
V_MODEL_GATEWAY="$MODEL_GATEWAY_BASEURL" V_MODEL_ID="$MODEL_ID" \
|
|
223
223
|
V_SERVER_IMAGE="$SEMA_SERVER_IMAGE" V_REPLICAS="$SERVER_REPLICAS" \
|
|
224
224
|
V_PG_INSTANCES="$PG_INSTANCES" V_PG_AA="$PG_AA" V_SC="$STORAGE_CLASS" V_SK_SC="$SEALED_KEY_SC" \
|
|
225
|
-
V_RT_CLASS="$RUNTIME_CLASS" V_REQ_PRINCIPAL="$(principal_of_users "$USERS")" \
|
|
225
|
+
V_RT_CLASS="$RUNTIME_CLASS" V_REQ_PRINCIPAL="$(principal_of_users "$USERS")" V_OPERATOR_SINGLE_USER="$(operator_single_user_of_users "$USERS")" \
|
|
226
226
|
V_PKG_SOURCE="$([ "$REGION" = "global" ] && echo global || echo '')" \
|
|
227
227
|
V_REG_ENABLED="$REGISTRY_ENABLED" V_REG_IMAGE="${SEMA_REGISTRY_IMAGE:-}" \
|
|
228
228
|
V_REG_PW="${REGISTRY_ADMIN_PASSWORD:-}" V_REG_SS="${REGISTRY_SESSION_SECRET:-}" V_REG_PT="${REGISTRY_PULL_TOKEN:-}" \
|
|
@@ -24,7 +24,7 @@ FLAG_WORDS_USERS="single multi"
|
|
|
24
24
|
principal_of_users() { [ "$1" = "multi" ] && echo true || echo false; }
|
|
25
25
|
# 租户形 ⇒ 单用户运维声明 OPERATOR_SINGLE_USER 的值(唯一定义;三只脚本 / 渲染段同调):server 装配运维面时要单用户部署说出谁是运维,
|
|
26
26
|
# 不声明不起服(声明与具名名单 OPERATOR_PRINCIPALS 二选一;本工具渲前者)。single = 这台只有一个人 ⇒ 他就是运维(true);
|
|
27
|
-
# multi = 多租,运维由具名名单另给 ⇒ 不声明(false;多租形上声明本身会被 server 拒)。
|
|
27
|
+
# multi = 多租,运维由具名名单另给 ⇒ 不声明(false;多租形上声明本身会被 server 拒)。helm 图表不派生它:kube-up / cluster-up 的 helm 路径把这一句的结果写进 values 的 server.operatorSingleUser。
|
|
28
28
|
operator_single_user_of_users() { [ "$1" = "multi" ] && echo false || echo true; }
|
|
29
29
|
|
|
30
30
|
# users_decide <显式给了 USERS 吗(1 / 空)> —— kube 两条装配路径(kube-up / cluster-up)的租户形决策,与 sema-up 的
|
|
@@ -10,6 +10,8 @@ print(json.dumps({
|
|
|
10
10
|
"modelGatewayBaseurl": e["V_MODEL_GATEWAY"], "modelId": e["V_MODEL_ID"],
|
|
11
11
|
"modelApiKey": e["V_MODEL_KEY"], "sandboxPkgSource": e["V_PKG_SOURCE"],
|
|
12
12
|
"requirePrincipal": e["V_REQ_PRINCIPAL"],
|
|
13
|
+
# 单用户运维声明由部署工具按 --users 写(图表不派生);值是 flagshape 那一句翻译的 true / false,JSON 布尔 = 图表只收的类型。
|
|
14
|
+
"operatorSingleUser": e["V_OPERATOR_SINGLE_USER"] == "true",
|
|
13
15
|
},
|
|
14
16
|
# chart 0.3.0 起 registry.enabled 默认 true(单机档语义)——machines 多机路径的 registry/git
|
|
15
17
|
# 面还没接线,必须显式关,不然 helm 撞 registry.image required(2026-07-12 自查)
|
|
@@ -17,6 +17,8 @@ v = {
|
|
|
17
17
|
"serviceAuthToken": e["V_SVC_TOKEN"], "modelGatewayBaseurl": e["V_MODEL_GATEWAY"],
|
|
18
18
|
"modelId": e["V_MODEL_ID"], "modelApiKey": e["V_MODEL_KEY"],
|
|
19
19
|
"sandboxPkgSource": e["V_PKG_SOURCE"], "requirePrincipal": e["V_REQ_PRINCIPAL"],
|
|
20
|
+
# 单用户运维声明由部署工具按 --users 写(图表不派生);值是 flagshape 那一句翻译的 true / false,JSON 布尔 = 图表只收的类型。
|
|
21
|
+
"operatorSingleUser": e["V_OPERATOR_SINGLE_USER"] == "true",
|
|
20
22
|
},
|
|
21
23
|
"sandbox": {"runtimeClass": e["V_RT_CLASS"],
|
|
22
24
|
"networkPolicy": {"nodeCidrs": json.loads(e["V_NODE_CIDRS"])}},
|
package/dist/adoption/import.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { SessionError } from "@sema-agent/core";
|
|
3
|
-
import { createStagedLogFeed, MalformedImportEntryError, newStagingToken,
|
|
3
|
+
import { createStagedLogFeed, MalformedImportEntryError, newStagingToken, StagedCommitOccupantChangedError } from "../session-sync-kernel.js";
|
|
4
4
|
import { STAGED_IMPORT_INVALID_SENTENCE } from "../session-error-wire.js";
|
|
5
5
|
import { recordFailOpen } from "../observability/fail-open.js";
|
|
6
6
|
import { AdoptionImportBodySchema, AdoptionImportEnvelopeSchema, ADOPTION_IMPORT_CLIENT_SESSION_ID_MAX_CHARS } from "./wire.js";
|
|
@@ -93,11 +93,11 @@ async function importOne(target, clientSessionId, entries) {
|
|
|
93
93
|
throw e;
|
|
94
94
|
}
|
|
95
95
|
try {
|
|
96
|
-
await handle.commit(target.toPrincipal, {
|
|
96
|
+
await handle.commit(target.toPrincipal, { expectedOccupant: undefined });
|
|
97
97
|
}
|
|
98
98
|
catch (e) {
|
|
99
99
|
await handle.abort().catch(() => undefined);
|
|
100
|
-
if (e instanceof
|
|
100
|
+
if (e instanceof StagedCommitOccupantChangedError)
|
|
101
101
|
return { clientSessionId, outcome: "already_imported", sessionId };
|
|
102
102
|
throw e;
|
|
103
103
|
}
|
|
@@ -18,7 +18,7 @@ export declare const MAX_DECISION_NOTE_CHARS = 2048;
|
|
|
18
18
|
/**
|
|
19
19
|
* 回决回执上「理由记上了吗」(`noteRecorded`)一格的**唯一判官与唯一组句器** —— 两口回决(live
|
|
20
20
|
* `POST /v1/tool-approvals/:id/respond` 与耐久 `POST /v1/tasks/:taskId/asks/:askId/decision`)的每一个 200
|
|
21
|
-
* 回体(PARKED
|
|
21
|
+
* 回体(含 PARKED 行经停驻赎回受理的那一腿:停驻门受理之后决定记在这只问的行上,理由就在那一列)都经这两只函数说这件事,
|
|
22
22
|
* 不在各自的回体字面量里手写第二份。
|
|
23
23
|
*
|
|
24
24
|
* 三态同一份契约:请求**没带** `note` ⇒ 键缺席(不是 `false`);带了 ⇒ `true | false`:`true` = **已确认**持久行上那段文本就是这次提交的
|
package/dist/approval-card.d.ts
CHANGED
|
@@ -590,8 +590,8 @@ export declare const ApprovalCardSchema: z.ZodObject<{
|
|
|
590
590
|
inputHasBidi: z.ZodOptional<z.ZodLiteral<true>>;
|
|
591
591
|
allowRuleShadowed: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
592
592
|
member: z.ZodEnum<{
|
|
593
|
-
request: "request";
|
|
594
593
|
deployment: "deployment";
|
|
594
|
+
request: "request";
|
|
595
595
|
skill: "skill";
|
|
596
596
|
hook: "hook";
|
|
597
597
|
persisted: "persisted";
|
|
@@ -768,8 +768,8 @@ export declare const ApprovalCardEnvelopeSchema: z.ZodObject<{
|
|
|
768
768
|
inputHasBidi: z.ZodOptional<z.ZodLiteral<true>>;
|
|
769
769
|
allowRuleShadowed: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
770
770
|
member: z.ZodEnum<{
|
|
771
|
-
request: "request";
|
|
772
771
|
deployment: "deployment";
|
|
772
|
+
request: "request";
|
|
773
773
|
skill: "skill";
|
|
774
774
|
hook: "hook";
|
|
775
775
|
persisted: "persisted";
|