@sema-agent/server 7.136.0 → 7.137.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.
Files changed (214) hide show
  1. package/MIGRATION.md +173 -0
  2. package/USAGE.md +84 -16
  3. package/deploy/sema-up/README.md +14 -0
  4. package/deploy/sema-up/chart/templates/sandbox-rbac.yaml +7 -1
  5. package/deploy/sema-up/stack/sema-stack-cluster.yaml +7 -1
  6. package/dist/approval-content-kind.d.ts +6 -0
  7. package/dist/approval-content-kind.js +7 -0
  8. package/dist/approval-gate-currency.d.ts +48 -6
  9. package/dist/approval-gate-currency.js +16 -9
  10. package/dist/approval-hmac.d.ts +13 -1
  11. package/dist/approval-hmac.js +1 -1
  12. package/dist/approval.js +3 -3
  13. package/dist/auth-bridge.js +2 -2
  14. package/dist/boot/execution-env.d.ts +24 -1
  15. package/dist/boot/execution-env.js +69 -6
  16. package/dist/boot/reapers.d.ts +3 -0
  17. package/dist/boot/reapers.js +15 -1
  18. package/dist/boot/resolve-spec.d.ts +4 -0
  19. package/dist/boot/resolve-spec.js +16 -17
  20. package/dist/boot/stage-03-store-backend.d.ts +1 -1
  21. package/dist/boot/stage-04-stores.d.ts +1 -1
  22. package/dist/boot/stage-05-execution-env.d.ts +3 -1
  23. package/dist/boot/stage-05-execution-env.js +11 -2
  24. package/dist/boot/stage-06-runners.d.ts +3 -1
  25. package/dist/boot/stage-06-runners.js +5 -1
  26. package/dist/boot/stage-07-capability-layer.d.ts +4 -1
  27. package/dist/boot/stage-07-capability-layer.js +1 -1
  28. package/dist/boot/stage-08-reapers.d.ts +4 -1
  29. package/dist/boot/stage-08-reapers.js +2 -1
  30. package/dist/boot/stage-09-leader.d.ts +4 -1
  31. package/dist/boot/stage-10-http-server.d.ts +4 -1
  32. package/dist/boot/stage-10-http-server.js +3 -2
  33. package/dist/boot/stores.d.ts +1 -1
  34. package/dist/broker/broker.d.ts +89 -0
  35. package/dist/broker/broker.js +287 -0
  36. package/dist/broker/constants.d.ts +39 -0
  37. package/dist/broker/constants.js +15 -0
  38. package/dist/broker/http1.d.ts +111 -0
  39. package/dist/broker/http1.js +256 -0
  40. package/dist/broker/lease-book.d.ts +87 -0
  41. package/dist/broker/lease-book.js +142 -0
  42. package/dist/broker/lease-file.d.ts +60 -0
  43. package/dist/broker/lease-file.js +127 -0
  44. package/dist/broker/main.d.ts +2 -0
  45. package/dist/broker/main.js +20 -0
  46. package/dist/capabilities/composite-members.d.ts +2 -1
  47. package/dist/capabilities/composite-members.js +2 -1
  48. package/dist/capabilities/engine-capabilities.js +1 -0
  49. package/dist/capabilities/scenarios.d.ts +23 -8
  50. package/dist/capabilities/scenarios.js +13 -8
  51. package/dist/capabilities/skills.d.ts +28 -5
  52. package/dist/capabilities/skills.js +8 -0
  53. package/dist/center-credential-renewer.js +5 -1
  54. package/dist/checkpoint-ctx-seal-m28.d.ts +3 -10
  55. package/dist/checkpoint-ctx-seal-m28.js +1 -1
  56. package/dist/checkpoint-identity.d.ts +3 -3
  57. package/dist/config-catalog.js +9 -6
  58. package/dist/config-types.d.ts +9 -0
  59. package/dist/config.d.ts +1 -1
  60. package/dist/config.js +34 -8
  61. package/dist/deployment-governance.d.ts +2 -2
  62. package/dist/deployment-governance.js +7 -9
  63. package/dist/device-ws-protocol.d.ts +1 -0
  64. package/dist/device-ws-protocol.js +2 -1
  65. package/dist/file-history-disclosure.d.ts +4 -2
  66. package/dist/file-history-disclosure.js +2 -0
  67. package/dist/hooks/classic-stations.d.ts +11 -54
  68. package/dist/http/admission.js +10 -7
  69. package/dist/http/approval-sweeps.js +4 -3
  70. package/dist/http/caller-trust.d.ts +2 -1
  71. package/dist/http/caller-trust.js +1 -3
  72. package/dist/http/checkpoint-ctx.d.ts +48 -7
  73. package/dist/http/checkpoint-ctx.js +40 -0
  74. package/dist/http/dispatch.js +15 -10
  75. package/dist/http/durable-run-leg.d.ts +5 -1
  76. package/dist/http/durable-run-leg.js +1 -1
  77. package/dist/http/health-self-report.d.ts +2 -2
  78. package/dist/http/mcp-remote-text.d.ts +5 -0
  79. package/dist/http/mcp-remote-text.js +7 -0
  80. package/dist/http/principal-gate.d.ts +15 -10
  81. package/dist/http/principal-gate.js +48 -9
  82. package/dist/http/resume-legs.d.ts +2 -20
  83. package/dist/http/resume-legs.js +52 -38
  84. package/dist/http/route-ctx.d.ts +8 -2
  85. package/dist/http/routes/approvals-assistant.js +18 -4
  86. package/dist/http/routes/capabilities.js +11 -1
  87. package/dist/http/routes/mcp-reconnect.d.ts +1 -1
  88. package/dist/http/routes/mcp-reconnect.js +5 -7
  89. package/dist/http/routes/runs.js +2 -1
  90. package/dist/http/routes/session-sync.js +42 -6
  91. package/dist/http/routes/sessions.js +2 -1
  92. package/dist/http/routes/tasks.js +8 -6
  93. package/dist/http/server.d.ts +4 -0
  94. package/dist/http/stored-body-replay.d.ts +3 -3
  95. package/dist/http/stored-body-replay.js +6 -1
  96. package/dist/http/wire-types.d.ts +52 -27
  97. package/dist/identity-source.d.ts +65 -0
  98. package/dist/identity-source.js +45 -0
  99. package/dist/memory-store-refusal.d.ts +3 -3
  100. package/dist/model-entry-refusal.d.ts +2 -0
  101. package/dist/model-entry-refusal.js +11 -0
  102. package/dist/model-select.d.ts +6 -17
  103. package/dist/model-select.js +0 -3
  104. package/dist/namespaced-rule-name.d.ts +1 -1
  105. package/dist/observability/fail-open.d.ts +13 -1
  106. package/dist/observability/fail-open.js +13 -1
  107. package/dist/observability/metrics.js +1 -1
  108. package/dist/observability/run-terminal.js +1 -0
  109. package/dist/operator-ask.d.ts +2 -2
  110. package/dist/org-delivery-gate.js +1 -1
  111. package/dist/org-memory-admission.d.ts +2 -2
  112. package/dist/org-memory-admission.js +39 -2
  113. package/dist/parked-decide.js +3 -2
  114. package/dist/peer-directory.js +2 -0
  115. package/dist/permission-rule-list.d.ts +2 -2
  116. package/dist/plugins/checkpoint-store-sql.d.ts +19 -9
  117. package/dist/plugins/checkpoint-store-sql.js +6 -6
  118. package/dist/plugins/file-history-store-sql.js +7 -14
  119. package/dist/plugins/file-run-store.js +8 -2
  120. package/dist/plugins/k8s-exec-protocol.d.ts +69 -13
  121. package/dist/plugins/k8s-exec-protocol.js +116 -28
  122. package/dist/plugins/k8s-pod-delete-failure.d.ts +25 -0
  123. package/dist/plugins/k8s-pod-delete-failure.js +17 -0
  124. package/dist/plugins/k8s-pod-reaper.d.ts +112 -0
  125. package/dist/plugins/k8s-pod-reaper.js +122 -0
  126. package/dist/plugins/local-checkpoint-store.d.ts +3 -6
  127. package/dist/plugins/local-checkpoint-store.js +3 -3
  128. package/dist/plugins/memory-run-store.js +2 -0
  129. package/dist/plugins/one-time-migrations.d.ts +28 -9
  130. package/dist/plugins/one-time-migrations.js +48 -5
  131. package/dist/plugins/permission-rule-store-file.js +2 -2
  132. package/dist/plugins/permission-rule-store-sql.d.ts +17 -17
  133. package/dist/plugins/permission-rule-store-sql.js +16 -17
  134. package/dist/plugins/pg-pool.js +4 -0
  135. package/dist/plugins/pg-session-storage.js +2 -2
  136. package/dist/plugins/remote-env-adb.d.ts +3 -0
  137. package/dist/plugins/remote-env-adb.js +1 -0
  138. package/dist/plugins/remote-env-device.d.ts +3 -0
  139. package/dist/plugins/remote-env-device.js +4 -0
  140. package/dist/plugins/remote-env-e2b.d.ts +3 -0
  141. package/dist/plugins/remote-env-e2b.js +1 -0
  142. package/dist/plugins/remote-env-file-error.d.ts +8 -1
  143. package/dist/plugins/remote-env-file-error.js +7 -1
  144. package/dist/plugins/remote-env-host.d.ts +7 -1
  145. package/dist/plugins/remote-env-host.js +7 -1
  146. package/dist/plugins/remote-env-k8s.d.ts +137 -10
  147. package/dist/plugins/remote-env-k8s.js +276 -14
  148. package/dist/plugins/remote-env-local-docker.d.ts +3 -0
  149. package/dist/plugins/remote-env-local-docker.js +1 -0
  150. package/dist/plugins/remote-env-ssh.d.ts +3 -0
  151. package/dist/plugins/remote-env-ssh.js +1 -0
  152. package/dist/plugins/run-store-sql.js +10 -4
  153. package/dist/plugins/session-ownership.d.ts +17 -3
  154. package/dist/plugins/session-ownership.js +19 -5
  155. package/dist/plugins/sql-errors.d.ts +23 -2
  156. package/dist/plugins/sql-errors.js +15 -0
  157. package/dist/plugins/store-contracts.d.ts +10 -1
  158. package/dist/plugins/store-fault.d.ts +2 -2
  159. package/dist/plugins/store-fault.js +4 -2
  160. package/dist/plugins/tidb-pool.js +7 -0
  161. package/dist/plugins/tidb-session-store.js +2 -2
  162. package/dist/request-key-closure.js +1 -1
  163. package/dist/request-value-closure.d.ts +31 -2
  164. package/dist/request-value-closure.js +7 -1
  165. package/dist/rule-entry-list.d.ts +3 -2
  166. package/dist/rule-entry-list.js +2 -2
  167. package/dist/rules-consent.js +7 -4
  168. package/dist/run-local.d.ts +2 -2
  169. package/dist/runs.js +2 -1
  170. package/dist/runtime-governance.d.ts +5 -5
  171. package/dist/sandbox-git-lease.d.ts +49 -0
  172. package/dist/sandbox-git-lease.js +60 -0
  173. package/dist/sandbox-git-plane.d.ts +84 -0
  174. package/dist/sandbox-git-plane.js +105 -0
  175. package/dist/security.d.ts +16 -4
  176. package/dist/security.js +8 -3
  177. package/dist/server-secret-env.d.ts +6 -0
  178. package/dist/server-secret-env.js +14 -0
  179. package/dist/session-error-wire.d.ts +14 -6
  180. package/dist/session-error-wire.js +2 -1
  181. package/dist/session-policy-wire.d.ts +1 -1
  182. package/dist/session-policy-wire.js +2 -2
  183. package/dist/session-sync.d.ts +1 -1
  184. package/dist/spec-fields.d.ts +43 -13
  185. package/dist/spec-fields.js +33 -12
  186. package/dist/stored-request-prompt-profile-m30.d.ts +49 -0
  187. package/dist/stored-request-prompt-profile-m30.js +25 -0
  188. package/dist/task-mcp.d.ts +1 -1
  189. package/dist/task-settings.d.ts +2 -2
  190. package/dist/tool-approval.d.ts +12 -2
  191. package/dist/tool-approval.js +8 -3
  192. package/dist/tool-rule-names.d.ts +5 -0
  193. package/dist/trace/core-keyset-guard.d.ts +4 -4
  194. package/dist/trace/engine-notice-wire.d.ts +1 -1
  195. package/dist/trace/engine-notice-wire.js +2 -0
  196. package/dist/trace/exit-seat.js +2 -2
  197. package/dist/trace/ledger-sink.d.ts +4 -5
  198. package/dist/trace/ledger-sink.js +3 -7
  199. package/dist/trace/project.d.ts +37 -3
  200. package/dist/trace/project.js +20 -6
  201. package/dist/trace/redact.d.ts +18 -6
  202. package/dist/trace/redact.js +118 -53
  203. package/dist/trace/self-minted-wire.d.ts +377 -3
  204. package/dist/trace/self-minted-wire.js +122 -0
  205. package/dist/trace/wire-projection-faces.d.ts +5 -3
  206. package/dist/trace/wire-projection-faces.js +7 -3
  207. package/dist/web-admin-client/apply-effective.js +0 -1
  208. package/dist/web-admin-client/center-request.d.ts +20 -2
  209. package/dist/web-admin-client/center-request.js +40 -5
  210. package/dist/web-admin-client/http-client.js +6 -6
  211. package/dist/web-admin-client/types.d.ts +5 -5
  212. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +11 -5
  213. package/package.json +2 -2
  214. package/wire-changes/server@7.137.0.json +825 -0
