@sema-agent/core 7.15.0 → 7.17.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 (287) hide show
  1. package/CHANGELOG.md +202 -0
  2. package/dist/agents/builtin-agents.d.ts +3 -3
  3. package/dist/agents/cross-session-envelope.d.ts +0 -1
  4. package/dist/agents/cross-session-envelope.js +0 -1
  5. package/dist/agents/peer-notices.d.ts +0 -9
  6. package/dist/agents/peer-notices.js +0 -63
  7. package/dist/agents/subagent.js +7 -15
  8. package/dist/brain/request-params.d.ts +2 -2
  9. package/dist/config/defaults.d.ts +0 -7
  10. package/dist/config/defaults.js +0 -2
  11. package/dist/core/artifact-host.d.ts +218 -0
  12. package/dist/core/artifact-host.js +92 -0
  13. package/dist/core/ask-origin.d.ts +29 -3
  14. package/dist/core/ask-origin.js +17 -9
  15. package/dist/core/ask-question.d.ts +25 -0
  16. package/dist/core/ask-question.js +4 -0
  17. package/dist/core/ask-unresolvable-notice.d.ts +30 -21
  18. package/dist/core/ask-unresolvable-notice.js +16 -8
  19. package/dist/core/auto-compaction.d.ts +10 -10
  20. package/dist/core/auto-mode-arming.d.ts +2 -2
  21. package/dist/core/background-agent-store.d.ts +5 -5
  22. package/dist/core/background-shell.d.ts +1 -1
  23. package/dist/core/checkpoint-execution-record.d.ts +0 -3
  24. package/dist/core/checkpoint-execution-record.js +0 -4
  25. package/dist/core/checkpoint-store.d.ts +71 -99
  26. package/dist/core/checkpoint-store.js +9 -16
  27. package/dist/core/context-edit.d.ts +36 -104
  28. package/dist/core/context-edit.js +37 -60
  29. package/dist/core/effective-path-target.d.ts +68 -8
  30. package/dist/core/effective-path-target.js +42 -30
  31. package/dist/core/engine-notice.d.ts +46 -32
  32. package/dist/core/env-budget.d.ts +31 -0
  33. package/dist/core/env-budget.js +39 -0
  34. package/dist/core/exec-output-tail.d.ts +5 -5
  35. package/dist/core/file-history-store.js +3 -6
  36. package/dist/core/fs-write-gate-policy.d.ts +1 -1
  37. package/dist/core/fs-write-gate-policy.js +3 -3
  38. package/dist/core/gate-lanes.js +9 -15
  39. package/dist/core/governance-codes.d.ts +1 -1
  40. package/dist/core/governance-codes.js +4 -0
  41. package/dist/core/hands-band.d.ts +1 -1
  42. package/dist/core/hooks.d.ts +18 -17
  43. package/dist/core/lsp-session.d.ts +1 -1
  44. package/dist/core/lsp.d.ts +1 -1
  45. package/dist/core/lsp.js +5 -4
  46. package/dist/core/mcp.d.ts +5 -5
  47. package/dist/core/mcp.js +4 -48
  48. package/dist/core/memory-engine/delegation-settlement.d.ts +37 -12
  49. package/dist/core/memory-engine/delegation-settlement.js +128 -39
  50. package/dist/core/memory-engine/engine.d.ts +9 -8
  51. package/dist/core/memory-engine/engine.js +115 -120
  52. package/dist/core/memory-engine/file-backend.d.ts +17 -5
  53. package/dist/core/memory-engine/file-backend.js +78 -34
  54. package/dist/core/memory-engine/index.d.ts +2 -2
  55. package/dist/core/memory-engine/index.js +2 -2
  56. package/dist/core/memory-engine/layout.d.ts +152 -54
  57. package/dist/core/memory-engine/layout.js +441 -104
  58. package/dist/core/memory-engine/types.d.ts +8 -3
  59. package/dist/core/memory-engine/types.js +5 -0
  60. package/dist/core/memory-recall.d.ts +0 -8
  61. package/dist/core/memory.d.ts +1 -1
  62. package/dist/core/oracle-isolation.js +2 -2
  63. package/dist/core/parent-spec-seat.d.ts +66 -0
  64. package/dist/core/parent-spec-seat.js +47 -0
  65. package/dist/core/permission-rule-model.d.ts +11 -6
  66. package/dist/core/permission-rule-model.js +53 -37
  67. package/dist/core/permission-rules.js +8 -3
  68. package/dist/core/protocol-naming.d.ts +2 -2
  69. package/dist/core/remote-env.d.ts +1 -1
  70. package/dist/core/retired-keys.d.ts +19 -0
  71. package/dist/core/retired-keys.js +15 -0
  72. package/dist/core/runner/abort-race.d.ts +3 -3
  73. package/dist/core/runner/active-skill-scope.d.ts +2 -2
  74. package/dist/core/runner/active-skill-scope.js +3 -3
  75. package/dist/core/runner/assemble-result.d.ts +42 -40
  76. package/dist/core/runner/assemble-result.js +5 -4
  77. package/dist/core/runner/checkpoint-scope.d.ts +4 -4
  78. package/dist/core/runner/clock-and-limits.d.ts +3 -3
  79. package/dist/core/runner/compaction-call-options.d.ts +35 -99
  80. package/dist/core/runner/compaction-knobs.d.ts +4 -4
  81. package/dist/core/runner/compaction-seams.d.ts +5 -5
  82. package/dist/core/runner/contracts.d.ts +232 -233
  83. package/dist/core/runner/decide-continuation.d.ts +6 -6
  84. package/dist/core/runner/denial-limit-arms.d.ts +8 -8
  85. package/dist/core/runner/derived-route-fallback.d.ts +2 -2
  86. package/dist/core/runner/gate-exit.d.ts +6 -6
  87. package/dist/core/runner/gate-exit.js +15 -1
  88. package/dist/core/runner/git-status-frame.d.ts +7 -7
  89. package/dist/core/runner/halt-attribution.d.ts +35 -0
  90. package/dist/core/runner/halt-attribution.js +16 -0
  91. package/dist/core/runner/inherited-ask-grants.d.ts +6 -6
  92. package/dist/core/runner/memory-capture-optout.d.ts +1 -1
  93. package/dist/core/runner/memory-consolidation-driver.d.ts +4 -4
  94. package/dist/core/runner/memory-consolidation.d.ts +6 -8
  95. package/dist/core/runner/memory-consolidation.js +0 -1
  96. package/dist/core/runner/park-commit.d.ts +6 -6
  97. package/dist/core/runner/permission-rule-lanes.d.ts +19 -19
  98. package/dist/core/runner/prepare-acquire-reconcile.d.ts +4 -4
  99. package/dist/core/runner/prepare-artifact.d.ts +53 -0
  100. package/dist/core/runner/prepare-artifact.js +77 -0
  101. package/dist/core/runner/prepare-ask-lane.d.ts +3 -3
  102. package/dist/core/runner/prepare-boundary-parks.d.ts +3 -3
  103. package/dist/core/runner/prepare-caps-and-workflow.d.ts +9 -7
  104. package/dist/core/runner/prepare-caps-and-workflow.js +2 -3
  105. package/dist/core/runner/prepare-config-doors.d.ts +24 -24
  106. package/dist/core/runner/prepare-config-doors.js +5 -2
  107. package/dist/core/runner/prepare-context-lane.d.ts +8 -8
  108. package/dist/core/runner/prepare-context-lane.js +2 -13
  109. package/dist/core/runner/prepare-defer-classify.d.ts +2 -2
  110. package/dist/core/runner/prepare-delegation-surface.d.ts +1 -1
  111. package/dist/core/runner/prepare-file-history.d.ts +3 -3
  112. package/dist/core/runner/prepare-file-history.js +3 -52
  113. package/dist/core/runner/prepare-gate-stations.d.ts +5 -5
  114. package/dist/core/runner/prepare-hands-readface.d.ts +35 -38
  115. package/dist/core/runner/prepare-hands-readface.js +3 -2
  116. package/dist/core/runner/prepare-inherited-gate.d.ts +9 -6
  117. package/dist/core/runner/prepare-inherited-gate.js +7 -8
  118. package/dist/core/runner/prepare-listings.d.ts +3 -3
  119. package/dist/core/runner/prepare-lsp.d.ts +3 -3
  120. package/dist/core/runner/prepare-memory-engine-session.d.ts +5 -5
  121. package/dist/core/runner/prepare-memory.d.ts +4 -6
  122. package/dist/core/runner/prepare-memory.js +10 -9
  123. package/dist/core/runner/prepare-offload-wrappers.d.ts +2 -2
  124. package/dist/core/runner/prepare-park-ask.d.ts +6 -6
  125. package/dist/core/runner/prepare-policy-chain.d.ts +7 -7
  126. package/dist/core/runner/prepare-policy-chain.js +15 -30
  127. package/dist/core/runner/prepare-prompt-assembly.js +1 -1
  128. package/dist/core/runner/prepare-prompt-inputs.d.ts +5 -5
  129. package/dist/core/runner/prepare-protocol-tools.d.ts +1 -1
  130. package/dist/core/runner/prepare-question-face.d.ts +4 -4
  131. package/dist/core/runner/prepare-run-refs.d.ts +11 -11
  132. package/dist/core/runner/prepare-safety-scan.d.ts +2 -2
  133. package/dist/core/runner/prepare-suspend-saga.d.ts +4 -4
  134. package/dist/core/runner/prepare-suspend-saga.js +0 -2
  135. package/dist/core/runner/prepare-task.d.ts +12 -12
  136. package/dist/core/runner/prepare-task.js +10 -9
  137. package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +2 -3
  138. package/dist/core/runner/prepare-wiring-manifest.d.ts +4 -4
  139. package/dist/core/runner/prepare-wiring-manifest.js +9 -7
  140. package/dist/core/runner/prepare-workspace-restore.d.ts +1 -1
  141. package/dist/core/runner/remote-env-retry.d.ts +3 -3
  142. package/dist/core/runner/resume-admission.d.ts +1 -1
  143. package/dist/core/runner/resume-admission.js +2 -1
  144. package/dist/core/runner/resume-claim.d.ts +1 -1
  145. package/dist/core/runner/resume-internals-and-config.d.ts +1 -1
  146. package/dist/core/runner/resume-internals-and-config.js +4 -0
  147. package/dist/core/runner/resume-policy-outcome.d.ts +1 -1
  148. package/dist/core/runner/resume-preflight.d.ts +1 -1
  149. package/dist/core/runner/resume-review-outcome.d.ts +1 -1
  150. package/dist/core/runner/retired-runner-deps.d.ts +3 -0
  151. package/dist/core/runner/retired-runner-deps.js +7 -0
  152. package/dist/core/runner/run-brain-sinks.d.ts +1 -1
  153. package/dist/core/runner/run-clock-and-content.d.ts +4 -4
  154. package/dist/core/runner/run-compaction-machinery.d.ts +3 -3
  155. package/dist/core/runner/run-git-lane.d.ts +1 -1
  156. package/dist/core/runner/run-harness-handlers.d.ts +2 -2
  157. package/dist/core/runner/run-harness-handlers.js +2 -3
  158. package/dist/core/runner/run-identity-wiring.d.ts +4 -4
  159. package/dist/core/runner/run-leg.d.ts +3 -3
  160. package/dist/core/runner/run-notification-lane.d.ts +2 -2
  161. package/dist/core/runner/run-reasoning-seat.d.ts +2 -2
  162. package/dist/core/runner/run-settle-and-teardown.d.ts +5 -5
  163. package/dist/core/runner/run-settle-and-teardown.js +3 -1
  164. package/dist/core/runner/run-telemetry-and-budget-seats.d.ts +2 -2
  165. package/dist/core/runner/run-terminal-adoption.d.ts +5 -5
  166. package/dist/core/runner/runtask.d.ts +14 -14
  167. package/dist/core/runner/session-file-state-replay.d.ts +3 -3
  168. package/dist/core/runner/session-file-state-replay.js +3 -3
  169. package/dist/core/runner/session-rule-policy.d.ts +2 -2
  170. package/dist/core/runner/session-rule-policy.js +3 -4
  171. package/dist/core/runner/steer-admission.d.ts +2 -2
  172. package/dist/core/runner/stream-halt-verbs.d.ts +1 -1
  173. package/dist/core/runner/stream-halt-verbs.js +1 -1
  174. package/dist/core/runner/stream-reap.d.ts +1 -1
  175. package/dist/core/runner/stream-steer-verb.js +1 -4
  176. package/dist/core/runner/synthetic-tools.d.ts +8 -8
  177. package/dist/core/runner/teardown-bounded.d.ts +2 -2
  178. package/dist/core/runner/tool-defer-gate.d.ts +1 -1
  179. package/dist/core/runner/tool-disclosure.d.ts +33 -33
  180. package/dist/core/runner/tool-end-body.d.ts +3 -3
  181. package/dist/core/runner/tool-face-overlay.d.ts +2 -2
  182. package/dist/core/runner/tool-output-projection.d.ts +2 -2
  183. package/dist/core/runner/turn-attachments.d.ts +53 -53
  184. package/dist/core/runner/usage-accounting.d.ts +4 -4
  185. package/dist/core/runner/workspace-path.d.ts +1 -1
  186. package/dist/core/runner/workspace-path.js +3 -0
  187. package/dist/core/runner-deps.d.ts +30 -49
  188. package/dist/core/safe-notify.d.ts +1 -1
  189. package/dist/core/sensitive-path-policy.d.ts +1 -1
  190. package/dist/core/sensitive-path-policy.js +4 -4
  191. package/dist/core/session.d.ts +2 -2
  192. package/dist/core/skill-tool-specifier.d.ts +1 -1
  193. package/dist/core/skills-directory.d.ts +1 -1
  194. package/dist/core/store-contracts/checkpoint-store-contract.js +1 -1
  195. package/dist/core/strategy-store.d.ts +8 -11
  196. package/dist/core/task-event.d.ts +20 -17
  197. package/dist/core/task-limits.d.ts +1 -1
  198. package/dist/core/task-notification.d.ts +5 -5
  199. package/dist/core/task-registry-agent.d.ts +5 -5
  200. package/dist/core/task-registry-monitor.d.ts +2 -2
  201. package/dist/core/task-registry-shared.d.ts +27 -27
  202. package/dist/core/task-registry-shared.js +3 -13
  203. package/dist/core/task-registry.d.ts +8 -8
  204. package/dist/core/task-result.d.ts +37 -37
  205. package/dist/core/task-spec.d.ts +5 -5
  206. package/dist/core/task-stream.d.ts +16 -11
  207. package/dist/core/tool-catalog-entries.d.ts +1 -0
  208. package/dist/core/tool-catalog-entries.js +5 -0
  209. package/dist/core/tool-conformance.d.ts +0 -2
  210. package/dist/core/tool-conformance.js +1 -3
  211. package/dist/core/tool-errors.d.ts +5 -0
  212. package/dist/core/tool-errors.js +1 -0
  213. package/dist/core/tool-policy.d.ts +51 -22
  214. package/dist/core/tool-policy.js +28 -5
  215. package/dist/core/tool-result-budget.d.ts +1 -1
  216. package/dist/core/tool-result-store.d.ts +11 -11
  217. package/dist/core/tool-spec.d.ts +34 -38
  218. package/dist/core/tools.d.ts +2 -2
  219. package/dist/core/trace.d.ts +12 -15
  220. package/dist/core/untrusted-text.d.ts +1 -1
  221. package/dist/core/wiring-manifest.d.ts +4 -3
  222. package/dist/core/workflow-journal-store.d.ts +11 -11
  223. package/dist/engine/execution-env/node-execution-env.d.ts +3 -2
  224. package/dist/engine/execution-env/node-execution-env.js +4 -2
  225. package/dist/engine/harness/agent-harness.d.ts +47 -4
  226. package/dist/engine/harness/agent-harness.js +52 -9
  227. package/dist/engine/llm/types.d.ts +1 -1
  228. package/dist/engine/loop/agent-loop.js +15 -8
  229. package/dist/engine/loop/types.d.ts +5 -0
  230. package/dist/index.d.ts +21 -16
  231. package/dist/index.js +17 -12
  232. package/dist/internal/harness.d.ts +1 -0
  233. package/dist/orchestration/run-spec.d.ts +3 -0
  234. package/dist/orchestration/run-spec.js +3 -3
  235. package/dist/orchestration/run-workflow-tool.d.ts +12 -6
  236. package/dist/orchestration/run-workflow-tool.js +23 -5
  237. package/dist/orchestration/workflow-primitives.d.ts +4 -2
  238. package/dist/orchestration/workflow-primitives.js +1 -4
  239. package/dist/orchestration/workflow-types.d.ts +34 -4
  240. package/dist/orchestration/workflow-types.js +2 -0
  241. package/dist/orchestration/workflow.d.ts +39 -7
  242. package/dist/orchestration/workflow.js +234 -113
  243. package/dist/prompt-assembly/assemble.d.ts +2 -2
  244. package/dist/prompt-assembly/assemble.js +9 -9
  245. package/dist/prompt-assembly/composer.d.ts +6 -7
  246. package/dist/prompt-assembly/composer.js +10 -10
  247. package/dist/prompt-assembly/epoch.js +1 -1
  248. package/dist/prompt-assembly/event-registry.d.ts +0 -21
  249. package/dist/prompt-assembly/packs/sema-default.js +30 -30
  250. package/dist/prompt-assembly/types.d.ts +14 -14
  251. package/dist/prompts/coordinator.d.ts +0 -13
  252. package/dist/prompts/coordinator.js +0 -3
  253. package/dist/stores/file/checkpoint-store.js +1 -5
  254. package/dist/stores/file/file-history-store.js +2 -2
  255. package/dist/stores/file/permission-rule-store.d.ts +4 -35
  256. package/dist/stores/file/permission-rule-store.js +4 -148
  257. package/dist/tools/artifact/artifact-text.d.ts +62 -0
  258. package/dist/tools/artifact/artifact-text.js +68 -0
  259. package/dist/tools/artifact/artifact-tool.d.ts +52 -0
  260. package/dist/tools/artifact/artifact-tool.js +351 -0
  261. package/dist/tools/artifact/local-stub.d.ts +26 -0
  262. package/dist/tools/artifact/local-stub.js +296 -0
  263. package/dist/tools/fs/bash-readonly-classifier.d.ts +114 -48
  264. package/dist/tools/fs/bash-readonly-classifier.js +171 -60
  265. package/dist/tools/fs/encoding.d.ts +31 -40
  266. package/dist/tools/fs/fs-bash.d.ts +49 -45
  267. package/dist/tools/fs/fs-bash.js +19 -27
  268. package/dist/tools/fs/fs-pdf.d.ts +8 -8
  269. package/dist/tools/fs/fs-search-tools.d.ts +4 -4
  270. package/dist/tools/fs/fs-search-tools.js +5 -2
  271. package/dist/tools/fs/fs-shared.d.ts +146 -158
  272. package/dist/tools/fs/fs-shared.js +3 -11
  273. package/dist/tools/fs/fs-write.d.ts +8 -8
  274. package/dist/tools/fs/gh-rate-limit.d.ts +13 -14
  275. package/dist/tools/fs/index.d.ts +78 -78
  276. package/dist/tools/fs/index.js +4 -1
  277. package/dist/tools/fs/notebook.d.ts +24 -25
  278. package/dist/tools/fs/pdf.d.ts +3 -3
  279. package/dist/tools/fs/read-deny.d.ts +22 -22
  280. package/dist/tools/fs/read-face.d.ts +21 -24
  281. package/dist/tools/fs/repo-map.d.ts +8 -8
  282. package/dist/tools/fs/safety.d.ts +233 -130
  283. package/dist/tools/fs/safety.js +131 -31
  284. package/dist/tools/fs/search.d.ts +63 -71
  285. package/dist/tools/fs/search.js +8 -6
  286. package/package.json +6 -2
  287. package/test/export-surface.snapshot.json +119 -39
