@sema-agent/core 5.56.0 → 5.58.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 (208) hide show
  1. package/CHANGELOG.md +122 -0
  2. package/dist/agents/cascade.d.ts +1 -1
  3. package/dist/agents/cumulative-stats.d.ts +1 -1
  4. package/dist/agents/observer.d.ts +2 -2
  5. package/dist/agents/peer-admission.d.ts +1 -1
  6. package/dist/agents/retain-ledger.d.ts +2 -2
  7. package/dist/agents/roster-store.d.ts +8 -8
  8. package/dist/agents/send-message-tool.d.ts +13 -2
  9. package/dist/agents/send-message-tool.js +34 -12
  10. package/dist/agents/subagent-steps.d.ts +1 -1
  11. package/dist/agents/subagent.d.ts +13 -13
  12. package/dist/agents/team.d.ts +15 -6
  13. package/dist/agents/team.js +1 -0
  14. package/dist/agents/tool-filter.d.ts +2 -2
  15. package/dist/agents/verify.d.ts +1 -1
  16. package/dist/bench/metrics.d.ts +35 -35
  17. package/dist/brain/anthropic.js +15 -5
  18. package/dist/brain/circuit-breaker.js +2 -1
  19. package/dist/brain/degrading.d.ts +1 -1
  20. package/dist/brain/degrading.js +4 -1
  21. package/dist/brain/errors.d.ts +3 -3
  22. package/dist/brain/failover.js +16 -1
  23. package/dist/brain/open-responses.js +15 -5
  24. package/dist/brain/openai.js +16 -5
  25. package/dist/brain/reasoning.d.ts +2 -2
  26. package/dist/brain/repetition.d.ts +1 -1
  27. package/dist/brain/request-params.d.ts +30 -27
  28. package/dist/brain/request-params.js +1 -7
  29. package/dist/brain/route-adjudicator.d.ts +190 -0
  30. package/dist/brain/route-adjudicator.js +189 -0
  31. package/dist/brain/route-conformance.d.ts +55 -0
  32. package/dist/brain/route-conformance.js +136 -0
  33. package/dist/brain/routing.js +8 -3
  34. package/dist/brain/status-sink.d.ts +2 -2
  35. package/dist/brain/stream-shared.d.ts +1 -1
  36. package/dist/config/catalog.d.ts +5 -5
  37. package/dist/core/arg-summary.d.ts +4 -4
  38. package/dist/core/ask-class.d.ts +2 -2
  39. package/dist/core/ask-question.d.ts +1 -1
  40. package/dist/core/auto-compaction.d.ts +15 -15
  41. package/dist/core/auto-mode.d.ts +5 -5
  42. package/dist/core/background-agent-store.d.ts +20 -20
  43. package/dist/core/background-shell.d.ts +4 -4
  44. package/dist/core/checkpoint-store.d.ts +35 -27
  45. package/dist/core/context-edit.d.ts +1 -1
  46. package/dist/core/context-guard.d.ts +1 -1
  47. package/dist/core/exec-output-tail.d.ts +6 -6
  48. package/dist/core/file-snapshot-store.d.ts +8 -8
  49. package/dist/core/git-worktree-env.d.ts +3 -3
  50. package/dist/core/governance-codes.js +2 -0
  51. package/dist/core/hooks.d.ts +73 -33
  52. package/dist/core/hooks.js +87 -25
  53. package/dist/core/image-downsample.d.ts +1 -1
  54. package/dist/core/locked-config.d.ts +1 -1
  55. package/dist/core/lsp.d.ts +1 -1
  56. package/dist/core/mailbox-store.d.ts +1 -1
  57. package/dist/core/mcp.d.ts +3 -3
  58. package/dist/core/mcp.js +4 -4
  59. package/dist/core/memory-engine/consolidation-driver.d.ts +207 -0
  60. package/dist/core/memory-engine/consolidation-driver.js +378 -0
  61. package/dist/core/memory-engine/consolidation.d.ts +46 -2
  62. package/dist/core/memory-engine/consolidation.js +1 -0
  63. package/dist/core/memory-engine/data-plane.d.ts +1 -1
  64. package/dist/core/memory-engine/distiller.d.ts +550 -0
  65. package/dist/core/memory-engine/distiller.js +598 -0
  66. package/dist/core/memory-engine/dual-root.d.ts +1 -1
  67. package/dist/core/memory-engine/engine.d.ts +62 -8
  68. package/dist/core/memory-engine/engine.js +40 -4
  69. package/dist/core/memory-engine/file-backend.d.ts +1 -1
  70. package/dist/core/memory-engine/index.d.ts +4 -2
  71. package/dist/core/memory-engine/index.js +4 -2
  72. package/dist/core/memory-engine/origin-clearance.d.ts +1 -1
  73. package/dist/core/memory-engine/scope-contract.d.ts +4 -4
  74. package/dist/core/memory-engine/sync-client.d.ts +16 -16
  75. package/dist/core/memory-engine/sync.d.ts +4 -4
  76. package/dist/core/memory-recall.d.ts +1 -1
  77. package/dist/core/memory.d.ts +2 -2
  78. package/dist/core/permission-rule-consent.d.ts +230 -36
  79. package/dist/core/permission-rule-consent.js +258 -54
  80. package/dist/core/permission-rule-model.d.ts +295 -97
  81. package/dist/core/permission-rule-model.js +132 -41
  82. package/dist/core/permission-rules.d.ts +9 -9
  83. package/dist/core/remote-env.d.ts +8 -8
  84. package/dist/core/roles.d.ts +3 -3
  85. package/dist/core/roles.js +1 -0
  86. package/dist/core/runner/assemble-result.d.ts +2 -2
  87. package/dist/core/runner/compaction-call-options.d.ts +3 -3
  88. package/dist/core/runner/memory-consolidation-driver.d.ts +49 -0
  89. package/dist/core/runner/memory-consolidation-driver.js +60 -0
  90. package/dist/core/runner/memory-consolidation.d.ts +1 -1
  91. package/dist/core/runner/prepare-config-doors.d.ts +3 -3
  92. package/dist/core/runner/prepare-task.d.ts +21 -21
  93. package/dist/core/runner/prepare-task.js +54 -18
  94. package/dist/core/runner/prepare-workspace-restore.d.ts +2 -2
  95. package/dist/core/runner/runtask.d.ts +15 -12
  96. package/dist/core/runner/runtask.js +48 -0
  97. package/dist/core/runner/session-rule-policy.d.ts +1 -1
  98. package/dist/core/runner/teardown-bounded.d.ts +1 -1
  99. package/dist/core/runner/tool-disclosure.d.ts +2 -2
  100. package/dist/core/runner/turn-attachments.d.ts +11 -11
  101. package/dist/core/scheduler.d.ts +10 -5
  102. package/dist/core/secret-env.d.ts +1 -1
  103. package/dist/core/sensitive-path-policy.d.ts +1 -1
  104. package/dist/core/session-policy-store.d.ts +2 -2
  105. package/dist/core/session-reconcile.d.ts +2 -2
  106. package/dist/core/session-store.d.ts +3 -3
  107. package/dist/core/session.d.ts +1 -1
  108. package/dist/core/shutdown-debug.d.ts +2 -2
  109. package/dist/core/side-query.d.ts +14 -7
  110. package/dist/core/spec-contract.d.ts +1 -1
  111. package/dist/core/store-contracts/contract-harness.d.ts +2 -2
  112. package/dist/core/store-contracts/contract-kit-version.d.ts +2 -2
  113. package/dist/core/store-contracts/mailbox-store-contract.d.ts +1 -1
  114. package/dist/core/store-contracts/mailbox-store-contract.js +1 -1
  115. package/dist/core/task-notification.d.ts +5 -5
  116. package/dist/core/task-registry-agent.d.ts +12 -12
  117. package/dist/core/task-registry-monitor.d.ts +1 -1
  118. package/dist/core/task-registry-shared.d.ts +41 -41
  119. package/dist/core/task-registry.d.ts +12 -12
  120. package/dist/core/tool-detach.d.ts +2 -2
  121. package/dist/core/tool-errors.d.ts +3 -3
  122. package/dist/core/tool-policy.d.ts +55 -28
  123. package/dist/core/tool-result-budget.d.ts +1 -1
  124. package/dist/core/tool-result-store.d.ts +2 -2
  125. package/dist/core/tools.d.ts +1 -1
  126. package/dist/core/trace.d.ts +26 -23
  127. package/dist/core/types.d.ts +155 -70
  128. package/dist/core/untrusted-egress.d.ts +1 -1
  129. package/dist/core/untrusted-text.d.ts +7 -7
  130. package/dist/core/wiring-manifest.d.ts +5 -5
  131. package/dist/core/workflow-journal-store.d.ts +14 -14
  132. package/dist/core/workflow-run-store-contract.d.ts +1 -1
  133. package/dist/core/workflow-run-store-contract.js +1 -1
  134. package/dist/core/workflow-run-store.d.ts +4 -4
  135. package/dist/engine/compaction/compaction.d.ts +3 -3
  136. package/dist/engine/compaction/utils.d.ts +2 -2
  137. package/dist/engine/execution-env/kill-tree.d.ts +1 -1
  138. package/dist/engine/execution-env/node-execution-env.d.ts +8 -8
  139. package/dist/engine/harness/agent-harness.d.ts +6 -6
  140. package/dist/engine/harness/agent-harness.js +26 -1
  141. package/dist/engine/harness/messages.d.ts +1 -1
  142. package/dist/engine/harness/types.d.ts +15 -11
  143. package/dist/engine/llm/types.d.ts +79 -14
  144. package/dist/engine/loop/agent-loop.d.ts +3 -3
  145. package/dist/engine/loop/types.d.ts +4 -4
  146. package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
  147. package/dist/engine/session/import-validate.d.ts +1 -1
  148. package/dist/engine/session/log-digest.d.ts +1 -1
  149. package/dist/engine/session/memory-repo.d.ts +2 -2
  150. package/dist/engine/session/session.d.ts +4 -4
  151. package/dist/fixtures/index.d.ts +4 -4
  152. package/dist/index.d.ts +8 -4
  153. package/dist/index.js +5 -2
  154. package/dist/internal/llm.d.ts +1 -1
  155. package/dist/orchestration/goal.d.ts +1 -1
  156. package/dist/orchestration/run-spec.d.ts +1 -1
  157. package/dist/orchestration/run-workflow-tool.d.ts +12 -12
  158. package/dist/orchestration/workflow-governance.d.ts +4 -4
  159. package/dist/orchestration/workflow-observe.d.ts +1 -1
  160. package/dist/orchestration/workflow-script-runner.d.ts +1 -1
  161. package/dist/orchestration/workflow-script-store.d.ts +9 -9
  162. package/dist/orchestration/workflow-size-guideline.d.ts +1 -1
  163. package/dist/orchestration/workflow-types.d.ts +5 -5
  164. package/dist/orchestration/workflow.d.ts +10 -10
  165. package/dist/prompt-assembly/artifact-store.d.ts +1 -1
  166. package/dist/prompt-assembly/artifact.d.ts +1 -1
  167. package/dist/prompt-assembly/assemble.d.ts +1 -1
  168. package/dist/prompt-assembly/composer.d.ts +2 -2
  169. package/dist/prompt-assembly/epoch.d.ts +2 -2
  170. package/dist/prompt-assembly/event-registry.d.ts +1 -1
  171. package/dist/prompt-assembly/explain.d.ts +3 -3
  172. package/dist/prompt-assembly/tool-catalog.d.ts +1 -1
  173. package/dist/prompt-assembly/turn-snapshot.d.ts +4 -4
  174. package/dist/prompt-assembly/types.d.ts +12 -12
  175. package/dist/prompts/coordinator.d.ts +1 -1
  176. package/dist/prompts/default.d.ts +10 -10
  177. package/dist/prompts/default.js +2 -0
  178. package/dist/prompts/simple-sections.d.ts +3 -3
  179. package/dist/prompts/supervisor.d.ts +2 -2
  180. package/dist/scenarios/full-body.d.ts +3 -3
  181. package/dist/scenarios/scenario-registry.d.ts +6 -2
  182. package/dist/scenarios/scenario-registry.js +4 -2
  183. package/dist/stores/cc/sidecar-transcript.d.ts +3 -3
  184. package/dist/stores/file/fs-atomic.d.ts +2 -2
  185. package/dist/stores/file/index.d.ts +1 -1
  186. package/dist/stores/file/session-store.d.ts +2 -2
  187. package/dist/stores/file/workflow-journal-store.d.ts +4 -4
  188. package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -1
  189. package/dist/tools/fs/encoding.d.ts +4 -4
  190. package/dist/tools/fs/fs-bash.d.ts +3 -3
  191. package/dist/tools/fs/fs-pdf.d.ts +1 -1
  192. package/dist/tools/fs/fs-shared.d.ts +6 -6
  193. package/dist/tools/fs/index.d.ts +2 -2
  194. package/dist/tools/fs/index.js +8 -1
  195. package/dist/tools/fs/notebook.d.ts +1 -1
  196. package/dist/tools/fs/pdf.d.ts +1 -1
  197. package/dist/tools/fs/read-deny.d.ts +1 -1
  198. package/dist/tools/fs/safety.d.ts +9 -9
  199. package/dist/tools/fs/search.d.ts +2 -2
  200. package/dist/tools/monitor.d.ts +3 -3
  201. package/dist/tools/scheduler-tools.js +28 -6
  202. package/dist/tools/task-list.d.ts +2 -2
  203. package/dist/tools/web.d.ts +19 -4
  204. package/dist/tools/web.js +8 -2
  205. package/dist/tools/worktree.d.ts +5 -5
  206. package/dist/tools/worktree.js +2 -2
  207. package/package.json +1 -1
  208. package/test/export-surface.snapshot.json +74 -3