@@ -123,8 +123,10 @@ function askStandingAnswerFacts(req, governanceForced, deploymentListAsks) {
123
123
  deploymentListQuestion,
124
124
  };
125
125
  }
126
- const NO_GATE_FACTS = { contentQuestion: false, markedUnresolvable: false, org: undefined, tightened: undefined, mandateMarks: {} };
127
- const DEPLOYMENT_LIST_ASK_CLASSES = new Set(classifyAsk(operatorAsk("APPROVAL_REQUIRE", ""), NO_GATE_FACTS).classes);
126
+ function noGateFacts(call) {
127
+ return { call, contentQuestion: false, markedUnresolvable: false, org: undefined, tightened: undefined, mandateMarks: {} };
128
+ }
129
+ const DEPLOYMENT_LIST_ASK_CLASSES = new Set(classifyAsk(operatorAsk("APPROVAL_REQUIRE", ""), noGateFacts({ toolCallId: "", toolName: "" })).classes);
128
130
  export function carriesDeploymentListQuestion(deploymentListAsks, classes) {
129
131
  return deploymentListAsks && classes !== undefined && classes.some((c) => DEPLOYMENT_LIST_ASK_CLASSES.has(c));
130
132
  }
@@ -134,7 +136,7 @@ export function policyAskStandingAnswerFacts(req, ask, deploymentListQuestion) {
134
136
  requiresRealApproval: ask.requiresRealApproval === true,
135
137
  mandated: ask.mandated === true,
136
138
  grantBinding: callGrantBindingOf(req),
137
- classes: [...classifyAsk(ask, NO_GATE_FACTS).classes],
139
+ classes: [...classifyAsk(ask, noGateFacts({ toolCallId: req.toolCallId, toolName: req.toolName })).classes],
138
140
  deploymentListQuestion,
139
141
  };