@@ -6,7 +6,6 @@ import { type QuestionAnswer } from "./ask-question.js";
6
6
  import type { ReadEntry } from "../tools/fs/safety.js";
7
7
  import type { RepairBundle } from "../agents/repair-loop.js";
8
8
  import type { WorkspaceHandle } from "./remote-env.js";
9
- import type { ConsolidationNote } from "./runner/memory-consolidation.js";
10
9
  import type { SessionPermissionRules } from "./session-policy-store.js";
11
10
  import type { NestedUsageAccum, ShellGateDoctrine, TaskResult } from "./types.js";
12
11
  import type { ActiveWorktreeSession } from "../internal/harness-types.js";
@@ -95,17 +94,18 @@ export type ResourceLimitReason = "budget_tokens" | "budget_cost" | "walltime" |
95
94
  */
96
95
  export type PlatformLimitReason = Extract<ResourceLimitReason, "env_lifetime" | "usage_window">;
97
96
  /**
98
- * design/80 D-2: which SAFETY MARK(s) on the tool caused an `ask` to mint an {@link CheckpointGate}
99
- * `irreversible_ask`. Derived from the tool's STATIC spec marks (`ToolSpec.egress` / `ToolSpec.irreversibility`,
100
- * round-1 council fix NOT the per-call `decisionReason`, which missed a policy/hook pre-ask and was
101
- * forgeable). Persisted on the gate so a network budget/escalation resolver reads WHY this is a safety ask FROM
102
- * THE DURABLE RECORD (never re-derives risk from a model-controlled value — the model self-reports nothing
103
- * here). Both can be true (a tool marked BOTH egress AND irreversible).
97
+ * design/80 D-2: which SAFETY axis of THIS call caused an `ask` to mint an {@link CheckpointGate}
98
+ * `irreversible_ask`. Derived by the gate (`safetyAxisOf`) from the tool's static marks plus the engine's own
99
+ * per-call factsnever from a decision member a policy composes (forgeable). Persisted on the gate so a
100
+ * network budget/escalation resolver reads WHY this is a safety ask FROM THE DURABLE RECORD. Both can be true.
104
101
  */
