agentfootprint 9.100.0 → 9.102.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 (183) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +343 -0
  3. package/CLAUDE.md +1 -1
  4. package/README.md +1 -0
  5. package/ai-instructions/claude-code/SKILL.md +1 -1
  6. package/dist/core/Agent.js +207 -2
  7. package/dist/core/Agent.js.map +1 -1
  8. package/dist/core/agent/AgentBuilder.js +118 -2
  9. package/dist/core/agent/AgentBuilder.js.map +1 -1
  10. package/dist/core/agent/buildAgentChart.js +11 -0
  11. package/dist/core/agent/buildAgentChart.js.map +1 -1
  12. package/dist/core/agent/buildDynamicAgentChart.js +22 -0
  13. package/dist/core/agent/buildDynamicAgentChart.js.map +1 -1
  14. package/dist/core/agent/buildToolRegistry.js +38 -0
  15. package/dist/core/agent/buildToolRegistry.js.map +1 -1
  16. package/dist/core/agent/findings/ledger.js +261 -0
  17. package/dist/core/agent/findings/ledger.js.map +1 -0
  18. package/dist/core/agent/findings/offer.js +179 -0
  19. package/dist/core/agent/findings/offer.js.map +1 -0
  20. package/dist/core/agent/findings/reserved.js +465 -0
  21. package/dist/core/agent/findings/reserved.js.map +1 -0
  22. package/dist/core/agent/findings/serve.js +400 -0
  23. package/dist/core/agent/findings/serve.js.map +1 -0
  24. package/dist/core/agent/findings/types.js +56 -0
  25. package/dist/core/agent/findings/types.js.map +1 -0
  26. package/dist/core/agent/stages/callLLM.js +78 -10
  27. package/dist/core/agent/stages/callLLM.js.map +1 -1
  28. package/dist/core/agent/stages/outputRetry.js +5 -0
  29. package/dist/core/agent/stages/outputRetry.js.map +1 -1
  30. package/dist/core/agent/stages/route.js +71 -12
  31. package/dist/core/agent/stages/route.js.map +1 -1
  32. package/dist/core/agent/stages/seed.js +33 -1
  33. package/dist/core/agent/stages/seed.js.map +1 -1
  34. package/dist/core/agent/stages/toolCalls.js +84 -11
  35. package/dist/core/agent/stages/toolCalls.js.map +1 -1
  36. package/dist/core/agent/stages/window.js +110 -10
  37. package/dist/core/agent/stages/window.js.map +1 -1
  38. package/dist/core/agent/window/index.js +3 -1
  39. package/dist/core/agent/window/index.js.map +1 -1
  40. package/dist/core/agent/window/ledgerFactPins.js +200 -0
  41. package/dist/core/agent/window/ledgerFactPins.js.map +1 -0
  42. package/dist/core/agent/window/turns.js +45 -11
  43. package/dist/core/agent/window/turns.js.map +1 -1
  44. package/dist/core/runCheckpoint.js +64 -1
  45. package/dist/core/runCheckpoint.js.map +1 -1
  46. package/dist/core/slots/buildToolsSlot.js +35 -1
  47. package/dist/core/slots/buildToolsSlot.js.map +1 -1
  48. package/dist/esm/core/Agent.d.ts +55 -0
  49. package/dist/esm/core/Agent.js +207 -2
  50. package/dist/esm/core/Agent.js.map +1 -1
  51. package/dist/esm/core/agent/AgentBuilder.d.ts +65 -0
  52. package/dist/esm/core/agent/AgentBuilder.js +118 -2
  53. package/dist/esm/core/agent/AgentBuilder.js.map +1 -1
  54. package/dist/esm/core/agent/buildAgentChart.d.ts +14 -0
  55. package/dist/esm/core/agent/buildAgentChart.js +11 -0
  56. package/dist/esm/core/agent/buildAgentChart.js.map +1 -1
  57. package/dist/esm/core/agent/buildDynamicAgentChart.js +22 -0
  58. package/dist/esm/core/agent/buildDynamicAgentChart.js.map +1 -1
  59. package/dist/esm/core/agent/buildToolRegistry.d.ts +7 -0
  60. package/dist/esm/core/agent/buildToolRegistry.js +38 -0
  61. package/dist/esm/core/agent/buildToolRegistry.js.map +1 -1
  62. package/dist/esm/core/agent/findings/ledger.d.ts +105 -0
  63. package/dist/esm/core/agent/findings/ledger.js +254 -0
  64. package/dist/esm/core/agent/findings/ledger.js.map +1 -0
  65. package/dist/esm/core/agent/findings/offer.d.ts +112 -0
  66. package/dist/esm/core/agent/findings/offer.js +171 -0
  67. package/dist/esm/core/agent/findings/offer.js.map +1 -0
  68. package/dist/esm/core/agent/findings/reserved.d.ts +127 -0
  69. package/dist/esm/core/agent/findings/reserved.js +457 -0
  70. package/dist/esm/core/agent/findings/reserved.js.map +1 -0
  71. package/dist/esm/core/agent/findings/serve.d.ts +149 -0
  72. package/dist/esm/core/agent/findings/serve.js +397 -0
  73. package/dist/esm/core/agent/findings/serve.js.map +1 -0
  74. package/dist/esm/core/agent/findings/types.d.ts +179 -0
  75. package/dist/esm/core/agent/findings/types.js +53 -0
  76. package/dist/esm/core/agent/findings/types.js.map +1 -0
  77. package/dist/esm/core/agent/stages/callLLM.d.ts +32 -0
  78. package/dist/esm/core/agent/stages/callLLM.js +78 -10
  79. package/dist/esm/core/agent/stages/callLLM.js.map +1 -1
  80. package/dist/esm/core/agent/stages/outputRetry.js +5 -0
  81. package/dist/esm/core/agent/stages/outputRetry.js.map +1 -1
  82. package/dist/esm/core/agent/stages/route.d.ts +8 -1
  83. package/dist/esm/core/agent/stages/route.js +71 -12
  84. package/dist/esm/core/agent/stages/route.js.map +1 -1
  85. package/dist/esm/core/agent/stages/seed.d.ts +28 -0
  86. package/dist/esm/core/agent/stages/seed.js +33 -1
  87. package/dist/esm/core/agent/stages/seed.js.map +1 -1
  88. package/dist/esm/core/agent/stages/toolCalls.d.ts +17 -0
  89. package/dist/esm/core/agent/stages/toolCalls.js +82 -9
  90. package/dist/esm/core/agent/stages/toolCalls.js.map +1 -1
  91. package/dist/esm/core/agent/stages/window.d.ts +22 -0
  92. package/dist/esm/core/agent/stages/window.js +111 -11
  93. package/dist/esm/core/agent/stages/window.js.map +1 -1
  94. package/dist/esm/core/agent/types.d.ts +113 -0
  95. package/dist/esm/core/agent/window/index.d.ts +1 -0
  96. package/dist/esm/core/agent/window/index.js +1 -0
  97. package/dist/esm/core/agent/window/index.js.map +1 -1
  98. package/dist/esm/core/agent/window/ledgerFactPins.d.ts +147 -0
  99. package/dist/esm/core/agent/window/ledgerFactPins.js +194 -0
  100. package/dist/esm/core/agent/window/ledgerFactPins.js.map +1 -0
  101. package/dist/esm/core/agent/window/strategy.d.ts +25 -0
  102. package/dist/esm/core/agent/window/turns.d.ts +25 -0
  103. package/dist/esm/core/agent/window/turns.js +45 -11
  104. package/dist/esm/core/agent/window/turns.js.map +1 -1
  105. package/dist/esm/core/agent/window/types.d.ts +64 -0
  106. package/dist/esm/core/runCheckpoint.d.ts +27 -1
  107. package/dist/esm/core/runCheckpoint.js +64 -1
  108. package/dist/esm/core/runCheckpoint.js.map +1 -1
  109. package/dist/esm/core/slots/buildToolsSlot.d.ts +20 -0
  110. package/dist/esm/core/slots/buildToolsSlot.js +35 -1
  111. package/dist/esm/core/slots/buildToolsSlot.js.map +1 -1
  112. package/dist/esm/events/payloads.d.ts +65 -0
  113. package/dist/esm/events/registry.d.ts +7 -1
  114. package/dist/esm/events/registry.js +6 -0
  115. package/dist/esm/events/registry.js.map +1 -1
  116. package/dist/esm/events/types.d.ts +3 -1
  117. package/dist/esm/index.d.ts +2 -1
  118. package/dist/esm/index.js +6 -0
  119. package/dist/esm/index.js.map +1 -1
  120. package/dist/esm/lib/time-travel/servedView.js +54 -10
  121. package/dist/esm/lib/time-travel/servedView.js.map +1 -1
  122. package/dist/events/registry.js +6 -0
  123. package/dist/events/registry.js.map +1 -1
  124. package/dist/index.js +11 -4
  125. package/dist/index.js.map +1 -1
  126. package/dist/lib/time-travel/servedView.js +54 -10
  127. package/dist/lib/time-travel/servedView.js.map +1 -1
  128. package/dist/types/core/Agent.d.ts +55 -0
  129. package/dist/types/core/Agent.d.ts.map +1 -1
  130. package/dist/types/core/agent/AgentBuilder.d.ts +65 -0
  131. package/dist/types/core/agent/AgentBuilder.d.ts.map +1 -1
  132. package/dist/types/core/agent/buildAgentChart.d.ts +14 -0
  133. package/dist/types/core/agent/buildAgentChart.d.ts.map +1 -1
  134. package/dist/types/core/agent/buildDynamicAgentChart.d.ts.map +1 -1
  135. package/dist/types/core/agent/buildToolRegistry.d.ts +7 -0
  136. package/dist/types/core/agent/buildToolRegistry.d.ts.map +1 -1
  137. package/dist/types/core/agent/findings/ledger.d.ts +106 -0
  138. package/dist/types/core/agent/findings/ledger.d.ts.map +1 -0
  139. package/dist/types/core/agent/findings/offer.d.ts +113 -0
  140. package/dist/types/core/agent/findings/offer.d.ts.map +1 -0
  141. package/dist/types/core/agent/findings/reserved.d.ts +128 -0
  142. package/dist/types/core/agent/findings/reserved.d.ts.map +1 -0
  143. package/dist/types/core/agent/findings/serve.d.ts +150 -0
  144. package/dist/types/core/agent/findings/serve.d.ts.map +1 -0
  145. package/dist/types/core/agent/findings/types.d.ts +180 -0
  146. package/dist/types/core/agent/findings/types.d.ts.map +1 -0
  147. package/dist/types/core/agent/stages/callLLM.d.ts +32 -0
  148. package/dist/types/core/agent/stages/callLLM.d.ts.map +1 -1
  149. package/dist/types/core/agent/stages/outputRetry.d.ts.map +1 -1
  150. package/dist/types/core/agent/stages/route.d.ts +8 -1
  151. package/dist/types/core/agent/stages/route.d.ts.map +1 -1
  152. package/dist/types/core/agent/stages/seed.d.ts +28 -0
  153. package/dist/types/core/agent/stages/seed.d.ts.map +1 -1
  154. package/dist/types/core/agent/stages/toolCalls.d.ts +17 -0
  155. package/dist/types/core/agent/stages/toolCalls.d.ts.map +1 -1
  156. package/dist/types/core/agent/stages/window.d.ts +22 -0
  157. package/dist/types/core/agent/stages/window.d.ts.map +1 -1
  158. package/dist/types/core/agent/types.d.ts +113 -0
  159. package/dist/types/core/agent/types.d.ts.map +1 -1
  160. package/dist/types/core/agent/window/index.d.ts +1 -0
  161. package/dist/types/core/agent/window/index.d.ts.map +1 -1
  162. package/dist/types/core/agent/window/ledgerFactPins.d.ts +148 -0
  163. package/dist/types/core/agent/window/ledgerFactPins.d.ts.map +1 -0
  164. package/dist/types/core/agent/window/strategy.d.ts +25 -0
  165. package/dist/types/core/agent/window/strategy.d.ts.map +1 -1
  166. package/dist/types/core/agent/window/turns.d.ts +25 -0
  167. package/dist/types/core/agent/window/turns.d.ts.map +1 -1
  168. package/dist/types/core/agent/window/types.d.ts +64 -0
  169. package/dist/types/core/agent/window/types.d.ts.map +1 -1
  170. package/dist/types/core/runCheckpoint.d.ts +27 -1
  171. package/dist/types/core/runCheckpoint.d.ts.map +1 -1
  172. package/dist/types/core/slots/buildToolsSlot.d.ts +20 -0
  173. package/dist/types/core/slots/buildToolsSlot.d.ts.map +1 -1
  174. package/dist/types/events/payloads.d.ts +65 -0
  175. package/dist/types/events/payloads.d.ts.map +1 -1
  176. package/dist/types/events/registry.d.ts +7 -1
  177. package/dist/types/events/registry.d.ts.map +1 -1
  178. package/dist/types/events/types.d.ts +3 -1
  179. package/dist/types/events/types.d.ts.map +1 -1
  180. package/dist/types/index.d.ts +2 -1
  181. package/dist/types/index.d.ts.map +1 -1
  182. package/dist/types/lib/time-travel/servedView.d.ts.map +1 -1
  183. package/package.json +2 -1
