@sema-agent/core 7.55.0 → 7.56.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 (418) hide show
  1. package/CHANGELOG.md +513 -0
  2. package/dist/agents/cascade.js +1 -1
  3. package/dist/agents/cc-peer-directory.js +1 -0
  4. package/dist/agents/child-model-seat.d.ts +0 -11
  5. package/dist/agents/child-model-seat.js +0 -3
  6. package/dist/agents/list-agents-tool.d.ts +3 -1
  7. package/dist/agents/list-agents-tool.js +7 -7
  8. package/dist/agents/peer-directory.d.ts +22 -4
  9. package/dist/agents/peer-directory.js +24 -2
  10. package/dist/agents/peer-session-drain.js +2 -2
  11. package/dist/agents/repair-loop.js +2 -2
  12. package/dist/agents/send-message-tool.js +4 -4
  13. package/dist/agents/subagent.d.ts +6 -4
  14. package/dist/agents/subagent.js +64 -60
  15. package/dist/agents/tool-filter.d.ts +7 -5
  16. package/dist/agents/tool-filter.js +12 -9
  17. package/dist/agents/verify.d.ts +3 -2
  18. package/dist/agents/verify.js +3 -3
  19. package/dist/brain/anthropic.js +30 -73
  20. package/dist/brain/media-degrade.d.ts +18 -7
  21. package/dist/brain/media-degrade.js +13 -2
  22. package/dist/brain/model-capability.d.ts +37 -0
  23. package/dist/brain/model-capability.js +34 -0
  24. package/dist/brain/model-presets.d.ts +2 -8
  25. package/dist/brain/model-presets.js +1 -6
  26. package/dist/brain/open-responses.js +13 -26
  27. package/dist/brain/openai.js +14 -87
  28. package/dist/brain/reasoning-request.d.ts +96 -0
  29. package/dist/brain/reasoning-request.js +174 -0
  30. package/dist/brain/reasoning.d.ts +11 -11
  31. package/dist/brain/reasoning.js +4 -3
  32. package/dist/brain/request-params.d.ts +7 -4
  33. package/dist/brain/request-params.js +7 -4
  34. package/dist/brain/status-sink.d.ts +20 -0
  35. package/dist/brain/status-sink.js +7 -0
  36. package/dist/core/a2a.d.ts +2 -1
  37. package/dist/core/a2a.js +19 -13
  38. package/dist/core/agent-definition.d.ts +10 -0
  39. package/dist/core/allow-entry.d.ts +20 -13
  40. package/dist/core/allow-entry.js +26 -22
  41. package/dist/core/allow-rule-shadow.d.ts +3 -3
  42. package/dist/core/ask-origin.d.ts +64 -18
  43. package/dist/core/ask-origin.js +63 -23
  44. package/dist/core/ask-question.d.ts +51 -8
  45. package/dist/core/ask-question.js +3 -4
  46. package/dist/core/ask-unresolvable-notice.d.ts +8 -3
  47. package/dist/core/ask-unresolvable-notice.js +16 -2
  48. package/dist/core/checkpoint-generation.d.ts +53 -0
  49. package/dist/core/checkpoint-generation.js +35 -0
  50. package/dist/core/checkpoint-queries.d.ts +180 -0
  51. package/dist/core/checkpoint-queries.js +272 -0
  52. package/dist/core/checkpoint-requirements.d.ts +13 -1
  53. package/dist/core/checkpoint-requirements.js +4 -0
  54. package/dist/core/checkpoint-store.d.ts +88 -24
  55. package/dist/core/checkpoint-store.js +24 -9
  56. package/dist/core/cross-boundary-taint.d.ts +6 -5
  57. package/dist/core/cross-boundary-taint.js +1 -3
  58. package/dist/core/decision-receipt.d.ts +37 -3
  59. package/dist/core/decision-receipt.js +17 -17
  60. package/dist/core/delegation-not-started.d.ts +6 -0
  61. package/dist/core/delegation-not-started.js +17 -0
  62. package/dist/core/engine-attestation.d.ts +93 -0
  63. package/dist/core/engine-attestation.js +70 -0
  64. package/dist/core/engine-capabilities.d.ts +4 -1
  65. package/dist/core/engine-capabilities.js +1 -1
  66. package/dist/core/engine-notice.d.ts +30 -11
  67. package/dist/core/file-history-store.d.ts +90 -14
  68. package/dist/core/file-history-store.js +23 -15
  69. package/dist/core/gate-fold.d.ts +1 -1
  70. package/dist/core/gate-fold.js +22 -10
  71. package/dist/core/gate-lanes.js +73 -64
  72. package/dist/core/gate-outcome.d.ts +26 -5
  73. package/dist/core/gate-outcome.js +26 -0
  74. package/dist/core/governance-codes.d.ts +5 -1
  75. package/dist/core/governance-codes.js +6 -0
  76. package/dist/core/hooks.d.ts +17 -16
  77. package/dist/core/hooks.js +3 -1
  78. package/dist/core/host-floor.d.ts +128 -0
  79. package/dist/core/host-floor.js +206 -0
  80. package/dist/core/host-target.d.ts +38 -3
  81. package/dist/core/host-target.js +38 -5
  82. package/dist/core/mcp.d.ts +5 -1
  83. package/dist/core/mcp.js +67 -41
  84. package/dist/core/memory-engine/delegation-settlement.js +15 -24
  85. package/dist/core/memory-engine/engine.js +4 -4
  86. package/dist/core/memory-engine/layout.d.ts +60 -8
  87. package/dist/core/memory-engine/layout.js +65 -6
  88. package/dist/core/model-seat.d.ts +10 -3
  89. package/dist/core/mods/classic-events.d.ts +67 -0
  90. package/dist/core/mods/classic-events.js +1 -0
  91. package/dist/core/mods/dollar.d.ts +13 -0
  92. package/dist/core/mods/extension-call.d.ts +31 -0
  93. package/dist/core/mods/extension-call.js +43 -0
  94. package/dist/core/mods/kernel/dispatch.d.ts +20 -3
  95. package/dist/core/mods/kernel/dispatch.js +140 -69
  96. package/dist/core/mods/kernel/events.d.ts +47 -11
  97. package/dist/core/mods/kernel/events.js +66 -42
  98. package/dist/core/mods/kernel/index.d.ts +4 -4
  99. package/dist/core/mods/kernel/index.js +2 -2
  100. package/dist/core/mods/kernel/receive.d.ts +39 -5
  101. package/dist/core/mods/kernel/receive.js +290 -17
  102. package/dist/core/mods/kernel/registration.d.ts +33 -2
  103. package/dist/core/mods/kernel/registration.js +6 -7
  104. package/dist/core/mods/kernel/site-rules.d.ts +44 -16
  105. package/dist/core/mods/kernel/site-rules.js +24 -42
  106. package/dist/core/mods/spec-seats.d.ts +69 -0
  107. package/dist/core/mods/spec-seats.js +114 -0
  108. package/dist/core/mods/stations.d.ts +28 -8
  109. package/dist/core/mods/stations.js +29 -13
  110. package/dist/core/mods/tool-call.d.ts +79 -0
  111. package/dist/core/mods/tool-call.js +152 -0
  112. package/dist/core/namespaced-rule-name.d.ts +32 -38
  113. package/dist/core/namespaced-rule-name.js +29 -36
  114. package/dist/core/parent-spec-seat.d.ts +6 -1
  115. package/dist/core/parent-spec-seat.js +2 -0
  116. package/dist/core/park-selfcheck.js +1 -0
  117. package/dist/core/permission-rule-consent.d.ts +19 -0
  118. package/dist/core/permission-rule-consent.js +116 -26
  119. package/dist/core/permission-rule-model.d.ts +14 -3
  120. package/dist/core/permission-rule-model.js +39 -24
  121. package/dist/core/permission-rule-org.d.ts +6 -2
  122. package/dist/core/permission-rule-org.js +7 -3
  123. package/dist/core/permission-rule-provider.d.ts +5 -2
  124. package/dist/core/permission-rule-provider.js +41 -11
  125. package/dist/core/permission-rule-store.d.ts +3 -2
  126. package/dist/core/permission-rule-store.js +11 -2
  127. package/dist/core/permission-rule-sync.js +3 -2
  128. package/dist/core/permission-rule-syntax.d.ts +5 -4
  129. package/dist/core/permission-rule-syntax.js +2 -2
  130. package/dist/core/permission-rules.d.ts +4 -4
  131. package/dist/core/permission-rules.js +11 -20
  132. package/dist/core/persisted-rule-arms.d.ts +2 -2
  133. package/dist/core/persisted-rule-arms.js +10 -12
  134. package/dist/core/principal-name.d.ts +20 -0
  135. package/dist/core/principal-name.js +22 -0
  136. package/dist/core/prompt-section-seat.js +4 -6
  137. package/dist/core/protocol-http-auth.d.ts +26 -5
  138. package/dist/core/protocol-http-auth.js +137 -4
  139. package/dist/core/retired-keys.d.ts +16 -0
  140. package/dist/core/retired-keys.js +16 -4
  141. package/dist/core/rewrite-rejudge.d.ts +60 -0
  142. package/dist/core/rewrite-rejudge.js +36 -0
  143. package/dist/core/roles.d.ts +28 -1
  144. package/dist/core/roles.js +31 -19
  145. package/dist/core/rule-lane-reads.d.ts +20 -15
  146. package/dist/core/rule-lane-reads.js +45 -17
  147. package/dist/core/rule-owner.d.ts +3 -3
  148. package/dist/core/rule-owner.js +3 -2
  149. package/dist/core/runner/announce-once-ledger.d.ts +14 -0
  150. package/dist/core/runner/announce-once-ledger.js +5 -0
  151. package/dist/core/runner/assemble-result.d.ts +1 -0
  152. package/dist/core/runner/assemble-result.js +1 -1
  153. package/dist/core/runner/call-hook-stations.d.ts +3 -2
  154. package/dist/core/runner/caller-roster.d.ts +16 -4
  155. package/dist/core/runner/caller-roster.js +33 -6
  156. package/dist/core/runner/capability-withheld-seat.d.ts +5 -0
  157. package/dist/core/runner/capability-withheld-seat.js +24 -0
  158. package/dist/core/runner/classifier-ladder.d.ts +7 -9
  159. package/dist/core/runner/classifier-ladder.js +3 -3
  160. package/dist/core/runner/construction-doors.js +3 -0
  161. package/dist/core/runner/contracts.d.ts +28 -25
  162. package/dist/core/runner/cross-boundary-lane.d.ts +17 -13
  163. package/dist/core/runner/cross-boundary-lane.js +40 -27
  164. package/dist/core/runner/denial-limit-arms.d.ts +2 -2
  165. package/dist/core/runner/denial-limit-arms.js +1 -1
  166. package/dist/core/runner/file-history-request.d.ts +18 -0
  167. package/dist/core/runner/file-history-request.js +21 -13
  168. package/dist/core/runner/file-history-restore.d.ts +45 -0
  169. package/dist/core/runner/file-history-restore.js +46 -0
  170. package/dist/core/runner/gate-exit.d.ts +3 -3
  171. package/dist/core/runner/gate-exit.js +4 -3
  172. package/dist/core/runner/image.d.ts +7 -17
  173. package/dist/core/runner/image.js +9 -60
  174. package/dist/core/runner/permission-rule-lanes.d.ts +4 -4
  175. package/dist/core/runner/permission-rule-lanes.js +26 -10
  176. package/dist/core/runner/person-path-rows.d.ts +12 -9
  177. package/dist/core/runner/person-path-rows.js +18 -7
  178. package/dist/core/runner/prepare-ask-lane.d.ts +2 -2
  179. package/dist/core/runner/prepare-ask-lane.js +5 -2
  180. package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -6
  181. package/dist/core/runner/prepare-caps-and-workflow.js +4 -3
  182. package/dist/core/runner/prepare-config-doors.d.ts +29 -38
  183. package/dist/core/runner/prepare-config-doors.js +42 -25
  184. package/dist/core/runner/prepare-defer-classify.d.ts +4 -3
  185. package/dist/core/runner/prepare-defer-classify.js +7 -8
  186. package/dist/core/runner/prepare-file-history.d.ts +48 -8
  187. package/dist/core/runner/prepare-file-history.js +7 -39
  188. package/dist/core/runner/prepare-gate-stations.d.ts +1 -1
  189. package/dist/core/runner/prepare-gate-stations.js +10 -1
  190. package/dist/core/runner/prepare-hands-readface.d.ts +2 -8
  191. package/dist/core/runner/prepare-hands-readface.js +15 -14
  192. package/dist/core/runner/prepare-inherited-gate.d.ts +6 -3
  193. package/dist/core/runner/prepare-inherited-gate.js +5 -3
  194. package/dist/core/runner/prepare-memory-engine-session.js +1 -1
  195. package/dist/core/runner/prepare-park-ask.js +5 -5
  196. package/dist/core/runner/prepare-policy-chain.d.ts +6 -3
  197. package/dist/core/runner/prepare-policy-chain.js +65 -72
  198. package/dist/core/runner/prepare-prompt-assembly.d.ts +5 -7
  199. package/dist/core/runner/prepare-prompt-assembly.js +10 -8
  200. package/dist/core/runner/prepare-prompt-inputs.d.ts +11 -9
  201. package/dist/core/runner/prepare-prompt-inputs.js +3 -5
  202. package/dist/core/runner/prepare-protocol-tools.d.ts +2 -0
  203. package/dist/core/runner/prepare-protocol-tools.js +3 -3
  204. package/dist/core/runner/prepare-safety-scan.d.ts +1 -1
  205. package/dist/core/runner/prepare-safety-scan.js +0 -17
  206. package/dist/core/runner/prepare-suspend-saga.d.ts +2 -0
  207. package/dist/core/runner/prepare-suspend-saga.js +5 -6
  208. package/dist/core/runner/prepare-task.d.ts +1 -1
  209. package/dist/core/runner/prepare-task.js +29 -20
  210. package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +7 -4
  211. package/dist/core/runner/prepare-tool-disclosure-mount.js +20 -16
  212. package/dist/core/runner/prepare-turn-wiring.d.ts +0 -4
  213. package/dist/core/runner/prepare-turn-wiring.js +2 -7
  214. package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -2
  215. package/dist/core/runner/prepare-wiring-manifest.js +3 -3
  216. package/dist/core/runner/resume-admission.js +1 -1
  217. package/dist/core/runner/resume-apply.js +11 -12
  218. package/dist/core/runner/resume-checkpoint-screen.js +3 -0
  219. package/dist/core/runner/resume-claim.d.ts +4 -2
  220. package/dist/core/runner/resume-claim.js +15 -8
  221. package/dist/core/runner/retired-runner-deps.js +1 -0
  222. package/dist/core/runner/rewind-files.d.ts +15 -0
  223. package/dist/core/runner/rewind-files.js +132 -0
  224. package/dist/core/runner/run-attachment-seats.js +2 -1
  225. package/dist/core/runner/run-brain-sinks.d.ts +4 -1
  226. package/dist/core/runner/run-brain-sinks.js +4 -2
  227. package/dist/core/runner/run-harness-handlers.js +12 -4
  228. package/dist/core/runner/run-leg.d.ts +1 -1
  229. package/dist/core/runner/run-leg.js +30 -18
  230. package/dist/core/runner/run-settle-and-teardown.js +2 -1
  231. package/dist/core/runner/run-turn-boundary.js +1 -10
  232. package/dist/core/runner/runtask.d.ts +3 -0
  233. package/dist/core/runner/runtask.js +8 -9
  234. package/dist/core/runner/session-read-file-states.d.ts +15 -0
  235. package/dist/core/runner/session-read-file-states.js +28 -0
  236. package/dist/core/runner/session-rule-policy.js +4 -3
  237. package/dist/core/runner/shell-env-withheld.d.ts +33 -0
  238. package/dist/core/runner/shell-env-withheld.js +51 -0
  239. package/dist/core/runner/skills-seat.js +6 -2
  240. package/dist/core/runner/stream-settle-backstop.js +1 -1
  241. package/dist/core/runner/sub-agent-deny-lists.js +4 -7
  242. package/dist/core/runner/synthetic-tools.d.ts +6 -0
  243. package/dist/core/runner/synthetic-tools.js +4 -1
  244. package/dist/core/runner/tool-disclosure.d.ts +10 -12
  245. package/dist/core/runner/tool-disclosure.js +1 -3
  246. package/dist/core/runner/tool-end-body.d.ts +1 -1
  247. package/dist/core/runner/tool-end-body.js +10 -9
  248. package/dist/core/runner/tool-not-executed.d.ts +5 -0
  249. package/dist/core/runner/tool-not-executed.js +11 -0
  250. package/dist/core/runner/tool-occurrence.d.ts +8 -0
  251. package/dist/core/runner/tool-occurrence.js +7 -0
  252. package/dist/core/runner/turn-attachments.d.ts +33 -15
  253. package/dist/core/runner/turn-attachments.js +62 -37
  254. package/dist/core/runner-deps.d.ts +5 -5
  255. package/dist/core/safety-axis-vocab.d.ts +6 -4
  256. package/dist/core/safety-axis-vocab.js +6 -5
  257. package/dist/core/safety-merge-corpus.js +11 -3
  258. package/dist/core/secret-env.d.ts +26 -3
  259. package/dist/core/secret-env.js +44 -8
  260. package/dist/core/select-model.js +3 -3
  261. package/dist/core/session-policy-store.d.ts +27 -15
  262. package/dist/core/session-policy-store.js +156 -36
  263. package/dist/core/session-store.d.ts +29 -10
  264. package/dist/core/session-store.js +51 -19
  265. package/dist/core/session.d.ts +82 -16
  266. package/dist/core/session.js +53 -0
  267. package/dist/core/shell-read-silence.d.ts +11 -12
  268. package/dist/core/shell-read-silence.js +9 -5
  269. package/dist/core/shell-run-candidates.js +3 -1
  270. package/dist/core/shell-wrapper-projection.js +1 -1
  271. package/dist/core/shell-wrapper-table.d.ts +14 -7
  272. package/dist/core/shell-wrapper-table.js +5 -4
  273. package/dist/core/side-query.js +10 -1
  274. package/dist/core/skill-grant.d.ts +7 -2
  275. package/dist/core/skill-grant.js +5 -0
  276. package/dist/core/skills-directory.js +6 -2
  277. package/dist/core/store-contracts/checkpoint-store-contract.d.ts +11 -1
  278. package/dist/core/store-contracts/checkpoint-store-contract.js +140 -2
  279. package/dist/core/store-contracts/file-history-store-contract.js +31 -1
  280. package/dist/core/store-contracts/peer-directory-contract.d.ts +7 -2
  281. package/dist/core/store-contracts/peer-directory-contract.js +14 -2
  282. package/dist/core/store-contracts/session-repo-contract.js +51 -0
  283. package/dist/core/store-contracts/session-store-contract.d.ts +2 -1
  284. package/dist/core/store-contracts/session-store-contract.js +150 -14
  285. package/dist/core/stub-env.d.ts +2 -0
  286. package/dist/core/stub-env.js +1 -0
  287. package/dist/core/synthetic-read-verdict.js +3 -3
  288. package/dist/core/task-event.d.ts +32 -4
  289. package/dist/core/task-notification.d.ts +16 -12
  290. package/dist/core/task-registry.d.ts +9 -0
  291. package/dist/core/task-registry.js +11 -1
  292. package/dist/core/task-result.d.ts +18 -0
  293. package/dist/core/task-spec.d.ts +18 -13
  294. package/dist/core/tighten-task-spec.js +2 -1
  295. package/dist/core/tool-catalog-entries.d.ts +17 -0
  296. package/dist/core/tool-catalog-entries.js +13 -2
  297. package/dist/core/tool-check-reading.d.ts +11 -0
  298. package/dist/core/tool-check-reading.js +11 -6
  299. package/dist/core/tool-model-gate.d.ts +2 -2
  300. package/dist/core/tool-name-aliases.d.ts +16 -16
  301. package/dist/core/tool-name-aliases.js +13 -19
  302. package/dist/core/tool-name-readings.d.ts +5 -35
  303. package/dist/core/tool-name-readings.js +1 -9
  304. package/dist/core/tool-policy.d.ts +68 -198
  305. package/dist/core/tool-policy.js +149 -198
  306. package/dist/core/tool-result-store.js +3 -0
  307. package/dist/core/tool-roster.d.ts +14 -19
  308. package/dist/core/tool-roster.js +11 -44
  309. package/dist/core/tool-spec-members.js +7 -2
  310. package/dist/core/tool-spec.d.ts +19 -11
  311. package/dist/core/tools.js +49 -9
  312. package/dist/core/trace.d.ts +2 -2
  313. package/dist/core/types.d.ts +1 -1
  314. package/dist/core/user-attachment.d.ts +8 -1
  315. package/dist/core/user-attachment.js +64 -4
  316. package/dist/core/wiring-manifest.d.ts +9 -0
  317. package/dist/core/wiring-manifest.js +1 -0
  318. package/dist/core/workflow-journal-store.js +1 -1
  319. package/dist/engine/compaction/compaction.js +3 -2
  320. package/dist/engine/execution-env/node-execution-env.d.ts +7 -3
  321. package/dist/engine/execution-env/node-execution-env.js +11 -2
  322. package/dist/engine/harness/agent-harness.d.ts +25 -1
  323. package/dist/engine/harness/agent-harness.js +54 -7
  324. package/dist/engine/harness/types.d.ts +29 -2
  325. package/dist/engine/llm/types.d.ts +28 -11
  326. package/dist/engine/loop/agent-loop.d.ts +22 -0
  327. package/dist/engine/loop/agent-loop.js +16 -26
  328. package/dist/engine/loop/types.d.ts +16 -6
  329. package/dist/engine/session/memory-repo.d.ts +9 -2
  330. package/dist/engine/session/memory-repo.js +11 -1
  331. package/dist/engine/session/repo-utils.d.ts +6 -5
  332. package/dist/engine/session/repo-utils.js +14 -6
  333. package/dist/index.d.ts +22 -10
  334. package/dist/index.js +15 -7
  335. package/dist/internal/harness-types.d.ts +1 -1
  336. package/dist/internal/llm.d.ts +1 -1
  337. package/dist/orchestration/run-workflow-tool.d.ts +6 -4
  338. package/dist/orchestration/run-workflow-tool.js +5 -3
  339. package/dist/orchestration/workflow.d.ts +3 -0
  340. package/dist/orchestration/workflow.js +36 -18
  341. package/dist/prompt-assembly/artifact.d.ts +2 -2
  342. package/dist/prompt-assembly/artifact.js +5 -3
  343. package/dist/prompt-assembly/assemble.d.ts +3 -2
  344. package/dist/prompt-assembly/assemble.js +1 -1
  345. package/dist/prompt-assembly/catalog/schema.d.ts +43 -12
  346. package/dist/prompt-assembly/catalog/schema.js +34 -2
  347. package/dist/prompt-assembly/catalog/sections.js +0 -1
  348. package/dist/prompt-assembly/composer.d.ts +3 -1
  349. package/dist/prompt-assembly/composer.js +1 -1
  350. package/dist/prompt-assembly/event-registry.js +1 -0
  351. package/dist/prompt-assembly/overlay.js +3 -3
  352. package/dist/prompt-assembly/renderers.d.ts +1 -1
  353. package/dist/prompt-assembly/renderers.js +0 -3
  354. package/dist/prompt-assembly/role-base.d.ts +15 -0
  355. package/dist/prompt-assembly/role-base.js +9 -0
  356. package/dist/prompt-assembly/select.d.ts +39 -14
  357. package/dist/prompt-assembly/select.js +47 -16
  358. package/dist/prompt-assembly/sugar.d.ts +17 -11
  359. package/dist/prompt-assembly/sugar.js +8 -3
  360. package/dist/prompt-assembly/tool-catalog.d.ts +37 -3
  361. package/dist/prompt-assembly/tool-catalog.js +114 -4
  362. package/dist/prompt-assembly/turn-snapshot.d.ts +4 -10
  363. package/dist/prompt-assembly/turn-snapshot.js +0 -3
  364. package/dist/prompt-assembly/types.d.ts +0 -7
  365. package/dist/scenarios/full-body.d.ts +11 -11
  366. package/dist/scenarios/full-body.js +4 -3
  367. package/dist/shell/lex.js +10 -1
  368. package/dist/stores/file/adoption/adopt.js +4 -3
  369. package/dist/stores/file/adoption/marker.js +3 -2
  370. package/dist/stores/file/checkpoint-store.d.ts +21 -0
  371. package/dist/stores/file/checkpoint-store.js +38 -6
  372. package/dist/stores/file/file-history-store.js +6 -7
  373. package/dist/stores/file/index.js +2 -1
  374. package/dist/stores/file/permission-rule-adopt.js +4 -3
  375. package/dist/stores/file/permission-rule-store.js +11 -5
  376. package/dist/stores/file/session-store.d.ts +29 -6
  377. package/dist/stores/file/session-store.js +42 -50
  378. package/dist/tools/artifact/artifact-tool.js +3 -2
  379. package/dist/tools/fs/bash-program-position.d.ts +19 -2
  380. package/dist/tools/fs/bash-program-position.js +56 -9
  381. package/dist/tools/fs/fs-bash.js +5 -5
  382. package/dist/tools/fs/fs-glob.d.ts +86 -0
  383. package/dist/tools/fs/fs-glob.js +226 -0
  384. package/dist/tools/fs/fs-read.js +14 -14
  385. package/dist/tools/fs/fs-search-tools.js +7 -7
  386. package/dist/tools/fs/pattern-kill-guard.d.ts +22 -0
  387. package/dist/tools/fs/pattern-kill-guard.js +397 -0
  388. package/dist/tools/fs/pdf.d.ts +9 -6
  389. package/dist/tools/fs/pdf.js +3 -3
  390. package/dist/tools/fs/program-read-model.d.ts +57 -7
  391. package/dist/tools/fs/program-read-model.js +11 -1
  392. package/dist/tools/fs/program-read-model.rows.js +78 -21
  393. package/dist/tools/fs/read-deny-home.js +3 -2
  394. package/dist/tools/fs/removal-targets.d.ts +17 -7
  395. package/dist/tools/fs/removal-targets.js +47 -20
  396. package/dist/tools/fs/search.d.ts +10 -0
  397. package/dist/tools/fs/search.js +20 -26
  398. package/dist/tools/fs/shell-read-argv.js +89 -12
  399. package/dist/tools/fs/shell-read-bindings.d.ts +31 -0
  400. package/dist/tools/fs/shell-read-bindings.js +41 -0
  401. package/dist/tools/fs/shell-read-check.js +6 -19
  402. package/dist/tools/fs/shell-read-environment.d.ts +5 -1
  403. package/dist/tools/fs/shell-read-environment.js +3 -2
  404. package/dist/tools/fs/shell-read-establish.d.ts +15 -0
  405. package/dist/tools/fs/shell-read-establish.js +19 -20
  406. package/dist/tools/fs/shell-read-plan.js +24 -16
  407. package/dist/tools/fs/shell-read-start.d.ts +6 -1
  408. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -1
  409. package/dist/tools/fs/shell-read-write-targets.js +2 -3
  410. package/dist/tools/fs/shell-reentry-text.d.ts +9 -0
  411. package/dist/tools/fs/shell-reentry-text.js +40 -2
  412. package/dist/tools/todo.js +63 -63
  413. package/dist/tools/web.d.ts +19 -14
  414. package/dist/tools/web.js +38 -55
  415. package/package.json +1 -1
  416. package/test/export-surface.snapshot.json +143 -5
  417. package/wire-changes/core@7.56.0.json +3891 -0
  418. package/wire-changes/mods-kernel@7.56.0.json +303 -0