105
102
  export interface SafetyAxis {
106
103
  /** design/70: the tool is egress-marked (`ToolSpec.egress` — an external write: push, open PR, send). */
107
104
  egress?: boolean;
108
- /** design/77 §4: the tool's irreversibility tier is `always` or `maybe` (`ToolSpec.irreversibility`). */
105
+ /** design/77 §4: this call carries an irreversibility MANDATE — the tool's own `always`/`maybe` tier, the
106
+ * operator's `shellGate:"always"`, the probe's structural verdict (mandated / unanswered), or the shell
107
+ * gate's own tighten under its `"maybe"` tier; a policy ask the doctrine's probe neither tightened nor
108
+ * mandated carries no bit (its park is the budgetable kind). */
109
109
  irreversible?: boolean;
110
110
  }
111
111
  /**
@@ -157,7 +157,7 @@ export interface RiskDescriptor {
157
157
  * {@link summary} (a path name can carry the same reordering hazard as a command) + capped.
158
158
  * Omitted when none derivable. */
159
159
  touchedPaths?: string[];
160
- /** #144 (additive): a persisted allow rule MATCHED this call but could not clear the mandated ask —
160
+ /** A persisted allow rule MATCHED this call but could not clear the mandated ask —
161
161
  * the matched rule text (rendered through the same display baseline as {@link summary}, capped),
162
162
  * threaded to the mint so the durable-park route carries the same disclosure the synchronous ask
163
163
  * does. The inbox renders "their rule is alive, just outranked" instead of the person concluding
@@ -173,7 +173,7 @@ export interface RiskDescriptor {
173
173
  * same-value contract (unlike `probeReason`/`probeCause` below), which is why the one-face move
174
174
  * is legal — a byte-pinning consumer must read per face.) */
