agentfootprint 9.86.0 → 9.87.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (299) hide show
  1. package/CHANGELOG.md +319 -8
  2. package/README.md +14 -0
  3. package/canonical-notes.json +1 -1
  4. package/dist/artifacts/placement.js +4 -0
  5. package/dist/artifacts/placement.js.map +1 -1
  6. package/dist/artifacts/present.js +6 -0
  7. package/dist/artifacts/present.js.map +1 -1
  8. package/dist/artifacts/wants.js +8 -0
  9. package/dist/artifacts/wants.js.map +1 -1
  10. package/dist/core/Agent.js +21 -7
  11. package/dist/core/Agent.js.map +1 -1
  12. package/dist/core/LLMCall.js +2 -1
  13. package/dist/core/LLMCall.js.map +1 -1
  14. package/dist/core/agent/buildMessageApiChart.js +2 -1
  15. package/dist/core/agent/buildMessageApiChart.js.map +1 -1
  16. package/dist/core/agent/buildToolRegistry.js +4 -0
  17. package/dist/core/agent/buildToolRegistry.js.map +1 -1
  18. package/dist/core/agent/coverage/answer.js +4 -0
  19. package/dist/core/agent/coverage/answer.js.map +1 -1
  20. package/dist/core/agent/coverage/ledger.js +8 -2
  21. package/dist/core/agent/coverage/ledger.js.map +1 -1
  22. package/dist/core/agent/evidence/evidenceIndex.js +3 -0
  23. package/dist/core/agent/evidence/evidenceIndex.js.map +1 -1
  24. package/dist/core/agent/evidence/gate.js +3 -0
  25. package/dist/core/agent/evidence/gate.js.map +1 -1
  26. package/dist/core/agent/outputEnforcement.js +3 -0
  27. package/dist/core/agent/outputEnforcement.js.map +1 -1
  28. package/dist/core/agent/presentTool.js +3 -0
  29. package/dist/core/agent/presentTool.js.map +1 -1
  30. package/dist/core/agent/repeatedCall.js +3 -0
  31. package/dist/core/agent/repeatedCall.js.map +1 -1
  32. package/dist/core/agent/resultCeiling.js +3 -0
  33. package/dist/core/agent/resultCeiling.js.map +1 -1
  34. package/dist/core/agent/selfCallNotice.js +5 -0
  35. package/dist/core/agent/selfCallNotice.js.map +1 -1
  36. package/dist/core/agent/stagedRefs.js +5 -0
  37. package/dist/core/agent/stagedRefs.js.map +1 -1
  38. package/dist/core/agent/stages/callLLM.js +9 -0
  39. package/dist/core/agent/stages/callLLM.js.map +1 -1
  40. package/dist/core/agent/stages/evidenceRecheck.js +6 -0
  41. package/dist/core/agent/stages/evidenceRecheck.js.map +1 -1
  42. package/dist/core/agent/stages/stepNudge.js +5 -0
  43. package/dist/core/agent/stages/stepNudge.js.map +1 -1
  44. package/dist/core/agent/stages/toolCalls.js +136 -20
  45. package/dist/core/agent/stages/toolCalls.js.map +1 -1
  46. package/dist/core/agent/stages/wrapUp.js +19 -4
  47. package/dist/core/agent/stages/wrapUp.js.map +1 -1
  48. package/dist/core/agent/window/notice.js +6 -0
  49. package/dist/core/agent/window/notice.js.map +1 -1
  50. package/dist/core/agent/window/summarize.js +4 -0
  51. package/dist/core/agent/window/summarize.js.map +1 -1
  52. package/dist/core/runbook/recording.js +3 -2
  53. package/dist/core/runbook/recording.js.map +1 -1
  54. package/dist/core/runbook/verdicts.js +3 -0
  55. package/dist/core/runbook/verdicts.js.map +1 -1
  56. package/dist/core/slots/buildToolsSlot.js +11 -0
  57. package/dist/core/slots/buildToolsSlot.js.map +1 -1
  58. package/dist/esm/artifacts/placement.js +4 -0
  59. package/dist/esm/artifacts/placement.js.map +1 -1
  60. package/dist/esm/artifacts/present.js +6 -0
  61. package/dist/esm/artifacts/present.js.map +1 -1
  62. package/dist/esm/artifacts/wants.js +8 -0
  63. package/dist/esm/artifacts/wants.js.map +1 -1
  64. package/dist/esm/core/Agent.js +21 -7
  65. package/dist/esm/core/Agent.js.map +1 -1
  66. package/dist/esm/core/LLMCall.js +2 -1
  67. package/dist/esm/core/LLMCall.js.map +1 -1
  68. package/dist/esm/core/agent/buildMessageApiChart.d.ts +2 -1
  69. package/dist/esm/core/agent/buildMessageApiChart.js +2 -1
  70. package/dist/esm/core/agent/buildMessageApiChart.js.map +1 -1
  71. package/dist/esm/core/agent/buildToolRegistry.js +4 -0
  72. package/dist/esm/core/agent/buildToolRegistry.js.map +1 -1
  73. package/dist/esm/core/agent/coverage/answer.js +4 -0
  74. package/dist/esm/core/agent/coverage/answer.js.map +1 -1
  75. package/dist/esm/core/agent/coverage/ledger.d.ts +5 -0
  76. package/dist/esm/core/agent/coverage/ledger.js +8 -2
  77. package/dist/esm/core/agent/coverage/ledger.js.map +1 -1
  78. package/dist/esm/core/agent/evidence/evidenceIndex.js +3 -0
  79. package/dist/esm/core/agent/evidence/evidenceIndex.js.map +1 -1
  80. package/dist/esm/core/agent/evidence/gate.js +3 -0
  81. package/dist/esm/core/agent/evidence/gate.js.map +1 -1
  82. package/dist/esm/core/agent/outputEnforcement.js +3 -0
  83. package/dist/esm/core/agent/outputEnforcement.js.map +1 -1
  84. package/dist/esm/core/agent/presentTool.js +3 -0
  85. package/dist/esm/core/agent/presentTool.js.map +1 -1
  86. package/dist/esm/core/agent/repeatedCall.js +3 -0
  87. package/dist/esm/core/agent/repeatedCall.js.map +1 -1
  88. package/dist/esm/core/agent/resultCeiling.js +3 -0
  89. package/dist/esm/core/agent/resultCeiling.js.map +1 -1
  90. package/dist/esm/core/agent/selfCallNotice.js +5 -0
  91. package/dist/esm/core/agent/selfCallNotice.js.map +1 -1
  92. package/dist/esm/core/agent/stagedRefs.js +5 -0
  93. package/dist/esm/core/agent/stagedRefs.js.map +1 -1
  94. package/dist/esm/core/agent/stages/callLLM.js +9 -0
  95. package/dist/esm/core/agent/stages/callLLM.js.map +1 -1
  96. package/dist/esm/core/agent/stages/evidenceRecheck.js +6 -0
  97. package/dist/esm/core/agent/stages/evidenceRecheck.js.map +1 -1
  98. package/dist/esm/core/agent/stages/stepNudge.js +5 -0
  99. package/dist/esm/core/agent/stages/stepNudge.js.map +1 -1
  100. package/dist/esm/core/agent/stages/toolCalls.d.ts +16 -2
  101. package/dist/esm/core/agent/stages/toolCalls.js +136 -20
  102. package/dist/esm/core/agent/stages/toolCalls.js.map +1 -1
  103. package/dist/esm/core/agent/stages/wrapUp.d.ts +11 -0
  104. package/dist/esm/core/agent/stages/wrapUp.js +19 -4
  105. package/dist/esm/core/agent/stages/wrapUp.js.map +1 -1
  106. package/dist/esm/core/agent/types.d.ts +5 -4
  107. package/dist/esm/core/agent/window/notice.js +6 -0
  108. package/dist/esm/core/agent/window/notice.js.map +1 -1
  109. package/dist/esm/core/agent/window/summarize.js +4 -0
  110. package/dist/esm/core/agent/window/summarize.js.map +1 -1
  111. package/dist/esm/core/runbook/recording.js +3 -2
  112. package/dist/esm/core/runbook/recording.js.map +1 -1
  113. package/dist/esm/core/runbook/verdicts.js +3 -0
  114. package/dist/esm/core/runbook/verdicts.js.map +1 -1
  115. package/dist/esm/core/slots/buildToolsSlot.js +11 -0
  116. package/dist/esm/core/slots/buildToolsSlot.js.map +1 -1
  117. package/dist/esm/events/eventTail.js +4 -0
  118. package/dist/esm/events/eventTail.js.map +1 -1
  119. package/dist/esm/events/payloads.d.ts +8 -0
  120. package/dist/esm/index.d.ts +1 -0
  121. package/dist/esm/index.js +9 -0
  122. package/dist/esm/index.js.map +1 -1
  123. package/dist/esm/integrity/disposition/ledger.js +0 -0
  124. package/dist/esm/integrity/disposition/ledger.js.map +1 -1
  125. package/dist/esm/lib/context-ledger/contextLedger.js +3 -0
  126. package/dist/esm/lib/context-ledger/contextLedger.js.map +1 -1
  127. package/dist/esm/lib/injection-engine/evaluator.js +3 -0
  128. package/dist/esm/lib/injection-engine/evaluator.js.map +1 -1
  129. package/dist/esm/lib/injection-engine/promptTemplate.js +4 -0
  130. package/dist/esm/lib/injection-engine/promptTemplate.js.map +1 -1
  131. package/dist/esm/lib/injection-engine/skillGraph.js +17 -0
  132. package/dist/esm/lib/injection-engine/skillGraph.js.map +1 -1
  133. package/dist/esm/lib/injection-engine/skillSteps.js +26 -2
  134. package/dist/esm/lib/injection-engine/skillSteps.js.map +1 -1
  135. package/dist/esm/lib/injection-engine/skillToolDescriptors.js +26 -0
  136. package/dist/esm/lib/injection-engine/skillToolDescriptors.js.map +1 -1
  137. package/dist/esm/lib/iterationBudget.js +4 -0
  138. package/dist/esm/lib/iterationBudget.js.map +1 -1
  139. package/dist/esm/lib/rag/defineRAG.js +4 -0
  140. package/dist/esm/lib/rag/defineRAG.js.map +1 -1
  141. package/dist/esm/lib/saidByPerson.js +4 -0
  142. package/dist/esm/lib/saidByPerson.js.map +1 -1
  143. package/dist/esm/lib/semantics/envelope.js +3 -0
  144. package/dist/esm/lib/semantics/envelope.js.map +1 -1
  145. package/dist/esm/lib/spokenIds.js +5 -0
  146. package/dist/esm/lib/spokenIds.js.map +1 -1
  147. package/dist/esm/lib/time-travel/index.d.ts +8 -0
  148. package/dist/esm/lib/time-travel/index.js +9 -0
  149. package/dist/esm/lib/time-travel/index.js.map +1 -0
  150. package/dist/esm/lib/time-travel/milestoneStops.d.ts +128 -0
  151. package/dist/esm/lib/time-travel/milestoneStops.js +179 -0
  152. package/dist/esm/lib/time-travel/milestoneStops.js.map +1 -0
  153. package/dist/esm/lib/trace-toolpack/debugPrompt.js +3 -0
  154. package/dist/esm/lib/trace-toolpack/debugPrompt.js.map +1 -1
  155. package/dist/esm/lib/trace-toolpack/traceToolpack.js +26 -14
  156. package/dist/esm/lib/trace-toolpack/traceToolpack.js.map +1 -1
  157. package/dist/esm/maps/engagement/lease.js +4 -0
  158. package/dist/esm/maps/engagement/lease.js.map +1 -1
  159. package/dist/esm/maps/engagement/parkCard.js +5 -0
  160. package/dist/esm/maps/engagement/parkCard.js.map +1 -1
  161. package/dist/esm/memory/beats/formatAsNarrative.js +4 -0
  162. package/dist/esm/memory/beats/formatAsNarrative.js.map +1 -1
  163. package/dist/esm/memory/causal/loadSnapshot.js +4 -0
  164. package/dist/esm/memory/causal/loadSnapshot.js.map +1 -1
  165. package/dist/esm/memory/facts/formatFacts.js +4 -0
  166. package/dist/esm/memory/facts/formatFacts.js.map +1 -1
  167. package/dist/esm/memory/stages/formatDefault.js +4 -0
  168. package/dist/esm/memory/stages/formatDefault.js.map +1 -1
  169. package/dist/esm/recorders/observability/FlowchartRecorder.js +3 -0
  170. package/dist/esm/recorders/observability/FlowchartRecorder.js.map +1 -1
  171. package/dist/esm/recorders/observability/recordRun.js +5 -0
  172. package/dist/esm/recorders/observability/recordRun.js.map +1 -1
  173. package/dist/esm/tool-providers/gatedTools.js +7 -0
  174. package/dist/esm/tool-providers/gatedTools.js.map +1 -1
  175. package/dist/esm/tool-providers/skillScopedTools.js +6 -0
  176. package/dist/esm/tool-providers/skillScopedTools.js.map +1 -1
  177. package/dist/events/eventTail.js +4 -0
  178. package/dist/events/eventTail.js.map +1 -1
  179. package/dist/index.js +115 -102
  180. package/dist/index.js.map +1 -1
  181. package/dist/integrity/disposition/ledger.js +0 -0
  182. package/dist/integrity/disposition/ledger.js.map +1 -1
  183. package/dist/lib/context-ledger/contextLedger.js +3 -0
  184. package/dist/lib/context-ledger/contextLedger.js.map +1 -1
  185. package/dist/lib/injection-engine/evaluator.js +3 -0
  186. package/dist/lib/injection-engine/evaluator.js.map +1 -1
  187. package/dist/lib/injection-engine/promptTemplate.js +4 -0
  188. package/dist/lib/injection-engine/promptTemplate.js.map +1 -1
  189. package/dist/lib/injection-engine/skillGraph.js +17 -0
  190. package/dist/lib/injection-engine/skillGraph.js.map +1 -1
  191. package/dist/lib/injection-engine/skillSteps.js +26 -2
  192. package/dist/lib/injection-engine/skillSteps.js.map +1 -1
  193. package/dist/lib/injection-engine/skillToolDescriptors.js +26 -0
  194. package/dist/lib/injection-engine/skillToolDescriptors.js.map +1 -1
  195. package/dist/lib/iterationBudget.js +4 -0
  196. package/dist/lib/iterationBudget.js.map +1 -1
  197. package/dist/lib/rag/defineRAG.js +4 -0
  198. package/dist/lib/rag/defineRAG.js.map +1 -1
  199. package/dist/lib/saidByPerson.js +4 -0
  200. package/dist/lib/saidByPerson.js.map +1 -1
  201. package/dist/lib/semantics/envelope.js +3 -0
  202. package/dist/lib/semantics/envelope.js.map +1 -1
  203. package/dist/lib/spokenIds.js +5 -0
  204. package/dist/lib/spokenIds.js.map +1 -1
  205. package/dist/lib/time-travel/index.js +15 -0
  206. package/dist/lib/time-travel/index.js.map +1 -0
  207. package/dist/lib/time-travel/milestoneStops.js +184 -0
  208. package/dist/lib/time-travel/milestoneStops.js.map +1 -0
  209. package/dist/lib/trace-toolpack/debugPrompt.js +3 -0
  210. package/dist/lib/trace-toolpack/debugPrompt.js.map +1 -1
  211. package/dist/lib/trace-toolpack/traceToolpack.js +26 -14
  212. package/dist/lib/trace-toolpack/traceToolpack.js.map +1 -1
  213. package/dist/maps/engagement/lease.js +4 -0
  214. package/dist/maps/engagement/lease.js.map +1 -1
  215. package/dist/maps/engagement/parkCard.js +5 -0
  216. package/dist/maps/engagement/parkCard.js.map +1 -1
  217. package/dist/memory/beats/formatAsNarrative.js +4 -0
  218. package/dist/memory/beats/formatAsNarrative.js.map +1 -1
  219. package/dist/memory/causal/loadSnapshot.js +4 -0
  220. package/dist/memory/causal/loadSnapshot.js.map +1 -1
  221. package/dist/memory/facts/formatFacts.js +4 -0
  222. package/dist/memory/facts/formatFacts.js.map +1 -1
  223. package/dist/memory/stages/formatDefault.js +4 -0
  224. package/dist/memory/stages/formatDefault.js.map +1 -1
  225. package/dist/recorders/observability/FlowchartRecorder.js +3 -0
  226. package/dist/recorders/observability/FlowchartRecorder.js.map +1 -1
  227. package/dist/recorders/observability/recordRun.js +5 -0
  228. package/dist/recorders/observability/recordRun.js.map +1 -1
  229. package/dist/tool-providers/gatedTools.js +7 -0
  230. package/dist/tool-providers/gatedTools.js.map +1 -1
  231. package/dist/tool-providers/skillScopedTools.js +6 -0
  232. package/dist/tool-providers/skillScopedTools.js.map +1 -1
  233. package/dist/types/artifacts/placement.d.ts.map +1 -1
  234. package/dist/types/artifacts/present.d.ts.map +1 -1
  235. package/dist/types/artifacts/wants.d.ts.map +1 -1
  236. package/dist/types/core/Agent.d.ts.map +1 -1
  237. package/dist/types/core/LLMCall.d.ts.map +1 -1
  238. package/dist/types/core/agent/buildMessageApiChart.d.ts +2 -1
  239. package/dist/types/core/agent/buildMessageApiChart.d.ts.map +1 -1
  240. package/dist/types/core/agent/buildToolRegistry.d.ts.map +1 -1
  241. package/dist/types/core/agent/coverage/answer.d.ts.map +1 -1
  242. package/dist/types/core/agent/coverage/ledger.d.ts +5 -0
  243. package/dist/types/core/agent/coverage/ledger.d.ts.map +1 -1
  244. package/dist/types/core/agent/evidence/evidenceIndex.d.ts.map +1 -1
  245. package/dist/types/core/agent/evidence/gate.d.ts.map +1 -1
  246. package/dist/types/core/agent/outputEnforcement.d.ts.map +1 -1
  247. package/dist/types/core/agent/presentTool.d.ts.map +1 -1
  248. package/dist/types/core/agent/repeatedCall.d.ts.map +1 -1
  249. package/dist/types/core/agent/resultCeiling.d.ts.map +1 -1
  250. package/dist/types/core/agent/selfCallNotice.d.ts.map +1 -1
  251. package/dist/types/core/agent/stagedRefs.d.ts.map +1 -1
  252. package/dist/types/core/agent/stages/callLLM.d.ts.map +1 -1
  253. package/dist/types/core/agent/stages/evidenceRecheck.d.ts.map +1 -1
  254. package/dist/types/core/agent/stages/stepNudge.d.ts.map +1 -1
  255. package/dist/types/core/agent/stages/toolCalls.d.ts +16 -2
  256. package/dist/types/core/agent/stages/toolCalls.d.ts.map +1 -1
  257. package/dist/types/core/agent/stages/wrapUp.d.ts +11 -0
  258. package/dist/types/core/agent/stages/wrapUp.d.ts.map +1 -1
  259. package/dist/types/core/agent/types.d.ts +5 -4
  260. package/dist/types/core/agent/types.d.ts.map +1 -1
  261. package/dist/types/core/agent/window/notice.d.ts.map +1 -1
  262. package/dist/types/core/agent/window/summarize.d.ts.map +1 -1
  263. package/dist/types/core/runbook/recording.d.ts.map +1 -1
  264. package/dist/types/core/runbook/verdicts.d.ts.map +1 -1
  265. package/dist/types/core/slots/buildToolsSlot.d.ts.map +1 -1
  266. package/dist/types/events/eventTail.d.ts.map +1 -1
  267. package/dist/types/events/payloads.d.ts +8 -0
  268. package/dist/types/events/payloads.d.ts.map +1 -1
  269. package/dist/types/index.d.ts +1 -0
  270. package/dist/types/index.d.ts.map +1 -1
  271. package/dist/types/integrity/disposition/ledger.d.ts.map +1 -1
  272. package/dist/types/lib/context-ledger/contextLedger.d.ts.map +1 -1
  273. package/dist/types/lib/injection-engine/evaluator.d.ts.map +1 -1
  274. package/dist/types/lib/injection-engine/promptTemplate.d.ts.map +1 -1
  275. package/dist/types/lib/injection-engine/skillGraph.d.ts.map +1 -1
  276. package/dist/types/lib/injection-engine/skillSteps.d.ts.map +1 -1
  277. package/dist/types/lib/injection-engine/skillToolDescriptors.d.ts.map +1 -1
  278. package/dist/types/lib/iterationBudget.d.ts.map +1 -1
  279. package/dist/types/lib/rag/defineRAG.d.ts.map +1 -1
  280. package/dist/types/lib/saidByPerson.d.ts.map +1 -1
  281. package/dist/types/lib/semantics/envelope.d.ts.map +1 -1
  282. package/dist/types/lib/spokenIds.d.ts.map +1 -1
  283. package/dist/types/lib/time-travel/index.d.ts +9 -0
  284. package/dist/types/lib/time-travel/index.d.ts.map +1 -0
  285. package/dist/types/lib/time-travel/milestoneStops.d.ts +129 -0
  286. package/dist/types/lib/time-travel/milestoneStops.d.ts.map +1 -0
  287. package/dist/types/lib/trace-toolpack/debugPrompt.d.ts.map +1 -1
  288. package/dist/types/lib/trace-toolpack/traceToolpack.d.ts.map +1 -1
  289. package/dist/types/maps/engagement/lease.d.ts.map +1 -1
  290. package/dist/types/maps/engagement/parkCard.d.ts.map +1 -1
  291. package/dist/types/memory/beats/formatAsNarrative.d.ts.map +1 -1
  292. package/dist/types/memory/causal/loadSnapshot.d.ts.map +1 -1
  293. package/dist/types/memory/facts/formatFacts.d.ts.map +1 -1
  294. package/dist/types/memory/stages/formatDefault.d.ts.map +1 -1
  295. package/dist/types/recorders/observability/FlowchartRecorder.d.ts.map +1 -1
  296. package/dist/types/recorders/observability/recordRun.d.ts.map +1 -1
  297. package/dist/types/tool-providers/gatedTools.d.ts.map +1 -1
  298. package/dist/types/tool-providers/skillScopedTools.d.ts.map +1 -1
  299. package/package.json +4 -4