@@ -3,8 +3,10 @@ import { assertContainmentFaceValue } from "../../tools/fs/index.js";
3
3
  import { MICRO_COMPACT_MACHINES } from "../context-edit.js";
4
4
  import { assertAddOnlySeats } from "../child-clamp-seats.js";
5
5
  import { CROSS_BOUNDARY_POSTURES } from "../cross-boundary-taint.js";
6
+ import { compileHostFloor } from "../host-floor.js";
6
7
  import { assertNoRetiredRunnerDeps } from "./retired-runner-deps.js";
7
8
  import { recordedModeSeed, resolveCheckpointStore } from "../checkpoint-store.js";
9
+ import { assertCheckpointStoreJudgesHolder, assertHolderValue } from "../checkpoint-generation.js";
8
10
  import { asResumeConfigRefusal, refusePermissionModeDoors } from "../mode-policy.js";
9
11
  import { resolveOutputStyleFrame } from "../output-style.js";
10
12
  import { screenUserAttachments } from "../user-attachment.js";
@@ -15,21 +17,24 @@ import { assertAutoConsolidationWirable } from "./memory-consolidation-driver.js
15
17
  import { isModelPriced, malformedPricingField, modelCostToPricing } from "../pricing.js";
16
18
  import { ENTER_AS_IS, preflightLockedConfig } from "../locked-config.js";
