@orkestrel/scaffold 0.0.107 → 0.0.109

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 (164) hide show
  1. package/dist/agents/skills/orkestrel-dispatch/scripts/bench.js +326 -91
  2. package/dist/agents/skills/orkestrel-dispatch/scripts/brief.js +110 -14
  3. package/dist/agents/skills/orkestrel-dispatch/scripts/chain.js +280 -0
  4. package/dist/agents/skills/orkestrel-dispatch/scripts/cite.js +188 -26
  5. package/dist/agents/skills/orkestrel-dispatch/scripts/launch.js +142 -43
  6. package/dist/agents/skills/orkestrel-dispatch/scripts/login.js +240 -62
  7. package/dist/agents/skills/orkestrel-dispatch/scripts/patch.js +323 -0
  8. package/dist/agents/skills/orkestrel-dispatch/scripts/result.js +169 -32
  9. package/dist/agents/skills/orkestrel-dispatch/scripts/sweep.js +368 -27
  10. package/dist/agents/skills/orkestrel-falsify/scripts/mutate.js +560 -0
  11. package/dist/agents/skills/orkestrel-harden/scripts/discovery.js +1052 -205
  12. package/dist/agents/skills/orkestrel-harden/scripts/measure.js +361 -0
  13. package/dist/agents/skills/orkestrel-harden/scripts/titles.js +455 -80
  14. package/dist/agents/skills/orkestrel-parallel/scripts/cases.js +327 -0
  15. package/dist/agents/skills/orkestrel-publish/scripts/compare.js +298 -51
  16. package/dist/agents/skills/orkestrel-publish/scripts/pins.js +170 -13
  17. package/dist/agents/skills/orkestrel-publish/scripts/swap.js +956 -191
  18. package/dist/agents/skills/orkestrel-publish/scripts/wave.js +707 -112
  19. package/dist/agents/skills/orkestrel-publish/scripts/window.js +235 -41
  20. package/dist/agents/skills/orkestrel-scout/scripts/map.js +341 -54
  21. package/dist/agents/templates/brief.md +1 -1
  22. package/dist/bin/main.js +51 -46
  23. package/dist/bin/main.js.map +1 -1
  24. package/dist/host/AGENTS.md +26 -20
  25. package/dist/host/agents/orchestration.md +98 -58
  26. package/dist/host/agents/platforms/posix.md +15 -0
  27. package/dist/host/agents/platforms/windows.md +37 -0
  28. package/dist/host/agents/skills/orkestrel-align/SKILL.md +10 -13
  29. package/dist/host/agents/skills/orkestrel-align/references/fleet.md +4 -10
  30. package/dist/host/agents/skills/orkestrel-align/references/integration.md +1 -1
  31. package/dist/host/agents/skills/orkestrel-build/SKILL.md +16 -48
  32. package/dist/host/agents/skills/orkestrel-build/agents/openai.yaml +1 -1
  33. package/dist/host/agents/skills/orkestrel-debrief/SKILL.md +19 -16
  34. package/dist/host/agents/skills/orkestrel-debrief/agents/openai.yaml +1 -1
  35. package/dist/host/agents/skills/orkestrel-debrief/references/field-testing.md +15 -28
  36. package/dist/host/agents/skills/orkestrel-debrief/references/instruction-audit.md +5 -6
  37. package/dist/host/agents/skills/orkestrel-debrief/references/retention.md +12 -14
  38. package/dist/host/agents/skills/orkestrel-dispatch/SKILL.md +36 -24
  39. package/dist/host/agents/skills/orkestrel-dispatch/references/launch.md +14 -11
  40. package/dist/host/agents/skills/orkestrel-dispatch/scripts/bench.ts +366 -75
  41. package/dist/host/agents/skills/orkestrel-dispatch/scripts/brief.ts +126 -16
  42. package/dist/host/agents/skills/orkestrel-dispatch/scripts/chain.ts +323 -0
  43. package/dist/host/agents/skills/orkestrel-dispatch/scripts/cite.ts +220 -31
  44. package/dist/host/agents/skills/orkestrel-dispatch/scripts/launch.ts +176 -33
  45. package/dist/host/agents/skills/orkestrel-dispatch/scripts/login.ts +294 -59
  46. package/dist/host/agents/skills/orkestrel-dispatch/scripts/patch.ts +401 -0
  47. package/dist/host/agents/skills/orkestrel-dispatch/scripts/result.ts +199 -34
  48. package/dist/host/agents/skills/orkestrel-dispatch/scripts/sweep.ts +428 -27
  49. package/dist/host/agents/skills/orkestrel-falsify/SKILL.md +10 -8
  50. package/dist/host/agents/skills/orkestrel-falsify/references/brief.md +1 -5
  51. package/dist/host/agents/skills/orkestrel-falsify/references/reconcile.md +1 -1
  52. package/dist/host/agents/skills/orkestrel-falsify/scripts/mutate.ts +701 -0
  53. package/dist/host/agents/skills/orkestrel-harden/SKILL.md +16 -12
  54. package/dist/host/agents/skills/orkestrel-harden/references/bindings.md +23 -81
  55. package/dist/host/agents/skills/orkestrel-harden/references/centralization.md +4 -5
  56. package/dist/host/agents/skills/orkestrel-harden/references/contract.md +2 -0
  57. package/dist/host/agents/skills/orkestrel-harden/references/document.md +33 -0
  58. package/dist/host/agents/skills/orkestrel-harden/references/equivalence.md +6 -3
  59. package/dist/host/agents/skills/orkestrel-harden/references/hardening.md +8 -4
  60. package/dist/host/agents/skills/orkestrel-harden/references/research.md +2 -0
  61. package/dist/host/agents/skills/orkestrel-harden/scripts/discovery.ts +1272 -279
  62. package/dist/host/agents/skills/orkestrel-harden/scripts/measure.ts +425 -0
  63. package/dist/host/agents/skills/orkestrel-harden/scripts/titles.ts +603 -98
  64. package/dist/host/agents/skills/orkestrel-journey/SKILL.md +75 -98
  65. package/dist/host/agents/skills/orkestrel-journey/references/captures.md +54 -17
  66. package/dist/host/agents/skills/orkestrel-journey/references/decide.md +1 -20
  67. package/dist/host/agents/skills/orkestrel-journey/references/layer.md +21 -31
  68. package/dist/host/agents/skills/orkestrel-journey/references/styles.md +1 -1
  69. package/dist/host/agents/skills/orkestrel-parallel/SKILL.md +91 -30
  70. package/dist/host/agents/skills/orkestrel-parallel/agents/openai.yaml +2 -2
  71. package/dist/host/agents/skills/orkestrel-parallel/references/claude.md +34 -0
  72. package/dist/host/agents/skills/orkestrel-parallel/references/codex.md +29 -0
  73. package/dist/host/agents/skills/orkestrel-parallel/references/cursor.md +29 -0
  74. package/dist/host/agents/skills/orkestrel-parallel/references/t3.md +31 -0
  75. package/dist/host/agents/skills/orkestrel-parallel/scripts/cases.ts +389 -0
  76. package/dist/host/agents/skills/orkestrel-polish/SKILL.md +16 -20
  77. package/dist/host/agents/skills/orkestrel-polish/references/capture-harness.md +16 -26
  78. package/dist/host/agents/skills/orkestrel-publish/SKILL.md +12 -26
  79. package/dist/host/agents/skills/orkestrel-publish/agents/openai.yaml +2 -2
  80. package/dist/host/agents/skills/orkestrel-publish/references/adopt.md +23 -0
  81. package/dist/host/agents/skills/orkestrel-publish/references/release.md +4 -4
  82. package/dist/host/agents/skills/orkestrel-publish/references/wave.md +12 -10
  83. package/dist/host/agents/skills/orkestrel-publish/references/window.md +20 -25
  84. package/dist/host/agents/skills/orkestrel-publish/scripts/compare.ts +348 -59
  85. package/dist/host/agents/skills/orkestrel-publish/scripts/pins.ts +202 -22
  86. package/dist/host/agents/skills/orkestrel-publish/scripts/swap.ts +1061 -191
  87. package/dist/host/agents/skills/orkestrel-publish/scripts/wave.ts +812 -140
  88. package/dist/host/agents/skills/orkestrel-publish/scripts/window.ts +280 -38
  89. package/dist/host/agents/skills/orkestrel-scout/SKILL.md +3 -3
  90. package/dist/host/agents/skills/orkestrel-scout/scripts/map.ts +428 -70
  91. package/dist/host/agents/templates/brief.md +1 -1
  92. package/dist/host/agents/transports/claude-cli.md +3 -3
  93. package/dist/host/agents/transports/codex.md +3 -8
  94. package/dist/host/agents/transports/cursor.md +2 -3
  95. package/dist/host/claude/AGENTS.md +7 -10
  96. package/dist/host/claude/agents/analyst.md +3 -3
  97. package/dist/host/claude/agents/astra.md +3 -3
  98. package/dist/host/claude/agents/builder.md +1 -1
  99. package/dist/host/claude/agents/checker.md +1 -1
  100. package/dist/host/claude/agents/distiller.md +1 -1
  101. package/dist/host/claude/agents/grok.md +1 -1
  102. package/dist/host/claude/agents/opus.md +2 -2
  103. package/dist/host/claude/agents/orkestrel.md +57 -90
  104. package/dist/host/claude/agents/researcher.md +1 -1
  105. package/dist/host/claude/agents/reviewer.md +4 -0
  106. package/dist/host/claude/agents/scout.md +1 -1
  107. package/dist/host/claude/agents/verifier.md +1 -1
  108. package/dist/host/claude/rules/application.md +14 -21
  109. package/dist/host/claude/rules/architecture.md +34 -44
  110. package/dist/host/claude/rules/browser.md +3 -4
  111. package/dist/host/claude/rules/campaign.md +55 -0
  112. package/dist/host/claude/rules/documentation.md +26 -11
  113. package/dist/host/claude/rules/names.md +9 -4
  114. package/dist/host/claude/rules/patterns.md +6 -7
  115. package/dist/host/claude/rules/portability.md +2 -3
  116. package/dist/host/claude/rules/quality.md +4 -5
  117. package/dist/host/claude/rules/styles.md +2 -2
  118. package/dist/host/claude/rules/tests.md +57 -114
  119. package/dist/host/claude/rules/typescript.md +8 -10
  120. package/dist/host/claude/rules/workspace.md +21 -19
  121. package/dist/host/claude/rules/writing.md +3 -3
  122. package/dist/host/claude/skills/orkestrel-dispatch/SKILL.md +1 -1
  123. package/dist/host/claude/skills/orkestrel-harden/SKILL.md +1 -1
  124. package/dist/host/claude/skills/orkestrel-parallel/SKILL.md +1 -1
  125. package/dist/host/claude/skills/orkestrel-publish/SKILL.md +1 -1
  126. package/dist/host/claude/skills/orkestrel-scout/SKILL.md +1 -1
  127. package/dist/host/codex/agents/analyst.toml +9 -3
  128. package/dist/host/codex/agents/astra.toml +3 -4
  129. package/dist/host/codex/agents/builder.toml +1 -1
  130. package/dist/host/codex/agents/opus.toml +3 -4
  131. package/dist/host/codex/agents/orkestrel.toml +1 -1
  132. package/dist/host/codex/agents/researcher.toml +2 -2
  133. package/dist/host/codex/agents/verifier.toml +1 -1
  134. package/dist/host/codex/config.toml +3 -3
  135. package/dist/host/configs/helpers.ts +21 -1
  136. package/dist/host/configs/policy.ts +405 -16
  137. package/dist/host/cursor/rules/orchestration.mdc +1 -0
  138. package/dist/host/dotfiles/oxlintrc.json +141 -5
  139. package/dist/host/guides/agent.md +111 -134
  140. package/dist/host/guides/capture.md +801 -0
  141. package/dist/host/guides/probe.md +27 -8
  142. package/dist/host/guides/scaffold.md +152 -19
  143. package/dist/host/guides/study.md +534 -440
  144. package/dist/host/guides/test.md +111 -44
  145. package/dist/host/manifest.json +199 -242
  146. package/dist/host/tests/config.test.ts +1558 -219
  147. package/dist/host/tests/policy.test.ts +127 -1
  148. package/dist/host/tests/setupPolicy.ts +1389 -39
  149. package/dist/src/core/index.cjs +239 -87
  150. package/dist/src/core/index.cjs.map +1 -1
  151. package/dist/src/core/index.d.cts +123 -39
  152. package/dist/src/core/index.d.ts +123 -39
  153. package/dist/src/core/index.js +234 -86
  154. package/dist/src/core/index.js.map +1 -1
  155. package/dist/src/server/index.cjs +20 -27
  156. package/dist/src/server/index.cjs.map +1 -1
  157. package/dist/src/server/index.js +21 -28
  158. package/dist/src/server/index.js.map +1 -1
  159. package/package.json +11 -11
  160. package/dist/agents/skills/orkestrel-dispatch/scripts/helpers.js +0 -283
  161. package/dist/host/agents/skills/orkestrel-dispatch/references/bench.md +0 -25
  162. package/dist/host/agents/skills/orkestrel-dispatch/scripts/helpers.ts +0 -333
  163. package/dist/host/agents/skills/orkestrel-parallel/references/harnesses.md +0 -19
  164. package/dist/host/guides/supervisor.md +0 -4890