@@ -175,6 +175,9 @@ function atMountedCursor(args) {
175
175
  return stay && args.parked?.has(args.target) !== true;
176
176
  }
177
177
  exports.atMountedCursor = atMountedCursor;
178
+ // LENS · tool-result · persistent-history
179
+ // reads: the dispatchable roster ← `toolCalls.ts` · dispatchRoster: registry ∪ provider cache, filtered through scope.hiddenSkillIds
180
+ // law: may omit, never deny; every clause anchored to the call it was composed on.
178
181
  /**
179
182
  * What a call to a name nothing can dispatch gets back (9.86.0).
180
183
  *
@@ -229,6 +232,11 @@ function unknownToolResult(toolName, dispatchable) {
229
232
  : `${head} No tool name resolved to an implementation on that call.`;
230
233
  }
231
234
  exports.unknownToolResult = unknownToolResult;
235
+ // LENS · tool-result · persistent-history
236
+ // reads: hops/open ← deps.allowedSkillIds + deps.openSkillIds, each through scope.hiddenSkillIds via spoken()
237
+ // target class ← skillGraph.ts · classifySkillTarget, carried in, not re-derived
238
+ // menu/turnStartedBy ← scope.turnRoute (the routing verdict, whole, not a boolean)
239
+ // law: may omit, never deny; every clause anchored to the call it was composed on.
232
240
  /**
233
241
  * THE ONE COMPOSER of every `read_skill` refusal (9.86.0) — reachability,
234
242
  * posture and tree, from one set of inputs.
@@ -276,7 +284,7 @@ exports.unknownToolResult = unknownToolResult;
276
284
  * composers rather than re-deriving what it says.
277
285
  */
