@sema-agent/server 7.116.1 → 7.118.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 +195 -0
- package/USAGE.md +65 -41
- package/dist/approval-card.d.ts +82 -18
- package/dist/approval-card.js +46 -4
- package/dist/approval.d.ts +4 -12
- package/dist/approval.js +4 -26
- package/dist/boot/budget-tracing.js +2 -3
- package/dist/boot/config-center.d.ts +2 -2
- package/dist/boot/config-center.js +5 -7
- package/dist/boot/parked-revive-gate.d.ts +1 -7
- package/dist/boot/parked-revive-gate.js +2 -12
- package/dist/boot/resolve-spec.js +18 -16
- package/dist/boot/runner-deps.d.ts +5 -3
- package/dist/boot/runner-deps.js +6 -4
- package/dist/boot/stage-07-capability-layer.js +2 -2
- package/dist/brain.d.ts +17 -8
- package/dist/brain.js +10 -7
- package/dist/capabilities/hands-lane.d.ts +25 -0
- package/dist/capabilities/hands-lane.js +1 -1
- package/dist/capabilities/mcp-probe.d.ts +2 -2
- package/dist/config-catalog.js +3 -2
- package/dist/config-center/apply-effective.d.ts +6 -16
- package/dist/config-center/apply-effective.js +0 -6
- package/dist/config-center/facade.d.ts +1 -1
- package/dist/config-center/facade.js +1 -1
- package/dist/config-center/restart-signal.d.ts +1 -1
- package/dist/config-types.d.ts +12 -16
- package/dist/config.d.ts +32 -29
- package/dist/config.js +20 -27
- package/dist/deployment-governance.d.ts +13 -19
- package/dist/deployment-governance.js +7 -14
- package/dist/governance-overrides.d.ts +20 -0
- package/dist/governance-overrides.js +8 -0
- package/dist/host-decision.d.ts +83 -25
- package/dist/host-decision.js +31 -1
- package/dist/http/admission.js +13 -7
- package/dist/http/approval-sweeps.js +16 -13
- package/dist/http/checkpoint-ctx.d.ts +83 -24
- package/dist/http/checkpoint-ctx.js +68 -8
- package/dist/http/mcp-dial-deadline.d.ts +35 -0
- package/dist/http/mcp-dial-deadline.js +21 -0
- package/dist/http/memory-compliance-failure-reply.d.ts +11 -5
- package/dist/http/memory-compliance-failure-reply.js +17 -8
- package/dist/http/memory-store-refusal-reply.d.ts +14 -11
- package/dist/http/memory-store-refusal-reply.js +16 -5
- package/dist/http/resume-legs.js +18 -18
- package/dist/http/retired-skill-manifest.d.ts +1 -1
- package/dist/http/route-ctx.d.ts +3 -3
- package/dist/http/routes/approvals-assistant.js +21 -24
- package/dist/http/routes/capabilities.js +5 -3
- package/dist/http/routes/mcp-reconnect.d.ts +17 -0
- package/dist/http/routes/mcp-reconnect.js +6 -1
- package/dist/http/routes/memory-bundle.js +1 -1
- package/dist/http/routes/memory-compliance.js +1 -1
- package/dist/http/routes/memory-origin.js +1 -1
- package/dist/http/routes/runs.js +53 -33
- package/dist/http/routes/sessions.d.ts +1 -1
- package/dist/http/routes/sessions.js +3 -6
- package/dist/http/routes/workflows.js +2 -0
- package/dist/http/wire-types.d.ts +6 -1
- package/dist/memory-store-refusal.d.ts +42 -17
- package/dist/memory-store-refusal.js +25 -6
- package/dist/model-select.d.ts +16 -5
- package/dist/model-select.js +7 -3
- package/dist/model-unreachable-notice.d.ts +1 -1
- package/dist/namespaced-rule-name.d.ts +45 -39
- package/dist/namespaced-rule-name.js +36 -22
- package/dist/observability/corrupt-read-seat.d.ts +4 -0
- package/dist/observability/corrupt-read-seat.js +1 -0
- package/dist/observability/fail-open.d.ts +15 -3
- package/dist/observability/fail-open.js +15 -3
- package/dist/observability/permission-rule-events.d.ts +3 -0
- package/dist/observability/permission-rule-events.js +4 -0
- package/dist/observability/run-terminal.js +21 -1
- package/dist/operator-ask.d.ts +4 -1
- package/dist/orchestration/workflow-agent-session-index.d.ts +82 -59
- package/dist/orchestration/workflow-agent-session-index.js +80 -14
- package/dist/orchestration/workflow-completion-inbox.d.ts +5 -0
- package/dist/orchestration/workflow-completion-inbox.js +39 -17
- package/dist/orchestration/workflow-notify-journal.d.ts +1 -1
- package/dist/orchestration/workflow-notify-journal.js +7 -2
- package/dist/outbound-dispatcher.d.ts +47 -20
- package/dist/outbound-dispatcher.js +198 -23
- package/dist/parked-decide.d.ts +43 -48
- package/dist/parked-decide.js +54 -16
- package/dist/permission-rule-list.d.ts +20 -31
- package/dist/permission-rule-vocab.d.ts +4 -3
- package/dist/permission-rule-vocab.js +1 -1
- package/dist/plugins/approval-ask-store-sql.d.ts +17 -20
- package/dist/plugins/approval-ask-store-sql.js +0 -3
- package/dist/plugins/one-time-migrations.d.ts +25 -0
- package/dist/plugins/one-time-migrations.js +192 -6
- package/dist/plugins/pg-pool.js +1 -1
- package/dist/plugins/tidb-pool.js +1 -1
- package/dist/plugins/web-search.d.ts +20 -1
- package/dist/plugins/web-search.js +39 -10
- package/dist/plugins/workflow-run-store-sql.d.ts +7 -6
- package/dist/plugins/workflow-run-store-sql.js +5 -7
- package/dist/request-key-closure.js +1 -1
- package/dist/request-value-closure.d.ts +1 -1
- package/dist/router/route-orchestration.d.ts +2 -23
- package/dist/rule-entry-list.d.ts +88 -0
- package/dist/rule-entry-list.js +102 -0
- package/dist/rules-consent.js +3 -0
- package/dist/run-local.d.ts +4 -2
- package/dist/run-local.js +4 -3
- package/dist/runs.d.ts +1 -1
- package/dist/runs.js +1 -0
- package/dist/runtime-governance.d.ts +5 -21
- package/dist/runtime-governance.js +4 -8
- package/dist/session-policy-wire.d.ts +13 -12
- package/dist/session-policy-wire.js +11 -6
- package/dist/spec-fields.d.ts +13 -24
- package/dist/spec-fields.js +13 -17
- package/dist/standing-answer-grant.d.ts +14 -2
- package/dist/standing-answer-grant.js +8 -1
- package/dist/task-settings.d.ts +18 -18
- package/dist/task-settings.js +63 -32
- package/dist/tool-approval.d.ts +77 -145
- package/dist/tool-approval.js +80 -62
- package/dist/trace/core-keyset-guard.d.ts +6 -6
- package/dist/trace/engine-notice-wire.d.ts +4 -6
- package/dist/trace/engine-notice-wire.js +14 -1
- package/dist/trace/self-minted-wire.d.ts +16 -2
- package/dist/trace/self-minted-wire.js +7 -0
- package/dist/user-input-ledger.d.ts +24 -12
- package/dist/user-input-ledger.js +33 -14
- package/package.json +2 -2
- package/scripts/drain-check-local.mjs +103 -7
- package/scripts/drain-check.mysql.sql +59 -8
- package/scripts/drain-check.pg.sql +66 -10
package/dist/approval-card.d.ts
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* 没有方法、没有捕获的行为。
|
|
22
22
|
*/
|
|
23
23
|
import { z } from "zod";
|
|
24
|
-
import { READ_ROOT_CANDIDATE_DIR_MAX, type AskClass, type AskEvidenceAbsence, type AskRequest as CoreAskRequest, type PendingAction as CorePendingAction, type ReadRootGrantCandidate, type RuleOffer } from "@sema-agent/core";
|
|
24
|
+
import { ALLOW_RULE_MEMBERS, READ_ROOT_CANDIDATE_DIR_MAX, type AskClass, type AskEvidenceAbsence, type AskRequest as CoreAskRequest, type PendingAction as CorePendingAction, type ReadRootGrantCandidate, type RuleOffer, type SteerReplayFacet } from "@sema-agent/core";
|
|
25
25
|
import type { AskRow } from "./plugins/approval-ask-store-sql.js";
|
|
26
26
|
/** 模型自由文本(`sourceAgentName` / `delegation.agentName`)的限长(设计稿 §6.2)。设计 §3.1 把
|
|
27
27
|
* 「限长 + 脱敏」写成 **server 新增责任**(引擎无此层):spawning model 挑的名字是自由文本,
|
|
@@ -81,11 +81,13 @@ export declare const RuleOfferSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
81
81
|
kind: z.ZodLiteral<"single">;
|
|
82
82
|
rule: z.ZodString;
|
|
83
83
|
match: z.ZodEnum<{
|
|
84
|
+
name: "name";
|
|
84
85
|
path: "path";
|
|
85
86
|
exact: "exact";
|
|
86
87
|
prefix: "prefix";
|
|
87
88
|
wildcard: "wildcard";
|
|
88
89
|
subpath: "subpath";
|
|
90
|
+
name_prefix: "name_prefix";
|
|
89
91
|
}>;
|
|
90
92
|
command: z.ZodString;
|
|
91
93
|
}, z.core.$strict>, z.ZodObject<{
|
|
@@ -94,11 +96,13 @@ export declare const RuleOfferSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
94
96
|
kind: z.ZodLiteral<"command">;
|
|
95
97
|
rule: z.ZodString;
|
|
96
98
|
match: z.ZodEnum<{
|
|
99
|
+
name: "name";
|
|
97
100
|
path: "path";
|
|
98
101
|
exact: "exact";
|
|
99
102
|
prefix: "prefix";
|
|
100
103
|
wildcard: "wildcard";
|
|
101
104
|
subpath: "subpath";
|
|
105
|
+
name_prefix: "name_prefix";
|
|
102
106
|
}>;
|
|
103
107
|
command: z.ZodString;
|
|
104
108
|
segment: z.ZodString;
|
|
@@ -126,7 +130,7 @@ export declare const RuleOfferSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
126
130
|
* `password=…` 换成更长的遮蔽标记)。拿带 `.max()` 的形去校验**脱敏前**的原文,再脱敏,产出的就可能是
|
|
127
131
|
* 一条超限的文本;而任何**回读**路径若再跑一遍同一个函数,那一条会在第二次校验时被整条丢掉 —— 于是
|
|
128
132
|
* 「落库时在、读回时不在」,并且**只发生在有回读的那条腿上**(SQL 有列回读、LOCAL 直接从 blob 投),
|
|
129
|
-
* 两个后端对同一份素材给出不同的卡面。同族先例逐字在 `tool-approval.ts` 的 `persistedRuleShadowed`
|
|
133
|
+
* 两个后端对同一份素材给出不同的卡面。同族先例逐字在 `tool-approval.ts` 的 `allowRuleShadowed`(7.41.x 时代叫 `persistedRuleShadowed`)
|
|
130
134
|
* 发帧点(「先脱敏再截,一次算定」)。
|
|
131
135
|
*
|
|
132
136
|
* ⇒ 正确顺序:**结构判(本 schema)→ 脱敏 → 截长 → 结果按 {@link RuleOfferSchema} 必然合形**。
|
|
@@ -158,11 +162,13 @@ export declare const RuleOfferRawSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
158
162
|
kind: z.ZodLiteral<"single">;
|
|
159
163
|
rule: z.ZodString;
|
|
160
164
|
match: z.ZodEnum<{
|
|
165
|
+
name: "name";
|
|
161
166
|
path: "path";
|
|
162
167
|
exact: "exact";
|
|
163
168
|
prefix: "prefix";
|
|
164
169
|
wildcard: "wildcard";
|
|
165
170
|
subpath: "subpath";
|
|
171
|
+
name_prefix: "name_prefix";
|
|
166
172
|
}>;
|
|
167
173
|
command: z.ZodString;
|
|
168
174
|
}, z.core.$strip>, z.ZodObject<{
|
|
@@ -171,11 +177,13 @@ export declare const RuleOfferRawSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
171
177
|
kind: z.ZodLiteral<"command">;
|
|
172
178
|
rule: z.ZodString;
|
|
173
179
|
match: z.ZodEnum<{
|
|
180
|
+
name: "name";
|
|
174
181
|
path: "path";
|
|
175
182
|
exact: "exact";
|
|
176
183
|
prefix: "prefix";
|
|
177
184
|
wildcard: "wildcard";
|
|
178
185
|
subpath: "subpath";
|
|
186
|
+
name_prefix: "name_prefix";
|
|
179
187
|
}>;
|
|
180
188
|
command: z.ZodString;
|
|
181
189
|
segment: z.ZodString;
|
|
@@ -282,7 +290,7 @@ export declare function readProbeCause(req: unknown): ProbeCauseProjection | und
|
|
|
282
290
|
* · 长度:超过 {@link MAX_PROBE_REASON_CODEPOINTS} ⇒ **整只丢,不截**(判据与 `probeCause.code` 超限同形);
|
|
283
291
|
* 先判长度再脱敏 ⇒ 喂给脱敏器的永远是个短串(脱敏器的 RangeError 面是超大输入)。
|
|
284
292
|
* · 内容族(部署自写的探针散文,人眼信任边界上的文本)⇒ `redactSecrets`。脱敏后**不再截**:耐久面同样不截,
|
|
285
|
-
* 两面逐字节同值比「帧上短一截」重要(
|
|
293
|
+
* 两面逐字节同值比「帧上短一截」重要(allow 层披露那一格 R2-[medium] 的反面:那里有卡面要对齐,这里没有)。
|
|
286
294
|
* · 缺席 ≠「没有原因」:只有 maybe 档收紧且探针真给了 reason 的 ask 才有它。
|
|
287
295
|
*/
|
|
288
296
|
export declare function readProbeReason(req: unknown): string | undefined;
|
|
@@ -337,6 +345,23 @@ export declare const RuleEvidenceSchema: z.ZodObject<{
|
|
|
337
345
|
personalRuleDotsAbsent: z.ZodOptional<z.ZodCustom<AskEvidenceAbsence, AskEvidenceAbsence>>;
|
|
338
346
|
}, z.core.$strict>;
|
|
339
347
|
export type RuleEvidenceProjection = z.infer<typeof RuleEvidenceSchema>;
|
|
348
|
+
/** 一条披露记录列出的条目上限 —— 防御值(引擎自己的上限更小,超出部分它计进 `omitted`);本层超出同样计进 `omitted`,不丢、不截条目个数以外的东西。 */
|
|
349
|
+
export declare const MAX_ALLOW_RULE_SHADOW_ENTRIES = 32;
|
|
350
|
+
/** 一条 allow 层披露记录的投影形(core `AllowRuleShadow` 的值形,条目已脱敏截长)。 */
|
|
351
|
+
export interface AllowRuleShadowProjection {
|
|
352
|
+
member: (typeof ALLOW_RULE_MEMBERS)[number];
|
|
353
|
+
entries: string[];
|
|
354
|
+
omitted?: number;
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* `AskRequest.allowRuleShadowed`(core 7.42.0 #1327)的**边界窄读** —— 活卡帧(`ToolApprovalFrame.allowRuleShadowed`)与 `card_json`
|
|
358
|
+
* (`buildApprovalCard`)的**唯一**铸造点,两面结构性同值(与 {@link readRuleEvidence} 同款分工)。姿势:
|
|
359
|
+
* · 整只形不合(不是数组 / 某条成员不在 core 闭集 / 条目不是字符串表 / `omitted` 不是正整数)⇒ 按缺席处置(半解上卡比缺席更坏);空数组 = 缺席;
|
|
360
|
+
* · 条目 = 内容族 ⇒ `redactSecrets` 后截 `MAX_RULE_TEXT_CHARS`,**先脱敏再截一次算定**(redact 会变长,两面各截会漂);超过
|
|
361
|
+
* {@link MAX_ALLOW_RULE_SHADOW_ENTRIES} 的条目计进 `omitted`(与引擎的计数相加);
|
|
362
|
+
* · 不包 try / catch:值来自引擎(已过引擎自己的 `readAllowRuleShadows` 判形),是纯数据;一只抛错的 getter 在这里抛 = 响亮失败,不是静默缺席。
|
|
363
|
+
*/
|
|
364
|
+
export declare function readAllowRuleShadowed(req: unknown): AllowRuleShadowProjection[] | undefined;
|
|
340
365
|
/**
|
|
341
366
|
* `AskRequest.ruleEvidence`(core 5.35.0 [ref] G-2)的**边界窄读**——活卡帧(`ToolApprovalFrame.
|
|
342
367
|
* ruleEvidence`)与 `card_json`(`buildApprovalCard`)的**唯一**铸造点,两面结构性同值(与
|
|
@@ -345,7 +370,7 @@ export type RuleEvidenceProjection = z.infer<typeof RuleEvidenceSchema>;
|
|
|
345
370
|
* · **恰一不变量**:一对成员(值 / 缺席词)**双在场** ⇒ 整只丢——那是矛盾证据(引擎盖章的恰一,
|
|
346
371
|
* 双在场只可能是第三方 producer 的坏行),半解上卡比缺席更坏。双缺席**容忍**(老 producer 行)。
|
|
347
372
|
* · `orgRule` 内容族(管理员写的规则文本)⇒ `redactSecrets` 后截 `MAX_RULE_TEXT_CHARS`,**先脱敏
|
|
348
|
-
* 再截一次算定**(
|
|
373
|
+
* 再截一次算定**(allow 层披露那一格 R2-[medium] 教训:redact 会变长,两面各截会漂);空串丢整只。
|
|
349
374
|
* · `dots.actor` 身份串 ⇒ `redactSecrets`(对正常 id 恒等);超限**整只丢**(见上限顶注,身份不可截)。
|
|
350
375
|
* · `orgRevision` / 缺席词 verbatim(数值 / 闭集词,非内容)。
|
|
351
376
|
*/
|
|
@@ -420,7 +445,7 @@ type ToolApprovalPark = Extract<CorePendingAction, {
|
|
|
420
445
|
kind: "tool_approval";
|
|
421
446
|
}>;
|
|
422
447
|
/**
|
|
423
|
-
* 🔴 **闭集词座的唯一窄读**(S-721 起 `mandate`;S-755 起 `origin`)——
|
|
448
|
+
* 🔴 **闭集词座的唯一窄读**(S-721 起 `mandate`;S-755 起 `origin`;S-1170 起 `classifierNoRuling` / `differs`)—— 一座一只成员筛,**名字是参数**(与
|
|
424
449
|
* {@link readParkRowTrueSeat} 同一条:一处解析,不是两只各写一遍的函数)。
|
|
425
450
|
* · `mandate`(core 7.32.0 #1092)—— 一问**站在哪一个 mandate 词上**(`mandated` 说「站在强制上」,本座说是 core
|
|
426
451
|
* `PERSISTED_RULE_MANDATES` 六词里的哪一个;core 只在强制位的**整因**是那一个词时铸 —— 治理 / hook / 祖先,或不止一个理由
|
|
@@ -429,6 +454,11 @@ type ToolApprovalPark = Extract<CorePendingAction, {
|
|
|
429
454
|
* · `origin`(core 7.5.0 [ref] 的 park 孪生座;S-755)—— **谁提的这一问**,core `ASK_ORIGINS` 闭集一词。读者:运维队列行读寄存行
|
|
430
455
|
* 孪生座 `PendingAction.tool_approval.origin`({@link parkRowFacts})。活卡帧**不经**本函数:它读引擎在门上刚盖好的
|
|
431
456
|
* `AskRequest.origin`(盖章点即 core 的筛点),照旧只过「非空串」形门(`tool-approval.ts` 帧键 `origin` 顶注)。
|
|
457
|
+
* · `classifierNoRuling`(core 7.43.0 #1353)—— 分类器没给判词的成因词,core `AUTO_MODE_FALLBACK_CAUSES` 闭集一词(筛 = `isAutoModeFallbackCause`)。
|
|
458
|
+
* 读者:活卡帧读 `AskRequest.classifierNoRuling`(`tool-approval.ts`);inbox 行读 core `CheckpointSummary` 已筛过的同名位、直投不经本函数。
|
|
459
|
+
* · `differs`(core 7.44.0 #1374)—— **载体是引擎拒 steer 重放那只错的 `detail`**(不是 ask 的三个载体之一),值是 core `STEER_REPLAY_FACETS` 的**非空子集**
|
|
460
|
+
* (core:「恒非空」;筛 = 本文件 {@link isSteerReplayDiffers},成员表取 core 常量)。读者:`runs.ts` 的 409 `steering.duplicate_input_id` 体(`detail.differs`)。
|
|
461
|
+
* 集外成员 / 空数组 / 非数组 ⇒ 按缺席(不铸 `detail`,码仍是契约)+ 计一次;detail 只报形名(`differs=<array>` —— 数组从不展开成员,见 {@link outOfSetDetail})。
|
|
432
462
|
*
|
|
433
463
|
* 什么时候经本函数 —— 一句话:**筛点在 core;server 只在「读的是持久层原字节、中间没有 core 投影」的地方亲手调 core 的那一只筛**。
|
|
434
464
|
* inbox 行读 core `CheckpointSummary.{mandate,origin}`(core `summarizeCheckpoint` 已用同一只 `isPersistedRuleMandate` / `isAskOrigin`
|
|
@@ -442,10 +472,12 @@ type ToolApprovalPark = Extract<CorePendingAction, {
|
|
|
442
472
|
* 只读值不调用值)。
|
|
443
473
|
*/
|
|
444
474
|
export declare function readClosedWordSeat<S extends ClosedWordSeat>(carrier: object, seat: S): ClosedWordOf<S> | undefined;
|
|
445
|
-
/**
|
|
446
|
-
type
|
|
447
|
-
/**
|
|
448
|
-
type
|
|
475
|
+
/** ask 载体上的闭集词座名:三个 core 载体上**同名**(`AskRequest` / 寄存行 `tool_approval` 臂 / `CheckpointSummary`)—— 任一处改名 / 退役 ⇒ 下面的围栏编译红。 */
|
|
476
|
+
type AskClosedWordSeat = "mandate" | "origin" | "classifierNoRuling";
|
|
477
|
+
/** 闭集词座的名 = ask 载体上的三座 + 引擎拒 steer 重放那只错的 `detail.differs`(载体不同、读法同一只)。 */
|
|
478
|
+
type ClosedWordSeat = AskClosedWordSeat | "differs";
|
|
479
|
+
/** 一座的值型:ask 三座 = core 寄存行上那一座的型(去掉可选位的 `undefined`);`differs` = core 闭集 `SteerReplayFacet` 的数组(core `detail.differs` 的型)。 */
|
|
480
|
+
type ClosedWordOf<S extends ClosedWordSeat> = S extends AskClosedWordSeat ? NonNullable<ToolApprovalPark[S]> : readonly SteerReplayFacet[];
|
|
449
481
|
/**
|
|
450
482
|
* 🔴 **S-934 ②(core 7.37.0 #1214)—— ask 类对的唯一窄读**:`askClass`(一问的类 = `classes` 的首员)与 `classes`(这一问属于的全部类,core
|
|
451
483
|
* `ASK_CLASSES` 序)。三个载体上同名:`AskRequest`(活卡帧 / 呈卡帧的卡读它)、寄存行 `PendingAction.tool_approval`(运维队列行经
|
|
@@ -568,16 +600,28 @@ export declare const ApprovalCardSchema: z.ZodObject<{
|
|
|
568
600
|
governanceForced: z.ZodOptional<z.ZodLiteral<true>>;
|
|
569
601
|
rememberRefused: z.ZodOptional<z.ZodLiteral<true>>;
|
|
570
602
|
inputHasBidi: z.ZodOptional<z.ZodLiteral<true>>;
|
|
571
|
-
|
|
603
|
+
allowRuleShadowed: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
604
|
+
member: z.ZodEnum<{
|
|
605
|
+
hook: "hook";
|
|
606
|
+
skill: "skill";
|
|
607
|
+
deployment: "deployment";
|
|
608
|
+
request: "request";
|
|
609
|
+
persisted: "persisted";
|
|
610
|
+
}>;
|
|
611
|
+
entries: z.ZodArray<z.ZodString>;
|
|
612
|
+
omitted: z.ZodOptional<z.ZodNumber>;
|
|
613
|
+
}, z.core.$strict>>>;
|
|
572
614
|
ruleOffers: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
573
615
|
kind: z.ZodLiteral<"single">;
|
|
574
616
|
rule: z.ZodString;
|
|
575
617
|
match: z.ZodEnum<{
|
|
618
|
+
name: "name";
|
|
576
619
|
path: "path";
|
|
577
620
|
exact: "exact";
|
|
578
621
|
prefix: "prefix";
|
|
579
622
|
wildcard: "wildcard";
|
|
580
623
|
subpath: "subpath";
|
|
624
|
+
name_prefix: "name_prefix";
|
|
581
625
|
}>;
|
|
582
626
|
command: z.ZodString;
|
|
583
627
|
}, z.core.$strict>, z.ZodObject<{
|
|
@@ -586,11 +630,13 @@ export declare const ApprovalCardSchema: z.ZodObject<{
|
|
|
586
630
|
kind: z.ZodLiteral<"command">;
|
|
587
631
|
rule: z.ZodString;
|
|
588
632
|
match: z.ZodEnum<{
|
|
633
|
+
name: "name";
|
|
589
634
|
path: "path";
|
|
590
635
|
exact: "exact";
|
|
591
636
|
prefix: "prefix";
|
|
592
637
|
wildcard: "wildcard";
|
|
593
638
|
subpath: "subpath";
|
|
639
|
+
name_prefix: "name_prefix";
|
|
594
640
|
}>;
|
|
595
641
|
command: z.ZodString;
|
|
596
642
|
segment: z.ZodString;
|
|
@@ -649,8 +695,8 @@ export declare const ApprovalCardSchema: z.ZodObject<{
|
|
|
649
695
|
}, z.core.$strict>>>;
|
|
650
696
|
personalRuleDotsAbsent: z.ZodOptional<z.ZodCustom<AskEvidenceAbsence, AskEvidenceAbsence>>;
|
|
651
697
|
}, z.core.$strict>>;
|
|
652
|
-
askClass: z.ZodOptional<z.ZodCustom<"mode" | "hook" | "org_rule" | "write_protection" | "write_protection_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "unverifiable_delete" | "transcript_write" | "governance_unavailable" | "rule_unreadable" | "requires_user_interaction" | "operator_forced" | "shell_floor" | "probe" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary", "mode" | "hook" | "org_rule" | "write_protection" | "write_protection_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "unverifiable_delete" | "transcript_write" | "governance_unavailable" | "rule_unreadable" | "requires_user_interaction" | "operator_forced" | "shell_floor" | "probe" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary">>;
|
|
653
|
-
classes: z.ZodOptional<z.ZodArray<z.ZodCustom<"mode" | "hook" | "org_rule" | "write_protection" | "write_protection_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "unverifiable_delete" | "transcript_write" | "governance_unavailable" | "rule_unreadable" | "requires_user_interaction" | "operator_forced" | "shell_floor" | "probe" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary", "mode" | "hook" | "org_rule" | "write_protection" | "write_protection_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "unverifiable_delete" | "transcript_write" | "governance_unavailable" | "rule_unreadable" | "requires_user_interaction" | "operator_forced" | "shell_floor" | "probe" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary">>>;
|
|
698
|
+
askClass: z.ZodOptional<z.ZodCustom<"mode" | "hook" | "org_rule" | "write_protection" | "write_protection_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "unverifiable_delete" | "transcript_write" | "governance_unavailable" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "operator_forced" | "shell_floor" | "probe" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary", "mode" | "hook" | "org_rule" | "write_protection" | "write_protection_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "unverifiable_delete" | "transcript_write" | "governance_unavailable" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "operator_forced" | "shell_floor" | "probe" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary">>;
|
|
699
|
+
classes: z.ZodOptional<z.ZodArray<z.ZodCustom<"mode" | "hook" | "org_rule" | "write_protection" | "write_protection_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "unverifiable_delete" | "transcript_write" | "governance_unavailable" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "operator_forced" | "shell_floor" | "probe" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary", "mode" | "hook" | "org_rule" | "write_protection" | "write_protection_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "unverifiable_delete" | "transcript_write" | "governance_unavailable" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "operator_forced" | "shell_floor" | "probe" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary">>>;
|
|
654
700
|
fromSubagent: z.ZodOptional<z.ZodLiteral<true>>;
|
|
655
701
|
sourceTaskId: z.ZodOptional<z.ZodString>;
|
|
656
702
|
sourceAgentName: z.ZodOptional<z.ZodString>;
|
|
@@ -684,16 +730,28 @@ export declare const ApprovalCardEnvelopeSchema: z.ZodObject<{
|
|
|
684
730
|
governanceForced: z.ZodOptional<z.ZodLiteral<true>>;
|
|
685
731
|
rememberRefused: z.ZodOptional<z.ZodLiteral<true>>;
|
|
686
732
|
inputHasBidi: z.ZodOptional<z.ZodLiteral<true>>;
|
|
687
|
-
|
|
733
|
+
allowRuleShadowed: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
734
|
+
member: z.ZodEnum<{
|
|
735
|
+
hook: "hook";
|
|
736
|
+
skill: "skill";
|
|
737
|
+
deployment: "deployment";
|
|
738
|
+
request: "request";
|
|
739
|
+
persisted: "persisted";
|
|
740
|
+
}>;
|
|
741
|
+
entries: z.ZodArray<z.ZodString>;
|
|
742
|
+
omitted: z.ZodOptional<z.ZodNumber>;
|
|
743
|
+
}, z.core.$strict>>>;
|
|
688
744
|
ruleOffers: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
689
745
|
kind: z.ZodLiteral<"single">;
|
|
690
746
|
rule: z.ZodString;
|
|
691
747
|
match: z.ZodEnum<{
|
|
748
|
+
name: "name";
|
|
692
749
|
path: "path";
|
|
693
750
|
exact: "exact";
|
|
694
751
|
prefix: "prefix";
|
|
695
752
|
wildcard: "wildcard";
|
|
696
753
|
subpath: "subpath";
|
|
754
|
+
name_prefix: "name_prefix";
|
|
697
755
|
}>;
|
|
698
756
|
command: z.ZodString;
|
|
699
757
|
}, z.core.$strict>, z.ZodObject<{
|
|
@@ -702,11 +760,13 @@ export declare const ApprovalCardEnvelopeSchema: z.ZodObject<{
|
|
|
702
760
|
kind: z.ZodLiteral<"command">;
|
|
703
761
|
rule: z.ZodString;
|
|
704
762
|
match: z.ZodEnum<{
|
|
763
|
+
name: "name";
|
|
705
764
|
path: "path";
|
|
706
765
|
exact: "exact";
|
|
707
766
|
prefix: "prefix";
|
|
708
767
|
wildcard: "wildcard";
|
|
709
768
|
subpath: "subpath";
|
|
769
|
+
name_prefix: "name_prefix";
|
|
710
770
|
}>;
|
|
711
771
|
command: z.ZodString;
|
|
712
772
|
segment: z.ZodString;
|
|
@@ -765,8 +825,8 @@ export declare const ApprovalCardEnvelopeSchema: z.ZodObject<{
|
|
|
765
825
|
}, z.core.$strict>>>;
|
|
766
826
|
personalRuleDotsAbsent: z.ZodOptional<z.ZodCustom<AskEvidenceAbsence, AskEvidenceAbsence>>;
|
|
767
827
|
}, z.core.$strict>>;
|
|
768
|
-
askClass: z.ZodOptional<z.ZodCustom<"mode" | "hook" | "org_rule" | "write_protection" | "write_protection_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "unverifiable_delete" | "transcript_write" | "governance_unavailable" | "rule_unreadable" | "requires_user_interaction" | "operator_forced" | "shell_floor" | "probe" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary", "mode" | "hook" | "org_rule" | "write_protection" | "write_protection_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "unverifiable_delete" | "transcript_write" | "governance_unavailable" | "rule_unreadable" | "requires_user_interaction" | "operator_forced" | "shell_floor" | "probe" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary">>;
|
|
769
|
-
classes: z.ZodOptional<z.ZodArray<z.ZodCustom<"mode" | "hook" | "org_rule" | "write_protection" | "write_protection_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "unverifiable_delete" | "transcript_write" | "governance_unavailable" | "rule_unreadable" | "requires_user_interaction" | "operator_forced" | "shell_floor" | "probe" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary", "mode" | "hook" | "org_rule" | "write_protection" | "write_protection_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "unverifiable_delete" | "transcript_write" | "governance_unavailable" | "rule_unreadable" | "requires_user_interaction" | "operator_forced" | "shell_floor" | "probe" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary">>>;
|
|
828
|
+
askClass: z.ZodOptional<z.ZodCustom<"mode" | "hook" | "org_rule" | "write_protection" | "write_protection_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "unverifiable_delete" | "transcript_write" | "governance_unavailable" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "operator_forced" | "shell_floor" | "probe" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary", "mode" | "hook" | "org_rule" | "write_protection" | "write_protection_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "unverifiable_delete" | "transcript_write" | "governance_unavailable" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "operator_forced" | "shell_floor" | "probe" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary">>;
|
|
829
|
+
classes: z.ZodOptional<z.ZodArray<z.ZodCustom<"mode" | "hook" | "org_rule" | "write_protection" | "write_protection_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "unverifiable_delete" | "transcript_write" | "governance_unavailable" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "operator_forced" | "shell_floor" | "probe" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary", "mode" | "hook" | "org_rule" | "write_protection" | "write_protection_unresolved" | "content_question" | "ask_rule" | "denial_limit_fallback" | "ancestor" | "unverifiable_delete" | "transcript_write" | "governance_unavailable" | "rule_unreadable" | "classifier_no_ruling" | "requires_user_interaction" | "operator_forced" | "shell_floor" | "probe" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary">>>;
|
|
770
830
|
fromSubagent: z.ZodOptional<z.ZodLiteral<true>>;
|
|
771
831
|
sourceTaskId: z.ZodOptional<z.ZodString>;
|
|
772
832
|
sourceAgentName: z.ZodOptional<z.ZodString>;
|
|
@@ -807,9 +867,6 @@ export interface ApprovalCardSource {
|
|
|
807
867
|
/** E-14:bidi 在场位 —— 与 wire 帧**同一份素材**(`ToolApprovalFrame` 结构上满足本接口)⇒ live 帧 /
|
|
808
868
|
* `approval_request` / `card_json` / 重放帧四面同源,不是四处各扫一遍。 */
|
|
809
869
|
inputHasBidi?: true;
|
|
810
|
-
/** [ref](core 5.25.0):被越级的持久规则原文 —— **已 redactSecrets**(发帧点做,本模块只 clip)。
|
|
811
|
-
* 与 wire 帧**同一份素材**(`ToolApprovalFrame` 结构上满足本接口)⇒ live 帧 / `card_json` / 重放帧三面同源。 */
|
|
812
|
-
persistedRuleShadowed?: string;
|
|
813
870
|
/** [ref](core 5.58.0):引擎铸的「不再询问」OFFER(**只在规则店装配时**由发帧点填;语义与在场性契约见
|
|
814
871
|
* `ApprovalCardSchema.ruleOffers`)。与 wire 帧**同一份素材** ⇒ live 帧 / `card_json` / 重放帧
|
|
815
872
|
* 三面同源。 */
|
|
@@ -942,6 +999,13 @@ export declare function buildRevokeFrame(batchId: string, askIds: readonly strin
|
|
|
942
999
|
* 竞争者;收敛是车2 的窗到期竞争者与车5 恢复扫描的职责)。
|
|
943
1000
|
*/
|
|
944
1001
|
export declare function buildReplayFrame(row: AskRow, nowMs: number): ApprovalRequestFrame | undefined;
|
|
1002
|
+
/**
|
|
1003
|
+
* S-1154 —— 持久行上那张卡**要不要人**:卡面 `risk.requiresRealApproval`(铸卡时取自引擎在 `AskRequest` 上盖的同一位,
|
|
1004
|
+
* {@link buildApprovalCard} 第三参)。读者 = 耐久 ask 回决口在裁决之前判「策略的放行」(`host-decision.ts` 的 `policyCannotAllow`)。
|
|
1005
|
+
* 🔴 读不出卡(`card_json` 形不合)⇒ **按要人读**(fail-closed):这一位只用来**拒**策略的放行,读坏的行上拒一次可以改成人答 / 策略拒
|
|
1006
|
+
* 再来;反方向(读坏当不要人)会让一次引擎终将拒掉的放行先落成一条宣称 approve 的行。
|
|
1007
|
+
*/
|
|
1008
|
+
export declare function storedCardDemandsAPerson(cardJson: unknown): boolean;
|
|
945
1009
|
/** {@link buildApprovalPreamble} 的返回形——帧 + 两个**计数**(调用方按自己的 logger 记 warn;本模块
|
|
946
1010
|
* 保持纯函数,不吃 logger:那会让一个 `build*` 捕获行为)。 */
|
|
947
1011
|
export interface ApprovalPreamble {
|
package/dist/approval-card.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { ASK_EVIDENCE_ABSENCE_VALUES, MAX_RULE_TEXT_CHARS, READ_ROOT_CANDIDATE_DIR_MAX, isAskClass, isAskOrigin, isPersistedRuleMandate, screenAskClassMembers } from "@sema-agent/core";
|
|
2
|
+
import { ALLOW_RULE_MEMBERS, ASK_EVIDENCE_ABSENCE_VALUES, MAX_RULE_TEXT_CHARS, READ_ROOT_CANDIDATE_DIR_MAX, STEER_REPLAY_FACETS, isAskClass, isAskOrigin, isAutoModeFallbackCause, isPersistedRuleMandate, screenAskClassMembers } from "@sema-agent/core";
|
|
3
3
|
import { redactSecrets } from "./trace/redact.js";
|
|
4
4
|
import { recordFailOpen } from "./observability/fail-open.js";
|
|
5
5
|
import { PERSISTED_RULE_MATCHES, UNCOVERED_SEGMENT_REASONS } from "./permission-rule-vocab.js";
|
|
@@ -211,6 +211,28 @@ const RuleEvidenceEnvelopeSchema = z.object({
|
|
|
211
211
|
})
|
|
212
212
|
.optional(),
|
|
213
213
|
});
|
|
214
|
+
export const MAX_ALLOW_RULE_SHADOW_ENTRIES = 32;
|
|
215
|
+
const ALLOW_RULE_MEMBER_SET = new Set(ALLOW_RULE_MEMBERS);
|
|
216
|
+
export function readAllowRuleShadowed(req) {
|
|
217
|
+
const raw = req !== null && typeof req === "object" ? req.allowRuleShadowed : undefined;
|
|
218
|
+
if (!Array.isArray(raw) || raw.length === 0 || raw.length > ALLOW_RULE_MEMBERS.length)
|
|
219
|
+
return undefined;
|
|
220
|
+
const list = raw;
|
|
221
|
+
const out = [];
|
|
222
|
+
for (const r of list) {
|
|
223
|
+
if (r === null || typeof r !== "object")
|
|
224
|
+
return undefined;
|
|
225
|
+
const { member, entries, omitted } = r;
|
|
226
|
+
if (!ALLOW_RULE_MEMBER_SET.has(member) || !Array.isArray(entries) || !entries.every((e) => typeof e === "string"))
|
|
227
|
+
return undefined;
|
|
228
|
+
if (omitted !== undefined && !(typeof omitted === "number" && Number.isInteger(omitted) && omitted > 0))
|
|
229
|
+
return undefined;
|
|
230
|
+
const shown = entries.slice(0, MAX_ALLOW_RULE_SHADOW_ENTRIES).map((e) => redactSecrets(e).slice(0, MAX_RULE_TEXT_CHARS));
|
|
231
|
+
const extra = entries.length - shown.length + (omitted ?? 0);
|
|
232
|
+
out.push({ member: member, entries: shown, ...(extra > 0 ? { omitted: extra } : {}) });
|
|
233
|
+
}
|
|
234
|
+
return out;
|
|
235
|
+
}
|
|
214
236
|
export function readRuleEvidence(req) {
|
|
215
237
|
const parsed = RuleEvidenceEnvelopeSchema.safeParse(req);
|
|
216
238
|
const raw = parsed.success ? parsed.data.ruleEvidence : undefined;
|
|
@@ -292,9 +314,15 @@ export function readClosedWordSeat(carrier, seat) {
|
|
|
292
314
|
recordFailOpen("server.approval-card.closed-word-out-of-set", `${seat}=${outOfSetDetail(raw)}`);
|
|
293
315
|
return undefined;
|
|
294
316
|
}
|
|
317
|
+
function isSteerReplayDiffers(v) {
|
|
318
|
+
const facets = STEER_REPLAY_FACETS;
|
|
319
|
+
return Array.isArray(v) && v.length > 0 && v.every((f) => facets.includes(f));
|
|
320
|
+
}
|
|
295
321
|
const CLOSED_WORD_SEAT_GUARDS = {
|
|
296
322
|
mandate: isPersistedRuleMandate,
|
|
297
323
|
origin: isAskOrigin,
|
|
324
|
+
classifierNoRuling: isAutoModeFallbackCause,
|
|
325
|
+
differs: isSteerReplayDiffers,
|
|
298
326
|
};
|
|
299
327
|
export function readAskClassPair(carrier) {
|
|
300
328
|
const askClass = "askClass" in carrier ? carrier.askClass : undefined;
|
|
@@ -356,7 +384,17 @@ export const ApprovalCardSchema = z
|
|
|
356
384
|
governanceForced: z.literal(true).optional(),
|
|
357
385
|
rememberRefused: z.literal(true).optional(),
|
|
358
386
|
inputHasBidi: z.literal(true).optional(),
|
|
359
|
-
|
|
387
|
+
allowRuleShadowed: z
|
|
388
|
+
.array(z
|
|
389
|
+
.object({
|
|
390
|
+
member: z.enum(ALLOW_RULE_MEMBERS),
|
|
391
|
+
entries: z.array(z.string().max(MAX_RULE_TEXT_CHARS)).max(MAX_ALLOW_RULE_SHADOW_ENTRIES),
|
|
392
|
+
omitted: z.number().int().positive().optional(),
|
|
393
|
+
})
|
|
394
|
+
.strict())
|
|
395
|
+
.min(1)
|
|
396
|
+
.max(ALLOW_RULE_MEMBERS.length)
|
|
397
|
+
.optional(),
|
|
360
398
|
ruleOffers: z.array(RuleOfferSchema).max(MAX_RULE_OFFERS).optional(),
|
|
361
399
|
ruleOffersAbsence: RuleOffersAbsenceSchema.optional(),
|
|
362
400
|
denialLimitFallback: DenialLimitFallbackSchema.optional(),
|
|
@@ -416,7 +454,7 @@ export function buildApprovalCard(source, req, requiresRealApproval) {
|
|
|
416
454
|
const toolCallId = clip(source.toolCallId, MAX_IDENT);
|
|
417
455
|
const sourceTaskId = clip(source.sourceTaskId, MAX_IDENT);
|
|
418
456
|
const sourceAgentName = clip(source.sourceAgentName, MAX_AGENT_NAME);
|
|
419
|
-
const
|
|
457
|
+
const allowRuleShadowed = readAllowRuleShadowed(req);
|
|
420
458
|
return {
|
|
421
459
|
toolName: clip(source.toolName, MAX_IDENT) ?? "",
|
|
422
460
|
message: clip(source.message, MAX_MESSAGE) ?? "",
|
|
@@ -430,7 +468,7 @@ export function buildApprovalCard(source, req, requiresRealApproval) {
|
|
|
430
468
|
...(source.governanceForced === true ? { governanceForced: true } : {}),
|
|
431
469
|
...(source.rememberRefused === true ? { rememberRefused: true } : {}),
|
|
432
470
|
...(source.inputHasBidi === true ? { inputHasBidi: true } : {}),
|
|
433
|
-
...(
|
|
471
|
+
...(allowRuleShadowed !== undefined ? { allowRuleShadowed } : {}),
|
|
434
472
|
...(probeCause !== undefined ? { probeCause } : {}),
|
|
435
473
|
...(ruleEvidence !== undefined ? { ruleEvidence } : {}),
|
|
436
474
|
...(source.ruleOffers !== undefined && source.ruleOffers.length > 0 ? { ruleOffers: source.ruleOffers.map(copyRuleOffer) } : {}),
|
|
@@ -488,6 +526,10 @@ export function buildReplayFrame(row, nowMs) {
|
|
|
488
526
|
approvalId: parsed.data.approvalId,
|
|
489
527
|
};
|
|
490
528
|
}
|
|
529
|
+
export function storedCardDemandsAPerson(cardJson) {
|
|
530
|
+
const parsed = ApprovalCardEnvelopeSchema.safeParse(cardJson);
|
|
531
|
+
return !parsed.success || parsed.data.card.risk.requiresRealApproval;
|
|
532
|
+
}
|
|
491
533
|
export function buildApprovalPreamble(rows, nowMs, replayMax) {
|
|
492
534
|
const frames = [];
|
|
493
535
|
let skipped = 0;
|
package/dist/approval.d.ts
CHANGED
|
@@ -52,7 +52,7 @@ export declare function singleUserAutoAcceptBaselineApplies(config: GateIntentVi
|
|
|
52
52
|
readonly requirePrincipal: boolean;
|
|
53
53
|
}): boolean;
|
|
54
54
|
/**
|
|
55
|
-
* 门意图**不可服务**的判据 —— 返回拒因(可服务 ⇒ `undefined`)
|
|
55
|
+
* 门意图**不可服务**的判据 —— 返回拒因(可服务 ⇒ `undefined`)。**全仓唯一一份**,三处调用、处置不同:
|
|
56
56
|
* · **boot**(`boot/stage-07-capability-layer.ts`):对装配完的整份 config 判,拒因 ⇒ **拒启**(全窗复审 D3-F1,
|
|
57
57
|
* HIGH;与 env 墓碑族同谱系)。v4.3.0 的轮询门形(APPROVAL_REQUIRE + DB backend + DURABLE_APPROVAL 未设)在
|
|
58
58
|
* 5.0.0 只剩 core 每任务 warn——**原先拦、现在放**(方向反转)。「留 undefined 让 core warn」对新配置是
|
|
@@ -60,6 +60,9 @@ export declare function singleUserAutoAcceptBaselineApplies(config: GateIntentVi
|
|
|
60
60
|
* · **热路径**(S-668 波 2 ④,`config-center/apply-effective.ts` 的审批组 stage):对**候选视图**
|
|
61
61
|
* (活配置 + 候选名单)判,拒因 ⇒ 审批组**整组拒**、活配置零变化、世代账停旧代。进程在跑,拒启不是选项;
|
|
62
62
|
* 而放行一份「没有 checkpoint 店可停车」的名单 = 单用户 auto-accept 基线仍在、名单静默不生效。
|
|
63
|
+
* · **每个任务的装配**(S-1144,`boot/resolve-spec.ts` 的 `resolveSpec` 头一道):对**活配置**判,拒因 ⇒ 请求 501
|
|
64
|
+
* `capability.checkpoint_store_required`。部署形到不了(boot 已拒启);可达的是嵌入方装配 / 直调 `resolveSpec`(自己递 ctx、没经 stage-07)。
|
|
65
|
+
* 修前这一形把审批基线静默铸成 `undefined`,请求的 allow 清「普通问」后任务零卡落盘 —— 同一条规则在起服层拒、在装配层静默 = 一事两读。
|
|
63
66
|
* `checkpointStorePresent` 是**部署事实**(本进程建没建出 checkpoint 店),不在 `ServiceConfig` 里 ⇒ 调用方显式递。
|
|
64
67
|
* 放这文件与 hasOperatorGateIntent/inv#2 同源(意图判据再漂要同时改两段)。
|
|
65
68
|
*/
|
|
@@ -134,17 +137,6 @@ export interface DurableAskOptions {
|
|
|
134
137
|
deny?: string[];
|
|
135
138
|
autoBudget?: number;
|
|
136
139
|
neverAuto?: string[];
|
|
137
|
-
/** Per-session approval-exemption probe ("本会话不再询问"): consulted ONLY for require-listed
|
|
138
|
-
* tools, AFTER deny/neverAuto (both always win) and BEFORE the budget path. Canonical-space toolName.
|
|
139
|
-
* A rejected promise is treated as NOT exempt (fail-closed → ask) at the call site below.
|
|
140
|
-
* 🔴 S-877 候裁 16:会话授权**两个读位、一只店、按问句的作者分**(收车档 ⑩ 16):本探针兑现**本仓自己的问**(名单门)
|
|
141
|
-
* —— 在它自己的层上「不问」,于是委派子代经父约束链继承到的同一问也不问;引擎自装的问(模式写门 / 形状层)由审批席
|
|
142
|
-
* (`ToolApprovalCoordinator.standingGrantSettles`)兑现。本探针**不能**退役:子代的继承问到达祖先审批席时 core 盖
|
|
143
|
-
* `mandated`(`ruleClearanceOf` 的 inheritedUnresolved / ancestorResolved 门),席的判据依约不退役它 —— 只有本层的
|
|
144
|
-
* 「不问」够得着继承链(钉 test/parked-decide-leg.test.ts「[候裁② 修]remember 全链行为」)。 */
|
|
145
|
-
exempt?: (canonicalToolName: string) => Promise<boolean>;
|
|
146
|
-
/** Audit hook — fired when an exemption short-circuits the ask (the `approval_exempted` log line). */
|
|
147
|
-
onExempted?: (canonicalToolName: string, rawToolName: string) => void;
|
|
148
140
|
}
|
|
149
141
|
export declare function createDurableAskPolicy(opts: DurableAskOptions): ToolPolicy;
|
|
150
142
|
//# sourceMappingURL=approval.d.ts.map
|
package/dist/approval.js
CHANGED
|
@@ -4,7 +4,6 @@ import { ASK_USER_QUESTION_TOOL_NAME } from "./approval-content-kind.js";
|
|
|
4
4
|
import { isExplicitPosture } from "./posture-source.js";
|
|
5
5
|
import { handsOnWorkerFilePlane } from "./execution-lane-caps.js";
|
|
6
6
|
import { heldRuleName } from "./tool-rule-names.js";
|
|
7
|
-
import { answerGrantsBeyondCall } from "./standing-answer-grant.js";
|
|
8
7
|
export function hasApprovalListIntent(config) {
|
|
9
8
|
return (config.approvalRequire.length > 0 ||
|
|
10
9
|
config.approvalDeny.length > 0 ||
|
|
@@ -93,33 +92,12 @@ export function createDurableAskPolicy(opts) {
|
|
|
93
92
|
if (neverAutoHit !== undefined)
|
|
94
93
|
return operatorAlwaysHumanAsk(`APPROVAL_NEVER_AUTO(${neverAutoHit})`, `human approval required to run "${req.toolName}"`);
|
|
95
94
|
const requireHit = heldRuleName(req, require);
|
|
96
|
-
if (requireHit !== undefined)
|
|
97
|
-
|
|
98
|
-
if (remEarly !== undefined && remEarly <= 0) {
|
|
99
|
-
return operatorAlwaysHumanAsk("RESOURCE_SUSPEND budget exhausted", `durable resource budget exhausted — human approval required to run "${req.toolName}"`);
|
|
100
|
-
}
|
|
101
|
-
if (opts.exempt && heldRuleName(req, isQuestionTool) === undefined && !answerGrantsBeyondCall(req)) {
|
|
102
|
-
return (async () => {
|
|
103
|
-
let exempted = false;
|
|
104
|
-
try {
|
|
105
|
-
exempted = (await opts.exempt(req.toolName)) === true;
|
|
106
|
-
}
|
|
107
|
-
catch {
|
|
108
|
-
exempted = false;
|
|
109
|
-
}
|
|
110
|
-
if (exempted) {
|
|
111
|
-
opts.onExempted?.(req.toolName, req.toolName);
|
|
112
|
-
return grantedByRule();
|
|
113
|
-
}
|
|
114
|
-
return decideRequired(req, requireHit);
|
|
115
|
-
})();
|
|
116
|
-
}
|
|
117
|
-
return decideRequired(req, requireHit);
|
|
118
|
-
}
|
|
95
|
+
if (requireHit !== undefined)
|
|
96
|
+
return decideRequired(req, operatorAsk(`APPROVAL_REQUIRE(${requireHit})`, `approval required to run "${req.toolName}"`));
|
|
119
97
|
return { action: "allow" };
|
|
120
98
|
},
|
|
121
99
|
};
|
|
122
|
-
function decideRequired(req,
|
|
100
|
+
function decideRequired(req, ask) {
|
|
123
101
|
const rem = req.budget?.resourceRemainingMicroUsd;
|
|
124
102
|
if (rem !== undefined && rem <= 0) {
|
|
125
103
|
return operatorAlwaysHumanAsk("RESOURCE_SUSPEND budget exhausted", `durable resource budget exhausted — human approval required to run "${req.toolName}"`);
|
|
@@ -128,7 +106,7 @@ export function createDurableAskPolicy(opts) {
|
|
|
128
106
|
autoApproved++;
|
|
129
107
|
return grantedByRule();
|
|
130
108
|
}
|
|
131
|
-
return
|
|
109
|
+
return ask;
|
|
132
110
|
}
|
|
133
111
|
}
|
|
134
112
|
//# sourceMappingURL=approval.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createBrainAssembly } from "../brain.js";
|
|
2
2
|
import { ModelUsageTracker, PromptManifestTracker, buildPricing, createSideQueryAccountant, createTracer } from "../budget.js";
|
|
3
3
|
import { FleetUsageAccumulator } from "../fleet-client.js";
|
|
4
4
|
import { createFleetLeaseFromEnv } from "../fleet-lease.js";
|
|
@@ -8,8 +8,7 @@ import { buildQuotaBounds } from "./limit-sync.js";
|
|
|
8
8
|
import { assembleFileHistory } from "../file-history-capture.js";
|
|
9
9
|
export function createBudgetAndTracing(ctx) {
|
|
10
10
|
const { config, logger, metrics, backend, breakerState } = ctx;
|
|
11
|
-
const brain =
|
|
12
|
-
const degradeRouteWatch = createDegradeRouteWatch(config);
|
|
11
|
+
const { brain, degradeRoute: degradeRouteWatch } = createBrainAssembly(config, { breakerState });
|
|
13
12
|
const pricing = buildPricing(config.models);
|
|
14
13
|
const counterDegradeHook = (info) => {
|
|
15
14
|
metrics.setGauge("counter_flush_fail_streak", info.streak, { table: info.table, kind: info.kind });
|
|
@@ -63,8 +63,8 @@ export interface ConfigCenterRuntime {
|
|
|
63
63
|
* CLI 之后不再有刷新拍,它继续用纯判据判一次)。
|
|
64
64
|
* `consolidationSeat`(S-668 波 0,过渡)= 整理驱动席的两侧读数口,喂 `memory-consolidation` 重启片;
|
|
65
65
|
* 缺席 = 阀门关着(没有 boot 烤死的席)。
|
|
66
|
-
* `degradeRoute`(S-794,**必填**)= 反应式降级壳的两侧读数口(brain.ts `
|
|
67
|
-
*
|
|
66
|
+
* `degradeRoute`(S-794,**必填**)= 反应式降级壳的两侧读数口(brain.ts `createBrainAssembly` 的产物 `degradeRoute`,`baked` 在焊壳处
|
|
67
|
+
* 算好随装配交出),喂 `degrade-route` 重启片。必填而不是可选:车道没开 / 没焊壳由席自己答「两侧同为 null」,缺席没有合法含义 ——
|
|
68
68
|
* 可选就是一条「接线漏了 ⇒ 片永远不签」的静默路([ref])。
|
|
69
69
|
* `checkpointStorePresent`(S-668 波 2,**必填**)= 部署事实「本进程建没建出 checkpoint 店」(stage-06 的产物,
|
|
70
70
|
* 不在 ServiceConfig 里)。审批名单转热之后,热腿要用它判 ④「门意图不可服务」(与 boot 拒启同一只判据);
|
|
@@ -19,7 +19,7 @@ import { centerManagedConfigKeys } from "../config-center/apply-effective.js";
|
|
|
19
19
|
import { createConfigProvider, raceBootFetch, serviceConfigSourceKind, BOOT_FETCH_DEFERRED } from "../config-provider.js";
|
|
20
20
|
import { createKeyResolver } from "../key-resolver.js";
|
|
21
21
|
import { buildSealedKeyPublicFace, ensureSealedKeyStore, reportExecutionPublicKey } from "../sealed-key.js";
|
|
22
|
-
import { applyEffective, applyCenterReadFace, mutateInPlace, logEffectiveDiff, applyCenterSkills, resolveMcpServers, resolveA2aPeers, restartReasons, modelPlaneChanged, withModelPlaneOf,
|
|
22
|
+
import { applyEffective, applyCenterReadFace, mutateInPlace, logEffectiveDiff, applyCenterSkills, resolveMcpServers, resolveA2aPeers, restartReasons, modelPlaneChanged, withModelPlaneOf, fullyLandedForLkg, fetchPromptArtifact } from "../config-center/facade.js";
|
|
23
23
|
import { createMcpRevocationLedger, enabledMcpEntries } from "../config-center/mcp-revocation.js";
|
|
24
24
|
import { SHA256_HEX_RE } from "../digest-form.js";
|
|
25
25
|
import { BOOT_REJUDGE_OF_REFUSED_GROUP, createConfigApplyLedger, modelPlaneCommitted, refusedGroups } from "../config-center/apply-ledger.js";
|
|
@@ -422,7 +422,7 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
422
422
|
const lkgPlane = modelPlaneCommitted(lkgReport);
|
|
423
423
|
if (lkgPlane)
|
|
424
424
|
markRosterLanded(lkgR.effective);
|
|
425
|
-
effective =
|
|
425
|
+
effective = lkgR.effective;
|
|
426
426
|
if (lkgPlane)
|
|
427
427
|
appliedPlaneEff = lkgR.effective;
|
|
428
428
|
if (fullyLandedForLkg(lkgR, lkgReport)) {
|
|
@@ -504,7 +504,7 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
504
504
|
}
|
|
505
505
|
if (bootPlaneEff !== undefined)
|
|
506
506
|
markRosterLanded(bootPlaneEff);
|
|
507
|
-
effective =
|
|
507
|
+
effective = r.effective;
|
|
508
508
|
if (bootPlaneEff !== undefined)
|
|
509
509
|
appliedPlaneEff = bootPlaneEff;
|
|
510
510
|
if (bootClean)
|
|
@@ -858,8 +858,7 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
858
858
|
await adoptCenterPrompts(r.effective, "refresh");
|
|
859
859
|
if (tickPlane)
|
|
860
860
|
markRosterLanded(r.effective);
|
|
861
|
-
|
|
862
|
-
if (!fullyApplied) {
|
|
861
|
+
if (!fullyLandedForLkg(r, applyReport)) {
|
|
863
862
|
ccEtag = undefined;
|
|
864
863
|
const refused = applyReport ? refusedGroups(applyReport) : [];
|
|
865
864
|
logger.warn("config_candidate_partially_applied", {
|
|
@@ -972,8 +971,7 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
972
971
|
await adoptCenterPrompts(r.effective, "boot-deferred");
|
|
973
972
|
if (latePlane)
|
|
974
973
|
markRosterLanded(r.effective);
|
|
975
|
-
|
|
976
|
-
if (!fullyAppliedLate) {
|
|
974
|
+
if (!fullyLandedForLkg(r, applyReportLate)) {
|
|
977
975
|
ccEtag = undefined;
|
|
978
976
|
const refusedLate = applyReportLate ? refusedGroups(applyReportLate) : [];
|
|
979
977
|
logger.warn("config_candidate_partially_applied", {
|
|
@@ -11,10 +11,6 @@ export interface ParkedReviveGateConfigView extends DeploymentGovernanceConfigVi
|
|
|
11
11
|
/** host 腿裁决 env 的 cwd 占位根(见下方 `hostGateCwd`)。 */
|
|
12
12
|
readonly localDataRoot?: ServiceConfig["localDataRoot"];
|
|
13
13
|
}
|
|
14
|
-
/** 会话豁免探针店的所需切面(canonical toolName 键空间;`StoreBackend.approvalExemption()` 结构满足)。 */
|
|
15
|
-
export interface ApprovalExemptionProbe {
|
|
16
|
-
has(sessionId: string, toolName: string): Promise<boolean>;
|
|
17
|
-
}
|
|
18
14
|
export interface ParkedReviveGateDeps {
|
|
19
15
|
/** ⚠️ **活引用**:热改字段(autonomy/commandPolicy/守卫集/审批四旋钮)每次赎回现读,见下方「禁 memoize」。 */
|
|
20
16
|
readonly config: ParkedReviveGateConfigView;
|
|
@@ -47,7 +43,6 @@ export interface ParkedReviveGateDeps {
|
|
|
47
43
|
* headless auto-deny,比「再问人一次」严且哑。交了之后最坏也是 park,方向 fail-safe。
|
|
48
44
|
*/
|
|
49
45
|
readonly approverSeat: RunnerDepsOnAsk | undefined;
|
|
50
|
-
readonly approvalExemptionStore: ApprovalExemptionProbe | undefined;
|
|
51
46
|
/**
|
|
52
47
|
* [ref] —— core `RunnerDeps.runtimeCapsResolver` 的**同一只**(main.ts 的 `runtimeCapsResolver`,
|
|
53
48
|
* 单一属主同 `boot/runtime-caps.ts`)。重建条目的第三位决议链元数据 `autoModeArmed` 的唯一判据是
|
|
@@ -69,7 +64,6 @@ export interface ParkedReviveGateDeps {
|
|
|
69
64
|
* 这一座可改读它 —— 接线不在本次提货单内,见 7.106.0 收车档「未闭环」。 */
|
|
70
65
|
readonly parentAutoModeIntent?: ((row: BackgroundAgentRecord) => boolean) | undefined;
|
|
71
66
|
readonly logger: {
|
|
72
|
-
info(event: string, fields?: Record<string, unknown>): void;
|
|
73
67
|
warn(event: string, fields?: Record<string, unknown>): void;
|
|
74
68
|
};
|
|
75
69
|
/** host 腿 cwd 占位的落地根(main.ts 的 `localRoot`;`config.localDataRoot` 优先)。 */
|
|
@@ -96,7 +90,7 @@ export type RebuiltParentConstraint = NonNullable<RebuiltInheritedGate["parentCo
|
|
|
96
90
|
* 赎回腿的父约束链重建([ref] 件二)。
|
|
97
91
|
*
|
|
98
92
|
* 语义:**同/跨副本一致地重建「部署 ⊇ 操作员」两层完整链**——审批基线(durable question 门 + F4 高危写
|
|
99
|
-
* 审批门
|
|
93
|
+
* 审批门)作 base 的 `toolPolicy` 座,经**折叠属主** `applyRuntimeGovernance`
|
|
100
94
|
* (→ core `tightenTaskSpec`)叠上部署治理段(autonomy / commandPolicy / MANUAL_MODE_SHELL_GATE /
|
|
101
95
|
* 守卫集),取其 `toolPolicy` 装进单层 `parentConstraints`。
|
|
102
96
|
*
|