@sema-agent/core 7.29.0 → 7.30.1

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 (158) hide show
  1. package/CHANGELOG.md +393 -0
  2. package/dist/agents/child-model-seat.d.ts +59 -7
  3. package/dist/agents/child-model-seat.js +33 -7
  4. package/dist/agents/cross-session-judge.d.ts +27 -5
  5. package/dist/agents/cross-session-judge.js +23 -12
  6. package/dist/agents/list-agents-tool.d.ts +31 -6
  7. package/dist/agents/list-agents-tool.js +66 -14
  8. package/dist/agents/peer-admission.d.ts +20 -8
  9. package/dist/agents/peer-admission.js +21 -12
  10. package/dist/agents/peer-directory.d.ts +29 -0
  11. package/dist/agents/peer-directory.js +20 -0
  12. package/dist/agents/peer-held-queue.d.ts +31 -4
  13. package/dist/agents/peer-held-queue.js +32 -1
  14. package/dist/agents/peer-session-drain.d.ts +91 -13
  15. package/dist/agents/peer-session-drain.js +409 -102
  16. package/dist/agents/read-inbox-tool.d.ts +22 -0
  17. package/dist/agents/read-inbox-tool.js +39 -0
  18. package/dist/agents/roster-store.d.ts +2 -4
  19. package/dist/agents/roster-store.js +1 -1
  20. package/dist/agents/send-message-tool.d.ts +4 -4
  21. package/dist/agents/send-message-tool.js +22 -2
  22. package/dist/agents/subagent.js +62 -44
  23. package/dist/agents/team-role.d.ts +34 -0
  24. package/dist/agents/team-role.js +17 -0
  25. package/dist/agents/verify.js +2 -2
  26. package/dist/core/auto-compaction.d.ts +42 -0
  27. package/dist/core/auto-compaction.js +35 -2
  28. package/dist/core/child-clamp-seats.d.ts +11 -0
  29. package/dist/core/child-clamp-seats.js +3 -0
  30. package/dist/core/context-edit.d.ts +3 -2
  31. package/dist/core/context-edit.js +6 -5
  32. package/dist/core/context-guard.d.ts +2 -1
  33. package/dist/core/context-guard.js +3 -2
  34. package/dist/core/context-settings.d.ts +103 -0
  35. package/dist/core/context-settings.js +60 -0
  36. package/dist/core/engine-notice.d.ts +11 -1
  37. package/dist/core/frame-settlement.d.ts +97 -0
  38. package/dist/core/frame-settlement.js +36 -0
  39. package/dist/core/governance-codes.d.ts +1 -1
  40. package/dist/core/governance-codes.js +2 -0
  41. package/dist/core/hooks.d.ts +10 -10
  42. package/dist/core/mailbox-store.d.ts +41 -7
  43. package/dist/core/mailbox-store.js +9 -3
  44. package/dist/core/parent-spec-seat.d.ts +14 -1
  45. package/dist/core/parent-spec-seat.js +6 -0
  46. package/dist/core/permission-rule-model.js +1 -1
  47. package/dist/core/roles.d.ts +20 -0
  48. package/dist/core/roles.js +35 -16
  49. package/dist/core/runner/assemble-result.d.ts +2 -0
  50. package/dist/core/runner/assemble-result.js +1 -1
  51. package/dist/core/runner/compaction-call-options.d.ts +26 -2
  52. package/dist/core/runner/compaction-call-options.js +9 -0
  53. package/dist/core/runner/compaction-seams.d.ts +4 -3
  54. package/dist/core/runner/compaction-seams.js +13 -6
  55. package/dist/core/runner/contracts.d.ts +56 -7
  56. package/dist/core/runner/decide-continuation.d.ts +2 -1
  57. package/dist/core/runner/decide-continuation.js +11 -10
  58. package/dist/core/runner/initial-run-state.js +1 -1
  59. package/dist/core/runner/prepare-caps-and-workflow.js +9 -1
  60. package/dist/core/runner/prepare-config-doors.js +4 -1
  61. package/dist/core/runner/prepare-context-lane.d.ts +9 -2
  62. package/dist/core/runner/prepare-context-lane.js +15 -10
  63. package/dist/core/runner/prepare-delegation-surface.d.ts +3 -2
  64. package/dist/core/runner/prepare-delegation-surface.js +9 -3
  65. package/dist/core/runner/prepare-file-history.js +10 -8
  66. package/dist/core/runner/prepare-gate-stations.d.ts +4 -0
  67. package/dist/core/runner/prepare-gate-stations.js +3 -1
  68. package/dist/core/runner/prepare-inherited-gate.js +1 -0
  69. package/dist/core/runner/prepare-prompt-inputs.d.ts +6 -0
  70. package/dist/core/runner/prepare-prompt-inputs.js +2 -1
  71. package/dist/core/runner/prepare-task.js +22 -9
  72. package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -1
  73. package/dist/core/runner/prepare-wiring-manifest.js +6 -1
  74. package/dist/core/runner/retired-runner-deps.d.ts +3 -1
  75. package/dist/core/runner/retired-runner-deps.js +1 -0
  76. package/dist/core/runner/run-compaction-machinery.d.ts +4 -2
  77. package/dist/core/runner/run-compaction-machinery.js +5 -3
  78. package/dist/core/runner/run-harness-handlers.js +1 -1
  79. package/dist/core/runner/run-identity-wiring.js +19 -1
  80. package/dist/core/runner/run-leg.js +1 -1
  81. package/dist/core/runner/run-notification-lane.js +8 -2
  82. package/dist/core/runner/run-recovery-lanes.js +9 -5
  83. package/dist/core/runner/run-settle-and-teardown.d.ts +4 -22
  84. package/dist/core/runner/run-settle-and-teardown.js +6 -10
  85. package/dist/core/runner/run-stop-and-final-verify.js +1 -0
  86. package/dist/core/runner/run-terminal-adoption.js +5 -5
  87. package/dist/core/runner/run-turn-boundary.js +32 -5
  88. package/dist/core/runner/runtask.d.ts +8 -1
  89. package/dist/core/runner/runtask.js +32 -1
  90. package/dist/core/runner-deps.d.ts +44 -13
  91. package/dist/core/secret-env.js +2 -1
  92. package/dist/core/swappable-deps.d.ts +20 -4
  93. package/dist/core/swappable-deps.js +6 -1
  94. package/dist/core/task-event.d.ts +5 -0
  95. package/dist/core/task-notification.d.ts +144 -2
  96. package/dist/core/task-notification.js +154 -5
  97. package/dist/core/task-result.d.ts +14 -0
  98. package/dist/core/task-spec.d.ts +7 -0
  99. package/dist/core/tool-catalog-entries.js +2 -1
  100. package/dist/core/tool-conformance.js +1 -0
  101. package/dist/core/tool-policy.d.ts +9 -4
  102. package/dist/core/tool-spec.d.ts +14 -0
  103. package/dist/core/wiring-manifest.d.ts +12 -0
  104. package/dist/core/wiring-manifest.js +5 -1
  105. package/dist/engine/harness/agent-harness.d.ts +14 -1
  106. package/dist/engine/harness/agent-harness.js +28 -3
  107. package/dist/engine/harness/types.d.ts +3 -1
  108. package/dist/engine/llm/types.d.ts +8 -7
  109. package/dist/engine/llm/types.js +1 -1
  110. package/dist/engine/lsp/node-lsp-manager.d.ts +3 -0
  111. package/dist/engine/lsp/node-lsp-manager.js +5 -3
  112. package/dist/engine/session/import-validate.js +4 -0
  113. package/dist/index.d.ts +10 -7
  114. package/dist/index.js +7 -5
  115. package/dist/orchestration/run-workflow-tool.d.ts +4 -4
  116. package/dist/orchestration/workflow.d.ts +1 -1
  117. package/dist/orchestration/workflow.js +8 -5
  118. package/dist/shell/lex.d.ts +38 -54
  119. package/dist/shell/lex.js +239 -286
  120. package/dist/stores/cc/mailbox-store.js +3 -2
  121. package/dist/stores/file/corrupt-read-sink.d.ts +28 -2
  122. package/dist/stores/file/file-history-store.d.ts +2 -4
  123. package/dist/stores/file/file-history-store.js +1 -1
  124. package/dist/stores/file/fs-atomic.d.ts +16 -11
  125. package/dist/stores/file/fs-atomic.js +17 -6
  126. package/dist/stores/file/index.d.ts +5 -6
  127. package/dist/stores/file/index.js +1 -1
  128. package/dist/stores/file/mailbox-store.d.ts +4 -9
  129. package/dist/stores/file/mailbox-store.js +29 -30
  130. package/dist/stores/file/session-policy-store.d.ts +2 -0
  131. package/dist/stores/file/session-policy-store.js +1 -1
  132. package/dist/stores/file/session-store.d.ts +11 -7
  133. package/dist/stores/file/session-store.js +23 -16
  134. package/dist/stores/file/shared-ledger.js +3 -14
  135. package/dist/stores/file/tool-result-store.d.ts +2 -0
  136. package/dist/stores/file/tool-result-store.js +5 -2
  137. package/dist/stores/file/workflow-journal-store.js +14 -9
  138. package/dist/tools/fs/bash-program-position.d.ts +15 -24
  139. package/dist/tools/fs/bash-program-position.js +11 -29
  140. package/dist/tools/fs/bash-readonly-classifier.d.ts +131 -117
  141. package/dist/tools/fs/bash-readonly-classifier.js +404 -272
  142. package/dist/tools/fs/shell-read-check.js +3 -3
  143. package/dist/tools/fs/shell-read-establish.d.ts +1 -1
  144. package/dist/tools/fs/shell-read-establish.js +5 -33
  145. package/dist/tools/fs/shell-read-identity.d.ts +13 -0
  146. package/dist/tools/fs/shell-read-identity.js +39 -0
  147. package/dist/tools/fs/shell-read-judge.d.ts +8 -0
  148. package/dist/tools/fs/shell-read-judge.js +7 -0
  149. package/dist/tools/fs/shell-read-plan.d.ts +15 -6
  150. package/dist/tools/fs/shell-read-plan.js +171 -195
  151. package/dist/tools/fs/shell-read-word.d.ts +64 -0
  152. package/dist/tools/fs/shell-read-word.js +94 -0
  153. package/dist/tools/fs/shell-reentry-text.d.ts +10 -0
  154. package/dist/tools/fs/shell-reentry-text.js +73 -0
  155. package/package.json +1 -1
  156. package/test/export-surface.snapshot.json +58 -8
  157. package/wire-changes/core@7.30.0.json +1821 -0
  158. package/wire-changes/core@7.30.1.json +154 -0