175
175
  shadowedRule?: string;
176
- /** backlog #239 (additive): WHY the reversibility probe did not clear this call, in the probe's own
176
+ /** WHY the reversibility probe did not clear this call, in the probe's own
177
177
  * words — the cause the tighten acted on, which until now existed only inside the probe and left the
178
178
  * card showing WHAT is gated with no account of WHY. Present only for a `"maybe"`-tier tighten whose
179
179
  * probe supplied a cause (an `"always"`-tier tighten runs no probe; a timeout/throw yields no verdict).
@@ -190,7 +190,7 @@ export interface RiskDescriptor {
190
190
  * one-face re-render would break it. A consumer rendering this seat owes its own screen (or the
191
191
  * descriptor family's display baseline). */
192
192
  probeReason?: string;
193
- /** backlog #239 (additive): the STRUCTURED cause, for a probe whose verdict this engine understands —
193
+ /** The STRUCTURED cause, for a probe whose verdict this engine understands —
194
194
  * the built-in shell probe is the first. Carries a machine-readable {@link ProbeCause.code} and the
195
195
  * operand families as ARRAYS with honest totals, so a consumer renders its own sentence in its own
196
196
  * language instead of receiving one this engine had to write in advance.
@@ -202,7 +202,7 @@ export interface RiskDescriptor {
202
202
  * whichever part sorts last. A code cannot be false and an array cannot be truncated into a lie. */
203
203
  probeCause?: ProbeCause;
204
204
  }
205
- /** backlog #239: one operand family inside a {@link ProbeCause} — the entries a card may NAME, plus how
205
+ /** One operand family inside a {@link ProbeCause} — the entries a card may NAME, plus how
206
206
  * many the family really has. `shown.length` ≤ {@link total}, and a consumer that renders only `shown`
207
207
  * is still obliged to tell the person when `total` exceeds it: the count is the part that cannot be
208
208
  * cut, and "there is a second unreviewed operand" is exactly what a reader cannot recover from the
@@ -221,7 +221,7 @@ export interface ProbeCauseOperands {
221
221
  readonly total: number;
222
222
  }
223
223
  /**
224
- * backlog #239: an ENGINE-MINTED, structured account of why a reversibility probe did not clear a call.
224
+ * An ENGINE-MINTED, structured account of why a reversibility probe did not clear a call.
225
225
  *
226
226
  * DISPLAY/TRIAGE metadata, exactly like the rest of {@link RiskDescriptor} — nothing reads it to gate,
227
227
  * budget or suppress anything, and it deliberately never reaches the ask's `message` (that string is
@@ -248,14 +248,14 @@ export interface ProbeCause {
248
248
  * account of an approval's reach is worse than none. */
249
249
  readonly further?: ProbeCauseOperands;
250
250
  }
251
- /** backlog #239: the bloat ceiling on {@link RiskDescriptor.probeReason} — one sentence of cause, sized
251
+ /** The bloat ceiling on {@link RiskDescriptor.probeReason} — one sentence of cause, sized
252
252
  * like its {@link RiskDescriptor.shadowedRule} sibling. The neutralizer is the injection ceiling; this
253
253
  * is only the length one. Exported (module-level, not part of the package's public surface) so the gate
254
254
  * that sanitizes at the entry boundary and the descriptor builder that re-sanitizes at the persist
255
255
  * boundary cannot cap the same value at two different lengths. */
256
256
  export declare const PROBE_REASON_MAX = 200;
257
257
  /**
258
- * backlog #239: the ONE validator for a {@link ProbeCause} arriving from a probe.
258
+ * The ONE validator for a {@link ProbeCause} arriving from a probe.
259
259
  *
260
260
  * The value crosses a trust boundary twice — once at the gate (where a deployment-supplied probe hands
261
261
  * it over) and once at the persist boundary (where {@link buildRiskDescriptor} is an exported function a
@@ -410,19 +410,19 @@ export declare function buildRiskDescriptor(input: {
410
410
  shellGated?: boolean;
411
411
  /** The resolved doctrine to persist when `shellGated` (see {@link RiskDescriptor.shellGateDoctrine}). */
412
412
  shellGateDoctrine?: ShellGateDoctrine;
413
- /** #144: the matched-but-outranked persisted rule to persist (see {@link RiskDescriptor.shadowedRule}). */
413
+ /** The matched-but-outranked persisted rule to persist (see {@link RiskDescriptor.shadowedRule}). */
414
414
  shadowedRule?: string;
415
- /** backlog #239: the reversibility probe's cause for not clearing this call (see
415
+ /** The reversibility probe's cause for not clearing this call (see
416
416
  * {@link RiskDescriptor.probeReason}). Re-neutralized here like its shadowed-rule sibling: this
417
417
  * function is exported, so a caller reaching it directly must get the same redaction the gate applies. */
418
418
  probeReason?: string;
419
- /** backlog #239: the STRUCTURED cause (see {@link RiskDescriptor.probeCause}). Re-validated here for
419
+ /** The STRUCTURED cause (see {@link RiskDescriptor.probeCause}). Re-validated here for
420
420
  * the same reason the prose sibling is re-neutralized — this function is exported, so a caller
421
421
  * reaching it directly must not be able to persist a shape the gate would have rejected. */
422
422
  probeCause?: unknown;
423
423
  }): RiskDescriptor;
424
424
  /**
425
- * #130/#131/#120 (2026-08-10) — the durable record of an ask's `requiresRealApproval` bit, which used
425
+ * The durable record of an ask's `requiresRealApproval` bit, which used
426
426
  * to DIE at the park: the mint keyed the gate kind on the static tool marks only, so an org-governed
427
427
  * ask on an unmarked tool minted a plain `{kind:"human"}` — the one kind a network budget resolver may
428
428
  * auto-approve — and the org's "only judgment clears this" demand was silently budgetable after the
@@ -567,7 +567,7 @@ export type ResumeOutcome = {
567
567
  * that the human actually saw/approved (`PendingAction.tool_approval.boundInputHash`, computed by the
568
568
  * engine at suspend-mint via {@link import("./canonical-json.js").boundInputHashOf} over the post-hook
569
569
  * `args`). The caller echoes it VERBATIM — it is opaque; the SDK/service NEVER re-canonicalize args
570
- * (review r3: a second runtime's serialization could diverge → false mismatch → fail-closed a
570
+ * (a second runtime's serialization could diverge → false mismatch → fail-closed a
571
571
  * legitimate approval). The resume verifies it by **string equality** against the checkpoint's
572
572
  * persisted value (`checkpoint.invalid_outcome`, fail-closed, pre-CAS) — closing the TOCTOU "same call
573
573
  * id, different input" variant that `boundCallId` alone misses (a re-mint that swapped the input under
@@ -687,11 +687,11 @@ export type ResumeOutcome = {
687
687
  *
688
688
  * `message` (optional): operator content delivered to the resumed run — the ATOMIC equivalent of
689
689
  * `setPendingSteer` + resume in one verb (same `validatePendingSteer` persist-time guards, same
690
- * trusted/untrusted delivery framing as {@link CheckpointState.pendingSteer}). It rides the resume
691
- * continuation's steer tail as its OWN segment, appended AFTER any already-parked `pendingSteer`
690
+ * trusted/untrusted delivery framing as {@link CheckpointState.pendingSteerQueue}). It rides the resume
691
+ * continuation's steer tail as its OWN segment, appended AFTER any already-parked queue entry
692
692
  * (X5: both are delivered — the wake message never displaces a parked, undelivered supervisor steer;
693
693
  * each segment is framed under its own `trusted` semantics, never one merged trust domain). WITHOUT a
694
- * `message`, the checkpoint must already carry a parked `pendingSteer` — a wake with nothing to
694
+ * `message`, the checkpoint must already carry a parked steer — a wake with nothing to
695
695
  * deliver is rejected (`wake.nothing_to_deliver`, anti spin-wake). Idempotency rides the existing
696
696
  * resolve CAS: a second wake of the same token loses the CAS (`checkpoint.already_resolved`). */
