@sema-agent/server 7.131.0 → 7.132.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 +309 -0
- package/README.md +5 -1
- package/README.zh-CN.md +3 -1
- package/USAGE.md +163 -54
- package/dist/approval-card.d.ts +3 -1
- package/dist/approval-card.js +2 -3
- package/dist/audit.d.ts +7 -10
- package/dist/auth-bridge.d.ts +4 -0
- package/dist/auth-bridge.js +10 -11
- package/dist/boot/deployment-mods.d.ts +31 -0
- package/dist/boot/deployment-mods.js +26 -0
- package/dist/boot/execution-env.d.ts +1 -1
- package/dist/boot/execution-env.js +19 -6
- package/dist/boot/memory-boundary.d.ts +2 -2
- package/dist/boot/read-deny-anchor-audit.d.ts +17 -0
- package/dist/boot/read-deny-anchor-audit.js +36 -0
- package/dist/boot/resolve-spec.d.ts +1 -5
- package/dist/boot/resolve-spec.js +19 -47
- package/dist/boot/runner-deps.d.ts +19 -8
- package/dist/boot/runner-deps.js +14 -2
- package/dist/boot/session-faces.d.ts +1 -7
- package/dist/boot/stage-03-store-backend.d.ts +1 -1
- package/dist/boot/stage-03-store-backend.js +2 -2
- package/dist/boot/stage-04-stores.d.ts +1 -1
- package/dist/boot/stage-05-execution-env.d.ts +4 -4
- package/dist/boot/stage-05-execution-env.js +7 -10
- package/dist/boot/stage-06-runners.d.ts +2 -2
- package/dist/boot/stage-06-runners.js +5 -4
- package/dist/boot/stage-07-capability-layer.d.ts +2 -2
- package/dist/boot/stage-07-capability-layer.js +3 -3
- package/dist/boot/stage-08-reapers.d.ts +2 -2
- package/dist/boot/stage-09-leader.d.ts +3 -9
- package/dist/boot/stage-10-http-server.d.ts +3 -9
- package/dist/boot/stage-10-http-server.js +6 -7
- package/dist/boot/stores.d.ts +1 -1
- package/dist/boot/stores.js +5 -6
- package/dist/boot/web-admin.d.ts +0 -3
- package/dist/boot/web-admin.js +35 -35
- package/dist/brain.js +17 -22
- package/dist/budget.js +5 -4
- package/dist/caller-text-echo.d.ts +20 -0
- package/dist/caller-text-echo.js +24 -0
- package/dist/capabilities/brand-identity.d.ts +26 -0
- package/dist/capabilities/brand-identity.js +27 -0
- package/dist/capabilities/center-plugins.js +1 -1
- package/dist/capabilities/center-prompts.d.ts +32 -59
- package/dist/capabilities/center-prompts.js +18 -32
- package/dist/capabilities/engine-capabilities.js +2 -1
- package/dist/capabilities/hands-lane.d.ts +9 -6
- package/dist/capabilities/hands-lane.js +1 -1
- package/dist/capabilities/mcp-probe.d.ts +14 -1
- package/dist/capabilities/mcp-probe.js +22 -133
- package/dist/capabilities/scenarios.d.ts +34 -40
- package/dist/capabilities/scenarios.js +16 -33
- package/dist/capabilities/skills.d.ts +19 -4
- package/dist/capabilities/skills.js +30 -10
- package/dist/config-catalog.js +6 -6
- package/dist/config-lkg.d.ts +9 -9
- package/dist/config-lkg.js +20 -4
- package/dist/config-provider.d.ts +3 -1
- package/dist/config-provider.js +12 -4
- package/dist/config-types.d.ts +7 -9
- package/dist/config.js +17 -4
- package/dist/device-ws-protocol.d.ts +1 -1
- package/dist/device-ws-protocol.js +1 -0
- package/dist/env-name-allowlist-knobs.d.ts +12 -2
- package/dist/env-name-allowlist-knobs.js +5 -4
- package/dist/exec-bounds.d.ts +15 -3
- package/dist/exec-bounds.js +4 -0
- package/dist/execution-lane-caps.d.ts +9 -2
- package/dist/execution-lane-caps.js +11 -0
- package/dist/hooks/classic-stations.d.ts +86 -0
- package/dist/hooks/classic-stations.js +27 -0
- package/dist/hooks/hook-llm.d.ts +8 -5
- package/dist/hooks/hook-llm.js +78 -35
- package/dist/hooks/hook-runner.d.ts +232 -80
- package/dist/hooks/hook-runner.js +218 -312
- package/dist/http/admission.d.ts +8 -2
- package/dist/http/admission.js +101 -57
- package/dist/http/approval-sweeps.js +57 -16
- package/dist/http/checkpoint-ctx.d.ts +25 -8
- package/dist/http/checkpoint-ctx.js +11 -7
- package/dist/http/claimed-run.d.ts +13 -0
- package/dist/http/claimed-run.js +15 -0
- package/dist/http/device-placement.js +5 -10
- package/dist/http/dispatch.d.ts +0 -4
- package/dist/http/dispatch.js +5 -9
- package/dist/http/durable-run-leg.d.ts +2 -1
- package/dist/http/durable-run-leg.js +5 -3
- package/dist/http/health-self-report.d.ts +7 -5
- package/dist/http/health-self-report.js +4 -18
- package/dist/http/principal-gate.d.ts +23 -6
- package/dist/http/principal-gate.js +24 -5
- package/dist/http/refusal-body.d.ts +21 -0
- package/dist/http/refusal-body.js +4 -0
- package/dist/http/request-guards.d.ts +27 -0
- package/dist/http/request-guards.js +24 -3
- package/dist/http/resume-legs.d.ts +25 -0
- package/dist/http/resume-legs.js +43 -22
- package/dist/http/routes/capabilities.js +1 -1
- package/dist/http/routes/diagnostics.js +1 -1
- package/dist/http/routes/rules.js +2 -2
- package/dist/http/routes/runs.js +7 -7
- package/dist/http/routes/session-sync.js +4 -2
- package/dist/http/routes/sessions.js +1 -1
- package/dist/http/routes/shared-memory.js +2 -13
- package/dist/http/routes/side-query.js +2 -3
- package/dist/http/routes/tasks.js +19 -9
- package/dist/http/send.d.ts +9 -7
- package/dist/http/send.js +7 -2
- package/dist/http/server.d.ts +21 -11
- package/dist/http/server.js +28 -2
- package/dist/http/submit-ctx.d.ts +25 -0
- package/dist/http/submit-ctx.js +39 -0
- package/dist/http/wire-types.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lane-home-probe.d.ts +43 -0
- package/dist/lane-home-probe.js +35 -0
- package/dist/limit-refusal.d.ts +47 -0
- package/dist/limit-refusal.js +12 -0
- package/dist/main.js +1 -1
- package/dist/mcp-assertion-header.d.ts +1 -9
- package/dist/mcp-assertion-header.js +0 -6
- package/dist/mcp-tool-faces.d.ts +5 -0
- package/dist/mcp-tool-faces.js +5 -1
- package/dist/memory-scope.d.ts +1 -1
- package/dist/model-provider.d.ts +39 -12
- package/dist/model-provider.js +19 -2
- package/dist/model-route-endpoint.d.ts +1 -1
- package/dist/model-route-endpoint.js +5 -5
- package/dist/observability/cost-taxonomy.d.ts +7 -7
- package/dist/observability/fail-open.d.ts +42 -6
- package/dist/observability/fail-open.js +42 -6
- package/dist/observability/metrics.js +3 -1
- package/dist/observability/prompt-manifest.d.ts +47 -82
- package/dist/observability/prompt-manifest.js +119 -17
- package/dist/observability/run-terminal.js +14 -6
- package/dist/observability/secret-env-scrub.d.ts +13 -1
- package/dist/observability/secret-env-scrub.js +13 -1
- package/dist/observability/tool-trace.d.ts +16 -21
- package/dist/observability/tool-trace.js +51 -42
- package/dist/per-task-image.d.ts +7 -1
- package/dist/per-task-image.js +3 -3
- package/dist/plain-string-record.d.ts +25 -0
- package/dist/plain-string-record.js +32 -0
- package/dist/plugins/blob-backend.d.ts +68 -13
- package/dist/plugins/blob-backend.js +53 -10
- package/dist/plugins/checkpoint-store-sql.d.ts +14 -4
- package/dist/plugins/checkpoint-store-sql.js +39 -26
- package/dist/plugins/k8s-bg-scripts.d.ts +11 -0
- package/dist/plugins/k8s-bg-scripts.js +22 -0
- package/dist/plugins/local-checkpoint-store.js +5 -2
- package/dist/plugins/local-session-store.js +1 -1
- package/dist/plugins/one-time-migrations.d.ts +137 -90
- package/dist/plugins/one-time-migrations.js +356 -207
- package/dist/plugins/permission-rule-store-sql.d.ts +13 -7
- package/dist/plugins/permission-rule-store-sql.js +4 -18
- package/dist/plugins/pg-session-storage.d.ts +4 -5
- package/dist/plugins/pg-session-storage.js +7 -17
- package/dist/plugins/remote-env-adb.d.ts +6 -0
- package/dist/plugins/remote-env-adb.js +9 -4
- package/dist/plugins/remote-env-device.js +3 -0
- package/dist/plugins/remote-env-e2b.d.ts +1 -1
- package/dist/plugins/remote-env-e2b.js +21 -9
- package/dist/plugins/remote-env-host.d.ts +9 -9
- package/dist/plugins/remote-env-host.js +10 -32
- package/dist/plugins/remote-env-k8s.d.ts +95 -26
- package/dist/plugins/remote-env-k8s.js +265 -90
- package/dist/plugins/remote-env-local-docker.d.ts +20 -1
- package/dist/plugins/remote-env-local-docker.js +77 -9
- package/dist/plugins/remote-env-ssh.d.ts +15 -0
- package/dist/plugins/remote-env-ssh.js +109 -3
- package/dist/plugins/remote-shell.d.ts +0 -1
- package/dist/plugins/remote-shell.js +1 -2
- package/dist/plugins/retention-store-sql.js +6 -2
- package/dist/plugins/schema-consistency.d.ts +54 -0
- package/dist/plugins/schema-consistency.js +52 -0
- package/dist/plugins/session-epoch-anchor.d.ts +13 -0
- package/dist/plugins/session-epoch-anchor.js +23 -0
- package/dist/plugins/shared-memory-store-sql.d.ts +9 -3
- package/dist/plugins/shared-memory-store-sql.js +5 -16
- package/dist/plugins/sql-driver.d.ts +141 -0
- package/dist/plugins/sql-driver.js +115 -1
- package/dist/plugins/sql-errors.d.ts +41 -0
- package/dist/plugins/sql-errors.js +36 -0
- package/dist/plugins/store-backend.js +2 -1
- package/dist/plugins/tidb-session-storage.d.ts +7 -11
- package/dist/plugins/tidb-session-storage.js +6 -16
- package/dist/plugins/tidb-session-store.js +1 -1
- package/dist/prompts-domain-validate.d.ts +17 -61
- package/dist/prompts-domain-validate.js +9 -119
- package/dist/request-key-closure.d.ts +2 -2
- package/dist/request-key-closure.js +2 -4
- package/dist/rule-entry-list.d.ts +12 -9
- package/dist/rule-entry-list.js +37 -21
- package/dist/run-local.js +19 -19
- package/dist/runs.d.ts +6 -0
- package/dist/runs.js +16 -0
- package/dist/server-secret-env.d.ts +44 -18
- package/dist/server-secret-env.js +49 -8
- package/dist/session-incarnation.d.ts +15 -5
- package/dist/session-incarnation.js +16 -9
- package/dist/session-titler.js +12 -2
- package/dist/spec-fields.d.ts +28 -16
- package/dist/spec-fields.js +46 -53
- package/dist/sql-engine-posture.d.ts +29 -4
- package/dist/sql-engine-posture.js +36 -1
- package/dist/stored-request-tool-axes-m19.d.ts +19 -4
- package/dist/stored-request-tool-axes-m19.js +30 -2
- package/dist/task-a2a.d.ts +9 -1
- package/dist/task-a2a.js +73 -47
- package/dist/task-mcp.d.ts +46 -58
- package/dist/task-mcp.js +99 -65
- package/dist/task-settings.d.ts +7 -21
- package/dist/task-settings.js +7 -36
- package/dist/text-bidi.d.ts +3 -46
- package/dist/text-bidi.js +3 -3
- package/dist/tool-approval.d.ts +1 -1
- package/dist/trace/core-keyset-guard.d.ts +24 -4
- package/dist/trace/engine-notice-wire.d.ts +11 -3
- package/dist/trace/engine-notice-wire.js +8 -1
- package/dist/trace/ledger-events.d.ts +3 -1
- package/dist/trace/ledger-sink.js +4 -1
- package/dist/trace/model-segment.js +1 -1
- package/dist/trace/project.d.ts +19 -6
- package/dist/trace/project.js +57 -22
- package/dist/trace/wire-projection-faces.d.ts +79 -1
- package/dist/trace/wire-projection-faces.js +22 -0
- package/dist/web-admin-client/candidate-gate.d.ts +6 -6
- package/dist/web-admin-client/candidate-gate.js +3 -3
- package/dist/web-admin-client/http-client.js +0 -6
- package/dist/web-admin-client/read-warnings.d.ts +13 -0
- package/dist/web-admin-client/read-warnings.js +10 -0
- package/dist/web-admin-client/skills-mcp.d.ts +3 -0
- package/dist/web-admin-client/skills-mcp.js +9 -6
- package/dist/web-admin-client/types.d.ts +2 -3
- package/dist/workspace-cache.d.ts +35 -0
- package/dist/workspace-cache.js +36 -0
- package/dist/workspace-space.d.ts +3 -2
- package/dist/workspace-space.js +2 -0
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +8 -1
- package/package.json +4 -4
- package/scripts/drain-check-local.mjs +34 -1
- package/scripts/drain-check.mysql.sql +30 -2
- package/scripts/drain-check.pg.sql +29 -2
- package/dist/capabilities/memory-notice.d.ts +0 -138
- package/dist/capabilities/memory-notice.js +0 -64
- package/dist/capabilities/prompt.d.ts +0 -17
- package/dist/capabilities/prompt.js +0 -6
- package/dist/mcp-content-origin.d.ts +0 -34
- package/dist/mcp-content-origin.js +0 -10
- package/dist/tool-axis-words.d.ts +0 -27
- package/dist/tool-axis-words.js +0 -9
- package/dist/wire-name-bound.d.ts +0 -14
- package/dist/wire-name-bound.js +0 -13
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **帽的拒**(一张表条数太多 / 一段文字太长)在本仓受理口的一只写法:句子的头一句 + 机读位,一处铸。
|
|
3
|
+
*
|
|
4
|
+
* 律:请求体上任何一处撞了帽,拒体带同一组机读位 ——
|
|
5
|
+
* · `field` = 撞帽的那一处在请求体里的坐标(`skills[1].allowedTools`、`agents[0].denyTools[3]`、`settings.permissions.allow`);
|
|
6
|
+
* · `reason` = 帽的量纲,闭集两词:`over_cap`(条数:数组的条目数)/ `too_long`(字符数:一段文字的长度);
|
|
7
|
+
* · `count` = 送来的量(条数或字符数,量纲由 `reason` 定);
|
|
8
|
+
* · `cap` = 帽。
|
|
9
|
+
* 句子的头一句同一句:`<field> has <count> entries|characters — at most <cap> are accepted`;之后各面可以接自己的出路句(为什么拒而不截、怎么改)。
|
|
10
|
+
* 帽本身(数字)归各面的属主;本模块只管「撞了帽怎么说、怎么机读」。
|
|
11
|
+
*
|
|
12
|
+
* 量纲 → `reason` 是一张闭表({@link LIMIT_REASONS}):加一种量纲 ⇒ 这里加一行,`reason` 的词随之进闭集,读者穷举读。
|
|
13
|
+
*/
|
|
14
|
+
/** 量纲 → 机读 `reason` 词(闭集)。 */
|
|
15
|
+
export declare const LIMIT_REASONS: {
|
|
16
|
+
readonly entries: "over_cap";
|
|
17
|
+
readonly characters: "too_long";
|
|
18
|
+
};
|
|
19
|
+
/** 帽的量纲:条数 / 字符数(句子里就是这个词)。 */
|
|
20
|
+
export type LimitMeasure = keyof typeof LIMIT_REASONS;
|
|
21
|
+
/** 机读 `reason`:`over_cap`(条数)/ `too_long`(字符数)。 */
|
|
22
|
+
export type LimitReason = (typeof LIMIT_REASONS)[LimitMeasure];
|
|
23
|
+
/** 一处撞帽的机读位(原样进拒体:`refusalBody` 的 facts / `HttpError.extra`;型别名而不是接口 —— 要能直接当 `Record<string, unknown>` 用)。 */
|
|
24
|
+
export type LimitFacts = {
|
|
25
|
+
readonly field: string;
|
|
26
|
+
readonly reason: LimitReason;
|
|
27
|
+
readonly count: number;
|
|
28
|
+
readonly cap: number;
|
|
29
|
+
};
|
|
30
|
+
/** 一处撞帽的拒:句子 + 机读位。 */
|
|
31
|
+
export interface LimitRefusal {
|
|
32
|
+
readonly message: string;
|
|
33
|
+
readonly facts: LimitFacts;
|
|
34
|
+
}
|
|
35
|
+
/** 撞帽的头一句(全仓同一句;`field` 是句子里点名的那一处)。 */
|
|
36
|
+
export declare function describeLimit(field: string, measure: LimitMeasure, count: number, cap: number): string;
|
|
37
|
+
/** 机读位:`reason` 由量纲定。 */
|
|
38
|
+
export declare function limitFacts(field: string, measure: LimitMeasure, count: number, cap: number): LimitFacts;
|
|
39
|
+
/**
|
|
40
|
+
* 一处撞帽的拒:句子 = {@link describeLimit}(+ `tail`:该面的出路句,接在头一句之后),机读位 = {@link limitFacts}(`field` 同一个坐标)。
|
|
41
|
+
* `sentenceField` 只在该面的句子沿用另一种点名写法时给(子代定义的句子写作 `agents[0]: agent.name`,机读位仍是体内坐标 `agents[0].name`)。
|
|
42
|
+
*/
|
|
43
|
+
export declare function limitRefusal(field: string, measure: LimitMeasure, count: number, cap: number, opts?: {
|
|
44
|
+
readonly tail?: string;
|
|
45
|
+
readonly sentenceField?: string;
|
|
46
|
+
}): LimitRefusal;
|
|
47
|
+
//# sourceMappingURL=limit-refusal.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const LIMIT_REASONS = { entries: "over_cap", characters: "too_long" };
|
|
2
|
+
export function describeLimit(field, measure, count, cap) {
|
|
3
|
+
return `${field} has ${count} ${measure} — at most ${cap} are accepted`;
|
|
4
|
+
}
|
|
5
|
+
export function limitFacts(field, measure, count, cap) {
|
|
6
|
+
return { field, reason: LIMIT_REASONS[measure], count, cap };
|
|
7
|
+
}
|
|
8
|
+
export function limitRefusal(field, measure, count, cap, opts = {}) {
|
|
9
|
+
const head = describeLimit(opts.sentenceField ?? field, measure, count, cap);
|
|
10
|
+
return { message: opts.tail === undefined ? head : `${head}. ${opts.tail}`, facts: limitFacts(field, measure, count, cap) };
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=limit-refusal.js.map
|
package/dist/main.js
CHANGED
|
@@ -15,7 +15,7 @@ async function main() {
|
|
|
15
15
|
const s02 = await runStage02(s01);
|
|
16
16
|
const s03 = await runStage03(s02);
|
|
17
17
|
const s04 = await runStage04(s03);
|
|
18
|
-
const s05 = runStage05(s04);
|
|
18
|
+
const s05 = await runStage05(s04);
|
|
19
19
|
await settleHostLaneShell(s05.config, s05.logger);
|
|
20
20
|
const s06 = runStage06(s05);
|
|
21
21
|
const s07 = await runStage07(s06);
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* · **fresh 提交腿**:判出问题 ⇒ 同步 400(同设 `request.body_shape`;值不是字符串 `request.field_invalid`)。
|
|
16
16
|
* · **其余腿(耐久 resume 重放存量 body)**:**不拒、不丢 server** —— 存量 body 里这个键当时是被静默忽略的,server 当时是挂着的;
|
|
17
17
|
* 此刻把 server 摘掉,一条 park 在该 server 工具审批上的任务批准后会撞 `resume.tool_unavailable` 并重开检查点,而每次重试重放同一份 body ⇒ 永远卡住。
|
|
18
|
-
* 所以读器
|
|
18
|
+
* 所以读器(契约包的 `readMcpIdentityHeaders`,`normalizeServer` 的 http 传输读两个身份头用它)的处置是**降级到升级前的读法**:`principalHeader` 胜(照挂,与升级前逐字相同),`assertionHeader` 不生效;
|
|
19
19
|
* 不静默 —— 真挂上的这类条目由 {@link noteMcpAssertionHeaderIgnored} 说一行 warn(部署声明面没有这一格:配置不是被重放的存量任务,契约包解析期那一刀直接丢这一条)。
|
|
20
20
|
*
|
|
21
21
|
* ## 发送归引擎座(本版只承载,不发送)
|
|
@@ -56,14 +56,6 @@ export type McpIdentityHeadersIssue = "both_set" | "not_a_string";
|
|
|
56
56
|
* 两类同时成立时报 `both_set`(先名字后值)。stdio 传输不判(两键在 stdio 形上本就不存在,契约包同判)。
|
|
57
57
|
*/
|
|
58
58
|
export declare function mcpIdentityHeadersIssue(transport: Record<string, unknown>): McpIdentityHeadersIssue | undefined;
|
|
59
|
-
/**
|
|
60
|
-
* 读器的这一格(`normalizeServer` 的 http 传输读两个身份头):字符串才收;**`principalHeader` 胜**——它在场(不论值形)时 `assertionHeader` 不收。
|
|
61
|
-
* 于是 normalize 后的形**结构上不可能同带两键**(`mcpIdentityHeadersIssue` 的 `both_set` 在读器之后不存在),重放存量 body 的处置因此就是升级前的读法。
|
|
62
|
-
*/
|
|
63
|
-
export declare function readMcpIdentityHeaders(transport: Record<string, unknown>): {
|
|
64
|
-
principalHeader?: string;
|
|
65
|
-
assertionHeader?: string;
|
|
66
|
-
};
|
|
67
59
|
/** 同设的拒句 —— 对契约包解析期那一句**逐字**(`server` = 条目名,调用方负责清洗后传入)。 */
|
|
68
60
|
export declare function describeMcpIdentityHeadersConflict(server: string): string;
|
|
69
61
|
/** `assertionHeader` 值不是字符串的**原因句**(不带条目名与键路径:点名由请求面统一的拒形 `entryFieldRefusal` 负责;值的形状只说种类,不回显值本身:它是一个调用方写的头名位置,可能是任何东西)。 */
|
|
@@ -7,12 +7,6 @@ export function mcpIdentityHeadersIssue(transport) {
|
|
|
7
7
|
return "not_a_string";
|
|
8
8
|
return undefined;
|
|
9
9
|
}
|
|
10
|
-
export function readMcpIdentityHeaders(transport) {
|
|
11
|
-
return {
|
|
12
|
-
...(typeof transport.principalHeader === "string" ? { principalHeader: transport.principalHeader } : {}),
|
|
13
|
-
...(transport.principalHeader === undefined && typeof transport.assertionHeader === "string" ? { assertionHeader: transport.assertionHeader } : {}),
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
10
|
export function describeMcpIdentityHeadersConflict(server) {
|
|
17
11
|
return `mcp server "${server}" sets both principalHeader and assertionHeader — an http entry names ONE header for the identity it sends: keep principalHeader (the end-user principal) or assertionHeader (the connector assertion), not both`;
|
|
18
12
|
}
|
package/dist/mcp-tool-faces.d.ts
CHANGED
|
@@ -58,6 +58,11 @@ export type McpToolFacesRead = {
|
|
|
58
58
|
/**
|
|
59
59
|
* 从任一腿的原始条目里读出 `toolFaces` —— **三条腿共用的唯一判据点**。
|
|
60
60
|
* 缺席 ⇒ 合形无覆盖层;整只不是对象 / **任一只**工具的面判不出形 ⇒ `ok:false`(调用方整条 server 不收)。
|
|
61
|
+
*
|
|
62
|
+
* 🔴 工具名是 `__proto__` ⇒ 同样判不出形,**响亮拒**:按名存面的记录装不下它 —— JSON 的自有键 `"__proto__"` 写进记录那一步走的是原型的设置器,
|
|
63
|
+
* 键从结果里消失而判官答 `ok`,那条 server 照挂、收窄面叠层被无声丢掉。方向与本模块头注同(收窄声明在场就必须原样可用)。
|
|
64
|
+
* 只拒这一个名字:`constructor` / `toString` 等其余根原型成员名写进记录是普通自有键、不丢,引擎按名查面也取得到 —— 拒它们是给重放存量 body 的腿
|
|
65
|
+
* 新添一条「整条 server 不进」,不是修这个病。
|
|
61
66
|
*/
|
|
62
67
|
export declare function readMcpToolFaces(v: unknown): McpToolFacesRead;
|
|
63
68
|
export {};
|
package/dist/mcp-tool-faces.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { TOOL_APPROVAL_CARDS, TOOL_FAMILIES, TOOL_PATH_ABSENCES, TOOL_PATH_ACCESSES, TOOL_PATH_BASES } from "@sema-agent/core";
|
|
2
|
+
import { quotedCallerText } from "./caller-text-echo.js";
|
|
2
3
|
function isRecord(v) {
|
|
3
4
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
4
5
|
}
|
|
@@ -92,9 +93,12 @@ export function readMcpToolFaces(v) {
|
|
|
92
93
|
return { ok: false, problem: `toolFaces is ${Array.isArray(v) ? "an array" : typeof v}, not an object of per-tool faces` };
|
|
93
94
|
const faces = {};
|
|
94
95
|
for (const [tool, raw] of Object.entries(v)) {
|
|
96
|
+
if (tool === "__proto__") {
|
|
97
|
+
return { ok: false, problem: `toolFaces names tool "__proto__" — a per-tool record cannot hold a face under that name (writing it sets the record's prototype instead of a key), so the declaration would silently vanish` };
|
|
98
|
+
}
|
|
95
99
|
const face = readOneFace(raw);
|
|
96
100
|
if (face === undefined)
|
|
97
|
-
return { ok: false, problem: `the declared face for tool ${
|
|
101
|
+
return { ok: false, problem: `the declared face for tool ${quotedCallerText(tool)} does not fit the tool-face shape` };
|
|
98
102
|
faces[tool] = face;
|
|
99
103
|
}
|
|
100
104
|
return Object.keys(faces).length > 0 ? { ok: true, faces } : { ok: true };
|
package/dist/memory-scope.d.ts
CHANGED
|
@@ -286,7 +286,7 @@ declarations?: {
|
|
|
286
286
|
/**
|
|
287
287
|
* 「这一腿挂不挂记忆面」的**唯一属主**(合并复审 车HF F1,2026-09-18):与 core `prepareMemory` 的判据同源 ——
|
|
288
288
|
* `normalizeMemorySpec(spec)?.enabled === true`。S-405 之后 `memory:"off"` 铸的是「键在场 + `enabled:false`」(保留事实),
|
|
289
|
-
* 任何按「键在不在场」判挂没挂的读者从那一天起都读错(
|
|
289
|
+
* 任何按「键在不在场」判挂没挂的读者从那一天起都读错(改前本仓的记忆披露判别式正是那样,把无记忆面的披露一起吞掉;那只判别式已随引擎接管披露退役)。
|
|
290
290
|
* 消费方拿本函数的布尔,不拿 `spec.memory` 自己判。
|
|
291
291
|
*
|
|
292
292
|
* ⚠️ **本函数会抛,而「抛」本身就是一条判据**(S-424 补注)。`normalizeMemorySpec` 对两形直接 throw
|
package/dist/model-provider.d.ts
CHANGED
|
@@ -77,20 +77,47 @@ export declare function modelBrainLane(provider: ModelProvider): ModelBrainLane;
|
|
|
77
77
|
*/
|
|
78
78
|
export declare function catalogBrainLane(provider: string | undefined): ModelBrainLane;
|
|
79
79
|
/**
|
|
80
|
-
* 🔴 S-623
|
|
80
|
+
* 🔴 **本部署装上的路由表的唯一铸法**(core 7.53.0 #1842;S-623 的「词 ∧ 路由装上」合取由此收成「问表」)。
|
|
81
81
|
*
|
|
82
|
-
* `
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* `apply-effective.ts` 那条 `web_admin_model_no_brain` warn 说的「mis-routes to the gateway brain」即此。
|
|
82
|
+
* 键 = `createRoutingBrain` 选线读的那个词(`model.provider`),值 = 那条路由上的东西 —— `createBrain` 铸 brain 交给路由器,判词侧(启动摘要、端点判官、
|
|
83
|
+
* hook 选线)铸路由自己的配置交给 {@link brainLaneFor}(core 的判官从不读值,只问 `Object.hasOwn(routes, word)`)。两侧走同一只函数 ⇒ 同一组键,
|
|
84
|
+
* 「哪条路由装上了」只有这里一处写法。
|
|
86
85
|
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
86
|
+
* `anthropic` 键在场 ⇔ anthropic 路由装上(`ANTHROPIC_API_KEY` / `ANTHROPIC_AUTH_TOKEN` 在场 ⇒ `config.anthropic` 在场);没装时**键缺席**,
|
|
87
|
+
* 绝不写成 `{ anthropic: undefined }` —— core 7.53.0 起「装上的键而值不是 brain」是一条坏线路(该请求 error terminal),不再回落网关
|
|
88
|
+
* (core CHANGELOG #1842「the key must be absent, not `undefined`」)。视图上 `anthropic` 的自有键带 `undefined`(配置对象的形)照样读成没装。
|
|
89
|
+
*/
|
|
90
|
+
export declare function mountRoutes<R extends object, T>(view: {
|
|
91
|
+
readonly anthropic?: R | undefined;
|
|
92
|
+
}, mount: (route: R) => T): Readonly<Record<string, T>>;
|
|
93
|
+
/**
|
|
94
|
+
* 🔴 **anthropic 路由的请求根** —— 唯一读法(S-1655 / core 7.53.0 #1905)。声明了 `ANTHROPIC_BASE_URL` ⇒ 它;没声明 ⇒ core 包根导出的 `ANTHROPIC_DEFAULT_BASE_URL`
|
|
95
|
+
* (引擎的 Anthropic brain 的请求根与配对律的车道缺省、`fable5Model` 预设的 `baseUrl` 读的同一只常量)。「没声明」按引擎的读法:缺席、空串、纯空白都是没声明
|
|
96
|
+
* (core 原话:「nothing, an empty string and whitespace read as undeclared」)。修前本仓两处手抄字面量:主路由的声明根(`brain.ts`,`??`)与 hook 的 anthropic 腿根
|
|
97
|
+
* (`hooks/hook-llm.ts`,`||`)—— 一个根、两份拷贝、两种合取。
|
|
98
|
+
*/
|
|
99
|
+
export declare function anthropicRouteRoot(route: {
|
|
100
|
+
readonly baseUrl?: string | undefined;
|
|
101
|
+
}): string;
|
|
102
|
+
/** 判词侧的路由表:值 = 路由自己的配置({@link mountRoutes} 的恒等铸法 —— 判官不读值,只问键)。 */
|
|
103
|
+
export declare function routeTableOf<R extends object>(view: {
|
|
104
|
+
readonly anthropic?: R | undefined;
|
|
105
|
+
}): Readonly<Record<string, R>>;
|
|
106
|
+
/**
|
|
107
|
+
* 🔴 **一条目录条目在本部署上真正落哪条 brain 腿**(= 引擎路由器对同一只表的答案,不是词面)—— 唯一判词。
|
|
108
|
+
*
|
|
109
|
+
* 判据是 core 包根导出的 `brainLaneOf({ provider }, routes)`(core 7.53.0 #1842):`createRoutingBrain` 对每个请求问的正是它,所以引擎主路由与本仓的
|
|
110
|
+
* 四处调用点(主路由降级腿与启动摘要在 `brain.ts`、端点判官 `model-route-endpoint.ts`、hook 选线 `hooks/hook-llm.ts`)读**一个**答案。修前本仓自写一只
|
|
111
|
+
* 合取 `dispatchBrainLane(provider, anthropicRouteMounted)`(`catalogBrainLane(provider) === "anthropic" ∧ 路由装上`)—— 两份写法,S-1630 那次真病
|
|
112
|
+
* (hook 面按词面判线、主路由按装配判线)就是两份写法分叉的样子。
|
|
113
|
+
*
|
|
114
|
+
* core 的答案是路由名或 `undefined`(网关 fallback 服务它:词下没装路由,或没有 string 词)。本部署只装 `anthropic` 一条路由(表的唯一铸法 {@link mountRoutes}),
|
|
115
|
+
* 所以答案映到本仓两词闭集:`"anthropic"` ⇒ anthropic 腿,`undefined` ⇒ 网关腿;别的名字结构上不可能(表里没有那个键),真撞上 ⇒ **响亮抛**([ref]:运行期
|
|
116
|
+
* miss 臂必须说出来,不静默折网关)。
|
|
90
117
|
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
118
|
+
* S-704(7.101.0):**目录条目**到不了「anthropic 词、路由没装」这一格 —— 模型面 stage 的逐条判据把它判成不可用(`config.model_no_brain`,那一判问的是
|
|
119
|
+
* 「词想要的腿装没装」,{@link catalogBrainLane},与本判词是两个问题)。这一格今天只剩 **env 腿**:`MODEL_PROVIDER=anthropic` 而没配 anthropic 凭据的部署,
|
|
120
|
+
* env 模型落网关腿、用的是网关自己的 `MODEL_API_KEY`(凭据与端点同属网关,不越界)。
|
|
94
121
|
*/
|
|
95
|
-
export declare function
|
|
122
|
+
export declare function brainLaneFor(provider: string | undefined, routes: Readonly<Record<string, unknown>>): ModelBrainLane;
|
|
96
123
|
//# sourceMappingURL=model-provider.d.ts.map
|
package/dist/model-provider.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ANTHROPIC_DEFAULT_BASE_URL, brainLaneOf } from "@sema-agent/core";
|
|
1
2
|
export const MODEL_PROVIDER_WORDS = ["gateway", "vllm", "anthropic"];
|
|
2
3
|
export function isModelProvider(word) {
|
|
3
4
|
return word !== undefined && MODEL_PROVIDER_WORDS.includes(word);
|
|
@@ -23,7 +24,23 @@ export function modelBrainLane(provider) {
|
|
|
23
24
|
export function catalogBrainLane(provider) {
|
|
24
25
|
return isModelProvider(provider) ? modelBrainLane(provider) : "gateway";
|
|
25
26
|
}
|
|
26
|
-
export function
|
|
27
|
-
|
|
27
|
+
export function mountRoutes(view, mount) {
|
|
28
|
+
const route = view.anthropic;
|
|
29
|
+
return route !== undefined ? { anthropic: mount(route) } : {};
|
|
30
|
+
}
|
|
31
|
+
export function anthropicRouteRoot(route) {
|
|
32
|
+
const declared = route.baseUrl;
|
|
33
|
+
return declared !== undefined && declared.trim() !== "" ? declared : ANTHROPIC_DEFAULT_BASE_URL;
|
|
34
|
+
}
|
|
35
|
+
export function routeTableOf(view) {
|
|
36
|
+
return mountRoutes(view, (route) => route);
|
|
37
|
+
}
|
|
38
|
+
export function brainLaneFor(provider, routes) {
|
|
39
|
+
const line = brainLaneOf({ provider }, routes);
|
|
40
|
+
if (line === undefined)
|
|
41
|
+
return "gateway";
|
|
42
|
+
if (line === "anthropic")
|
|
43
|
+
return "anthropic";
|
|
44
|
+
throw new Error(`brainLaneFor: the engine's route judge answered route "${line}", which this deployment never mounts (the route table holds only the anthropic route) — the table was built outside mountRoutes`);
|
|
28
45
|
}
|
|
29
46
|
//# sourceMappingURL=model-provider.js.map
|
|
@@ -97,7 +97,7 @@ export interface ModelRouteEndpointView {
|
|
|
97
97
|
*
|
|
98
98
|
* 判序即语义:
|
|
99
99
|
* ① 备用网关设了、主网关没设 ⇒ `config.gateway_fallback_without_primary`(备用是主的镜像,这一条与条目无关,先说);
|
|
100
|
-
* ② 逐条目:按 {@link
|
|
100
|
+
* ② 逐条目:按 {@link brainLaneFor}(引擎路由器对本部署路由表的答案)落 openai 腿、且 {@link openaiRouteBaseUrl} 解析不到 ⇒ 收集名字,
|
|
101
101
|
* 一句话**全部点名**(运维一次改完,而不是改一个撞下一个)。
|
|
102
102
|
*
|
|
103
103
|
* `default` 键是目录里另一条的别名(env 腿 `{default: m, [m.id]: m}`、center 腿 `models.default = models[picked]`),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { brainLaneFor, catalogBrainLane, routeTableOf } from "./model-provider.js";
|
|
2
2
|
import { DEFAULT_MODEL_REF, servedModelTableLeg } from "./model-select.js";
|
|
3
3
|
export const MODEL_ROUTE_ENDPOINT_MISSING_CODE = "config.model_route_endpoint_missing";
|
|
4
4
|
export const GATEWAY_FALLBACK_WITHOUT_PRIMARY_CODE = "config.gateway_fallback_without_primary";
|
|
@@ -11,7 +11,7 @@ export function openaiRouteBaseUrl(routeBaseUrl, gatewayBaseUrl) {
|
|
|
11
11
|
return declared(routeBaseUrl) ?? declared(gatewayBaseUrl);
|
|
12
12
|
}
|
|
13
13
|
function unresolvedRouteLabel(name, provider) {
|
|
14
|
-
return provider === "anthropic"
|
|
14
|
+
return catalogBrainLane(provider) === "anthropic"
|
|
15
15
|
? `"${name}" (provider "anthropic", but no Anthropic route is mounted — ANTHROPIC_API_KEY / ANTHROPIC_AUTH_TOKEN are unset — so it falls to the openai-compatible lane)`
|
|
16
16
|
: `"${name}"`;
|
|
17
17
|
}
|
|
@@ -32,18 +32,18 @@ export function judgeModelRouteEndpoint(view, leg) {
|
|
|
32
32
|
"or unset MODEL_GATEWAY_FALLBACK_URLS.");
|
|
33
33
|
return { code: GATEWAY_FALLBACK_WITHOUT_PRIMARY_CODE, gap: "endpoint_missing", reason };
|
|
34
34
|
}
|
|
35
|
-
const
|
|
35
|
+
const routes = routeTableOf(view);
|
|
36
36
|
const entries = Object.entries(view.models ?? {});
|
|
37
37
|
const unresolved = [];
|
|
38
38
|
let laneCredentialMissing = false;
|
|
39
39
|
for (const [name, m] of entries) {
|
|
40
40
|
if (name === DEFAULT_MODEL_REF && entries.some(([k, other]) => k !== name && other === m))
|
|
41
41
|
continue;
|
|
42
|
-
if (
|
|
42
|
+
if (brainLaneFor(m.provider, routes) !== "gateway")
|
|
43
43
|
continue;
|
|
44
44
|
if (openaiRouteBaseUrl(m.baseUrl, gateway) !== undefined)
|
|
45
45
|
continue;
|
|
46
|
-
laneCredentialMissing ||= m.provider === "anthropic";
|
|
46
|
+
laneCredentialMissing ||= catalogBrainLane(m.provider) === "anthropic";
|
|
47
47
|
unresolved.push(unresolvedRouteLabel(name, m.provider));
|
|
48
48
|
}
|
|
49
49
|
if (unresolved.length === 0)
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* MODEL_COST_* — opt-in pricing). The per-run usage extraction (sandbox wall-clock from the run's remote-env
|
|
19
19
|
* spans, tool-call count from the trace) is the data-source wiring fed in by the caller; this layer is the math.
|
|
20
20
|
*/
|
|
21
|
+
import type { TaskResult } from "@sema-agent/core";
|
|
21
22
|
/** Deployment infra pricing (config; default 0 = not priced, mirrors MODEL_COST_*). */
|
|
22
23
|
export interface InfraCostRates {
|
|
23
24
|
/** $ (micro-USD) per tool invocation. */
|
|
@@ -40,13 +41,12 @@ export interface InfraCostBreakdown {
|
|
|
40
41
|
egressMicroUsd: number;
|
|
41
42
|
totalMicroUsd: number;
|
|
42
43
|
}
|
|
43
|
-
/**
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
44
|
+
/**
|
|
45
|
+
* Core's LLM-family breakdown — core's own `TaskResult.stats.costBreakdown` type, accepted read-only for composition (S-1687: not a hand-copied
|
|
46
|
+
* mirror — core 7.52.0 added the `sideCallMicroUsd` "of which" line and a copy would have missed it). Its partition lines add up to core's
|
|
47
|
+
* `costMicroUsd`; `sideCallMicroUsd` (the classifier's and mods' model calls) is an "of which" line INSIDE `llmRootMicroUsd`, never added to them.
|
|
48
|
+
*/
|
|
49
|
+
export type LlmCostBreakdown = NonNullable<TaskResult["stats"]["costBreakdown"]>;
|
|
50
50
|
/** The combined supervisor cost surface: core's LLM axes + the service's infra axes + a reconciled grand total. */
|
|
51
51
|
export interface SupervisorCostBreakdown {
|
|
52
52
|
llm: LlmCostBreakdown | null;
|
|
@@ -65,7 +65,7 @@ export declare const FAIL_OPEN_TAGS: {
|
|
|
65
65
|
};
|
|
66
66
|
readonly "server.trace.projection-input-malformed": {
|
|
67
67
|
readonly cls: "F";
|
|
68
|
-
readonly note: "7.78.0(core 7.18.0 #741/#786/#789/#790,`trace/project.ts` 的五张新投影脸共用一条规则;之后逐版入族 —— NP-5 / 7.100.0 起含 `trace/task-notification-facets.ts` 的 S-616 委派终态 facet / 重供两键与 `compacted.summarizedCrossSessionMessages`,助手住叶模块 `trace/projection-drop.ts`,全表见普查表第 73 行):`tool_progress` / `tool_disclosure` 两帧的必需位读不出 ⇒ **整帧不发**;`wiring_manifest.hooks[]`
|
|
68
|
+
readonly note: "7.78.0(core 7.18.0 #741/#786/#789/#790,`trace/project.ts` 的五张新投影脸共用一条规则;之后逐版入族 —— NP-5 / 7.100.0 起含 `trace/task-notification-facets.ts` 的 S-616 委派终态 facet / 重供两键与 `compacted.summarizedCrossSessionMessages`,助手住叶模块 `trace/projection-drop.ts`,全表见普查表第 73 行):`tool_progress` / `tool_disclosure` 两帧的必需位读不出 ⇒ **整帧不发**;`wiring_manifest.mods[]`(7.132.0 前为 `hooks[]`)/ `wiring_manifest.lsp` / `context_usage.sections[]` 三段的容器形或成员形读不出 ⇒ 那一行/那一段被丢、全丢光即键缺席;7.132.0 起含 `observability/prompt-manifest.ts` 的耐久 `prompt_assembled` 行(引擎清单 v3):`identity` / `selectors` / `toolDisclosure` / `totalChars` 读不出 ⇒ 该成员丢,`blocks` / `sections` / `superseded` / `tools` 一行一判、全丢光即键缺席。规则一句话:**在场但读不出 ⇒ 计一次并丢弃;缺席从不计数**(缺席是这几张脸上的一等状态,契约把它定义成一个正面事实 —— `mods` 缺席 = 「这条腿没有注册」、`sections` 缺席 = 「这条腿没装配出段 IR」、`lsp` 缺席 = 「本部署没接 LSP」)。放行的最坏后果=这条腿的消费端少一张观测/渲染面(壳退回上一份已知状态或通用卡片),**不影响任何裁决**——门在引擎里早已判完。反方向(半张脸照发)严格更坏:消费端会把读不出的行当成那个正面事实。计数是**唯一**能把「坏世代 / 第三方 producer 一直在发坏载荷」与那个正面事实分开的位。";
|
|
69
69
|
};
|
|
70
70
|
readonly "server.task-mcp.source-label-dropped": {
|
|
71
71
|
readonly cls: "F";
|
|
@@ -117,12 +117,36 @@ export declare const FAIL_OPEN_TAGS: {
|
|
|
117
117
|
};
|
|
118
118
|
readonly "server.session-titler.gateway-unreachable": {
|
|
119
119
|
readonly cls: "F";
|
|
120
|
-
readonly note: "S-178(cli [6662] ① clay 裁定转达,`session-titler.ts logFailure`):自动会话标题那一次廉价模型调用失败
|
|
120
|
+
readonly note: "S-178(cli [6662] ① clay 裁定转达,`session-titler.ts logFailure`):自动会话标题那一次廉价模型调用失败 —— **只数真不可达**:连不上 / 网络层失败 / 超时(失败码 `unreachable`,没有应答)。其它成因族各有自己的 tag,不再进本 tag:端点回 3xx 被拒 `server.session-titler.redirect-refused`;端点答了但不是可用 completion `server.session-titler.bad-response`;空应答 `server.session-titler.no-content`;选不出模型 `server.session-titler.model-unresolved`;路由核验拒 `server.session-titler.route-refused`;凭据托管失败 `server.session-titler.credential-custody-failed`;失败码缺席 `server.session-titler.unclassified`。标题是**纯装饰**——列表面回退 objectivePreview,零行为影响,门/裁决/账本一个字节不受它管。此前每个新会话首次同 cause 打一条 `warn`,于是一台没配模型 gateway 的单机部署在日志里被这条噪音刷屏,壳因此去关 `SESSION_AUTO_TITLE`(替上游压噪),而那是把一个部署级旋钮当消音器用。现在:逐次 `debug` + 本计数 + 一次性 warn(recorder 自己的),运维仍看得见「这台机器的 titler 一直在失败」,用户面零噪音。观测面另有 `session_title_total{outcome}` 逐次记账。";
|
|
121
121
|
};
|
|
122
122
|
readonly "server.session-titler.redirect-refused": {
|
|
123
123
|
readonly cls: "F";
|
|
124
124
|
readonly note: "`session-titler.ts logFailure`:自动会话标题那一次廉价模型调用被拒 —— 配置的模型端点回了 3xx 重定向。本服务发往配置端点的直连请求不跟随重定向(跟随会把请求体里的用户内容与凭据头送到 `Location` 指向的另一个 origin),所以这是**端点配置问题,不是网络问题**:出路 = 把该模型的网关 URL(`MODEL_GATEWAY_BASEURL` / 目录条目自己的 baseUrl / `ANTHROPIC_BASE_URL`)改成最终地址,查网络没有用。与 `server.session-titler.gateway-unreachable` 的分界 = 失败码(llm 面交回的 `redirect_refused`),不看文案。标题是**纯装饰**——列表面回退 objectivePreview,零行为影响,门/裁决/账本一个字节不受它管。放行的最坏后果 = 该部署的会话没有自动标题。逐次 `debug` + 本计数 + 一次性 warn(recorder 自己的);`session_title_total{outcome=llm_failed}` 照常逐次记账。";
|
|
125
125
|
};
|
|
126
|
+
readonly "server.session-titler.model-unresolved": {
|
|
127
|
+
readonly cls: "F";
|
|
128
|
+
readonly note: "`session-titler.ts logFailure`(失败码 `model_unresolved`,铸点 `hooks/hook-llm.ts` 的选模闸 `hookModelFor`):自动会话标题那一次廉价模型调用**选不出模型** —— 目录里没有这只模型 / 条目已发布但本部署不可用 / 网关腿解析不出端点(没有网关的部署上条目也不自带 baseUrl)。**配置问题,不是网络问题**:出路 = 改模型目录或网关配置(summarize 角色指向的模型名、`MODEL_CHEAP_ID`、`MODEL_GATEWAY_BASEURL`),查网络没有用;零请求出门。此前与「连不上」共用 `gateway-unreachable`。标题是**纯装饰**——列表面回退 objectivePreview,零行为影响,门/裁决/账本一个字节不受它管。放行的最坏后果 = 该部署的会话没有自动标题。逐次 `debug` + 本计数 + 一次性 warn(recorder 自己的);`session_title_total{outcome=llm_failed}` 照常逐次记账。";
|
|
129
|
+
};
|
|
130
|
+
readonly "server.session-titler.route-refused": {
|
|
131
|
+
readonly cls: "F";
|
|
132
|
+
readonly note: "`session-titler.ts logFailure`(失败码 `route_refused`,铸点 `hooks/hook-llm.ts` 的 `judgeRoute` 与组装期的 URL 铸造):自动会话标题那一次廉价模型调用被路由核验拒发 —— key↔URL 不配对(core 配对法的 `route.credential_*`)/ foreign 端点无 per-model key(标题 prompt 内嵌用户内容,未认证地发往未声明的端点等于把数据交给该 URL 的运营方)/ 请求 URL 铸不出来(如根带 `#fragment`)。**配置问题,零请求出门**:出路 = 改路由或凭据配置(模型条目的 baseUrl 与它的 key),查网络没有用。此前与「连不上」共用 `gateway-unreachable`。标题是**纯装饰**——列表面回退 objectivePreview,零行为影响,门/裁决/账本一个字节不受它管。放行的最坏后果 = 该部署的会话没有自动标题。逐次 `debug` + 本计数 + 一次性 warn(recorder 自己的);`session_title_total{outcome=llm_failed}` 照常逐次记账。";
|
|
133
|
+
};
|
|
134
|
+
readonly "server.session-titler.credential-custody-failed": {
|
|
135
|
+
readonly cls: "F";
|
|
136
|
+
readonly note: "`session-titler.ts logFailure`(失败码 `credential_custody_failed`,铸点 `hooks/hook-llm.ts` 的 per-model key 读取):自动会话标题那一次廉价模型调用的 per-model key 托管读不出(密封 key 中毒 / 解密失败)。**fail-closed 方向不变**:不回落共享路由凭据、零请求出门(回落会把共享凭据发给不该拿到它的端点)。出路 = 查密钥托管(该模型的 sealed key / `apiKeyEnv`),查网络没有用。此前与「连不上」共用 `gateway-unreachable`。标题是**纯装饰**——列表面回退 objectivePreview,零行为影响,门/裁决/账本一个字节不受它管。放行的最坏后果 = 该部署的会话没有自动标题。逐次 `debug` + 本计数 + 一次性 warn(recorder 自己的);`session_title_total{outcome=llm_failed}` 照常逐次记账。";
|
|
137
|
+
};
|
|
138
|
+
readonly "server.session-titler.bad-response": {
|
|
139
|
+
readonly cls: "F";
|
|
140
|
+
readonly note: "`session-titler.ts logFailure`(失败码 `bad_response`,铸点 `hooks/hook-llm.ts` 的应答读取):自动会话标题那一次廉价模型调用打到了端点、端点**答了**,但答的不是可用的 completion —— 非 2xx 状态(401 / 403 凭据被端点拒 · 429 · 5xx 网关故障),或 2xx 而 body 不是 JSON(中间的代理塞了一页 HTML)。**不是不可达**:出路 = 看端点答了什么(网关日志 / 凭据是否被它认),不是查网络。此前与「连不上」共用 `gateway-unreachable`。标题是**纯装饰**——列表面回退 objectivePreview,零行为影响,门/裁决/账本一个字节不受它管。放行的最坏后果 = 该部署的会话没有自动标题。逐次 `debug` + 本计数 + 一次性 warn(recorder 自己的);`session_title_total{outcome=llm_failed}` 照常逐次记账。";
|
|
141
|
+
};
|
|
142
|
+
readonly "server.session-titler.no-content": {
|
|
143
|
+
readonly cls: "F";
|
|
144
|
+
readonly note: "`session-titler.ts logFailure`(失败码 `no_content`,铸点 `hooks/hook-llm.ts`):自动会话标题那一次廉价模型调用得到合法 JSON 应答、但里面**没有文本**(例:推理档模型的思考占满了输出额度 / 网关侧内容过滤清空了 choices)。出路 = 看该模型对这类短输出的行为(换 summarize 角色的模型),不是查网络。此前与「连不上」共用 `gateway-unreachable`。标题是**纯装饰**——列表面回退 objectivePreview,零行为影响,门/裁决/账本一个字节不受它管。放行的最坏后果 = 该部署的会话没有自动标题。逐次 `debug` + 本计数 + 一次性 warn(recorder 自己的);`session_title_total{outcome=llm_failed}` 照常逐次记账。";
|
|
145
|
+
};
|
|
146
|
+
readonly "server.session-titler.unclassified": {
|
|
147
|
+
readonly cls: "F";
|
|
148
|
+
readonly note: "`session-titler.ts logFailure` 的 `switch` 在**失败码缺席**时的明说臂:自动会话标题那一次调用失败了,但载体没有给码(失败臂漏铸码 / 异常路径:store 写失败、载体违约抛出)。它**不冒充任何一族**:此前这一臂记成 `gateway-unreachable`,运维去查网络。计数非零 = 有失败臂没带码,去补铸点(`hooks/hook-llm.ts`)或看 `session_title_failed` 的 debug 行,不是去查网络。标题是**纯装饰**——列表面回退 objectivePreview,零行为影响,门/裁决/账本一个字节不受它管。放行的最坏后果 = 该部署的会话没有自动标题。逐次 `debug` + 本计数 + 一次性 warn(recorder 自己的);`session_title_total{outcome=llm_failed}` 照常逐次记账。";
|
|
149
|
+
};
|
|
126
150
|
readonly "server.prompts.artifact-cache-write-failed": {
|
|
127
151
|
readonly cls: "F";
|
|
128
152
|
readonly note: "已验签的提示词工件回填本地缓存失败。工件本身已返回给调用方;代价是下次同 digest 还要再取一次网络。";
|
|
@@ -155,6 +179,10 @@ export declare const FAIL_OPEN_TAGS: {
|
|
|
155
179
|
readonly cls: "F";
|
|
156
180
|
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`。";
|
|
157
181
|
};
|
|
182
|
+
readonly "server.approvals.queue-row-gate-kind-missing": {
|
|
183
|
+
readonly cls: "F";
|
|
184
|
+
readonly note: "S-1681(`plugins/checkpoint-store-sql.ts` 的 `queueRowGateKind`,7.132.0;SQL 与 local 两只孪生的 `listPending` 同调这一只判官):运维待批队列(`GET /v1/approvals` / `/stream`)读到一行 pending 的门型(SQL 孪生:`checkpoint.gate_kind` 列;local 孪生:快照上的门)是 NULL 或不是 core 登记的门型 ⇒ 这一行**不列**。按构造不可达:每次停驻都把门型反范式进这一列,一次性迁移 M21 把没有它的存量行从门子树补齐(读不出登记门型的置 expired)。放行(不列、队列其余照常)的最坏后果 = 一行谁也决不了的行不出现在队列上 —— 它本来就不可决:每一条决断口按门型绑定取行(`gate_kind IN (…)`),证不出门型就不当它是这道门;不放行(整只拒)的代价是一行坏行打掉整个租户的队列(列表 500、SSE 心跳照常而队列永远停在旧帧)。也不按缺键投出去:消费方按 `gateKind` 路由、缺键即 fail-closed,队列行的契约是 `gateKind` 恒在场。故 F 类;计数非零 = 写腿或手改出了错,`SELECT session_id FROM checkpoint WHERE status = 'pending' AND gate_kind IS NULL` 查那一行(置 expired 或删会话)。";
|
|
185
|
+
};
|
|
158
186
|
readonly "server.sql-json.checkpoint.pending-steer-queue-lossy": {
|
|
159
187
|
readonly cls: "F";
|
|
160
188
|
readonly note: "S-550(`plugins/checkpoint-store-sql.ts` 的 `get()`,core 5.14.0 #147 的耐久转向队列):一条挂起 run 的 `checkpoint.pending_steer_queue` 这一格**没能完整读出来**(不是合法 JSON 文本 / 不是数组 / 某一条目的四个必备键不合形)⇒ 读不出的那部分**丢掉**,run 照常 resume。放行的最坏后果 = 一条已经 park 的操作员转向指令**没有**在这次 resume 上注入(人以为说过的话没送到);不放行的代价是这条挂起的 run **永远不可 resume** —— resume 是它唯一的出路,为一格读不出的转向把整条 run 变成砖是错误的失败方向(写侧刻意相反:`setPendingSteer` 往一份读不全的队列上追加会把读不出的条目永久抹掉,那里 fail-loud)。故 F 类。留痕从一条 `logger.info` 升成登记 tag 的理由:日志行在**遥测轴**上是零信号,「这台机器的转向队列一直读不出来」与「这台机器本来就没人 steer」在指标上完全同形。计数非零 = 去按日志里的 token 指纹查那一行。";
|
|
@@ -241,7 +269,7 @@ export declare const FAIL_OPEN_TAGS: {
|
|
|
241
269
|
};
|
|
242
270
|
readonly "server.hooks.matcher-unjudged": {
|
|
243
271
|
readonly cls: "F";
|
|
244
|
-
readonly note: "S-995(`hooks/hook-runner.ts` 的 `
|
|
272
|
+
readonly note: "S-995(`hooks/hook-runner.ts` 的 `hooksMatcherIssue`,fresh 受理面「工具事件 matcher 选中别名而选不中正名 ⇒ 400」判据的**未判**臂;detail = `event=… reason=… matcherChars=…`,不带 matcher 原字节):一只 matcher 没能被判 ⇒ 照旧受理。判据一条顺序、两档共用(7.114.0 修复轮):长度上限 → 形只问契约包的 `hookMatcherForm`(literal 形〔名字表 / 空 / `*`〕两档都直接问 `hookMatcherSelects`、不占预算;regex 形 regex 档把同一只契约函数交进 vm 带每次求值各一份的固定预算〔超时 = 灾难回溯 ⇒ 确定的 400 拒,不是未判、不登记;一次受理里所有已完成求值的耗时之和超过受理总额度同样是确定的 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)显形。";
|
|
245
273
|
};
|
|
246
274
|
readonly "server.hooks.resume-reader-refused": {
|
|
247
275
|
readonly cls: "P-DEBT";
|
|
@@ -445,15 +473,15 @@ export declare const FAIL_OPEN_TAGS: {
|
|
|
445
473
|
};
|
|
446
474
|
readonly "server.workspace-cache.unavailable": {
|
|
447
475
|
readonly cls: "F";
|
|
448
|
-
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`)
|
|
476
|
+
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`)。`claim_unbound` / `claim_unmountable` 按空间记一个快照时限(部署的 per-run 绑定持有的进程内记忆):窗内这个空间的后续 run 直接走这条臂(不发 claim 请求、不起等卷的 pod),每条 run 仍计一次、出一行,`error` 点名「记着的」。计数非零 = 这台部署开了缓存卷却拿不到,运维去看 StorageClass / Role / 配额。";
|
|
449
477
|
};
|
|
450
478
|
readonly "server.workspace-cache.reclaim-failed": {
|
|
451
479
|
readonly cls: "F";
|
|
452
|
-
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
|
|
480
|
+
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` / `count` / `error` —— 一次调用里同 `reason` 的失败合成一行,`count` = 撞上它的空间数、其余键点名调用里排第一的那个,计数仍逐空间;住客读不出那一形:`sessionId` / `reason` / `error`)。计数非零 = 有卷没回收掉,运维按行里的标签手清,并核 Role。";
|
|
453
481
|
};
|
|
454
482
|
readonly "server.workspace-space.reclaim-failed": {
|
|
455
483
|
readonly cls: "F";
|
|
456
|
-
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` 留给桶的生命周期规则。";
|
|
484
|
+
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` / `count` / `error`;一次调用里同类〔分区 × 阶段〕的失败合成一行,`count` = 撞上它的空间数,其余键点名调用里排第一的那个,计数仍逐空间;回收座同一时刻最多 4 个空间在收,sweep 与会话删除共用这一只门)。计数非零 = 有对象没回收掉,运维按行里的空间前缀 / 会话 id 去桶里手清,并核对象存储的可达性与 DELETE 权限。回收与同一空间的尚在途的 run 末提交不是互斥的:会话删除时没有活 run(409 挡),但上一条 run 的提交若恰在删除之后才落对象,这批对象不在本次回收射程内(同样归桶的生命周期规则)。停驻分区按会话 id 分区,所以只删名字带被结束住客归属记号的对象(不读任何钟)—— 会话 id 删后被别人重新登记,新住客停驻出的快照带它自己的记号、不碰;不带记号的旧形与 `none` 留给桶的生命周期规则。";
|
|
457
485
|
};
|
|
458
486
|
readonly "server.sandbox-egress.policy-gap": {
|
|
459
487
|
readonly cls: "P-DEBT";
|
|
@@ -467,6 +495,14 @@ export declare const FAIL_OPEN_TAGS: {
|
|
|
467
495
|
readonly cls: "P-DEBT";
|
|
468
496
|
readonly note: "7.121.0(`fleet/serving-lease.ts` 的 `enterDenied`,中心以正面证据拒了本实例的服务租约那一拍;detail = `worker=<w> generation=<g>`):拒要落成数据根下一只文件(重启后起步即排空),而这一次**没落下** —— 没有数据根,或写失败(盘满 / 只读挂载 / 目录不在)。本进程照样被拒、照样当拍排空、到期自停;放行的是**重启之后**:同代际重启的实例不记得被拒,在第一次续租得到答复之前会接新工作(中心宣告了能力位时,第一次续租就再被拒一次 —— 中心的代际下限是持久的;中心那时不可达则一直接单到过期满 `FLEET_LEASE_OUTAGE_MAX_MS`)。归 P 类:这是围栏的记忆;归 DEBT:进程内无法把「记不住」变成 fail-closed(起步不接单直到第一次答复,是对租约不可达容忍规则的改动,另案)。denied 行的 `sticky` 同拍说 `process-only`,不声称跨重启记得。计数非零 = 这台机器的数据根写不进,或部署没有数据根。";
|
|
469
497
|
};
|
|
498
|
+
readonly "server.sql.tidb-row-cap-unread": {
|
|
499
|
+
readonly cls: "F";
|
|
500
|
+
readonly note: "TiDB 连接初始化读不出单行上限(`plugins/sql-driver.ts` `readTidbEntrySizeLimit`;detail = `assumed=<字节> <两次读各自的原因>`):会话变量 `@@tidb_txn_entry_size_limit` 为 0 / 不认识(TiDB 7.6 之前没有它),且 `SHOW CONFIG` 读 `performance.txn-entry-size-limit` 失败(要 `CONFIG` 权限)或读不到行 ⇒ 按 TiDB 自己的缺省 6291456 字节当本库的单行上限(`SqlEngineFacts.maxRowBytes`),提交口据它把装不进一行的请求体答 413。每条池连接初始化各记一次。放行的最坏后果:运维抬过上限而读不到 ⇒ 6 MiB 到真上限之间的体被多拒(413,出路 = 给账号 `CONFIG` 权限,或 TiDB 7.6+ 设 `tidb_txn_entry_size_limit`);运维调低过而读不到 ⇒ 门放进了装不下的体,写库那一刻被库拒:提交时写续跑输入那一笔(durable 审批部署)答带码的 413(店的 `StoreRowTooLargeError`),开跑后的写(会话日志的用户消息等)按各自的既有失败面。不是门、不是凭据、不改任何裁决;计数非零 = 去给库账号授权或设会话变量。";
|
|
501
|
+
};
|
|
502
|
+
readonly "server.sql.packet-cap-unread": {
|
|
503
|
+
readonly cls: "F";
|
|
504
|
+
readonly note: "MySQL 协议连接初始化读不出语句级包墙(`plugins/sql-driver.ts` `readMaxAllowedPacket`,InnoDB 与 TiDB 同一处初始化;detail = `assumed=<字节> engine=<tidb|innodb> <读不出的原因>`):会话变量 `@@max_allowed_packet` 不认识 / 读它的查询失败 / 读到的不是正整数 ⇒ 按该服务器族的文档缺省当本库的包墙(`SqlEngineFacts.maxPacketBytes`;tidb 67108864,innodb 取 MariaDB 与 MySQL 8 两个缺省里小的 16777216),SQL 快照 blob 的缺省帽据它扣语句余量(1 KiB)再折半(文本协议 2× 膨胀)后与单行墙取小。每条池连接初始化各记一次。放行的最坏后果:库的真包墙比落点小(DBA 调小而没读到)⇒ 缺省帽放进了装不进一条语句的 blob,库在写的那一刻以 `ER_NET_PACKET_TOO_LARGE` 拒,快照 blob 写走各自既有的失败面(店的 never-throw 结果形折成 502);比落点大(调大而没读到)⇒ 缺省帽多拒(413 `blob_too_large_for_sql`,出路 = 显式旋钮 `SNAPSHOT_BLOB_SQL_MAX_BYTES` 或配对象存储)。不是门、不是凭据、不改任何裁决;计数非零 = 去看库账号能不能读 `@@max_allowed_packet`(普通账号都读得到,读不出多半是代理 / 中间件拦了这句)。";
|
|
505
|
+
};
|
|
470
506
|
};
|
|
471
507
|
/** 词表键推导的闭集类型——未登记的 tag 传不进 {@link recordFailOpen}(编译期拒)。 */
|
|
472
508
|
export type FailOpenTag = keyof typeof FAIL_OPEN_TAGS;
|