278
286
  function composeReadSkillRefusal(args) {
279
- const { requestedId, targetClass, cursorId, hops, openIds, isTree, posture, menuOffered, routedDecisively, } = args;
287
+ const { requestedId, targetClass, cursorId, hops, openIds, isTree, posture, menuOffered, turnStartedBy, cursorWithheld, } = args;
280
288
  const head = `read_skill("${requestedId}") was not granted on that call: `;
281
289
  // Open skills are the one list every arm may name: they are admitted from
282
290
  // every cursor and no posture governs them (the posture arm below is reached
@@ -307,10 +315,23 @@ function composeReadSkillRefusal(args) {
307
315
  return (`${head}this graph's 'guard' posture admits a routing pick only from the menu the ` +
308
316
  `framework offered, and '${requestedId}' was not admitted on that call.${openClause}`);
309
317
  }
318
+ // What the gate KNOWS about why no menu was outstanding is `TurnRoute.by`,
319
+ // and each value is a different finished fact. Nothing is asserted about
320
+ // how the cursor came to be where it was beyond that — the old tail,
321
+ // "Declared routes moved the cursor instead.", was composed for every
322
+ // value and was true of none of them in particular.
323
+ const startClause = turnStartedBy === 'entry' || turnStartedBy === 'intent'
324
+ ? " — the turn's start had already been resolved decisively"
325
+ : turnStartedBy === 'continuity'
326
+ ? ' — the cursor had been carried over from the previous turn'
327
+ : turnStartedBy === 'menu'
328
+ ? ' — the menu had already been resolved by an earlier pick'
329
+ : turnStartedBy === 'decider'
330
+ ? " — the menu had been resolved by the configured decider before the turn's first call"
331
+ : '';
310
332
  return (`${head}this graph's 'guard' posture admits a routing pick only while the framework ` +
311
333
  `has declared ambiguity, and no menu was outstanding when that call was made` +
312
- `${routedDecisively === true ? " — the turn's start had already been resolved decisively" : ''}` +
313
- `. Declared routes moved the cursor instead.${openClause}`);
334
+ `${startClause}.${openClause}`);
314
335
  }