697
697
  | {
@@ -798,7 +798,7 @@ export type PendingAction = {
798
798
  * this"). Absent otherwise (never `false`). Display metadata: the resume belts keep reading the
799
799
  * gate's own bit. */
800
800
  requiresRealApproval?: true;
801
- /** #557 (additive, same precedent) — the PARK twin of `AskRequest.denialLimitFallback`: present
801
+ /** The PARK twin of `AskRequest.denialLimitFallback`: present
802
802
  * ⇔ this parked ask is the classifier DENIAL-LIMIT fallback, carrying the counts that tripped
803
803
  * the bound. Its `autoDenyAfterMs` is ALWAYS `0` on a row: the window is a fact of the ask's
804
804
  * route, armed only at a hand-out to a live approver, and nothing counts down on the parked lane
@@ -935,8 +935,6 @@ export interface CheckpointState {
935
935
  };
936
936
  /** design/38: nested sub-agent cumulative cost — else pre-suspend child cost evaporates (§4.bis/Q7). */
937
937
  nestedStats: NestedUsageAccum;
938
- /** design/41: consolidation notes collected pre-suspend — else the task-end pass loses them. */
939
- consolidationNotes?: ConsolidationNote[];
940
938
  /** design/44: the hand's read-file state (content hashes), serialized from the hands-toolkit closure
941
939
  * (NOT part of Prepared — §15.2 net-add #8). Without it a resumed `edit_file` is rejected "not read". */
942
940
  readFileState?: Array<[string, ReadEntry]>;
@@ -1002,56 +1000,31 @@ export interface CheckpointState {
1002
1000
  */
1003
1001
  workspaceHandle?: WorkspaceHandle;
1004
1002
  /**
1005
- * design/80 D-A: a durable mid-task STEER for a DURABLY-SUSPENDED task. Live `TaskStream.steer`
1006
- * (runtask.ts) is unreachable while the harness is idle (durably suspended), so a human supervisor's
1007
- * guidance is parked HERE via {@link CheckpointStore.setPendingSteer} and injected on resume (runtask.ts,
1008
- * after the resume-continuation prompt). It is GUIDANCE ONLY — never an approval channel (§3 inv #4) and
1009
- * never parsed into control state (§3 inv #5); a budget/autonomy/gate-threshold is CONFIG, not steer text.
1003
+ * design/171 §5.3 the BOUNDED, ORDERED queue of parked operator steers for a DURABLY-SUSPENDED task,
1004
+ * drained in `seq` order on resume with every entry framed under its own trust semantics. Live
1005
+ * `TaskStream.steer` (runtask.ts) is unreachable while the harness is idle, so a supervisor's guidance is
1006
+ * parked HERE via {@link CheckpointStore.setPendingSteer} and injected on resume (after the
1007
+ * resume-continuation prompt). It is GUIDANCE ONLY — never an approval channel (§3 inv #4) and never
1008
+ * parsed into control state (§3 inv #5); a budget/autonomy/gate-threshold is CONFIG, not steer text.
1010
1009
  *
1011
1010
  * `trusted` is FROZEN at `setPendingSteer` from the SERVICE's verified-principal check (an operator-role
1012
- * check, NOT a client header the service's job, out of scope here) and NEVER recomputed on resume
1013
- * (§3 inv #1). On resume a `trusted:false` steer reaches the model as a PLAIN user message with NO
1014
- * `<system-reminder>` wrapper (no authority laundering, §3 inv #3); a `trusted:true` steer MAY ride the
1015
- * reminder (`formatHookFeedback`, mirroring the live trusted branch). `text` containing `</system-reminder>`
1016
- * is REJECTED at `setPendingSteer` (typed `steering.invalid_content`) so a dirty steer never enters this
1017
- * state (§3 inv #2); the untrusted-injection path ALSO sanitizes the text as untrusted data, belt-and-braces.
1018
- * Absent when no steer is pending. All-string fields → JSON/`structuredClone` round-trips safely.
1011
+ * check, NOT a client header) and NEVER recomputed on resume (§3 inv #1). A `trusted:false` entry reaches
1012
+ * the model as a PLAIN user message with NO `<system-reminder>` wrapper (§3 inv #3); a `trusted:true`
1013
+ * entry MAY ride the reminder. `text` containing `</system-reminder>` is REJECTED at `setPendingSteer`
1014
+ * (`steering.invalid_content`) so a dirty steer never enters this state (§3 inv #2).
1019
1015
  *
1020
- * **Delivery is BEST-EFFORT, at-most-meaningfully-once (review-council, by design):** a steer is GUIDANCE,
1021
- * not a correctness-critical message, so the delivery guarantee is intentionally loose:
1022
- * - It rides EVERY resume of THIS checkpoint that runs a turn including a faithful `env_failed`/
1023
- * `tool_unavailable` reopen→re-resume, which re-shows the guidance (coherent with the reopen REPLAYING the
1024
- * leg; the model re-does the work, re-seeing the steer). It is NOT carried onto a NEW re-suspend checkpoint
1025
- * (serializeCheckpointState stamps `undefined`) — a supervisor steers the new checkpoint afresh.
1026
- * - It is DROPPED (never delivered) on a resume that runs no turn (an exhausted-budget resume) or that is
1027
- * set in the get→resolve race window of an in-flight resume — both rare; the run is ending or the steer
1028
- * just missed its train. A supervisor re-issues `setPendingSteer` if a steer didn't land.
1029
- * A precise exactly-once delivery would need clearing the steer from the persisted row on consume (a reopen
1030
- * clear + a get→resolve interlock); deferred as not worth the cross-backend complexity for guidance text.
1031
- *
1032
- * **Superseded by {@link CheckpointState.pendingSteerQueue} (design/171 §5.3).** New writes go to the
1033
- * queue; this seat remains ONLY so rows written before the queue existed keep delivering their parked
1034
- * steer. Never read it directly — {@link readPendingSteerQueue} is the single read point that folds
1035
- * this legacy seat in as queue member 0.
1036
- */
1037
- pendingSteer?: {
1038
- text: string;
1039
- trusted: boolean;
1040
- };
1041
- /**
1042
- * design/171 §5.3 — the BOUNDED, ORDERED queue of parked operator steers, drained in `seq` order on
1043
- * resume with every entry framed under its own trust semantics.
1044
- *
1045
- * It replaces the single {@link CheckpointState.pendingSteer} seat, whose last-writer-wins overwrite
1046
- * meant two people steering one suspended run silently destroyed the first instruction — and destroyed
1047
- * it with no attribution, so nobody could tell afterwards that anything was lost.
1016
+ * Delivery is BEST-EFFORT, at-most-meaningfully-once: an entry rides EVERY resume of THIS checkpoint
1017
+ * that runs a turn (a faithful reopen→re-resume re-shows it), is NOT carried onto a re-suspend
1018
+ * checkpoint (serializeCheckpointState stamps `undefined`), and is DROPPED on a resume that runs no
1019
+ * turn. A supervisor re-issues `setPendingSteer` if a steer did not land.
1048
1020
  *
1049
1021
  * Bounds are fail-loud, never lossy: {@link MAX_PENDING_STEER_ENTRIES} entries and
1050
1022
  * {@link PENDING_STEER_QUEUE_BYTE_BUDGET_BYTES} serialized bytes, whichever binds first, reject the
1051
1023
  * APPEND with `steering.queue_full` rather than evicting an already-accepted instruction.
1052
1024
  *
1053
- * Absent when nothing is parked. A row may legally carry BOTH this and the legacy seat (a pre-queue
1054
- * suspend that was steered again after the upgrade); the read helper orders the legacy seat first.
1025
+ * Absent when nothing is parked. {@link readPendingSteerQueue} is the single read point; a row that
1026
+ * still carries the retired pre-queue single seat (`pendingSteer`) is refused there
1027
+ * (`checkpoint.unsupported_version`, `seat_retired`), never folded in.
1055
1028
  */
1056
1029
  pendingSteerQueue?: PendingSteerEntry[];
1057
1030
  /**
@@ -1258,7 +1231,7 @@ export interface CheckpointState {
1258
1231
  * EXPLICIT live `internals.placementRoot` wins when re-supplied; otherwise THIS key restores into
1259
1232
  * `internals.placementRoot` at prepare so descendants and the NEXT re-suspend mint inherit it too
1260
1233
  * — outranking a supplied `rootSessionId`, which is DELEGATION IDENTITY (the peer/registry axis a
1261
- * revive leg re-supplies from its row), never a placement claim (rescan C1: reading it as one
1234
+ * revive leg re-supplies from its row), never a placement claim (reading it as one
1262
1235
  * permanently stuck every parked agent spawned under an explicit placement root). The resume entry
1263
1236
  * ALSO reads this key as an identity record: a resume whose supplied `internals.placementRoot`
1264
1237
  * CONTRADICTS it is refused pre-CAS (`resume.placement_mismatch`); either side absent skips the
@@ -1474,7 +1447,7 @@ export declare function remainingTokens(ledger: ResourceLedger | undefined): num
1474
1447
  * later D-1 slice (1a.2) and is deliberately NOT part of this winner.
1475
1448
  */
1476
1449
  export interface ResolvedOutcome {
1477
- /** The pending tool call this decision was bound to (design/80 D-1 slice 1a). RB-64: a REVIEW gate binds
1450
+ /** The pending tool call this decision was bound to (design/80 D-1 slice 1a). A REVIEW gate binds
1478
1451
  * no tool call, so it records the synthetic `gate:<kind>` marker instead — the replay guard compares the
1479
1452
  * DECISION for those, never a call id. */
1480
1453
  boundCallId: string;
@@ -1878,7 +1851,7 @@ export interface CheckpointSummary {
1878
1851
  */
1879
1852
  toolInput?: string;
1880
1853
  /**
1881
- * RB-439-b — HOW this pause's remote workspace comes back, projected from
1854
+ * HOW this pause's remote workspace comes back, projected from
1882
1855
  * `state.workspaceHandle.restoreMode` so a supervisor inbox can tell the two apart in ONE `listByScope`
1883
1856
  * call. `"snapshot"` = the VM was paused into a snapshot (billing typically stops, memory state
1884
1857
  * captured); `"park_only"` = a non-suspendable target (SSH host / ADB device) was never paused — the
@@ -1906,12 +1879,12 @@ export interface CheckpointSummary {
1906
1879
  * projection's own materials (a pre-#457 row therefore reads absent, which is honest: unreported).
1907
1880
  * ECHO-ONLY display metadata; nothing gates on it. */
1908
1881
  previewWithheld?: "oversize" | "unavailable";
1909
- /** #557 — the row's `PendingAction.tool_approval.requiresRealApproval`, projected so the ONE-CALL
1882
+ /** The row's `PendingAction.tool_approval.requiresRealApproval`, projected so the ONE-CALL
1910
1883
  * inbox can label "only a person can clear this" without an N+1 `get`. `true` or OMITTED (the
1911
1884
  * {@link toolCallId} absence-shape contract); pure echo of the persisted bit — a pre-#557 row reads
1912
1885
  * absent, which is honest (unreported), never a claim that budget may clear it. */
1913
1886
  requiresRealApproval?: true;
1914
- /** #557 — the row's `PendingAction.tool_approval.denialLimitFallback`, projected BESIDE the preview
1887
+ /** The row's `PendingAction.tool_approval.denialLimitFallback`, projected BESIDE the preview
1915
1888
  * for the same one-call reason: a card that shows the fallback's counts and limit must not re-open
1916
1889
  * the row to learn them (`autoDenyAfterMs` is `0` on every row — see the row member). Pure echo;
1917
1890
  * OMITTED when the row carries none. */
@@ -1925,7 +1898,7 @@ export interface CheckpointSummary {
1925
1898
  * member of the closed set ({@link import("./ask-origin.js").isRuleStoreUnreadable}); OMITTED otherwise. */
1926
1899
  ruleStoreUnreadable?: import("./ask-origin.js").RuleStoreUnreadable;
1927
1900
  /**
1928
- * #438: PRESENCE ONLY — this pending `tool_approval` row's payload carries at least one DIRECTIONAL
1901
+ * PRESENCE ONLY — this pending `tool_approval` row's payload carries at least one DIRECTIONAL
1929
1902
  * format control (the {@link import("./tool-policy.js").AskRequest.hasBidiControls} character class;
1930
1903
  * that doc owns the hazard). Only ever for a `tool_approval` pendingAction; OMITTED for every other
1931
1904
  * kind (the {@link toolCallId} ABSENCE-SHAPE contract applies: never `null`, never present-but-
@@ -1984,12 +1957,14 @@ export declare function summarizeCheckpoint(cp: Checkpoint): CheckpointSummary;
1984
1957
  * decides the orphaned card itself, no worker version redeems it), `"ledger_event_unknown"` (a durable
1985
1958
  * LEDGER carries an event kind this binary does not know, so the replay is refused rather than served
1986
1959
  * incomplete — the one arm that is not row-scoped: NO row in that data directory is readable here, so
1987
- * the host rolls the binary forward instead of routing one token elsewhere).
1960
+ * the host rolls the binary forward instead of routing one token elsewhere), `"seat_retired"` (the row
1961
+ * parks a steer in the retired pre-queue single seat — terminal for the row's bytes; no worker version
1962
+ * reads that seat, the host decides the parked instruction itself).
1988
1963
  * · `invalid_outcome` pre-CAS row-integrity arms: `"real_approval_damaged"`, `"real_approval_forged"`,
1989
1964
  * `"read_face_damaged"`, `"read_face_forged"`, `"constraint_chain_missing"` (all terminal for the row's
1990
1965
  * current bytes — no worker version redeems a damaged row).
1991
1966
  */
1992
- export type CheckpointErrorReason = "version_newer" | "env_factory_missing" | "governed_unwired" | "origin_missing" | "ledger_event_unknown" | "real_approval_damaged" | "real_approval_forged" | "read_face_damaged" | "read_face_forged" | "constraint_chain_missing";
1967
+ export type CheckpointErrorReason = "version_newer" | "env_factory_missing" | "governed_unwired" | "origin_missing" | "ledger_event_unknown" | "seat_retired" | "real_approval_damaged" | "real_approval_forged" | "read_face_damaged" | "read_face_forged" | "constraint_chain_missing";
1993
1968
  /** A typed checkpoint-store error so callers branch on `code` (mirrors `SessionError`). */
1994
1969
  export declare class CheckpointError extends Error {
1995
1970
  readonly code: "checkpoint.already_exists" | "checkpoint.already_resolved" | "checkpoint.not_found"
@@ -1997,7 +1972,7 @@ export declare class CheckpointError extends Error {
1997
1972
  * persisted {@link CheckpointGate} `kind` (council #3 — type confusion guard), or a gate v1
1998
1973
  * resume does not serve (`task_done`). */
1999
1974
  | "checkpoint.gate_mismatch"
2000
- /** RB-77: `runner.resume` was handed an ALREADY-ABORTED `TaskSpec.signal`. Refused BEFORE the CAS, so
1975
+ /** `runner.resume` was handed an ALREADY-ABORTED `TaskSpec.signal`. Refused BEFORE the CAS, so
2001
1976
  * the checkpoint stays `pending` — this worker demonstrably cannot execute the approved action, and
2002
1977
  * consuming the human's decision on a leg that will abort immediately loses BOTH the decision and the
2003
1978
  * suspended work with nothing to reopen. Re-resume with a live signal. */
@@ -2011,7 +1986,7 @@ export declare class CheckpointError extends Error {
2011
1986
  * Rejected pre-CAS so the checkpoint stays `pending` and a capable worker can still resume it
2012
1987
  * (design/49 §2/§3, code-ready council round-2). */
2013
1988
  | "checkpoint.unsupported_version"
2014
- /** backlog #243: `resume`/`resumeStream` was handed `internals.requestedCwd` for a checkpoint that
1989
+ /** `resume`/`resumeStream` was handed `internals.requestedCwd` for a checkpoint that
2015
1990
  * carries a remote `workspaceHandle`. The restored workspace's mountPath is authoritative for the
2016
1991
  * task root, so the cwd would be ignored at best — and verifying it would touch the env BEFORE the
2017
1992
  * VM restore (a lazy-connect adapter then connects a fresh empty sandbox, the design/49 disease).
@@ -2074,7 +2049,7 @@ export declare class CheckpointError extends Error {
2074
2049
  * the checkpoint through its own decide entry instead (the error message names it). */
2075
2050
  | "wake.gate_pending"
2076
2051
  /** design/144 §3 (anti spin-wake): a `wake` outcome carried no `message` and the checkpoint has no
2077
- * parked `pendingSteer` either — there is nothing to deliver, so the wake is rejected pre-CAS
2052
+ * parked steer either — there is nothing to deliver, so the wake is rejected pre-CAS
2078
2053
  * (the checkpoint stays pending) instead of burning the token on an empty continuation. */
2079
2054
  | "wake.nothing_to_deliver"
2080
2055
  /** Parent effective-policy inheritance: the checkpoint records `state.inheritedGate.requiresParentConstraint`
@@ -2114,7 +2089,7 @@ export declare class CheckpointError extends Error {
2114
2089
  * the suspend mint. A target-bound env factory keys its placement lookup on that fixed point,
2115
2090
  * so silently resuming under a different one would re-place the leg — and every descendant
2116
2091
  * the child-internals chain hands it to — on another target than the parked workspace lives
2117
- * on. A supplied `rootSessionId` deliberately does NOT take this refusal (rescan C1): it is
2092
+ * on. A supplied `rootSessionId` deliberately does NOT take this refusal: it is
2118
2093
  * delegation identity, re-supplied by every revive leg, and legitimately differs from the
2119
2094
  * recorded root whenever the spawner carried an explicit placement — the recorded root simply
2120
2095
  * outranks it in prepare's restore fold. Rejected PRE-CAS (the checkpoint stays `pending`);
@@ -2176,7 +2151,7 @@ export declare class CheckpointError extends Error {
2176
2151
  * persisted {@link CheckpointGate} `kind` (council #3 — type confusion guard), or a gate v1
2177
2152
  * resume does not serve (`task_done`). */
2178
2153
  | "checkpoint.gate_mismatch"
2179
- /** RB-77: `runner.resume` was handed an ALREADY-ABORTED `TaskSpec.signal`. Refused BEFORE the CAS, so
2154
+ /** `runner.resume` was handed an ALREADY-ABORTED `TaskSpec.signal`. Refused BEFORE the CAS, so
2180
2155
  * the checkpoint stays `pending` — this worker demonstrably cannot execute the approved action, and
2181
2156
  * consuming the human's decision on a leg that will abort immediately loses BOTH the decision and the
2182
2157
  * suspended work with nothing to reopen. Re-resume with a live signal. */
@@ -2190,7 +2165,7 @@ export declare class CheckpointError extends Error {
2190
2165
  * Rejected pre-CAS so the checkpoint stays `pending` and a capable worker can still resume it
2191
2166
  * (design/49 §2/§3, code-ready council round-2). */
2192
2167
  | "checkpoint.unsupported_version"
2193
- /** backlog #243: `resume`/`resumeStream` was handed `internals.requestedCwd` for a checkpoint that
2168
+ /** `resume`/`resumeStream` was handed `internals.requestedCwd` for a checkpoint that
2194
2169
  * carries a remote `workspaceHandle`. The restored workspace's mountPath is authoritative for the
2195
2170
  * task root, so the cwd would be ignored at best — and verifying it would touch the env BEFORE the
2196
2171
  * VM restore (a lazy-connect adapter then connects a fresh empty sandbox, the design/49 disease).
@@ -2253,7 +2228,7 @@ export declare class CheckpointError extends Error {
2253
2228
  * the checkpoint through its own decide entry instead (the error message names it). */
2254
2229
  | "wake.gate_pending"
2255
2230
  /** design/144 §3 (anti spin-wake): a `wake` outcome carried no `message` and the checkpoint has no
2256
- * parked `pendingSteer` either — there is nothing to deliver, so the wake is rejected pre-CAS
2231
+ * parked steer either — there is nothing to deliver, so the wake is rejected pre-CAS
2257
2232
  * (the checkpoint stays pending) instead of burning the token on an empty continuation. */
2258
2233
  | "wake.nothing_to_deliver"
2259
2234
  /** Parent effective-policy inheritance: the checkpoint records `state.inheritedGate.requiresParentConstraint`
@@ -2293,7 +2268,7 @@ export declare class CheckpointError extends Error {
2293
2268
  * the suspend mint. A target-bound env factory keys its placement lookup on that fixed point,
2294
2269
  * so silently resuming under a different one would re-place the leg — and every descendant
2295
2270
  * the child-internals chain hands it to — on another target than the parked workspace lives
2296
- * on. A supplied `rootSessionId` deliberately does NOT take this refusal (rescan C1): it is
2271
+ * on. A supplied `rootSessionId` deliberately does NOT take this refusal: it is
2297
2272
  * delegation identity, re-supplied by every revive leg, and legitimately differs from the
2298
2273
  * recorded root whenever the spawner carried an explicit placement — the recorded root simply
2299
2274
  * outranks it in prepare's restore fold. Rejected PRE-CAS (the checkpoint stays `pending`);
@@ -2627,11 +2602,9 @@ export interface CheckpointStore {
2627
2602
  * {@link PENDING_STEER_QUEUE_BYTE_BUDGET_BYTES} throws `steering.queue_full` — bounded fail-loud, never
2628
2603
  * by evicting an accepted instruction.
2629
2604
  *
2630
- * **Migration (additive read):** a row written before the queue existed keeps its legacy
2631
- * {@link CheckpointState.pendingSteer} seat and is read back as queue member 0 by
2632
- * {@link readPendingSteerQueue}; new writes only ever touch the queue. A backend must round-trip BOTH
2633
- * fields, and must build its new queue with {@link appendPendingSteer} so the bounds and the `seq` mint
2634
- * are one implementation rather than one per store.
2605
+ * A backend must round-trip the queue field verbatim and must build its new queue with
2606
+ * {@link appendPendingSteer} so the bounds and the `seq` mint are one implementation rather than one
2607
+ * per store.
2635
2608
  *
2636
2609
  * **Trust is FROZEN here** — `steer.trusted` is whatever the SERVICE computed from the verified principal
2637
2610
  * at this call (an operator-role check, NOT a client header — the service's job); the core stores it
@@ -2841,17 +2814,16 @@ export declare const MAX_STEER_INPUT_ID_CHARS = 128;
2841
2814
  export declare const ACTOR_ASSERTION_FROZEN_FIELDS: readonly ["id", "hostAsserted", "issuer"];
2842
2815
  /**
2843
2816
  * design/171 §5.3 — THE single read point for a checkpoint's parked steers, in delivery (`seq`) order.
2817
+ * Every consumer — the resume drain, the wake's nothing-to-deliver guard, a serving layer — goes through
2818
+ * here, so no site can grow its own idea of what "the parked steer" is.
2844
2819
  *
2845
- * Additive read: a row written before the queue existed carries its steer in the legacy
2846
- * {@link CheckpointState.pendingSteer} seat, and it is folded in as the FIRST member (it was parked
2847
- * before anything in the queue could have been). Every consumer the resume drain, the wake's
2848
- * nothing-to-deliver guard, a serving layer goes through here, so no site can grow its own idea of
2849
- * what "the parked steer" is.
2820
+ * A row that still carries the RETIRED pre-queue single seat (`state.pendingSteer`, written before the
2821
+ * queue existed) is refused here rather than read: the seat has no `inputId`, `seq` or actor, so folding
2822
+ * it in would mint a synthetic identity nothing else can name. The refusal is `checkpoint.unsupported_version`
2823
+ * with `reason: "seat_retired"`terminal for the row's bytes; the host decides the parked instruction
2824
+ * on its own surface and parks it again through `setPendingSteer` if it still applies.
2850
2825
  */
2851
- export declare function readPendingSteerQueue(state: Pick<CheckpointState, "pendingSteer" | "pendingSteerQueue">): PendingSteerEntry[];
2852
- /** design/171 §5.3 — the synthetic `inputId` a pre-queue single-seat steer reads back as. Stable (never
2853
- * minted per read) so dedupe and re-reads behave, and reserved so a caller cannot collide with it. */
2854
- export declare const LEGACY_PENDING_STEER_INPUT_ID = "legacy-single-seat";
2826
+ export declare function readPendingSteerQueue(state: Pick<CheckpointState, "pendingSteerQueue">): PendingSteerEntry[];
2855
2827
  /**
2856
2828
  * design/171 §5.3/§6.3 — THE append, shared by every backend so the bounds and the ordering are one
2857
2829
  * implementation rather than one per store.
@@ -2860,7 +2832,7 @@ export declare const LEGACY_PENDING_STEER_INPUT_ID = "legacy-single-seat";
2860
2832
  * be crossed. Re-appending an entry whose `inputId` is already queued is a NO-OP returning the queue
2861
2833
  * unchanged — that is what keeps `setPendingSteer` retry-safe now that it appends instead of overwriting.
2862
2834
  */
2863
- export declare function appendPendingSteer(state: Pick<CheckpointState, "pendingSteer" | "pendingSteerQueue">, entry: Omit<PendingSteerEntry, "seq">): PendingSteerEntry[];
2835
+ export declare function appendPendingSteer(state: Pick<CheckpointState, "pendingSteerQueue">, entry: Omit<PendingSteerEntry, "seq">): PendingSteerEntry[];
2864
2836
  /**
2865
2837
  * REF-A4 — THE row half of every guarded checkpoint transition's CAS predicate, shared by every backend:
2866
2838
  * the row must EXIST, its `scope` must match (multi-tenant isolation, §2.1 — a wrong-scope caller never
@@ -453,9 +453,6 @@ export function validatePendingSteer(steer) {
453
453
  if (inputId !== undefined && (inputId === "" || inputId.length > MAX_STEER_INPUT_ID_CHARS)) {
454
454
  throw new CheckpointError("steering.invalid_content", `steering inputId must be a non-empty string of at most ${MAX_STEER_INPUT_ID_CHARS} characters`);
455
455
  }
456
- if (inputId === LEGACY_PENDING_STEER_INPUT_ID) {
457
- throw new CheckpointError("steering.invalid_content", `steering inputId "${LEGACY_PENDING_STEER_INPUT_ID}" is reserved for a pre-queue parked steer and cannot be supplied by a caller`);
458
- }
459
456
  if (sanitizeUntrustedText(text) !== text) {
460
457
  throw new CheckpointError("steering.invalid_content", "steering text must not contain a system-reminder break-out tag");
461
458
  }
@@ -512,14 +509,11 @@ function captureActorAssertion(actor) {
512
509
  return { id, hostAsserted, ...(issuer !== undefined ? { issuer } : {}) };
513
510
  }
514
511
  export function readPendingSteerQueue(state) {
515
- const legacy = state.pendingSteer === undefined
516
- ? []
517
- :
518
- [{ text: state.pendingSteer.text, trusted: state.pendingSteer.trusted, seq: 0, inputId: LEGACY_PENDING_STEER_INPUT_ID }];
519
- const queued = [...(state.pendingSteerQueue ?? [])].sort((a, b) => a.seq - b.seq);
520
- return [...legacy, ...queued];
521
- }
522
- export const LEGACY_PENDING_STEER_INPUT_ID = "legacy-single-seat";
512
+ if (state.pendingSteer !== undefined) {
513
+ throw new CheckpointError("checkpoint.unsupported_version", "this checkpoint carries a parked steer in the retired pre-queue single seat (`state.pendingSteer`), which this engine does not read — decide the parked instruction on the host's surface and, if it still applies, park it again with setPendingSteer", { reason: "seat_retired" });
514
+ }
515
+ return [...(state.pendingSteerQueue ?? [])].sort((a, b) => a.seq - b.seq);
516
+ }
523
517
  function samePendingSteerPayload(a, b) {
524
518
  return (a.text === b.text &&
525
519
  a.trusted === b.trusted &&
@@ -530,23 +524,22 @@ function samePendingSteerPayload(a, b) {
530
524
  }
531
525
  export function appendPendingSteer(state, entry) {
532
526
  const current = readPendingSteerQueue(state);
533
- const existingQueue = [...(state.pendingSteerQueue ?? [])].sort((a, b) => a.seq - b.seq);
534
527
  const collision = current.find((e) => e.inputId === entry.inputId);
535
528
  if (collision !== undefined) {
536
529
  if (!samePendingSteerPayload(collision, entry)) {
537
530
  throw new CheckpointError("steering.duplicate_input_id", `a different steering instruction is already parked under inputId "${entry.inputId}" — ` +
538
531
  `re-issue this one with a fresh inputId (an identical payload would have been an idempotent retry)`);
539
532
  }
540
- return existingQueue;
533
+ return current;
541
534
  }
542
535
  const nextSeq = current.reduce((max, e) => Math.max(max, e.seq), 0) + 1;
543
- const next = [...existingQueue, { ...entry, seq: nextSeq }];
544
- const totalEntries = next.length + (state.pendingSteer === undefined ? 0 : 1);
536
+ const next = [...current, { ...entry, seq: nextSeq }];
537
+ const totalEntries = next.length;
545
538
  if (totalEntries > MAX_PENDING_STEER_ENTRIES) {
546
539
  throw new CheckpointError("steering.queue_full", `the parked steering queue already holds ${totalEntries - 1} entries (max ${MAX_PENDING_STEER_ENTRIES}) — ` +
547
540
  `deliver or remove a parked steer before adding another`);
548
541
  }
549
- const bytes = Buffer.byteLength(JSON.stringify({ pendingSteer: state.pendingSteer, pendingSteerQueue: next }), "utf8");
542
+ const bytes = Buffer.byteLength(JSON.stringify({ pendingSteerQueue: next }), "utf8");
550
543
  if (bytes > PENDING_STEER_QUEUE_BYTE_BUDGET_BYTES) {
551
544
  throw new CheckpointError("steering.queue_full", `the parked steering queue would serialize to ${bytes} bytes (max ${PENDING_STEER_QUEUE_BYTE_BUDGET_BYTES}) — ` +
552
545
  `deliver or remove a parked steer before adding another`);