@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
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
* ## 铸点(唯一)
|
|
11
11
|
* {@link buildEntryModeClampNotice} 是本码**唯一**的铸点;调用点只有一处:`http/admission.ts` 的 `prepareSpec`(提交入口,盖章之后、装配
|
|
12
12
|
* 之后 —— 那时会话 id 才定)。一次提交一次 ⇒ 一条 run 至多一帧(core 码册的去重单位「once per run」)。读的是盖章那一次求值的读数
|
|
13
|
-
* (`EntryPermissionMode`)
|
|
13
|
+
* (`EntryPermissionMode`),不另判一遍「折没折」。续跑腿不铸:续跑口按**现**地板钳存储体的词时(`permission-mode-admission.ts` `stampReplayEntryMode`),
|
|
14
|
+
* 那一腿的生效词由它的 `wiring_manifest.permissionMode` 说(引擎收到的就是钳过的词);本码只说受理门那一折(per run 一帧)。
|
|
14
15
|
* 装配期铸、腿开口那一拍投(`PreparedTaskSubmission.engineNotices` → `registerEngineNoticeLeg` 的 `pending`)—— 与请求腿 MCP 丢弃同一条投递路,
|
|
15
16
|
* 白名单 / 归属 / 消毒 / 隔离一个不绕。
|
|
16
17
|
*
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 本仓自铸的**执行环境拒码**闭集(`env.*` 族)的唯一属主(纯叶:零值依赖)。
|
|
3
|
+
*
|
|
4
|
+
* 一族一句:**这只执行环境没开,而且再问也是同一个答** —— 部署状态(或会话数据)与这条 run 冲突,原样重试不改判,出路在部署。两处产出、同一族:
|
|
5
|
+
* · host 车道的工厂在铸环境之前拒(读数在构造时就到手:`lane-home-probe.ts` 的 `laneHomeRefusal`),引擎在准备期原样再抛;
|
|
6
|
+
* · 远端车道在建连时答的**立定拒**(这只环境此后每一次建连都答同一个拒,适配器记住它):码由 `plugins/remote-env-connect-seat.ts` 的拒因表从事实词拼出
|
|
7
|
+
* —— 那张表是远端车道拼本族码的唯一入口,立定 ⇔ 码在引擎可重试表之外 ⇔ 记住。
|
|
8
|
+
* 同步提交腿按零工作拒落档(`runs.ts` 的 `EXECUTION_ENV_REFUSAL_HTTP_STATUS`,按本闭集键控:加一员而档没跟 ⇒ tsc 红)。
|
|
9
|
+
* · `env.home_unconfirmed` —— 家目录主张证不了(`judgeLaneHome` 的三形拒句:读不出 / 不是绝对路径 / 与实测不一致;远端车道只在环境**答了**的两形上记住它)。
|
|
10
|
+
* 三形一个码:出路都在部署(声明、环境里的 `HOME`,或会话 `settings.env` 里的 `HOME`),消费端不按形分岔;是哪一形、怎么改,句子里说。
|
|
11
|
+
* · `env.snapshot_bucket_missing` —— k8s 车道的工作区快照桶不在(对象存储对 `latest` 或归档的读答 `404 NoSuchBucket`):建桶,或把
|
|
12
|
+
* `WORKSPACE_SNAPSHOT_BUCKET` 指向已有的桶,或 `WORKSPACE_PERSIST=off`。
|
|
13
|
+
* · `env.occupant_missing` —— k8s 车道读这条 run 的会话住客:会话行在、却不带住客令牌(存储数据缺陷,重发不改判):给行补令牌或删会话,或关掉要它的旋钮。
|
|
14
|
+
* · `env.sandbox_refused` —— 隔离车道(k8s / e2b / local-docker)替这条 run 建的沙箱被立定地拒:集群在准入时拒了 pod、成员凭据中继建不起来、
|
|
15
|
+
* 快照归档在桶里却取不回、工作区的填充(会话附件 / 项目包种子)放不进且换一台机器也是同一个答。是哪一件、怎么改,句子里说。
|
|
16
|
+
* · `env.host_key_rejected` —— ssh 车道:目标机出示的主机密钥过不了部署钉的判(`SSH_HOST_FINGERPRINT` / `SSH_KNOWN_HOSTS`:指纹不符、条目换了钥、被吊销、没有条目)。
|
|
17
|
+
* 改钉或查明对面为什么换了钥;同一配置同一主机每次同答。
|
|
18
|
+
*/
|
|
19
|
+
export declare const EXECUTION_ENV_REFUSAL_CODES: readonly ["env.home_unconfirmed", "env.snapshot_bucket_missing", "env.occupant_missing", "env.sandbox_refused", "env.host_key_rejected"];
|
|
20
|
+
export type ExecutionEnvRefusalCode = (typeof EXECUTION_ENV_REFUSAL_CODES)[number];
|
|
21
|
+
/** 这个码是不是本族的一员(按闭集,不按前缀:引擎自己的 `env.lifetime_expired` 同前缀而不是本族)。 */
|
|
22
|
+
export declare function isExecutionEnvRefusalCode(code: unknown): code is ExecutionEnvRefusalCode;
|
|
23
|
+
//# sourceMappingURL=execution-env-refusal.d.ts.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export const EXECUTION_ENV_REFUSAL_CODES = ["env.home_unconfirmed", "env.snapshot_bucket_missing", "env.occupant_missing", "env.sandbox_refused", "env.host_key_rejected"];
|
|
2
|
+
export function isExecutionEnvRefusalCode(code) {
|
|
3
|
+
return typeof code === "string" && EXECUTION_ENV_REFUSAL_CODES.includes(code);
|
|
4
|
+
}
|
|
5
|
+
//# sourceMappingURL=execution-env-refusal.js.map
|
|
@@ -184,7 +184,7 @@ export declare function deployedExecutionLanes(config: Pick<ServiceConfigFlat, "
|
|
|
184
184
|
* 读者问的都是这一句,**同一只函数**,不许各写一份 `=== "host"`:
|
|
185
185
|
* ① 部署形表行 `toolsOnThisHost`(`deployment-shape.ts`)—— wire `executionLane.toolsOnThisHost` + 出厂自扫技能与中心 plugin 技能的 `baseDir`;
|
|
186
186
|
* ② 部署形表行 `callerOwnsWorkerDisk`(本列 ∧ 单主)—— SendUserFile 本机腿(「无手不挂」)、调用方宿主路径(附加目录 / 项目上下文)、指令文件探针、
|
|
187
|
-
* 本机语言服务器(`createLspManager
|
|
187
|
+
* 本机语言服务器(`createLspManager`;「绑得住读」`openBound` 不是本列的事,是每条有手车道的结构前提,见 {@link laneWiresExecutionEnv});
|
|
188
188
|
* ③ `approval.ts` 的 `buildNoResponderBootWarns` —— 写门的 ask 只在「有手写本机盘」时才会发生(它手里已有车道词,直接读本列)。
|
|
189
189
|
*/
|
|
190
190
|
export declare function handsOnWorkerFilePlane(lane: ExecutionLane): boolean;
|
|
@@ -230,6 +230,8 @@ export declare function laneIsolated(lane: ExecutionLane): boolean;
|
|
|
230
230
|
* 这条车道**有没有手**(块 `io`:文件与 shell 两面真到达目标;`none` 的桩块 false)的唯一布尔口。读者四处:路由的「有没有执行环境」(`boot/resolve-spec.ts`)、
|
|
231
231
|
* wire `executionLane.isolated` 的在场判据(`capabilities/execution-lane.ts`)、场景详情的附件供给集(`boot/stage-07-capability-layer.ts` 把它填进
|
|
232
232
|
* `ScenarioDeps.handsLane`:「这一 run 有没有工作区」的车道半场)、起服家目录那一行({@link buildLaneHomeBootNote})—— 同读这一只。
|
|
233
|
+
* 有手车道的结构前提:适配器有绑定读面(`openBound`;设备的面 presence-typed,执行器声明了才装)—— 「能不能绑定读」的源是适配器对象本身,
|
|
234
|
+
* 本列不另存一位(对拍钉 `test/host-env-open-bound.test.ts` P3;本版唯一缓装 = ssh,同文件 `HELD_THIS_VERSION`,翻回条件钉在那里)。
|
|
233
235
|
*/
|
|
234
236
|
export declare function laneWiresExecutionEnv(lane: ExecutionLane): boolean;
|
|
235
237
|
/** 一条**已登记**的分叉:表写的是目标态,今天的判别式还答别的。 */
|
package/dist/field-conflict.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export type FieldConflictReason = (typeof FIELD_CONFLICT_REASONS)[number];
|
|
|
7
7
|
* 动态下标的坐标用模板字面量型(`agents[1].skills`)。
|
|
8
8
|
*/
|
|
9
9
|
export interface FieldConflictCoordinates {
|
|
10
|
-
readonly cascade_verify: "verify" | "cascade" | "sandboxImageProfile" | "resumeAt" | "suggestNextPrompts";
|
|
10
|
+
readonly cascade_verify: "verify" | "cascade" | "sandboxImageProfile" | "resumeAt" | "rewindFilesTo" | "suggestNextPrompts";
|
|
11
11
|
readonly image_profile: "capabilitiesNeeded" | "sandboxImageProfile";
|
|
12
12
|
readonly resume_anchor: "resumeAtMode" | "resumeAt";
|
|
13
13
|
readonly system_prompt_fold: "appendSystemPrompt" | "projectId" | "settings.outputStyle";
|
|
@@ -52,21 +52,28 @@ export interface FileHistoryAssembly {
|
|
|
52
52
|
/** 擦除脸:在场 ⟺ 后端在(与旋钮无关;是 {@link store} 的删除类动词视图)。 */
|
|
53
53
|
readonly erasure: FileHistoryErasureFace | undefined;
|
|
54
54
|
}
|
|
55
|
-
/**
|
|
55
|
+
/** 「这台部署有没有文件历史店」的唯一判定:店是后端恒交的那一只(`StoreBackend.fileHistory()`,落定席位写的同一只)⇒ 店在 ⟺ 后端在。旋钮不在这里 ——
|
|
56
|
+
* 它只关捕获,不摘店([ref])。只问「在不在」的读者(能力位)读这一只,不必取店。 */
|
|
57
|
+
export declare function fileHistoryWired(backend: StoreBackend | undefined): backend is StoreBackend;
|
|
58
|
+
/** 装配:取那只店(判定 = {@link fileHistoryWired})。起服装配(引擎的还原族 / 擦除脸)与服务面要店的读者(同步族、rewind 口)都经这里取,手里有后端 ⇒ 型上就有店。 */
|
|
59
|
+
export declare function assembleFileHistory(backend: StoreBackend): {
|
|
60
|
+
readonly store: ServiceFileHistoryStore;
|
|
61
|
+
readonly erasure: FileHistoryErasureFace;
|
|
62
|
+
};
|
|
56
63
|
export declare function assembleFileHistory(backend: StoreBackend | undefined): FileHistoryAssembly;
|
|
57
64
|
/**
|
|
58
|
-
* 「捕不捕」的**唯一**判定(纯函数):能力词。`
|
|
65
|
+
* 「捕不捕」的**唯一**判定(纯函数):能力词。`wired` = 店在不在({@link fileHistoryWired} 的答 / 装配出来的店在不在),`knob` = 部署旋钮 `FILE_HISTORY_CAPTURE`
|
|
59
66
|
* (`config.fileHistoryCapture`)。从**装配结果**派生,不照旋钮字面回声:后端本来就没有这只店的部署同样是 `off`。
|
|
60
67
|
*
|
|
61
68
|
* 与 `restoreFiles` 分叉([ref] 当时写下的分叉条件,自 [ref] 成真):本词答「这台部署捕不捕、能不能按 run 关掉」,
|
|
62
69
|
* `restoreFiles` 答「这台部署能不能还原」—— 旋钮关的部署本词 `off` 而 `restoreFiles` 仍为真。
|
|
63
70
|
*/
|
|
64
|
-
export declare function fileHistoryCaptureOf(
|
|
71
|
+
export declare function fileHistoryCaptureOf(wired: boolean, knob: boolean): FileHistoryCapture;
|
|
65
72
|
/**
|
|
66
73
|
* core 的部署捕获位 `RunnerDeps.fileHistoryCapture`,由 {@link fileHistoryCaptureOf} 派生(同一组输入、同一只判定)。
|
|
67
74
|
* 形照 `execution-lane-caps.ts` 的穷举 switch(无 default 臂):能力词加一个而这里不加臂 ⇒ 编译红 —— 加臂的那一刻就是
|
|
68
75
|
* 决定「这一词下 core 的捕获位怎么递」的地方。没有店 ⇒ 恒 `undefined`(core 对「off 但没店」拒 prepare)。
|
|
69
76
|
*/
|
|
70
|
-
export declare function coreFileHistoryCaptureSeat(
|
|
77
|
+
export declare function coreFileHistoryCaptureSeat(wired: boolean, knob: boolean): RunnerDeps["fileHistoryCapture"];
|
|
71
78
|
export {};
|
|
72
79
|
//# sourceMappingURL=file-history-capture.d.ts.map
|
|
@@ -3,19 +3,22 @@ const FILE_HISTORY_CAPTURE_WORD_SET = {
|
|
|
3
3
|
"on-optional": true,
|
|
4
4
|
};
|
|
5
5
|
export const FILE_HISTORY_CAPTURE_WORDS = Object.keys(FILE_HISTORY_CAPTURE_WORD_SET);
|
|
6
|
+
export function fileHistoryWired(backend) {
|
|
7
|
+
return backend !== undefined;
|
|
8
|
+
}
|
|
6
9
|
export function assembleFileHistory(backend) {
|
|
7
|
-
if (backend
|
|
10
|
+
if (!fileHistoryWired(backend))
|
|
8
11
|
return { store: undefined, erasure: undefined };
|
|
9
12
|
const physical = backend.fileHistory();
|
|
10
13
|
return { store: physical, erasure: physical };
|
|
11
14
|
}
|
|
12
|
-
export function fileHistoryCaptureOf(
|
|
13
|
-
return
|
|
15
|
+
export function fileHistoryCaptureOf(wired, knob) {
|
|
16
|
+
return wired && knob ? "on-optional" : "off";
|
|
14
17
|
}
|
|
15
|
-
export function coreFileHistoryCaptureSeat(
|
|
16
|
-
if (
|
|
18
|
+
export function coreFileHistoryCaptureSeat(wired, knob) {
|
|
19
|
+
if (!wired)
|
|
17
20
|
return undefined;
|
|
18
|
-
const word = fileHistoryCaptureOf(
|
|
21
|
+
const word = fileHistoryCaptureOf(wired, knob);
|
|
19
22
|
switch (word) {
|
|
20
23
|
case "off":
|
|
21
24
|
return "off";
|
|
@@ -50,16 +50,18 @@ export interface CaughtFailure {
|
|
|
50
50
|
readonly fault: Pick<FileHistoryError, "permanence">;
|
|
51
51
|
}
|
|
52
52
|
/**
|
|
53
|
-
* 把一个 caught error 折成店侧的散文 + 判断,**并**在它是一枚 typed
|
|
53
|
+
* 把一个 caught error 折成店侧的散文 + 判断,**并**在它是一枚 typed 永久失败时留痕。**先读店边界**(`storeBoundaryFault`,`site` = 折点所在的店方法):
|
|
54
|
+
* 文件历史店把失败**返回**成值(不抛),值里的文本取自这里 —— 驱动错(以及词法外的码:工作区 fs 的 `ENOENT` / `EACCES`、对象存储的码)在这里换成边界形
|
|
55
|
+
* (类别句 + 原码尾注,原句进运维日志 `at=store` 一行),返回值里不再带库的原话。
|
|
54
56
|
*
|
|
55
|
-
* `text` =
|
|
56
|
-
*
|
|
57
|
+
* `text` = 散文形:带本仓词法内 `code` 的(typed 失败:`blob_too_large_for_sql` 一类)前缀一个括号词(`(blob_too_large_for_sql) blob of … exceeds …`),
|
|
58
|
+
* 其余逐字是(过了边界的)message —— 边界句自带 `[original code: <码>]` 尾注,不再前缀第二遍码。
|
|
57
59
|
* `fault` = 判断形(core 7.55.0 `FileHistoryError.permanence`):永久码表里的码 ⇒ `{ permanence: "terminal" }`;连接类故障 ⇒ `{ permanence: "transient" }`
|
|
58
60
|
* (什么都不改稍后再试可能成);部署错配类故障 ⇒ `{ permanence: "terminal" }`(修表 / 授权之前重试注定失败);其余 ⇒ `{}`(店不知道 —— 认不出的驱动 / 库错是不是会自己好,不归本店判)。
|
|
59
|
-
* 永久码先于分类判(一只错不会两个都是);分类词只读判官 `storeFaultClassOf
|
|
61
|
+
* 永久码先于分类判(一只错不会两个都是);分类词只读判官 `storeFaultClassOf`(边界形带着它在原错上判的词),本文件不写码。
|
|
60
62
|
* 副作用 = 机器形:码取自错误对象,逐次计数 + 每进程每码一条 warn。观测绝不抛。
|
|
61
63
|
*/
|
|
62
|
-
export declare function foldCaughtFailure(err: unknown): CaughtFailure;
|
|
64
|
+
export declare function foldCaughtFailure(err: unknown, site: string): CaughtFailure;
|
|
63
65
|
/** 装配层把 logger/metrics 接上(main.ts,与 `installFailOpenRecorder` 同一处)。 */
|
|
64
66
|
export declare function installFileHistoryFailureRecorder(deps: Sink): void;
|
|
65
67
|
/** 本进程逐码累计(测试/诊断读面)。 */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { FILE_HISTORY_ERROR_CODES, FileHistoryStoreError } from "@sema-agent/core";
|
|
2
2
|
import { storeFaultClassOf } from "./plugins/store-fault.js";
|
|
3
|
+
import { outwardFailureCode, storeBoundaryFault } from "./terminal.js";
|
|
3
4
|
const PERMANENT_STORE_FAILURE_CODES = {
|
|
4
5
|
blob_too_large_for_sql: {
|
|
5
6
|
note: "a blob is larger than this deployment's SQL snapshot-blob cap — the same file will fail every turn until the deployment changes",
|
|
@@ -30,16 +31,17 @@ function drainToMetrics() {
|
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
|
-
export function foldCaughtFailure(err) {
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
const
|
|
34
|
+
export function foldCaughtFailure(err, site) {
|
|
35
|
+
const seen = storeBoundaryFault(err, site);
|
|
36
|
+
const message = seen instanceof Error ? seen.message : String(seen);
|
|
37
|
+
const code = seen?.code;
|
|
38
|
+
const typedCode = typeof code === "string" && code !== "" && outwardFailureCode(code) === code ? code : undefined;
|
|
37
39
|
const permanentCode = typedCode !== undefined && isPermanentCode(typedCode) ? typedCode : undefined;
|
|
38
40
|
if (permanentCode !== undefined)
|
|
39
41
|
recordPermanent(permanentCode, message);
|
|
40
42
|
return {
|
|
41
43
|
text: typedCode !== undefined ? `(${typedCode}) ${message}` : message,
|
|
42
|
-
fault: permanentCode !== undefined ? { permanence: "terminal" } : faultOfClass(storeFaultClassOf(
|
|
44
|
+
fault: permanentCode !== undefined ? { permanence: "terminal" } : faultOfClass(storeFaultClassOf(seen)),
|
|
43
45
|
};
|
|
44
46
|
}
|
|
45
47
|
function faultOfClass(cls) {
|
|
@@ -87,6 +87,8 @@ export type DrainEntryAnswer = DrainReceipt | DrainDeadlineRefusal;
|
|
|
87
87
|
* `session-resident-background.ts` 头注)· retain 的后台 shell · 只读订阅流(只进 `attachedStreams`)。
|
|
88
88
|
* 四项在同一次读里求出(`http/server.ts` 的 `inflightBreakdown` 是唯一的分项函数,两个和都读它),`/health` 的 `inflight` 与 `inflightBreakdown` 因此永远自洽,
|
|
89
89
|
* 判停与 `/health` 也不会各有一份算法。只有这两个函数各写一次这两个和,没有第三张计法表。
|
|
90
|
+
* 第三个读数 `/health.engineLease.attached`(附着流条数,[ref])进的是**同一张**计法表(契约「附着」一列:每一类活进不进它),不是第二套计数:
|
|
91
|
+
* 它读 {@link DrainState.attachedStreams} —— 自退判据第一合取读的那一只(`http/dispatch.ts` 的开放响应集 × SSE 章,定义只此一处)。
|
|
90
92
|
*/
|
|
91
93
|
export interface InflightBreakdown {
|
|
92
94
|
readonly http: number;
|
|
@@ -128,6 +130,8 @@ export interface DrainState {
|
|
|
128
130
|
/** [ref]:首个**非探针**请求的单调时刻(`null` = 还没有过)。与 `lastActivityAt` 同一个写者(`http/server.ts` 的活性打点)、写一次就定;
|
|
129
131
|
* 读者 = 租约腿的候首触态(`boot/engine-lease.ts`)与 `/health.engineLease.firstAttach.attachedAt`。 */
|
|
130
132
|
firstActivityAt?: () => number | null;
|
|
133
|
+
/** 本副本此刻打开着的 SSE 流条数(`createHttpServer` 自赋;定义只此一处)。读者:附着租约自退判据的第一合取、`/health.engineLease.attached`(经租约腿的读数)—— 同一只读口,
|
|
134
|
+
* 不另数。语义是**附着流条数,不是活跃调用方**:订阅流与流式提交腿算,后台腿 / 无流同步腿不算(契约计法表「附着」列);纯轮询壳读到 0 合法。 */
|
|
131
135
|
attachedStreams?: () => number;
|
|
132
136
|
lastAttachEndedAt?: () => number;
|
|
133
137
|
/** [ref]:附着租约窗的读口(`/health.engineLease`)。收尾链在**装了租约腿**时才装它,读口现读租约腿的把手 —— 腿还在观察才有读数,未装配的盒子里根本没有这只口。 */
|
|
@@ -60,8 +60,8 @@ export const SETTINGS_HOOK_STATIONS = {
|
|
|
60
60
|
function chainsBelowTaskOn(patterns, station) {
|
|
61
61
|
return patterns.some((p) => p === station || (p.endsWith(".*") && station.startsWith(p.slice(0, -1))));
|
|
62
62
|
}
|
|
63
|
-
const REQUEST_HOOK_REWRITE_UNSHOWN_REASON = "a request PreToolUse hook rewrote this call's input, but
|
|
64
|
-
const REQUEST_HOOK_ALLOW_UNJUDGED_REASON = "a request PreToolUse hook allowed this call, but
|
|
63
|
+
const REQUEST_HOOK_REWRITE_UNSHOWN_REASON = "a request PreToolUse hook rewrote this call's input, but a deployment-seat handler is admitted at the PreToolUse site below the request's hooks (admission is per site; whether its matcher fits this call is not read), and such a handler never sees a rewrite made above it, so request-hook rewrites are refused at this site and the call was not executed";
|
|
64
|
+
const REQUEST_HOOK_ALLOW_UNJUDGED_REASON = "a request PreToolUse hook allowed this call, but a deployment-seat handler is admitted at the PreToolUse site below the request's hooks (admission is per site; whether its matcher fits this call is not read), and a request hook's allow does not stand in for that handler's judgment, so request-hook allows are refused at this site and the call was not executed";
|
|
65
65
|
function hangTranslator(on, event, translators) {
|
|
66
66
|
const translate = translators[event];
|
|
67
67
|
if (translate === undefined)
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* `LSP_HOST_ENABLED`。理由:core 的 `NodeLspManager` 在 worker 上起本机子进程、在 worker 盘上找根,问的正是「这块盘是不是调用方的」;
|
|
7
7
|
* 车道能力表不另存一位(同一个答案的第二个写者)。两个入口(服务装配 `boot/execution-env.ts`、纯本地 CLI `run-local.ts`)的 `lspManager`
|
|
8
8
|
* 就是本函数的返回值,不再有任何条件(结构钉 `test/secret-env-scrub-disclosure.test.ts` 的 P1,逐格钉 `test/lsp-host-manager.test.ts` 的 P2)。
|
|
9
|
-
* 「绑得住读」(`openBound`)
|
|
10
|
-
*
|
|
9
|
+
* 「绑得住读」(`openBound`)不是本铸点的判据:它是每条有手车道的结构前提(对拍钉 `test/host-env-open-bound.test.ts` P3;本版 ssh 缓装),
|
|
10
|
+
* 运行期的不可绑由那一答答(远端目标给不出那一次观测 ⇒ `not_supported`,引擎读作缺席)。
|
|
11
11
|
*
|
|
12
12
|
* ## 子进程 env:病([ref],core 7.30.1 [ref] 提货;DEBTS [ref] 同轴的第二条,7.99.0 修复验证 opus 腿普查带出)
|
|
13
13
|
* core 的 `NodeLspManager` 默认 spawn(`defaultLspSpawn`)在 7.30.1 之前**不带 env** ⇒ 语言服务器整份继承本进程的
|
package/dist/http/admission.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { APPROVAL_REACH, IMAGE_ADMISSION, isApprovalReach, isPermissionMode, isThinkingLevel, expandTiers } from "@sema-agent/core";
|
|
2
2
|
import { isAtMentionable, matchCatalogModel, refusedCatalogEntry, selectableCatalog } from "../model-select.js";
|
|
3
3
|
import { echoModelRef, modelUnavailableMessage } from "../model-entry-refusal.js";
|
|
4
|
-
import { HttpError, sessionIdShapeIssue } from "../security.js";
|
|
4
|
+
import { HttpError, SESSION_KIND_UNRECORDABLE_MESSAGE, sessionIdShapeIssue } from "../security.js";
|
|
5
5
|
import { MAX_SETTINGS_OUTPUT_STYLE_CHARS, MAX_SETTINGS_ENV_VARS, appendFold, MAX_SETTINGS_ENV_KEY_CHARS, MAX_SETTINGS_ENV_VALUE_CHARS, PERMISSION_MODE_WORDS, autoCompactEnabledOk, parseTaskSettings, readSettingsEnv, settingsEnvComposeIssue, settingsEnvCredentialIssue, settingsPermissionBucketIssue, skillListingBudgetFractionOk, skillListingMaxDescOk, hooksKeyIssue, taskHooksHonored, taskSettingsKeyIssue } from "../task-settings.js";
|
|
6
6
|
import { serverCredentialValueSources } from "../server-secret-env.js";
|
|
7
7
|
import { tightenOnlySeatIssue } from "../tighten-only-seats.js";
|
|
@@ -9,7 +9,7 @@ import { approvalFrameFamiliesIssue } from "../tool-approval.js";
|
|
|
9
9
|
import { buildEntryModeClampNotice } from "../entry-mode-clamp-notice.js";
|
|
10
10
|
import { stampSubmissionEntryMode } from "../permission-mode-admission.js";
|
|
11
11
|
import { taskBodyKeyIssue } from "../request-key-closure.js";
|
|
12
|
-
import { FILE_HISTORY_DISABLED_NO_RESTORE, fileHistoryRestoreConflict, fileHistoryRestoreKeysInBody, inheritEnvFieldIssue, singleMemberOffFieldIssue } from "../request-value-closure.js";
|
|
12
|
+
import { FILE_HISTORY_DISABLED_NO_RESTORE, fileHistoryRestoreConflict, fileHistoryRestoreKeysInBody, inheritEnvFieldIssue, sessionKindFieldIssue, singleMemberOffFieldIssue } from "../request-value-closure.js";
|
|
13
13
|
import * as facts from "../capability-facts.js";
|
|
14
14
|
import { buildHooksRefusal, buildHooksUrlCredentialRefusal, parseHooksConfig, hooksMatcherIssue, hooksUrlCredentialIssue } from "../hooks/hook-runner.js";
|
|
15
15
|
import { judgeFreshRequestWebSearch } from "../plugins/web-search.js";
|
|
@@ -404,6 +404,10 @@ export function createAdmission(ctx) {
|
|
|
404
404
|
return null;
|
|
405
405
|
}
|
|
406
406
|
}
|
|
407
|
+
if (body.cascade === true && fileHistoryRestoreKeysInBody(body).includes("rewindFilesTo")) {
|
|
408
|
+
sendError(res, 400, "request.field_conflict", "rewindFilesTo is not supported with cascade (every rung starts a fresh session, so there is no history to restore files from)", fieldConflictFacts("cascade_verify", ["rewindFilesTo", "cascade"]));
|
|
409
|
+
return null;
|
|
410
|
+
}
|
|
407
411
|
if (body.resumeAtMode !== undefined) {
|
|
408
412
|
if (body.resumeAtMode !== "at" && body.resumeAtMode !== "before") {
|
|
409
413
|
sendError(res, 400, "request.field_invalid", 'resumeAtMode must be "at" or "before"');
|
|
@@ -454,6 +458,17 @@ export function createAdmission(ctx) {
|
|
|
454
458
|
return null;
|
|
455
459
|
}
|
|
456
460
|
}
|
|
461
|
+
{
|
|
462
|
+
const kindIssue = sessionKindFieldIssue(body);
|
|
463
|
+
if (kindIssue) {
|
|
464
|
+
sendError(res, 400, "request.field_invalid", kindIssue);
|
|
465
|
+
return null;
|
|
466
|
+
}
|
|
467
|
+
if (body.sessionKind !== undefined && !facts.sessionKinds(deps).available) {
|
|
468
|
+
sendError(res, 400, "request.precondition_unmet", SESSION_KIND_UNRECORDABLE_MESSAGE);
|
|
469
|
+
return null;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
457
472
|
if (fileHistoryRestoreConflict(body)) {
|
|
458
473
|
sendError(res, 400, "request.field_conflict", FILE_HISTORY_DISABLED_NO_RESTORE, fieldConflictFacts("file_history_restore", ["fileHistory", ...fileHistoryRestoreKeysInBody(body)]));
|
|
459
474
|
return null;
|
|
@@ -7,8 +7,8 @@ import { hostDecisionFacts } from "../host-decision.js";
|
|
|
7
7
|
import {} from "../tool-approval.js";
|
|
8
8
|
import { APPROVAL_GATE_KINDS } from "../approval-content-kind.js";
|
|
9
9
|
import { createWallClockJumpGuard } from "../wall-clock-jump-guard.js";
|
|
10
|
-
import { gatedPerson } from "./principal-gate.js";
|
|
11
|
-
import {
|
|
10
|
+
import { gatedPerson, verifiedIdentitySource } from "./principal-gate.js";
|
|
11
|
+
import { passesCredentialGate } from "../identity-source.js";
|
|
12
12
|
import { costQuotaRefusalOf } from "./request-guards.js";
|
|
13
13
|
import { admissionRefusalOf, readinessOf } from "./readiness.js";
|
|
14
14
|
import { memberLeaseOf } from "../fleet/engine-signal.js";
|
|
@@ -216,8 +216,8 @@ export function createApprovalSweeps(ctx) {
|
|
|
216
216
|
if (!cs) {
|
|
217
217
|
return { status: 404, body: refusalBody({ errorCode: "not_found.approval", message: "approval not found" }) };
|
|
218
218
|
}
|
|
219
|
-
if (!
|
|
220
|
-
return { status: 503, body: refusalBody({ errorCode: "auth.service_token_required", message: "this worker requires a service auth token (set SERVICE_AUTH_TOKEN) before accepting task submissions" }) };
|
|
219
|
+
if (!passesCredentialGate(req.httpReq === undefined ? undefined : verifiedIdentitySource(req.httpReq, deps.config)) && !deps.config.allowUnauthedWrites) {
|
|
220
|
+
return { status: 503, body: refusalBody({ errorCode: "auth.service_token_required", message: "this worker requires a service auth token (set SERVICE_AUTH_TOKEN) or a verified registry sign-in token before accepting task submissions" }) };
|
|
221
221
|
}
|
|
222
222
|
const refusal = admissionRefusalOf(readinessOf(deps), memberLeaseOf(deps), "hitl-answer");
|
|
223
223
|
if (refusal !== undefined)
|
|
@@ -232,7 +232,7 @@ export function createApprovalSweeps(ctx) {
|
|
|
232
232
|
}
|
|
233
233
|
}
|
|
234
234
|
}
|
|
235
|
-
const answerer = { subject: recoveredSubject(req.principal), operator:
|
|
235
|
+
const answerer = { subject: recoveredSubject(req.principal), operator: req.operator };
|
|
236
236
|
let cp;
|
|
237
237
|
try {
|
|
238
238
|
cp = await cs.get(req.gateToken);
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
import type { CheckpointCtx } from "./route-ctx.js";
|
|
44
44
|
import type { TaskRequestBody } from "./wire-types.js";
|
|
45
45
|
import type { ProjectContext } from "../project-context.js";
|
|
46
|
+
import type { MemorySeed } from "../project-registry.js";
|
|
46
47
|
import type { InertToolListEntry } from "../rule-entry-list.js";
|
|
47
48
|
import { type Refusal } from "./refusal-body.js";
|
|
48
49
|
/** allow 层读法从这一版起(7.117.0):此前的写者对 `settings.permissions.allow` 是另一种读法(≤7.114.x 名单 / 7.115.0–7.116.x 表态)。规则见顶注「allow 读法问」。 */
|
|
@@ -79,6 +80,7 @@ export declare function buildCheckpointCtx(fields: {
|
|
|
79
80
|
unattendedLeg?: true;
|
|
80
81
|
promptScreened?: true;
|
|
81
82
|
projectContext?: ProjectContext | undefined;
|
|
83
|
+
memorySeed?: MemorySeed | null | undefined;
|
|
82
84
|
writerVersion: string;
|
|
83
85
|
}, sealer: CheckpointCtxSealer | undefined, sessionId: string): SealedCheckpointCtx;
|
|
84
86
|
/**
|
|
@@ -44,6 +44,7 @@ export function buildCheckpointCtx(fields, sealer, sessionId) {
|
|
|
44
44
|
...(fields.unattendedLeg === true ? { unattendedLeg: true } : {}),
|
|
45
45
|
...(fields.promptScreened === true ? { promptScreened: true } : {}),
|
|
46
46
|
...(fields.projectContext !== undefined ? { projectContext: fields.projectContext } : {}),
|
|
47
|
+
...(fields.memorySeed !== undefined ? { memorySeed: fields.memorySeed } : {}),
|
|
47
48
|
};
|
|
48
49
|
return sealCheckpointCtx(ctx, sealer, sessionId);
|
|
49
50
|
}
|
package/dist/http/dispatch.d.ts
CHANGED
|
@@ -33,7 +33,8 @@ export interface HealthDeploymentModsSection {
|
|
|
33
33
|
* 配了 service token、没开 REQUIRE_PRINCIPAL 的部署上,`POST /v1/tasks` 吃凭据,这三族读路对端口全开。
|
|
34
34
|
*
|
|
35
35
|
* 规则(一条,三族同读;fail-closed):
|
|
36
|
-
* · 部署**没配**任何 service 凭据(`hasServiceAuth` 假)⇒ 放行 ——
|
|
36
|
+
* · 部署**没配**任何 service 凭据(`hasServiceAuth` 假)⇒ 放行 —— 问的是「全局凭据门武装没有」,与门后各口同判(门不武装 ⇒ 门后的读口也不要凭据;
|
|
37
|
+
* 写门是另一问,问的是请求,见 `identity-source.ts` 头注律 5);
|
|
37
38
|
* · 否则要么出示了**服务凭据**(service token 单 / 多,或只读 `TRACE_TOKEN` —— 后者正是这几族在门前的理由),
|
|
38
39
|
* 要么带着**验过的** principal(registry 登录令牌 / direct-door 签名 principal 令牌;判据 = `verifiedIdentitySource`,
|
|
39
40
|
* 与 off-box operator 读面同一只)。调用方自己写的 principal 头不是凭据。
|
package/dist/http/dispatch.js
CHANGED
|
@@ -4,7 +4,7 @@ import { partsOf } from "../owner-brands.js";
|
|
|
4
4
|
import { DEPLOYMENT_SHAPE_PREDICATES } from "../deployment-shape.js";
|
|
5
5
|
import { publicStoreProbeError } from "../store-live-probe.js";
|
|
6
6
|
import { looksLikeJwt } from "@sema-agent/settings-schema/api/auth-bridge";
|
|
7
|
-
import { admitBridgeIdentity } from "../auth-bridge.js";
|
|
7
|
+
import { admitBridgeIdentity, ssoForeignScope } from "../auth-bridge.js";
|
|
8
8
|
import { ROUTE_METHOD_ORDER } from "./route-ctx.js";
|
|
9
9
|
import { READ_CREDENTIAL_ROUTES, PUBLIC_ROUTES, POST_CREDENTIAL_ROUTES, routeLabel, isBillableSubmitPath, billableKindOf, isCredentialGatedRewrite, isMethodDispatchedSubmitPath, lookupRoute, isProbePath, isSubscriptionRequest } from "./route-table.js";
|
|
10
10
|
import { sendJson, sendError, sendHttpError, isSseResponse, endSseWithError } from "./send.js";
|
|
@@ -16,7 +16,7 @@ import { projectHealthStoreSection, unwiredStorePosture } from "../store-posture
|
|
|
16
16
|
import { autoBackgroundOnTimeout as autoBackgroundOnTimeoutFact, autoBackgroundOnTimeoutWord, deploymentModPackages as deploymentModPackagesFact } from "../capability-facts.js";
|
|
17
17
|
import { hostBackgroundShellEnabled } from "../config.js";
|
|
18
18
|
import { actsForDeployment, admitRunIdentity, authorized, bearerPresentedButUnverified, devOpenDeployment, systemFor, gatedSubject, sendPrincipalRefusal, sendUnauthorized, traceTokenPresented, verifiedIdentitySource } from "./principal-gate.js";
|
|
19
|
-
import { hasServiceAuth } from "../identity-source.js";
|
|
19
|
+
import { hasServiceAuth, passesCredentialGate } from "../identity-source.js";
|
|
20
20
|
import { inflightTotal } from "../fleet/drain-entry.js";
|
|
21
21
|
const PROCESS_STARTED_AT_MS = Date.now() - Math.round(process.uptime() * 1000);
|
|
22
22
|
export function readCredentialOk(req, config) {
|
|
@@ -31,6 +31,18 @@ export function healthReaderOf(req, config) {
|
|
|
31
31
|
return "open";
|
|
32
32
|
return readCredentialOk(req, config) ? "credentialed" : "anonymous";
|
|
33
33
|
}
|
|
34
|
+
function credentialAttribution(req, credential, config) {
|
|
35
|
+
switch (credential) {
|
|
36
|
+
case "service_token":
|
|
37
|
+
return systemFor(req, config) ?? null;
|
|
38
|
+
case "sso":
|
|
39
|
+
return "sso";
|
|
40
|
+
default: {
|
|
41
|
+
const unknownCredential = credential;
|
|
42
|
+
throw new Error(`credential gate: credential ${String(unknownCredential)} has no attribution`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
34
46
|
function cors(res, req, origins, principalHeader) {
|
|
35
47
|
if (!origins || origins.length === 0)
|
|
36
48
|
return;
|
|
@@ -120,6 +132,11 @@ export function createDispatch(ctx) {
|
|
|
120
132
|
const rawBearer = /^Bearer\s/i.test(authz) ? authz.replace(/^Bearer\s+/i, "") : "";
|
|
121
133
|
if (rawBearer && looksLikeJwt(rawBearer)) {
|
|
122
134
|
const identity = admitBridgeIdentity(await deps.webAdminJwtVerifier.verify(rawBearer), { logger: deps.logger, metrics: deps.metrics });
|
|
135
|
+
const foreign = identity === undefined ? undefined : ssoForeignScope(identity, deps.config);
|
|
136
|
+
if (identity !== undefined && foreign !== undefined) {
|
|
137
|
+
deps.logger?.warn?.("auth_bridge_scope_refused", { principal: identity.principal, tokenScope: foreign.tokenScope, boundScope: foreign.boundScope });
|
|
138
|
+
return systemFor(req, deps.config) === undefined ? "foreign_scope" : undefined;
|
|
139
|
+
}
|
|
123
140
|
if (identity) {
|
|
124
141
|
setSsoPrincipal(req, identity.principal);
|
|
125
142
|
req.headers[deps.config.principalHeader.toLowerCase()] = identity.principal;
|
|
@@ -132,6 +149,7 @@ export function createDispatch(ctx) {
|
|
|
132
149
|
}
|
|
133
150
|
}
|
|
134
151
|
}
|
|
152
|
+
return undefined;
|
|
135
153
|
}
|
|
136
154
|
async function handle(req, res) {
|
|
137
155
|
const startedAt = Date.now();
|
|
@@ -209,6 +227,7 @@ export function createDispatch(ctx) {
|
|
|
209
227
|
lingerMs: lease.lingerMs,
|
|
210
228
|
tickMs: lease.tickMs,
|
|
211
229
|
lane: lease.lane,
|
|
230
|
+
attached: lease.attached,
|
|
212
231
|
...(fa ? { firstAttach: { windowMs: fa.windowMs, since: fa.since, attachedAt: fa.attachedAt } } : {}),
|
|
213
232
|
...(ho ? { handover: { since: ho.since, reason: ho.reason, lingerMs: ho.lingerMs, backgroundShells: ho.backgroundShells } } : {}),
|
|
214
233
|
},
|
|
@@ -294,39 +313,27 @@ export function createDispatch(ctx) {
|
|
|
294
313
|
res.end(deps.metrics.render());
|
|
295
314
|
return;
|
|
296
315
|
}
|
|
297
|
-
await attachBridgeIdentity(req)
|
|
316
|
+
if ((await attachBridgeIdentity(req)) === "foreign_scope") {
|
|
317
|
+
sendError(res, 403, "auth.scope_mismatch", "forbidden — the sign-in token was issued for a different scope than the one this worker serves: send a sign-in token issued for this worker's scope, or send this request to a worker of your token's scope");
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
298
320
|
if (await dispatchSegment(READ_CREDENTIAL_ROUTES, req, res, url, search, method, allow.pre, ctx, (r) => readCredentialOk(r, deps.config)))
|
|
299
321
|
return;
|
|
300
322
|
if (await dispatchSegment(PUBLIC_ROUTES, req, res, url, search, method, allow.pre, ctx, undefined, false))
|
|
301
323
|
return;
|
|
302
324
|
const identitySource = verifiedIdentitySource(req, deps.config);
|
|
303
325
|
admitRunIdentity(req, identitySource, deps.logger);
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
case "service_token":
|
|
309
|
-
source = systemFor(req, deps.config) ?? null;
|
|
310
|
-
break;
|
|
311
|
-
case "sso":
|
|
312
|
-
source = "sso";
|
|
313
|
-
break;
|
|
314
|
-
case "direct_door_jwt":
|
|
315
|
-
case undefined:
|
|
316
|
-
sendUnauthorized(res, "credential");
|
|
317
|
-
return;
|
|
318
|
-
default: {
|
|
319
|
-
const unknownSource = identitySource;
|
|
320
|
-
throw new Error(`credential gate: identity source ${String(unknownSource)} has no gate row`);
|
|
321
|
-
}
|
|
322
|
-
}
|
|
326
|
+
const credential = passesCredentialGate(identitySource) ? identitySource : undefined;
|
|
327
|
+
if (credential === undefined && hasServiceAuth(deps.config)) {
|
|
328
|
+
sendUnauthorized(res, "credential");
|
|
329
|
+
return;
|
|
323
330
|
}
|
|
324
|
-
reqState.source =
|
|
325
|
-
if (
|
|
331
|
+
reqState.source = credential === undefined ? null : credentialAttribution(req, credential, deps.config);
|
|
332
|
+
if (credential === undefined &&
|
|
326
333
|
!deps.config.allowUnauthedWrites &&
|
|
327
334
|
((req.method === "POST" && (isBillableSubmitPath(url) || url.startsWith("/v1/images/bakes"))) ||
|
|
328
335
|
isCredentialGatedRewrite(req.method ?? "", url))) {
|
|
329
|
-
sendError(res, 503, "auth.service_token_required", "this worker requires a service auth token (set SERVICE_AUTH_TOKEN) before accepting task submissions");
|
|
336
|
+
sendError(res, 503, "auth.service_token_required", "this worker requires a service auth token (set SERVICE_AUTH_TOKEN) or a verified registry sign-in token before accepting task submissions");
|
|
330
337
|
return;
|
|
331
338
|
}
|
|
332
339
|
const billableKind = req.method === "POST" && !isMethodDispatchedSubmitPath(url) ? billableKindOf(url) : undefined;
|
|
@@ -337,8 +344,8 @@ export function createDispatch(ctx) {
|
|
|
337
344
|
return;
|
|
338
345
|
}
|
|
339
346
|
}
|
|
340
|
-
if (isDestructiveSessionWrite(req.method ?? "", url) &&
|
|
341
|
-
sendError(res, 503, "auth.service_token_required", "this worker requires a service auth token (set SERVICE_AUTH_TOKEN) before accepting destructive session writes (policy / sync-import / fork / delete)");
|
|
347
|
+
if (isDestructiveSessionWrite(req.method ?? "", url) && credential === undefined && !deps.config.allowUnauthedWrites) {
|
|
348
|
+
sendError(res, 503, "auth.service_token_required", "this worker requires a service auth token (set SERVICE_AUTH_TOKEN) or a verified registry sign-in token before accepting destructive session writes (policy / sync-import / fork / delete)");
|
|
342
349
|
return;
|
|
343
350
|
}
|
|
344
351
|
if (await dispatchSegment(POST_CREDENTIAL_ROUTES, req, res, url, search, method, allow.post, ctx))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { uuidv7 } from "@sema-agent/core";
|
|
2
2
|
import { heldWorkflowParkDecisions } from "../parked-decide.js";
|
|
3
|
-
import { runInBackground } from "../runs.js";
|
|
3
|
+
import { createRunAnchorWriter, runInBackground } from "../runs.js";
|
|
4
4
|
import { recheckClaimBeforeLaunch, refusalAfterLostClaim, startClaimHeartbeat } from "./claim-heartbeat.js";
|
|
5
5
|
import { heldFor } from "../peer-seat.js";
|
|
6
6
|
import { fleetRunPublisher, fleetRunLabels, nameFleetRowOnDelivery } from "../fleet/fleet-bus.js";
|
|
@@ -11,12 +11,12 @@ import { buildActiveRunConflict } from "./active-run-conflict.js";
|
|
|
11
11
|
import { commitExecutionContext, faultedAnswerOf } from "./execution-context.js";
|
|
12
12
|
import { rootSessionAbsentAnswer } from "./execution-context.js";
|
|
13
13
|
import { timeClaim } from "./claim-latency.js";
|
|
14
|
-
import {
|
|
14
|
+
import { commitLegBindings } from "../session-bindings.js";
|
|
15
15
|
import { clearTurnActivity, readTurnActivityMs } from "../turn-activity.js";
|
|
16
16
|
import { recordResourceWindow } from "../resource-window.js";
|
|
17
17
|
import { persistSubmissionCtx, SUBMIT_CTX_CLAIM_LOST } from "./submit-ctx.js";
|
|
18
18
|
import { withdrawClaimedRun } from "./claimed-run.js";
|
|
19
|
-
import { sessionFactsReadOf } from "./owner-access.js";
|
|
19
|
+
import { sessionFactsReadOf, sessionOccupantReadOf } from "./owner-access.js";
|
|
20
20
|
import { createSessionWorkspaceRecorder, sessionWorkspaceStoreOf } from "../session-workspace.js";
|
|
21
21
|
export async function mintAndDriveDurableRun(ctx, runStore, args) {
|
|
22
22
|
const { deps } = ctx;
|
|
@@ -82,24 +82,24 @@ async function claimAndCommit(ctx, runStore, args, sessionId, taskId) {
|
|
|
82
82
|
finally {
|
|
83
83
|
stopPreLaunchHeartbeat();
|
|
84
84
|
}
|
|
85
|
-
|
|
85
|
+
commitLegBindings(deps, undefined, args.prepared.spec.sessionId, args.prepared.legFacts?.sessionBindings);
|
|
86
86
|
return { holdingLeg: created.legId };
|
|
87
87
|
}
|
|
88
88
|
function launchDurableRun(ctx, runStore, args, sessionId, taskId, trustedInternals, legId) {
|
|
89
89
|
const { deps } = ctx;
|
|
90
90
|
const { inflightRuns, preemptableRuns, steerableRuns } = ctx.registry;
|
|
91
|
-
const anchorOwner = args.prepared.auth?.subject ?? null;
|
|
92
91
|
const sessionFactsOf = sessionFactsReadOf(deps.sessionStorage);
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
:
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
92
|
+
const anchors = createRunAnchorWriter({
|
|
93
|
+
seat: deps.backend?.landedAttendants(),
|
|
94
|
+
sessionId,
|
|
95
|
+
owner: args.prepared.auth?.subject ?? null,
|
|
96
|
+
promptKey: taskId,
|
|
97
|
+
witness: args.prepared.legFacts?.sessionWitness,
|
|
98
|
+
occupantOf: sessionOccupantReadOf(deps.sessionStorage),
|
|
99
|
+
leafOf: sessionFactsOf === undefined ? undefined : async (id) => (await sessionFactsOf(id))?.leafId,
|
|
100
|
+
});
|
|
101
|
+
const captureTurnAnchor = anchors.turn;
|
|
102
|
+
const captureUserMessageAnchor = anchors.prompt;
|
|
103
103
|
const fleetPub = fleetRunPublisher(deps.fleetBus, {
|
|
104
104
|
runId: taskId,
|
|
105
105
|
scope: args.fleetScope,
|
|
@@ -122,7 +122,7 @@ function launchDurableRun(ctx, runStore, args, sessionId, taskId, trustedInterna
|
|
|
122
122
|
declaredFamilies: declaredApprovalFrameFamilies(args.prepared.body.settings),
|
|
123
123
|
origin: approvalLegOriginOf(args.prepared.execution),
|
|
124
124
|
}
|
|
125
|
-
: undefined, deps.checkpointStore, args.prepared.engineNotices, trustedInternals, deps.userInputLedger, args.prepared.acceptance, createSessionWorkspaceRecorder(sessionWorkspaceStoreOf(deps.sessionStorage), args.prepared.legFacts?.sessionWitness), args.prepared.legFacts?.skills, args.prepared.legFacts?.
|
|
125
|
+
: undefined, deps.checkpointStore, args.prepared.engineNotices, trustedInternals, deps.userInputLedger, args.prepared.acceptance, createSessionWorkspaceRecorder(sessionWorkspaceStoreOf(deps.sessionStorage), args.prepared.legFacts?.sessionWitness), args.prepared.legFacts?.skills, args.prepared.legFacts?.sessionBindings.cwd));
|
|
126
126
|
args.runSlot?.release();
|
|
127
127
|
args.prepared.seat.markRecord();
|
|
128
128
|
return { status: 202, body: { taskId, sessionId, status: "running", ...(args.prepared.warnings !== undefined ? { warnings: args.prepared.warnings } : {}) } };
|
|
@@ -23,6 +23,9 @@
|
|
|
23
23
|
* 中心铸的中继令牌,不带 service token)∧ 会话枚举面在(事实 `sessionList`,web 面中继 `GET /v1/sessions`);缺任一 ⇒ `false`。
|
|
24
24
|
* 四件齐时:多租户(`REQUIRE_PRINCIPAL`)每条会话都落着验过的属主 ⇒ `true`;单用户形下一条会话归谁取决于提交它的那次请求带没带
|
|
25
25
|
* 身份(web 面只列调用人自己的会话)—— 部署级答不了 ⇒ `"unknown"`。
|
|
26
|
+
* · `center.assertionToken` = web-admin 断言令牌的**声明读数**(配置 `webAdmin.assertionToken`,读口 `center-credential.ts` 的 `readWebAdminCredentialDeclaration`,
|
|
27
|
+
* 与主凭证同一只判官):`declared` ⇔ 两键之一设了,`absent` ⇔ 都没设;只在接了中心时在场(没接中心的部署不读这一对键,答不了)。只说声明,不说令牌
|
|
28
|
+
* 有效、也不说引擎向中心出示了它(本版不出示)。
|
|
26
29
|
*
|
|
27
30
|
* ## 无鉴权面
|
|
28
31
|
* `/health` 排在凭据门之前、缺省全网卡监听:本模块只出闭集词、布尔与运维要发布的 URL。两只 URL 值都过 display-safe 律
|
|
@@ -33,7 +36,8 @@
|
|
|
33
36
|
* 所以那一键不是闭集词:调用方不要往里放秘密或人名。
|
|
34
37
|
*
|
|
35
38
|
* ## 在场律
|
|
36
|
-
* 三键**恒在场**;缺席 = 老 worker(≤7.120.x)。`center.issuer` / `center.webBaseUrl` 缺席即缺席(没有鉴权桥 / 没配旋钮)
|
|
39
|
+
* 三键**恒在场**;缺席 = 老 worker(≤7.120.x)。`center.issuer` / `center.webBaseUrl` 缺席即缺席(没有鉴权桥 / 没配旋钮),不拼不猜;
|
|
40
|
+
* `center.assertionToken` 在场 ⇔ 接了中心(接了中心却缺席 = 老 worker)。
|
|
37
41
|
*/
|
|
38
42
|
import type { FlatServiceDeps } from "./server.js";
|
|
39
43
|
import { type IdentitySource } from "../identity-source.js";
|
|
@@ -43,6 +47,9 @@ export type IdentityAttach = (typeof IDENTITY_ATTACH_WORDS)[number];
|
|
|
43
47
|
/** `operator` 的词表。 */
|
|
44
48
|
export declare const OPERATOR_PRESENCE_WORDS: readonly ["present", "absent"];
|
|
45
49
|
export type OperatorPresence = (typeof OPERATOR_PRESENCE_WORDS)[number];
|
|
50
|
+
/** `center.assertionToken` 的词表(声明读数:两键之一设了 / 都没设)。 */
|
|
51
|
+
export declare const ASSERTION_TOKEN_DECLARATION_WORDS: readonly ["declared", "absent"];
|
|
52
|
+
export type AssertionTokenDeclaration = (typeof ASSERTION_TOKEN_DECLARATION_WORDS)[number];
|
|
46
53
|
/** `center.sessionsVisible` 的值域(两个布尔 + 一个词;`"unknown"` = 接线齐了,但会话归谁要看提交它的那次请求)。 */
|
|
47
54
|
export declare const SESSIONS_VISIBLE_VALUES: readonly [true, false, "unknown"];
|
|
48
55
|
export type SessionsVisible = (typeof SESSIONS_VISIBLE_VALUES)[number];
|
|
@@ -59,6 +66,7 @@ export interface HealthSelfReport {
|
|
|
59
66
|
readonly issuer?: string;
|
|
60
67
|
readonly webBaseUrl?: string;
|
|
61
68
|
readonly sessionsVisible: SessionsVisible;
|
|
69
|
+
readonly assertionToken?: AssertionTokenDeclaration;
|
|
62
70
|
};
|
|
63
71
|
}
|
|
64
72
|
/**
|
|
@@ -5,6 +5,7 @@ import { centerLaneConfigured } from "../web-admin-client/center-request.js";
|
|
|
5
5
|
import { buildDisplaySafeUrl } from "../trace/redact.js";
|
|
6
6
|
export const IDENTITY_ATTACH_WORDS = ["available", "unavailable"];
|
|
7
7
|
export const OPERATOR_PRESENCE_WORDS = ["present", "absent"];
|
|
8
|
+
export const ASSERTION_TOKEN_DECLARATION_WORDS = ["declared", "absent"];
|
|
8
9
|
export const SESSIONS_VISIBLE_VALUES = [true, false, "unknown"];
|
|
9
10
|
function carriesCallerIdentity(kind) {
|
|
10
11
|
switch (kind) {
|
|
@@ -34,6 +35,7 @@ export function buildHealthSelfReport(deps) {
|
|
|
34
35
|
...(issuer !== undefined ? { issuer: buildDisplaySafeUrl(issuer) } : {}),
|
|
35
36
|
...(webBaseUrl !== undefined ? { webBaseUrl: buildDisplaySafeUrl(webBaseUrl) } : {}),
|
|
36
37
|
sessionsVisible,
|
|
38
|
+
...(config.webAdmin !== undefined ? { assertionToken: config.webAdmin.assertionToken !== undefined ? "declared" : "absent" } : {}),
|
|
37
39
|
},
|
|
38
40
|
};
|
|
39
41
|
}
|