@@ -142,6 +142,36 @@ const registry_js_1 = require("../thinking/registry.js");
142
142
  // Public types (AgentOptions, AgentInput, AgentOutput) extracted to
143
143
  // ./agent/types.ts and re-exported above (v2.11.1).
144
144
  // AgentState extracted to ./agent/types.ts (v2.11.1).
145
+ /**
146
+ * The ledger-fact hold's default ceiling (9.102.0): how many fact turns the
147
+ * window holds beyond `keepRecentTurns` when `.findings()` and a window
148
+ * strategy are both configured and nobody named a number. Resolved in the
149
+ * constructor, ONCE, and threaded to `buildWindowStage` as a plain number —
150
+ * the stage applies no default of its own (absent = unarmed = no hold), so a
151
+ * reader has one place to look. `window/options.ts ·
152
+ * DEFAULT_KEEP_LAST_TOOL_RESULTS` is the pin's twin of this constant.
153
+ */
154
+ const DEFAULT_KEEP_LEDGER_FACTS = 4;
155
+ /**
156
+ * Validate the `keepLedgerFacts` dial — `window/options.ts ·
157
+ * requireKeepLastToolResults`'s twin: the same rule, the same moment.
158
+ * Refused at construction, never mid-run.
159
+ */
160
+ function requireKeepLedgerFacts(value, label) {
161
+ if (value === false)
162
+ return;
163
+ if (!Number.isInteger(value) || value < 0) {
164
+ throw new Error(`${label}: keepLedgerFacts must be a whole number >= 0, or false, got ` +
165
+ `${String(value)}. It is how many fact turns the window holds beyond ` +
166
+ `keepRecentTurns under .findings(); 0 and false both switch the hold off.`);
167
+ }
168
+ }
169
+ /** `false` → `0`; a number as named; nothing named → the default. */
170
+ function resolveKeepLedgerFacts(named) {
171
+ if (named === false)
172
+ return 0;
173
+ return named ?? DEFAULT_KEEP_LEDGER_FACTS;
174
+ }
145
175
  class Agent extends RunnerBase_js_1.RunnerBase {
146
176
  name;
147
177
  id;
@@ -244,6 +274,17 @@ class Agent extends RunnerBase_js_1.RunnerBase {
244
274
  contextBudget;
245
275
  permissionChecker;
246
276
  toolArgValidation;
277
+ /** See AgentOptions.findings (9.101.0). Set by `.findings()` and undefined
278
+ * on every other agent — the one value every findings gate below is
279
+ * conditioned on, so an unarmed agent hands each stage exactly the deps
280
+ * it always did. `serve` is threaded to seed (the run constant
281
+ * `findingsServe`) and to call-llm (`findingsServe` in its deps) on an
282
+ * armed agent only. `keepLedgerFacts` is resolved once, here in the
283
+ * constructor (this door over `AgentOptions.keepLedgerFacts`), into the
284
+ * `keepLedgerFacts` field below and threaded to the window stage on an
285
+ * armed agent with a window, where `stages/window.ts · buildWindowStage`
286
+ * spends it as the `'ledger-fact'` pin ceiling. */
287
+ findingsOptions;
247
288
  /** The opt-in tool-result ceiling in characters (9.11.0). Absent → results
248
289
  * are never measured. See {@link AgentOptions.maxToolResultChars}. */
249
290
  maxToolResultChars;
@@ -306,6 +347,13 @@ class Agent extends RunnerBase_js_1.RunnerBase {
306
347
  /** The last-tool-result pin (9.57.0) — set only when the operator named a
307
348
  * value other than the default 2. See AgentOptions.keepLastToolResults. */
308
349
  keepLastToolResults;
350
+ /** The ledger-fact hold's ceiling (9.102.0), RESOLVED — set exactly when
351
+ * `.findings()` is on: `findings({ keepLedgerFacts })` over
352
+ * `AgentOptions.keepLedgerFacts`, `false` → `0`, nothing named →
353
+ * `DEFAULT_KEEP_LEDGER_FACTS`. Undefined on every unarmed agent, so the
354
+ * thread into the window stage reads as the decision it is. See
355
+ * AgentOptions.keepLedgerFacts. */
356
+ keepLedgerFacts;
309
357
  /** See AgentOptions.integrityPosture (9.60.0). Default 'observe'. */
310
358
  integrityPosture = 'observe';
311
359
  /**
@@ -427,6 +475,10 @@ class Agent extends RunnerBase_js_1.RunnerBase {
427
475
  * destroyed by the act of continuing, which is the one thing retention
428
476
  * exists to prevent. Cleared on first read, exactly like the history. */
429
477
  pendingResumeFolded;
478
+ /** Its sibling for the findings ledger (9.101.0) — the model's standings
479
+ * on results this process never saw, carried by the checkpoint and
480
+ * restored as a stored record. Cleared on first read, like the history. */
481
+ pendingResumeFindingsLedger;
430
482
  /** The last completed run's final answer — see `checkpoint()` for why it is
431
483
  * kept here rather than read back from the recording. Undefined after a run
432
484
  * that failed or paused. */
@@ -605,6 +657,8 @@ class Agent extends RunnerBase_js_1.RunnerBase {
605
657
  this.permissionChecker = opts.permissionChecker;
606
658
  if (opts.toolArgValidation !== undefined)
607
659
  this.toolArgValidation = opts.toolArgValidation;
660
+ if (opts.findings !== undefined)
661
+ this.findingsOptions = opts.findings;
608
662
  // The tool-result ceiling (9.11.0). Refused HERE, naming the value, rather
609
663
  // than at the first tool call of the first run — a dial that cannot cap
610
664
  // anything is a configuration mistake, not a runtime condition.
@@ -672,6 +726,35 @@ class Agent extends RunnerBase_js_1.RunnerBase {
672
726
  (0, options_js_1.requireKeepLastToolResults)(opts.keepLastToolResults, 'Agent');
673
727
  this.keepLastToolResults = opts.keepLastToolResults;
674
728
  }
729
+ // Its content-aware sibling (9.102.0). The top-level door is refused
730
+ // HERE, whether or not `.findings()` is on — a dial that is silently
731
+ // ignored is a configuration mistake, not a runtime condition (the
732
+ // `.findings()` door was refused by the builder). The value is resolved
733
+ // ONCE, under the arm only: the `.findings()` door wins when both are
734
+ // given, `false` is `0`, nothing named is the default. Without
735
+ // `.findings()` there is no ledger to hold facts from, so the option is
736
+ // accepted and does nothing — the keepLastToolResults-without-a-window
737
+ // precedent.
738
+ if (opts.keepLedgerFacts !== undefined)
739
+ requireKeepLedgerFacts(opts.keepLedgerFacts, 'Agent');
740
+ if (this.findingsOptions !== undefined) {
741
+ // The ledger needs the tools slot recomposed every call: from the second
742
+ // call on, the served `_findings` property binds the ids the model may
743
+ // name (`findings/offer.ts · offeredResultIds`, bound at the Tools
744
+ // mount) — and on a hosted model that binding is what makes a standing
745
+ // resolve at all (docs/design/2026-09-findings-ledger-real-model.md).
746
+ // `reactMode: 'classic'` selects the Tools branch on turn 1 only, so an
747
+ // armed classic agent would serve the offer-less base on every call and
748
+ // file every standing as `unknownId`. Refused loud, here at build, the
749
+ // `AgentBuilder.selfExplain` twin — never a silent degrade.
750
+ if (this.reactMode === 'classic') {
751
+ throw new Error("Agent: .findings() requires per-iteration slot recomposition — reactMode 'classic' " +
752
+ 'caches the tools slot on turn 1, so the ids the model may name (bound into every ' +
753
+ 'served tool schema from the second call on) would never reach it and every standing ' +
754
+ "would file as unknownId. Use the default 'dynamic' mode (or 'dynamic-grouped').");
755
+ }
756
+ this.keepLedgerFacts = resolveKeepLedgerFacts(this.findingsOptions.keepLedgerFacts ?? opts.keepLedgerFacts);
757
+ }
675
758
  // Refused at construction, never mid-run — a misspelled posture that was
676
759
  // ignored would leave the liveness theorems switched off in an agent
677
760
  // that believes they are on (the concurrency-mode precedent).
@@ -1356,7 +1439,10 @@ class Agent extends RunnerBase_js_1.RunnerBase {
1356
1439
  this.conversationOwner(),
1357
1440
  // …and the same graph cursor (SG-C), from the same snapshot reader —
1358
1441
  // one reader, two carriers, so neither can lose what the other keeps.
1359
- this.continuityCursorOf(this.getLastSnapshot()?.sharedState), this.evidenceRecoveryOf(this.getLastSnapshot()?.sharedState));
1442
+ this.continuityCursorOf(this.getLastSnapshot()?.sharedState), this.evidenceRecoveryOf(this.getLastSnapshot()?.sharedState),
1443
+ // …and the findings ledger (9.101.0), from the same snapshot reader
1444
+ // `checkpoint()` uses — one reader, two carriers.
1445
+ this.findingsLedgerOf(this.getLastSnapshot()?.sharedState));
1360
1446
  throw new runCheckpoint_js_1.RunCheckpointError(cause, checkpoint);
1361
1447
  }
1362
1448
  throw cause;
@@ -1377,6 +1463,7 @@ class Agent extends RunnerBase_js_1.RunnerBase {
1377
1463
  // nobody asked it to. One run, one continuation.
1378
1464
  this.pendingResumeHistory = undefined;
1379
1465
  this.pendingResumeFolded = undefined;
1466
+ this.pendingResumeFindingsLedger = undefined;
1380
1467
  this.pendingResumeSkillCursor = undefined;
1381
1468
  this.pendingEvidenceRecovery = undefined;
1382
1469
  }
@@ -1783,6 +1870,7 @@ class Agent extends RunnerBase_js_1.RunnerBase {
1783
1870
  const owner = this.conversationOwner();
1784
1871
  const skillCursor = this.continuityCursorOf(state);
1785
1872
  const evidenceRecovery = this.evidenceRecoveryOf(state);
1873
+ const findingsLedger = this.findingsLedgerOf(state);
1786
1874
  return {
1787
1875
  version: 1,
1788
1876
  runId: this.currentRunContext.runId,
@@ -1802,6 +1890,9 @@ class Agent extends RunnerBase_js_1.RunnerBase {
1802
1890
  // exact byte shape.
1803
1891
  ...(skillCursor !== undefined && { skillCursor }),
1804
1892
  ...(evidenceRecovery !== undefined && { evidenceRecovery }),
1893
+ // The model's standings (9.101.0) — absent unless the run recorded any,
1894
+ // by the `folded` rule: an optional key, never a format change.
1895
+ ...(findingsLedger !== undefined && { findingsLedger }),
1805
1896
  };
1806
1897
  }
1807
1898
  /** Both checkpoint doors keep the repair budget separately from conversation text. */
@@ -1855,6 +1946,20 @@ class Agent extends RunnerBase_js_1.RunnerBase {
1855
1946
  return undefined;
1856
1947
  return structuredClone(spans);
1857
1948
  }
1949
+ /**
1950
+ * The findings ledger for a checkpoint (9.101.0) — `foldedSpansOf`'s twin:
1951
+ * one reader for `checkpoint()` and the crash carrier, `undefined` when the
1952
+ * run recorded no rows (so the key stays absent), and a detached copy
1953
+ * otherwise, never a reference into the live heap.
1954
+ *
1955
+ * @internal
1956
+ */
1957
+ findingsLedgerOf(state) {
1958
+ const ledger = state?.findingsLedger;
1959
+ if (ledger === undefined || ledger.length === 0)
1960
+ return undefined;
1961
+ return structuredClone(ledger);
1962
+ }
1858
1963
  /**
1859
1964
  * The two owner facts every conversation carrier stamps — who the run was
1860
1965
  * for, and which agent ran it (9.2.0).
@@ -1901,6 +2006,11 @@ class Agent extends RunnerBase_js_1.RunnerBase {
1901
2006
  // and `undefined` is the right answer there — it means "this conversation
1902
2007
  // recorded no folds", which is exactly true.
1903
2008
  this.pendingResumeFolded = cp.folded;
2009
+ // The findings ledger beside it (9.101.0). Stashed whether or not THIS
2010
+ // agent is armed: seed restores it only under `.findings()` (the deps
2011
+ // gate), and an unarmed continuation consumes and ignores it — exactly
2012
+ // like a `folded` field on an agent that never folds.
2013
+ this.pendingResumeFindingsLedger = cp.findingsLedger;
1904
2014
  // The conversation's skill cursor (SG-C). Stashed unconditionally —
1905
2015
  // whether it is HONORED is seed's `restoreSkillCursor` gate, which reads
1906
2016
  // the mounted graph's `continuity` declaration; a checkpoint written by a
@@ -2460,6 +2570,19 @@ class Agent extends RunnerBase_js_1.RunnerBase {
2460
2570
  getRunContext: getRunCtx,
2461
2571
  }));
2462
2572
  }
2573
+ // Same wiring for `agentfootprint.findings.*` (9.101.0) — the ledger's two
2574
+ // events, filed by `recordFindings` on scope. Attached only under
2575
+ // `.findings()`: an unarmed agent gains no bridge, no listener and no
2576
+ // per-event work, and `agent.on('agentfootprint.findings.*')` can only
2577
+ // ever fire on an agent that could have filed a row.
2578
+ if (this.findingsOptions !== undefined) {
2579
+ attachObserver(new EmitBridge_js_1.EmitBridge({
2580
+ id: 'agentfootprint.findings-bridge',
2581
+ prefix: 'agentfootprint.findings.',
2582
+ dispatcher,
2583
+ getRunContext: getRunCtx,
2584
+ }));
2585
+ }
2463
2586
  for (const r of this.attachedRecorders) {
2464
2587
  // A recorder's OWN `delivery` field is more specific than the
2465
2588
  // agent-level default — footprintjs's options bag would override the
@@ -2797,6 +2920,34 @@ class Agent extends RunnerBase_js_1.RunnerBase {
2797
2920
  const state = this.getLastSnapshot()?.sharedState;
2798
2921
  return state?.unsupportedValues;
2799
2922
  }
2923
+ /**
2924
+ * The last run's findings ledger (9.101.0) — the model's OWN standings on
2925
+ * its tool results, as `.findings()` recorded them: `basis` rows (what a
2926
+ * call was for, declared before it ran), `standing` rows (`fact` with the
2927
+ * assertions stood on, `open`, `ruled-out`, `noise` — the LAST row per
2928
+ * `toolCallId` is the current reading; earlier ones are quotable history)
2929
+ * and `conflict` rows (two stood-on readings that disagree, witnesses by
2930
+ * identity). Undefined when the agent has no `.findings()` OR the model
2931
+ * declared nothing — never an empty array standing in for "no findings",
2932
+ * and an id with no standing row is undeclared, never `open`.
2933
+ *
2934
+ * Detached from the execution record (`structuredClone`), so a caller may
2935
+ * keep or mutate it without touching the run's state.
2936
+ *
2937
+ * @example
2938
+ * ```ts
2939
+ * await agent.run({ message: 'which port is down?' });
2940
+ * const current = new Map<string, string>();
2941
+ * for (const row of agent.findings() ?? []) {
2942
+ * if (row.kind === 'standing') current.set(row.toolCallId, row.standing);
2943
+ * }
2944
+ * ```
2945
+ */
2946
+ findings() {
2947
+ const ledger = this.getLastSnapshot()?.sharedState
2948
+ ?.findingsLedger;
2949
+ return ledger === undefined ? undefined : structuredClone(ledger);
2950
+ }
2800
2951
  /** The last run's answer checks, detached from its execution record.
2801
2952
  * Undefined means no terminal validation ran, never an implicit pass. */
2802
2953
  answerValidation() {
@@ -3049,6 +3200,20 @@ class Agent extends RunnerBase_js_1.RunnerBase {
3049
3200
  this.pendingResumeFolded = undefined;
3050
3201
  return f;
3051
3202
  },
3203
+ // The findings ledger (9.101.0): the arm, the serve mode it puts on the
3204
+ // record (the `forcedOutputToolName` precedent — a build-time constant
3205
+ // the rebuild reads instead of the receipt), and the continued
3206
+ // conversation's rows, all under the one gate — an unarmed agent hands
3207
+ // seed exactly the deps object it always did.
3208
+ ...(this.findingsOptions !== undefined && {
3209
+ findings: true,
3210
+ findingsServe: this.findingsOptions.serve ?? 'ledger-and-facts',
3211
+ consumePendingResumeFindingsLedger: () => {
3212
+ const l = this.pendingResumeFindingsLedger;
3213
+ this.pendingResumeFindingsLedger = undefined;
3214
+ return l;
3215
+ },
3216
+ }),
3052
3217
  // The conversation's inherited skill cursor (SG-C). Consumed (cleared)
3053
3218
  // on every run; HONORED only when the mounted graph declared
3054
3219
  // `continuity: 'conversation'` — the same one-option-one-behavior gate
@@ -3109,6 +3274,9 @@ class Agent extends RunnerBase_js_1.RunnerBase {
3109
3274
  // name uniqueness; produces the dispatch map.
3110
3275
  const { registryByName, toolSchemas, toolDeclaringSkills, toolClaimants } = (0, buildToolRegistry_js_1.buildToolRegistry)(registry, this.injections, {
3111
3276
  hasArtifactStore: artifactStore !== undefined,
3277
+ // The reserved-argument refusal (9.101.0) — only when the ledger is
3278
+ // armed may a registry tool's own `_findings` be refused.
3279
+ ...(this.findingsOptions !== undefined && { findings: true }),
3112
3280
  });
3113
3281
  // A statically registered tool that declares `wants` on an agent with no
3114
3282
  // store is configuration that lies: every call would be refused at
@@ -3371,6 +3539,9 @@ class Agent extends RunnerBase_js_1.RunnerBase {
3371
3539
  ...(budget?.tools !== undefined && { budgetCap: budget.tools }),
3372
3540
  // Steps (9.18.0): per-step narrowing + banner + the skip_step offer.
3373
3541
  ...(stepPlanFor !== undefined && { stepPlanFor }),
3542
+ // The findings ledger (9.101.0): the ONE decoration site is inside this
3543
+ // slot; the gate rides in value-conditionally.
3544
+ ...(this.findingsOptions !== undefined && { findings: true }),
3374
3545
  });
3375
3546
  // callLLM extracted to ./agent/stages/callLLM.ts (v2.11.2). Same
3376
3547
  // late-binding pattern as seed for toolSchemas (computed below).
@@ -3379,6 +3550,18 @@ class Agent extends RunnerBase_js_1.RunnerBase {
3379
3550
  this.evidenceGate.posture !== 'assist' && {
3380
3551
  hasEvidenceRecovery: true,
3381
3552
  }),
3553
+ // The findings ledger (9.101.0): the choice seam and `postValidate`
3554
+ // read peeled args / content under `findings`; the SERVING (step 3) —
3555
+ // the ledger piece after the recovery piece, the wire-only collapse of
3556
+ // judged results — rides `hasFindingsLedger` with its mode, the same
3557
+ // value seed records as the run constant `findingsServe`. One gate,
3558
+ // the `hasEvidenceRecovery` grammar: an unarmed agent hands the stage
3559
+ // exactly the deps it always did and reads no new key.
3560
+ ...(this.findingsOptions !== undefined && {
3561
+ findings: true,
3562
+ hasFindingsLedger: true,
3563
+ findingsServe: this.findingsOptions.serve ?? 'ledger-and-facts',
3564
+ }),
3382
3565
  ...(this.answerValidationConfig !== undefined && { suppressDraftTokens: true }),
3383
3566
  // The receipt's salt (9.88.0) — read per call, like seed's own accessor.
3384
3567
  getRunId: () => this.currentRunContext?.runId,
@@ -3474,6 +3657,16 @@ class Agent extends RunnerBase_js_1.RunnerBase {
3474
3657
  ...(this.keepLastToolResults !== undefined && {
3475
3658
  keepLastToolResults: this.keepLastToolResults,
3476
3659
  }),
3660
+ // The findings ledger (9.102.0): the arm and the RESOLVED
3661
+ // ledger-fact ceiling, together or not at all. `keepLedgerFacts`
3662
+ // is set exactly when `.findings()` is on, so an unarmed agent
3663
+ // hands the stage exactly the deps object it always did; an
3664
+ // armed agent with no window strategy threads nothing, because
3665
+ // this whole stage does not exist for it.
3666
+ ...(this.keepLedgerFacts !== undefined && {
3667
+ hasFindingsLedger: true,
3668
+ keepLedgerFacts: this.keepLedgerFacts,
3669
+ }),
3477
3670
  ...(pricingTable !== undefined && { pricingTable }),
3478
3671
  ...(costBudget !== undefined && { costBudget }),
3479
3672
  }),
@@ -3513,7 +3706,11 @@ class Agent extends RunnerBase_js_1.RunnerBase {
3513
3706
  // exactly the arguments it always did — and `buildRouteDeciderStage`'s
3514
3707
  // no-judge fast path still returns the very function reference every
3515
3708
  // pre-9.83.0 chart was given.
3516
- this.noticePriorTurnEvidence && this.evidenceGate !== undefined ? true : undefined);
3709
+ this.noticePriorTurnEvidence && this.evidenceGate !== undefined ? true : undefined,
3710
+ // THE ANSWER TURN'S STANDINGS (9.101.0) — the same value-conditional
3711
+ // trailing positional, for the same reason: an unarmed agent hands the
3712
+ // builder exactly the arguments it always did.
3713
+ this.findingsOptions !== undefined ? true : undefined);
3517
3714
  const routeDecider = this.answerValidationConfig === undefined
3518
3715
  ? baseRouteDecider
3519
3716
  : (0, answerValidation_js_1.withAnswerValidation)(baseRouteDecider, this.answerValidationConfig, this.outputSchemaParser, artifactStore, () => this.consentOutstanding.size > 0);
@@ -3529,6 +3726,9 @@ class Agent extends RunnerBase_js_1.RunnerBase {
3529
3726
  // contract to read it (9.61.0) — value-conditional, so every other
3530
3727
  // agent commits exactly what it always did.
3531
3728
  ...(this.claimContract !== undefined && { collectClaimFacts: true }),
3729
+ // The findings ledger (9.101.0) — the peel, the basis row and the
3730
+ // previous batch's standings all live in this handler under this gate.
3731
+ ...(this.findingsOptions !== undefined && { findings: true }),
3532
3732
  // THE WRITE SEAM (9.77.0) — `empty-lookup`. Handed the SAME harvested
3533
3733
  // map callLLM reads at the choice seam, so the two stages agree by
3534
3734
  // construction about which calls are armed. Value-conditional on both
@@ -3719,6 +3919,11 @@ class Agent extends RunnerBase_js_1.RunnerBase {
3719
3919
  // Escalation (9.19.0): the grouped chart threads `skillEscalated`
3720
3920
  // across the sf-llm-call boundary only when the policy exists.
3721
3921
  ...(this.skillBrains?.escalation !== undefined && { hasEscalation: true }),
3922
+ // The findings ledger (9.102.0): both charts compute the OFFER on the
3923
+ // Tools branch's mount only under the arm — the same value-conditional
3924
+ // grammar as the slot's `findings` and callLLM's `hasFindingsLedger`,
3925
+ // so the three can never disagree about whether the ledger is armed.
3926
+ ...(this.findingsOptions !== undefined && { hasFindingsLedger: true }),
3722
3927
  // `.limitsTravelWithTheAnswer()` (this release) — value-conditional, the
3723
3928
  // `resolvedModel` precedent: absent from the deps object entirely for an
3724
3929
  // agent that did not ask, so both builders mount the final-branch stage