@@ -274,6 +274,20 @@ export interface TaskResult {
274
274
  * Undefined on every other terminal and when there was nothing to salvage.
275
275
  */
276
276
  salvagedOutput?: string;
277
+ /**
278
+ * Present iff this run compacted its context at least once at a turn boundary or a prompt-too-long
279
+ * recovery, or opened its compaction breaker: `passes` = landed compactions, `kind` = the last landed
280
+ * pass's trigger (`reactive` is the wire's `forced`), `breakerOpen` = compaction was disabled for the
281
+ * rest of the run (later context was trimmed away, not summarized). The end-of-task settle pass is
282
+ * NOT counted (ruled): it summarizes AFTER the work, for the next run, and says nothing about what this
283
+ * run's model saw. Projected onto a delegated child's terminal frame so
284
+ * the parent can tell that a child forgot.
285
+ */
286
+ compaction?: {
287
+ passes: number;
288
+ breakerOpen: boolean;
289
+ kind?: import("./task-notification.js").CompactionKind;
290
+ };
277
291
  /**
278
292
  * The remote-workspace lifecycle failures this run hit, as DATA. The seam declares eleven
279
293
  * distinct `RemoteExecutionErrorCode`s, but every one of them used to reach the caller as the same
@@ -554,6 +554,13 @@ export interface TaskSpec {
554
554
  * interception, prompt gating, stop pushback, compaction taps, permission-denied observation; each
555
555
  * member's contract is on the interface). Overrides `RunnerDeps.hooks`. */
556
556
  hooks?: import("./hooks.js").Hooks;
557
+ /**
558
+ * The session's SELF-REPORTED presence for the peer directory (`agent` = what it is, `intent` = what
559
+ * it is doing; each ≤ 120 chars). The engine never writes a directory row: the same object goes out
560
+ * on the leg's `wiring_manifest` so a host copies it into the row it writes, and `ListAgents` renders
561
+ * it on other sessions' listings prefixed `self:`. Labels only — never read by any judgment.
562
+ */
563
+ peerPresence?: import("../agents/peer-directory.js").PeerPresence;
557
564
  /**
558
565
  * design/45 **durable suspend-on-approval** (F4). When set AND a `CheckpointStore` is wired
559
566
  * (`checkpointStore` here or on `RunnerDeps`), a tool-policy `ask` **can suspend durably**: when no LIVE
@@ -111,7 +111,8 @@ export const TOOL_CATALOG_ENTRIES = [
111
111
  { id: "monitor", name: "Monitor", source: "builtin", definedIn: "src/tools/monitor.ts", mountedBy: ["backgroundTasks"], cards: ["monitor-start", "readonly_out_of_root"], face: { family: "other", effect: "write", contract: c("core.monitor@1"), offloadThresholdChars: 10_000 } },
112
112
  { id: "send-message", name: "SendMessage", source: "builtin", definedIn: "src/agents/send-message-tool.ts", mountedBy: ["delegation", "hostInternals", "peerLane"], cards: ["send-message"], face: { family: "protocol", effect: "write", contract: c("core.send_message@1") } },
113
113
  { id: "agent-transcript", name: "AgentTranscript", source: "builtin", definedIn: "src/agents/agent-transcript-tool.ts", mountedBy: ["delegation"], cards: ["agent-transcript"], face: { family: "delegate", effect: "read", contract: c("core.agent_transcript@1") } },
114
- { id: "list-agents", name: "ListAgents", source: "builtin", definedIn: "src/agents/list-agents-tool.ts", mountedBy: ["peerLane"], cards: ["list-agents"], face: { family: "protocol", effect: "read", aliases: ["ListPeers"], contract: c("core.list_agents@1") } },
114
+ { id: "list-agents", name: "ListAgents", source: "builtin", definedIn: "src/agents/list-agents-tool.ts", mountedBy: ["delegation", "peerLane"], cards: ["list-agents"], face: { family: "protocol", effect: "read", aliases: ["ListPeers"], contract: c("core.list_agents@1") } },
115
+ { id: "read-inbox", name: "ReadInbox", source: "builtin", definedIn: "src/agents/read-inbox-tool.ts", mountedBy: ["peerLane"], cards: ["read-inbox"], face: { family: "protocol", effect: "read", contract: c("core.read_inbox@1"), offload: false, budgetExempt: true } },
115
116
  { id: "workflow", name: "Workflow", source: "builtin", definedIn: "src/orchestration/run-workflow-tool.ts", mountedBy: ["workflow"], cards: ["workflow-run"], face: { family: "delegate", effect: "write", contract: c("core.workflow@1") } },
116
117
  { id: "report-blocked", name: "ReportBlocked", source: "builtin", definedIn: "src/core/runner/synthetic-tools.ts", mountedBy: ["always"], cards: [], face: { family: "scaffold", effect: "read", contract: c("core.report_blocked@1") } },
117
118
  { id: "report-findings", name: "ReportFindings", source: "builtin", definedIn: "src/core/runner/synthetic-tools.ts", mountedBy: ["always"], cards: ["report-findings"], face: { family: "scaffold", effect: "read", contract: c("core.report_findings@1") } },
@@ -13,6 +13,7 @@ export const TOOL_CONFORMANCE_VECTORS = [
13
13
  vector("hands-full", ["always", "hands", "backgroundTasks", "delegation"], [
14
14
  { name: "SendMessage", why: "needs the runner self seat (a direct prepare has none)" },
15
15
  { name: "AgentTranscript", why: "needs the runner self seat (a direct prepare has none)" },
16
+ { name: "ListAgents", why: "mounts with the delegation face only under a runner self seat (a direct prepare has none)" },
16
17
  ], [OFFLOAD_READER]),
17
18
  vector("hands-readonly", ["always", "hands"], [
18
19
  { name: "Edit", why: "the read-only band mounts the read half only" },
@@ -321,8 +321,12 @@ export type PermissionResult = {
321
321
  * in the one direction the stamp cannot reach (a caller composing its own ask) the claim is
322
322
  * tightening-only: it can make an ask outlive a rule, never turn one into an allow. */
323
323
  probeMandated?: true;
324
- /** This ask is MANDATED — no persisted allow rule and no standing posture may retire it, only an
325
- * answer to THIS call. ENGINE-STAMPED at the gate's single origin stamp from the ONE derivation
324
+ /** This ask is MANDATED — no persisted allow rule and no STANDING ANSWER (a release remembered from an
325
+ * earlier call, at any scope, a session included) may retire it; only an answer produced for THIS call
326
+ * clears it — a person, a hook, a deployment's blanket `onAsk: "allow"` seat, or the live deciders the
327
+ * mandate tables admit ({@link import("./ask-origin.js").classifierMayAnswerMandate} /
328
+ * `sandboxMayAdmitMandate`); {@link requiresRealApproval} is the stronger demand that also refuses the
329
+ * blanket seat. ENGINE-STAMPED at the gate's single origin stamp from the ONE derivation
326
330
  * the approval card's rule-offer word also reads ({@link import("./ask-origin.js").ruleClearanceOf},
327
331
  * which lists the doors). TIGHTENING-ONLY: a layer below the mint may not clear one a layer above
328
332
  * set, and a policy self-declaring it only opts its own ask OUT of automatic answering. Carried
@@ -1259,8 +1263,9 @@ export interface AskRequest {
1259
1263
  * caller/worker-settable field. */
1260
1264
  readonly requiresRealApproval?: boolean;
1261
1265
  /**
1262
- * PRESENCE ONLY, and a FACT ABOUT THIS ASK: no persisted allow rule and no standing posture can
1263
- * retire this question. ABSENT is not the inverse claim: a person's own explicit `ask` rule and a
1266
+ * PRESENCE ONLY, and a FACT ABOUT THIS ASK: no persisted allow rule and no STANDING ANSWER — a release
1267
+ * remembered from an earlier call, at any scope, a session included — can retire this question; it is
1268
+ * answered only for THIS call, by an answerer (see the ask-arm member of the same name for who may). ABSENT is not the inverse claim: a person's own explicit `ask` rule and a
1264
1269
  * matching allow rule the lane already refused both leave it absent and still block rule clearance
1265
1270
  * ({@link ruleOffersAbsence} words those `shadowed`). The wire twin of the
1266
1271
  * {@link PermissionResult} ask-arm member of the same name, minted once by the engine at the gate's
@@ -14,6 +14,7 @@ import type { AgentDefinition } from "./agent-definition.js";
14
14
  import type { TaskEvent } from "./task-event.js";
15
15
  import type { TaskSpec } from "./task-spec.js";
16
16
  import type { BackgroundChildEvent } from "./delegation-frames.js";
17
+ import type { ModelRef } from "./model-seat.js";
17
18
  import type { ToolFamily, ToolPathTarget, ToolRenderHints, ToolRuleFace } from "./tool-face.js";
18
19
  /**
19
20
  * Side-effect class of a tool. Used by wake/resume reconciliation: when a call was interrupted
@@ -819,6 +820,19 @@ export interface ToolExecuteContext {
819
820
  * the tool runs outside a Runner task.
820
821
  */
821
822
  model?: Model;
823
+ /**
824
+ * WHICH REF chose {@link model} — the catalog word the parent leg is running under, or the `Model`
825
+ * object itself when no word exists (an object-pinned spec, a `select`-criteria role). Snapshotted at
826
+ * the same call-time instant as {@link model}, and its companion in the same sense {@link thinkingLevel}
827
+ * is: one read, one moment.
828
+ *
829
+ * A delegation tool inheriting the caller's model reads THIS, not {@link model}: a word resolves against
830
+ * the catalog generation in force at the CHILD's own spawn, so a child spawned after a catalog hot-swap
831
+ * lands on the current generation instead of on the object its parent has been holding since its own
832
+ * prepare (and a word the swap retired refuses loudly, exactly as a caller-written retired word does).
833
+ * Undefined when the tool runs outside a Runner task — the same absence {@link model} has there.
834
+ */
835
+ modelRef?: ModelRef;
822
836
  /**
823
837
  * The PARENT task's current thinking level, snapshotted at call time — the {@link model} companion.
824
838
  * A delegation tool threads it into the child so a sub-agent inherits the caller's thinking depth by
@@ -158,6 +158,14 @@ export interface WiringManifest {
158
158
  leg?: {
159
159
  kind: WiringLegKind;
160
160
  };
161
+ /** Effective half only — the leg's team role ({@link import("../agents/team-role.js").teamRoleOf}):
162
+ * `lead` for a top-level leg, `teammate` for a named delegation, `none` for an unnamed one. Leg-local
163
+ * (excluded from the fingerprint). */
164
+ teamRole?: import("../agents/team-role.js").TeamRole;
165
+ /** Effective half only, present iff the spec reported one — the session's self-reported presence,
166
+ * the very object `TaskSpec.peerPresence` carried, for a host to copy into the directory row it
167
+ * writes without parsing the spec. Leg-local (excluded from the fingerprint). */
168
+ peerPresence?: import("../agents/peer-directory.js").PeerPresence;
161
169
  ask: {
162
170
  form: AskSeamForm;
163
171
  /** Absent iff `form === "absent"` (no seat supplied a value — a fabricated provenance would be
@@ -413,6 +421,10 @@ export interface WiringFacts {
413
421
  half: "static" | "effective";
414
422
  /** Required on the effective half; must be absent on the static half. */
415
423
  leg?: WiringLegKind;
424
+ /** Effective half only — see {@link WiringManifest.teamRole}. */
425
+ teamRole?: import("../agents/team-role.js").TeamRole;
426
+ /** Effective half only — see {@link WiringManifest.peerPresence}; copied, never aliased. */
427
+ peerPresence?: import("../agents/peer-directory.js").PeerPresence;
416
428
  askForm: AskSeamForm;
417
429
  askProvenance?: SeamProvenance;
418
430
  questionWired: boolean;
@@ -146,9 +146,13 @@ export function deriveWiringManifest(facts) {
146
146
  ? { readDeny: { builtinTiers: [...facts.readDenyBuiltinTiersActive] } }
147
147
  : {}),
148
148
  ...(facts.half === "effective" && facts.autoConsolidationOnRecommendation === true ? { autoConsolidation: { onRecommendation: true } } : {}),
149
+ ...(facts.half === "effective" && facts.teamRole !== undefined ? { teamRole: facts.teamRole } : {}),
150
+ ...(facts.half === "effective" && facts.peerPresence !== undefined && (facts.peerPresence.agent !== undefined || facts.peerPresence.intent !== undefined)
151
+ ? { peerPresence: { ...(facts.peerPresence.agent !== undefined ? { agent: facts.peerPresence.agent } : {}), ...(facts.peerPresence.intent !== undefined ? { intent: facts.peerPresence.intent } : {}) } }
152
+ : {}),
149
153
  };
150
154
  if (facts.half === "effective") {
151
- const { leg: _leg, mcp: _mcp, tools: _tools, lsp: _lsp, hooks: _hooks, ...assembly } = manifest;
155
+ const { leg: _leg, mcp: _mcp, tools: _tools, lsp: _lsp, hooks: _hooks, teamRole: _teamRole, peerPresence: _peerPresence, ...assembly } = manifest;
152
156
  const { provenance: _askSeat, ...askForHash } = assembly.ask;
153
157
  const { provenance: _questionSeat, ...questionForHash } = assembly.question;
154
158
  manifest.configFingerprint = createHash("sha256")
@@ -2,6 +2,7 @@ import type { ActorAssertion, AssistantMessage, ImageContent, Model, UserMessage
2
2
  import type { HaltRemainingDirective } from "../loop/types.js";
3
3
  import type { AgentMessage, AgentTool, LoopMalformedToolUseRecovery, LoopThinkingOnlyRecovery, LoopTruncatedOutputRecovery, QueueMode, ThinkingLevel } from "../loop/types.js";
4
4
  import { type EngineSegment } from "../../core/untrusted-text.js";
5
+ import type { CommittedFrameCarrier } from "../../core/frame-settlement.js";
5
6
  import type { AbortResult, AgentHarnessEvent, AgentHarnessEventResultMap, AgentHarnessOptions, AgentHarnessOwnEvent, AgentHarnessResources, AgentHarnessStreamOptions, ExecutionEnv, PromptTemplate, Skill } from "./types.js";
6
7
  /** [c209-C] 收口 C1/C2 — engine-provenance metadata a caller can stamp on the user message it
7
8
  * mints (see the field docs on {@link UserMessage}). Threaded from `prompt`/`steer`/`followUp`/
@@ -56,6 +57,10 @@ export interface UserMessageProvenance {
56
57
  * while an engine-authored one is held. Minter-stated at the single relay seam that mints such
57
58
  * frames — never inferred from text. Metadata only; not persisted on the message. */
58
59
  callerAuthored?: true;
60
+ /** #1036 — the frame's injection-queue dedup key, persisted on the message it becomes
61
+ * ({@link UserMessage.engineNoteKey}) so a reader of the TRANSCRIPT alone can join an entry back
62
+ * to its frame. Rides only WITH `provenance:"engine-note"`. */
63
+ engineNoteKey?: string;
59
64
  /** RB-30 terminal fix — an OPAQUE payload the engine rides on this queued message (the runner's
60
65
  * task-notification frame). Never serialized, never interpreted by the harness: if the message is
61
66
  * still undrained at agent_end, the payload is handed back through `onUndrainedEngineNotes` so
@@ -178,6 +183,8 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
178
183
  private runPromise?;
179
184
  private pendingSessionWrites;
180
185
  private model;
186
+ /** The ref that chose {@link model}, moved by the SAME assignment (one value, never two answers). */
187
+ private modelRef;
181
188
  /** The run's thinking level; `undefined` = undeclared (provider default, no wire key) — distinct from "off". */
182
189
  private thinkingLevel;
183
190
  /** RB-30 terminal fix — runner-set sink for engine-note payloads left undrained at agent_end. */
@@ -200,6 +207,9 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
200
207
  * Advisory (swallow-guarded at the call sites via the runner's own closure); never re-entered
201
208
  * for the same payload — consumption deletes the sidecar entry in the same step. */
202
209
  onEngineNoteConsumed?: (payload: unknown) => void;
210
+ /** #1036 — THE RECEIPT SINK: a frame reached the TRANSCRIPT, reported at the `message_end` append
211
+ * that proves it, with its carrier and entry id. Advisory. */
212
+ onFrameCommitted?: (carrier: CommittedFrameCarrier, entryId: string) => void;
203
213
  /** Runner-set HOLD — the single gate for every engine-authored injection against the run's live
204
214
  * human-halt fact. When it reports true (a person's bare rejection halted the run at this
205
215
  * boundary, and only that person's own input may continue it):
@@ -496,9 +506,12 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
496
506
  } & UserMessageProvenance): Promise<void>;
497
507
  appendMessage(message: AgentMessage): Promise<void>;
498
508
  getModel(): Model;
509
+ /** The ref that chose the CURRENT model — {@link getModel}'s companion (a word re-resolves, an object pins). */
510
+ getModelRef(): import("../../core/model-seat.js").ModelRef;
499
511
  /** The current level, or `undefined` when none was declared (provider default — no wire key). */
500
512
  getThinkingLevel(): ThinkingLevel | undefined;
501
- setModel(model: Model): Promise<void>;
513
+ /** `ref` = the word that chose `model`; omitted ⇒ the object pins itself. The pair moves together. */
514
+ setModel(model: Model, ref?: import("../../core/model-seat.js").ModelRef): Promise<void>;
502
515
  setThinkingLevel(level: ThinkingLevel): Promise<void>;
503
516
  setActiveTools(toolNames: string[]): Promise<void>;
504
517
  getSteeringMode(): QueueMode;
@@ -28,6 +28,7 @@ function createUserMessage(text, images, provenance) {
28
28
  : {}),
29
29
  ...(provenance?.engineMinted === true && !engineNote ? { engineMinted: true } : {}),
30
30
  ...(engineNote ? { provenance: "engine-note" } : {}),
31
+ ...(engineNote && typeof provenance?.engineNoteKey === "string" && provenance.engineNoteKey.length > 0 ? { engineNoteKey: provenance.engineNoteKey } : {}),
31
32
  ...(provenance?.actor !== undefined &&
32
33
  typeof provenance.actor.id === "string" &&
33
34
  provenance.actor.id.length > 0 &&
@@ -206,10 +207,12 @@ export class AgentHarness {
206
207
  runPromise;
207
208
  pendingSessionWrites = [];
208
209
  model;
210
+ modelRef;
209
211
  thinkingLevel;
210
212
  onUndrainedEngineNotes;
211
213
  onUndrainedUserInputs;
212
214
  onEngineNoteConsumed;
215
+ onFrameCommitted;
213
216
  engineInjectionsHeld;
214
217
  recoverUndrainedEngineNotes() {
215
218
  this.sweepUndrainedEngineNotes([this.drainedPendingInjection, this.nextTurnQueue, this.steerQueue, this.followUpQueue]);
@@ -297,6 +300,7 @@ export class AgentHarness {
297
300
  this.tools.set(tool.name, tool);
298
301
  }
299
302
  this.model = options.model;
303
+ this.modelRef = options.modelRef ?? options.model;
300
304
  this.thinkingLevel = options.thinkingLevel;
301
305
  this.activeToolNames =
302
306
  options.activeToolNames ?? (options.tools ?? []).map((tool) => tool.name);
@@ -582,11 +586,21 @@ export class AgentHarness {
582
586
  const gone = new Set(messages);
583
587
  this.drainedPendingInjection = this.drainedPendingInjection.filter((m) => !gone.has(m));
584
588
  }
585
- settleInjectedFrame(message) {
589
+ settleInjectedFrame(message, entryId) {
586
590
  if (!this.drainedPendingInjection.includes(message))
587
591
  return;
588
592
  this.unbookInFlight([message]);
589
593
  userInputParkRecords.delete(message);
594
+ if (entryId !== undefined) {
595
+ const payload = engineNotePayloads.get(message);
596
+ if (payload !== undefined) {
597
+ try {
598
+ this.onFrameCommitted?.({ kind: "engine_note", payload }, entryId);
599
+ }
600
+ catch {
601
+ }
602
+ }
603
+ }
590
604
  engineNotePayloads.delete(message);
591
605
  }
592
606
  createLoopConfig(getTurnState, setTurnState, runPromptOverride) {
@@ -788,7 +802,14 @@ export class AgentHarness {
788
802
  let entryId;
789
803
  if (!isEmptyFailureAssistant(event.message)) {
790
804
  entryId = await this.session.appendMessage(event.message);
791
- this.settleInjectedFrame(event.message);
805
+ this.settleInjectedFrame(event.message, entryId);
806
+ if (entryId !== undefined && event.message.role === "toolResult" && typeof event.message.toolCallId === "string") {
807
+ try {
808
+ this.onFrameCommitted?.({ kind: "tool_result", toolCallId: event.message.toolCallId, content: event.message.content }, entryId);
809
+ }
810
+ catch {
811
+ }
812
+ }
792
813
  }
793
814
  else if (event.message.isApiErrorMessage === true) {
794
815
  await this.recordApiFailure(event.message);
@@ -1169,10 +1190,13 @@ export class AgentHarness {
1169
1190
  getModel() {
1170
1191
  return this.model;
1171
1192
  }
1193
+ getModelRef() {
1194
+ return this.modelRef;
1195
+ }
1172
1196
  getThinkingLevel() {
1173
1197
  return this.thinkingLevel;
1174
1198
  }
1175
- async setModel(model) {
1199
+ async setModel(model, ref) {
1176
1200
  try {
1177
1201
  const previousModel = this.model;
1178
1202
  if (this.phase === "idle") {
@@ -1186,6 +1210,7 @@ export class AgentHarness {
1186
1210
  });
1187
1211
  }
1188
1212
  this.model = model;
1213
+ this.modelRef = ref ?? model;
1189
1214
  await this.emitOwn({ type: "model_select", model, previousModel, source: "set" });
1190
1215
  }
1191
1216
  catch (error) {
@@ -210,7 +210,7 @@ export declare class CompactionError extends Error {
210
210
  code: CompactionErrorCode;
211
211
  constructor(code: CompactionErrorCode, message: string, cause?: Error);
212
212
  }
213
- export type SessionErrorCode = "not_found" | "invalid_session" | "invalid_entry" | "invalid_fork_target" | "storage" | "conflict" | "placement_refused" | "unknown";
213
+ export type SessionErrorCode = "not_found" | "invalid_session" | "invalid_entry" | "invalid_fork_target" | "storage" | "conflict" | "placement_refused" | "corrupt_session" | "unknown";
214
214
  /** Error thrown by session storage, repositories, and session tree operations. */
215
215
  export declare class SessionError extends Error {
216
216
  /** Session subsystem error code. */
@@ -1380,6 +1380,8 @@ export interface AgentHarnessOptions<TSkill extends Skill = Skill, TPromptTempla
1380
1380
  /** Curated stream/provider request options. Snapshotted at turn start. */
1381
1381
  streamOptions?: AgentHarnessStreamOptions;
1382
1382
  model: Model;
1383
+ /** WHICH REF chose {@link AgentHarnessOptions.model} — the word, else the object. Omitted ⇒ pinned. */
1384
+ modelRef?: import("../../core/model-seat.js").ModelRef;
1383
1385
  thinkingLevel?: ThinkingLevel;
1384
1386
  activeToolNames?: string[];
1385
1387
  steeringMode?: QueueMode;
@@ -348,6 +348,8 @@ export interface UserMessage {
348
348
  * invariant outranks the may-skip one (dropping visible content is the unrecoverable direction).
349
349
  */
350
350
  engineMinted?: true;
351
+ /** #1036 — this frame's injection-queue dedup key, with `provenance:"engine-note"`; OPAQUE (equality only), the DURABLE half of frame identity. */
352
+ engineNoteKey?: string;
351
353
  /**
352
354
  * [c209-C] R3 收口 — the "visible but not the user" THIRD state. This message is an
353
355
  * ENGINE-INJECTED note whose CONTENT the model must read (LSP `<new-diagnostics>` blocks,
@@ -524,13 +526,12 @@ export interface ToolResultMessage<TDetails = unknown> {
524
526
  export type Message = UserMessage | AssistantMessage | ToolResultMessage;
525
527
  /**
526
528
  * RB-3 (stage S4 carry): strip the engine-provenance metadata fields from user messages before
527
- * serializing a Context to an external wire. The five fields (`enginePrefixChars`/`engineSegments`/
528
- * `engineMinted`/`provenance`/`actor`, the last per design/171 §5.2) are INTERNAL coordination
529
- * between the engine's minting side and its consumers (permission classifier, compaction summarizer,
530
- * prompt suggestions, multiplayer attribution) — they must never reach a provider payload. The
531
- * built-in brains construct their own wire shapes and are immune; a CUSTOM Brain that
532
- * whole-object-serializes messages (`JSON.stringify(context.messages)`) would leak them — run the
533
- * array through this projection first.
529
+ * serializing a Context to an external wire. The six fields (`enginePrefixChars`/`engineSegments`/
530
+ * `engineMinted`/`provenance`/`actor`/`engineNoteKey`) are INTERNAL coordination between the engine's
531
+ * minting side and its consumers (permission classifier, compaction summarizer, prompt suggestions,
532
+ * multiplayer attribution) — they must never reach a provider payload. The built-in brains construct
533
+ * their own wire shapes and are immune; a CUSTOM Brain that whole-object-serializes messages
534
+ * (`JSON.stringify(context.messages)`) would leak them — run the array through this projection first.
534
535
  */
535
536
  export declare function stripEngineMetadata(messages: Message[]): Message[];
536
537
  export type ImagesInputContent = TextContent | ImageContent;
@@ -9,7 +9,7 @@ export function stripEngineMetadata(messages) {
9
9
  return messages.map((m) => {
10
10
  if (m.role !== "user")
11
11
  return m;
12
- const { enginePrefixChars: _a, engineSegments: _b, engineMinted: _c, provenance: _d, actor: _e, ...rest } = m;
12
+ const { enginePrefixChars: _a, engineSegments: _b, engineMinted: _c, provenance: _d, actor: _e, engineNoteKey: _f, ...rest } = m;
13
13
  return rest;
14
14
  });
15
15
  }
@@ -19,6 +19,9 @@ export interface NodeLspManagerOptions {
19
19
  servers?: Record<string, string | null>;
20
20
  /** Injectable spawn (tests supply a fake server; default = {@link defaultLspSpawn} over `child_process.spawn`). */
21
21
  spawn?: LspSpawn;
22
+ /** The language server's environment for the default spawn, verbatim. Omitted ⇒ the host environment scrubbed of
23
+ * credential-shaped names (`scrubSecretEnv`, a tool child's scrub). Unread when {@link spawn} is supplied. */
24
+ env?: Record<string, string>;
22
25
  /** Read a file's CURRENT text for the session's didOpen/didChange re-sync (default = local `fs.readFile` utf8). */
23
26
  readText?: LspReadText;
24
27
  /** Resolve the server `cwd`/`rootUri` for a file (default = env.cwd ?? nearest project marker ?? file dir). */
@@ -9,6 +9,7 @@ import { TransportLspSession } from "../../core/lsp-session.js";
9
9
  import { StdioLspTransport } from "./stdio-lsp-transport.js";
10
10
  import { MAX_LSP_FILE_BYTES, SharedAbortScope, settleOnAbort } from "../../core/lsp.js";
11
11
  import { asThrownError, thrownText } from "../../core/thrown-value.js";
12
+ import { scrubSecretEnv } from "../../core/secret-env.js";
12
13
  export const DEFAULT_LSP_SERVERS = {
13
14
  typescript: "typescript-language-server --stdio",
14
15
  javascript: "typescript-language-server --stdio",
@@ -66,7 +67,7 @@ export class NodeLspManager {
66
67
  disposed = false;
67
68
  constructor(opts = {}) {
68
69
  this.servers = { ...DEFAULT_LSP_SERVERS, ...opts.servers };
69
- this.spawnFn = opts.spawn ?? defaultLspSpawn;
70
+ this.spawnFn = opts.spawn ?? (opts.env !== undefined ? lspSpawnWithEnv(opts.env) : defaultLspSpawn);
70
71
  this.readTextFn = opts.readText ?? defaultLspReadText;
71
72
  this.resolveRootFn = opts.resolveRoot ?? defaultResolveRoot;
72
73
  this.log = opts.log ?? (() => { });
@@ -328,10 +329,11 @@ export function lspSpawnOptions(cwd) {
328
329
  ? { cwd, stdio: ["pipe", "pipe", "ignore"], shell: true }
329
330
  : { cwd, stdio: ["pipe", "pipe", "ignore"] };
330
331
  }
331
- export const defaultLspSpawn = (command, args, cwd, signal) => new Promise((resolve, reject) => {
332
+ export const defaultLspSpawn = (command, args, cwd, signal) => lspSpawnWithEnv(undefined)(command, args, cwd, signal);
333
+ const lspSpawnWithEnv = (env) => (command, args, cwd, signal) => new Promise((resolve, reject) => {
332
334
  let child;
333
335
  try {
334
- child = spawn(command, args, lspSpawnOptions(cwd));
336
+ child = spawn(command, args, { ...lspSpawnOptions(cwd), env: env ?? scrubSecretEnv(process.env) });
335
337
  }
336
338
  catch (e) {
337
339
  return reject(asThrownError(e));
@@ -293,6 +293,10 @@ function normalizeEngineProvenanceStamp(message, preserveActorAssertions = false
293
293
  delete m.engineMinted;
294
294
  if (m.provenance !== undefined && m.provenance !== "engine-note")
295
295
  delete m.provenance;
296
+ if (m.engineNoteKey !== undefined && !(typeof m.engineNoteKey === "string" && m.engineNoteKey.length > 0))
297
+ delete m.engineNoteKey;
298
+ if (m.engineNoteKey !== undefined && m.provenance !== "engine-note")
299
+ delete m.engineNoteKey;
296
300
  if (m.engineMinted === true && m.provenance === "engine-note") {
297
301
  delete m.engineMinted;
298
302
  }
package/dist/index.d.ts CHANGED
@@ -128,14 +128,15 @@ export type { FileHistoryRetentionPolicy } from "./core/file-history-retention.j
128
128
  export { FileStorageBackend, FileSessionRepo, FileCheckpointStore, FileMemoryStore, FileToolResultStore, FileSessionPolicyStore, FileStrategyStore, FileFileHistoryStore, FileWorkflowJournalStore, MAX_JOURNAL_RESULT_BYTES, oversizeJournalResult, resolveDataRoot, sanitizeScope, sanitizePathComponent, createFileConsolidationLock, atomicWriteFile, writeThenLink, ensureDir, readJsonlRecords, AppendLog, FileStoreLockError, type FileStoreLockErrorCode, processFingerprint, isProcessLive, type ProcessFingerprint, type FileStorageBackendOptions, type FileStorageCorruptReadInfo, type FileStrategyStoreOptions, type FileFileHistoryStoreOptions, type FileSessionRepoOptions, type FileCheckpointStoreOptions, } from "./stores/file/index.js";
129
129
  export { CacheBreakDetector, type CacheBreakFinding, type ToolFingerprintInput } from "./core/cache-break-detector.js";
130
130
  export { maybeCompact, type MaybeCompactOptions, type CompactionWindowSafetyInfo } from "./core/auto-compaction.js";
131
+ export type { CompactionEffect } from "./core/frame-settlement.js";
131
132
  export { brainToRuntime } from "./core/runtime.js";
132
133
  export { createSensitivePathPolicy, RECOMMENDED_SENSITIVE_PATTERNS } from "./core/sensitive-path-policy.js";
133
134
  export { createFsWriteGatePolicy, WRITE_EXEMPT_DIR_COVERS_ROOT_CODE, type FsWriteGatePolicyOptions } from "./core/fs-write-gate-policy.js";
134
135
  export { RETIRED_TOOL_NAMES } from "./core/tool-name-aliases.js";
135
136
  export { DEFAULT_SUBAGENT_TOOL_NAME } from "./agents/subagent.js";
136
- export { renderTaskNotificationXml, taskNotificationDedupKey, isDelegatedAgentTerminal, isTerminalTaskNotification, SystemInjectionQueue, type TaskNotificationPayload, type TaskNotificationStatus, type ExternalNotificationInput, type SystemInjection, type SystemInjectionPriority, type NotificationInjectionOutcome, // the injector's outcome words (`parked_durably` = the session's durable box took the frame)
137
+ export { renderTaskNotificationXml, RESUPPLIED_FRAME_PREAMBLE, taskNotificationDedupKey, isDelegatedAgentTerminal, isTerminalTaskNotification, SystemInjectionQueue, type TaskNotificationPayload, type TaskNotificationStatus, type ExternalNotificationInput, type SystemInjection, type SystemInjectionPriority, type NotificationInjectionOutcome, // the injector's outcome words (`parked_durably` = the session's durable box took the frame)
137
138
  NOTIFICATION_INJECTION_OUTCOMES, // …and their value half + guard, so a host wiring its own uplink validates a reported outcome without duplicating the vocabulary
138
- isNotificationInjectionOutcome, SYSTEM_INJECTION_PRIORITIES, isSystemInjectionPriority, AGENT_MESSAGE_TAG, renderAgentMessageFrame, type SemaProvenance, } from "./core/task-notification.js";
139
+ isNotificationInjectionOutcome, SYSTEM_INJECTION_PRIORITIES, isSystemInjectionPriority, AGENT_MESSAGE_TAG, renderAgentMessageFrame, type SemaProvenance, HANDBACK_STATES, type HandbackState, COMPACTION_KINDS, type CompactionKind, handbackStateOf, terminalFrameFacets, } from "./core/task-notification.js";
139
140
  export { TOOL_FAMILIES, TOOL_MOUNT_TAGS, TOOL_APPROVAL_CARDS, TOOL_PATH_ACCESSES, TOOL_PATH_BASES, TOOL_PATH_ABSENCES, TOOL_WIRE_NAME_MAX_CHARS, TOOL_CONTRACT_MAX_CHARS, TOOL_CARD_ID_MAX_CHARS, TOOL_KEY_MAX_CHARS, TOOL_KEYS_MAX, RENDER_HINT_MAX_CHARS, RENDER_HINT_ACTIVITY_MAX_CHARS, RENDER_HINT_MAX_LIST, type ToolFamily, type ToolMountTag, type ToolApprovalCard, type ToolPathAccess, type ToolPathBase, type ToolPathAbsence, type ToolPathTarget, type ToolCallPathTarget, type ToolRosterPathTarget, pathTargetSlotOnly, type ToolRuleFace, type ToolRenderHints, type ToolFaceDeclaration, type ToolCatalogEntry, } from "./core/tool-face.js";
140
141
  export { describeToolCatalog, catalogEntriesNamed, catalogToolNames, catalogRuleFaceOf, pathTargetOf, pathTargetValue, protectivePathTargetOf, declaredPathTargetOf, BARE_REQUEST_CODE, isProtectedWrite, isDeclaredWrite, fileOpAccessOf, type ToolCallLike, pathConfinableWriteToolNames, skillScopeWriteToolNames, pathTargetingToolNames, compactableToolNames, budgetExemptToolNames, handBandEffects, engineCardTypes, predictMountedToolNames, HANDS_BAND_TAGS, MOUNT_TAG_IN_HANDS_BAND, } from "./core/tool-registry.js";
141
142
  export { ToolRosterEntry, ToolRoster, ToolRosterDelta, ToolRosterRenderHints, ROSTER_SOURCES, type RosterSource, type ToolIdentity, toolIdentityOf, mintCapabilityId, diffToolRoster, judgeParkedToolIdentity, ruleFacesFromRoster, toolCallFaceOf, inputKeysOf, ruleFaceOfInstance, rosterMemberBoundProblem, type RosterBoundMembers, type RosterBoundCode, ToolRosterDeltaSeat, } from "./core/tool-roster.js";
@@ -158,7 +159,7 @@ export { type StoreDurability } from "./core/checkpoint-store.js";
158
159
  export { type StoreFidelity } from "./core/checkpoint-store.js";
159
160
  export { projectHumanInput, buildHumanInputEvent, type HumanInputSource, type HumanInputFrame, type HumanInputEvent, type HumanInputDelivery, } from "./core/human-input-projection.js";
160
161
  export { TaskRegistry, defaultTaskRegistry, createTaskOutputTool, createTaskStopTool, type SemaTaskType, type SemaTaskStatus, type SemaTaskHandle, type ParkedClaimTicket, type TaskAccess, type UnifiedTaskOutput, type TaskRetrievalStatus, type StopSource, type RegisterMonitorInput, type MonitorTimers, MONITOR_BATCH_WINDOW_MS, MONITOR_DEFAULT_TIMEOUT_MS, MONITOR_MAX_TIMEOUT_MS, MONITOR_MAX_BATCHES_PER_MINUTE, canAccessWorkflowRun, DURABLE_AGENT_HANDLE_RE, } from "./core/task-registry.js";
161
- export { InMemoryMailboxStore, type MailboxStore, type MailboxMessage, type MailboxLease, MailboxStoreError, type MailboxStoreErrorCode, MAILBOX_TOMBSTONED_RECIPIENT_CODE, type MailboxAppendMessage, type MailboxPeerMeta, type MailboxPeerFromMode, type MailboxPeerRecordKind, type MailboxPeerNoticeMeta, type MailboxPeerNoticeState, MAILBOX_PEER_NOTICE_STATES, MAILBOX_PEER_FROM_MODES, MAILBOX_PEER_RECORD_KINDS, MAILBOX_INVALID_PEER_META_CODE, MAILBOX_CROSS_PROCESS_UNSAFE_CODE, readMailboxPeerMeta, mailboxCrossProcessMountVerdict, type MailboxCrossProcessVerdict, } from "./core/mailbox-store.js";
162
+ export { InMemoryMailboxStore, type MailboxStore, type MailboxMessage, type MailboxLease, MailboxStoreError, type MailboxStoreErrorCode, MAILBOX_TOMBSTONED_RECIPIENT_CODE, type MailboxAppendMessage, type MailboxPeerMeta, type MailboxPeerFromMode, type MailboxPeerRecordKind, type MailboxPeerNoticeMeta, type MailboxPeerNoticeState, MAILBOX_PEER_NOTICE_STATES, MAILBOX_PEER_FROM_MODES, MAILBOX_PEER_RECORD_KINDS, MAILBOX_INVALID_PEER_META_CODE, MAILBOX_CROSS_PROCESS_UNSAFE_CODE, readMailboxPeerMeta, mailboxCrossProcessMountVerdict, type MailboxCrossProcessVerdict, type MailboxAckResult, } from "./core/mailbox-store.js";
162
163
  export { FileMailboxStore, type FileMailboxStoreOptions } from "./stores/file/mailbox-store.js";
163
164
  export { createFileTaskListStore } from "./stores/file/task-list-store.js";
164
165
  export { createCcFileTaskListStore } from "./stores/cc/task-list-store.js";
@@ -311,14 +312,16 @@ export { COORDINATOR_ROLE_PROMPT, TEAMMATE_COMMUNICATION_ADDENDUM } from "./prom
311
312
  export { createSubagentTool, FORK_SUBAGENT_TYPE, GENERAL_PURPOSE_SUBAGENT_TYPE, agentWhenToUseText, FORK_DIRECTIVE_FRAME, SUBAGENT_SYSTEM_NOTE, type SubagentToolOptions, resolveDelegationEntryCaps, type ResolvedDelegationEntryCaps, type SubagentSpawnContext, type SubagentSteerHandle, type SubagentStep, type SubagentEditedFile, } from "./agents/subagent.js";
312
313
  export { getSessionRetainLedger, releaseSessionRetainLedger, } from "./agents/retain-ledger.js";
313
314
  export { createSendMessageTool, createAgentContinuationVerb, SEND_MESSAGE_TOOL_NAME, type SendMessageToolOptions, type AgentContinuationReceipt } from "./agents/send-message-tool.js";
314
- export { createPeerAdmission, peerAdmissionFor, judgePeerAdmission, resolvePeerAdmissionConfig, PEER_ADMISSION_DEFAULTS, PEER_HOP_CHAIN_WINDOW, PEER_MESSAGE_NOTICE, createPeerSelfRef, createPeerInboundChainRef, peerAxisToken, appendHopToken, type PeerAdmission, type PeerAdmissionConfig, type PeerAdmissionOptions, type PeerAdmissionRequest, type PeerAdmissionVerdict, type PeerAdmissionRefusal, type PeerRefusalCode, type PeerAxisTag, type PeerIdentity, type PeerSelfRef, type PeerInboundChainRef, } from "./agents/peer-admission.js";
315
+ export { createPeerAdmission, peerAdmissionFor, judgePeerAdmission, resolvePeerLaneConfig, PEER_LANE_DEFAULTS, PEER_HOP_CHAIN_WINDOW, PEER_MESSAGE_NOTICE, createPeerSelfRef, createPeerInboundChainRef, peerAxisToken, appendHopToken, type PeerAdmission, type PeerLaneConfig, type PeerAdmissionOptions, type PeerAdmissionRequest, type PeerAdmissionVerdict, type PeerAdmissionRefusal, type PeerRefusalCode, type PeerAxisTag, type PeerIdentity, type PeerSelfRef, type PeerInboundChainRef, } from "./agents/peer-admission.js";
315
316
  export { CROSS_SESSION_MESSAGE_TAG, CROSS_SESSION_MESSAGE_NOTICE, PERMISSION_MODE_CLASSES, isPermissionModeClass, CrossSessionCodecError, PEER_HOP_CHAIN_CARRY_WINDOW, encodePeerAddress, isCanonicalPeerAddress, encodeScopeAttribute, decodeScopeAttribute, canonicalPeerDisplayName, buildCrossSessionEnvelope, parseCrossSessionEnvelope, clampHopChain, encodeCcPeerFrame, decodeCcPeerFrame, type PermissionModeClass, type CrossSessionEnvelopeFields, type CrossSessionEnvelopeParse, type CrossSessionEnvelopeRefusal, type CcPeerFrameFields, type CcPeerFrameParse, } from "./agents/cross-session-envelope.js";
316
317
  export { CROSS_SESSION_INBOUND_SETTINGS, isCrossSessionInboundSetting, resolveCrossSessionInboundSetting, CROSS_SESSION_HOLD_CAUSES, describeCrossSessionHoldCause, judgeCrossSessionInbound, foldPermissionModeClass, PEER_SEND_VERDICT_CODES, peerSendVerdictSeverity, type CrossSessionInboundSetting, type CrossSessionSettingSource, type CrossSessionInboundSettingLayers, type ResolvedCrossSessionInboundSetting, type CrossSessionHoldCause, type CrossSessionInboundVerdict, type CrossSessionInboundInput, type PeerSendVerdictCode, type PeerSendVerdict, } from "./agents/cross-session-judge.js";
317
318
  export { PEER_REF_MIN, PEER_REF_MAX, PEER_REF_RE, mintPeerRef, formatPeerNameRef, parsePeerNameRef, normalizePeerName, PEER_ADDRESS_PREFIXES, reservedPeerNameReason, type PeerRefEntry, } from "./agents/cross-session-ref.js";
318
- export { PEER_SESSION_RECORD_SCHEMA_VERSION, PEER_SESSION_RECORD_MAX_BYTES, SESSION_BOX_PREFIX, peerSessionBoxHandle, isPeerSessionId, PEER_SESSION_ID_GRAMMAR, parsePeerSessionAddress, readPeerSessionRecord, defaultPeerLivenessProbe, isPeerSessionProcessAlive, mintPeerSessionCandidates, resolvePeerSessions, createInMemoryPeerDirectory, vetPeerRegistryDirectory, judgePeerRecordFile, type PeerSessionRecord, type PeerSessionLiveness, type PeerSessionTempo, type PeerSessionRecordRefusal, type PeerSessionRecordRead, type PeerLivenessProbe, type PeerDirectory, type PeerDirectoryAccess, type PeerSessionCandidate, type PeerSessionResolution, type InMemoryPeerDirectory, type PeerRegistryDirectoryRefusal, type PeerRegistryDirectoryVerdict, } from "./agents/peer-directory.js";
319
- export { createListAgentsTool, LIST_AGENTS_TOOL_NAME, LIST_AGENTS_TOOL_ALIAS, LIST_AGENTS_MAX_RESULT_CHARS, type ListAgentsToolOptions, type ListAgentsRow } from "./agents/list-agents-tool.js";
319
+ export { PEER_SESSION_RECORD_SCHEMA_VERSION, PEER_SESSION_RECORD_MAX_BYTES, SESSION_BOX_PREFIX, peerSessionBoxHandle, isPeerSessionId, PEER_SESSION_ID_GRAMMAR, parsePeerSessionAddress, readPeerSessionRecord, defaultPeerLivenessProbe, isPeerSessionProcessAlive, mintPeerSessionCandidates, resolvePeerSessions, createInMemoryPeerDirectory, vetPeerRegistryDirectory, judgePeerRecordFile, type PeerSessionRecord, type PeerPresence, PEER_PRESENCE_MAX_CHARS, type PeerSessionLiveness, type PeerSessionTempo, type PeerSessionRecordRefusal, type PeerSessionRecordRead, type PeerLivenessProbe, type PeerDirectory, type PeerDirectoryAccess, type PeerSessionCandidate, type PeerSessionResolution, type InMemoryPeerDirectory, type PeerRegistryDirectoryRefusal, type PeerRegistryDirectoryVerdict, } from "./agents/peer-directory.js";
320
+ export { createReadInboxTool, READ_INBOX_TOOL_NAME, READ_INBOX_MAX_LIMIT, READ_INBOX_RESULT_BUDGET_CHARS, type ReadInboxToolOptions } from "./agents/read-inbox-tool.js";
321
+ export { TEAM_ROLES, DIRECTION_RELATIONS, teamRoleOf, mayDirect, type TeamRole, type DirectionRelation } from "./agents/team-role.js";
322
+ export { createListAgentsTool, LIST_AGENTS_TOOL_NAME, LIST_AGENTS_TOOL_ALIAS, LIST_AGENTS_MAX_RESULT_CHARS, PEER_LISTING_FRESH_WINDOW_MS, isFreshPeerRow, type ListAgentsToolOptions, type ListAgentsRow } from "./agents/list-agents-tool.js";
320
323
  export { CROSS_SESSION_CLASSIFIER_RULE } from "./agents/cross-session-envelope.js";
321
- export { PEER_SESSION_ID_UNGRAMMATICAL_CODE, type PeerLaneMountVerdict, type PeerInboundDisposition } from "./agents/peer-session-drain.js";
324
+ export { PEER_SESSION_ID_UNGRAMMATICAL_CODE, PEER_RESUPPLY_CAP, type PeerLaneMountVerdict, type PeerInboundDisposition } from "./agents/peer-session-drain.js";
322
325
  export { renderCrossSessionMessageFrame, renderCrossSessionNoticeLine } from "./core/task-notification.js";
323
326
  export { PEER_HELD_QUEUE_CAP, PEER_IDLE_SUBSCRIPTION_TTL_MS, PEER_IDLE_SUBSCRIBER_TABLE_CAP, PEER_IDLE_OUTSTANDING_CAP, PEER_IDLE_PRIORS_KEPT, PEER_IDLE_FIRE_DEBOUNCE_MS, PEER_IDLE_HELD_BACKOFF_MS, PEER_IDLE_LABEL_MAX, CROSS_SESSION_DIALOG_EXPIRY_VALUES, CROSS_SESSION_DIALOG_EXPIRY_DEFAULT, resolveCrossSessionDialogExpiry, PEER_HELD_REVIEW_CAUSES, PEER_DELIVERY_RECEIPT_STATES, isPeerDeliveryReceiptState, PEER_DROP_REASONS, peerRecipientSuffix, renderCrossSessionDeliveryNotice, describePeerDropReasons, renderCrossSessionDroppedNotice, PEER_IDLE_NOTICE_KINDS, isPeerIdleNoticeKind, PEER_IDLE_UNAVAILABLE_CAUSES, peerIdleNoticeLabel, formatPeerNoticeClock, renderCrossSessionIdleNotice, describePeerIdleSubscription, type CrossSessionDialogExpiry, type ResolvedCrossSessionDialogExpiry, type PeerDeliveryReceiptState, type PeerDropReason, type PeerIdleNoticeKind, type PeerIdleNoticeFields, } from "./agents/peer-notices.js";
324
327
  export { createPeerHeldQueue, peerHeldQueueFor, peerHeldQueueIfAny, peerHeldQueueKey, realPeerClock, type PeerInboundHoldCause, type PeerHeldEntry, type PeerHeldSettlement, type PeerHeldSettleReason, type PeerHeldSettleOutcome, type PeerClock, type PeerHeldQueueSink, type PeerHeldQueueConfig, type PeerHeldQueue, } from "./agents/peer-held-queue.js";
package/dist/index.js CHANGED
@@ -108,7 +108,7 @@ export { createSensitivePathPolicy, RECOMMENDED_SENSITIVE_PATTERNS } from "./cor
108
108
  export { createFsWriteGatePolicy, WRITE_EXEMPT_DIR_COVERS_ROOT_CODE } from "./core/fs-write-gate-policy.js";
109
109
  export { RETIRED_TOOL_NAMES } from "./core/tool-name-aliases.js";
110
110
  export { DEFAULT_SUBAGENT_TOOL_NAME } from "./agents/subagent.js";
111
- export { renderTaskNotificationXml, taskNotificationDedupKey, isDelegatedAgentTerminal, isTerminalTaskNotification, SystemInjectionQueue, NOTIFICATION_INJECTION_OUTCOMES, isNotificationInjectionOutcome, SYSTEM_INJECTION_PRIORITIES, isSystemInjectionPriority, AGENT_MESSAGE_TAG, renderAgentMessageFrame, } from "./core/task-notification.js";
111
+ export { renderTaskNotificationXml, RESUPPLIED_FRAME_PREAMBLE, taskNotificationDedupKey, isDelegatedAgentTerminal, isTerminalTaskNotification, SystemInjectionQueue, NOTIFICATION_INJECTION_OUTCOMES, isNotificationInjectionOutcome, SYSTEM_INJECTION_PRIORITIES, isSystemInjectionPriority, AGENT_MESSAGE_TAG, renderAgentMessageFrame, HANDBACK_STATES, COMPACTION_KINDS, handbackStateOf, terminalFrameFacets, } from "./core/task-notification.js";
112
112
  export { TOOL_FAMILIES, TOOL_MOUNT_TAGS, TOOL_APPROVAL_CARDS, TOOL_PATH_ACCESSES, TOOL_PATH_BASES, TOOL_PATH_ABSENCES, TOOL_WIRE_NAME_MAX_CHARS, TOOL_CONTRACT_MAX_CHARS, TOOL_CARD_ID_MAX_CHARS, TOOL_KEY_MAX_CHARS, TOOL_KEYS_MAX, RENDER_HINT_MAX_CHARS, RENDER_HINT_ACTIVITY_MAX_CHARS, RENDER_HINT_MAX_LIST, pathTargetSlotOnly, } from "./core/tool-face.js";
113
113
  export { describeToolCatalog, catalogEntriesNamed, catalogToolNames, catalogRuleFaceOf, pathTargetOf, pathTargetValue, protectivePathTargetOf, declaredPathTargetOf, BARE_REQUEST_CODE, isProtectedWrite, isDeclaredWrite, fileOpAccessOf, pathConfinableWriteToolNames, skillScopeWriteToolNames, pathTargetingToolNames, compactableToolNames, budgetExemptToolNames, handBandEffects, engineCardTypes, predictMountedToolNames, HANDS_BAND_TAGS, MOUNT_TAG_IN_HANDS_BAND, } from "./core/tool-registry.js";
114
114
  export { ToolRosterEntry, ToolRoster, ToolRosterDelta, ToolRosterRenderHints, ROSTER_SOURCES, toolIdentityOf, mintCapabilityId, diffToolRoster, judgeParkedToolIdentity, ruleFacesFromRoster, toolCallFaceOf, inputKeysOf, ruleFaceOfInstance, rosterMemberBoundProblem, ToolRosterDeltaSeat, } from "./core/tool-roster.js";
@@ -258,14 +258,16 @@ export { COORDINATOR_ROLE_PROMPT, TEAMMATE_COMMUNICATION_ADDENDUM } from "./prom
258
258
  export { createSubagentTool, FORK_SUBAGENT_TYPE, GENERAL_PURPOSE_SUBAGENT_TYPE, agentWhenToUseText, FORK_DIRECTIVE_FRAME, SUBAGENT_SYSTEM_NOTE, resolveDelegationEntryCaps, } from "./agents/subagent.js";
259
259
  export { getSessionRetainLedger, releaseSessionRetainLedger, } from "./agents/retain-ledger.js";
260
260
  export { createSendMessageTool, createAgentContinuationVerb, SEND_MESSAGE_TOOL_NAME } from "./agents/send-message-tool.js";
261
- export { createPeerAdmission, peerAdmissionFor, judgePeerAdmission, resolvePeerAdmissionConfig, PEER_ADMISSION_DEFAULTS, PEER_HOP_CHAIN_WINDOW, PEER_MESSAGE_NOTICE, createPeerSelfRef, createPeerInboundChainRef, peerAxisToken, appendHopToken, } from "./agents/peer-admission.js";
261
+ export { createPeerAdmission, peerAdmissionFor, judgePeerAdmission, resolvePeerLaneConfig, PEER_LANE_DEFAULTS, PEER_HOP_CHAIN_WINDOW, PEER_MESSAGE_NOTICE, createPeerSelfRef, createPeerInboundChainRef, peerAxisToken, appendHopToken, } from "./agents/peer-admission.js";
262
262
  export { CROSS_SESSION_MESSAGE_TAG, CROSS_SESSION_MESSAGE_NOTICE, PERMISSION_MODE_CLASSES, isPermissionModeClass, CrossSessionCodecError, PEER_HOP_CHAIN_CARRY_WINDOW, encodePeerAddress, isCanonicalPeerAddress, encodeScopeAttribute, decodeScopeAttribute, canonicalPeerDisplayName, buildCrossSessionEnvelope, parseCrossSessionEnvelope, clampHopChain, encodeCcPeerFrame, decodeCcPeerFrame, } from "./agents/cross-session-envelope.js";
263
263
  export { CROSS_SESSION_INBOUND_SETTINGS, isCrossSessionInboundSetting, resolveCrossSessionInboundSetting, CROSS_SESSION_HOLD_CAUSES, describeCrossSessionHoldCause, judgeCrossSessionInbound, foldPermissionModeClass, PEER_SEND_VERDICT_CODES, peerSendVerdictSeverity, } from "./agents/cross-session-judge.js";
264
264
  export { PEER_REF_MIN, PEER_REF_MAX, PEER_REF_RE, mintPeerRef, formatPeerNameRef, parsePeerNameRef, normalizePeerName, PEER_ADDRESS_PREFIXES, reservedPeerNameReason, } from "./agents/cross-session-ref.js";
265
- export { PEER_SESSION_RECORD_SCHEMA_VERSION, PEER_SESSION_RECORD_MAX_BYTES, SESSION_BOX_PREFIX, peerSessionBoxHandle, isPeerSessionId, PEER_SESSION_ID_GRAMMAR, parsePeerSessionAddress, readPeerSessionRecord, defaultPeerLivenessProbe, isPeerSessionProcessAlive, mintPeerSessionCandidates, resolvePeerSessions, createInMemoryPeerDirectory, vetPeerRegistryDirectory, judgePeerRecordFile, } from "./agents/peer-directory.js";
266
- export { createListAgentsTool, LIST_AGENTS_TOOL_NAME, LIST_AGENTS_TOOL_ALIAS, LIST_AGENTS_MAX_RESULT_CHARS } from "./agents/list-agents-tool.js";
265
+ export { PEER_SESSION_RECORD_SCHEMA_VERSION, PEER_SESSION_RECORD_MAX_BYTES, SESSION_BOX_PREFIX, peerSessionBoxHandle, isPeerSessionId, PEER_SESSION_ID_GRAMMAR, parsePeerSessionAddress, readPeerSessionRecord, defaultPeerLivenessProbe, isPeerSessionProcessAlive, mintPeerSessionCandidates, resolvePeerSessions, createInMemoryPeerDirectory, vetPeerRegistryDirectory, judgePeerRecordFile, PEER_PRESENCE_MAX_CHARS, } from "./agents/peer-directory.js";
266
+ export { createReadInboxTool, READ_INBOX_TOOL_NAME, READ_INBOX_MAX_LIMIT, READ_INBOX_RESULT_BUDGET_CHARS } from "./agents/read-inbox-tool.js";
267
+ export { TEAM_ROLES, DIRECTION_RELATIONS, teamRoleOf, mayDirect } from "./agents/team-role.js";
268
+ export { createListAgentsTool, LIST_AGENTS_TOOL_NAME, LIST_AGENTS_TOOL_ALIAS, LIST_AGENTS_MAX_RESULT_CHARS, PEER_LISTING_FRESH_WINDOW_MS, isFreshPeerRow } from "./agents/list-agents-tool.js";
267
269
  export { CROSS_SESSION_CLASSIFIER_RULE } from "./agents/cross-session-envelope.js";
268
- export { PEER_SESSION_ID_UNGRAMMATICAL_CODE } from "./agents/peer-session-drain.js";
270
+ export { PEER_SESSION_ID_UNGRAMMATICAL_CODE, PEER_RESUPPLY_CAP } from "./agents/peer-session-drain.js";
269
271
  export { renderCrossSessionMessageFrame, renderCrossSessionNoticeLine } from "./core/task-notification.js";
270
272
  export { PEER_HELD_QUEUE_CAP, PEER_IDLE_SUBSCRIPTION_TTL_MS, PEER_IDLE_SUBSCRIBER_TABLE_CAP, PEER_IDLE_OUTSTANDING_CAP, PEER_IDLE_PRIORS_KEPT, PEER_IDLE_FIRE_DEBOUNCE_MS, PEER_IDLE_HELD_BACKOFF_MS, PEER_IDLE_LABEL_MAX, CROSS_SESSION_DIALOG_EXPIRY_VALUES, CROSS_SESSION_DIALOG_EXPIRY_DEFAULT, resolveCrossSessionDialogExpiry, PEER_HELD_REVIEW_CAUSES, PEER_DELIVERY_RECEIPT_STATES, isPeerDeliveryReceiptState, PEER_DROP_REASONS, peerRecipientSuffix, renderCrossSessionDeliveryNotice, describePeerDropReasons, renderCrossSessionDroppedNotice, PEER_IDLE_NOTICE_KINDS, isPeerIdleNoticeKind, PEER_IDLE_UNAVAILABLE_CAUSES, peerIdleNoticeLabel, formatPeerNoticeClock, renderCrossSessionIdleNotice, describePeerIdleSubscription, } from "./agents/peer-notices.js";
271
273
  export { createPeerHeldQueue, peerHeldQueueFor, peerHeldQueueIfAny, peerHeldQueueKey, realPeerClock, } from "./agents/peer-held-queue.js";
@@ -293,10 +293,10 @@ export interface RunWorkflowToolDeps {
293
293
  * `ToolExecuteContext.interactiveTools` seat — without it a headless-clamped host's workflow
294
294
  * children could re-mount the interactive tool the host run disabled. */
295
295
  parentInteractiveTools?: false;
296
- /** Call-time getter for the HOST task's RESOLVED Model object: a spawned agent whose
297
- * fold chain produced no model inherits the parent's full object (baseUrl/key routing included),
298
- * mirroring the subagent lane's ctx.model semantics. */
299
- parentModel?: () => import("../internal/llm.js").Model | undefined;
296
+ /** Call-time getter for the HOST task's RESOLVED model AND the word that chose it: a spawned agent whose
297
+ * fold chain produced no model inherits the object on its spec and the word on its trusted channel
298
+ * (the subagent lane's `ctx.model` / `ctx.modelRef` pair). Word-less ⇒ the object alone, i.e. a pin. */
299
+ parentModel?: () => import("../agents/child-model-seat.js").InheritedModelPick | undefined;
300
300
  /** The HOST task's per-model auth hook: the CREDENTIAL half of model
301
301
  * inheritance. The Model object fixed the URL routing but the child brain still authenticated
302
302
  * with the boot env token (rerun: 7/7 kimi-route 401s with the qwen key). The subagent lane
@@ -451,7 +451,7 @@ export interface RunWorkflowOptions {
451
451
  * parent's full object — baseUrl/key routing included — instead of falling to a string/role
452
452
  * re-resolution that loses per-model routing (the 4/4-agents-404 incident: session model id
453
453
  * re-resolved against the base gateway). Mirrors the subagent lane's `ctx.model` semantics. */
454
- defaultModel?: () => import("../internal/llm.js").Model | undefined;
454
+ defaultModel?: () => import("../agents/child-model-seat.js").InheritedModelPick | undefined;
455
455
  /** Call-time getter for the thinking level a spawned agent runs at when neither the script, the
456
456
  * agentType definition nor the governance baseline set `thinking` — the child thinking seat's lower rungs
457
457
  * (the deployment's STATED `roles.subagent.thinking`, else the host's current level), as the run-workflow