17
19
  import { assertRetentionCapability } from "../retention.js";
18
- import { resolveModel, resolveTaskModel, roleModelIfSet } from "../roles.js";
20
+ import { resolveModel, resolveTaskModel, roleModelIfSet, screenRoleMap } from "../roles.js";
19
21
  import { resolveSkillListingBudget } from "../skill-listing-budget.js";
20
22
  import { describeRejectedValue } from "../tool-search-setting.js";
21
23
  import { assertAdvisorModelShape } from "../advisor-verdict.js";
22
- import { applyToolModelGate, assertRestoreGatedToolsValue, modelIdTail } from "../tool-model-gate.js";
24
+ import { applyToolModelGate, assertRestoreGatedToolsValue } from "../tool-model-gate.js";
23
25
  import { resolveUsageWindows } from "../usage-window-store.js";
24
26
  import { deriveAskEffective, resolveAskSeat, resolveQuestionSeam, screenApprovalReach } from "../wiring-manifest.js";
25
- import { resolveHost } from "../../prompt-assembly/select.js";
27
+ import { effectiveTraitsOf, readModelPromptTraits, resolveHost, resolvePromptLean } from "../../prompt-assembly/select.js";
28
+ import { assertNoRetiredKeys, RETIRED_MODEL_KEYS } from "../retired-keys.js";
26
29
  import { resolvePromptBinding } from "../../prompt-assembly/overlay.js";