315
336
  if (isTree === true) {
316
337
  return (`${head}this map is a decision tree. A tree routes by predicate on every iteration ` +
@@ -321,7 +342,14 @@ function composeReadSkillRefusal(args) {
321
342
  // this arm — 'self' is answered by the notice, 'hop' and 'open' are admitted
322
343
  // — and it is carried rather than re-derived so the sentence and the verdict
323
344
  // read the same classification.
324
- const from = cursorId !== undefined ? `'${cursorId}'` : "the turn's start";
345
+ // Three anchors, not two: a named cursor, a cursor this caller may not be
346
+ // told the name of, and a genuine cold start. The middle one used to print
347
+ // the raw id — the one name the description's own law withholds.
348
+ const from = cursorId !== undefined
349
+ ? `'${cursorId}'`
350
+ : cursorWithheld === true
351
+ ? 'the skill the cursor stood in'
352
+ : "the turn's start";
325
353
  // The gate reaches this arm only with `'unreachable'`; the weaker sentence is
326
354
  // for a caller that refused an admissible class for a reason of its own, and
327
355
  // it is deliberately not an invented explanation of one.
@@ -441,6 +469,9 @@ function buildToolCallsHandler(deps) {
441
469
  : (0, toolResultCap_js_1.capToolResult)(values.modelResult, { toolName, maxChars: max }).value,
442
470
  };
443
471
  };
472
+ // LENS · tool-result · persistent-history
473
+ // reads: the tool's own declared resultCeiling / resultColumns ← ../resultCeiling.ts · applyResultCeiling, one owner of the measurement and the sentence
474
+ // law: may omit, never deny; every clause anchored to the call it was composed on.
444
475
  /**
445
476
  * The tool's OWN refusing ceiling (9.20.0) — ONE implementation for every
446
477
  * dispatch door, applied at the execute boundary the moment the handler's
@@ -781,6 +812,10 @@ function buildToolCallsHandler(deps) {
781
812
  const step = (0, skillSteps_js_1.currentStepOf)(ptr, plan);
782
813
  return step ? { ptr, plan, step } : undefined;
783
814
  };
815
+ // LENS · tool-result · persistent-history
816
+ // reads: the advanced pointer ← pointerOf(scope.stepPointer), under `toolCalls.ts` · "── Step-procedure boundary (9.18.0)"; the sentence ← ../../lib/injection-engine/skillSteps.ts
817
+ // note: it overwrites the placeholder BEFORE the after-tool moment, so the record carries the authoritative words.
818
+ // law: may omit, never deny; every clause anchored to the call it was composed on.
784
819
  /**
785
820
  * `skip_step` bookkeeping — returns the AUTHORITATIVE result that
786
821
  * replaces the tool's placeholder (both channels, the read_skill-refusal
@@ -931,6 +966,11 @@ function buildToolCallsHandler(deps) {
931
966
  }
932
967
  const currentSkillId = scope.currentSkillId;
933
968
  const hops = deps.allowedSkillIds(currentSkillId);
969
+ const targetClass = (0, skillGraph_js_1.classifySkillTarget)({
970
+ ...(currentSkillId !== undefined && { cursor: currentSkillId }),
971
+ target,
972
+ hops,
973
+ });
934
974
  // ── A PROPOSAL TO THE CURSOR'S OWN SKILL IS A STAY (9.86.0) ──────
935
975
  // `makeReachableSkills` filters the cursor out of its own successor
936
976
  // set — right for a MOVE, and this judge read it as "not reachable"
@@ -943,11 +983,47 @@ function buildToolCallsHandler(deps) {
943
983
  // The event carries the existing `'accepted'` outcome plus an
944
984
  // ADDITIVE `stay: true`, deliberately not a new enum member: an
945
985
  // exhaustive switch over `outcome` in a consumer must keep compiling.
946
- if ((0, skillGraph_js_1.classifySkillTarget)({
947
- ...(currentSkillId !== undefined && { cursor: currentSkillId }),
948
- target,
949
- hops,
950
- }) === 'self') {
986
+ //
987
+ // A STAY COMPETES FOR THE SLOT LIKE ANY OTHER ACCEPTED PROPOSAL
988
+ // (9.86.1). The batch law is "first ACCEPTED proposal wins, later
989
+ // proposals to OTHER targets are superseded", and a stay is accepted
990
+ // — so a stay judged first holds the slot (with nothing written to
991
+ // `pendingToolTransition`, because a stay moves nothing) and a later
992
+ // sibling proposing a hop is `'superseded'` and lands in the
993
+ // `route_conflict` losers, exactly as two conflicting hops do. Before
994
+ // this the stay `continue`d past the bookkeeping, so the tool that
995
+ // judged its data first lost to whichever sibling came second, with
996
+ // two `'accepted'` events in one batch and no conflict on the record.
997
+ // The same law in the other order: a stay proposed AFTER an accepted
998
+ // hop is superseded by it, not accepted beside it.
999
+ if (targetClass === 'self') {
1000
+ if (state.winner !== undefined && state.winner.targetSkillId !== target) {
1001
+ state.losers.push({
1002
+ toolCallId: call.toolCallId,
1003
+ toolName: call.toolName,
1004
+ target,
1005
+ });
1006
+ (0, typedEmit_js_1.typedEmit)(scope, 'agentfootprint.tools.effect', {
1007
+ kind: 'propose-transition',
1008
+ outcome: 'superseded',
1009
+ toolName: call.toolName,
1010
+ toolCallId: call.toolCallId,
1011
+ iteration: call.iteration,
1012
+ targetSkillId: target,
1013
+ reason: effect.reason,
1014
+ supersededBy: 'earlier-proposal',
1015
+ });
1016
+ continue;
1017
+ }
1018
+ if (state.winner === undefined) {
1019
+ state.winner = {
1020
+ targetSkillId: target,
1021
+ toolName: call.toolName,
1022
+ toolCallId: call.toolCallId,
1023
+ reason: effect.reason,
1024
+ iteration: call.iteration,
1025
+ };
1026
+ }
951
1027
  (0, typedEmit_js_1.typedEmit)(scope, 'agentfootprint.tools.effect', {
952
1028
  kind: 'propose-transition',
953
1029
  outcome: 'accepted',
@@ -960,10 +1036,25 @@ function buildToolCallsHandler(deps) {
960
1036
  });
961
1037
  continue;
962
1038
  }
963
- if (!hops.includes(target)) {
1039
+ if (targetClass === 'unreachable') {
1040
+ // ── THE REFUSAL SPEAKS WITH THE FILTERED SETS (9.86.1) ──────────
1041
+ // This sentence is appended to the tool result the model reads and
1042
+ // rides the `tools.effect` payload, and it named the raw hop set and
1043
+ // the raw cursor — the leak the `read_skill` refusals closed one
1044
+ // function up. Same filter, same law: the hidden set the tools slot
1045
+ // resolved for this iteration, and OMIT, NEVER DENY — a hop set the
1046
+ // filter emptied composes no reachable clause rather than an empty
1047
+ // one. Admission is still judged on the raw `hops`.
1048
+ const hiddenIds = new Set(scope.hiddenSkillIds ?? []);
1049
+ const mayName = (id) => !hiddenIds.has(id);
1050
+ const reachable = (0, spokenIds_js_1.spoken)(hops, mayName);
1051
+ const from = currentSkillId === undefined
1052
+ ? 'the turn start'
1053
+ : mayName(currentSkillId)
1054
+ ? `'${currentSkillId}'`
1055
+ : 'the skill the cursor stood in';
964
1056
  refuse('propose-transition', `propose-transition → '${target}' was refused: '${target}' is not reachable from ` +
965
- `${currentSkillId !== undefined ? `'${currentSkillId}'` : 'the turn start'} per ` +
966
- `the graph's own law${hops.length > 0 ? ` (reachable: ${hops.join(', ')})` : ''}. The graph decides — a proposal is evidence, never authority.`, { targetSkillId: target, reason: effect.reason });
1057
+ `${from} per the graph's own law${reachable.named.length > 0 ? ` (reachable: ${reachable.named.join(', ')})` : ''}. The graph decides — a proposal is evidence, never authority.`, { targetSkillId: target, reason: effect.reason });
967
1058
  continue;
968
1059
  }
969
1060
  if (state.winner !== undefined && state.winner.targetSkillId !== target) {
@@ -1443,6 +1534,9 @@ function buildToolCallsHandler(deps) {
1443
1534
  // which owns the scope, the store and the emit channel — OVERWRITES its
1444
1535
  // result with the description snapshot (or the teaching refusal), so
1445
1536
  // governance rules and the caps compose over what the model will read.
1537
+ // LENS · tool-result · persistent-history
1538
+ // reads: the artifact's description snapshot ← the ArtifactStore port (src/artifacts/present.ts, the owner of head/list)
1539
+ // law: may omit, never deny; every clause anchored to the call it was composed on.
1446
1540
  const applyPresent = async (scope, call) => {
1447
1541
  const store = deps.artifactStore;
1448
1542
  if (store === undefined) {
@@ -1623,6 +1717,9 @@ function buildToolCallsHandler(deps) {
1623
1717
  const parkedNow = (scope) => deps.engagementPlan === undefined
1624
1718
  ? undefined
1625
1719
  : (0, types_js_2.parkedMemberIds)(deps.engagementPlan, scope.mapEngagement);
1720
+ // FOLD · the one owner of "which tool names this caller may be told exist" for one iteration
1721
+ // consumers read this and never re-derive it: `toolCalls.ts` · unknownToolResult, called at both dispatch doors
1722
+ // detached: yes — a fresh SpokenIds; the named half leaves through spoken().
1626
1723
  /**
1627
1724
  * Every name `lookupTool` would resolve, in resolution order, through the
1628
1725
  * role filter (9.86.0) — the roster `unknownToolResult` names.
@@ -2103,6 +2200,12 @@ function buildToolCallsHandler(deps) {
2103
2200
  ...(decision.rationale !== undefined && { rationale: decision.rationale }),
2104
2201
  ...(decision.reason !== undefined && { reason: decision.reason }),
2105
2202
  });
2203
+ // LENS · tool-result · persistent-history
2204
+ // reads: the checker's own words ← decision.tellLLM ?? decision.rationale (an AUTHORITY omission: the rule space is never named)
2205
+ // known gap: the generic fallback anchors a per-call refusal to the whole run and is on the record as
2206
+ // unrepaired in test/modelFacingScan.test.ts · `LEDGER`, under this file's own key.
2207
+ // Do not widen it here without that test.
2208
+ // law: may omit, never deny; every clause anchored to the call it was composed on.
2106
2209
  if (decision.result === 'deny') {
2107
2210
  denied = true;
2108
2211
  // Deny default keeps the existing v2.4 shape (carries
@@ -2785,6 +2888,15 @@ function buildToolCallsHandler(deps) {
2785
2888
  // "nothing reachable may be named", and it used to assert the first.
2786
2889
  const hopsSpoken = (0, spokenIds_js_1.spoken)(hops, mayName);
2787
2890
  const openSpoken = (0, spokenIds_js_1.spoken)(openAll, mayName);
2891
+ // The cursor through the SAME filter (9.86.1). The description
2892
+ // withholds a hidden cursor's name and every refusal below printed
2893
+ // it raw in two clauses; `cursorWithheld` keeps the sentence's
2894
+ // anchor honest ("the skill the cursor stood in") without the id.
2895
+ const cursorSpoken = currentSkillId === undefined
2896
+ ? {}
2897
+ : mayName(currentSkillId)
2898
+ ? { cursorId: currentSkillId }
2899
+ : { cursorWithheld: true };
2788
2900
  const hopsNamed = hopsSpoken.named;
2789
2901
  const openNamed = openSpoken.named;
2790
2902
  // The ONE owner of "is this target the cursor?" — the same function
@@ -2902,7 +3014,7 @@ function buildToolCallsHandler(deps) {
2902
3014
  result = composeReadSkillRefusal({
2903
3015
  requestedId: reqId,
2904
3016
  targetClass,
2905
- ...(currentSkillId !== undefined && { cursorId: currentSkillId }),
3017
+ ...cursorSpoken,
2906
3018
  hops: hopsSpoken,
2907
3019
  openIds: openSpoken,
2908
3020
  ...(deps.skillGraphIsTree === true && { isTree: true }),
@@ -2939,7 +3051,7 @@ function buildToolCallsHandler(deps) {
2939
3051
  result = composeReadSkillRefusal({
2940
3052
  requestedId: reqId,
2941
3053
  targetClass,
2942
- ...(currentSkillId !== undefined && { cursorId: currentSkillId }),
3054
+ ...cursorSpoken,
2943
3055
  // No hop is named under a posture, and the graph's hop set
2944
3056
  // is not this arm's subject — `held: false` is the honest
2945
3057
  // shape, not a claim that nothing was reachable (this arm
@@ -2948,9 +3060,9 @@ function buildToolCallsHandler(deps) {
2948
3060
  openIds: openSpoken,
2949
3061
  posture: deps.skillStrictness,
2950
3062
  ...(menuNamed !== undefined && { menuOffered: menuNamed }),
2951
- ...((turnRoute?.by === 'intent' || turnRoute?.by === 'entry') && {
2952
- routedDecisively: true,
2953
- }),
3063
+ // The whole verdict, not a boolean derived from two of its
3064
+ // six values: the composer says one past fact per value.
3065
+ ...(turnRoute !== undefined && { turnStartedBy: turnRoute.by }),
2954
3066
  });
2955
3067
  (0, typedEmit_js_1.typedEmit)(scope, 'agentfootprint.skill.rejected', {
2956
3068
  requestedId: reqId,
@@ -3396,10 +3508,14 @@ function buildToolCallsHandler(deps) {
3396
3508
  // silently invents a decision, for the same reason it never silently
3397
3509
  // drops one.
3398
3510
  error = true;
3511
+ // A past fact about the resumed call, not a forecast about the
3512
+ // turn (9.86.1): "cannot be retried this turn … Answer without it,
3513
+ // or finish" was a prediction plus a standing order on a result
3514
+ // that is re-read on every later call.
3399
3515
  result =
3400
- `tool '${toolName}' was not executed and cannot be retried this turn: it declares ` +
3401
- `its own checkIn consent gate, that gate trips for these arguments, and a resumed ` +
3402
- `dispatch has no second checkpoint to ask on. Answer without it, or finish. (To ` +
3516
+ `tool '${toolName}' was not executed on that call, and the resumed dispatch had ` +
3517
+ `no second checkpoint to retry it on: it declares its own checkIn consent gate, ` +
3518
+ `and that gate tripped for those arguments. (To ` +
3403
3519
  `the agent's author: the middleware '${askedBy}' and the tool's checkIn ask ` +
3404
3520
  `different questions — one is the rule's, one is the tool's with the evidence ` +
3405
3521
  `pack attached — so approving one is not answering the other. Keep one gate for ` +