@@ -467,29 +467,38 @@ Write criteria for a judge that reads literally (see [Jev 1.13 jaggedness](https
467
467
 
468
468
  ### Serving a conversation through a ledger
469
469
 
470
- A ledger serves one conversation as an event-sourced briefing with per-owner records. The `createLedger(provider, options)` factory returns a `LedgerInterface` value that owns the conversation, the agent that answers it, and that agent's tools, and its `respond` method appends a request as a user message and serves it through to the reply. The conversation is the event log. Each request reads a briefing that the ledger projects from what a judge filed about every message, then a tail, then the request. With `recent` omitted or false, the tail selects only seed history (the messages added before the first request), and an earlier request and its reply don't re-enter that tail; what its lookups returned reaches a later request through the records and the `recall` tool. When the selection faults, the agent builds the prompt from the whole conversation view instead, earlier requests and replies included, with no briefing.
470
+ A ledger serves one conversation as an event-sourced briefing with per-owner records. The `createLedger(provider, options)` factory returns a `LedgerInterface` value that owns the conversation, the agent that answers it, and that agent's tools, and its `respond` method appends a request as a user message and serves it through to the reply. The conversation is the event log. Each request reads a briefing that the ledger projects from what a judge filed about every message, then a tail of the seed history (the messages added before the first request), then the request. An earlier request and its reply don't re-enter a planned prompt; what its lookups returned reaches a later request through the records and the `recall` tool. When the selection faults, the agent builds the prompt from the whole conversation view instead, earlier requests and replies included, with no briefing.
471
471
 
472
472
  Run the ledger's agent only through the `respond` method. An active `respond` call owns a run whose request, the newest message, is that call's request or one of the ledger's notes. A run that no active `respond` call owns, such as a direct call to the agent's `generate` method, gets a faulted selection when its newest message is a user message: the selection's `fault` is a `LedgerError` with code `'REQUEST'`, so the agent emits `fault` and builds the prompt from the whole conversation view with no briefing, and the ledger asks its judge nothing for that run. When its newest message isn't a user message, the run gets no selection and builds from the whole view. Calibration admits no run, so a run during the `calibrate` method, or during the calibration that opens a `respond` call, is one that no active `respond` call owns.
473
473
 
474
474
  The method has the following pieces, each named by its export:
475
475
 
476
476
  - **The filing.** The `Classifier` class files each message through the judge the `judge` option injects. The ledger files a tool result, its own notes, an assistant call, and an assistant reply after the first request by their shape, and asks the judge about the rest: the `LEDGER_QUESTIONS` category question about each remaining non-request message, and the topic question, for each desk topic, about each non-quiet statement and each request unless that topic has `requested: false`; and the `amends` question about a later user message whose `correction` probability reaches the `correction` cutoff and an earlier message that isn't quiet and shares an id, an owner, or a desk topic with it, followed by the `supersedes` question about the same pair when the `amends` answer reaches its cutoff. Every answer lands in the conversation's `judgments` store, so a later request asks only what no earlier one asked. A judge failure leaves its question unanswered, and the next request asks it again, except for two failures that hold the question so that no later request asks it: a refused question, which the judge reports as a `JudgeError` with code `'QUESTION'`, and the deterministic logprob failure the `DETERMINISTIC_JUDGE_ERROR` constant matches. The `LedgerClassification` value reads the filing back at the cutoffs: an `amends` answer at its cutoff marks a pair amended only when the two messages share an id or a number, and a `supersedes` answer at its cutoff marks the pair superseded and amended whatever they share. Each `classify` call also returns one `ClassifierReading` value per logical filing question it attempted, in asking order, and observes the filing without changing it. A reading names the question's key and its `ClassifierPhase` value, and its `ClassifierOutcome` value says whether the conversation already held the judgment (`cached`), the classifier held the question after a deterministic failure (`skipped`), or the judgment manager's `resolve` call fulfilled (`resolved`), rejected under a live signal (`failed`), or was cut short by an abort (`aborted`). A `resolved`, `failed`, or `aborted` reading carries the monotonic milliseconds the classifier waited on that call as `duration`, and a `cached` or `skipped` reading carries none. A question that a caller abort preceded has no reading, because it never began. The readings count logical question attempts and resolve requests, never the physical wire calls a judge makes for them, and they record no join of pending requests. The `readings` member of the `LedgerResult` value holds the readings of the filing selections of that `respond` call alone; the `Selection` values the ledger emits carry none.
477
- - **The records.** The `buildRecords` helper projects the filing into one `LedgerRecord` value per owner a lookup result names, plus one rules record for the rules and corrections no owner claims. Each line is a sentence of a live message, verbatim except that a sentence that opens with a pronoun opens with its party and a colon. A message filed quiet or superseded isn't live, and a sentence that shares an id or a number with a later message that amends it is stale: the projection lists it in its `stale` member and leaves it out of every record and the briefing. The `recall` tool and the answer note keep the stored content of each message they carry, stale sentences included. The tail keeps stored content except for lookup results, which the plan replaces with stubs.
478
- - **Owner linking.** By default, only an id-shaped lookup subject links: an owner id links to itself, and another id links to the single owner named in the reading's text. With the boolean `link` option on, a subject such as `order:BC-7301` that carries exactly one id uses that id under the same rules. The link is keyed by `BC-7301`, so a later message or request naming that bare id resolves to the owner. A subject carrying no id or several ids links nothing; a non-owner id whose reading names no owner or several owners also links nothing. The option defaults to `false`.
479
- - **The plan.** For each request, the ledger selects the records the request names through the `selectRecords` helper and fits the briefing and the tail inside a token budget: the `capacity` option less the `predict` option, times the `prompt` share, less the overhead cost of the gauge and held back by the `LEDGER_SCALE_DRIFT` constant, of which the tail takes at most the `tail` share while `recent` is off. The budget bounds only the briefing and the tail of a request's first call. The request, each lookup result, the pass's own assistant turns with their calls and replayed thinking, the answer note and the `cue` note, and the whole view a faulted selection builds from enter the prompt unbounded, so any of them can carry a prompt past the budget. The plan prices each lookup stub in the tail at the longer of its `shown` and `hidden` forms, so a tail that fits the plan still fits after the briefing decides which results it shows. The `share` option sets both shares, and the `DEFAULT_LEDGER_SHARE` constant holds the defaults. After cutting any earlier work, with lexical selection off, until the briefing fits, the ledger drops the rules off the request's topics, then the sources outside the selected records, then the rules on its topics, then the owner lines. The `Gauge` class prices the prompt; without the `gauge` option, the ledger calibrates before its first pass, and the `calibrate` method measures the price on demand. A lookup in the tail reaches the model as the stub the `renderStub` helper writes, which says whether the briefing shows its result. The plan reaches the agent as a `Selection` value: its `messages` member is the tail, and its `briefing` member is the text the `build` method appends as the last part of the system message.
480
- - **Recent history.** Set the boolean `recent` option to `true` to select history up to the current request. The optional `pins` handler, a `LedgerPinHandler` predicate, holds each whole exchange containing a matching message. The newest unheld whole exchanges fill the tail allowance, in conversation order. Lookup groups stay whole and lookup results keep their stubs. Pins can exceed the allowance; the plan keeps them and cuts the briefing, recording the cuts in `trims` and wholly cut sources in `omitted`. With no handler, no exchange is held. Omission and `false` preserve the seed tail and never call the handler.
481
- - **Earlier work.** Set the boolean `work` option to `true` to append an “Earlier work” section after the Rules section. The optional `names` handler, a `LedgerNameHandler` function, names each earlier request with a nonempty call-free assistant reply. The `collectLedgerWork` helper pairs it with the last such reply before the next request, including an answer-pass reply. A name matches when it and the current request share an id token as read by `extractTokens`; token case is folded, and adjacent ids remain distinct. The `renderLedgerWork` helper carries the exact reply under `[NAME]`. The `LEDGER_WORK_HEADING` and `LEDGER_WORK_NOTE` constants label the section as your own earlier drafts, never evidence that an action happened. Replies already in the tail are excluded. Entries render in conversation order and are cut whole, oldest first, before every other briefing cut; `trims` counts those cuts. Work adds no source, owner, filed id, rendered source, sentence, or omitted source, and changes no judge question or recall behavior. With no naming handler, no request is named. Omission and `false` preserve the briefing and never call the handler.
482
- - **Lexical selection.** Set the boolean `lexical` option to `true` to enable BM25 (Best Matching 25) for lexical discovery and ranked recall; omission and `false` preserve the preceding selection behavior. The option is independent of `link`. The shared Unicode analyzer counts lowercase word occurrences for term frequency and length. Each plan and recall computes transient statistics over every call-free message, including held, tail, empty, and non-live messages. The coefficients are `LEDGER_BM25_K1` at 1.2 and `LEDGER_BM25_B` at 0.75. Existing candidate exclusions and keyed membership remain. Keyed units keep the same inverse-document-frequency sum for order and cut keys as with lexical selection off. BM25 decides only a discovery source's admission, order, and cut order in the briefing. A discovery source follows the existing planning groups, needs a positive score at or above `LEDGER_BM25_FLOOR` at `ln(2)`, and orders by descending score then earlier conversation position. The plan cuts discovery first, by lower score then later position, before every keyed unit and within the same room. Recall admits a lexical source only when every word in a topic part matches its content and at least one analyzed whole word overlaps. Recall keeps keyed matches first, then scores each entry root against the distinct analyzed whole topic, then orders equal scores by later position. It constructs amendment entries newest-first before ranking, keeps whole entries, and labels a ranked cut as “items” without age wording. The results note removes only the suffix form its arm writes: neutral wording with lexical selection enabled, and “older items” with the option omitted or false. Pass the same `ranked` value to `cutListing` and `matchesCutLine`; the matcher defaults to `false`. Empty analyzed queries and no lexical overlap add no lexical hits; punctuation-only recall matches no keyed source. Recall limits, room, and repeat identity stay the same.
483
- - **The `recall` tool.** The ledger registers a `recall` tool beside the application's lookups. The following listing order applies with lexical selection off. It lists the earlier messages and lookup readings that match a topic (an owner name, an id, or a desk topic) with their stored content, newest first, each source followed by the amenders the topic doesn't match itself; an amender the topic matches lists as its own newer item. The tool cuts the list by whole items to the room the gauge leaves for the reply, naming how many older items it left out. A request can call it as many times as the `limit` member of the `recall` option allows, the `DEFAULT_RECALL_LIMIT` constant by default; after that, or when the capacity left less the `predict` option falls under twice the reply's reserve, it returns the `closure` note.
477
+ - **The records.** The `buildRecords` helper projects the filing into one `LedgerRecord` value per owner a lookup result names, plus one rules record for the rules and corrections no owner claims. Each line is a sentence of a live message, verbatim except that a sentence that opens with a pronoun opens with its party and a colon. A message filed quiet or superseded isn't live. Accepted message-level amendments preserve every original indexed sentence of live earlier sources; the projection lists distinct direct edges in its `amendments` member. Sentence scope remains unresolved. The `recall` tool and the answer note keep the stored content of each message they carry. The seed tail keeps stored content except for lookup results, which the plan replaces with stubs.
478
+ - **Amendment scope.** The first retained occurrence of an amended source carries a `[Ledger source N]` label and an unresolved-scope note. Distinct retained sources receive decimal references starting at 1 in first-occurrence emission order, after deduplication. References are local to one briefing and are recomputed after each trim; omitted sources do not shift them. Repeated occurrences share one reference. Recall and storage retain original source IDs. Authored content is unchanged. A fully included later source receives matching framing and the note “Accepted later amendment [Ledger source N] is fully included in this briefing. Sentence scope is unresolved.” If any effective correction is absent, partial, or superseded, the note says “Accepted later amendment text is not fully included in this briefing. Sentence scope is unresolved.” The omission note exposes no omitted identity, text, owner, or count. Completeness uses every original sentence identity after source deduplication and each trim; annotations count against the existing room. Effective superseded amenders retain provenance without restoring their text. No transitive amendment edge is inferred. Earlier text can conflict with its correction; downstream correction application and semantic sentence withdrawal remain unproved.
479
+ - **The plan.** For each request, the ledger selects the records the request names through the `selectRecords` helper and fits the briefing and the tail inside a token budget: the `capacity` option less the `predict` option, times the `prompt` share, less the overhead cost of the gauge and held back by the `LEDGER_SCALE_DRIFT` constant, of which the tail takes at most the `tail` share. Owner records with the same member ids in the same order render once, under their titles joined with `; `; before trimming, the view keeps the first requested record's key, members, and lines. The projection, held sources, and recall stay unchanged. The budget bounds only the briefing and the tail of a request's first call. The request, each lookup result, the pass's own assistant turns with their calls and replayed thinking, the answer note and the `cue` note, and the whole view a faulted selection builds from enter the prompt unbounded, so any of them can carry a prompt past the budget. The plan prices each lookup stub in the tail at the longer of its `shown` and `hidden` forms, so a tail that fits the plan still fits after the briefing decides which results it shows. The `share` option sets both shares, and the `DEFAULT_LEDGER_SHARE` constant holds the defaults. Until the briefing fits, the ledger drops the rules off the request's topics, then the sources outside the selected records, then the rules on its topics, then the owner lines. The `Gauge` class prices the prompt; without the `gauge` option, the ledger calibrates before its first pass, and the `calibrate` method measures the price on demand. A lookup in the tail reaches the model as the stub the `renderStub` helper writes, which says whether the briefing shows its result. The plan reaches the agent as a `Selection` value: its `messages` member is the tail, and its `briefing` member is the text the `build` method appends as the last part of the system message.
480
+ - **The `recall` tool.** The ledger registers a `recall` tool beside the application's lookups. It lists the earlier messages and lookup readings that match a topic (an owner name, an id, or a desk topic) with their stored content, newest first, each source followed by the amenders the topic doesn't match itself; an amender the topic matches lists as its own newer item. The tool cuts the list by whole items to the room the gauge leaves for the reply, naming how many older items it left out. A request can call it as many times as the `limit` member of the `recall` option allows, the `DEFAULT_RECALL_LIMIT` constant by default; after that, or when the capacity left less the `predict` option falls under twice the reply's reserve, it returns the `closure` note.
484
481
  - **The repeat stop.** A lookup or `recall` call that repeats an earlier call of the same request, compared by tool name and canonical arguments, returns the `repeat` note as its failure, and the ledger aborts the pass. For a lookup, the repeat stop's identity compares string arguments as written. The projection's lookup identity, which the `identifyLookup` helper writes, trims and uppercases each top-level string argument and decides which reading replaces an earlier one. So `lookup_order` calls for `bw-5512` and `BW-5512` both run in one request, and the second reading replaces the first in the records.
485
482
  - **The answer pass.** When the first pass ends partial or without final text and the caller didn't abort, the ledger adds an answer note when the pass's lookups or recalls returned anything, carrying what they returned without their call text, then the `cue` note, and runs one answer pass that advertises no tools and always turns thinking off. The `passes` member of the `LedgerResult` value holds both passes, and its `content` member is the last pass's. A rejected first pass counts as unfinished. When the answer pass rejects as well, the `respond` method rejects with that pass's error, and the ledger stays free for a later request.
486
483
  - **The thinking budget.** The `predict` option reserves the generation room that thinking and the reply share, taking it out of the plan budget, the recall room, and the close rule. The gauge counts only the thinking the next request carries: under the provider's default `replay` of `'none'`, it leaves a call's thinking out of the capacity that call used, and the `computeThinking` helper apportions that thinking from the completion by character share. Under every policy, the reply reserve reads the reply without its thinking. The `think` option requests or suppresses thinking for the first pass, and omission leaves the provider's default; the answer pass always runs with thinking off. With replay `'none'`, a ledger at a `capacity` of `W + P` with a `predict` of `P`, where `W` is a context window and `P` a generation cap, budgets like a ledger at `W` without thinking.
487
484
 
488
- The `LedgerResult` value also returns the entered message's id as `request` and a `LedgerReceipt` value for each pass in `receipts`, including a recovered failed first pass. Each receipt keeps every adopted selection in order, after answer-pass filtering. A `LedgerSelectionReceipt` value records the open `turn` index, or undefined at entry, the emitted message ids in `tail`, the earlier request ids actually present in that tail as `prior`, and the successful plan facts in `plan`. A fallback keeps its tail with an undefined plan. A rejected request returns no result or receipt.
485
+ Display references identify sources within a rendered briefing while the line keeps the stored identity:
489
486
 
490
- The `LedgerPlanReceipt` value keeps selected `owners`, every nonempty live projected source in `filed`, the compositor's emitted source ids in `rendered`, their surviving sentence identities in `sentences`, wholly cut sources in `omitted`, and the applied cut count in `trims`. The `withdrawn` member deduplicates effective earlier/later amendment pairs. A partially cut source stays rendered. The `sources` member joins carriage in this precedence: a section id is `recap`, stored tail content equality is `verbatim`, emitted record lines establish `record`, and wholly cut content establishes `absent`. A stub with none of those facts has undefined carriage. Recap identity establishes carriage, not preservation of every original fact.
491
-
492
- Each `LedgerCall` value in a pass's `calls` member keeps the gauge's estimate and optional prompt usage, and its `selection` member indexes the adoption active at that observation. An observation before adoption has undefined selection; missing provider usage stays undefined. A turn observation precedes admission and can measure an earlier selection, so it does not establish provider dispatch. Receipts carry identities and composition facts, enter no model messages or options, and establish no claim about whether the answer used a fact.
487
+ ```ts
488
+ import type { LedgerLine } from '@orkestrel/agent'
489
+ import { buildLedgerRenderContext } from '@orkestrel/agent'
490
+
491
+ const first: LedgerLine = {
492
+ text: 'Keep the receipt.',
493
+ source: 'stored-source-id',
494
+ sentence: 0,
495
+ topics: [],
496
+ role: 'user',
497
+ }
498
+ const display = buildLedgerRenderContext([], [first], [])
499
+ display.references.get('stored-source-id') // '1'
500
+ first.source // 'stored-source-id'
501
+ ```
493
502
 
494
503
  The application supplies the following through `LedgerOptions`:
495
504
 
@@ -511,8 +520,8 @@ The method has the following documented limits:
511
520
  - **A seed tool message counts as successful.** A tool message the application adds to the conversation has no recorded result, so the ledger reads it as a successful lookup and files it as a fact, and its reading handler decides what the result names.
512
521
  - **An abort during calibration rejects.** When the caller's signal aborts while the ledger calibrates, the `respond` method rejects with the abort reason instead of resolving a partial result; after calibration, an abort ends the request partial and skips the answer pass.
513
522
  - **A foreign signal rejects before anything is appended.** A `signal` that isn't a native `AbortSignal` rejects the `respond` method with a `ContractError` before the request is appended, and the ledger stays free for a later request.
514
- - **The default tail selects only the seed.** With `recent` omitted or false, only the messages added before the first request form the seed tail, so an application message added after the first request reaches a planned prompt only through the briefing or the `recall` tool.
515
- - **Records don't retire.** No age or request count retires a message: it leaves the records only when a later message supersedes it or makes its sentences stale, a later reading of the same lookup replaces it, or a later answer files it quiet. Only the plan decides which of its lines a briefing shows.
523
+ - **Only the seed forms the tail.** Only the messages added before the first request form the seed tail, so an application message added after the first request reaches a planned prompt only through the briefing or the `recall` tool.
524
+ - **Records don't retire.** No age or request count retires a message: it leaves the records only when a later message supersedes it, a later reading of the same lookup replaces it, or a later answer files it quiet. Only the plan decides which of its lines a briefing shows.
516
525
  - **The ledger refuses no over-window prompt.** A request, a lookup result, the pass's own turns, the answer note, or the whole view a faulted selection builds from reaches the provider whole when it's larger than the room the `capacity` option leaves, and the provider's own context limit decides what happens to it.
517
526
 
518
527
  ### Customizing the format (the cascade)
@@ -1274,64 +1283,51 @@ The `ledgers` module serves a conversation through an event-sourced briefing: th
1274
1283
 
1275
1284
  The following table lists the types the ledger declares, each with its shape:
1276
1285
 
1277
- | Type | Kind | Shape | Summary |
1278
- | ------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1279
- | `LedgerCategory` | type | `'fact' \| 'rule' \| 'correction' \| 'request' \| 'opinion' \| 'chatter' \| 'distractor'` | Names the category the ledger files a message under, one of `LEDGER_CATEGORIES`. |
1280
- | `LedgerQuestion` | interface | `{ category, topic, amends, supersedes }` | Carries the wording of every question the ledger asks its judge. |
1281
- | `LedgerThreshold` | interface | `{ category, topic, amends, supersedes, correction }` | Carries the probability cutoff of each reading the ledger takes from its judge. |
1282
- | `LedgerTopic` | interface | `{ name, criterion, requested? }` | Carries one desk topic: the subject the ledger asks its judge about for statements and, when enabled, requests. |
1283
- | `LedgerShare` | interface | `{ prompt, tail }` | Carries the share of the context capacity the prompt can take and the share of that budget the tail can take. |
1284
- | `LedgerNote` | interface | `{ cue, results, repeat, closure }` | Carries the text of each note the ledger writes into its conversation or returns to the model. |
1285
- | `LedgerRecallOptions` | interface | `{ limit? }` | Configures the ledger's `recall` tool. |
1286
- | `LedgerOwner` | interface | `{ id, names }` | Carries one owner a lookup result names: its id and the names it goes by. |
1287
- | `LedgerLookupResult` | interface | `{ ids, owners }` | Carries what a lookup handler read from one lookup result: the ids it names and the owners among them. |
1288
- | `LedgerLookupHandler` | type | `(args, text) => LedgerLookupResult \| undefined` | Reads one successful lookup result into the ids and owners it names. |
1289
- | `LedgerLookup` | interface | `{ tool, read }` | Carries one application lookup: the tool the model calls and the handler that reads its results. |
1290
- | `LedgerLookupReading` | interface | `{ id, name, arguments, text, result }` | Carries one successful lookup result as the ledger read it. |
1291
- | `LedgerLookupState` | type | `'failed' \| 'empty' \| 'shown' \| 'hidden'` | Names what became of a lookup of an earlier request, as the tail stub of its result reports it. |
1292
- | `LedgerRegistry` | interface | `{ ids, owners }` | Carries the ids the ledger's lookups named and the owners among them. |
1293
- | `LedgerGauge` | interface | `{ scale, overhead }` | Carries the price of a prompt in tokens, measured against the model the ledger serves. |
1294
- | `LedgerAgentOptions` | type | `Pick<AgentOptions, 'limit' \| 'timeout' \| 'on'>` | Selects the agent bounds and hooks a ledger passes through to the agent it builds. |
1295
- | `LedgerPinHandler` | type | `(message) => boolean` | Decides whether the recent tail holds a history message's whole exchange regardless of age. |
1296
- | `LedgerWork` | interface | `{ request, reply }` | Pairs an earlier request with its last nonempty call-free assistant reply before the next request. |
1297
- | `LedgerNameHandler` | type | `(request) => string \| undefined` | Names an earlier request for matching against the current request's id tokens. |
1298
- | `LedgerOptions` | interface | `{ judge, system, topics, questions, thresholds, capacity, predict?, think?: boolean, gauge?, lookups?, link?: boolean, lexical?: boolean, recent?: boolean, pins?: LedgerPinHandler, work?: boolean, names?: LedgerNameHandler, share?, recall?, agent? }` | Configures a ledger: its judge and the wording and cutoffs it files with, the desk topics, the context capacity, and the optional first-pass thinking, lookups, gauge, shares, recall, and agent bounds. |
1299
- | `LedgerCarriage` | type | `'verbatim' \| 'record' \| 'recap' \| 'absent'` | Names how composition carries a selected source's content. |
1300
- | `LedgerSentence` | interface | `{ source, sentence }` | Identifies a source sentence the briefing compositor emitted. |
1301
- | `LedgerWithdrawal` | interface | `{ earlier, later }` | Identifies an effective amendment that withdrew an earlier sentence. |
1302
- | `LedgerSource` | interface | `{ source, carriage: LedgerCarriage \| undefined }` | Records a selected source's established content carriage. |
1303
- | `LedgerPlanReceipt` | interface | `{ owners, filed, rendered, sentences, omitted, trims, withdrawn }` | Preserves the projection and composition facts of one successful plan. |
1304
- | `LedgerPlan` | interface | `Selection plus receipt: LedgerPlanReceipt` | Holds a successful selection with its request-owned planning evidence. |
1305
- | `LedgerSelectionReceipt` | interface | `{ turn, tail, prior, plan, sources }` | Preserves one adopted selection after all message filtering. |
1306
- | `LedgerCall` | interface | `GaugeCall plus selection: number \| undefined` | Preserves one gauge observation and its selection at measurement time. |
1307
- | `LedgerReceipt` | interface | `{ selections, calls }` | Preserves the adopted selections and gauge observations of one pass. |
1308
- | `LedgerResult` | interface | `{ content, thinking?, usage?, partial, stop?, request, passes, readings, receipts }` | Carries the reply, passes, filing readings, and evidence of a resolved request. |
1309
- | `LedgerInterface` | interface | `{ agent, conversation, gauge } plus respond, calibrate` | Serves the requests of one conversation through an agent whose prompt the ledger projects from what the judge filed. |
1310
- | `LedgerRequestInterface` | interface | `{ message, plan, selection, boundary, usage, calls, readings, receipts } plus enter, open, adopt, observe, spend, think, file, admit, recall, close, list, listing` | Holds what one `respond` call of a ledger keeps while it serves its request: the request message, the filing readings and the plan its selections produced, the gauge calls of its passes, and its repeat and recall stops. |
1311
- | `LedgerTokenSet` | interface | `{ ids, numbers }` | Carries the id-shaped tokens and the numbers of a text. |
1312
- | `LedgerWordSet` | interface | `{ words, names }` | Carries the lowercase words and non-opening capitalized names of a message. |
1313
- | `LedgerClassification` | interface | `{ quiet, categories, topics, amendments, supersessions }` | Carries the ledger's filing of its conversation's messages, keyed by message id. |
1314
- | `LedgerLine` | interface | `{ text, source, sentence, party?, topics, role }` | Carries one record line: a sentence of a live message, verbatim except that a sentence that opens with a pronoun opens with its party and a colon. |
1315
- | `LedgerRecord` | interface | `{ key, title, members, lines }` | Carries one record: the live messages placed on one owner or on the rules, as lines. |
1316
- | `LedgerStaleSentence` | interface | `{ source, sentence, tokens, later }` | Carries one stale sentence and the effective amenders sharing its tokens. |
1317
- | `LedgerProjection` | interface | `{ records, stale, orphans }` | Carries the records projected from a conversation, the stale sentences, and the live messages no record placed. |
1318
- | `LedgerProjectionInput` | interface | `{ link?: boolean, system, exclusions, owners, messages, readings, entities, classification }` | Carries what a projection reads. |
1319
- | `LedgerProjectionRequest` | interface | `{ owners, topics }` | Carries the owners and the desk topics one request names, which select its records. |
1320
- | `LedgerCategoryHandler` | type | `(message) => LedgerCategory \| undefined` | Reads a message's category from its shape, or returns undefined to leave it to the judge. |
1321
- | `LedgerEntityHandler` | type | `(text, partial) => ReadonlySet<string>` | Lists the registry ids and owner ids a text names. |
1322
- | `ClassifierOptions` | interface | `{ conversation, judge, questions, topics, thresholds, assign, entities }` | Configures a classifier: the conversation it files, the judge and the wording it asks with, the desk topics, the cutoffs, and the ledger's handlers. |
1323
- | `ClassifierPhase` | type | `'category' \| 'topic' \| 'amends' \| 'supersedes'` | Names the filing question a classifier asked: a message's category, a message's topic, or an earlier and later message's amendment or supersession. |
1324
- | `ClassifierOutcome` | type | `'cached' \| 'skipped' \| 'resolved' \| 'failed' \| 'aborted'` | Names what became of one filing question. |
1325
- | `ClassifierReading` | interface | `{ key, phase, outcome, duration? }` | Carries what became of one filing question: its judgment key, its phase, its outcome, and the time spent resolving it. |
1326
- | `ClassifierResult` | interface | `{ judgments, usage?, readings, fault? }` | Carries the judgment keys one classification rests on and the judge usage it spent. |
1327
- | `ClassifierInterface` | interface | `{} plus classify, category, quiet, decisive, topics, classification` | Files a conversation's messages through a judge and reads the filing. |
1328
- | `GaugeCall` | interface | `{ estimate, prompt?, completion?, thinking?, tools }` | Carries one agent call as the gauge reads it. |
1329
- | `GaugeOptions` | interface | `{ scale, overhead, capacity, predict?, replay? }` | Configures a gauge: its starting price of a prompt and the context capacity it measures against. |
1330
- | `GaugeInterface` | interface | `{ scale, overhead } plus rate, remainder, reserve, room, observe` | Prices prompts in tokens and measures the room a request has left. |
1331
- | `LedgerPlanningGroup` | type | `1 \| 2 \| 3 \| 4` | Names a topic, rule, name, or lexical planning group. |
1332
- | `LedgerLexicon` | interface | `{ frequencies, length }` | Carries occurrence counts from the ledger's word matches. |
1333
- | `LedgerCorpus` | interface | `{ count, frequencies, average }` | Carries statistics over every call-free message. |
1334
- | `LedgerErrorCode` | type | `'REQUEST' \| 'THRESHOLD' \| 'SHARE' \| 'CAPACITY' \| 'LIMIT' \| 'TOPIC' \| 'LOOKUP' \| 'GAUGE'` | Names the machine-readable conditions a `LedgerError` error reports. |
1286
+ | Type | Kind | Shape | Summary |
1287
+ | ------------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1288
+ | `LedgerCategory` | type | `'fact' \| 'rule' \| 'correction' \| 'request' \| 'opinion' \| 'chatter' \| 'distractor'` | Names the category the ledger files a message under, one of `LEDGER_CATEGORIES`. |
1289
+ | `LedgerQuestion` | interface | `{ category, topic, amends, supersedes }` | Carries the wording of every question the ledger asks its judge. |
1290
+ | `LedgerThreshold` | interface | `{ category, topic, amends, supersedes, correction }` | Carries the probability cutoff of each reading the ledger takes from its judge. |
1291
+ | `LedgerTopic` | interface | `{ name, criterion, requested? }` | Carries one desk topic: the subject the ledger asks its judge about for statements and, when enabled, requests. |
1292
+ | `LedgerShare` | interface | `{ prompt, tail }` | Carries the share of the context capacity the prompt can take and the share of that budget the tail can take. |
1293
+ | `LedgerNote` | interface | `{ cue, results, repeat, closure }` | Carries the text of each note the ledger writes into its conversation or returns to the model. |
1294
+ | `LedgerRecallOptions` | interface | `{ limit? }` | Configures the ledger's `recall` tool. |
1295
+ | `LedgerOwner` | interface | `{ id, names }` | Carries one owner a lookup result names: its id and the names it goes by. |
1296
+ | `LedgerLookupResult` | interface | `{ ids, owners }` | Carries what a lookup handler read from one lookup result: the ids it names and the owners among them. |
1297
+ | `LedgerLookupHandler` | type | `(args, text) => LedgerLookupResult \| undefined` | Reads one successful lookup result into the ids and owners it names. |
1298
+ | `LedgerLookup` | interface | `{ tool, read }` | Carries one application lookup: the tool the model calls and the handler that reads its results. |
1299
+ | `LedgerLookupReading` | interface | `{ id, name, arguments, text, result }` | Carries one successful lookup result as the ledger read it. |
1300
+ | `LedgerLookupState` | type | `'failed' \| 'empty' \| 'shown' \| 'hidden'` | Names what became of a lookup of an earlier request, as the tail stub of its result reports it. |
1301
+ | `LedgerRegistry` | interface | `{ ids, owners }` | Carries the ids the ledger's lookups named and the owners among them. |
1302
+ | `LedgerGauge` | interface | `{ scale, overhead }` | Carries the price of a prompt in tokens, measured against the model the ledger serves. |
1303
+ | `LedgerAgentOptions` | type | `Pick<AgentOptions, 'limit' \| 'timeout' \| 'on'>` | Selects the agent bounds and hooks a ledger passes through to the agent it builds. |
1304
+ | `LedgerOptions` | interface | `{ judge, system, topics, questions, thresholds, capacity, predict?, think?: boolean, gauge?, lookups?, share?, recall?, agent? }` | Configures a ledger: its judge and the wording and cutoffs it files with, the desk topics, the context capacity, and the optional first-pass thinking, lookups, gauge, shares, recall, and agent bounds. |
1305
+ | `LedgerResult` | interface | `{ content, thinking?, usage?, partial, stop?, passes, readings }` | Carries the outcome of one request a ledger served: the agent result of its reply and every pass it took. |
1306
+ | `LedgerInterface` | interface | `{ agent, conversation, gauge } plus respond, calibrate` | Serves the requests of one conversation through an agent whose prompt the ledger projects from what the judge filed. |
1307
+ | `LedgerRequestInterface` | interface | `{ message, plan, selection, boundary, usage, calls, readings } plus enter, open, adopt, observe, spend, think, file, admit, recall, close, list, listing` | Holds what one `respond` call of a ledger keeps while it serves its request: the request message, the filing readings and the plan its selections produced, the gauge calls of its passes, and its repeat and recall stops. |
1308
+ | `LedgerTokenSet` | interface | `{ ids, numbers }` | Carries the id-shaped tokens and the numbers of a text. |
1309
+ | `LedgerWordSet` | interface | `{ words, names }` | Carries the lowercase words and non-opening capitalized names of a message. |
1310
+ | `LedgerClassification` | interface | `{ quiet, categories, topics, amendments, supersessions }` | Carries the ledger's filing of its conversation's messages, keyed by message id. |
1311
+ | `LedgerLine` | interface | `{ text, source, sentence, party?, topics, role }` | Carries one record line: a sentence of a live message, verbatim except that a sentence that opens with a pronoun opens with its party and a colon. |
1312
+ | `LedgerRecord` | interface | `{ key, title, members, lines }` | Carries one record: the live messages placed on one owner or on the rules, as lines. |
1313
+ | `LedgerAmendment` | interface | `{ earlier, later }` | Identifies an accepted direct message amendment whose sentence scope remains unresolved. |
1314
+ | `LedgerRenderContext` | interface | `{ amendments, complete, first, references }` | Supplies accepted amendments and completely included sources for one briefing rendering. |
1315
+ | `LedgerProjection` | interface | `{ records, amendments, orphans }` | Carries the records projected from a conversation, accepted amendments, and the live messages no record placed. |
1316
+ | `LedgerProjectionInput` | interface | `{ system, exclusions, owners, messages, readings, entities, classification }` | Carries what a projection reads. |
1317
+ | `LedgerProjectionRequest` | interface | `{ owners, topics }` | Carries the owners and the desk topics one request names, which select its records. |
1318
+ | `LedgerCategoryHandler` | type | `(message) => LedgerCategory \| undefined` | Reads a message's category from its shape, or returns undefined to leave it to the judge. |
1319
+ | `LedgerEntityHandler` | type | `(text, partial) => ReadonlySet<string>` | Lists the registry ids and owner ids a text names. |
1320
+ | `ClassifierOptions` | interface | `{ conversation, judge, questions, topics, thresholds, assign, entities }` | Configures a classifier: the conversation it files, the judge and the wording it asks with, the desk topics, the cutoffs, and the ledger's handlers. |
1321
+ | `ClassifierPhase` | type | `'category' \| 'topic' \| 'amends' \| 'supersedes'` | Names the filing question a classifier asked: a message's category, a message's topic, or an earlier and later message's amendment or supersession. |
1322
+ | `ClassifierOutcome` | type | `'cached' \| 'skipped' \| 'resolved' \| 'failed' \| 'aborted'` | Names what became of one filing question. |
1323
+ | `ClassifierReading` | interface | `{ key, phase, outcome, duration? }` | Carries what became of one filing question: its judgment key, its phase, its outcome, and the time spent resolving it. |
1324
+ | `ClassifierResult` | interface | `{ judgments, usage?, readings, fault? }` | Carries the judgment keys one classification rests on and the judge usage it spent. |
1325
+ | `ClassifierInterface` | interface | `{} plus classify, category, quiet, decisive, topics, classification` | Files a conversation's messages through a judge and reads the filing. |
1326
+ | `GaugeCall` | interface | `{ estimate, prompt?, completion?, thinking?, tools }` | Carries one agent call as the gauge reads it. |
1327
+ | `GaugeOptions` | interface | `{ scale, overhead, capacity, predict?, replay? }` | Configures a gauge: its starting price of a prompt and the context capacity it measures against. |
1328
+ | `GaugeInterface` | interface | `{ scale, overhead } plus rate, remainder, reserve, room, observe` | Prices prompts in tokens and measures the room a request has left. |
1329
+ | `LedgerPlanningGroup` | type | `1 \| 2 \| 3` | Names a briefing source's planning group: a topic match, an off-topic rule or correction, or a name match. |
1330
+ | `LedgerErrorCode` | type | `'REQUEST' \| 'THRESHOLD' \| 'SHARE' \| 'CAPACITY' \| 'LIMIT' \| 'TOPIC' \| 'LOOKUP' \| 'GAUGE' \| 'REFERENCE'` | Names the machine-readable conditions a `LedgerError` error reports. |
1335
1331
 
1336
1332
  #### Constants
1337
1333
 
@@ -1339,10 +1335,6 @@ The following table lists the constants that hold the ledger's categories, recor
1339
1335
 
1340
1336
  | API | Kind | Shape | Summary |
1341
1337
  | --------------------------- | ----- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
1342
- | `LEDGER_WORD_PATTERN` | const | `RegExp` | Matches the Unicode words used by both ledger analyzers. |
1343
- | `LEDGER_BM25_K1` | const | `number` | Sets the BM25 term-frequency saturation coefficient. |
1344
- | `LEDGER_BM25_B` | const | `number` | Sets the BM25 length-normalization coefficient. |
1345
- | `LEDGER_BM25_FLOOR` | const | `number` | Sets the inclusive lexical discovery floor. |
1346
1338
  | `LEDGER_CATEGORIES` | const | `readonly LedgerCategory[]` | Lists the categories the ledger files a message under, in the order the category question names them — the one list the `LedgerCategory` union derives from. |
1347
1339
  | `QUIET_CATEGORIES` | const | `readonly LedgerCategory[]` | Lists the categories whose messages the projection leaves out as quiet. |
1348
1340
  | `DECISIVE_CATEGORIES` | const | `readonly LedgerCategory[]` | Lists the categories whose messages state what the desk acts on, which the briefing renders. |
@@ -1351,8 +1343,6 @@ The following table lists the constants that hold the ledger's categories, recor
1351
1343
  | `LEDGER_OWNER_PREFIX` | const | `string` | Prefixes the key of an owner's record, which the owner's id follows. |
1352
1344
  | `LEDGER_QUESTIONS` | const | `LedgerQuestion` | Supplies the wording of every question the ledger asks its judge. |
1353
1345
  | `LEDGER_NOTES` | const | `LedgerNote` | Supplies the text of each ledger note, worded for a model that answers in its final message. |
1354
- | `LEDGER_WORK_HEADING` | const | `string` | Heads the briefing section carrying the agent's named earlier replies. |
1355
- | `LEDGER_WORK_NOTE` | const | `string` | Labels earlier replies as the agent's drafts rather than evidence of an action. |
1356
1346
  | `DEFAULT_LEDGER_SHARE` | const | `LedgerShare` | Supplies the default prompt and tail shares. |
1357
1347
  | `DEFAULT_LEDGER_LIMIT` | const | `number` | Caps the tool-iteration turns of a ledger's agent at 8 turns. |
1358
1348
  | `DEFAULT_RECALL_LIMIT` | const | `number` | Caps the `recall` calls of one request at 2 calls. |
@@ -1400,48 +1390,44 @@ The following guards validate ledger fractions and capacity:
1400
1390
 
1401
1391
  The following table lists the pure helpers that read text, project and select records, render a briefing, and fit a price:
1402
1392
 
1403
- | API | Kind | Signature | Summary |
1404
- | ---------------------- | -------- | --------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
1405
- | `splitSentences` | function | `(text) => readonly string[]` | Splits a message into its sentences. |
1406
- | `extractTokens` | function | `(text) => LedgerTokenSet` | Reads the id-shaped tokens and the numbers of a text. |
1407
- | `collectNames` | function | `(text) => readonly string[]` | Collects the capitalized name runs of a text, leaving out the run that opens each sentence. |
1408
- | `identifyLookup` | function | `(name, args) => string \| undefined` | Identifies a lookup reading for projection by its tool name and normalized arguments. |
1409
- | `linkOwners` | function | `(readings, owners, link?) => ReadonlyMap<string, string>` | Links each eligible lookup argument id to its owner. |
1410
- | `collectRegistry` | function | `(readings) => LedgerRegistry` | Collects the ids and the owner names the lookup readings named. |
1411
- | `matchEntities` | function | `(registry, text, partial) => ReadonlySet<string>` | Matches the registry ids and owners a text names. |
1412
- | `buildRecords` | function | `(input) => LedgerProjection` | Projects the owner records and the rules record from a conversation's messages. |
1413
- | `selectRecords` | function | `(projection, request) => readonly LedgerRecord[]` | Selects a request's view of the projected records. |
1414
- | `findLedgerCall` | function | `(group, message) => ToolCall \| undefined` | Finds the call that owns a tool message within a collected tool group. |
1415
- | `collectLedgerWork` | function | `(messages, requests) => readonly LedgerWork[]` | Collects each request's last nonempty call-free assistant reply before the next request. |
1416
- | `renderLedgerWork` | function | `(name, work) => string` | Renders one named earlier reply without changing its content. |
1417
- | `collectProjectionIds` | function | `(projection) => ReadonlySet<string>` | Collects the live message ids placed in records or left without a record. |
1418
- | `scanAmendments` | function | `(amendments, start, admit) => readonly string[]` | Scans admitted amendments in breadth-first order without revisiting a message. |
1419
- | `buildLedgerSources` | function | `(emitted, stored, sections, plan) => readonly LedgerSource[]` | Builds source carriage from emitted messages and established composition facts. |
1420
- | `buildRecallMessage` | function | `(topic) => Message` | Builds the placeholder assistant recall call used to price recall framing. |
1421
- | `renderTopicNames` | function | `(topics) => string` | Renders topic names as a comma-separated list in their supplied order. |
1422
- | `renderCauseChain` | function | `(error) => string` | Renders an error and its causes, stopping after 4 entries. |
1423
- | `extractWords` | function | `(message) => LedgerWordSet` | Extracts lowercase words and capitalized names that do not open a sentence. |
1424
- | `countLedgerWords` | function | `(message) => LedgerLexicon` | Counts lowercase word occurrences without changing their boundaries. |
1425
- | `computeLedgerCorpus` | function | `(texts) => LedgerCorpus` | Computes document frequencies and mean occurrence length. |
1426
- | `computeLedgerScore` | function | `(text, query, corpus) => number` | Computes BM25 for distinct query words against one corpus member. |
1427
- | `splitWords` | function | `(part) => readonly string[]` | Splits a topic part into lowercase words with surrounding punctuation removed. |
1428
- | `rankLedgerCut` | function | `(group, unsettled, category) => number` | Ranks a briefing source for removal before the next prompt. |
1429
- | `renderLedgerRecord` | function | `(record) => string` | Renders one record as a heading and one list item per line. |
1430
- | `renderLedgerPinned` | function | `(record) => string` | Renders one owner record under a `###` heading, which the briefing nests under its one `## Pinned` heading. |
1431
- | `splitTopic` | function | `(topic) => readonly string[]` | Splits a recall topic at its joints. |
1432
- | `cutListing` | function | `(entries, room, ranked?) => string` | Cuts entries to a room and names how many it left out. |
1433
- | `matchesCutLine` | function | `(line, ranked?) => boolean` | Checks whether a line is the cut line `cutListing` writes for the same ranking option. |
1434
- | `normalizeArgument` | function | `(value) => string` | Normalizes a lookup argument string to the spelling that lookup identity and owner linking compare. |
1435
- | `splitResultLines` | function | `(text) => readonly string[]` | Splits a tool result into its lines at each line feed, with or without a carriage return before it. |
1436
- | `renderLookupCall` | function | `(name, args) => string` | Renders a lookup call as its tool name and its JSON arguments. |
1437
- | `renderStub` | function | `(name, args, state) => string` | Renders the tail stub of a lookup result from an earlier request. |
1438
- | `computeThinking` | function | `(message, completion) => number` | Computes the completion tokens attributable to a message's thinking. |
1439
- | `resolvePredict` | function | `(predict, capacity) => number` | Resolves the generation cap and checks it against the context capacity. |
1440
- | `fitSlope` | function | `(groups) => number \| undefined` | Fits the marginal tokens one estimate unit adds within a request. |
1441
- | `collectLive` | function | `(input) => readonly string[]` | Collects the ids of the live messages in conversation order. |
1442
- | `placeMember` | function | `(input, links, amending, id, seen, settled?) => ReadonlySet<string>` | Places a message on the record keys it joins. |
1443
- | `collectStale` | function | `(input, byId, live) => readonly LedgerStaleSentence[]` | Collects the sentences that live messages made stale. |
1444
- | `buildLines` | function | `(input, byId, id, dead, holders, system) => readonly LedgerLine[]` | Builds the record lines of one message. |
1393
+ | API | Kind | Signature | Summary |
1394
+ | -------------------------- | -------- | --------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
1395
+ | `splitSentences` | function | `(text) => readonly string[]` | Splits a message into its sentences. |
1396
+ | `extractTokens` | function | `(text) => LedgerTokenSet` | Reads the id-shaped tokens and the numbers of a text. |
1397
+ | `collectNames` | function | `(text) => readonly string[]` | Collects the capitalized name runs of a text, leaving out the run that opens each sentence. |
1398
+ | `identifyLookup` | function | `(name, args) => string \| undefined` | Identifies a lookup reading for projection by its tool name and normalized arguments. |
1399
+ | `linkOwners` | function | `(readings, owners) => ReadonlyMap<string, string>` | Links each id-shaped lookup argument to its owner. |
1400
+ | `collectRegistry` | function | `(readings) => LedgerRegistry` | Collects the ids and the owner names the lookup readings named. |
1401
+ | `matchEntities` | function | `(registry, text, partial) => ReadonlySet<string>` | Matches the registry ids and owners a text names. |
1402
+ | `buildRecords` | function | `(input) => LedgerProjection` | Projects the owner records and the rules record from a conversation's messages. |
1403
+ | `selectRecords` | function | `(projection, request) => readonly LedgerRecord[]` | Selects a request's records, collapsing owners with equal ordered member ids under titles joined with `; `. |
1404
+ | `findLedgerCall` | function | `(group, message) => ToolCall \| undefined` | Finds the call that owns a tool message within a collected tool group. |
1405
+ | `collectProjectionIds` | function | `(projection) => ReadonlySet<string>` | Collects the live message ids placed in records or left without a record. |
1406
+ | `scanAmendments` | function | `(amendments, start, admit) => readonly string[]` | Scans admitted amendments in breadth-first order without revisiting a message. |
1407
+ | `buildRecallMessage` | function | `(topic) => Message` | Builds the placeholder assistant recall call used to price recall framing. |
1408
+ | `renderTopicNames` | function | `(topics) => string` | Renders topic names as a comma-separated list in their supplied order. |
1409
+ | `renderCauseChain` | function | `(error) => string` | Renders an error and its causes, stopping after 4 entries. |
1410
+ | `extractWords` | function | `(message) => LedgerWordSet` | Extracts lowercase words and capitalized names that do not open a sentence. |
1411
+ | `splitWords` | function | `(part) => readonly string[]` | Splits a topic part into lowercase words with surrounding punctuation removed. |
1412
+ | `rankLedgerCut` | function | `(group, unsettled, category) => number` | Ranks a briefing source for removal before the next prompt. |
1413
+ | `renderLedgerRecord` | function | `(record, context?) => string` | Renders one record as a heading and one list item per line. |
1414
+ | `renderLedgerPinned` | function | `(record, context?) => string` | Renders one owner record under a `###` heading, which the briefing nests under its one `## Pinned` heading. |
1415
+ | `splitTopic` | function | `(topic) => readonly string[]` | Splits a recall topic at its joints. |
1416
+ | `cutListing` | function | `(entries, room) => string` | Cuts entries to a room and names how many it left out. |
1417
+ | `matchesCutLine` | function | `(line) => boolean` | Checks whether a line is the cut line `cutListing` writes. |
1418
+ | `normalizeArgument` | function | `(value) => string` | Normalizes a lookup argument string to the spelling that lookup identity and owner linking compare. |
1419
+ | `splitResultLines` | function | `(text) => readonly string[]` | Splits a tool result into its lines at each line feed, with or without a carriage return before it. |
1420
+ | `renderLookupCall` | function | `(name, args) => string` | Renders a lookup call as its tool name and its JSON arguments. |
1421
+ | `renderStub` | function | `(name, args, state) => string` | Renders the tail stub of a lookup result from an earlier request. |
1422
+ | `computeThinking` | function | `(message, completion) => number` | Computes the completion tokens attributable to a message's thinking. |
1423
+ | `resolvePredict` | function | `(predict, capacity) => number` | Resolves the generation cap and checks it against the context capacity. |
1424
+ | `fitSlope` | function | `(groups) => number \| undefined` | Fits the marginal tokens one estimate unit adds within a request. |
1425
+ | `collectLive` | function | `(input) => readonly string[]` | Collects the ids of the live messages in conversation order. |
1426
+ | `placeMember` | function | `(input, links, amending, id, seen, settled?) => ReadonlySet<string>` | Places a message on the record keys it joins. |
1427
+ | `buildLedgerRenderContext` | function | `(messages, lines, amendments) => LedgerRenderContext` | Derives complete source identities, first occurrences, and local references from the actual briefing lines. |
1428
+ | `renderLedgerAnnotation` | function | `(line, context) => string` | Renders source framing and unresolved amendment scope at a source's first retained line. |
1429
+ | `collectAmendments` | function | `(input, byId, live) => readonly LedgerAmendment[]` | Collects accepted direct amendments of live messages. |
1430
+ | `buildLines` | function | `(input, byId, id, holders, system) => readonly LedgerLine[]` | Builds the record lines of one message. |
1445
1431
 
1446
1432
  The `Classifier` and `Gauge` classes the ledger composes are public, so a harness can file a conversation or price a prompt without a ledger. The following classifier files one rule, and the following gauge prices the calls of one request:
1447
1433
 
@@ -1806,7 +1792,7 @@ The conversation ledger. The `respond` method serves one request through to its
1806
1792
 
1807
1793
  #### `LedgerRequestInterface`
1808
1794
 
1809
- The state of one `respond` call. The ledger creates one request per call and drops it when the call settles, so no request state reaches a later call or a run no call owns. Each agent run the call makes is a pass: the `open` method starts one, and the `selection`, `boundary`, and `usage` data members read the current pass. The `message`, `plan`, `selection`, `boundary`, `usage`, `calls`, `readings`, and `receipts` data members stay Surface rows. The `file` method accepts a successful `LedgerPlan` value; its receipt remains request-owned when answer selection reuses that plan. The `adopt` method takes `(selection, boundary, receipt)`, where the `LedgerSelectionReceipt` value describes the filtered adoption. The `receipts` member projects every opened pass, including a pass with no selection or observation.
1795
+ The state of one `respond` call. The ledger creates one request per call and drops it when the call settles, so no request state reaches a later call or a run no call owns. Each agent run the call makes is a pass: the `open` method starts one, and the `selection`, `boundary`, and `usage` data members read the current pass. The `message`, `plan`, `selection`, `boundary`, `usage`, `calls`, and `readings` data members stay Surface rows.
1810
1796
 
1811
1797
  | Method | Returns | Summary |
1812
1798
  | --------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ |
@@ -1841,18 +1827,11 @@ const selection: Selection = {
1841
1827
  judgments: [],
1842
1828
  usage: { prompt: 30, completion: 2, total: 32 },
1843
1829
  }
1844
- request.adopt(selection, conversation.count, {
1845
- turn: undefined,
1846
- tail: [message.id],
1847
- prior: [],
1848
- plan: undefined,
1849
- sources: [{ source: message.id, carriage: 'verbatim' }],
1850
- })
1830
+ request.adopt(selection, conversation.count)
1851
1831
  request.observe({ estimate: 40, tools: 2 }, conversation.count)
1852
1832
  request.spend({ prompt: 52, completion: 8, total: 60 })
1853
1833
  request.usage // { prompt: 82, completion: 10, total: 92 } — the selection's usage and the call's
1854
1834
  request.calls // [{ estimate: 40, tools: 2, prompt: 52, completion: 8 }] — the call in flight took its usage
1855
- request.receipts[0]?.calls[0]?.selection // 0 — the adoption active at the observation
1856
1835
 
1857
1836
  request.admit('lookup_order', { id: 'BW-5512' })
1858
1837
  request.admit('lookup_order', { id: 'BW-5512' }) // throws Error(LEDGER_NOTES.repeat)
@@ -2595,7 +2574,7 @@ const result = await agent.generate() // { content: 'Refunds need a manager.', p
2595
2574
 
2596
2575
  ### Serving requests through a ledger
2597
2576
 
2598
- Build a ledger from a provider, a judge, the lookups, and the measured questions, add the seed history to its conversation, and send each request through the `respond` method. Read the `briefing` member of each `select` event's selection to see what the ledger told the model. Read the returned `request` identity and per-pass `receipts` for selection and gauge evidence. The following ledger serves two requests; a scripted provider stands in for the model and a scripted judge for Mica:
2577
+ Build a ledger from a provider, a judge, the lookups, and the measured questions, add the seed history to its conversation, and send each request through the `respond` method. Read the `briefing` member of each `select` event's receipt to see what the ledger told the model. The following ledger serves two requests; a scripted provider stands in for the model and a scripted judge for Mica:
2599
2578
 
2600
2579
  ```ts
2601
2580
  import type {
@@ -2678,8 +2657,6 @@ const gauge = await ledger.calibrate(AbortSignal.timeout(30_000))
2678
2657
  gauge.overhead // 120 — what advertising the tools adds to a prompt
2679
2658
  const first = await ledger.respond('Can Brightwater Studio get a refund on order BW-5512?')
2680
2659
  first.content // 'Order BW-5512 qualifies for a $148.50 refund.'
2681
- first.receipts.length === first.passes.length // true
2682
- first.receipts[0]?.calls[0]?.prompt // undefined — this scripted provider reports no turn usage
2683
2660
  const second = await ledger.respond('Does the Brightwater Studio refund need a manager?')
2684
2661
  second.content // 'Yes. Refunds over $100 need a manager.'
2685
2662
  briefings[0] // '## Rules\n- Refunds over $100 need a manager.' — no lookup has named an owner yet
@@ -2825,12 +2802,12 @@ The following test files back this guide:
2825
2802
  - [`tests/src/core/agents/factories.test.ts`](../tests/src/core/agents/factories.test.ts) — `createChannel`, `createAgent`, `createAgentRegistry`, `createAgentQueue` with its durability, partial policy, and lifecycle, `createAgentRunner` with fan-out, and the `AgentJobError` / `isAgentJobError` block.
2826
2803
  - [`tests/src/core/agents/helpers.test.ts`](../tests/src/core/agents/helpers.test.ts) — `agentResultToJSON` with its `stop` projection, `tokenUsageToJSON`, `inferStop`, `requireBudget`, `estimateMessages`, `estimateRequest`, `measureMessage`, `measureRequest`, `settleAgentJob`, `assembleResult`, `denyCall`, and `chargeUsage`.
2827
2804
  - [`tests/src/core/agents/AgentFanout.test.ts`](../tests/src/core/agents/AgentFanout.test.ts) — `AgentFanout` through a real runner: one fan-out per unit across a retried attempt, every distinct unit's children, and the partial policy.
2828
- - [`tests/src/core/ledgers/Ledger.test.ts`](../tests/src/core/ledgers/Ledger.test.ts) — the ledger over a scripted provider: owner records, seed stubs paired with their calls by call id and priced at their longer form, and the seed tail, the `'REQUEST'` fault of a run no active `respond` call owns, the repeat stop, the answer pass and the abort that skips it, calibration with its replay at the next user boundary and its refusals, the filing of notes and failed lookups, the `recall` tool's listing, limit, and room, the answer note's lines, the generation cap and thinking per pass, and the stale sentences the briefing drops while `recall`, the answer note, and the seed tail keep stored content. The lexical claims prove discovery at the inclusive floor, owner identity, group and score order, priority cuts, keyed-first recall, amendment grouping, repeat identity, and omitted/false byte captures.
2805
+ - [`tests/src/core/ledgers/Ledger.test.ts`](../tests/src/core/ledgers/Ledger.test.ts) — the ledger over a scripted provider: owner records, seed stubs paired with their calls by call id and priced at their longer form, and the seed tail, the `'REQUEST'` fault of a run no active `respond` call owns, the repeat stop, the answer pass and the abort that skips it, calibration with its replay at the next user boundary and its refusals, the filing of notes and failed lookups, the `recall` tool's listing, limit, and room, the answer note's lines, the generation cap and thinking per pass, and retained amended sentences with unresolved scope while `recall`, the answer note, and the seed tail keep stored content.
2829
2806
  - [`tests/src/core/ledgers/LedgerRequest.test.ts`](../tests/src/core/ledgers/LedgerRequest.test.ts) — the request's recall-limit refusal, its single `enter`, its passes with their selections, usage, calls, and thinking, its filing readings and plan, the repeat stop, the recall limit and `close`, and the listings of a recall result.
2830
2807
  - [`tests/src/core/ledgers/Classifier.test.ts`](../tests/src/core/ledgers/Classifier.test.ts) — the measured question bytes and asking order, judgment reuse and usage, exact cutoffs, pair questions, deterministic and transient judge failures, abort faults that keep the completed judgments, and the cached, skipped, resolved, failed, and aborted readings each of those paths records.
2831
2808
  - [`tests/src/core/ledgers/Gauge.test.ts`](../tests/src/core/ledgers/Gauge.test.ts) — the gauge's construction refusals and its `observe`, `rate`, `remainder`, `reserve`, and `room` methods, under the generation cap and each replay policy.
2832
2809
  - [`tests/src/core/ledgers/factories.test.ts`](../tests/src/core/ledgers/factories.test.ts) — `createLedger` and its `LedgerError` refusals for thresholds, shares, capacity, limits, topics, lookups, and a supplied gauge, and the barrel exports of the ledger module.
2833
- - [`tests/src/core/ledgers/helpers.test.ts`](../tests/src/core/ledgers/helpers.test.ts) — the projection helpers from `splitSentences` through `buildRecords` and `selectRecords`, the record renderers, `findLedgerCall`, `rankLedgerCut`, `splitTopic`, `cutListing` and `matchesCutLine`, `renderStub`, `normalizeArgument`, `splitResultLines`, `renderLookupCall`, `computeThinking`, `resolvePredict`, and `fitSlope`. The lexical claims compare occurrence counts and BM25 against hand-computed answers, empty inputs, discovery cut ranks, and ranked cut suffixes.
2810
+ - [`tests/src/core/ledgers/helpers.test.ts`](../tests/src/core/ledgers/helpers.test.ts) — the projection helpers from `splitSentences` through `buildRecords` and `selectRecords`, the record renderers, `findLedgerCall`, `rankLedgerCut`, `splitTopic`, `cutListing` and `matchesCutLine`, `renderStub`, `normalizeArgument`, `splitResultLines`, `renderLookupCall`, `computeThinking`, `resolvePredict`, and `fitSlope`.
2834
2811
 
2835
2812
  ### Placement proofs
2836
2813