27
30
  import { assertPeerPresenceValue } from "../../agents/peer-directory.js";
28
31
  import { snapshotDefinitionLists } from "../../agents/tool-filter.js";
29
- import { TOTAL_TOKENS_REMINDER_MODES } from "./turn-attachments.js";
30
- import { rosterFaceOf } from "./caller-roster.js";
32
+ import { mcpUnavailableOn, TOTAL_TOKENS_REMINDER_MODES } from "./turn-attachments.js";
33
+ import { refuseRetiredMember, rosterFaceOf } from "./caller-roster.js";
31
34
  import { assertToolBoundaryLegs } from "../tool-roster.js";
35
+ import { assertToolCardDeclarations } from "../../prompt-assembly/tool-catalog.js";
32
36
  import { refuseRenamedDelegationMounts } from "./sub-agent-deny-lists.js";
37
+ import { readPrincipal } from "../principal-name.js";
33
38
  const TASK_LIMIT_KEY_DICT = {
34
39
  maxTokens: true,
35
40
  maxCostUsd: true,
@@ -54,6 +59,12 @@ export function limitConfigError(code, message) {
54
59
  e.code = code;
55
60
  return e;
56
61
  }
62
+ export function assertPrincipalValue(raw) {
63
+ const reading = readPrincipal(raw);
64
+ if (reading.kind === "invalid") {
65
+ throw limitConfigError("config.invalid_argument", `TaskSpec.principal must be a principal name when present (got ${reading.fault}) — omit the key for a task with no principal; a provided value that names nobody is refused, never read as "no principal".`);
66
+ }
67
+ }
57
68
  export function resolveTaskLimits(limits) {
58
69
  if (limits === undefined)
59
70
  return undefined;
@@ -99,6 +110,7 @@ export function resolveTaskLimits(limits) {
99
110
  export function resolveAttachmentsConfig(attachments) {
100
111
  if (attachments === null || (typeof attachments !== "object" && typeof attachments !== "function"))
101
112
  return attachments;
113
+ mcpUnavailableOn(attachments);
102
114
  const mode = attachments.totalTokensReminderMode;
103
115
  if (mode !== undefined) {
104
116
  const legal = TOTAL_TOKENS_REMINDER_MODES;
@@ -109,15 +121,9 @@ export function resolveAttachmentsConfig(attachments) {
109
121
  }
110
122
  return attachments;
111
123
  }
112
- export function isFableFamilyModelId(id) {
113
- const tail = modelIdTail(id);
114
- return /^claude-fable-\d/.test(tail) || /^claude-mythos-5(?!\d)/.test(tail);
115
- }
116
- export function resolveModelPromptTraits(model, spec, internals) {
117
- return {
118
- promptProfile: spec.promptProfile ?? internals?.promptProfile ?? "simple",
119
- fableMitigations: isFableFamilyModelId(model.id),
120
- };
124
+ export function resolvePromptTraits(model, promptLean) {
125
+ assertNoRetiredKeys(model, RETIRED_MODEL_KEYS, "Model");
126
+ return effectiveTraitsOf(readModelPromptTraits(model), promptLean);
121
127
  }
122
128
  function microCompactConfigError(field, value, legal) {
123
129
  let shown;
@@ -173,8 +179,9 @@ export function assertResumeConfigRecord(config) {
173
179
  }
174
180
  }
175
181
  export function configValueDoors(input, enter = ENTER_AS_IS) {
176
- const { spec, deps, resumeLeg, sessions } = input;
182
+ const { spec, deps, resumeLeg, sessions, holder } = input;
177
183
  enter("deps", () => assertNoRetiredRunnerDeps(deps));
184
+ enter("taskConfig", () => assertPrincipalValue(spec.principal));
178
185
  enter("taskConfig", () => assertPeerPresenceValue(spec.peerPresence));
179
186
  enter("taskConfig", () => assertRestoreGatedToolsValue(spec.restoreGatedTools));
180
187
  const microCompactKnob = enter("deps", () => resolveMicroCompactKnob(deps.microCompact));
@@ -213,7 +220,10 @@ export function configValueDoors(input, enter = ENTER_AS_IS) {
213
220
  : undefined,
214
221
  };
215
222
  const promptHost = enter("taskConfig", () => resolveHost(spec));
223
+ enter("deps", () => screenRoleMap(deps.roles, "RunnerDeps.roles"));
224
+ enter("taskConfig", () => screenRoleMap(spec.roles, "TaskSpec.roles"));
216
225
  const promptBinding = enter("taskConfig", () => resolvePromptBinding(spec));
226
+ const promptLean = enter("taskConfig", () => resolvePromptLean(spec));
217
227
  if (spec.resumeAt !== undefined)
218
228
  enter("taskConfig", () => {
219
229
  if (resumeLeg) {
@@ -236,6 +246,7 @@ export function configValueDoors(input, enter = ENTER_AS_IS) {
236
246
  const memoryProvenance = enter("deps", () => closedWord(deps.memoryProvenance, "RunnerDeps.memoryProvenance", ["off", "carry"], "carry", "config.memory_provenance", "an unevaluable provenance mode is refused loudly, never folded to either mode."));
237
247
  const memoryCapturePolicy = enter("deps", () => closedWord(deps.memoryCapturePolicy, "RunnerDeps.memoryCapturePolicy", ["open", "governed", "capture-required"], "open", "config.memory_capture_policy", "an unevaluable capture posture is refused loudly, never folded to any posture (the fault arms differ per posture, so a guess would pick a polarity nobody configured)."));
238
248
  const crossBoundaryPosture = enter("deps", () => closedWord(deps.crossBoundaryPosture, "RunnerDeps.crossBoundaryPosture", CROSS_BOUNDARY_POSTURES, undefined, "config.cross_boundary_posture", "an unevaluable posture is refused loudly, never folded to either word (an absent seat is undeclared, which is its own fact)."));
249
+ const hostFloor = enter("deps", () => compileHostFloor(deps.hostFloor));
239
250
  const advisorTool = enter("deps", () => closedWord(deps.advisorTool, "RunnerDeps.advisorTool", ["disabled"], undefined, "config.advisor_tool_invalid", "the switch has one word; anything else is refused, never read as either state."));
240
251
  if (advisorTool === undefined)
241
252
  enter("taskConfig", () => assertAdvisorModelShape(spec.advisorModel));
@@ -310,6 +321,8 @@ export function configValueDoors(input, enter = ENTER_AS_IS) {
310
321
  const taskGuardrail = spec.limits?.brainCallGuardrailMs;
311
322
  const brainCallGuardrailMs = enter(taskGuardrail != null ? "taskConfig" : "deps", () => resolveBrainCallGuardrailMs(taskGuardrail ?? deps.brainCallGuardrailMs));
312
323
  const checkpointStore = enter(checkpointStoreSeat(spec), () => resolveCheckpointStore(spec, deps));
324
+ enter("deps", () => assertHolderValue(holder));
325
+ enter(checkpointStoreSeat(spec), () => assertCheckpointStoreJudgesHolder(checkpointStoreSeat(spec) === "taskConfig" ? "TaskSpec.checkpointStore" : "RunnerDeps.checkpointStore", checkpointStore, holder));
313
326
  const taskStore = checkpointStoreSeat(spec) === "taskConfig" ? checkpointStore : undefined;
314
327
  const retention = { policy: deps.retentionPolicy, locked: lockedPreflight.lockedKeys.has("retentionPolicy") };
315
328
  enter("deps", () => assertRetentionCapability({
@@ -322,9 +335,9 @@ export function configValueDoors(input, enter = ENTER_AS_IS) {
322
335
  }));
323
336
  if (taskStore !== undefined)
324
337
  enter("taskConfig", () => assertRetentionCapability({ ...retention, stores: [{ name: "checkpointStore", store: taskStore }] }));
325
- return { toolFaceLists, promptHost, promptBinding, lockedPreflight, skillListingSeats, skills, projectMemory, microCompactKnob, memoryDelegationEvidence, memoryProvenance, memoryCapturePolicy, usageWindows, brainCallGuardrailMs, crossBoundaryPosture, advisorTool };
338
+ return { toolFaceLists, promptHost, promptBinding, promptLean, lockedPreflight, skillListingSeats, skills, projectMemory, microCompactKnob, memoryDelegationEvidence, memoryProvenance, memoryCapturePolicy, usageWindows, brainCallGuardrailMs, crossBoundaryPosture, advisorTool, hostFloor };
326
339
  }
327
- export function refuseResumeDoors(config, recordedGate, deps, sessions) {
340
+ export function refuseResumeDoors(config, recordedGate, deps, sessions, holder) {
328
341
  asResumeConfigRefusal("taskConfig", () => {
329
342
  refusePermissionModeDoors(config);
330
343
  resolveOutputStyleFrame(config.outputStyle);
@@ -332,19 +345,20 @@ export function refuseResumeDoors(config, recordedGate, deps, sessions) {
332
345
  screenUserInvokedSkills(config);
333
346
  screenUserAttachments(config.userAttachments, { resumeLeg: true });
334
347
  assertToolBoundaryLegs(config.tools);
348
+ assertToolCardDeclarations(config.tools);
335
349
  });
336
- const { lockedPreflight, skills } = configValueDoors({ spec: config, deps, resumeLeg: true, sessions }, asResumeConfigRefusal);
350
+ const { lockedPreflight, skills } = configValueDoors({ spec: config, deps, resumeLeg: true, sessions, holder }, asResumeConfigRefusal);
337
351
  asResumeConfigRefusal("inheritedGate", () => void recordedModeSeed(recordedGate));
338
352
  return { ...config, ...(config.mcp !== undefined ? { mcp: lockedPreflight.mcp ?? [] } : {}), ...(config.a2a !== undefined ? { a2a: lockedPreflight.a2a ?? [] } : {}), skills };
339
353
  }
340
354
  export function prepareConfigDoors(input) {
341
355
  const { deps, sessions, resume, internals } = input;
342
356
  assertToolBoundaryLegs(input.spec.tools);
357
+ assertToolCardDeclarations(input.spec.tools);
343
358
  let spec = input.spec;
344
- const { toolFaceLists, promptHost, promptBinding, lockedPreflight, skillListingSeats, skills, projectMemory, microCompactKnob, memoryDelegationEvidence, memoryProvenance, memoryCapturePolicy, usageWindows, brainCallGuardrailMs, crossBoundaryPosture, advisorTool } = configValueDoors({ spec, deps, resumeLeg: resume !== undefined, sessions });
359
+ const { toolFaceLists, promptHost, promptBinding, promptLean, lockedPreflight, skillListingSeats, skills, projectMemory, microCompactKnob, memoryDelegationEvidence, memoryProvenance, memoryCapturePolicy, usageWindows, brainCallGuardrailMs, crossBoundaryPosture, advisorTool, hostFloor } = configValueDoors({ spec, deps, resumeLeg: resume !== undefined, sessions, holder: internals?.holder });
345
360
  const doorRead = (value) => ({ value, enumerable: value !== undefined, writable: false, configurable: false });
346
361
  spec = Object.create(Object.getPrototypeOf(spec), { ...Object.getOwnPropertyDescriptors(spec), skills: doorRead(skills), projectMemory: doorRead(projectMemory) });
347
- const promptProfile = resolveModelPromptTraits({ id: "" }, spec, internals).promptProfile;
348
362
  const resolvedInteractionPosture = spec.interactionPosture ?? internals?.parentInteractionPosture ?? deps.interactionPosture;
349
363
  const askSeat = resolveAskSeat(spec, deps);
350
364
  {
@@ -410,7 +424,10 @@ export function prepareConfigDoors(input) {
410
424
  if (typeof t.withAgents !== "function")
411
425
  return t;
412
426
  const rebuilt = t.withAgents(perTask);
413
- return rosterFaceOf(t.modelGate !== undefined && rebuilt.modelGate === undefined ? { ...rebuilt, modelGate: t.modelGate } : rebuilt, index);
427
+ const restamp = t.modelGate !== undefined && rebuilt.modelGate === undefined;
428
+ if (restamp)
429
+ refuseRetiredMember(rebuilt, index);
430
+ return rosterFaceOf(restamp ? { ...rebuilt, modelGate: t.modelGate } : rebuilt, index);
414
431
  }),
415
432
  };
416
433
  }
@@ -447,7 +464,7 @@ export function prepareConfigDoors(input) {
447
464
  throw limitConfigError("config.limit_invalid", `TaskSpec.${dollarCeiling} is a money ceiling, but the price table for model ${JSON.stringify(model.id)} declares an unevaluable ${bad} — every rate must be a finite, non-negative number of USD per 1M tokens. A table like this prices every turn at zero (or below), so the ceiling would never trip: refused rather than enforced in name only.`);
448
465
  }
449
466
  }
450
- const fableMitigations = resolveModelPromptTraits(model, spec, internals).fableMitigations;
467
+ const promptTraits = resolvePromptTraits(model, promptLean);
451
468
  const gateDecision = applyToolModelGate({
452
469
  tools: spec.tools,
453
470
  modelId: model.id,
@@ -471,7 +488,8 @@ export function prepareConfigDoors(input) {
471
488
  return {
472
489
  spec,
473
490
  toolFaceLists,
474
- promptProfile,
491
+ promptLean,
492
+ promptTraits,
475
493
  promptHost,
476
494
  promptBinding,
477
495
  lockedPreflight,
@@ -482,12 +500,11 @@ export function prepareConfigDoors(input) {
482
500
  model,
483
501
  thinking,
484
502
  compModel,
485
- fableMitigations,
486
503
  modelGate,
487
504
  memoryDelegationEvidence,
488
505
  skillListingBudget,
489
506
  memoryProvenance,
490
- memoryCapturePolicy, crossBoundaryPosture, advisorTool,
507
+ memoryCapturePolicy, crossBoundaryPosture, advisorTool, hostFloor,
491
508
  usageWindows,
492
509
  brainCallGuardrailRef,
493
510
  brainCallGuardrailMs,
@@ -1,4 +1,5 @@
1
1
  import type { Model } from "../../internal/llm.js";
2
+ import type { PromptTraitName } from "../../prompt-assembly/catalog/schema.js";
2
3
  import type { MaterializedA2a } from "../a2a.js";
3
4
  import type { MaterializedMcp } from "../mcp.js";
4
5
  import type { RunnerDeps, TaskSpec } from "../types.js";
@@ -11,7 +12,7 @@ export interface PrepareDeferClassifyInput {
11
12
  deps: Pick<RunnerDeps, "deferMode" | "toolSearch">;
12
13
  /** borrowed-mutable — the shared mount array (later refs alias it; in-place contract, never
13
14
  * re-created). Mutated here, in order: `splice` of every excluded name; element REPLACEMENT with a
14
- * shallow copy for the classic-profile description swap (the caller's ToolSpec object is never
15
+ * shallow copy for a description variant chosen by the run's traits (the caller's ToolSpec object is never
15
16
  * mutated); `splice` of a retracted memory group. After this phase: the content-origin wrap
16
17
  * (element replacement with the wrapped object), the disclosure mount, the MCP refresh re-splice. Since
17
18
  * Every one of those writes is a builder verb (`unmountWhere` / `replaceAt`). */
@@ -22,8 +23,8 @@ export interface PrepareDeferClassifyInput {
22
23
  handsEnabled: boolean;
23
24
  /** borrowed-readonly — the spec-time precomputation the invariant checks the post-exclusion roster against: a mismatch is an engine bug, thrown. */
24
25
  fullShellReachable: boolean;
25
- /** borrowed-readonly — the resolved prompt profile (`classic` swaps in `descriptionClassic`). */
26
- promptProfile: "simple" | "classic";
26
+ /** borrowed-readonly — the run's effective prompt traits (each tool's description variants are chosen on them). */
27
+ promptTraits: ReadonlySet<PromptTraitName>;
27
28
  /** borrowed-readonly — the resolved model (the deferral gate's threshold reads its context window). */
28
29
  model: Model;
29
30
  /** borrowed-readonly — the materialized MCP roster; only `tools` is read (protocol names; `mcpAlwaysLoad` self-declarations lose to an operator defer). */
@@ -1,4 +1,4 @@
1
- import { getToolContract } from "../../prompt-assembly/tool-catalog.js";
1
+ import { getToolContract, mountDescriptionVariant } from "../../prompt-assembly/tool-catalog.js";
2
2
  import { FULL_SHELL_CONTRACT_ID } from "../../tools/fs/index.js";
3
3
  import { ASK_USER_QUESTION_TOOL_NAME } from "../ask-question.js";
4
4
  import { MEMORY_ENGINE_TOOL_NAMES } from "../memory-engine/tools.js";
@@ -17,7 +17,7 @@ function memoryGroupRetractionSet(builtinDeferPairNames, engineTrioInPlay) {
17
17
  return new Set([...builtinDeferPairNames, ...(engineTrioInPlay ? MEMORY_ENGINE_TOOL_NAMES : [])]);
18
18
  }
19
19
  export function prepareDeferClassify(input) {
20
- const { spec, deps, roster, toolFaceSnapshot, handsEnabled, fullShellReachable, promptProfile, model, mcp, a2a, sharedMemoryPairMounted, memoryEnginePairMounted, memoryRecallSegment, onceLedger, sessionId } = input;
20
+ const { spec, deps, roster, toolFaceSnapshot, handsEnabled, fullShellReachable, promptTraits, model, mcp, a2a, sharedMemoryPairMounted, memoryEnginePairMounted, memoryRecallSegment, onceLedger, sessionId } = input;
21
21
  const tools = roster.tools;
22
22
  let memoryBlock = input.memoryBlock;
23
23
  const leaves = valveLeaves(spec, toolFaceSnapshot.selector);
@@ -32,12 +32,11 @@ export function prepareDeferClassify(input) {
32
32
  throw e;
33
33
  }
34
34
  }
35
- if (promptProfile === "classic") {
36
- for (let i = 0; i < tools.length; i++) {
37
- const t = tools[i];
38
- if (t.descriptionClassic !== undefined)
39
- roster.replaceAt(i, { ...t, description: t.descriptionClassic });
40
- }
35
+ for (let i = 0; i < tools.length; i++) {
36
+ const t = tools[i];
37
+ const face = mountDescriptionVariant(t, promptTraits);
38
+ if (face !== t)
39
+ roster.replaceAt(i, face);
41
40
  }
42
41
  const protocolToolNames = [...mcp.tools, ...a2a.tools].filter((t) => protocolOf(t.name) !== undefined).map((t) => t.name);
43
42
  const mcpAlwaysLoadNames = mcp.tools
@@ -14,15 +14,18 @@
14
14
  *
15
15
  * The request door (the bad-value doors and every refusal the request decides alone) lives in
16
16
  * `./file-history-request.ts` and runs BEFORE the session is acquired; this phase receives its resolution.
17
- * The module-level helpers below the phase (`restoredAbsPathsOf`,
18
- * the refusal's epoch-tail wording helper, `adoptForkedFileHistory` with its per-store carry memo,
17
+ * The module-level helpers below the phase (`adoptForkedFileHistory` with its per-store carry memo,
19
18
  * `createFileHistoryBoundarySeat`, `resolveFileHistoryCoordinates` / `resolveFileHistoryScope` /
20
19
  * `fileHistoryFilesystemIdentity`, `childScopeRewindRefusal`) moved with it unchanged; the two the test
21
- * suite reaches through the driver are re-exported from there.
20
+ * suite reaches through the driver are re-exported from there. The restore itself and the reading of its
21
+ * answer live in `./file-history-restore.ts`, shared with the out-of-run rewind (`./rewind-files.ts`), which
22
+ * also reaches down here for the coordinates and the fork carry — a rewind outside a run is the same history
23
+ * operation as the one this phase runs.
22
24
  */
23
25
  import type { ExecutionEnv } from "../../internal/harness.js";
24
26
  import type { StoredSession } from "../../engine/session/session.js";
25
27
  import type { RunnerDeps, TaskResult, TaskSpec, TrackFileEditHook } from "../types.js";
28
+ import type { FileHistoryStore } from "../file-history-store.js";
26
29
  import type { FileHistoryBoundarySeat, RunInternals } from "./contracts.js";
27
30
  import type { FileHistoryRequest } from "./file-history-request.js";
28
31
  export interface PrepareFileHistoryInput {
@@ -36,8 +39,9 @@ export interface PrepareFileHistoryInput {
36
39
  * acquired: every refusal the request and the deployment's seats decide on their own has already thrown. */
37
40
  request: FileHistoryRequest;
38
41
  /** borrowed-readonly — the trusted lineage a delegating parent handed this run (absent for a root run
39
- * and for a host's own fork), read for the recording-scope decision only. */
40
- internals: Pick<RunInternals, "fileHistoryLineage"> | undefined;
42
+ * and for a host's own fork), read for the recording-scope decision only; and the Runner's session
43
+ * read-state seats, whose restore channel the restore writes the paths it moved into. */
44
+ internals: Pick<RunInternals, "fileHistoryLineage" | "sessionReadStates"> | undefined;
41
45
  /** borrowed-readonly — the run's resolved env (owned or static or the stub); every history verb runs
42
46
  * against ITS filesystem ops. Never rebound or destroyed here. */
43
47
  executionEnv: ExecutionEnv;
@@ -60,9 +64,6 @@ export interface PrepareFileHistoryResult {
60
64
  /** borrowed-readonly — the turn-start boundary seat runtask drives; `undefined` when not live or when
61
65
  * this run records into its ROOT session's scope (a child mints no boundaries). */
62
66
  fileHistoryBoundary: FileHistoryBoundarySeat | undefined;
63
- /** borrowed-readonly — the absolute paths the restore MUTATED (empty when no restore ran), for the
64
- * read-face phase's read-state invalidation. */
65
- restoredFilePaths: string[];
66
67
  /** borrowed-mutable — the non-fatal rewind disclosures (`TaskResult.rewindNotes`). Mutation owners after
67
68
  * this call: none — every push happens inside this phase; the driver only reads it into `Prepared`. */
68
69
  rewindNotes: NonNullable<TaskResult["rewindNotes"]>;
@@ -79,6 +80,45 @@ export interface PrepareFileHistoryResult {
79
80
  historyFs: string;
80
81
  }
81
82
  export declare function prepareFileHistory(input: PrepareFileHistoryInput): Promise<PrepareFileHistoryResult>;
83
+ /**
84
+ * Carry a forked session's file history from its parent scope (the seat §5 names).
85
+ * Never throws and never fails the turn: a store that cannot carry leaves the fork with an empty
86
+ * history, which is DEGRADED (a pre-fork boundary is not restorable from the new session) and not
87
+ * wrong (nothing is silently mis-restored — the restore seat answers "no boundary" honestly).
88
+ */
89
+ export declare function adoptForkedFileHistory(store: FileHistoryStore, session: {
90
+ getMetadata(): Promise<{
91
+ forkedFrom?: string;
92
+ }>;
93
+ }, sessionId: string, onError: RunnerDeps["onError"]): Promise<void>;
94
+ /**
95
+ * The run's two file-history COORDINATES, resolved once where store/env/root meet (module-level per
96
+ * the body ratchet):
97
+ * - `historyRoot` — ONE canonical root coordinate for every history verb: capture keys (rel-under-root
98
+ * vs absolute, DV-6) must agree with the canonical containment keys the hands band mints — a
99
+ * symlinked root spelling (macOS /var → /private/var) would otherwise record in-root files as
100
+ * absolute and un-tether them from the root they live in.
101
+ * - `historyScope` — WHICH scope this run's first-touch records land in. A top-level run owns its own
102
+ * (its sessionId). A delegated child that was handed a {@link RunInternals.fileHistoryLineage} and
103
+ * runs on the SAME canonical root records into the lineage's scope — the root session's — so the
104
+ * edits a child makes on the user's behalf are part of the ONE history the user rewinds from
105
+ * (before this, a child's first touch minted its baseline in a scope no rewind ever read, and the
106
+ * parent's own later first touch of that file recorded the child-modified bytes as pristine). A
107
+ * child on a DIFFERENT root keeps its own scope: keys are root-relative and carry no root, so a
108
+ * record minted under a worktree re-joined against the root session's tree would converge a file
109
+ * that run never edited — the structural out-of-scope guarantee the store contract opens with.
110
+ * Same-tree equality is judged on TWO coordinates, both minted here: the CANONICAL root spelling
111
+ * both sides minted their keys against, and the FILESYSTEM the env is a view of
112
+ * ({@link fileHistoryFilesystemIdentity}) — a path string alone is not a tree (two per-task
113
+ * sandboxes can both spell `/workspace` and hold unrelated files).
114
+ * With no live history store there is nothing to coordinate: own scope, uncanonicalized root, no
115
+ * filesystem identity (nothing reads any of them).
116
+ */
117
+ export declare function resolveFileHistoryCoordinates(enabled: boolean, env: ExecutionEnv, taskRoot: string, lineage: RunInternals["fileHistoryLineage"], sessionId: string): Promise<{
118
+ historyRoot: string;
119
+ historyScope: string;
120
+ historyFs: string;
121
+ }>;
82
122
  /** The ONE reading of {@link RunInternals.fileHistoryLineage} (see {@link resolveFileHistoryCoordinates}):
83
123
  * the lineage's scope iff BOTH tree coordinates match; otherwise the run's own session. */
84
124
  export declare function resolveFileHistoryScope(lineage: RunInternals["fileHistoryLineage"], historyRoot: string, historyFs: string, sessionId: string): string;
@@ -1,8 +1,9 @@
1
1
  import { NodeExecutionEnv } from "../../engine/execution-env/node-execution-env.js";
2
2
  import { isRemoteExecutionEnv } from "../remote-env.js";
3
- import { FILE_HISTORY_ERROR_CODES, FileHistoryStoreError, resolveTrackKey } from "../file-history-store.js";
3
+ import { FILE_HISTORY_ERROR_CODES, FileHistoryStoreError } from "../file-history-store.js";
4
4
  import { readMember, thrownText } from "../thrown-value.js";
5
5
  import { isGovernanceRetryClass } from "../governance-codes.js";
6
+ import { fileHistoryRestoreLedgerLine, settleFileHistoryRestore } from "./file-history-restore.js";
6
7
  export async function prepareFileHistory(input) {
7
8
  const { deps, spec, request, internals, executionEnv, taskRootFinal, handsEnabled, sessionId, session, abortController } = input;
8
9
  const rewindNotes = [];
@@ -45,25 +46,10 @@ export async function prepareFileHistory(input) {
45
46
  });
46
47
  }
47
48
  }
48
- let restoredFilePaths = [];
49
49
  if (rewindTarget !== undefined && fileHistoryStore !== undefined && handsEnabled) {
50
50
  const restoreSignal = spec.signal ? AbortSignal.any([abortController.signal, spec.signal]) : abortController.signal;
51
- const restored = await fileHistoryStore.restore(sessionId, rewindTarget, executionEnv, historyRoot, restoreSignal);
52
- const ledgerLine = (r) => `applied ${r.filesChanged.length}, identical ${r.identicalSkipped.length}, refused ${r.refused.length}${r.refused.length > 0 ? ` (${r.refused.map((f) => `${f.path}: ${f.reason}`).join("; ")})` : ""}, failed ${r.failed.length}${r.failed.length > 0 ? ` (${r.failed.map((f) => `${f.path}: ${f.reason}`).join("; ")})` : ""}`;
53
- if (restored.outcome === "failed") {
54
- if (restored.error?.code === "not_found") {
55
- if (rewindBefore)
56
- throw beforeWithoutBoundaryRefusal(rewindTarget, sessionId);
57
- const e = new Error(`rewind-files: no file-history boundary exists for entry "${rewindTarget}" on session "${sessionId}" — the working tree was NOT rewound. ${rewindRefusalTail()}`);
58
- e.code = "rewind_snapshot.unresolvable";
59
- throw e;
60
- }
61
- const e = new Error(`rewind-files restore failed (${restored.error?.code ?? "restore_failed"}): ${restored.error?.message ?? "unknown"} — ledger: ${ledgerLine(restored)}`);
62
- e.code = "rewind.restore_failed";
63
- if (restored.error !== undefined)
64
- e.detail = { code: restored.error.code, ...(isGovernanceRetryClass(restored.error.permanence) ? { permanence: restored.error.permanence } : {}) };
65
- throw e;
66
- }
51
+ const restored = await settleFileHistoryRestore({ store: fileHistoryStore, sessionId, target: rewindTarget, before: rewindBefore, env: executionEnv, root: historyRoot, signal: restoreSignal, readStates: internals?.sessionReadStates });
52
+ const ledgerLine = fileHistoryRestoreLedgerLine;
67
53
  if (restored.outcome === "partial") {
68
54
  if (spec.acceptPartialRestore === true) {
69
55
  rewindNotes.push({
@@ -77,7 +63,6 @@ export async function prepareFileHistory(input) {
77
63
  throw e;
78
64
  }
79
65
  }
80
- restoredFilePaths = restoredAbsPathsOf(restored, historyRoot);
81
66
  }
82
67
  const trackFileEdit = fileHistoryEnabled
83
68
  ? async (req) => {
@@ -115,24 +100,7 @@ export async function prepareFileHistory(input) {
115
100
  ? createFileHistoryBoundarySeat({ store: fileHistoryStore, sessionId, env: executionEnv, root: historyRoot, onError: deps.onError })
116
101
  : undefined;
117
102
  const fileHistoryFact = fileHistoryEnabled ? "on" : "disabled";
118
- return { trackFileEdit, fileHistoryBoundary, restoredFilePaths, rewindNotes, fileHistoryEnabled, fileHistoryFact, historyScope, historyRoot, historyFs };
119
- }
120
- function restoredAbsPathsOf(restored, root) {
121
- const out = [];
122
- for (const key of [...restored.filesChanged, ...restored.failed.map((f) => f.path)]) {
123
- const abs = resolveTrackKey(root, key);
124
- if (abs.ok)
125
- out.push(abs.abs);
126
- }
127
- return out;
128
- }
129
- function rewindRefusalTail() {
130
- return `Boundaries are keyed by a turn's INITIAL entry and exist only for turns that recorded history (a RunnerDeps.fileHistoryStore wired, capture on, and the run's file history not disabled); a boundary from the retired whole-tree snapshot era is not restorable by this seat, and reaped boundaries have none.`;
131
- }
132
- function beforeWithoutBoundaryRefusal(target, sessionId) {
133
- const e = new Error(`rewind-files: entry "${target}" has no file-history boundary on session "${sessionId}" — a before-restore needs the target's own boundary and never crosses into an earlier turn, so the working tree was NOT rewound. ${rewindRefusalTail()}`);
134
- e.code = "rewind_snapshot.unresolvable";
135
- return e;
103
+ return { trackFileEdit, fileHistoryBoundary, rewindNotes, fileHistoryEnabled, fileHistoryFact, historyScope, historyRoot, historyFs };
136
104
  }
137
105
  const FILE_HISTORY_BOUNDARY_TIMEOUT_MS = 30_000;
138
106
  const FILE_HISTORY_LIVENESS_MEMO = new WeakMap();
@@ -160,7 +128,7 @@ function answerOf(call, code) {
160
128
  return { ok: false, error: { code: known, message: text, ...(isGovernanceRetryClass(permanence) ? { permanence } : {}) } };
161
129
  }, (value) => unanswered(`the history store threw: ${thrownText(value)}`, { value }));
162
130
  }
163
- async function adoptForkedFileHistory(store, session, sessionId, onError) {
131
+ export async function adoptForkedFileHistory(store, session, sessionId, onError) {
164
132
  const memo = FILE_HISTORY_CARRY_MEMO.get(store) ?? { settled: new Set(), disclosed: new Set(), inFlight: new Map() };
165
133
  FILE_HISTORY_CARRY_MEMO.set(store, memo);
166
134
  const discloseOnce = (err) => {
@@ -242,7 +210,7 @@ function createFileHistoryBoundarySeat(opts) {
242
210
  },
243
211
  };
244
212
  }
245
- async function resolveFileHistoryCoordinates(enabled, env, taskRoot, lineage, sessionId) {
213
+ export async function resolveFileHistoryCoordinates(enabled, env, taskRoot, lineage, sessionId) {
246
214
  if (!enabled)
247
215
  return { historyRoot: taskRoot, historyScope: sessionId, historyFs: "" };
248
216
  const canonRoot = await env.canonicalPath(taskRoot);
@@ -108,7 +108,7 @@ export interface PrepareGateStationsInput {
108
108
  complianceDenies: ReadonlySet<ComplianceCapability>;
109
109
  /** borrowed-mutable — the built harness. Writer here: `on("tool_call")` / `on("tool_result")` — the registrations this
110
110
  * phase exists for, in this order, after the driver's boundary-lease handler. */
111
- harness: Pick<AgentHarness, "on">;
111
+ harness: Pick<AgentHarness, "on" | "isBatchSafe">;
112
112
  /** borrowed-mutable — the blocked/suspended call ids (`Prepared.blockedToolCalls`). Writers here: the head-of-evaluation
113
113
  * hygiene `delete`, the two short-circuits' and the gate outcome's `add`, the `tool_result` station's one-shot `delete`. */
114
114
  blockedToolCalls: Set<string>;
@@ -13,6 +13,8 @@ import { PATH_CONFINABLE_WRITE_TOOLS } from "./session-rule-policy.js";
13
13
  import { callFaceSeat, rosterToolName, toolCallFaceOf } from "../tool-roster.js";
14
14
  import { heldBy, heldValues, seatOf, wireOf } from "../tool-name-readings.js";
15
15
  import { createApprovedCallScreen, createToolResultStation } from "./call-hook-stations.js";
16
+ import { extensionCallOf } from "../mods/extension-call.js";
17
+ import { extensionCallOverlap } from "../mods/tool-call.js";
16
18
  const PEER_MESSAGE_NAMES = new Set([SEND_MESSAGE_TOOL_NAME]);
17
19
  function screenGateResult(result) {
18
20
  if (result.suspend !== undefined)
@@ -123,7 +125,7 @@ export function prepareGateStations(input) {
123
125
  toolFaceOf: (name) => toolCallFaceOf(toolRosterDeltas.current, name === e.toolName ? called.toolName : name),
124
126
  adjudicate,
125
127
  resolveAsk: (...args) => toolOccurrences.whileAwaitingUser(args[1].toolCallId, () => resolveAskBound(...args)),
126
- suspendAsk,
128
+ ...(extensionCallOf(modBus, e.toolCallId) === undefined ? { suspendAsk } : {}),
127
129
  resolveContentAsk: (...args) => toolOccurrences.whileAwaitingUser(args[0].toolCallId, () => resolveContentAsk(...args)),
128
130
  egress: heldBy("gate.egress", egressTools, call),
129
131
  peerMessage: heldBy("gate.peerMessage", PEER_MESSAGE_NAMES, call),
@@ -236,6 +238,13 @@ export function prepareGateStations(input) {
236
238
  }
237
239
  return { block: true, reason: result.reason, ...details };
238
240
  }
241
+ const overlap = result.suspend === undefined && extensionCallOf(modBus, e.toolCallId) !== undefined ? extensionCallOverlap({ occurrences: toolOccurrences, toolCallId: e.toolCallId, toolName: e.toolName, args: result.finalInput ?? e.input, batchSafe: (n, a) => harness.isBatchSafe(n, a) }) : undefined;
242
+ if (overlap !== undefined) {
243
+ toolOccurrences.refuse(e.toolCallId, "hook");
244
+ if (blockedTracked)
245
+ blockedToolCalls.add(e.toolCallId);
246
+ return { block: true, reason: formatHookFeedback(overlap, reminderMark) };
247
+ }
239
248
  if (result.suspend === undefined)
240
249
  toolOccurrences.release(e.toolCallId);
241
250
  return result.updatedInput !== undefined ? { updatedInput: result.updatedInput } : undefined;
@@ -96,7 +96,8 @@ export interface PrepareHandsReadFaceInput {
96
96
  deps: Pick<RunnerDeps, "onError" | "onNotice" | "tracer" | "readDenyPatterns" | "readDenyBuiltinTiers" | "readDenyBuiltinExclude" | "agentConfigDir" | "readFace" | "writeFace" | "permissionRuleStore" | "hands">;
97
97
  /** borrowed-readonly — the trusted spawn-side seats the band forwards: the finished-command
98
98
  * notification lane, the mid-flight detach hub, and the Runner's per-session
99
- * read-state seats (absent on a standalone prepare ⇒ the transcript-replay rung covers alone). */
99
+ * read-state seats and their restore channel (absent on a standalone prepare ⇒ the transcript-replay rung
100
+ * covers alone, and no restore is owed a check — the channel is the Runner's). */
100
101
  internals: Pick<RunInternals, "onTaskNotification" | "detachHub" | "sessionReadStates"> | undefined;
101
102
  /** borrowed-mutable — the harness seat, read LIVE by the band's queued-human-input predicate (the shell's
102
103
  * auto-backgrounding leg asks it mid-command). Late-bound: the band is built here, the harness later. */
@@ -110,13 +111,6 @@ export interface PrepareHandsReadFaceInput {
110
111
  };
111
112
  /** borrowed-mutable — the leg's occurrence table; writer here: the shell read station's refused-admission callback. */
112
113
  toolOccurrences: ToolOccurrenceTable;
113
- /** borrowed-readonly — ABSOLUTE paths this prepare's restore wrote, deleted,
114
- * or failed to write. Every read-state seed above describes the PRE-restore tree, so these keys are
115
- * dropped from the map: the engine replaced those bytes itself, and a surviving entry makes the
116
- * next refusal blame "the user or a linter" for the engine's own write. Absent (the common case)
117
- * when no file restore ran. Fail-closed by construction — dropping a read record only ever
118
- * produces refusals. */
119
- restoredFilePaths?: readonly string[];
120
114
  /** borrowed-readonly — the memory write gate the memory phase minted (it runs BEFORE this phase: the memory root
121
115
  * must be known before the toolkit compiles), composed into the band's beforeWrite below; undefined for a
122
116
  * memory-less run (every write passes the engine half). */
@@ -260,22 +260,23 @@ export async function prepareHandsMount(input) {
260
260
  }
261
261
  }
262
262
  }
263
- if (input.restoredFilePaths !== undefined) {
264
- for (const abs of input.restoredFilePaths) {
265
- const k = await judgeKey(abs);
266
- if (k === undefined)
267
- continue;
268
- const entry = readFileState.get(k);
269
- if (entry === undefined || entry.seededFromContext === true)
270
- continue;
271
- const cur = await executionEnv.readTextFile(abs);
272
- if (cur.ok && entry.hash === sha256(normalizeFileText(cur.value)))
273
- continue;
274
- readFileState.delete(k);
275
- }
263
+ const restoredOwed = sessionSeats?.pendingRestored(sessionId) ?? [];
264
+ for (const abs of restoredOwed) {
265
+ const k = await judgeKey(abs);
266
+ if (k === undefined)
267
+ continue;
268
+ const entry = readFileState.get(k);
269
+ if (entry === undefined || entry.seededFromContext === true)
270
+ continue;
271
+ const cur = await executionEnv.readTextFile(abs);
272
+ if (cur.ok && entry.hash === sha256(normalizeFileText(cur.value)))
273
+ continue;
274
+ readFileState.delete(k);
276
275
  }
277
- if (seatLeafId !== undefined)
276
+ if (seatLeafId !== undefined) {
278
277
  sessionSeats?.adopt(sessionId, readFileState, seatLeafId);
278
+ sessionSeats?.settleRestored(sessionId, restoredOwed);
279
+ }
279
280
  sealReadStateSeat =
280
281
  sessionSeats !== undefined && seatLeafId !== undefined
281
282
  ? (ownCommittedTailEntryId) => {
@@ -62,6 +62,8 @@ export interface PrepareInheritedGateInput {
62
62
  checkpointSeat: import("../checkpoint-seat.js").CheckpointSeat | undefined;
63
63
  /** borrowed-readonly — this leg's checkpoint scope (the driver's one `checkpointScopeOf` derivation): the ctx's `checkpointScopeForChildren`, which every delegation lane copies into its children's internals. */
64
64
  checkpointScope: string;
65
+ /** borrowed-readonly — the deployment's host floor as the config doors compiled it (`RunnerDeps.hostFloor`): the ctx's `hostFloor`, absent when none is declared. */
66
+ hostFloor: import("../host-floor.js").HostFloor | undefined;
65
67
  /** borrowed-readonly — the deployment seats: `autoMode.denialLimit` (the rebuilt trackers' bounds), `memoryScopeAdmission` /
66
68
  * `deploymentMemoryScopes` / `compliancePostureResolver` (the governed-provenance bit), `onError` (the screening-face crash
67
69
  * lane), `onNotice` (the stop seat's notice), `executionEnv` (the hook-env identity predicate), `delegationEntryCaps` (resolved
@@ -109,8 +111,8 @@ export interface PrepareInheritedGateInput {
109
111
  mountsCallerTool: (tool: ToolSpec) => boolean;
110
112
  /** borrowed-readonly — the ctx's `mountedMcp` seat: the MCP surface the run mounts right now (call-time; the roster is minted after this phase). Present iff the run declared a server. */
111
113
  mountedMcp?: () => import("../mounted-mcp.js").MountedMcp;
112
- /** borrowed-readonly — the resolved prompt profile (ctx seat). */
113
- promptProfile: ToolExecuteContext["promptProfile"];
114
+ /** borrowed-readonly — the task-level lean switch (ctx seat; absent ⇒ no key). */
115
+ promptLean: ToolExecuteContext["promptLean"];
114
116
  /** borrowed-readonly — the resolved interaction posture (ctx seat; absent ⇒ no key). */
115
117
  resolvedInteractionPosture: ToolExecuteContext["interactionPosture"];
116
118
  /** borrowed-readonly — the task's own permission-mode key, screened and snapshotted before the first await (undefined =
@@ -160,7 +162,8 @@ export interface PrepareInheritedGateInput {
160
162
  /** borrowed-readonly — LATE-BOUND: the per-principal entitlements the caps phase resolves after this one; read only inside
161
163
  * `inheritedGateForChildren` (the two mandate tests), at spawn time. */
162
164
  runtimeCaps: () => RuntimeCaps | undefined;
163
- /** borrowed-readonly — the leg's mods bus: the chain assembly mints this leg's screening entry over its `classic.PreToolUse` chain. */
165
+ /** borrowed-readonly — what the leg hands its descendants of its mods bus (`LegMods.handedDown`: without the skills' own
166
+ * registrations): the chain assembly mints this leg's screening entry over its `classic.PreToolUse` chain. */
164
167
  modBus: LegModBus;
165
168
  /** borrowed-readonly — this leg's chain identity as its admission recorded it (`chainOfBus`) — the installation identity's chain term. */
166
169
  ownModChain: readonly ModChainLink[];
@@ -1,3 +1,4 @@
1
+ import { principalNameOf } from "../principal-name.js";
1
2
  import { forkGovernanceDenial, resolveDelegationEntryCaps } from "../../agents/subagent.js";
2
3
  import { isLiveQuestionFace } from "../ask-question.js";
3
4
  import { parentSpecSeatOf } from "../parent-spec-seat.js";
@@ -16,7 +17,7 @@ import { frozenSkillGrants } from "../skill-grant.js";
16
17
  import { attachRebuiltDenialTrackers, createDenialLimitStop } from "./denial-limit-arms.js";
17
18
  import { valveLeaves } from "../../agents/tool-filter.js";
18
19
  export function prepareInheritedGate(input) {
19
- const { spec, deps, askSeat, internals, resume, sessions, sessionId, runId, hostTaskId, taskRootFinal, executionEnv, ownedEnv, lockedPreflight, pathRuleAnchors, toolFaceSnapshot, mountsCallerTool, promptProfile, resolvedInteractionPosture, permissionModeSeat, handsEnabled, reportUsage, harnessRef, skillGrants, forwardEvent, subagentRetain, worktreeIsolation, requestReview, requestStopAfterTurn, enterPlanMode, reminderMark, reminderDisclosureCounts, fileHistoryEnabled, historyScope, historyRoot, historyFs, abortRun } = input;
20
+ const { spec, deps, askSeat, internals, resume, sessions, sessionId, runId, hostTaskId, taskRootFinal, executionEnv, ownedEnv, lockedPreflight, pathRuleAnchors, toolFaceSnapshot, mountsCallerTool, promptLean, resolvedInteractionPosture, permissionModeSeat, handsEnabled, reportUsage, harnessRef, skillGrants, forwardEvent, subagentRetain, worktreeIsolation, requestReview, requestStopAfterTurn, enterPlanMode, reminderMark, reminderDisclosureCounts, fileHistoryEnabled, historyScope, historyRoot, historyFs, abortRun } = input;
20
21
  const liveInheritedGate = internals?.inheritedGate;
21
22
  const seedInheritedGate = resume?.seed.inheritedGate;
22
23
  const inheritedAncestorRules = (() => {
@@ -221,7 +222,7 @@ export function prepareInheritedGate(input) {
221
222
  deferTools: toolFaceSnapshot.defer,
222
223
  alwaysLoadTools: toolFaceSnapshot.alwaysLoad,
223
224
  ...(toolFaceSnapshot.restoreGated !== undefined ? { restoreGatedTools: toolFaceSnapshot.restoreGated } : {}),
224
- promptProfile,
225
+ ...(promptLean !== undefined ? { promptLean } : {}),
225
226
  ...(spec.memoryPersistenceCapable !== undefined ? { memoryPersistenceCapable: spec.memoryPersistenceCapable } : {}),
226
227
  get memoryCaptureOptedOut() {
227
228
  return input.memoryEngineSession()?.captureOptOut?.optedOut() ?? false;
@@ -238,6 +239,7 @@ export function prepareInheritedGate(input) {
238
239
  },
239
240
  getApiKeyAndHeaders: spec.getApiKeyAndHeaders,
240
241
  parentCwd: taskRootFinal,
242
+ ...(input.hostFloor !== undefined ? { hostFloor: input.hostFloor } : {}),
241
243
  ...(fileHistoryEnabled ? { fileHistoryLineage: { scope: historyScope, root: historyRoot, fs: historyFs } } : {}),
242
244
  reminderMark,
243
245
  reminderDisclosureCounts,
@@ -264,7 +266,7 @@ export function prepareInheritedGate(input) {
264
266
  ...(sessions.fork !== undefined
265
267
  ? {
266
268
  hostSessionFork: async () => {
267
- const forked = (await sessions.fork(sessionId, spec.principal ?? null)) ?? null;
269
+ const forked = (await sessions.fork(sessionId, principalNameOf(spec.principal) ?? null)) ?? null;
268
270
  if (forked === null)
269
271
  return null;
270
272
  return {