@sema-agent/server 7.125.1 → 7.127.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 +229 -2
- package/README.md +2 -2
- package/README.zh-CN.md +2 -2
- package/USAGE.md +346 -145
- package/deploy/sema-up/README.md +1 -1
- package/deploy/sema-up/chart/templates/networkpolicy-sandbox.yaml +57 -0
- package/deploy/sema-up/chart/templates/sandbox-rbac.yaml +32 -1
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +3 -2
- package/deploy/sema-up/chart/templates/server.yaml +2 -1
- package/deploy/sema-up/chart/values.yaml +22 -0
- package/deploy/sema-up/cluster-up.sh +10 -10
- package/deploy/sema-up/kube-up.sh +20 -13
- package/deploy/sema-up/lib/dataroot.sh +1 -1
- package/deploy/sema-up/lib/envf.sh +5 -5
- package/deploy/sema-up/lib/flagshape.sh +5 -5
- package/deploy/sema-up/lib/lanes.py +1 -1
- package/deploy/sema-up/lib/node-addrs.sh +42 -0
- package/deploy/sema-up/lib/parse-machines.py +2 -2
- package/deploy/sema-up/lib/shell-access.sh +1 -1
- package/deploy/sema-up/preflight.sh +4 -4
- package/deploy/sema-up/sema-up.sh +33 -33
- package/deploy/sema-up/smoke.sh +3 -3
- package/deploy/sema-up/stack/compose.yaml +1 -1
- package/deploy/sema-up/stack/sema-stack-cluster.yaml +26 -3
- package/dist/approval-card.d.ts +20 -4
- package/dist/approval-content-kind.d.ts +38 -22
- package/dist/approval-content-kind.js +20 -4
- package/dist/audit.js +3 -0
- package/dist/bench/s1/arms.d.ts +9 -37
- package/dist/bench/s1/arms.js +4 -61
- package/dist/bench/s1/live-deps.d.ts +4 -10
- package/dist/bench/s1/live-deps.js +1 -222
- package/dist/bench/s1/oracle.d.ts +1 -1
- package/dist/bench/s1/reviewer.d.ts +1 -1
- package/dist/bench/s1/row.d.ts +5 -7
- package/dist/bench/s1/row.js +0 -2
- package/dist/bench/s1/run-firm.d.ts +2 -2
- package/dist/bench/s1/run-firm.js +1 -4
- package/dist/bench/s1/runner-ctx.d.ts +17 -29
- package/dist/bench/s1/runner-ctx.js +3 -7
- package/dist/bench/s1/tasks.d.ts +9 -46
- package/dist/bench/s1/tasks.js +4 -63
- package/dist/boot/execution-env.d.ts +38 -26
- package/dist/boot/execution-env.js +87 -41
- package/dist/boot/leader.d.ts +2 -1
- package/dist/boot/memory-boundary.d.ts +1 -1
- package/dist/boot/memory-consolidation.d.ts +37 -3
- package/dist/boot/memory-consolidation.js +18 -2
- package/dist/boot/parked-revive-gate.d.ts +0 -3
- package/dist/boot/parked-revive-gate.js +2 -2
- package/dist/boot/resolve-spec.d.ts +0 -2
- package/dist/boot/resolve-spec.js +12 -17
- package/dist/boot/retention-lane.d.ts +12 -1
- package/dist/boot/retention-lane.js +2 -0
- package/dist/boot/runner-deps.d.ts +7 -6
- package/dist/boot/runner-deps.js +5 -16
- package/dist/boot/session-faces.d.ts +7 -2
- package/dist/boot/session-faces.js +37 -1
- package/dist/boot/stage-03-store-backend.d.ts +1 -0
- package/dist/boot/stage-03-store-backend.js +2 -2
- package/dist/boot/stage-04-stores.d.ts +1 -0
- package/dist/boot/stage-05-execution-env.d.ts +2 -2
- package/dist/boot/stage-05-execution-env.js +7 -4
- package/dist/boot/stage-06-runners.d.ts +2 -3
- package/dist/boot/stage-06-runners.js +13 -9
- package/dist/boot/stage-07-capability-layer.d.ts +2 -3
- package/dist/boot/stage-07-capability-layer.js +3 -4
- package/dist/boot/stage-08-reapers.d.ts +2 -3
- package/dist/boot/stage-08-reapers.js +2 -2
- package/dist/boot/stage-09-leader.d.ts +2 -3
- package/dist/boot/stage-09-leader.js +2 -1
- package/dist/boot/stage-10-http-server.d.ts +2 -3
- package/dist/boot/stage-10-http-server.js +2 -2
- package/dist/boot/stores.d.ts +1 -0
- package/dist/boot/stores.js +4 -3
- package/dist/boot/web-admin.d.ts +5 -0
- package/dist/boot/web-admin.js +28 -14
- package/dist/brain.d.ts +2 -2
- package/dist/brain.js +1 -1
- package/dist/capabilities/builtin-tools.d.ts +2 -1
- package/dist/capabilities/composite-members.d.ts +1 -1
- package/dist/capabilities/composite-members.js +1 -1
- package/dist/capabilities/hands-lane.d.ts +9 -6
- package/dist/capabilities/hands-lane.js +2 -2
- package/dist/capabilities/memory-notice.d.ts +27 -22
- package/dist/capabilities/memory-notice.js +15 -17
- package/dist/capabilities/scenarios.d.ts +9 -14
- package/dist/capabilities/scenarios.js +5 -50
- package/dist/capability-facts.d.ts +22 -11
- package/dist/capability-facts.js +13 -6
- package/dist/config-catalog.js +14 -5
- package/dist/config-provider.d.ts +5 -1
- package/dist/config-provider.js +23 -4
- package/dist/config-types.d.ts +19 -2
- package/dist/config.js +41 -6
- package/dist/deployment-governance.d.ts +19 -21
- package/dist/deployment-governance.js +7 -8
- package/dist/env-name-allowlist-knobs.d.ts +5 -5
- package/dist/env-name-allowlist-knobs.js +1 -0
- package/dist/execution-lane-caps.d.ts +12 -0
- package/dist/execution-lane-caps.js +18 -4
- package/dist/fleet/subagent-tail-bus.js +15 -5
- package/dist/hooks/hook-runner.d.ts +84 -30
- package/dist/hooks/hook-runner.js +74 -41
- package/dist/http/admission.js +17 -10
- package/dist/http/durable-run-leg.d.ts +5 -4
- package/dist/http/durable-run-leg.js +2 -4
- package/dist/http/idempotency.d.ts +28 -6
- package/dist/http/idempotency.js +10 -2
- package/dist/http/principal-gate.d.ts +14 -0
- package/dist/http/principal-gate.js +7 -0
- package/dist/http/request-guards.d.ts +2 -1
- package/dist/http/request-guards.js +14 -14
- package/dist/http/resume-legs.d.ts +2 -2
- package/dist/http/resume-legs.js +20 -10
- package/dist/http/route-ctx.d.ts +15 -7
- package/dist/http/routes/a2a-serve.js +11 -7
- package/dist/http/routes/approvals-assistant.js +18 -3
- package/dist/http/routes/background.d.ts +1 -1
- package/dist/http/routes/background.js +1 -1
- package/dist/http/routes/capabilities.js +10 -2
- package/dist/http/routes/mcp-reconnect.js +1 -1
- package/dist/http/routes/runs.d.ts +4 -3
- package/dist/http/routes/runs.js +35 -14
- package/dist/http/routes/session-sync.js +14 -11
- package/dist/http/routes/sessions.js +9 -9
- package/dist/http/routes/side-query.js +6 -19
- package/dist/http/routes/tasks.js +29 -19
- package/dist/http/routes/workflows.js +8 -0
- package/dist/http/server.d.ts +4 -0
- package/dist/http/server.js +3 -5
- package/dist/http/submit-replay.d.ts +15 -8
- package/dist/http/submit-replay.js +6 -0
- package/dist/http/wire-types.d.ts +7 -9
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/internal-run-env.d.ts +30 -0
- package/dist/internal-run-env.js +11 -0
- package/dist/leader/wire.js +3 -2
- package/dist/lsp/manager.js +1 -1
- package/dist/memory-scope.d.ts +19 -7
- package/dist/memory-scope.js +25 -8
- package/dist/observability/fail-open.d.ts +31 -3
- package/dist/observability/fail-open.js +31 -3
- package/dist/observability/metrics.d.ts +0 -1
- package/dist/observability/metrics.js +1 -4
- package/dist/observability/run-terminal.js +72 -4
- package/dist/permission-rule-vocab.d.ts +3 -2
- package/dist/permission-rule-vocab.js +1 -1
- package/dist/plan-cache-probe.d.ts +3 -2
- package/dist/plugins/approval-ask-store-sql.d.ts +1 -1
- package/dist/plugins/caching-session-store.d.ts +42 -22
- package/dist/plugins/caching-session-store.js +19 -9
- package/dist/plugins/checkpoint-store-sql.d.ts +42 -28
- package/dist/plugins/checkpoint-store-sql.js +57 -11
- package/dist/plugins/file-run-store.d.ts +25 -21
- package/dist/plugins/file-run-store.js +70 -34
- package/dist/plugins/k8s-exec-protocol.js +3 -0
- package/dist/plugins/local-checkpoint-store.d.ts +8 -5
- package/dist/plugins/local-checkpoint-store.js +5 -15
- package/dist/plugins/local-session-store.d.ts +66 -7
- package/dist/plugins/local-session-store.js +168 -101
- package/dist/plugins/mailbox-recipient-lifecycle.d.ts +1 -1
- package/dist/plugins/memory-run-store.d.ts +19 -3
- package/dist/plugins/memory-run-store.js +38 -3
- package/dist/plugins/one-time-migrations.d.ts +165 -39
- package/dist/plugins/one-time-migrations.js +51 -144
- package/dist/plugins/pg-pool.js +11 -1
- package/dist/plugins/pg-session-storage.d.ts +2 -0
- package/dist/plugins/pg-session-storage.js +9 -5
- package/dist/plugins/remote-env-adb.d.ts +3 -0
- package/dist/plugins/remote-env-adb.js +1 -0
- package/dist/plugins/remote-env-device.d.ts +3 -0
- package/dist/plugins/remote-env-device.js +1 -0
- package/dist/plugins/remote-env-e2b.d.ts +4 -0
- package/dist/plugins/remote-env-e2b.js +2 -1
- package/dist/plugins/remote-env-host.d.ts +23 -1
- package/dist/plugins/remote-env-host.js +20 -2
- package/dist/plugins/remote-env-k8s.d.ts +264 -41
- package/dist/plugins/remote-env-k8s.js +551 -82
- package/dist/plugins/remote-env-local-docker.d.ts +4 -0
- package/dist/plugins/remote-env-local-docker.js +2 -1
- package/dist/plugins/remote-env-ssh.d.ts +3 -0
- package/dist/plugins/remote-env-ssh.js +1 -0
- package/dist/plugins/retention-store-sql.d.ts +4 -1
- package/dist/plugins/retention-store-sql.js +11 -9
- package/dist/plugins/run-store-sql.d.ts +44 -6
- package/dist/plugins/run-store-sql.js +92 -27
- package/dist/plugins/session-capture-record-store-sql.d.ts +2 -3
- package/dist/plugins/session-store.d.ts +4 -3
- package/dist/plugins/session-store.js +1 -1
- package/dist/plugins/sql-driver.d.ts +2 -1
- package/dist/plugins/store-backend.d.ts +12 -5
- package/dist/plugins/store-backend.js +13 -4
- package/dist/plugins/store-contracts.d.ts +20 -3
- package/dist/plugins/store-open-wait.js +3 -0
- package/dist/plugins/tidb-pool.js +15 -3
- package/dist/plugins/tidb-session-storage.js +3 -2
- package/dist/plugins/tidb-session-store.d.ts +2 -0
- package/dist/plugins/tidb-session-store.js +6 -2
- package/dist/request-key-closure.d.ts +32 -7
- package/dist/request-key-closure.js +25 -9
- package/dist/router/route-orchestration.d.ts +3 -11
- package/dist/router/route-orchestration.js +0 -4
- package/dist/rule-entry-list.js +0 -4
- package/dist/rules-consent.js +3 -0
- package/dist/run-acceptance.d.ts +51 -0
- package/dist/run-acceptance.js +27 -0
- package/dist/run-local.d.ts +5 -4
- package/dist/run-local.js +23 -17
- package/dist/runs.d.ts +7 -11
- package/dist/runs.js +6 -16
- package/dist/sandbox-egress-policy.d.ts +61 -0
- package/dist/sandbox-egress-policy.js +235 -0
- package/dist/security.d.ts +7 -0
- package/dist/security.js +5 -0
- package/dist/server-secret-env.d.ts +10 -4
- package/dist/server-secret-env.js +4 -1
- package/dist/session-error-wire.d.ts +2 -2
- package/dist/session-incarnation.d.ts +46 -2
- package/dist/session-incarnation.js +14 -3
- package/dist/session-sync-kernel.d.ts +10 -3
- package/dist/session-titler.d.ts +5 -3
- package/dist/spec-fields.d.ts +24 -8
- package/dist/spec-fields.js +21 -2
- package/dist/task-workflow.d.ts +6 -4
- package/dist/task-workflow.js +3 -2
- package/dist/tool-approval.d.ts +78 -6
- package/dist/tool-approval.js +7 -3
- package/dist/trace/core-keyset-guard.d.ts +6 -5
- package/dist/trace/engine-notice-wire.d.ts +26 -1
- package/dist/trace/engine-notice-wire.js +7 -2
- package/dist/trace/ledger-events.d.ts +9 -3
- package/dist/trace/ledger-sink.d.ts +7 -0
- package/dist/trace/ledger-sink.js +14 -4
- package/dist/trace/project.d.ts +57 -11
- package/dist/trace/project.js +54 -8
- package/dist/trace/self-minted-wire.d.ts +94 -2
- package/dist/trace/self-minted-wire.js +28 -0
- package/dist/trace/tool-output-media.d.ts +26 -0
- package/dist/trace/tool-output-media.js +57 -0
- package/dist/trace/wire-projection-faces.d.ts +7 -1
- package/dist/trace/wire-projection-faces.js +2 -1
- package/dist/web-admin-client/apply-effective.d.ts +13 -7
- package/dist/web-admin-client/apply-effective.js +11 -26
- package/dist/web-admin-client/apply-ledger.d.ts +2 -2
- package/dist/web-admin-client/candidate-gate.d.ts +39 -4
- package/dist/web-admin-client/candidate-gate.js +9 -2
- package/dist/web-admin-client/facade.d.ts +2 -2
- package/dist/web-admin-client/http-client.d.ts +3 -1
- package/dist/web-admin-client/http-client.js +4 -3
- package/dist/web-admin-client/read-warnings.d.ts +33 -5
- package/dist/web-admin-client/read-warnings.js +41 -6
- package/dist/web-admin-client/types.d.ts +11 -5
- package/dist/workspace-cache.d.ts +45 -0
- package/dist/workspace-cache.js +30 -0
- package/dist/workspace-space-commit.d.ts +116 -0
- package/dist/workspace-space-commit.js +117 -0
- package/dist/workspace-space.d.ts +75 -9
- package/dist/workspace-space.js +52 -1
- package/package.json +4 -4
- package/dist/boot/session-incarnation-seat.d.ts +0 -41
- package/dist/boot/session-incarnation-seat.js +0 -69
- package/dist/capabilities/code-review-council.d.ts +0 -49
- package/dist/capabilities/code-review-council.js +0 -111
- package/dist/capabilities/collab-wire.d.ts +0 -36
- package/dist/capabilities/collab-wire.js +0 -2
- package/dist/capabilities/collab-workflows.d.ts +0 -47
- package/dist/capabilities/collab-workflows.js +0 -90
- package/dist/capabilities/prompts/code-review.d.ts +0 -25
- package/dist/capabilities/prompts/code-review.js +0 -39
- package/dist/capabilities/prompts/team.d.ts +0 -10
- package/dist/capabilities/prompts/team.js +0 -6
- package/dist/capabilities/team.d.ts +0 -113
- package/dist/capabilities/team.js +0 -70
package/dist/memory-scope.d.ts
CHANGED
|
@@ -133,19 +133,19 @@ engineWired: boolean): {
|
|
|
133
133
|
*/
|
|
134
134
|
/**
|
|
135
135
|
* S-133(7.59.0 合并重扫 wf_5ac18676 #1)—— **引擎数据根的唯一推导点**。模型是用 fs 工具往这里写记忆的
|
|
136
|
-
* ([ref] 记忆边界不变式,boot/memory-boundary.ts)
|
|
137
|
-
* (boot/stores.ts 三腿)、②`RunnerDeps.memoryEngineDir
|
|
138
|
-
*
|
|
136
|
+
* ([ref] 记忆边界不变式,boot/memory-boundary.ts),所以两件事必须读**同一只**值:①boot 起哪只记忆后端的根
|
|
137
|
+
* (boot/stores.ts 三腿)、②`RunnerDeps.memoryEngineDir` —— core 7.49.0 [ref] 起它也是守卫集的**唯一**豁免根(落在这个根**里面**的
|
|
138
|
+
* 目标按相对根判,根自己的祖先段不算目标的账;此前守卫集另收一份 `dataRoot`,那是第三个读者,已随 core 退役)。
|
|
139
139
|
* 此前 ③ 读的是 `config.localDataRoot`(本地**店**根:`LOCAL_DATA_ROOT → CONFIG_LOCAL_DIR → AGENT_DATA_DIR`),
|
|
140
140
|
* 而 ① 的 file 腿读的是 `MEMORY_ENGINE_DIR ?? AGENT_DATA_DIR`——两条链在「店根另指他处 + 记忆根坐在守卫段下
|
|
141
141
|
* (壳布局 `~/.sema/engine-data`)」时分家 ⇒ 记忆库每一次 Write 被硬拒(7.58.0 放行 ⇒ 回归);反向
|
|
142
142
|
* (`CONFIG_LOCAL_DIR=~/.sema` 当 dataRoot)则让配置根自身免检。两根本就是两件事:店根归誊本门,引擎根归本函数。
|
|
143
143
|
*
|
|
144
|
-
* 形与 boot/stores.ts 逐字同律:DB 记忆腿(pg/tidb)的根 = `<localDataRoot ??
|
|
145
|
-
* (per-worker 物化区);file 腿 = `resolveMemoryEngineRoot(memoryEngineDir
|
|
146
|
-
*
|
|
144
|
+
* 形与 boot/stores.ts 逐字同律:DB 记忆腿(pg/tidb)的根 = `<localDataRoot ?? localRoot>/memory-work`
|
|
145
|
+
* (per-worker 物化区);file 腿 = boot file 后端的链 `resolveMemoryEngineRoot(memoryEngineDir)`。**不判引擎是否
|
|
146
|
+
* 启用**——纯路径推导,禁用态下豁免根仍以「若开引擎会写到哪」为根(boot 的 `engineDataRoot` 恒铸,经共享基座交每只 Runner)。
|
|
147
147
|
*/
|
|
148
|
-
export declare function memoryEngineRootFor(config: Pick<ServiceConfig, "memoryEngineBackend" | "memoryEngineDir" | "localDataRoot">,
|
|
148
|
+
export declare function memoryEngineRootFor(config: Pick<ServiceConfig, "memoryEngineBackend" | "memoryEngineDir" | "localDataRoot">, localRoot?: string): string;
|
|
149
149
|
/** file 后端的根链(`MEMORY_ENGINE_DIR ?? fallback ?? $AGENT_DATA_DIR ?? ~/.ai-agent`)—— 与后端选择器**无关**:
|
|
150
150
|
* `memoryEngineBackendFor` 恒造 file 后端(run-local 从 env 继承 `MEMORY_ENGINE_BACKEND=pg|tidb` 时仍是 file),
|
|
151
151
|
* 所以它的根必须走这条链而不是 `memoryEngineRootFor` 的分派(codex 修复验证轮 [medium]:分派会把 run-local 的
|
|
@@ -215,6 +215,18 @@ onIncident?: (err: Error & {
|
|
|
215
215
|
backend: FileMemoryEngineBackend;
|
|
216
216
|
root: string;
|
|
217
217
|
} | undefined;
|
|
218
|
+
/**
|
|
219
|
+
* core 7.49.0 #1103 —— **记忆店根搬动 ⇒ 拒启**(不降级)。店根的物理路径是控制面里的一条记录(`root-anchor.json`),每次打开都比对;
|
|
220
|
+
* 目录被搬走 / 换成指向别处的链接之后,File 后端的**构造器**就抛 `memory.target_outside_store`(`detail` 恰在这一形上带
|
|
221
|
+
* `{ path, controlDir, recorded, now }`)。本函数是本仓构造 File 后端的唯一一处(boot 与 run-local 两个入口都经它),构造在 boot 的 `try`
|
|
222
|
+
* 之外 ⇒ 拒启。不降级成「记忆暗」的理由:降级会让这台部署在运维不知道的情况下丢掉全部记忆(而店还在,只是搬了家);拒启把那一刻交给人。
|
|
223
|
+
* 本函数只把引擎那一句(不带路径)换成**带出路**的一句:放回原处,或按引擎给的两个坐标调 `reanchorMemoryStoreRoot` 重锚后再起服。
|
|
224
|
+
* 码原样(`memory.target_outside_store`),原错误在 `cause`。别的错误(包括同码的别的形:没有 `controlDir` 的就不是根搬动)⇒ `undefined`,原样抛。
|
|
225
|
+
*/
|
|
226
|
+
export declare function memoryStoreRootMovedRefusal(e: unknown): (Error & {
|
|
227
|
+
code: string;
|
|
228
|
+
cause: unknown;
|
|
229
|
+
}) | undefined;
|
|
218
230
|
/**
|
|
219
231
|
* MF-30 memory PAUSE (option B, per-request — clay 2026-06-27): build the `TaskSpec.memory` spec for ONE run from
|
|
220
232
|
* the resolved memory `scope` + the request's `memoryWrite` toggle. `memoryWrite === false` ⇒ `writeScope: null`
|
package/dist/memory-scope.js
CHANGED
|
@@ -81,10 +81,10 @@ export function buildMemoryRemoteLaneWarn(config, engineWired) {
|
|
|
81
81
|
"WORKER fs; verify the lane really shares it.",
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
|
-
export function memoryEngineRootFor(config,
|
|
84
|
+
export function memoryEngineRootFor(config, localRoot) {
|
|
85
85
|
if (config.memoryEngineBackend !== "file")
|
|
86
|
-
return join(config.localDataRoot ??
|
|
87
|
-
return fileMemoryEngineRoot(config
|
|
86
|
+
return join(config.localDataRoot ?? localRoot ?? resolveMemoryEngineRoot(undefined), "memory-work");
|
|
87
|
+
return fileMemoryEngineRoot(config);
|
|
88
88
|
}
|
|
89
89
|
export function fileMemoryEngineRoot(config, fallbackRoot) {
|
|
90
90
|
return resolveMemoryEngineRoot(config.memoryEngineDir ?? fallbackRoot);
|
|
@@ -109,13 +109,30 @@ export function memoryEngineBackendFor(config, fallbackRoot, onIncident) {
|
|
|
109
109
|
const plane = fileMemoryPlaneFor(config, fallbackRoot);
|
|
110
110
|
if (plane === undefined)
|
|
111
111
|
return undefined;
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
let backend;
|
|
113
|
+
try {
|
|
114
|
+
backend = new FileMemoryEngineBackend(plane.memoryDir, {
|
|
114
115
|
controlDir: plane.controlDir,
|
|
115
116
|
...(onIncident !== undefined ? { onIncident } : {}),
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
catch (e) {
|
|
120
|
+
throw memoryStoreRootMovedRefusal(e) ?? e;
|
|
121
|
+
}
|
|
122
|
+
return { backend, root: plane.root };
|
|
123
|
+
}
|
|
124
|
+
export function memoryStoreRootMovedRefusal(e) {
|
|
125
|
+
const err = e;
|
|
126
|
+
const d = err?.detail;
|
|
127
|
+
if (err?.code !== "memory.target_outside_store" || typeof d?.path !== "string" || typeof d.controlDir !== "string")
|
|
128
|
+
return undefined;
|
|
129
|
+
const call = `reanchorMemoryStoreRoot(${JSON.stringify(d.path)}, { controlDir: ${JSON.stringify(d.controlDir)} })`;
|
|
130
|
+
const refusal = new Error(`the memory store root moved: its control plane records ${JSON.stringify(String(d.recorded))} but the store now resolves to ${JSON.stringify(String(d.now))} ` +
|
|
131
|
+
`(memory.target_outside_store) — refusing to start rather than read or write memory somewhere else. Put the directory back, or re-anchor it once ` +
|
|
132
|
+
`from this server's directory: node --input-type=module -e 'import("@sema-agent/core").then(m => m.${call})' — then start again.`);
|
|
133
|
+
refusal.code = "memory.target_outside_store";
|
|
134
|
+
refusal.cause = e;
|
|
135
|
+
return refusal;
|
|
119
136
|
}
|
|
120
137
|
export function memorySpecForRequest(scope, projectKey, memoryWrite, defaultScopes, originPolicy, declarations) {
|
|
121
138
|
if (!scope)
|
|
@@ -35,6 +35,18 @@ export declare const FAIL_OPEN_TAGS: {
|
|
|
35
35
|
readonly cls: "F";
|
|
36
36
|
readonly note: "S-297(`http/routes/sessions.ts lastLegMcpFor`,`/mcp` 面板的可选键 `lastLegMcp`):按会话取最近 run 的索引读 / 那条 run 的账本读**抛错或超期** ⇒ 该键缺席,面板本体照常 200。放行的最坏后果=这一屏少一格「上一次真挂上了什么」(壳退回翻账本),不是门、不是权限、不是凭证 —— 而反方向(让附加键的读失败打掉整张面板)会给一口此前零 MCP 配置下根本不碰账本的**既有**读面新加一条挂掉的理由。缺席本就是本键 wire 上的一等状态(消费端必须会读),所以这条兜底不产生任何新的消费端形态;计数让「某台部署的账本一直读不出来」显形。";
|
|
37
37
|
};
|
|
38
|
+
readonly "server.ledger.forward-append-failed": {
|
|
39
|
+
readonly cls: "F";
|
|
40
|
+
readonly note: "durable 腿 forward 道的写失败(`trace/ledger-sink.ts` 的 `createForwardAppendFailedNote`:账本汇 `onForwardEvent` —— bg 腿、sync detach 车道、续跑腿 verify 臂 —— 与续跑腿自己的 forward 回调同一只出口)。forward 道是同步回调里的 fire-and-forget 写(序号同步分配,结构上不能 await),写失败 ⇒ 这一帧(子代的 `task_started` / `task_progress` / 工具卡)永远不在 `GET /v1/runs/:id/events` 的回放面,run 照跑。放行的最坏后果 = 回放面少一帧子代事实(起跑帧每周期一只,丢了就补不回 `agentType` / `rootSessionId` / `startedAt`),不是门、不是凭据、不改任何裁决;不重试 —— 晚到的重试行会落在读方游标之后(单写串行链存在的理由)。计数非零 = 这台部署的账本写口在出错(主流的 awaited 写多半同时在报错),去看库。detail = `type=<帧型> err=<原句,经记录器脱敏>`。";
|
|
41
|
+
};
|
|
42
|
+
readonly "server.tool-end-media.live-backlog-degraded": {
|
|
43
|
+
readonly cls: "F";
|
|
44
|
+
readonly note: "core 7.50.0 媒体块提货(`trace/tool-output-media.ts` 的 `liveToolEndForBacklog`,三处活面写口共用的那一只判据 —— 同步流出口 `sseData`、子代 tail 路由写环、tail 总线每订阅者队列):本帧媒体字节 + 这条连接 / 这个订阅者还没送出去的字节 > 上界(64 MiB)⇒ 本帧媒体块降成持久面那只描述符(`{ type, mimeType?, bytes, truncated: true }`,帧级 `truncated` + `totalChars`)。每降一帧记一次,只在这只函数里记(三处写口不各记)。放行的最坏后果 = 一个读得慢的观众在 SSE 上看不到这张图,只见「这里有一张多大的什么图、没送达」(账本面本就恒是描述符),不是门、不是凭据、不改任何裁决;反方向(不降)让一条停读的连接随帧数线性压住几百 MiB。帧上它与引擎自己的媒体预算降级同形不可分,所以计数是运维唯一能看出「多少观众丢了图」的位;计数持续非零 = 有消费端读流太慢(或网络瓶颈),去看那几条连接。detail = `backlog=<待发字节> media=<本帧媒体字节>`。";
|
|
45
|
+
};
|
|
46
|
+
readonly "server.memory-consolidation.operator-valve-unjudged": {
|
|
47
|
+
readonly cls: "P-DEBT";
|
|
48
|
+
readonly note: "core 7.50.0 #1653 提货(`boot/memory-consolidation.ts` `createOperatorValveWriteJudge`):运维手动整理阀门这条腿的写判官座答 `no_objection` —— 这条腿没有腿(无名册写脸、无引擎盖的豁免根、无人的持久规则车道),引擎包不导出它那只合成写判官的构造器,本仓不手搭第二只。每被问一次(早问库目录一次 + 每个产物一次)记一次。放行的最坏后果 = 运维手动整理时,一条点名记忆库路径的部署写策略或人的持久规则拦不住这一轮折叠(与引擎 7.49.x 逐字同:那时驱动根本不问);自动整理腿走引擎腿自己的判官,不在本 tag 射程。收口 = 引擎导出宿主可用的写判官构造器,换上即删本 tag。";
|
|
49
|
+
};
|
|
38
50
|
readonly "server.workflow-park-index.sync-failed": {
|
|
39
51
|
readonly cls: "P-DEBT";
|
|
40
52
|
readonly note: "S-185 车CM(codex r1-F2 [high],验真后登记):workflow 出身 park 的 join 索引(`workflow_agent_session` / local 账本)在**一次成功的 run 写之后**同步失败 ⇒ 该次同步被吞,重试要等这条 run 的**下一次**写。而 park 恰好常常是这条 run 的**最后**一次写(park = run 终局 `failed`)⇒ 那条 park 可能永久 join 不到。**多数情形**是诚实 miss:这张卡没有别的指针 ⇒ `/decide` 结构性退回本批之前的行为(409 `conflict.resume_context_unavailable`),不误配、不伪造、不放行,丢的是「人能不能把这条批准送出去」这个能力。**7.118.0 起不止于此**:路由把指针候选当持有者的全集读,并有分叉门(两条同代次持有者 ⇒ 409 `decide.workflow_park_forked`);同一张卡上一枚**竞争**指针没写上(本臂的写失败,或写记录与写指针之间进程崩溃 —— 后者不经本臂、不计数)⇒ 分叉被判成唯一持有者 ⇒ 决定投给幸存的那一支(它确实持有这张卡,但另一支同样站在上面,引擎把这种形交给消费方拒)。归 P 类的理由:缺指针决定**车道选择**(缺行 ⇒ 选中 legacy 腿),且能让分叉门失效;归 DEBT 的理由是真正的解要一条**按子代 checkpoint 键的耐久决议回执 + 重启期回填**(与 codex r1-F3 同一件欠账,另车),分叉门失效那一形另有设计票。计数非零 = 有 park 可能决不掉、或这张卡的分叉门可能失效,运维要按 detail 里的 runId 去查那条 run 的续跑链。";
|
|
@@ -137,7 +149,7 @@ export declare const FAIL_OPEN_TAGS: {
|
|
|
137
149
|
};
|
|
138
150
|
readonly "server.approvals.park-row-blob-unreadable": {
|
|
139
151
|
readonly cls: "F";
|
|
140
|
-
readonly note: "S-700(`plugins/checkpoint-store-sql.ts` 的 `readParkRowFactsCell`):运维待批队列(`GET /v1/approvals` / `/stream`)的某一行,`checkpoint` 列里寄存行的 **`pendingAction` 子树**(NP-3 / 7.100.0 起引擎内只取这一棵、整只快照不出库;只为 park 行事实 `requiresRealApproval` / `ruleOffersAbsence` / `mandated`(S-663 二段,core #1079)/ `mandate`(S-721)/ `origin`(S-755)而读 —— 事实位的真源是 `approval-card.ts` 的 `ParkRowFacts`)**在场却不是一只对象**(JSON `null` 字面 / 串 / 数 —— 手改 / 迁移脚本改过)。子树**缺席**(SQL NULL:成员不在,或整只文档不是对象 —— 后者 `get()` 照旧拒;MariaDB 文本承载上的非 JSON 字节同样答 SQL NULL)⇒ 事实缺席、不计数。放行的最坏后果 = **这一行**的 park 行事实(`ParkRowFacts` 各位)缺席(展示/分诊材料;core 定性 display metadata,resume 的带子读 gate 自己的位),队列其余部分照常 —— 而这一行本来就 resume 不了(`get()` 对同一格拒)。不放行的代价是整只 `rows.map` 抛出 ⇒ 一行坏 blob 打掉整个租户的队列(列表 500、SSE 心跳照常而队列永远空),与同一 `rows.map` 里 `rule_suggestions` / `risk_descriptor` 两格同族同判。故 F 类;tag 与那两格**分开计**(哪一格在坏要读得出来)。计数非零 = 这一行的 decide 同样读不动(`get()` 对同一格拒),去按 session 查那一行。";
|
|
152
|
+
readonly note: "S-700(`plugins/checkpoint-store-sql.ts` 的 `readParkRowFactsCell`):运维待批队列(`GET /v1/approvals` / `/stream`)的某一行,`checkpoint` 列里寄存行的 **`pendingAction` 子树**(NP-3 / 7.100.0 起引擎内只取这一棵、整只快照不出库;只为 park 行事实 `requiresRealApproval` / `ruleOffersAbsence` / `mandated`(S-663 二段,core #1079)/ `mandate`(S-721)/ `origin`(S-755)而读 —— 事实位的真源是 `approval-card.ts` 的 `ParkRowFacts`)**在场却不是一只对象**(JSON `null` 字面 / 串 / 数 —— 手改 / 迁移脚本改过)。子树**缺席**(SQL NULL:成员不在,或整只文档不是对象 —— 后者 `get()` 照旧拒;MariaDB 文本承载上的非 JSON 字节同样答 SQL NULL)⇒ 事实缺席、不计数。放行的最坏后果 = **这一行**的 park 行事实(`ParkRowFacts` 各位)缺席(展示/分诊材料;core 定性 display metadata,resume 的带子读 gate 自己的位),队列其余部分照常 —— 而这一行本来就 resume 不了(`get()` 对同一格拒)。不放行的代价是整只 `rows.map` 抛出 ⇒ 一行坏 blob 打掉整个租户的队列(列表 500、SSE 心跳照常而队列永远空),与同一 `rows.map` 里 `rule_suggestions` / `risk_descriptor` 两格同族同判。故 F 类;tag 与那两格**分开计**(哪一格在坏要读得出来)。计数非零 = 这一行的 decide 同样读不动(`get()` 对同一格拒),去按 session 查那一行。 **第二座 `member=gate`**(`readParkGateCell`:同一列的 **`gate` 子树**在场却不是一只对象 —— 队列行的卡词与到期两条腿的分法都读它):读不出 = 门上无卡,队列行不带卡词,**到期改道** —— core `facetOf` 读「无卡 = 不是一问」为 `A`,所以一张本该到期**作废**的问答行改走 SLA **拒扫腿**(模型拿到一次「拒」而不是整条 run 作废);改道后的续跑 `get()` 对同一份坏 blob 响亮拒(拒扫腿每拍一条失败),行留停驻、由 `terminal_at_ms` 兜底收割 —— 所以最坏后果**不是**「只少展示」,是一张问答行的到期去向变了、最长挂到绝对上限。放行仍对:不放行的代价与 pendingAction 座同(一行坏 blob 打掉整个租户的队列与到期读腿)。计数 detail = `member=gate` 时,去按 session 查那一行的 `checkpoint.gate`。";
|
|
141
153
|
};
|
|
142
154
|
readonly "server.sql-json.checkpoint.pending-steer-queue-lossy": {
|
|
143
155
|
readonly cls: "F";
|
|
@@ -225,7 +237,7 @@ export declare const FAIL_OPEN_TAGS: {
|
|
|
225
237
|
};
|
|
226
238
|
readonly "server.hooks.matcher-unjudged": {
|
|
227
239
|
readonly cls: "F";
|
|
228
|
-
readonly note: "S-995(`hooks/hook-runner.ts` 的 `
|
|
240
|
+
readonly note: "S-995(`hooks/hook-runner.ts` 的 `toolMatcherIssue`,fresh 受理面「工具事件 matcher 选中别名而选不中正名 ⇒ 400」判据的**未判**臂;detail = `event=… reason=… matcherChars=…`,不带 matcher 原字节):一只 matcher 没能被判 ⇒ 照旧受理。判据一条顺序、两档共用(7.114.0 修复轮):长度上限 → 形只问契约包的 `hookMatcherForm`(literal 形〔名字表 / 空 / `*`〕两档都直接问 `hookMatcherSelects`、不占预算;regex 形 regex 档把同一只契约函数交进 vm 带每次求值各一份的固定预算〔超时 = 灾难回溯 ⇒ 确定的 400 拒,不是未判、不登记〕、literal 档不适用;invalid 形 regex 档 = 确定的 400 拒〔S-1455 收尾:不是未判、不登记;运行期另记 `hook_matcher_invalid`〕、literal 档不适用)。现在只有一种 reason —— `oversize`(两档:超 8 192 字符不读;多租户车道上 hooks 不装配,这一笔只为让超长输入显形)。`invalid_regex` 臂自 S-1455 收尾(7.126.0)起退役:它是确定性的坏配置、不是「判不了」,与超预算同类 ⇒ 受理当场 400。**不记**的:literal 档(多租户车道)遇正则形 = 不适用 —— 该车道 hooks 整只不装配,没有被守的对象,不是未判。放行的最坏后果 = **那一只 matcher 没被这条判据守住**:它若真写了别名,照旧永不命中(7.112.0 对正则形一律不判,同一后果);**不是安全闸**(受理面的有效性判 = S-924 的「响亮」,决定不了任何放行 / 拒绝 / 权限;hook 的 deny 语义在运行期 hook-runner)。拒放集合相对 7.113.0 的一处放宽:超过上限的字面别名 matcher 7.113.0 拒、7.114.0 两档未判受理(已披露)。计数让「受理面一直判不了」(超长 matcher)显形。";
|
|
229
241
|
};
|
|
230
242
|
readonly "server.hooks.notice-sink-threw": {
|
|
231
243
|
readonly cls: "F";
|
|
@@ -313,7 +325,7 @@ export declare const FAIL_OPEN_TAGS: {
|
|
|
313
325
|
};
|
|
314
326
|
readonly "server.approval-card.closed-word-out-of-set": {
|
|
315
327
|
readonly cls: "F";
|
|
316
|
-
readonly note: "S-249(`approval-card.ts`
|
|
328
|
+
readonly note: "S-249(`approval-card.ts` 的边界窄读族;今天四个成员:`readRuleOffersAbsence`、S-934 ② 起的 `readAskClassPair`(core 7.37.0 #1214 的类对 `askClass` / `classes`,活卡帧 / 呈卡帧的卡 / 运维队列行同一只,判法 = core 屏 `screenAskClassMembers`(S-955 ⑥ / core 7.38.0 #1249,本仓零自写对判),两键同在同缺,半对 / 集外 / 首员不符 / 重复员 = 屏拒 = 读不出;detail 前缀 `askClass=` / `classes=`),与 S-721 起的 `readClosedWordSeat` —— 一座一只 core 成员筛,座是参数:`mandate`(core 7.32.0 #1092,活卡帧 / 活挂起行 / 运维队列行同一只,闭集筛 = core `isPersistedRuleMandate`)与 S-755 起的 `origin`(运维队列行读 park 行孪生座,闭集筛 = core `isAskOrigin`,与 inbox 行 core 投影处同一只筛)、S-1170 起的 `classifierNoRuling`(core 7.43.0 #1353 的成因词,活卡帧读 `AskRequest.classifierNoRuling`,闭集筛 = core `isAutoModeFallbackCause`)与 `differs`(core 7.44.0 #1374,载体是 `runs.ts` 的 409 `steering.duplicate_input_id` 体读的引擎拒错 `detail.differs`,闭集筛 = core `STEER_REPLAY_FACETS` 的非空子集;集外成员 / 空 / 非数组 ⇒ 不铸 `detail`,码仍是契约);detail 前缀 `ruleOffersAbsence=` / `mandate=` / `origin=` / `classifierNoRuling=` / `differs=` 判别是哪一座;第四个成员是 `approval-content-kind.ts` 的 `readApprovalCard` —— 卡词 `approvalCard` 自己的闭集窄读,活 ask / LOCAL 店停驻门 / SQL 店读出的门子树三个载体共用一只,闭集 = core `TOOL_APPROVAL_CARDS`,detail 前缀 `approvalCard=`):活卡帧 / `card_json` / (S-700 起)运维队列行(`parkRowFacts` 读寄存行上的 park 孪生座;队列是热读面 ⇒ 同一行每读一次计一次)的一个**闭集词**座上,键在场而词不在本仓认得的那张表里(世代差,或第三方 producer)⇒ 该座**按缺席**处置。放行的最坏后果=卡上少一行「为什么这次没有规则候选」的解释(壳退回不显示该行),它**不改变任何裁决**——门在引擎里早已判完,本座是展示/观测面;反方向(把一个消费端词表外的值原样上卡)更坏:下游按闭集写的分支会落进 default 臂或渲染出生词。本臂存在的全部理由是**判别**:修前「上游发了个生词」与「上游根本没发这个键」在遥测上同形,而前者意味着本仓的词表该跟着 core 加词了(型面另有两向编译围栏,但那只在**重新编译**时说话,跑在线上的那一版不会自己红)。detail 带座名与那个词(经 redactSecrets 截 40);数 / 布尔等原始值原样,对象 / 数组 / 函数 / null 只报形名(`<object>` / `<array>` / `<function>` / `<null>`,S-700 codex r1:格式化从不调用值自己的转换方法 —— 持久层里一格 `{\"toString\":null}` 曾让诊断本身抛出、打掉整只队列)。";
|
|
317
329
|
};
|
|
318
330
|
readonly "server.pg-pool.idle-client-error": {
|
|
319
331
|
readonly cls: "F";
|
|
@@ -419,6 +431,22 @@ export declare const FAIL_OPEN_TAGS: {
|
|
|
419
431
|
readonly bound: "FLEET_LEASE_OUTAGE_MAX_MS";
|
|
420
432
|
readonly note: "`fleet/serving-lease.ts` 的 `noteCenterCapabilities`(fleet 成员每一次中心能力读数;detail = `worker=<w> generation=<g> was=<enabled|none>`):中心答复体读得出、却**没有宣告** `servingLease`(老中心 `{ ok: true }` / 降级中心 / 位撤掉)⇒ 规则 1:租约不生效,`leaseState: none`,零续租、零 503 —— 这只 fleet 成员此刻**不受围栏**。答复体读不出不进这一臂(那是「没有读数」,上一次的位与钟原样,`fleet-client.ts` `capabilityReadingOf`);已被拒的实例不进(拒是黏的,位消失不复活)。归 R:能力门控是契约规则(中心不宣告 = 中心不执行围栏),裁定写定替换只来自中心权威终止或运维覆盖;位只开关围栏、不碰钟 —— 位缺席期间 `T_max` 的钟照走(最后一次授予的到期 / 本进程第一次见到位的时刻),位一回来即按它判,所以位的抖动绕不过 `FLEET_LEASE_OUTAGE_MAX_MS`。放行的最坏后果 = 中心不执行围栏期间,一只被取代的实例照常服务(这一段由中心的选择定界,不由引擎)。计数长期保留:非零 = 这台中心没宣告租约能力。";
|
|
421
433
|
};
|
|
434
|
+
readonly "server.workspace-cache.unavailable": {
|
|
435
|
+
readonly cls: "F";
|
|
436
|
+
readonly note: "k8s 车道按工作区空间的构建缓存卷(`WORKSPACE_CACHE=volume`,`plugins/remote-env-k8s.ts` 连沙箱那一步):这条 run 拿不到它空间的缓存卷 —— 卷建不成(RBAC 少动词 / API 拒 / 网络错,`reason=claim_failed`)、卷在快照时限内没绑定(集群没有缺省 StorageClass / 供给器不在,`reason=claim_unbound`)、卷绑上了而挂着它的 pod 起不来(挂载失败 / 卷所在节点没了,`reason=claim_unmountable`)—— 后两种把等它的那只 pod 删掉,换一只不挂卷的 —— 、或本副本读不出会话住客没有空间键(`reason=incarnation_unknown`)⇒ run **照常起**:不挂卷、不注入工具缓存 env,工具按镜像自己的缓存目录工作(每轮重下依赖)。放行的最坏后果 = 这一轮构建慢(缓存定义上可再生),不是门、不是凭据、不碰工作区与快照;反方向(卷拿不到就拒这一轮)会让一个缓存把整条 run 打掉。同拍一行运维日志 `workspace_cache_unavailable`(`space` 前缀 / `reason` / `error`)。计数非零 = 这台部署开了缓存卷却拿不到,运维去看 StorageClass / Role / 配额。";
|
|
437
|
+
};
|
|
438
|
+
readonly "server.workspace-cache.reclaim-failed": {
|
|
439
|
+
readonly cls: "F";
|
|
440
|
+
readonly note: "k8s 车道按工作区空间的构建缓存卷的**回收**(`plugins/remote-env-k8s.ts` `createSpaceReclaimer`;两条腿同一只回收座:会话删除协调器 `boot/session-faces.ts` `purgeSession` 与托管留存 sweep `boot/retention-lane.ts` 删掉会话树之后):按标签 `sema.space=<空间摘要>` 删卷的请求失败(Role 少 `deletecollection` / API 拒 / 网络,`reason=delete_failed`)、回收座这次调用的绝对截止(= 快照时限)先到(请求没发或在途被切,`reason=budget`),或在线腿删除前读不出被删会话的住客(`reason=occupant_unreadable`;化身缺席的存量行 = 没有空间,不计)⇒ 卷留着(住客读不出时该空间的快照对象也没回收,归桶的生命周期规则),会话照删(不挡删除)。放行的最坏后果 = 节点盘上多留一只没人再用的卷(存储泄漏,不碰任何别的空间、不是门不是凭据);反方向(删卷失败就拒删会话)会让一个缓存挡住删除权。同拍一行 `workspace_cache_reclaim_failed`(回收座的两形:`space` 前缀 / `label` / `reason` / `error`;住客读不出那一形:`sessionId` / `reason` / `error`)。计数非零 = 有卷没回收掉,运维按行里的标签手清,并核 Role。";
|
|
441
|
+
};
|
|
442
|
+
readonly "server.workspace-space.reclaim-failed": {
|
|
443
|
+
readonly cls: "F";
|
|
444
|
+
readonly note: "k8s 车道工作区空间结束时对**快照对象**的回收(`plugins/remote-env-k8s.ts` `createSpaceReclaimer` 的对象部分;与上一条同一只回收座、两条腿:会话删除协调器与托管留存 sweep):按空间的 `<前缀>/<化身>/space/` 分区(快照 + `latest`)和该会话停驻车道里名字带被结束住客归属记号的 `<前缀>/<会话 id>/*.tar.gz` 分别 LIST、逐个预签 DELETE;LIST 失败、DELETE 失败(HTTP 非 2xx / 非 404、网络)LIST 超过 1000 个对象被截断,或回收座一次调用的绝对截止(= 快照时限;卷回收也在内)到点〔切断在途请求、停掉余下的;这次调用里还没轮到的空间零请求、各记一次;没删的归生命周期规则〕,各记一次(detail `lane=space|park stage=list|delete|budget`;会话删除口把回收座脱离应答路径,座若抛了——契约禁止——记 `stage=seat_threw`)⇒ 这些对象留在桶里,会话照删(不挡删除)。放行的最坏后果 = 一份已无人能读的工作区快照留在桶里(会话已删,经 API 不可达;内容是用户工作区,所以不是「只占盘」—— 留到桶的生命周期规则把它过期掉为止);不碰任何别的空间、不是门不是凭据;反方向(清不掉对象就拒删会话)会让一个对象存储抖动挡住用户的删除权。故 F 类,但必须留痕:静默吞掉之后「这个会话删了、它的工作区内容还在不在桶里」在遥测里没有任何痕迹。同拍一行 `workspace_space_reclaim_failed`(`space` 前缀 / `sessionId` / `lane` / `stage` / `error`)。计数非零 = 有对象没回收掉,运维按行里的空间前缀 / 会话 id 去桶里手清,并核对象存储的可达性与 DELETE 权限。回收与同一空间的尚在途的 run 末提交不是互斥的:会话删除时没有活 run(409 挡),但上一条 run 的提交若恰在删除之后才落对象,这批对象不在本次回收射程内(同样归桶的生命周期规则)。停驻分区按会话 id 分区,所以只删名字带被结束住客归属记号的对象(不读任何钟)—— 会话 id 删后被别人重新登记,新住客停驻出的快照带它自己的记号、不碰;不带记号的旧形与 `none` 留给桶的生命周期规则。";
|
|
445
|
+
};
|
|
446
|
+
readonly "server.sandbox-egress.policy-gap": {
|
|
447
|
+
readonly cls: "P-DEBT";
|
|
448
|
+
readonly note: "k8s 车道沙箱出网的起服自检(`plugins/remote-env-k8s.ts` `checkSandboxEgressPolicy` 读节点表与沙箱 ns 的 NetworkPolicy,判法 `sandbox-egress-policy.ts` `sandboxEgressGaps`;起服一次、不挡起服)读出一个缺口 —— 某节点的 InternalIP / ExternalIP 落在一条放行 ipBlock 内(`kind=node_address_open`)、没有策略以 Egress 选中沙箱 pod(`kind=policy_absent`)、pod 保留 IPv6 而策略层担保不了 v6(`kind=ipv6_enabled`)、节点表或策略表读不到(`kind=unreadable what=nodes|networkpolicies`)⇒ 车道**照常起**,每个缺口一行 `sandbox_egress_policy_gap`(带后果句与去哪改)。归 P 类:出网策略是保护面,缺口意味着沙箱里的代码可能够到节点上的服务;归 DEBT 的理由:修法都在集群配置里(节点地址点名、kubelet 放行 v6 sysctl、CNI 的 v6 执行、RBAC),本服务改不了,而拒起车道会让缺省单节点装法(恒有 `ipv6_enabled`)升级即停摆沙箱执行 —— 车道自己的隔离(VM 边界、零 SA token)仍在。放行的最坏后果 = 读出缺口的那一面照旧可达,直到运维按行里的后果句改配置。计数非零 = 这台部署的沙箱出网面有读得出的缺口。读不出的面(宿主 DNAT 发布端口、「pod 所在节点恒放行」的实现差异、CNI 根本不执行策略)不在本 tag 的射程里。";
|
|
449
|
+
};
|
|
422
450
|
readonly "server.fleet.announce-reply-unreadable": {
|
|
423
451
|
readonly cls: "P-DEBT";
|
|
424
452
|
readonly note: "7.121.0 修复验证轮(`fleet-client.ts` 的公告环,fleet 成员每一拍心跳 2xx 答复;detail = `why=<body|not-an-object|invalid-capabilities> leaseState=<此刻的租约态>`):答复不是能力读数(体读不出 / 不是对象 / `capabilities` 键在场而形坏 —— settings-schema 9.0.0 `readCapabilityReading` 的 `unreadable`,外加本仓的 `body`)⇒ 当作没有这一拍答复,租约的状态与钟原样。**一律**计数(不论租约生效与否):租约还没生效(`leaseState=none`)时这只成员**一直不受围栏**,而修前这一形零计数(中心每拍答 `<html>` ⇒ 成员恒 none、零痕迹);租约已生效时计数说明中心的答复在坏、围栏靠的是上一次读数。归 P 类:围栏轴;归 DEBT:本进程判不出中心为什么答坏体,收口条件 = 中心契约 / 监控(中心侧对心跳答复形的执法)落地。每段连拍另有一行 warn `fleet_announce_reply_unreadable`(带 `why`)。";
|
|
@@ -16,6 +16,18 @@ export const FAIL_OPEN_TAGS = {
|
|
|
16
16
|
cls: "F",
|
|
17
17
|
note: "S-297(`http/routes/sessions.ts lastLegMcpFor`,`/mcp` 面板的可选键 `lastLegMcp`):按会话取最近 run 的索引读 / 那条 run 的账本读**抛错或超期** ⇒ 该键缺席,面板本体照常 200。放行的最坏后果=这一屏少一格「上一次真挂上了什么」(壳退回翻账本),不是门、不是权限、不是凭证 —— 而反方向(让附加键的读失败打掉整张面板)会给一口此前零 MCP 配置下根本不碰账本的**既有**读面新加一条挂掉的理由。缺席本就是本键 wire 上的一等状态(消费端必须会读),所以这条兜底不产生任何新的消费端形态;计数让「某台部署的账本一直读不出来」显形。",
|
|
18
18
|
},
|
|
19
|
+
"server.ledger.forward-append-failed": {
|
|
20
|
+
cls: "F",
|
|
21
|
+
note: "durable 腿 forward 道的写失败(`trace/ledger-sink.ts` 的 `createForwardAppendFailedNote`:账本汇 `onForwardEvent` —— bg 腿、sync detach 车道、续跑腿 verify 臂 —— 与续跑腿自己的 forward 回调同一只出口)。forward 道是同步回调里的 fire-and-forget 写(序号同步分配,结构上不能 await),写失败 ⇒ 这一帧(子代的 `task_started` / `task_progress` / 工具卡)永远不在 `GET /v1/runs/:id/events` 的回放面,run 照跑。放行的最坏后果 = 回放面少一帧子代事实(起跑帧每周期一只,丢了就补不回 `agentType` / `rootSessionId` / `startedAt`),不是门、不是凭据、不改任何裁决;不重试 —— 晚到的重试行会落在读方游标之后(单写串行链存在的理由)。计数非零 = 这台部署的账本写口在出错(主流的 awaited 写多半同时在报错),去看库。detail = `type=<帧型> err=<原句,经记录器脱敏>`。",
|
|
22
|
+
},
|
|
23
|
+
"server.tool-end-media.live-backlog-degraded": {
|
|
24
|
+
cls: "F",
|
|
25
|
+
note: "core 7.50.0 媒体块提货(`trace/tool-output-media.ts` 的 `liveToolEndForBacklog`,三处活面写口共用的那一只判据 —— 同步流出口 `sseData`、子代 tail 路由写环、tail 总线每订阅者队列):本帧媒体字节 + 这条连接 / 这个订阅者还没送出去的字节 > 上界(64 MiB)⇒ 本帧媒体块降成持久面那只描述符(`{ type, mimeType?, bytes, truncated: true }`,帧级 `truncated` + `totalChars`)。每降一帧记一次,只在这只函数里记(三处写口不各记)。放行的最坏后果 = 一个读得慢的观众在 SSE 上看不到这张图,只见「这里有一张多大的什么图、没送达」(账本面本就恒是描述符),不是门、不是凭据、不改任何裁决;反方向(不降)让一条停读的连接随帧数线性压住几百 MiB。帧上它与引擎自己的媒体预算降级同形不可分,所以计数是运维唯一能看出「多少观众丢了图」的位;计数持续非零 = 有消费端读流太慢(或网络瓶颈),去看那几条连接。detail = `backlog=<待发字节> media=<本帧媒体字节>`。",
|
|
26
|
+
},
|
|
27
|
+
"server.memory-consolidation.operator-valve-unjudged": {
|
|
28
|
+
cls: "P-DEBT",
|
|
29
|
+
note: "core 7.50.0 #1653 提货(`boot/memory-consolidation.ts` `createOperatorValveWriteJudge`):运维手动整理阀门这条腿的写判官座答 `no_objection` —— 这条腿没有腿(无名册写脸、无引擎盖的豁免根、无人的持久规则车道),引擎包不导出它那只合成写判官的构造器,本仓不手搭第二只。每被问一次(早问库目录一次 + 每个产物一次)记一次。放行的最坏后果 = 运维手动整理时,一条点名记忆库路径的部署写策略或人的持久规则拦不住这一轮折叠(与引擎 7.49.x 逐字同:那时驱动根本不问);自动整理腿走引擎腿自己的判官,不在本 tag 射程。收口 = 引擎导出宿主可用的写判官构造器,换上即删本 tag。",
|
|
30
|
+
},
|
|
19
31
|
"server.workflow-park-index.sync-failed": {
|
|
20
32
|
cls: "P-DEBT",
|
|
21
33
|
note: "S-185 车CM(codex r1-F2 [high],验真后登记):workflow 出身 park 的 join 索引(`workflow_agent_session` / local 账本)在**一次成功的 run 写之后**同步失败 ⇒ 该次同步被吞,重试要等这条 run 的**下一次**写。而 park 恰好常常是这条 run 的**最后**一次写(park = run 终局 `failed`)⇒ 那条 park 可能永久 join 不到。**多数情形**是诚实 miss:这张卡没有别的指针 ⇒ `/decide` 结构性退回本批之前的行为(409 `conflict.resume_context_unavailable`),不误配、不伪造、不放行,丢的是「人能不能把这条批准送出去」这个能力。**7.118.0 起不止于此**:路由把指针候选当持有者的全集读,并有分叉门(两条同代次持有者 ⇒ 409 `decide.workflow_park_forked`);同一张卡上一枚**竞争**指针没写上(本臂的写失败,或写记录与写指针之间进程崩溃 —— 后者不经本臂、不计数)⇒ 分叉被判成唯一持有者 ⇒ 决定投给幸存的那一支(它确实持有这张卡,但另一支同样站在上面,引擎把这种形交给消费方拒)。归 P 类的理由:缺指针决定**车道选择**(缺行 ⇒ 选中 legacy 腿),且能让分叉门失效;归 DEBT 的理由是真正的解要一条**按子代 checkpoint 键的耐久决议回执 + 重启期回填**(与 codex r1-F3 同一件欠账,另车),分叉门失效那一形另有设计票。计数非零 = 有 park 可能决不掉、或这张卡的分叉门可能失效,运维要按 detail 里的 runId 去查那条 run 的续跑链。",
|
|
@@ -118,7 +130,7 @@ export const FAIL_OPEN_TAGS = {
|
|
|
118
130
|
},
|
|
119
131
|
"server.approvals.park-row-blob-unreadable": {
|
|
120
132
|
cls: "F",
|
|
121
|
-
note: "S-700(`plugins/checkpoint-store-sql.ts` 的 `readParkRowFactsCell`):运维待批队列(`GET /v1/approvals` / `/stream`)的某一行,`checkpoint` 列里寄存行的 **`pendingAction` 子树**(NP-3 / 7.100.0 起引擎内只取这一棵、整只快照不出库;只为 park 行事实 `requiresRealApproval` / `ruleOffersAbsence` / `mandated`(S-663 二段,core #1079)/ `mandate`(S-721)/ `origin`(S-755)而读 —— 事实位的真源是 `approval-card.ts` 的 `ParkRowFacts`)**在场却不是一只对象**(JSON `null` 字面 / 串 / 数 —— 手改 / 迁移脚本改过)。子树**缺席**(SQL NULL:成员不在,或整只文档不是对象 —— 后者 `get()` 照旧拒;MariaDB 文本承载上的非 JSON 字节同样答 SQL NULL)⇒ 事实缺席、不计数。放行的最坏后果 = **这一行**的 park 行事实(`ParkRowFacts` 各位)缺席(展示/分诊材料;core 定性 display metadata,resume 的带子读 gate 自己的位),队列其余部分照常 —— 而这一行本来就 resume 不了(`get()` 对同一格拒)。不放行的代价是整只 `rows.map` 抛出 ⇒ 一行坏 blob 打掉整个租户的队列(列表 500、SSE 心跳照常而队列永远空),与同一 `rows.map` 里 `rule_suggestions` / `risk_descriptor` 两格同族同判。故 F 类;tag 与那两格**分开计**(哪一格在坏要读得出来)。计数非零 = 这一行的 decide 同样读不动(`get()` 对同一格拒),去按 session 查那一行。",
|
|
133
|
+
note: "S-700(`plugins/checkpoint-store-sql.ts` 的 `readParkRowFactsCell`):运维待批队列(`GET /v1/approvals` / `/stream`)的某一行,`checkpoint` 列里寄存行的 **`pendingAction` 子树**(NP-3 / 7.100.0 起引擎内只取这一棵、整只快照不出库;只为 park 行事实 `requiresRealApproval` / `ruleOffersAbsence` / `mandated`(S-663 二段,core #1079)/ `mandate`(S-721)/ `origin`(S-755)而读 —— 事实位的真源是 `approval-card.ts` 的 `ParkRowFacts`)**在场却不是一只对象**(JSON `null` 字面 / 串 / 数 —— 手改 / 迁移脚本改过)。子树**缺席**(SQL NULL:成员不在,或整只文档不是对象 —— 后者 `get()` 照旧拒;MariaDB 文本承载上的非 JSON 字节同样答 SQL NULL)⇒ 事实缺席、不计数。放行的最坏后果 = **这一行**的 park 行事实(`ParkRowFacts` 各位)缺席(展示/分诊材料;core 定性 display metadata,resume 的带子读 gate 自己的位),队列其余部分照常 —— 而这一行本来就 resume 不了(`get()` 对同一格拒)。不放行的代价是整只 `rows.map` 抛出 ⇒ 一行坏 blob 打掉整个租户的队列(列表 500、SSE 心跳照常而队列永远空),与同一 `rows.map` 里 `rule_suggestions` / `risk_descriptor` 两格同族同判。故 F 类;tag 与那两格**分开计**(哪一格在坏要读得出来)。计数非零 = 这一行的 decide 同样读不动(`get()` 对同一格拒),去按 session 查那一行。 **第二座 `member=gate`**(`readParkGateCell`:同一列的 **`gate` 子树**在场却不是一只对象 —— 队列行的卡词与到期两条腿的分法都读它):读不出 = 门上无卡,队列行不带卡词,**到期改道** —— core `facetOf` 读「无卡 = 不是一问」为 `A`,所以一张本该到期**作废**的问答行改走 SLA **拒扫腿**(模型拿到一次「拒」而不是整条 run 作废);改道后的续跑 `get()` 对同一份坏 blob 响亮拒(拒扫腿每拍一条失败),行留停驻、由 `terminal_at_ms` 兜底收割 —— 所以最坏后果**不是**「只少展示」,是一张问答行的到期去向变了、最长挂到绝对上限。放行仍对:不放行的代价与 pendingAction 座同(一行坏 blob 打掉整个租户的队列与到期读腿)。计数 detail = `member=gate` 时,去按 session 查那一行的 `checkpoint.gate`。",
|
|
122
134
|
},
|
|
123
135
|
"server.sql-json.checkpoint.pending-steer-queue-lossy": {
|
|
124
136
|
cls: "F",
|
|
@@ -206,7 +218,7 @@ export const FAIL_OPEN_TAGS = {
|
|
|
206
218
|
},
|
|
207
219
|
"server.hooks.matcher-unjudged": {
|
|
208
220
|
cls: "F",
|
|
209
|
-
note: "S-995(`hooks/hook-runner.ts` 的 `
|
|
221
|
+
note: "S-995(`hooks/hook-runner.ts` 的 `toolMatcherIssue`,fresh 受理面「工具事件 matcher 选中别名而选不中正名 ⇒ 400」判据的**未判**臂;detail = `event=… reason=… matcherChars=…`,不带 matcher 原字节):一只 matcher 没能被判 ⇒ 照旧受理。判据一条顺序、两档共用(7.114.0 修复轮):长度上限 → 形只问契约包的 `hookMatcherForm`(literal 形〔名字表 / 空 / `*`〕两档都直接问 `hookMatcherSelects`、不占预算;regex 形 regex 档把同一只契约函数交进 vm 带每次求值各一份的固定预算〔超时 = 灾难回溯 ⇒ 确定的 400 拒,不是未判、不登记〕、literal 档不适用;invalid 形 regex 档 = 确定的 400 拒〔S-1455 收尾:不是未判、不登记;运行期另记 `hook_matcher_invalid`〕、literal 档不适用)。现在只有一种 reason —— `oversize`(两档:超 8 192 字符不读;多租户车道上 hooks 不装配,这一笔只为让超长输入显形)。`invalid_regex` 臂自 S-1455 收尾(7.126.0)起退役:它是确定性的坏配置、不是「判不了」,与超预算同类 ⇒ 受理当场 400。**不记**的:literal 档(多租户车道)遇正则形 = 不适用 —— 该车道 hooks 整只不装配,没有被守的对象,不是未判。放行的最坏后果 = **那一只 matcher 没被这条判据守住**:它若真写了别名,照旧永不命中(7.112.0 对正则形一律不判,同一后果);**不是安全闸**(受理面的有效性判 = S-924 的「响亮」,决定不了任何放行 / 拒绝 / 权限;hook 的 deny 语义在运行期 hook-runner)。拒放集合相对 7.113.0 的一处放宽:超过上限的字面别名 matcher 7.113.0 拒、7.114.0 两档未判受理(已披露)。计数让「受理面一直判不了」(超长 matcher)显形。",
|
|
210
222
|
},
|
|
211
223
|
"server.hooks.notice-sink-threw": {
|
|
212
224
|
cls: "F",
|
|
@@ -273,7 +285,7 @@ export const FAIL_OPEN_TAGS = {
|
|
|
273
285
|
"server.redact.ppk-eat-to-end": { cls: "F", note: "S-107 第三十二轮重扫:PuTTY .ppk 容器扫描器(redact.ts redactPpkContainers)在「无合格终止 / 收口后同容器范围再见私钥字段 / 收口后到下一版本头之间夹非空白」三形下从头**吃到输入末尾**(fail-closed 取证丢弃)——终态 errorMessage 座上=整条错误文案变成 «redacted:private-key»,与 redactions_applied_total{private-key} 的诚实替换同形不可分,故要有自己的计数/探针;影子扫不计;计数=多少次整段吃尾。" },
|
|
274
286
|
"server.approval-card.closed-word-out-of-set": {
|
|
275
287
|
cls: "F",
|
|
276
|
-
note: "S-249(`approval-card.ts`
|
|
288
|
+
note: "S-249(`approval-card.ts` 的边界窄读族;今天四个成员:`readRuleOffersAbsence`、S-934 ② 起的 `readAskClassPair`(core 7.37.0 #1214 的类对 `askClass` / `classes`,活卡帧 / 呈卡帧的卡 / 运维队列行同一只,判法 = core 屏 `screenAskClassMembers`(S-955 ⑥ / core 7.38.0 #1249,本仓零自写对判),两键同在同缺,半对 / 集外 / 首员不符 / 重复员 = 屏拒 = 读不出;detail 前缀 `askClass=` / `classes=`),与 S-721 起的 `readClosedWordSeat` —— 一座一只 core 成员筛,座是参数:`mandate`(core 7.32.0 #1092,活卡帧 / 活挂起行 / 运维队列行同一只,闭集筛 = core `isPersistedRuleMandate`)与 S-755 起的 `origin`(运维队列行读 park 行孪生座,闭集筛 = core `isAskOrigin`,与 inbox 行 core 投影处同一只筛)、S-1170 起的 `classifierNoRuling`(core 7.43.0 #1353 的成因词,活卡帧读 `AskRequest.classifierNoRuling`,闭集筛 = core `isAutoModeFallbackCause`)与 `differs`(core 7.44.0 #1374,载体是 `runs.ts` 的 409 `steering.duplicate_input_id` 体读的引擎拒错 `detail.differs`,闭集筛 = core `STEER_REPLAY_FACETS` 的非空子集;集外成员 / 空 / 非数组 ⇒ 不铸 `detail`,码仍是契约);detail 前缀 `ruleOffersAbsence=` / `mandate=` / `origin=` / `classifierNoRuling=` / `differs=` 判别是哪一座;第四个成员是 `approval-content-kind.ts` 的 `readApprovalCard` —— 卡词 `approvalCard` 自己的闭集窄读,活 ask / LOCAL 店停驻门 / SQL 店读出的门子树三个载体共用一只,闭集 = core `TOOL_APPROVAL_CARDS`,detail 前缀 `approvalCard=`):活卡帧 / `card_json` / (S-700 起)运维队列行(`parkRowFacts` 读寄存行上的 park 孪生座;队列是热读面 ⇒ 同一行每读一次计一次)的一个**闭集词**座上,键在场而词不在本仓认得的那张表里(世代差,或第三方 producer)⇒ 该座**按缺席**处置。放行的最坏后果=卡上少一行「为什么这次没有规则候选」的解释(壳退回不显示该行),它**不改变任何裁决**——门在引擎里早已判完,本座是展示/观测面;反方向(把一个消费端词表外的值原样上卡)更坏:下游按闭集写的分支会落进 default 臂或渲染出生词。本臂存在的全部理由是**判别**:修前「上游发了个生词」与「上游根本没发这个键」在遥测上同形,而前者意味着本仓的词表该跟着 core 加词了(型面另有两向编译围栏,但那只在**重新编译**时说话,跑在线上的那一版不会自己红)。detail 带座名与那个词(经 redactSecrets 截 40);数 / 布尔等原始值原样,对象 / 数组 / 函数 / null 只报形名(`<object>` / `<array>` / `<function>` / `<null>`,S-700 codex r1:格式化从不调用值自己的转换方法 —— 持久层里一格 `{\"toString\":null}` 曾让诊断本身抛出、打掉整只队列)。",
|
|
277
289
|
},
|
|
278
290
|
"server.pg-pool.idle-client-error": {
|
|
279
291
|
cls: "F",
|
|
@@ -379,6 +391,22 @@ export const FAIL_OPEN_TAGS = {
|
|
|
379
391
|
bound: "FLEET_LEASE_OUTAGE_MAX_MS",
|
|
380
392
|
note: "`fleet/serving-lease.ts` 的 `noteCenterCapabilities`(fleet 成员每一次中心能力读数;detail = `worker=<w> generation=<g> was=<enabled|none>`):中心答复体读得出、却**没有宣告** `servingLease`(老中心 `{ ok: true }` / 降级中心 / 位撤掉)⇒ 规则 1:租约不生效,`leaseState: none`,零续租、零 503 —— 这只 fleet 成员此刻**不受围栏**。答复体读不出不进这一臂(那是「没有读数」,上一次的位与钟原样,`fleet-client.ts` `capabilityReadingOf`);已被拒的实例不进(拒是黏的,位消失不复活)。归 R:能力门控是契约规则(中心不宣告 = 中心不执行围栏),裁定写定替换只来自中心权威终止或运维覆盖;位只开关围栏、不碰钟 —— 位缺席期间 `T_max` 的钟照走(最后一次授予的到期 / 本进程第一次见到位的时刻),位一回来即按它判,所以位的抖动绕不过 `FLEET_LEASE_OUTAGE_MAX_MS`。放行的最坏后果 = 中心不执行围栏期间,一只被取代的实例照常服务(这一段由中心的选择定界,不由引擎)。计数长期保留:非零 = 这台中心没宣告租约能力。",
|
|
381
393
|
},
|
|
394
|
+
"server.workspace-cache.unavailable": {
|
|
395
|
+
cls: "F",
|
|
396
|
+
note: "k8s 车道按工作区空间的构建缓存卷(`WORKSPACE_CACHE=volume`,`plugins/remote-env-k8s.ts` 连沙箱那一步):这条 run 拿不到它空间的缓存卷 —— 卷建不成(RBAC 少动词 / API 拒 / 网络错,`reason=claim_failed`)、卷在快照时限内没绑定(集群没有缺省 StorageClass / 供给器不在,`reason=claim_unbound`)、卷绑上了而挂着它的 pod 起不来(挂载失败 / 卷所在节点没了,`reason=claim_unmountable`)—— 后两种把等它的那只 pod 删掉,换一只不挂卷的 —— 、或本副本读不出会话住客没有空间键(`reason=incarnation_unknown`)⇒ run **照常起**:不挂卷、不注入工具缓存 env,工具按镜像自己的缓存目录工作(每轮重下依赖)。放行的最坏后果 = 这一轮构建慢(缓存定义上可再生),不是门、不是凭据、不碰工作区与快照;反方向(卷拿不到就拒这一轮)会让一个缓存把整条 run 打掉。同拍一行运维日志 `workspace_cache_unavailable`(`space` 前缀 / `reason` / `error`)。计数非零 = 这台部署开了缓存卷却拿不到,运维去看 StorageClass / Role / 配额。",
|
|
397
|
+
},
|
|
398
|
+
"server.workspace-cache.reclaim-failed": {
|
|
399
|
+
cls: "F",
|
|
400
|
+
note: "k8s 车道按工作区空间的构建缓存卷的**回收**(`plugins/remote-env-k8s.ts` `createSpaceReclaimer`;两条腿同一只回收座:会话删除协调器 `boot/session-faces.ts` `purgeSession` 与托管留存 sweep `boot/retention-lane.ts` 删掉会话树之后):按标签 `sema.space=<空间摘要>` 删卷的请求失败(Role 少 `deletecollection` / API 拒 / 网络,`reason=delete_failed`)、回收座这次调用的绝对截止(= 快照时限)先到(请求没发或在途被切,`reason=budget`),或在线腿删除前读不出被删会话的住客(`reason=occupant_unreadable`;化身缺席的存量行 = 没有空间,不计)⇒ 卷留着(住客读不出时该空间的快照对象也没回收,归桶的生命周期规则),会话照删(不挡删除)。放行的最坏后果 = 节点盘上多留一只没人再用的卷(存储泄漏,不碰任何别的空间、不是门不是凭据);反方向(删卷失败就拒删会话)会让一个缓存挡住删除权。同拍一行 `workspace_cache_reclaim_failed`(回收座的两形:`space` 前缀 / `label` / `reason` / `error`;住客读不出那一形:`sessionId` / `reason` / `error`)。计数非零 = 有卷没回收掉,运维按行里的标签手清,并核 Role。",
|
|
401
|
+
},
|
|
402
|
+
"server.workspace-space.reclaim-failed": {
|
|
403
|
+
cls: "F",
|
|
404
|
+
note: "k8s 车道工作区空间结束时对**快照对象**的回收(`plugins/remote-env-k8s.ts` `createSpaceReclaimer` 的对象部分;与上一条同一只回收座、两条腿:会话删除协调器与托管留存 sweep):按空间的 `<前缀>/<化身>/space/` 分区(快照 + `latest`)和该会话停驻车道里名字带被结束住客归属记号的 `<前缀>/<会话 id>/*.tar.gz` 分别 LIST、逐个预签 DELETE;LIST 失败、DELETE 失败(HTTP 非 2xx / 非 404、网络)LIST 超过 1000 个对象被截断,或回收座一次调用的绝对截止(= 快照时限;卷回收也在内)到点〔切断在途请求、停掉余下的;这次调用里还没轮到的空间零请求、各记一次;没删的归生命周期规则〕,各记一次(detail `lane=space|park stage=list|delete|budget`;会话删除口把回收座脱离应答路径,座若抛了——契约禁止——记 `stage=seat_threw`)⇒ 这些对象留在桶里,会话照删(不挡删除)。放行的最坏后果 = 一份已无人能读的工作区快照留在桶里(会话已删,经 API 不可达;内容是用户工作区,所以不是「只占盘」—— 留到桶的生命周期规则把它过期掉为止);不碰任何别的空间、不是门不是凭据;反方向(清不掉对象就拒删会话)会让一个对象存储抖动挡住用户的删除权。故 F 类,但必须留痕:静默吞掉之后「这个会话删了、它的工作区内容还在不在桶里」在遥测里没有任何痕迹。同拍一行 `workspace_space_reclaim_failed`(`space` 前缀 / `sessionId` / `lane` / `stage` / `error`)。计数非零 = 有对象没回收掉,运维按行里的空间前缀 / 会话 id 去桶里手清,并核对象存储的可达性与 DELETE 权限。回收与同一空间的尚在途的 run 末提交不是互斥的:会话删除时没有活 run(409 挡),但上一条 run 的提交若恰在删除之后才落对象,这批对象不在本次回收射程内(同样归桶的生命周期规则)。停驻分区按会话 id 分区,所以只删名字带被结束住客归属记号的对象(不读任何钟)—— 会话 id 删后被别人重新登记,新住客停驻出的快照带它自己的记号、不碰;不带记号的旧形与 `none` 留给桶的生命周期规则。",
|
|
405
|
+
},
|
|
406
|
+
"server.sandbox-egress.policy-gap": {
|
|
407
|
+
cls: "P-DEBT",
|
|
408
|
+
note: "k8s 车道沙箱出网的起服自检(`plugins/remote-env-k8s.ts` `checkSandboxEgressPolicy` 读节点表与沙箱 ns 的 NetworkPolicy,判法 `sandbox-egress-policy.ts` `sandboxEgressGaps`;起服一次、不挡起服)读出一个缺口 —— 某节点的 InternalIP / ExternalIP 落在一条放行 ipBlock 内(`kind=node_address_open`)、没有策略以 Egress 选中沙箱 pod(`kind=policy_absent`)、pod 保留 IPv6 而策略层担保不了 v6(`kind=ipv6_enabled`)、节点表或策略表读不到(`kind=unreadable what=nodes|networkpolicies`)⇒ 车道**照常起**,每个缺口一行 `sandbox_egress_policy_gap`(带后果句与去哪改)。归 P 类:出网策略是保护面,缺口意味着沙箱里的代码可能够到节点上的服务;归 DEBT 的理由:修法都在集群配置里(节点地址点名、kubelet 放行 v6 sysctl、CNI 的 v6 执行、RBAC),本服务改不了,而拒起车道会让缺省单节点装法(恒有 `ipv6_enabled`)升级即停摆沙箱执行 —— 车道自己的隔离(VM 边界、零 SA token)仍在。放行的最坏后果 = 读出缺口的那一面照旧可达,直到运维按行里的后果句改配置。计数非零 = 这台部署的沙箱出网面有读得出的缺口。读不出的面(宿主 DNAT 发布端口、「pod 所在节点恒放行」的实现差异、CNI 根本不执行策略)不在本 tag 的射程里。",
|
|
409
|
+
},
|
|
382
410
|
"server.fleet.announce-reply-unreadable": {
|
|
383
411
|
cls: "P-DEBT",
|
|
384
412
|
note: "7.121.0 修复验证轮(`fleet-client.ts` 的公告环,fleet 成员每一拍心跳 2xx 答复;detail = `why=<body|not-an-object|invalid-capabilities> leaseState=<此刻的租约态>`):答复不是能力读数(体读不出 / 不是对象 / `capabilities` 键在场而形坏 —— settings-schema 9.0.0 `readCapabilityReading` 的 `unreadable`,外加本仓的 `body`)⇒ 当作没有这一拍答复,租约的状态与钟原样。**一律**计数(不论租约生效与否):租约还没生效(`leaseState=none`)时这只成员**一直不受围栏**,而修前这一形零计数(中心每拍答 `<html>` ⇒ 成员恒 none、零痕迹);租约已生效时计数说明中心的答复在坏、围栏靠的是上一次读数。归 P 类:围栏轴;归 DEBT:本进程判不出中心为什么答坏体,收口条件 = 中心契约 / 监控(中心侧对心跳答复形的执法)落地。每段连拍另有一行 warn `fleet_announce_reply_unreadable`(带 `why`)。",
|
|
@@ -62,7 +62,6 @@ export interface MetricsSummary {
|
|
|
62
62
|
};
|
|
63
63
|
cascade: Record<string, number>;
|
|
64
64
|
verifications: Record<string, number>;
|
|
65
|
-
councilRuns: Record<string, number>;
|
|
66
65
|
toolErrors: Record<string, number>;
|
|
67
66
|
/** S-451(additive,7.87.0):窗内 HTTP **失败**请求数,按状态码**类**聚合 —— 键只有 `"4xx"` / `"5xx"`
|
|
68
67
|
* 两种,2xx/3xx 一格不进。⚠️ `"4xx"` 里**含 `499`**(本仓给「客户端在响应结束前断连」铸的标签,
|
|
@@ -186,7 +186,6 @@ export class Metrics {
|
|
|
186
186
|
})(cby("plan_cache_recurrence_total", "hit")),
|
|
187
187
|
cascade: cby("cascade_total", "outcome"),
|
|
188
188
|
verifications: cby("verifications_total", "verdict"),
|
|
189
|
-
councilRuns: cby("council_runs_total", "mode"),
|
|
190
189
|
toolErrors: Object.fromEntries([...(this.counters.get("tool_calls_total")?.series.values() ?? [])]
|
|
191
190
|
.filter((s) => s.labels.ok === "false")
|
|
192
191
|
.map((s) => [s.labels.name ?? "?", s.value])),
|
|
@@ -221,8 +220,6 @@ export function createMetrics() {
|
|
|
221
220
|
m.counter("task_tokens_total", "Total model tokens consumed by tasks");
|
|
222
221
|
m.histogram("task_duration_seconds", "Async run wall-clock duration");
|
|
223
222
|
m.gauge("runs_active", "Async runs currently executing");
|
|
224
|
-
m.counter("council_runs_total", "Code-review council runs (L1+L3)");
|
|
225
|
-
m.histogram("council_tokens", "Total model tokens per council review (lenses + arbiter)");
|
|
226
223
|
m.histogram("task_cache_hit_rate", "Prefix-cache hit rate per task (core-computed stats.cacheHitRate, 0..1)", [
|
|
227
224
|
0.05, 0.1, 0.25, 0.5, 0.75, 0.9, 0.95, 1,
|
|
228
225
|
]);
|
|
@@ -283,7 +280,7 @@ export function createMetrics() {
|
|
|
283
280
|
m.counter("memory_dedup_folded_total", "Memory writes folded into an existing near-duplicate row (LOW)");
|
|
284
281
|
m.counter("memory_dedup_probe_failed_total", "Memory dedup KNN probes that failed and fell through to INSERT (LOW)");
|
|
285
282
|
m.counter("redactions_applied_total", "redactSecrets rewrites (S24), by pattern label and `arm` (S-88: full vs prefix-fragment arm — which RULE fired, NOT proof the text was upstream-truncated)");
|
|
286
|
-
m.counter("
|
|
283
|
+
m.counter("session_cache_stale_hit_total", "Warm session-cache hits dropped because the store had moved past the cached leaf (written by another replica, or gone); the session was re-woken from the store");
|
|
287
284
|
m.counter("breaker_writethrough_failed_total", "Circuit-breaker cross-replica write-through failures (LOW), by backend");
|
|
288
285
|
m.counter("web_search_bad_payload_total", "Web-search provider responses whose results field was not an array (LOW), by provider");
|
|
289
286
|
m.counter("auto_mode_classifier_deny_cause_total", "Auto-mode gate denials where the classifier did NOT rule, by the FORM of the deny (core CLASSIFIER_DENY_CAUSES on GateDisposition.cause: 'unavailable' = the classifier could not run at all (threw/rejected/ran past the cap — retryable), 'parse_error' = it ran but answered outside its verdict contract (blocked for safety); 'other' = this build cannot name the word). 🔴 BREAKING in server 7.72.0: this counter was named auto_mode_classifier_unavailable_total through 7.71.0 and is RENAMED with NO alias (a counter that also counts parse_error is not an 'unavailable' counter); its label vocabulary was 'error'/'timeout' (WHY it was unavailable) — those two collapsed into 'unavailable' (the WHY now rides the deny sentence and the auto_mode.classified trace frame), and 'parse_error' is a bucket the old counter could not see, so by-cause series do NOT splice across the upgrade. Distinct from permission_denied_total{deniedBy=\"classifier\"}, which also counts genuine safety blocks (the classifier's own <block> ruling carries NO cause) — a spike here means the classifier itself is not working (gateway/credential fault, too slow, or answering off-contract), not that the model kept asking for dangerous things");
|
|
@@ -6,6 +6,7 @@ import { isUnsuccessfulRunStatus } from "../plugins/store-contracts.js";
|
|
|
6
6
|
import { sealResultForExit } from "../terminal.js";
|
|
7
7
|
import { errorText } from "./err-text.js";
|
|
8
8
|
import { recordFailOpen } from "./fail-open.js";
|
|
9
|
+
import { toolEndMediaAsDescriptors } from "../trace/tool-output-media.js";
|
|
9
10
|
const MESSAGE_CAP = 1024;
|
|
10
11
|
export function runTerminalLogLevel(status, errorCode) {
|
|
11
12
|
if (!isUnsuccessfulRunStatus(status))
|
|
@@ -172,10 +173,74 @@ const STRANDED_ANSWER_TREATMENT = {
|
|
|
172
173
|
toolCallId: "provider-join-key",
|
|
173
174
|
};
|
|
174
175
|
const TERMINAL_FAILURE_DETAIL_TREATMENT = {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
176
|
+
provider_rejected: {
|
|
177
|
+
kind: "verbatim",
|
|
178
|
+
status: "verbatim",
|
|
179
|
+
code: "provider-echo",
|
|
180
|
+
providerCondition: "verbatim",
|
|
181
|
+
providerConditionSource: "verbatim",
|
|
182
|
+
providerResetAtMs: "verbatim",
|
|
183
|
+
route: "verbatim",
|
|
184
|
+
},
|
|
185
|
+
coded: { kind: "verbatim", detail: "free-text-tree" },
|
|
186
|
+
model_output_invalid: { kind: "verbatim", cause: "verbatim", outputLimit: "verbatim" },
|
|
178
187
|
};
|
|
188
|
+
const TERMINAL_DETAIL_WALK_DEPTH = 32;
|
|
189
|
+
const TERMINAL_DETAIL_TOO_DEEP = "[omitted: nested deeper than 32 levels]";
|
|
190
|
+
function redactStringLeaves(node, depth = 0) {
|
|
191
|
+
if (typeof node === "string")
|
|
192
|
+
return redactErrorMessage(node) ?? node;
|
|
193
|
+
if (node === null || typeof node !== "object")
|
|
194
|
+
return node;
|
|
195
|
+
if (depth > TERMINAL_DETAIL_WALK_DEPTH)
|
|
196
|
+
return TERMINAL_DETAIL_TOO_DEEP;
|
|
197
|
+
if (Array.isArray(node)) {
|
|
198
|
+
const next = node.map((x) => redactStringLeaves(x, depth + 1));
|
|
199
|
+
return next.every((x, i) => x === node[i]) ? node : next;
|
|
200
|
+
}
|
|
201
|
+
let out;
|
|
202
|
+
for (const [k, v] of Object.entries(node)) {
|
|
203
|
+
const nv = redactStringLeaves(v, depth + 1);
|
|
204
|
+
if (nv !== v)
|
|
205
|
+
(out ??= { ...node })[k] = nv;
|
|
206
|
+
}
|
|
207
|
+
return out ?? node;
|
|
208
|
+
}
|
|
209
|
+
function shapeTerminalFailureDetail(detail) {
|
|
210
|
+
if (detail === null || typeof detail !== "object" || Array.isArray(detail))
|
|
211
|
+
return detail;
|
|
212
|
+
const d = detail;
|
|
213
|
+
const kind = d.kind;
|
|
214
|
+
const table = typeof kind === "string" && Object.hasOwn(TERMINAL_FAILURE_DETAIL_TREATMENT, kind) ? TERMINAL_FAILURE_DETAIL_TREATMENT[kind] : undefined;
|
|
215
|
+
if (table === undefined)
|
|
216
|
+
return redactStringLeaves(d);
|
|
217
|
+
let out;
|
|
218
|
+
for (const [key, treatment] of Object.entries(table)) {
|
|
219
|
+
const v = d[key];
|
|
220
|
+
if (v === undefined)
|
|
221
|
+
continue;
|
|
222
|
+
switch (treatment) {
|
|
223
|
+
case "verbatim":
|
|
224
|
+
case "provider-join-key":
|
|
225
|
+
break;
|
|
226
|
+
case "provider-echo":
|
|
227
|
+
if (!admitProviderEcho(v, `terminal.detail.${key}`))
|
|
228
|
+
delete (out ??= { ...d })[key];
|
|
229
|
+
break;
|
|
230
|
+
case "free-text-tree": {
|
|
231
|
+
const nv = redactStringLeaves(v);
|
|
232
|
+
if (nv !== v)
|
|
233
|
+
(out ??= { ...d })[key] = nv;
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
default: {
|
|
237
|
+
const unhandled = treatment;
|
|
238
|
+
throw new Error(`unhandled failure-detail treatment: ${String(unhandled)}`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return out ?? detail;
|
|
243
|
+
}
|
|
179
244
|
const TERMINAL_BLOCKED_DETAIL_TREATMENT = {
|
|
180
245
|
kind: "verbatim",
|
|
181
246
|
cause: "verbatim",
|
|
@@ -279,7 +344,7 @@ export function redactTerminalResult(result) {
|
|
|
279
344
|
nt = { ...base, nestedPause: { ...np, gate: g.gate } };
|
|
280
345
|
const cur = nt ?? base;
|
|
281
346
|
const detail = cur.detail;
|
|
282
|
-
const shaped =
|
|
347
|
+
const shaped = shapeTerminalFailureDetail(detail);
|
|
283
348
|
if (shaped !== detail)
|
|
284
349
|
nt = { ...cur, detail: shaped };
|
|
285
350
|
}
|
|
@@ -387,6 +452,8 @@ export function redactLedgerEventData(type, data) {
|
|
|
387
452
|
}
|
|
388
453
|
if (type === "turn_end")
|
|
389
454
|
return shapeEchoMembers(data, TURN_END_ECHO_TREATMENT, "turn_end");
|
|
455
|
+
if (type === "tool_end")
|
|
456
|
+
return toolEndMediaAsDescriptors(data);
|
|
390
457
|
if (type === "task_notification") {
|
|
391
458
|
const af = data.apiFailure;
|
|
392
459
|
if (af === undefined)
|
|
@@ -609,6 +676,7 @@ const CHECKPOINT_GATE_TREATMENT = {
|
|
|
609
676
|
safetyAxis: "verbatim",
|
|
610
677
|
realApproval: "verbatim",
|
|
611
678
|
resumeAfterMs: "verbatim",
|
|
679
|
+
approvalCard: "verbatim",
|
|
612
680
|
};
|
|
613
681
|
export function redactCheckpointGate(gate) {
|
|
614
682
|
if (gate === null || typeof gate !== "object" || Array.isArray(gate))
|
|
@@ -14,9 +14,10 @@ export declare function isPersistedRuleTool(name: string): boolean;
|
|
|
14
14
|
* 唯一拼写)/ `wildcard`([ref] 尾 space-star,单命令体上与 prefix **同一谓词**,建议面自此铸它)/
|
|
15
15
|
* `subpath`(Read 目录形,永不容纳任何命令)/ `path`(core 7.9.0 [ref]:路径族 deny/ask/allow 的模式文法
|
|
16
16
|
* —— `//abs`、`~/`、`/root-relative`、cwd 相对,段内 `*`、跨段 `**`)/ `name` / `name_prefix`(core 7.43.0 #1318:`Skill` 的名字文法 ——
|
|
17
|
-
* `Skill(<名>)` 精确、`Skill(<前缀>:*)` 名字前缀、无词界;技能卡的建议行 `match: "name"`)
|
|
17
|
+
* `Skill(<名>)` 精确、`Skill(<前缀>:*)` 名字前缀、无词界;技能卡的建议行 `match: "name"`)/ `host` / `subdomain`(core 7.49.0 #1365:
|
|
18
|
+
* `WebFetch(domain:<host>)` 精确主机、`WebFetch(domain:*.<域>)` 域下每个主机 —— 只有 allow 形)。
|
|
18
19
|
*/
|
|
19
|
-
export declare const PERSISTED_RULE_MATCHES: readonly ["exact", "prefix", "wildcard", "subpath", "path", "name", "name_prefix"];
|
|
20
|
+
export declare const PERSISTED_RULE_MATCHES: readonly ["exact", "prefix", "wildcard", "subpath", "path", "name", "name_prefix", "host", "subdomain"];
|
|
20
21
|
/**
|
|
21
22
|
* S-511 —— `RuleBehavior` 每一员在**无同意仪式的直接写口**(`POST /v1/rules`)上的逐员表态。
|
|
22
23
|
*
|
|
@@ -2,7 +2,7 @@ import { ruleToolGrammarOf } from "@sema-agent/core";
|
|
|
2
2
|
export function isPersistedRuleTool(name) {
|
|
3
3
|
return ruleToolGrammarOf(name) !== undefined;
|
|
4
4
|
}
|
|
5
|
-
export const PERSISTED_RULE_MATCHES = ["exact", "prefix", "wildcard", "subpath", "path", "name", "name_prefix"];
|
|
5
|
+
export const PERSISTED_RULE_MATCHES = ["exact", "prefix", "wildcard", "subpath", "path", "name", "name_prefix", "host", "subdomain"];
|
|
6
6
|
const MATCHES_PIN = true;
|
|
7
7
|
void MATCHES_PIN;
|
|
8
8
|
export const DIRECT_RULE_WRITE_ADMITS = {
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
* does an agent's traffic actually re-pose near-duplicate objectives per tenant? (arXiv 2602.18922:
|
|
9
9
|
* heterogeneous queries can hit 0–12%.) We hold the real multi-tenant traffic, so this is ours to count.
|
|
10
10
|
*
|
|
11
|
-
* **The token criterion is
|
|
12
|
-
*
|
|
11
|
+
* **The token criterion is core `strategy-store`'s (`compileStrategyQuery`) as last shipped in core 7.48.0** — core 7.49.0
|
|
12
|
+
* retired the strategy store with no replacement, so there is no core counterpart left to stay in lockstep with: from
|
|
13
|
+
* that release on this criterion is the probe's own definition, frozen at that form. Note the
|
|
13
14
|
* **asymmetry**: a stored problem is matched on its full `tokens()` set, the query on its
|
|
14
15
|
* `significant()` set. A hit = `significant(new) ⊆ tokens(historical)` OR (5.49 legacy acceptance
|
|
15
16
|
* arm) the non-CJK subset `qAlnum` is non-empty and fully contained (`qAlnum ⊆ tokens(historical)`).
|
|
@@ -538,7 +538,7 @@ export declare const APPROVAL_BATCH_TABLE = "approval_batch";
|
|
|
538
538
|
* 64 字符(`approval-ask-machine.ts` deterministicId),按构造不可能更长。
|
|
539
539
|
* · `task_id` → 64:入口 `UUIDV7_RE`(`security.ts:134`)只放行 36 字符的规范 uuidv7;与兄弟列
|
|
540
540
|
* `task_run.task_id VARCHAR(64)` 同宽(此前 255 是本家族独有的偏离,无依据)。
|
|
541
|
-
* · `session_id` → 64
|
|
541
|
+
* · `session_id` → 64:提交入口只收 canonical uuid(36 字符;7.125.x 及更早硬拒 >64),列宽仍容存量,
|
|
542
542
|
* 与 `session_meta`/`task_run` 同宽。
|
|
543
543
|
* · `owner` → 190:`assertPrincipalShape` 的 `PRINCIPAL_MAX_LENGTH = 190`(`security.ts` 的同名导出常量,
|
|
544
544
|
* 刻意不钉行号 —— 旧注写的 `security.ts:350` 已随该文件编辑漂走)硬拒更长者;
|