140
142
  }
@@ -335,6 +337,9 @@ function unattendedRefusalReason(site) {
335
337
  function isChildAsk(req) {
336
338
  return req.fromSubagent === true;
337
339
  }
340
+ export function approverFacingArgs(args) {
341
+ return boundArgs(args).args;
342
+ }
338
343
  function boundArgs(args) {
339
344
  const redacted = redactDeep(args);
340
345
  let hasBidi = false;
@@ -22,6 +22,11 @@
22
22
  * 7.53.x 及以前,`MyShell` 的 `egress: true` / `irreversibility: "always"` 会让引擎 `Bash` 的调用多问一次(收紧),它的恒可逆探针会让引擎 `Bash` 的
23
23
  * `touch` 不问就跑(放宽);7.54.0 起两者都不再作用于引擎 shell。要收紧引擎 shell:给**正名**叫 `Bash` 的工具声明标记(同名标记仍作用),或请求
24
24
  * `TaskSpec.shellGate: "always"`(本仓的入口 `MANUAL_MODE_SHELL_GATE` / 请求 `shellGate`)。
25
+ * ⚠️ **反方向(core 7.56.0 [ref])**:一次调用的安全轴只按它答得上的名字读,别名不带副本;两个名字的层级**平局时归 wire 名**(真正跑的那只工具)。
26
+ * 于是 `MyShell{irreversibility:"maybe", aliases:["Bash"]}` 在引擎 shell 被选择器卸下的腿上按 `Bash` 被调时,判它的是 **`MyShell` 自己的探针**
27
+ * (7.55.x 及以前是引擎 shell 席的形状探针:`ls` 不问就跑、`MyShell` 的探针从未被问)。⇒ 嵌入方给这类工具**照实声明**判它自己命令的探针,
28
+ * 或不声明层级、或 `irreversibility: "always"`;不声明层级时引擎 shell 席的层级仍够得着它(引擎侧候设计车,问的模式下按 shell 探针问,
29
+ * `bypassPermissions` 下照放)。本仓自身不声明带别名的工具,零码;这一形只有经 `resolveSpec` 席挂别名工具的嵌入方走得到。
25
30
  *
26
31
  * 返回**命中的那个名字**(调用答得上的名字里第一个被规则够到的,拼写在先)—— 规则归因(`matchedAskRule`)写运维名单里的那个名,
27
32
  * 不写一个名单里查不到的 wire 名;够不到 ⇒ `undefined`。判定式(精确集 / covering 规则)由调用方给,本函数只管「读哪些名字」。
@@ -45,7 +45,7 @@ type RosterProjected = "name" | "agentId" | "sessionId" | "toolUseId" | "owner"
45
45
  type _GuardRoster = AssertAllKeysHandled<Exclude<keyof RosterEntry, RosterProjected>>;
46
46
  type _GuardRosterReverse = AssertAllKeysHandled<Exclude<RosterProjected, keyof RosterEntry>>;
47
47
  type AskProjected = "toolName" | "toolCallId" | "args" | "message" | "sourceTaskId" | "fromSubagent" | "sourceAgentName" | "delegation" | "ruleOffers" | "ruleOffersAbsence" | "allowRuleShadowed" | "probeCause" | "probeReason" | "ruleEvidence" | "requiresRealApproval" | "denialLimitFallback" | "origin" | "readRootCandidate" | "mandated" | "mandate" | "askClass" | "classes" | "boundGrantDigest" | "boundGrants" | "classifierNoRuling" | "approvalCard" | "boundGrantAbsence";
48
- type AskExcluded = "preview" | "principal" | "riskAxes" | "boundInputHash" | "isDelegatedChild" | "hasBidiControls" | "previewWithheld" | "execCwd" | "authoredBy";
48
+ type AskExcluded = "preview" | "principal" | "riskAxes" | "boundInputHash" | "isDelegatedChild" | "hasBidiControls" | "previewWithheld" | "execCwd" | "authoredBy" | "requestedBy" | "editRewritten";
49
49
  type _GuardAsk = AssertAllKeysHandled<Exclude<keyof AskRequest, AskProjected | AskExcluded>>;
50
50
  type _GuardAskReverse = AssertAllKeysHandled<Exclude<AskProjected | AskExcluded, keyof AskRequest>>;
51
51
  type AskFrameServerMinted = "type" | "approvalId" | "argsOmitted" | "outcome" | "governanceForced" | "expiresAtMs" | "expiresInMs" | "serverNowMs" | "parked" | "cause" | "inputHasBidi" | "rememberRefused";
@@ -219,16 +219,16 @@ type ParkArmKeys = keyof Extract<PendingAction, {
219
219
  kind: "tool_approval";
220
220
  }>;
221
221
  type ParkArmQueueProjected = "toolName" | "toolCallId" | "boundInputHash" | "ruleOffers" | "hasBidiControls" | keyof import("../approval-card.js").ParkRowFacts | keyof import("../approval-card.js").SkillCardFacts;
222
- type ParkArmQueueExcluded = "kind" | "args" | "batchToolCallIds" | "completedCallIds" | "capabilityId" | "contractId" | "shapeDigest" | "implementationRevision" | "family" | "pathTarget" | "hostTarget" | "targets" | "names" | "preview" | "previewWithheld" | "execCwd" | "denialLimitFallback" | "authoredBy";
222
+ type ParkArmQueueExcluded = "kind" | "args" | "batchToolCallIds" | "completedCallIds" | "capabilityId" | "contractId" | "shapeDigest" | "implementationRevision" | "family" | "pathTarget" | "hostTarget" | "targets" | "names" | "preview" | "previewWithheld" | "execCwd" | "denialLimitFallback" | "authoredBy" | "engineMounted";
223
223
  type _GuardParkArmQueue = AssertAllKeysHandled<Exclude<ParkArmKeys, ParkArmQueueProjected | ParkArmQueueExcluded>>;
224
224
  type _GuardParkArmQueueReverse = AssertAllKeysHandled<Exclude<ParkArmQueueProjected | ParkArmQueueExcluded, ParkArmKeys>>;
225
225
  type _NoDoubleBookParkArmQueue = AssertAllKeysHandled<Extract<ParkArmQueueProjected, ParkArmQueueExcluded>>;
226
- type TaskSpecWired = "objective" | "principal" | "images" | "sessionId" | "requireExistingSession" | "oneShot" | "clientContext" | "resumeAt" | "resumeAtMode" | "model" | "compactionModel" | "thinking" | "systemPrompt" | "appendSystemPrompt" | "promptRole" | "promptBinding" | "memory" | "suggestNextPrompts" | "restoreFiles" | "acceptPartialRestore" | "rewindFilesTo" | "tools" | "excludeTools" | "deferTools" | "toolMaterializeStrategy" | "promptProfile" | "toolPolicy" | "onAsk" | "onQuestion" | "mods" | "durableApproval" | "resourceSuspend" | "resilience" | "finalVerification" | "checkpointStore" | "handsReadOnly" | "memoryPersistenceCapable" | "additionalDirectories" | "additionalReadDirectories" | "enablePlanMode" | "interactiveTools" | "enableFork" | "shellGate" | "approvalReach" | "writeFace" | "mcp" | "a2a" | "skills" | "backgroundScope" | "envFacts" | "limits" | "configOverrides" | "forwardSubagentEvents" | "retainSubagentSessions" | "retainBackgroundProcesses" | "outputSchema" | "outputRetries" | "compaction" | "attachments" | "selfOrchestration" | "getApiKeyAndHeaders" | "interactionPosture" | "agents" | "permissionMode" | "taskId" | "signal" | "preemptSignal" | "maxSuspends" | "skillListingBudgetFraction" | "skillListingMaxDescChars" | "excludeAllTools" | "fileHistory" | "userInvokedSkills" | "outputStyle" | "projectMemory" | "allowedTools" | "allowTools" | "userAttachments" | "readDenyPatterns" | "writeProtectedAdditions" | "complianceAdditionalDenies";
226
+ type TaskSpecWired = "objective" | "principal" | "images" | "sessionId" | "requireExistingSession" | "oneShot" | "clientContext" | "resumeAt" | "resumeAtMode" | "model" | "compactionModel" | "thinking" | "systemPrompt" | "appendSystemPrompt" | "promptRole" | "promptBinding" | "memory" | "suggestNextPrompts" | "restoreFiles" | "acceptPartialRestore" | "rewindFilesTo" | "tools" | "excludeTools" | "deferTools" | "toolMaterializeStrategy" | "promptLean" | "toolPolicy" | "onAsk" | "onQuestion" | "mods" | "durableApproval" | "resourceSuspend" | "resilience" | "finalVerification" | "checkpointStore" | "handsReadOnly" | "memoryPersistenceCapable" | "additionalDirectories" | "additionalReadDirectories" | "enablePlanMode" | "interactiveTools" | "enableFork" | "shellGate" | "approvalReach" | "writeFace" | "mcp" | "a2a" | "skills" | "backgroundScope" | "envFacts" | "limits" | "configOverrides" | "forwardSubagentEvents" | "retainSubagentSessions" | "retainBackgroundProcesses" | "outputSchema" | "outputRetries" | "compaction" | "attachments" | "selfOrchestration" | "getApiKeyAndHeaders" | "interactionPosture" | "agents" | "permissionMode" | "taskId" | "signal" | "preemptSignal" | "maxSuspends" | "skillListingBudgetFraction" | "skillListingMaxDescChars" | "excludeAllTools" | "fileHistory" | "userInvokedSkills" | "outputStyle" | "projectMemory" | "allowedTools" | "allowTools" | "userAttachments" | "readDenyPatterns" | "writeProtectedAdditions" | "complianceAdditionalDenies";
227
227
  /** 导出:请求体键闭集门(`request-key-closure.ts`)据它锁「本仓记为未接线的引擎座,提交口不许受理」—— 两处分类只能同向。 */
228
228
  export type TaskSpecUnwired = "actor" | "roles" | "lspManager" | "tracer" | "readFace" | "interactiveQuestionFallback" | "alwaysLoadTools" | "restoreGatedTools" | "deferSelfResolve" | "basePolicyForResumeEdit" | "lspDiagnostics" | "streamingToolExecution" | "toolResultThresholdChars" | "peerPresence" | "modelRole" | "enableBlockedReport" | "promptForm" | "advisorModel";
229
229
  type _GuardTaskSpec = AssertAllKeysHandled<Exclude<keyof TaskSpec, TaskSpecWired | TaskSpecUnwired>>;
230
230
  type _GuardTaskSpecReverse = AssertAllKeysHandled<Exclude<TaskSpecWired | TaskSpecUnwired, keyof TaskSpec>>;
231
- type TaskResultForwarded = "taskId" | "runId" | "sessionId" | "terminal" | "model" | "effectiveReasoning" | "result" | "salvagedOutput" | "remoteEnvFailures" | "apiFailure" | "retryAfterMs" | "degraded" | "structuredOutput" | "rewindNotes" | "haltedOnUserRejection" | "haltedByUser" | "strandedHumanAnswers" | "pendingApproval" | "approvalWaitedMs" | "effectiveReadFace" | "effectiveReadDenyPatterns" | "effectiveWriteFace" | "effectiveMemoryScopes" | "stats" | "editedFiles" | "responseModel" | "compaction";
231
+ type TaskResultForwarded = "taskId" | "runId" | "sessionId" | "terminal" | "model" | "effectiveReasoning" | "result" | "salvagedOutput" | "remoteEnvFailures" | "apiFailure" | "retryAfterMs" | "degraded" | "structuredOutput" | "rewindNotes" | "haltedOnUserRejection" | "haltedByUser" | "strandedHumanAnswers" | "pendingApproval" | "approvalWaitedMs" | "effectiveReadFace" | "effectiveReadDenyPatterns" | "effectiveWriteFace" | "effectiveMemoryScopes" | "stats" | "editedFiles" | "responseModel" | "compaction" | "resultEntryIds";
232
232
  type TaskResultStripped = never;
233
233
  type _GuardTaskResult = AssertAllKeysHandled<Exclude<keyof TaskResult, TaskResultForwarded | TaskResultStripped>>;
234
234
  type _GuardTaskResultReverse = AssertAllKeysHandled<Exclude<TaskResultForwarded | TaskResultStripped, keyof TaskResult>>;
@@ -16,7 +16,7 @@
16
16
  * 同文件 G1 e2e 的全码扇出夹具、以及契约文档附录 D.3 那张表(含**小节标题里的码数** —— 那道门本批
17
17
  * 刚立,立完就在下一次加码时自己咬住了)。
18
18
  */
19
- export declare const ENGINE_NOTICE_WIRE_CODES: readonly ["memory.session_polluted", "memory.harvest_quarantined", "memory.delegation_static_mark_waived", "memory.hold_opened", "memory.hold_released", "memory.hold_disposed", "task.turn_interrupted", "steering.parked_input_blocked", "task.user_steer_undrained", "task.user_followup_undrained", "memory.capture_opted_out", "memory.capture_optout_unpersisted", "task.halt_unconsumed", "task.late_approval", "config.durable_gate_unavailable", "peer.inbound_disposition", "peer.held_settled", "peer.idle_subscription", "classifier.denial_limit", "mcp.injection_dropped", "delegation.ask_unresolvable", "task.interrupt_unconsumed", "approval.read_root_granted", "approval.read_root_grant_rejected", "instructions.source_changed", "session.records_skipped", "server.model_unreachable", "permission.entry_mode_clamped", "classifier.unavailable", "config.permission_mode_unavailable", "permission.ask_released_by_mode", "permission.read_deny_unapplied", "permission.rule_store_unavailable", "permission.rule_row_dropped", "permission.allowed_tool_not_granted", "task.tool_turn_incomplete", "route.finish_reason_unknown", "route.stream_end_ignored", "route.credential_origin_mismatch", "mods.registration_refused", "config.session_rules_earlier_grammar", "advisor.not_attached"];
19
+ export declare const ENGINE_NOTICE_WIRE_CODES: readonly ["memory.session_polluted", "memory.harvest_quarantined", "memory.delegation_static_mark_waived", "memory.hold_opened", "memory.hold_released", "memory.hold_disposed", "task.turn_interrupted", "steering.parked_input_blocked", "task.user_steer_undrained", "task.user_followup_undrained", "memory.capture_opted_out", "memory.capture_optout_unpersisted", "task.halt_unconsumed", "task.late_approval", "config.durable_gate_unavailable", "peer.inbound_disposition", "peer.held_settled", "peer.idle_subscription", "classifier.denial_limit", "mcp.injection_dropped", "delegation.ask_unresolvable", "task.interrupt_unconsumed", "approval.read_root_granted", "approval.read_root_grant_rejected", "instructions.source_changed", "session.records_skipped", "server.model_unreachable", "permission.entry_mode_clamped", "classifier.unavailable", "config.permission_mode_unavailable", "permission.ask_released_by_mode", "permission.read_deny_unapplied", "permission.rule_store_unavailable", "permission.rule_row_dropped", "permission.allowed_tool_not_granted", "task.tool_turn_incomplete", "route.finish_reason_unknown", "route.stream_end_ignored", "route.credential_origin_mismatch", "mods.registration_refused", "config.session_rules_earlier_grammar", "advisor.not_attached", "inherit_env.names_withheld", "model.capability_downgraded"];
20
20
  export type EngineNoticeWireCode = (typeof ENGINE_NOTICE_WIRE_CODES)[number];
21
21
  /** 白名单谓词(单点):路由与门都读这一个,不许第二处手抄码串。 */
22
22
  export declare function isEngineNoticeWireCode(code: string): code is EngineNoticeWireCode;
@@ -44,6 +44,8 @@ export const ENGINE_NOTICE_WIRE_CODES = [
44
44
  "mods.registration_refused",
45
45
  "config.session_rules_earlier_grammar",
46
46
  "advisor.not_attached",
47
+ "inherit_env.names_withheld",
48
+ "model.capability_downgraded",
47
49
  ];
48
50
  const WIRE_CODES = new Set(ENGINE_NOTICE_WIRE_CODES);
49
51
  export function isEngineNoticeWireCode(code) {
@@ -3,7 +3,7 @@ import { CALLER_TEXT_CUT_MARK } from "../caller-text-echo.js";
3
3
  import { errorKindOf } from "../observability/err-text.js";
4
4
  import { recordFailOpen } from "../observability/fail-open.js";
5
5
  import { OVERSIZED_REDACTION_PLACEHOLDER } from "../observability/run-terminal.js";
6
- import { proposeRedactionSpans, readingHeadEnd, REDACTION_TOKEN_RE_SRC } from "./redact.js";
6
+ import { proposeRedactionSpans, readingHeadEnd, REDACTION_TOKEN_RE_SRC, WHOLE_EXTENT } from "./redact.js";
7
7
  const EXIT_SEATS = {
8
8
  "trace-frame-text": { scope: "free-text" },
9
9
  "trace-frame-line": { scope: "free-text", maxChars: 300 },
@@ -118,7 +118,7 @@ export function seatText(seat, text) {
118
118
  out = "";
119
119
  else {
120
120
  const emitUntil = regionEnd;
121
- const extent = windowEnd === undefined ? "whole" : "head";
121
+ const extent = windowEnd === undefined || regionEnd === undefined ? WHOLE_EXTENT : { kind: "head", emitEnd: regionEnd };
122
122
  const rendered = renderOnce(head, mergeSpans(proposeRedactionSpans(head, row.scope, layout, extent)), emitUntil);
123
123
  out = boundRow(row.emit === undefined ? rendered : emitAs(row.emit, rendered), row, windowEnd !== undefined);
124
124
  }
@@ -1,8 +1,7 @@
1
1
  import { type TerminalCause } from "@sema-agent/core";
2
- import { brainStatusEventData } from "./project.js";
2
+ import { brainStatusEventData, type LegWiringSections } from "./project.js";
3
3
  import { NotifiedKeys } from "../orchestration/workflow-completion-inbox.js";
4
4
  import { type LedgerEventType, type ParkLedgerEventType } from "./ledger-events.js";
5
- import type { InstructionsSegment } from "../instruction-selection.js";
6
5
  /**
7
6
  * LedgerSink — the SINGLE "stream event → durable runs-ledger" projection, shared by the background leg
8
7
  * (runs.ts `runInBackground`) and the sync `/v1/tasks/stream` detach lane (server.ts, `x-detach-on-disconnect`).
@@ -152,8 +151,8 @@ export declare function createLedgerSink(opts: {
152
151
  * 各传自己看得见的那个词(位①=流事件 `ev.type`,位②=账本行 `type`);拿不到类型的打点方
153
152
  * (core 的 onActivity 第五席、resume 腿手动打点)省参,`kind` 诚实缺席(见 turn-activity.ts)。 */
154
153
  onActivity?: (kind?: string, statusData?: Record<string, unknown>) => void;
155
- /** [ref]:这条腿的 `wiring_manifest.instructions` 段(腿的 `InstructionSelectionLeg.segment`)。**必填**:账本行与 live 帧是
156
- * 同一条腿的两个载体,段必须来自同一只腿;在投帧那一刻读(core 推帧之前已 await 过 loader)。返回 `undefined` ⇒ 段缺席。 */
157
- instructionsSegment: () => InstructionsSegment | undefined;
154
+ /** 这条腿的 `wiring_manifest` **本仓自铸段**(`LegWiringSections`:[ref] `instructions` 读腿的 `InstructionSelectionLeg.segment`、run 级 `skills` 读 spec 字段
155
+ * `runSkillsOf`)。**必填**:账本行与 live 帧是同一条腿的两个载体,段必须来自同一只腿;在投帧那一刻读(core 推帧之前已 await 过 loader)。 */
156
+ legSections: () => LegWiringSections;
158
157
  }): LedgerSink;
159
158
  //# sourceMappingURL=ledger-sink.d.ts.map
@@ -1,7 +1,7 @@
1
1
  import {} from "@sema-agent/core";
2
2
  import { outwardPlane } from "../terminal.js";
3
3
  import { recordFailOpen } from "../observability/fail-open.js";
4
- import { modelTextEventData, toolStartEventData, toolEndEventData, taskProgressEventData, taskStartedEventData, taskNotificationEventData, compactedEventData, diagnosticsEventData, brainStatusEventData, steeringInjectedEventData, compactionOutcomeEventData, compactionStartedEventData, workspaceChangedEventData, wiringManifestEventData, toolRosterDeltaEventData, toolDisclosureEventData, humanInputEventData, turnEndEventData, contextUsageEventData } from "./project.js";
4
+ import { modelTextEventData, toolStartEventData, toolEndEventData, taskProgressEventData, taskStartedEventData, taskNotificationEventData, compactedEventData, diagnosticsEventData, brainStatusEventData, steeringInjectedEventData, compactionOutcomeEventData, compactionStartedEventData, workspaceChangedEventData, wiringManifestEventData, toolRosterDeltaEventData, toolDisclosureEventData, humanInputEventData, turnEndEventData, contextUsageEventData, parkEventData } from "./project.js";
5
5
  import { NotifiedKeys, taskNotificationStreamKeyOf } from "../orchestration/workflow-completion-inbox.js";
6
6
  import { isParkLedgerEventType } from "./ledger-events.js";
7
7
  import { isModelSegmentBoundary, reasoningDeltaBytes, reasoningSegmentEventId } from "./model-segment.js";
@@ -115,7 +115,7 @@ export function createLedgerSink(opts) {
115
115
  await append("workspace_changed", workspaceChangedEventData(ev));
116
116
  break;
117
117
  case "wiring_manifest":
118
- await append("wiring_manifest", wiringManifestEventData(ev, opts.instructionsSegment()));
118
+ await append("wiring_manifest", wiringManifestEventData(ev, opts.legSections()));
119
119
  break;
120
120
  case "tool_roster_delta": {
121
121
  const rosterDelta = toolRosterDeltaEventData(ev);
@@ -179,11 +179,7 @@ export function createLedgerSink(opts) {
179
179
  return append("status", statusData);
180
180
  };
181
181
  const appendParked = (kind, result) => {
182
- const t = result?.terminal;
183
- return append(kind, {
184
- gate: t?.kind === "paused" ? t.gate : null,
185
- ...(typeof result?.toolCallId === "string" ? { toolCallId: result.toolCallId } : {}),
186
- });
182
+ return append(kind, parkEventData(result));
187
183
  };
188
184
  const appendDone = (result) => append("done", { result });
189
185
  const onDone = async (result) => {
@@ -31,6 +31,7 @@ import { type SafeText } from "./exit-seat.js";
31
31
  import { type SemaProvenanceInput } from "./sema-provenance.js";
32
32
  import type { LedgerEventType } from "./ledger-events.js";
33
33
  import type { InstructionsSegment } from "../instruction-selection.js";
34
+ import type { RunSkillEntry } from "../capabilities/skills.js";
34
35
  /** 账本写口的统一签名 —— `type` 是**闭集**(`ledger-events.ts`):新型必须先登记,否则调用点编译红
35
36
  * (codex 交叉复审 F2:别名门 `ap("x")` 与动态首参让纯词法门结构性抓不全)。 */
36
37
  type AppendFn = (type: LedgerEventType, data: unknown) => Promise<void>;
@@ -387,6 +388,25 @@ export declare function taskProgressEventData(ev: {
387
388
  currentAction?: SafeText;
388
389
  workflowAgentLabel?: SafeText;
389
390
  }>;
391
+ /** park 账本行(`suspended` / `needs_review`)的 `data` 形 —— {@link parkEventData} 的产物。 */
392
+ export interface ParkEventData {
393
+ /** 暂停因由上的门(没有暂停因由 ⇒ `null`:同步口兜底行、重开行)。 */
394
+ readonly gate: Extract<TaskResult["terminal"], {
395
+ kind: "paused";
396
+ }>["gate"] | null;
397
+ /** [ref] 待批工具调用身份 —— 调用方先 graft(`graftParkToolCallId`)再交进来;tool-less park 缺席。 */
398
+ readonly toolCallId?: string;
399
+ /** 门身份(7.137.0):与运维队列 / 收件行同名、同一只读法(`durableRowIdentity`:过信任边界,读不出 ⇒ 缺席 + 计数)。决断方据它回显 `plan_review` 的 `checkpointId`。 */
400
+ readonly checkpointId?: string;
401
+ /** 重开臂:续跑腿失败而店说卡又 pending ⇒ 行回到 park,这一位带那次失败码(`null` = 码缺席);普通 park 缺席。 */
402
+ readonly reopened?: string | null;
403
+ }
404
+ /**
405
+ * park 账本行的**唯一**构造器 —— 三类写者同经这一只:后台腿与同步 detach 腿(`LedgerSink.appendParked`)、续跑腿的再停两臂与重开臂(`resume-legs.ts`)。
406
+ * 键律见 {@link ParkEventData}。恢复凭据 token 只进门身份的信任边界判,**永不**进行(调用方交未封口的结果时 token 在因由上;交已封口的结果时它已被摘,判据退化为形判)。
407
+ * 门身份读法与三处 durable 读面同一只(`durableRowIdentity`,face `run-events-park`):没有暂停因由的行不问身份(没有门可认);有因由而读不出 ⇒ 键缺席 + 计一次。
408
+ */
409
+ export declare function parkEventData(result: unknown, reopened?: string | null): ParkEventData;
390
410
  /**
391
411
  * The `task_started` payload(core 7.50.0):一只委派子代**起跑**的那一帧 —— 每周期一只(首派 / 复活;耐久续跑腿不铸),
392
412
  * 序在子代的 `wiring_manifest` 之后、它的首个 `task_progress` 与首次模型请求之前。
@@ -832,6 +852,20 @@ export declare function toolRosterDeltaEventData(ev: {
832
852
  eventId?: unknown;
833
853
  parentToolCallId?: unknown;
834
854
  }): Record<string, unknown> | undefined;
855
+ /**
856
+ * `wiring_manifest` 上**本仓自铸**的段 —— core 的 manifest 里没有它们(属主不在引擎),所以不从 `ev` 读:每条投帧的腿把自己的陈述**一次交齐**。
857
+ * 键集 = `wire-projection-faces.ts` 租户行的 `minted`(编译期双向绑定在 `core-keyset-guard.ts`:多一段 / 少一段都红)。第二参**必传**、每一键**必填**
858
+ * (值可以是 `undefined`)—— 漏递的腿当场 tsc 红,而不是静默投出一个「缺席」(缺席在 wire 上是一句话:「这条腿对这件事没有陈述」)。
859
+ * · `instructions`([ref],7.111.0)—— 这条腿的 project-memory loader 选中的指令文件链成员 `{ selected: string[] }`;值来自腿的
860
+ * `InstructionSelectionLeg.segment()`。`undefined` ⇒ 段缺席;`{ selected: [] }` ⇒ 显式空(走了链、没选中)。
861
+ * · `skills`(7.137.0)—— 这条 run 交给引擎的技能名册(`{ name, description, source }[]`,与场景卡技能清单同一张形);值来自 spec 字段 `runSkillsOf(spec)`
862
+ * (唯一铸点 = resolveSpec 出口的 `buildRunSkills`)。**run 级** ⇒ 只投根腿 / 续跑腿的帧,委派子代的帧(`parentToolCallId` 在场)不投(子代的技能由它自己的定义决定);
863
+ * `[]` = 零技能(含 `disableSkills`);`undefined` ⇒ 段缺席(这条腿的 spec 不是本仓装配的)。`description` 过上 wire 的自由文本出口 {@link sanitizeWireText}。
864
+ */
865
+ export interface LegWiringSections {
866
+ readonly instructions: InstructionsSegment | undefined;
867
+ readonly skills: readonly RunSkillEntry[] | undefined;
868
+ }
835
869
  /**
836
870
  * `wiring_manifest.sessionRules` 段的**处置表**(core 7.55.0 [ref];[ref] 起新面写表 —— 门 `core-keyset-guard.ts` ⑥b 读 `TableCoreKeys`,core 给段加成员 ⇒ tsc 红,
837
871
  * 先判受众再写进表)。唯一一位 `childrenReadLive` 是布尔才出门(读法拒 ⇒ 表的丢弃口计一次)。裁定 = 两个出口都投(理由在 ⑥b 段注)。
@@ -845,7 +879,7 @@ export declare function wiringManifestEventData(ev: {
845
879
  manifest?: unknown;
846
880
  eventId?: unknown;
847
881
  parentToolCallId?: unknown;
848
- }, instructions: InstructionsSegment | undefined): Record<string, unknown>;
882
+ }, minted: LegWiringSections): Record<string, unknown>;
849
883
  /**
850
884
  * `wiring_manifest` 的 **operator 投影**([ref] 件一)—— {@link wiringManifestEventData} 的租户形加上
851
885
  * `governance` 段与 core 的真 `configFingerprint`。
@@ -881,7 +915,7 @@ export declare function wiringManifestOperatorEventData(ev: {
881
915
  manifest?: unknown;
882
916
  eventId?: unknown;
883
917
  parentToolCallId?: unknown;
884
- }, instructions: InstructionsSegment | undefined): Record<string, unknown>;
918
+ }, minted: LegWiringSections): Record<string, unknown>;
885
919
  /**
886
920
  * `wiring_manifest` 的**唯一分叉点**([ref])—— 两条知道调用方身份的 live 消费腿共用它:
887
921
  * `/v1/tasks/stream` 的 SSE 帧,与 `POST /v1/tasks`(非流式)200 体里的 `wiringManifest` 起手回执。
@@ -902,7 +936,7 @@ export declare function wiringManifestFaceEventData(ev: {
902
936
  manifest?: unknown;
903
937
  eventId?: unknown;
904
938
  parentToolCallId?: unknown;
905
- }, operatorFace: boolean, instructions: InstructionsSegment | undefined): Record<string, unknown>;
939
+ }, operatorFace: boolean, minted: LegWiringSections): Record<string, unknown>;
906
940
  /**
907
941
  * `human_input`(core 5.14.0 [ref] 新 `TaskEvent` 臂)—— 「谁把什么喂进了这条 run」的生命周期账本
908
942
  * 帧(objective / 实时 steer / nextTurn / parked-steer 续跑 / wake 五个载体共用一个投影点)。
@@ -11,6 +11,7 @@ import { semaProvenanceOrAbsent } from "./sema-provenance.js";
11
11
  import { resupplyFields, terminalFrameFacetFields } from "./task-notification-facets.js";
12
12
  import { dropProjectedFace } from "./projection-drop.js";
13
13
  import { projectByTable } from "./projection-table.js";
14
+ import { durableRowIdentity } from "../checkpoint-identity.js";
14
15
  export async function appendModelUsageDelta(append, modelUsage, taskId) {
15
16
  const delta = modelUsage?.drain(taskId);
16
17
  if (delta) {
@@ -292,6 +293,16 @@ export function taskProgressEventData(ev) {
292
293
  ...identityFields(ev),
293
294
  };
294
295
  }
296
+ export function parkEventData(result, reopened) {
297
+ const r = (result ?? {});
298
+ const paused = r.terminal?.kind === "paused" ? r.terminal : undefined;
299
+ return {
300
+ gate: paused !== undefined ? paused.gate : null,
301
+ ...(typeof r.toolCallId === "string" ? { toolCallId: r.toolCallId } : {}),
302
+ ...(paused !== undefined ? durableRowIdentity("run-events-park", paused.checkpointId, paused.token) : {}),
303
+ ...(reopened !== undefined ? { reopened } : {}),
304
+ };
305
+ }
295
306
  export function taskStartedEventData(ev) {
296
307
  return {
297
308
  taskId: ev.taskId,
@@ -460,7 +471,7 @@ export function toolRosterDeltaEventData(ev) {
460
471
  export const WIRING_SESSION_RULES_DISPOSITIONS = {
461
472
  childrenReadLive: { forward: (raw) => typeof raw === "boolean" },
462
473
  };
463
- export function wiringManifestEventData(ev, instructions) {
474
+ export function wiringManifestEventData(ev, minted) {
464
475
  const str = (v) => (typeof v === "string" && v.length > 0 ? v : undefined);
465
476
  const bool = (v) => (typeof v === "boolean" ? v : undefined);
466
477
  const num = (v) => (typeof v === "number" && Number.isFinite(v) ? v : undefined);
@@ -695,12 +706,15 @@ export function wiringManifestEventData(ev, instructions) {
695
706
  ...(lsp !== undefined ? { lsp } : {}),
696
707
  ...(hands !== undefined ? { hands } : {}),
697
708
  ...(writeProtection !== undefined ? { writeProtection } : {}),
698
- ...(instructions !== undefined ? { instructions: { selected: [...instructions.selected] } } : {}),
709
+ ...(minted.instructions !== undefined ? { instructions: { selected: [...minted.instructions.selected] } } : {}),
710
+ ...(minted.skills !== undefined && typeof ev.parentToolCallId !== "string"
711
+ ? { skills: minted.skills.map((e) => ({ name: e.name, description: sanitizeWireText(e.description), source: e.source })) }
712
+ : {}),
699
713
  ...identityFields(ev),
700
714
  };
701
715
  }
702
- export function wiringManifestOperatorEventData(ev, instructions) {
703
- const tenant = wiringManifestEventData(ev, instructions);
716
+ export function wiringManifestOperatorEventData(ev, minted) {
717
+ const tenant = wiringManifestEventData(ev, minted);
704
718
  const str = (v) => (typeof v === "string" && v.length > 0 ? v : undefined);
705
719
  const bool = (v) => (typeof v === "boolean" ? v : undefined);
706
720
  const sec = (v) => (typeof v === "object" && v !== null && !Array.isArray(v) ? { ...v } : undefined);
@@ -744,8 +758,8 @@ export function wiringManifestOperatorEventData(ev, instructions) {
744
758
  ...(str(m.configFingerprint) !== undefined ? { configFingerprint: m.configFingerprint } : {}),
745
759
  };
746
760
  }
747
- export function wiringManifestFaceEventData(ev, operatorFace, instructions) {
748
- return operatorFace ? wiringManifestOperatorEventData(ev, instructions) : wiringManifestEventData(ev, instructions);
761
+ export function wiringManifestFaceEventData(ev, operatorFace, minted) {
762
+ return operatorFace ? wiringManifestOperatorEventData(ev, minted) : wiringManifestEventData(ev, minted);
749
763
  }
750
764
  export function humanInputEventData(ev) {
751
765
  const str = (v) => (typeof v === "string" && v.length > 0 ? v : undefined);
@@ -126,19 +126,31 @@ export declare function setRedactionObserver(fn: ((patternLabel: string, count:
126
126
  */
127
127
  export type RedactionLayout = "multi-line" | "single-line";
128
128
  /**
129
- * 一段文本相对「它所在的那一整段」的**范围**(闭集两词;调用方对自己交来的文本的陈述,不是旋钮):
129
+ * 一段文本相对「它所在的那一整段」的**范围**(闭集两形;调用方对自己交来的文本的陈述,不是旋钮):
130
130
  * · `whole`:这就是全部。所有「见收尾才认」的结构臂走到末尾仍没见收尾 ⇒ 这一起点不成 —— 判据 = 声明正则(`test/trace-redact.test.ts` 的真值表钉着扫描器与声明正则逐跨度等价);
131
- * · `head`:这只是更长文本的头一段(出口座对有界行只扫一段头,见 `trace/exit-seat.ts` 的扫描窗)。**一条律:结构的判定走到这一段末尾还没走完 ⇒ 判定在更远处(未决)⇒ 从结构起点遮到这一段的末尾**
132
- * (fail-closed:起点在、判定要看窗外,明文不许出门)。未决只有两种,同读一条臂:
131
+ * · `head`:这只是更长文本的头一段(出口座对有界行只扫一段头,见 `trace/exit-seat.ts` 的扫描窗),并带 **`emitEnd`** —— 调用方真会往外交的那一段的终点(**原文下标**;出口座的出门区终点,
132
+ * 其后的窗内余量只喂脱敏器、不出门)。窗几何只有调用方知道,脱敏器不猜、不抄第二份。**一条律,所有臂同读:结构的判定走到这一段末尾还没走完 ⇒ 判定在更远处(未决)⇒ 从结构起点遮到这一段的末尾
133
+ * (fail-closed:起点在、判定要看窗外,明文不许出门);而未决尾只在它的起点 `< emitEnd` 时才算** —— 起点在余量里的,对出门字节零作用(出门的至多到 `emitEnd`;余量只喂脱敏器、不出门,
134
+ * 其后的原文也不再被扫):不产跨度、不记 `redactions_applied_total`、不参与解重叠、也不参与档位盖章(候选不存在,所以不盖住也不截断别的候选)。取舍在池收尾的一处({@link armPool}:收集之后、解重叠之前;读的是臂收上来的原始起点,经 {@link StartReach} 问回原文下标),
135
+ * 臂自己只管把未决那一支标出来({@link SecretSpan.undecided})。
136
+ * 未决只有两种,同读一条臂:
133
137
  * ① **收尾没见到** —— JSON 串值(要收尾引号)· URL authority(要 `@`;authority 一路走到末尾没有 `/` / 空白,里面有没有 `@` 都读成还在 userinfo 里)·
134
138
  * SSH2 / PEM 栅栏(要收尾栅栏)· 带引号的强锚值(要收尾引号)· PuTTY 容器(终止符之后到末尾没见下一个版本头);
135
139
  * ② **起头没读完**(起头本身不设长度上界,起点可以离末尾很远)—— PEM 起始栅栏行(标签之后到末尾一枚 `-----` 都没有,已读到的部分也还可能是合法栅栏行的前缀)· PuTTY 版本头(`<数字串>: ` 没写完)·
136
- * 无头 .ppk 字段(`Private-Lines: <数字串>` 之后下一个体行的判定没走完)。
140
+ * 无头 .ppk 字段(`Private-Lines: <数字串>` 之后下一个体行的判定没走完)· 词法关键字臂(`Bearer` / `Basic` / `token`)的起头(完整关键字之后跟着不设长度上界的分隔段、值被窗尾切在窗外,见 {@link undecidedKeywordStart};
141
+ * 关键字写了一半 / 关键字紧贴值的起点离窗尾至多几十个字符,不另立一支)。
137
142
  * PuTTY 容器臂的「无合格终止 ⇒ 吃到输入末尾」本来就是这一律在整段文本上的形,两种范围都吃到末尾;区别只在留痕 —— 整段读法上它是兜底(记 `server.redact.ppk-eat-to-end`),
138
143
  * head 读法上终止可能在更远处,是未决(不记)。**未决一律不记 fail-open**:它是这一律的正常读数,不是回退;
139
- * 由裸形 / 关键字 / 查询参数 / 环境变量赋值等**不靠收尾**的臂认出的凭据(值到字符类的自然右界)两种范围读法逐字相同。
144
+ * 由裸形 / 关键字 / 查询参数 / 环境变量赋值等**不靠收尾**的臂认出的凭据(值到字符类的自然右界)两种范围读法逐字相同;关键字臂只多上面 ② 里那一条未决尾。
140
145
  */
141
- export type RedactionExtent = "whole" | "head";
146
+ export type RedactionExtent = {
147
+ readonly kind: "whole";
148
+ } | {
149
+ readonly kind: "head";
150
+ readonly emitEnd: number;
151
+ };
152
+ /** 整段读法(`RedactionExtent` 的 `whole` 形;不带数据,一个值)。 */
153
+ export declare const WHOLE_EXTENT: RedactionExtent;
142
154
  /**
143
155
  * 🔴 **出口座扫描窗的单位 = 读法单元,不是原始码元**(修复验证腿 high ①):从 `from`(缺省 0)起数 `units` 个**读法单元**(各读法里最少的那一读 —— 删得最多的 —— 剩下的码元),
144
156
  * 返回原文里的终点(含 `≥ units` 个读法单元的前缀,至多是最短那一个的两倍;文本不够长 ⇒ `text.length`)。格式字符 / 控制字符 / 转义写法的不可见字符不计数:它们在读法格里被删,