@@ -156,7 +156,7 @@ export declare function screenApproverAttribution(v: unknown): {
156
156
  * denied) so a deny OBSERVER (`Hooks.permissionDenied`) sees the final post-rewrite args, not the
157
157
  * stale un-redacted ones.
158
158
  * - `ask` requests human confirmation; with no approver wired it resolves deterministically to deny
159
- * (headless auto-deny, see `RunnerDeps.onAsk`). `requiresRealApproval: true` (RB-203 codex review,
159
+ * (headless auto-deny, see `RunnerDeps.onAsk`). `requiresRealApproval: true` (RB-203
160
160
  * confirmed P1) additionally refuses to let a BLANKET `onAsk: "allow"` circumvention clear it — that
161
161
  * configuration is "no approver looked at this at all", indistinguishable from headless, for a rule
162
162
  * whose whole point is that a blanket policy setting must not be the thing that clears it (see
@@ -200,7 +200,8 @@ export type PermissionResult = {
200
200
  /** #144 disclosure (additive): a persisted allow rule MATCHED this call but could not clear the
201
201
  * ask, because the ask is MANDATED (operator shellGate:"always", or the tool's own
202
202
  * egress/irreversibility marks) rather than a classifier's hesitation — "allow rules silence
203
- * the classifier's questions, never a mandated one". Carries the matched rule text so a
203
+ * the classifier's questions, never a mandated one". Carries the matched rule text a covering
204
+ * SET (conjunction arm) joins up to five sanitized member texts with an "and N more" tail — so a
204
205
  * consumer (approval card, wire frame) can tell the person their rule is alive, just outranked.
205
206
  * Absent ⇒ no rule matched, or the ask was cleared normally. */
206
207
  persistedRuleShadowed?: string;
@@ -235,6 +236,16 @@ export type PermissionResult = {
235
236
  * about itself is not evidence). Carried onto the approval request by the gate's own ask mint
236
237
  * site. Display/reconciliation metadata, never adjudication input. */
237
238
  ruleEvidence?: AskRuleEvidence;
239
+ /** design/375 §5.2②: the per-segment coverage table behind this surviving ask — which segments
240
+ * of a compound an eligible persisted rule already admits, read off the SAME store read that
241
+ * adjudicated the call (snapshot = adjudication snapshot). ENGINE-STAMPED at the gate's one
242
+ * stamp point whenever the persisted-rule lane reported one (overwriting a policy's claim);
243
+ * consumed only by the offer factory, which puts on the batch offer exactly the segments this
244
+ * table calls uncovered. Absent ⇒ all segments read as uncovered (over-offer, the safe way).
245
+ * Same display-only posture as {@link persistedRuleShadowed}: never adjudication input, and a
246
+ * value nobody stamps over can only shrink or annotate the card's ADVISORY offers — every
247
+ * offered rule still passes the validator at redemption. */
248
+ segmentCoverage?: readonly import("./permission-rule-model.js").SegmentCoverage[];
238
249
  } | {
239
250
  action: "deny";
240
251
  updatedInput?: unknown;
@@ -299,7 +310,9 @@ export interface AskRuleEvidence {
299
310
  /** Present iff {@link orgRule} is not. */
300
311
  readonly orgRuleAbsent?: AskEvidenceAbsence;
301
312
  /** The add dots of the PERSONAL allow rule that matched this call but did not clear the ask (the
302
- * #144 shadowed arm). The dots are the rule's durable identity unlike
313
+ * #144 shadowed arm) the deduplicated UNION across the covering set when the conjunction arm
314
+ * matched, so the array does not belong to one rule on those asks. The dots are the rule's durable
315
+ * identity — unlike
303
316
  * {@link AskRequest.persistedRuleShadowed}, which is a sanitized, length-capped DISPLAY value and
304
317
  * deliberately not an identity channel. A rule is a set of adds (concurrent approvals on one text
305
318
  * each redeem their own dot), so this is an array by construction: render/reconcile the entries as
@@ -425,7 +438,7 @@ export declare function checkToolPolicyProjection(projection: Pick<ToolPolicyPro
425
438
  * load-bearing — the chain digest binds the ORDERED topology (layer boundaries included), so an
426
439
  * opaque layer's position is part of what a resume re-supply must reproduce.
427
440
  *
428
- * F-012 (codex round 12): each entry ALSO carries the serializable DECISION-CHAIN METADATA posture —
441
+ * F-012: each entry ALSO carries the serializable DECISION-CHAIN METADATA posture —
429
442
  * whether the layer was classifier-armed (`autoModeArmed`) and its durable-mandate / content-mandate
430
443
  * flags. The digest binds these, so a cross-process resume re-supplying a same-shape chain whose
431
444
  * projections match but whose classifier was DROPPED (or whose mandate posture changed) — a
@@ -614,7 +627,7 @@ export declare function combinePolicies(...policies: ToolPolicy[]): ToolPolicy;
614
627
  * gate at all; the same substitution makes `rm -rf ~/.ai-agent/sessions` a way to erase the audit trail.
615
628
  */
616
629
  /**
617
- * RB-153 (server [1708]): EXPORTED. A downstream governance layer keeps its own copy of this list so its
630
+ * RB-153: EXPORTED. A downstream governance layer keeps its own copy of this list so its
618
631
  * per-command ask-list gates the same tools core does, and it had no way to read the real one — its guard
619
632
  * had to probe a hand-written candidate list of names, which stays green for any name nobody thought to
620
633
  * put in it. The list itself is the fact; publishing it removes the guess.
@@ -721,7 +734,7 @@ export declare function findUnverifiableRecursiveDelete(command: string, safeVar
721
734
  * (`decisionReason: "classifier"`, fully audited), an `allow` verdict still requires a live classifier to
722
735
  * have actually cleared it, and "no classifier configured" still means deny.
723
736
  *
724
- * codex review (confirmed P1): the one piece of NEW plumbing this DOES need — `requiresRealApproval: true`
737
+ * A review-confirmed P1 gap: the one piece of NEW plumbing this DOES need — `requiresRealApproval: true`
725
738
  * (see {@link PermissionResult}'s `ask` doc) — closes a real gap the first cut of this fix missed. A
726
739
  * deployment using the documented `onAsk: "allow"` circumvention mode (sandbox-is-the-boundary posture, the
727
740
  * shape a sandboxed autonomy container runs) would otherwise have this rule's `ask` rubber-stamped by that blanket
@@ -790,8 +803,11 @@ export interface AskDelegationProvenance {
790
803
  export interface AskRequest {
791
804
  toolName: string;
792
805
  /** #144: a persisted allow rule MATCHED this call but could not clear the ask (mandated — see
793
- * {@link PermissionResult}'s ask arm). The matched rule text, so the approval card renders "your
794
- * rule is alive, just outranked" instead of leaving the person to regex the message prose. */
806
+ * {@link PermissionResult}'s ask arm). The matched rule text — or, when a covering SET admitted the
807
+ * command segment-wise (the conjunction arm), a comma-joined display list of up to five sanitized
808
+ * rule texts with an "and N more" tail — so the approval card renders "your rule is alive, just
809
+ * outranked" instead of leaving the person to regex the message prose. A DISPLAY value, not an
810
+ * identity channel: per-rule identity travels on {@link AskRuleEvidence.personalRuleDots}. */
795
811
  persistedRuleShadowed?: string;
796
812
  /** backlog #239: WHY the reversibility probe did not clear this call — the account of the tighten the
797
813
  * card was showing WITHOUT until now (the gate knew the cause and dropped it at this seam, leaving the
@@ -819,7 +835,7 @@ export interface AskRequest {
819
835
  toolCallId: string;
820
836
  /** The (post-rewrite) args the tool would run with. */
821
837
  args: unknown;
822
- /** [1245] — the tool's approval display projection of {@link args} (AgentTool.approvalPreview),
838
+ /** the tool's approval display projection of {@link args} (AgentTool.approvalPreview),
823
839
  * clamped + control-char-sanitized by the gate. **UNTRUSTED, ADVISORY display metadata**: render
824
840
  * with contextual escaping and show {@link args} alongside — the preview can misrepresent the
825
841
  * executable action and never replaces args. Never adjudication input. */
@@ -834,24 +850,35 @@ export interface AskRequest {
834
850
  * invoke its approver function directly. */
835
851
  readonly boundInputHash?: string;
836
852
  /**
837
- * design/179 §4 — the persistable allow-rule forms this exact call could be covered by, so a surface can
838
- * offer "allow, and stop asking me this" with something concrete behind it. Present only when a
839
- * persisted allow-rule lane is armed AND the call is one the lane can speak for (a compound, a
840
- * redirection or a substitution yields NO suggestion, which is the honest answer rather than an option
841
- * that would be refused on redemption) AND the ask is one a persisted rule could actually clear — a
842
- * mandated ask (operator shellGate:"always", the tool's own egress/irreversibility marks, a
853
+ * design/179 §4, re-formed by design/375 §3.1 (BREAKING this seat REPLACES the retired
854
+ * `ruleSuggestions` key, which is never emitted again; the new name is the safe failure posture for
855
+ * the hard-cut window: a consumer that has not upgraded simply renders no "don't ask again" row,
856
+ * fail toward asking, instead of mis-rendering a consent surface through its old parser) the
857
+ * persistable allow-rule OFFERS this exact call could be covered by, so a surface can render
858
+ * "allow, and stop asking me this" with something concrete behind it. Present only when a persisted
859
+ * allow-rule lane is armed AND the call is one the lane can speak for (a redirection or a
860
+ * substitution yields NO offer, which is the honest answer rather than an option that would be
861
+ * refused on redemption) AND the ask is one a persisted rule could actually clear — a mandated ask
862
+ * (operator shellGate:"always", the tool's own egress/irreversibility marks, a
843
863
  * `requiresRealApproval` demand) and an ask carrying {@link persistedRuleShadowed} offer none.
844
864
  *
845
- * CONTRACT — array order is display order, narrowest first: the EXACT form is always index 0, a
846
- * broader reviewed PREFIX form (at most one) follows. Basis 2. Selection indices and redemption
847
- * tickets are keyed against this order, and the durable park row carries the same array under the
848
- * same contract.
865
+ * CONTRACT — see {@link import("./permission-rule-model.js").RuleOffer} for the closed union, the
866
+ * per-element parse/degrade rules and the original-index-keying obligation. Array order is display
867
+ * order: at most 2 offers, the whole-string EXACT single always index 0 when present, the BATCH
868
+ * offer (a compound's per-segment conjunction — choosing it is one yes to all of its 1..5 rules at
869
+ * once) always last. Selection indices (`confirmRuleApproval`'s `selectedOffer`) are keyed
870
+ * against this order; redemption TICKETS are NOT — they key on the consent record's flat
871
+ * CANDIDATE list (a batch's members each carry their own ticket), so a chosen offer is redeemed
872
+ * via `redeemRuleBatch`, never by indexing a ticket array with an offer index. The durable park
873
+ * row carries the same array under the same contract.
849
874
  *
850
875
  * ADVISORY display metadata, never adjudication input, and never a rule by itself: minting one is a
851
876
  * separate act that goes through the approval-record protocol, so a surface that ignores this field
852
- * changes nothing about what is allowed.
877
+ * changes nothing about what is allowed. The AUTHORITATIVE render source for a consent card is the
878
+ * PREPARED approval record's own offers; this member is the ask-time projection, which may drift
879
+ * from it across a coverage change — harmlessly, since the record is what gets confirmed.
853
880
  */
854
- readonly ruleSuggestions?: readonly import("./permission-rule-model.js").RuleSuggestion[];
881
+ readonly ruleOffers?: readonly import("./permission-rule-model.js").RuleOffer[];
855
882
  /** The human/model-readable prompt explaining what needs approval. */
856
883
  message: string;
857
884
  /** Runner-filled source identity (design S1d §1): the end-user {@link AskRequest} issuing task's
@@ -868,7 +895,7 @@ export interface AskRequest {
868
895
  * Runner mints it); a top-level caller MAY continue its own session id via `TaskSpec.sessionId`, so this
869
896
  * is NOT a global "never forgeable" run id — aggregation only aggregates delegated workers, the context
870
897
  * where it holds (design S1d §1.3). `readonly` + same sync-path-only / P-a caveat as `principal`.
871
- * Undefined ⇒ no source task id. **NOT a subagent discriminator** ([1546] MED-1: the HOST's own asks
898
+ * Undefined ⇒ no source task id. **NOT a subagent discriminator** (the HOST's own asks
872
899
  * carry it too — it is always the issuing task's session id); "from a background agent" attribution
873
900
  * keys on {@link fromSubagent}, never on this field's presence. */
874
901
  readonly sourceTaskId?: string;
@@ -892,7 +919,7 @@ export interface AskRequest {
892
919
  * non-fork facet of `effectiveDelegationFacts`, serving the authority/context faces, excludes it), but
893
920
  * its interaction contract is one-shot — "report once and stop … no waiting for the user"
894
921
  * (FORK_DIRECTIVE_FRAME) — so a stop-and-wait refusal would instruct it to do the impossible
895
- * (codex adversarial round, confirmed). NOT the same fact as {@link fromSubagent} either: that is
922
+ * (confirmed). NOT the same fact as {@link fromSubagent} either: that is
896
923
  * the design/153 attribution discriminator (`parentTaskId` presence), which a directly-started
897
924
  * workflow's children lack even though refusals must still speak the child posture to them.
898
925
  * `readonly`, trusted (internals never ride a TaskSpec), sync-path-only like its siblings.
@@ -903,7 +930,7 @@ export interface AskRequest {
903
930
  * - `isDelegatedChild` — REFUSAL POSTURE: "no user turn ever lands in this run's transcript";
904
931
  * drives which deny text the model is told (stop-and-wait vs adapt-or-report), forks included. */
905
932
  readonly isDelegatedChild?: true;
906
- /** RB-203 (codex review, confirmed P1) — carried from the originating {@link PermissionResult}'s ask
933
+ /** RB-203 (confirmed P1) — carried from the originating {@link PermissionResult}'s ask
907
934
  * variant of the same name: `true` ⇒ {@link resolveAsk} must not let a blanket `onAsk: "allow"`
908
935
  * clear this ask (see that field's doc). `readonly`, filled by the gate from the decision, never a
909
936
  * caller/worker-settable field. */
@@ -933,7 +960,7 @@ export interface AskRequest {
933
960
  * - `"allow"` — auto-approve every `ask` (e.g. a trusted batch run).
934
961
  * - a function — await an operator's decision (true=allow, false=deny). `signal` fires when the task
935
962
  * aborts; race your wait against it so an unanswered ask is released at the deadline, not hung.
936
- * G1 three-value ([871]①): the function may also return `"unavailable"` — an affirmative "no operator
963
+ * G1 three-value: the function may also return `"unavailable"` — an affirmative "no operator
937
964
  * is reachable for THIS ask right now" (judged PER-ASK inside the callback, not at wire time). It is a
938
965
  * ROUTING verdict, not a decision: the gate re-routes the ask onto the durable park leg (same behavior
939
966
  * as if no live approver were wired — checkpoint + suspend, the 1.293 fallback), and when no park
@@ -948,7 +975,7 @@ export interface AskRequest {
948
975
  */
949
976
  export type OnAsk = "deny" | "allow" | ((req: AskRequest, signal?: AbortSignal) => AskOutcome | Promise<AskOutcome>);
950
977
  /**
951
- * What an `onAsk` approver may return ([1458]/[1462] object arm):
978
+ * What an `onAsk` approver may return (object arm):
952
979
  * - `boolean` — plain verdict (true=allow, false=deny). STRICT fold (RB-482 #17, server bridge
953
980
  * zero-ripple confirmed): only the literal `true` approves; an out-of-contract truthy from an
954
981
  * untyped bridge is a fail-closed deny naming the defect (the historical truthy leniency was a
@@ -982,7 +1009,7 @@ export type OnAsk = "deny" | "allow" | ((req: AskRequest, signal?: AbortSignal)
982
1009
  * input), relayed to the model so it can follow the person's direction instead of guessing. In-place
983
1010
  * conditions, all screened at {@link resolveAsk}:
984
1011
  * - meaningful ONLY on a deny (`allow: false`); on an allow the seat is NEVER READ (accepted and
985
- * unused, literally — codex round: a junk value or a throwing accessor riding an approval cannot
1012
+ * unused, literally: a junk value or a throwing accessor riding an approval cannot
986
1013
  * destroy the approval). Same net posture as the durable leg, where a `reason` on an `allow` row
987
1014
  * is never rendered;
988
1015
  * - UNTRUSTED input (a human's free text riding a callback): it reaches the model only inside a
@@ -1128,7 +1155,7 @@ export declare function coreMintedResolutionOf(d: unknown, call: {
1128
1155
  */
1129
1156
  export type ResolvedAsk = PermissionResult & {
1130
1157
  approverUnavailable?: true;
1131
- /** [1462] r5 — the EXACT data snapshot the approver was shown (the `structuredClone` of the
1158
+ /** The EXACT data snapshot the approver was shown (the `structuredClone` of the
1132
1159
  * presented args). On a plain approval (no edit) the gate EXECUTES this snapshot, not the original
1133
1160
  * object: a stateful getter or an external alias must not be able to make the executed action
1134
1161
  * differ from the approved one (shown == executed, by construction). Set only on the
@@ -27,7 +27,7 @@ export interface AggregateBudgetOptions {
27
27
  store?: ToolResultStore;
28
28
  /** Namespaces the stable ref so an offloaded result is globally addressable. */
29
29
  sessionId: string;
30
- /** service [398] C8: fired once per result actually capped (offloaded OR degraded to a truncation
30
+ /** C8: fired once per result actually capped (offloaded OR degraded to a truncation
31
31
  * preview). `storeFallback` = the model LOST read-back for this result (store.put failed / no store)
32
32
  * — the silent-degradation face this callback exists for. Must not throw (caller-side contract). */
33
33
  onCapped?: (info: {
@@ -310,7 +310,7 @@ export interface ToolResultSlice {
310
310
  }
311
311
  /** Default in-memory store (no cross-process durability); write-once per ref.
312
312
  *
313
- * Blackboard 2026-07-03 (clay dogfood: `ReadToolResult(ref)` came back empty for a workflow child's
313
+ * Field-reported (`ReadToolResult(ref)` came back empty for a workflow child's
314
314
  * offloaded output): the Runner now shares ONE instance across its tasks (instead of a per-task
315
315
  * island), so a parent can deref a child's ref within the process. A shared long-lived instance
316
316
  * needs a bound — `maxTotalChars` FIFO-evicts the oldest refs past the cap (an evicted deref lands
@@ -351,7 +351,7 @@ export declare class InMemoryToolResultStore implements ToolResultStore {
351
351
  export declare class RunnerSharedToolResultStore extends InMemoryToolResultStore {
352
352
  }
353
353
  /**
354
- * Per-task view over the Runner-shared fallback (impl-review 2026-07-03, codex 2 BLOCKER):
354
+ * Per-task view over the Runner-shared fallback (impl-review 2026-07-03):
355
355
  * 1. **Tenant isolation**: refs are namespaced by the task's trust scope (principal), so tenant B's
356
356
  * `ReadToolResult` can never deref tenant A's ref — the per-task-instance era made this isolation
357
357
  * implicit; sharing one instance re-opened it. Same-scope cross-task deref (the A2 fix's whole
@@ -2,7 +2,7 @@ import type { TSchema } from "typebox";
2
2
  import type { AgentTool } from "../internal/harness.js";
3
3
  import type { ToolExecuteContext, ToolSpec } from "./types.js";
4
4
  /**
5
- * E1(黑板 [1937],test/server/cli 三方交叉核实): wrap an already-built failure message string into the
5
+ * Wrap an already-built failure message string into the
6
6
  * `ToolReturn` shape that actually signals failure. A bare `string` return is UNCONDITIONALLY
7
7
  * `isError:false` (see `ToolReturn.isError`'s own doc comment) — the toolkit-wide survey found 120+
8
8
  * sites across fs/web/sql/scheduler/worktree/etc. that build a correct `"Error (...): ..."` message
@@ -87,11 +87,11 @@ export type TraceEvent = {
87
87
  hash: string;
88
88
  }>;
89
89
  /**
90
- * Manifest v2 (campaign S1, ADDITIVE — the v1 `blocks` id wordlist above is a downstream
90
+ * Manifest v2 (stage S1, ADDITIVE — the v1 `blocks` id wordlist above is a downstream
91
91
  * contract and stays as-is): the compiled-IR view, one entry per pack section, carrying the
92
92
  * assembly protocol's semantic/lifecycle dimensions (slot/carrier/cadence/cacheClass).
93
93
  * Absent on the legacy free-form provider path (single opaque block, no section structure).
94
- * `contentHash` (digest tiering, [1050]②): UNSALTED full sha256, present ONLY on
94
+ * `contentHash` (digest tiering): UNSALTED full sha256, present ONLY on
95
95
  * operator-declared sections (typed `stableBlocks` lane) — the center-publish ↔ manifest
96
96
  * reconciliation anchor. Core-native sections stay salted-only (`hash`).
97
97
  */
@@ -106,7 +106,7 @@ export type TraceEvent = {
106
106
  contentHash?: string;
107
107
  }>;
108
108
  /**
109
- * Campaign S2 (additive): the mounted tools plane — per-tool contract identity, durable-replay
109
+ * S2 (additive): the mounted tools plane — per-tool contract identity, durable-replay
110
110
  * aliases, presentation-invariant shape digest and full wire-schema digest (initial mount face;
111
111
  * deferred activations announce via tools_delta). Content-addressed digests (schemas are code).
112
112
  */
@@ -128,7 +128,7 @@ export type TraceEvent = {
128
128
  toolDisclosure?: ToolDisclosureManifest;
129
129
  ts: number;
130
130
  } | {
131
- /** design/148 S3 (codex F3) — a mid-run identity refresh (deferred materialization / RB-31
131
+ /** design/148 S3 — a mid-run identity refresh (deferred materialization / RB-31
132
132
  * adoption / finalize thinking flip): the trace stream must never keep claiming a superseded
133
133
  * prefix identity. Digests only, never prompt text. */
134
134
  kind: "prompt.snapshot_changed";
@@ -204,7 +204,7 @@ export type TraceEvent = {
204
204
  ts: number;
205
205
  } | {
206
206
  /**
207
- * Config-catalog manifest (clay ruling 2026-07-19) — the run's EFFECTIVE task-launch config
207
+ * Config-catalog manifest (ruled 2026-07-19) — the run's EFFECTIVE task-launch config
208
208
  * with per-field provenance (default / spec / derived / host-declared), emitted once right
209
209
  * after `prompt.assembled`. Kills the "which layer set this knob" archaeology: every run
210
210
  * self-reports its true scale, and host-layer overrides arrive as DECLARED entries
@@ -266,7 +266,7 @@ export type TraceEvent = {
266
266
  * loop breathes, so lateness this size means the environment starved the process (run89: an
267
267
  * abandoned compile group froze the loop 646s; the 1200s hard abort landed 683s late). */
268
268
  timerLatenessMs?: number;
269
- /** RB-20 (TB [991] b-form): the run was stopped by the SYNCHRONOUS turn-boundary walltime
269
+ /** RB-20 (TB b-form): the run was stopped by the SYNCHRONOUS turn-boundary walltime
270
270
  * backstop, not the hard-abort timer — i.e. the deadline had passed but the setTimeout leg
271
271
  * had not fired yet (starved event loop). Pairs with `timerLatenessMs` for attribution. */
272
272
  walltimeSyncBackstop?: boolean;
@@ -314,7 +314,7 @@ export type TraceEvent = {
314
314
  callStartedAt?: number;
315
315
  /** ABSENT when THIS call's serving model was unpriced (RB-368 — no fabricated 0). */
316
316
  costMicroUsd?: number;
317
- /** TB telemetry B1 (service [397]): the NORMALIZED finish reason of this call (`StopReason`:
317
+ /** TB telemetry B1: the NORMALIZED finish reason of this call (`StopReason`:
318
318
  * `"stop"`/`"length"`/`"toolUse"`/`"error"`/`"aborted"`). Post-normalization (Anthropic
319
319
  * `end_turn`/`stop_sequence`→`"stop"`, `max_tokens`→`"length"`). */
320
320
  stopReason?: string;
@@ -345,7 +345,7 @@ export type TraceEvent = {
345
345
  effect?: ToolEffect;
346
346
  ts: number;
347
347
  } | {
348
- /** Degenerate-repetition detector telemetry (clay 2026-07-10, 2e1c161 observability): a model
348
+ /** Degenerate-repetition detector telemetry (2026-07-10, 2e1c161 observability): a model
349
349
  * stream was CUT for a degenerate loop, or a repetition landed in a detection window but was
350
350
  * SPARED by a structural allowance (code-line shape / divider run). One event per detector hit. */
351
351
  kind: "repetition.detected";
@@ -386,17 +386,20 @@ export type TraceEvent = {
386
386
  ts: number;
387
387
  } | {
388
388
  /**
389
- * design/179 — a persisted allow rule resolved an ask, so no person was asked and no checkpoint was
390
- * minted. The gate has an attribution channel for the deny side and had none for the allow side;
391
- * this is that channel, because "why did this run without asking me?" must be answerable. Metadata
392
- * only (the rule text is the canonical rule spelling, never the command's arguments).
389
+ * design/179 — a persisted allow-rule COVERAGE resolved an ask, so no person was asked and no
390
+ * checkpoint was minted. The gate has an attribution channel for the deny side and had none for
391
+ * the allow side; this is that channel, because "why did this run without asking me?" must be
392
+ * answerable. Metadata only (each rule text is the canonical rule spelling, never the command's
393
+ * arguments). version 2 (design/375, BREAKING): `rule: string` became `rules: string[]` — a
394
+ * compound may now be admitted by the CONJUNCTION of per-segment rules, and the attribution names
395
+ * every rule the decision stood on (a single-rule resolution is a one-element array).
393
396
  */
394
397
  kind: "permission.persisted_rule_allowed";
395
- version: 1;
398
+ version: 2;
396
399
  taskId: string;
397
400
  toolName: string;
398
401
  toolCallId: string;
399
- rule: string;
402
+ rules: readonly string[];
400
403
  ts: number;
401
404
  } | {
402
405
  /**
@@ -571,12 +574,12 @@ export type TraceEvent = {
571
574
  trigger: "auto" | "manual";
572
575
  ts: number;
573
576
  } | {
574
- /** MF-18 修① [496]③ — a compaction pass FAILED: either a burned summary attempt threw
577
+ /** MF-18 修① — a compaction pass FAILED: either a burned summary attempt threw
575
578
  * (summarizer error / empty summary / oversized-summary guard; counted toward the §17.4
576
579
  * breaker) or a manual /compact was drained against an ALREADY-OPEN breaker (no attempt).
577
580
  * Before this frame the only evidence was `Runner.onError(phase:"compaction")` — a service
578
581
  * that acked the manual verb (202) but saw no `compacted` event had ZERO stream/trace signal
579
- * about why (the [496]③ fingerprint). */
582
+ * about why (the fingerprint). */
580
583
  kind: "compaction.failed";
581
584
  version: 1;
582
585
  taskId: string;
@@ -586,7 +589,7 @@ export type TraceEvent = {
586
589
  reason: string;
587
590
  ts: number;
588
591
  } | {
589
- /** MF-18 修① [496]③ — a manual /compact request was PROCESSED but MOOTED: the loop is dying
592
+ /** MF-18 修① — a manual /compact request was PROCESSED but MOOTED: the loop is dying
590
593
  * (abort fired / durable suspend / plan review in flight) so no compaction can run. The
591
594
  * compact() promise resolves "mooted"; this frame is the trace-side counterpart.
592
595
  * `reason:"cancelled"` (additive) — the caller withdrew an IN-FLIGHT request via
@@ -601,7 +604,7 @@ export type TraceEvent = {
601
604
  reason: "task_ending" | "cancelled";
602
605
  ts: number;
603
606
  } | {
604
- /** MF-18 修① [496]③ — a manual /compact attempt ran but found NOTHING to compact (no valid
607
+ /** MF-18 修① — a manual /compact attempt ran but found NOTHING to compact (no valid
605
608
  * cut point / empty history): `maybeCompact` returned a structural `{compacted:false}` on a
606
609
  * forced pass. Manual-only by design — an auto pass no-ops at nearly every boundary (spam). */
607
610
  kind: "compaction.noop";
@@ -609,7 +612,7 @@ export type TraceEvent = {
609
612
  taskId: string;
610
613
  ts: number;
611
614
  } | {
612
- /** MF-18 修① [496]③ — a manual /compact was processed while compaction is DISABLED by the
615
+ /** MF-18 修① — a manual /compact was processed while compaction is DISABLED by the
613
616
  * task spec (`compaction.enabled:false`): the request can never be honored this run. */
614
617
  kind: "compaction.disabled";
615
618
  version: 1;
@@ -667,7 +670,7 @@ export type TraceEvent = {
667
670
  taskId: string;
668
671
  ts: number;
669
672
  } | {
670
- /** MF-18 修② [496]③ — the summarization INPUT was truncated to fit the compaction model's
673
+ /** MF-18 修② — the summarization INPUT was truncated to fit the compaction model's
671
674
  * context window (the 300K-session shape that previously guaranteed a prompt-too-long throw
672
675
  * at every boundary). Fidelity disclosure: oldest `droppedChars` characters of the serialized
673
676
  * conversation were omitted from the summary prompt. */
@@ -708,8 +711,8 @@ export type TraceEvent = {
708
711
  durationMs: number;
709
712
  ts: number;
710
713
  } | {
711
- /** MF-18 修③ [496]③ — a compaction landed at the run's FINAL boundary and the one-shot
712
- * post-compact announce latch (background-task snapshot, G1 [482]) was never consumed: the
714
+ /** MF-18 修③ — a compaction landed at the run's FINAL boundary and the one-shot
715
+ * post-compact announce latch (background-task snapshot, G1) was never consumed: the
713
716
  * next collected boundary it waits for never came. The announce is lost for THIS run (a
714
717
  * follow-up run on the same session re-arms it from the session tail — see the resume
715
718
  * re-arm seed in runtask). */
@@ -758,7 +761,7 @@ export type TraceEvent = {
758
761
  /** C11 — a tool requested a human plan review (`ctx.requestReview()`) but the deployment cannot
759
762
  * honor it (no checkpoint store / loop already terminating): the request was consumed + DROPPED
760
763
  * (headless degrade). The HITL ask vanished with zero signal before this. NO free-text reason
761
- * field (codex MED: `requestReview({reason})` carries tool/model-authored text — the file-header
764
+ * field (`requestReview({reason})` carries tool/model-authored text — the file-header
762
765
  * metadata-only rule forbids it here; the fact of the drop is the signal). */
763
766
  kind: "review.dropped";
764
767
  version: 1;