@orkestrel/scaffold 0.0.104 → 0.0.106

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 (33) hide show
  1. package/dist/bin/main.js +8 -8
  2. package/dist/bin/main.js.map +1 -1
  3. package/dist/host/agents/orchestration.md +3 -3
  4. package/dist/host/agents/skills/orkestrel-parallel/SKILL.md +72 -0
  5. package/dist/host/agents/skills/orkestrel-parallel/agents/openai.yaml +4 -0
  6. package/dist/host/agents/skills/orkestrel-parallel/references/harnesses.md +12 -0
  7. package/dist/host/claude/agents/orkestrel.md +7 -7
  8. package/dist/host/claude/agents/verifier.md +1 -1
  9. package/dist/host/claude/skills/orkestrel-parallel/SKILL.md +11 -0
  10. package/dist/host/codex/agents/verifier.toml +3 -1
  11. package/dist/host/guides/agent.md +102 -57
  12. package/dist/host/guides/form.md +8 -8
  13. package/dist/host/guides/ollama.md +275 -18
  14. package/dist/host/guides/scaffold.md +38 -38
  15. package/dist/host/guides/study.md +589 -39
  16. package/dist/host/guides/table.md +14 -14
  17. package/dist/host/guides/test.md +94 -67
  18. package/dist/host/manifest.json +42 -14
  19. package/dist/host/tests/policy.test.ts +2 -2
  20. package/dist/host/tests/setupPolicy.ts +1 -1
  21. package/dist/src/core/index.cjs +13 -12
  22. package/dist/src/core/index.cjs.map +1 -1
  23. package/dist/src/core/index.d.cts +6 -6
  24. package/dist/src/core/index.d.ts +6 -6
  25. package/dist/src/core/index.js +13 -12
  26. package/dist/src/core/index.js.map +1 -1
  27. package/dist/src/server/index.cjs +7 -7
  28. package/dist/src/server/index.cjs.map +1 -1
  29. package/dist/src/server/index.d.cts +10 -10
  30. package/dist/src/server/index.d.ts +10 -10
  31. package/dist/src/server/index.js +7 -7
  32. package/dist/src/server/index.js.map +1 -1
  33. package/package.json +8 -8
@@ -467,20 +467,30 @@ 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 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.
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.
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 seed tail keeps stored content except for lookup results, which the plan replaces with stubs.
478
- - **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. 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.
479
- - **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.
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.
480
484
  - **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.
481
485
  - **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.
482
486
  - **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.
483
487
 
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.
489
+
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.
493
+
484
494
  The application supplies the following through `LedgerOptions`:
485
495
 
486
496
  - the judge, through the `judge` option;
@@ -501,7 +511,7 @@ The method has the following documented limits:
501
511
  - **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.
502
512
  - **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.
503
513
  - **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.
504
- - **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.
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.
505
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.
506
516
  - **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.
507
517
 
@@ -1264,50 +1274,64 @@ The `ledgers` module serves a conversation through an event-sourced briefing: th
1264
1274
 
1265
1275
  The following table lists the types the ledger declares, each with its shape:
1266
1276
 
1267
- | Type | Kind | Shape | Summary |
1268
- | ------------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1269
- | `LedgerCategory` | type | `'fact' \| 'rule' \| 'correction' \| 'request' \| 'opinion' \| 'chatter' \| 'distractor'` | Names the category the ledger files a message under, one of `LEDGER_CATEGORIES`. |
1270
- | `LedgerQuestion` | interface | `{ category, topic, amends, supersedes }` | Carries the wording of every question the ledger asks its judge. |
1271
- | `LedgerThreshold` | interface | `{ category, topic, amends, supersedes, correction }` | Carries the probability cutoff of each reading the ledger takes from its judge. |
1272
- | `LedgerTopic` | interface | `{ name, criterion, requested? }` | Carries one desk topic: the subject the ledger asks its judge about for statements and, when enabled, requests. |
1273
- | `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. |
1274
- | `LedgerNote` | interface | `{ cue, results, repeat, closure }` | Carries the text of each note the ledger writes into its conversation or returns to the model. |
1275
- | `LedgerRecallOptions` | interface | `{ limit? }` | Configures the ledger's `recall` tool. |
1276
- | `LedgerOwner` | interface | `{ id, names }` | Carries one owner a lookup result names: its id and the names it goes by. |
1277
- | `LedgerLookupResult` | interface | `{ ids, owners }` | Carries what a lookup handler read from one lookup result: the ids it names and the owners among them. |
1278
- | `LedgerLookupHandler` | type | `(args, text) => LedgerLookupResult \| undefined` | Reads one successful lookup result into the ids and owners it names. |
1279
- | `LedgerLookup` | interface | `{ tool, read }` | Carries one application lookup: the tool the model calls and the handler that reads its results. |
1280
- | `LedgerLookupReading` | interface | `{ id, name, arguments, text, result }` | Carries one successful lookup result as the ledger read it. |
1281
- | `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. |
1282
- | `LedgerRegistry` | interface | `{ ids, owners }` | Carries the ids the ledger's lookups named and the owners among them. |
1283
- | `LedgerGauge` | interface | `{ scale, overhead }` | Carries the price of a prompt in tokens, measured against the model the ledger serves. |
1284
- | `LedgerAgentOptions` | type | `Pick<AgentOptions, 'limit' \| 'timeout' \| 'on'>` | Selects the agent bounds and hooks a ledger passes through to the agent it builds. |
1285
- | `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. |
1286
- | `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. |
1287
- | `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. |
1288
- | `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. |
1289
- | `LedgerTokenSet` | interface | `{ ids, numbers }` | Carries the id-shaped tokens and the numbers of a text. |
1290
- | `LedgerWordSet` | interface | `{ words, names }` | Carries the lowercase words and non-opening capitalized names of a message. |
1291
- | `LedgerClassification` | interface | `{ quiet, categories, topics, amendments, supersessions }` | Carries the ledger's filing of its conversation's messages, keyed by message id. |
1292
- | `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. |
1293
- | `LedgerRecord` | interface | `{ key, title, members, lines }` | Carries one record: the live messages placed on one owner or on the rules, as lines. |
1294
- | `LedgerStaleSentence` | interface | `{ source, sentence, tokens }` | Carries one sentence a later message made stale, with the tokens the two share. |
1295
- | `LedgerProjection` | interface | `{ records, stale, orphans }` | Carries the records projected from a conversation, the stale sentences, and the live messages no record placed. |
1296
- | `LedgerProjectionInput` | interface | `{ system, exclusions, owners, messages, readings, entities, classification }` | Carries what a projection reads. |
1297
- | `LedgerProjectionRequest` | interface | `{ owners, topics }` | Carries the owners and the desk topics one request names, which select its records. |
1298
- | `LedgerCategoryHandler` | type | `(message) => LedgerCategory \| undefined` | Reads a message's category from its shape, or returns undefined to leave it to the judge. |
1299
- | `LedgerEntityHandler` | type | `(text, partial) => ReadonlySet<string>` | Lists the registry ids and owner ids a text names. |
1300
- | `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. |
1301
- | `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. |
1302
- | `ClassifierOutcome` | type | `'cached' \| 'skipped' \| 'resolved' \| 'failed' \| 'aborted'` | Names what became of one filing question. |
1303
- | `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. |
1304
- | `ClassifierResult` | interface | `{ judgments, usage?, readings, fault? }` | Carries the judgment keys one classification rests on and the judge usage it spent. |
1305
- | `ClassifierInterface` | interface | `{} plus classify, category, quiet, decisive, topics, classification` | Files a conversation's messages through a judge and reads the filing. |
1306
- | `GaugeCall` | interface | `{ estimate, prompt?, completion?, thinking?, tools }` | Carries one agent call as the gauge reads it. |
1307
- | `GaugeOptions` | interface | `{ scale, overhead, capacity, predict?, replay? }` | Configures a gauge: its starting price of a prompt and the context capacity it measures against. |
1308
- | `GaugeInterface` | interface | `{ scale, overhead } plus rate, remainder, reserve, room, observe` | Prices prompts in tokens and measures the room a request has left. |
1309
- | `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. |
1310
- | `LedgerErrorCode` | type | `'REQUEST' \| 'THRESHOLD' \| 'SHARE' \| 'CAPACITY' \| 'LIMIT' \| 'TOPIC' \| 'LOOKUP' \| 'GAUGE'` | Names the machine-readable conditions a `LedgerError` error reports. |
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. |
1311
1335
 
1312
1336
  #### Constants
1313
1337
 
@@ -1315,6 +1339,10 @@ The following table lists the constants that hold the ledger's categories, recor
1315
1339
 
1316
1340
  | API | Kind | Shape | Summary |
1317
1341
  | --------------------------- | ----- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
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. |
1318
1346
  | `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. |
1319
1347
  | `QUIET_CATEGORIES` | const | `readonly LedgerCategory[]` | Lists the categories whose messages the projection leaves out as quiet. |
1320
1348
  | `DECISIVE_CATEGORIES` | const | `readonly LedgerCategory[]` | Lists the categories whose messages state what the desk acts on, which the briefing renders. |
@@ -1323,6 +1351,8 @@ The following table lists the constants that hold the ledger's categories, recor
1323
1351
  | `LEDGER_OWNER_PREFIX` | const | `string` | Prefixes the key of an owner's record, which the owner's id follows. |
1324
1352
  | `LEDGER_QUESTIONS` | const | `LedgerQuestion` | Supplies the wording of every question the ledger asks its judge. |
1325
1353
  | `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. |
1326
1356
  | `DEFAULT_LEDGER_SHARE` | const | `LedgerShare` | Supplies the default prompt and tail shares. |
1327
1357
  | `DEFAULT_LEDGER_LIMIT` | const | `number` | Caps the tool-iteration turns of a ledger's agent at 8 turns. |
1328
1358
  | `DEFAULT_RECALL_LIMIT` | const | `number` | Caps the `recall` calls of one request at 2 calls. |
@@ -1376,25 +1406,31 @@ The following table lists the pure helpers that read text, project and select re
1376
1406
  | `extractTokens` | function | `(text) => LedgerTokenSet` | Reads the id-shaped tokens and the numbers of a text. |
1377
1407
  | `collectNames` | function | `(text) => readonly string[]` | Collects the capitalized name runs of a text, leaving out the run that opens each sentence. |
1378
1408
  | `identifyLookup` | function | `(name, args) => string \| undefined` | Identifies a lookup reading for projection by its tool name and normalized arguments. |
1379
- | `linkOwners` | function | `(readings, owners) => ReadonlyMap<string, string>` | Links each id-shaped lookup argument to its owner. |
1409
+ | `linkOwners` | function | `(readings, owners, link?) => ReadonlyMap<string, string>` | Links each eligible lookup argument id to its owner. |
1380
1410
  | `collectRegistry` | function | `(readings) => LedgerRegistry` | Collects the ids and the owner names the lookup readings named. |
1381
1411
  | `matchEntities` | function | `(registry, text, partial) => ReadonlySet<string>` | Matches the registry ids and owners a text names. |
1382
1412
  | `buildRecords` | function | `(input) => LedgerProjection` | Projects the owner records and the rules record from a conversation's messages. |
1383
1413
  | `selectRecords` | function | `(projection, request) => readonly LedgerRecord[]` | Selects a request's view of the projected records. |
1384
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. |
1385
1417
  | `collectProjectionIds` | function | `(projection) => ReadonlySet<string>` | Collects the live message ids placed in records or left without a record. |
1386
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. |
1387
1420
  | `buildRecallMessage` | function | `(topic) => Message` | Builds the placeholder assistant recall call used to price recall framing. |
1388
1421
  | `renderTopicNames` | function | `(topics) => string` | Renders topic names as a comma-separated list in their supplied order. |
1389
1422
  | `renderCauseChain` | function | `(error) => string` | Renders an error and its causes, stopping after 4 entries. |
1390
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. |
1391
1427
  | `splitWords` | function | `(part) => readonly string[]` | Splits a topic part into lowercase words with surrounding punctuation removed. |
1392
1428
  | `rankLedgerCut` | function | `(group, unsettled, category) => number` | Ranks a briefing source for removal before the next prompt. |
1393
1429
  | `renderLedgerRecord` | function | `(record) => string` | Renders one record as a heading and one list item per line. |
1394
1430
  | `renderLedgerPinned` | function | `(record) => string` | Renders one owner record under a `###` heading, which the briefing nests under its one `## Pinned` heading. |
1395
1431
  | `splitTopic` | function | `(topic) => readonly string[]` | Splits a recall topic at its joints. |
1396
- | `cutListing` | function | `(entries, room) => string` | Cuts entries to a room and names how many it left out. |
1397
- | `matchesCutLine` | function | `(line) => boolean` | Checks whether a line is the cut line `cutListing` writes. |
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. |
1398
1434
  | `normalizeArgument` | function | `(value) => string` | Normalizes a lookup argument string to the spelling that lookup identity and owner linking compare. |
1399
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. |
1400
1436
  | `renderLookupCall` | function | `(name, args) => string` | Renders a lookup call as its tool name and its JSON arguments. |
@@ -1770,7 +1806,7 @@ The conversation ledger. The `respond` method serves one request through to its
1770
1806
 
1771
1807
  #### `LedgerRequestInterface`
1772
1808
 
1773
- 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.
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.
1774
1810
 
1775
1811
  | Method | Returns | Summary |
1776
1812
  | --------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ |
@@ -1805,11 +1841,18 @@ const selection: Selection = {
1805
1841
  judgments: [],
1806
1842
  usage: { prompt: 30, completion: 2, total: 32 },
1807
1843
  }
1808
- request.adopt(selection, conversation.count)
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
+ })
1809
1851
  request.observe({ estimate: 40, tools: 2 }, conversation.count)
1810
1852
  request.spend({ prompt: 52, completion: 8, total: 60 })
1811
1853
  request.usage // { prompt: 82, completion: 10, total: 92 } — the selection's usage and the call's
1812
1854
  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
1813
1856
 
1814
1857
  request.admit('lookup_order', { id: 'BW-5512' })
1815
1858
  request.admit('lookup_order', { id: 'BW-5512' }) // throws Error(LEDGER_NOTES.repeat)
@@ -2552,7 +2595,7 @@ const result = await agent.generate() // { content: 'Refunds need a manager.', p
2552
2595
 
2553
2596
  ### Serving requests through a ledger
2554
2597
 
2555
- 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:
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:
2556
2599
 
2557
2600
  ```ts
2558
2601
  import type {
@@ -2635,6 +2678,8 @@ const gauge = await ledger.calibrate(AbortSignal.timeout(30_000))
2635
2678
  gauge.overhead // 120 — what advertising the tools adds to a prompt
2636
2679
  const first = await ledger.respond('Can Brightwater Studio get a refund on order BW-5512?')
2637
2680
  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
2638
2683
  const second = await ledger.respond('Does the Brightwater Studio refund need a manager?')
2639
2684
  second.content // 'Yes. Refunds over $100 need a manager.'
2640
2685
  briefings[0] // '## Rules\n- Refunds over $100 need a manager.' — no lookup has named an owner yet
@@ -2780,12 +2825,12 @@ The following test files back this guide:
2780
2825
  - [`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.
2781
2826
  - [`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`.
2782
2827
  - [`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.
2783
- - [`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.
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.
2784
2829
  - [`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.
2785
2830
  - [`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.
2786
2831
  - [`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.
2787
2832
  - [`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.
2788
- - [`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`.
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.
2789
2834
 
2790
2835
  ### Placement proofs
2791
2836
 
@@ -164,7 +164,7 @@ A `Shape` cell holds the constant's declared type.
164
164
  ### Guards
165
165
 
166
166
  Total `is*` guards over unknown input. None throws, none coerces, and each returns `false` for
167
- anything off-shape — including a hostile prototype, a symbol key, or a cyclic value. `isFieldValue`
167
+ anything off-shape — including an unexpected prototype, a symbol key, or a cyclic value. `isFieldValue`
168
168
  also refuses a number that is not finite, so `NaN` and `Infinity` are not field values, and
169
169
  `isFormSchema` reads structure alone: domain soundness is `auditSchema`'s question.
170
170
 
@@ -778,7 +778,7 @@ evaluateField(again, 'hunter3', { password: 'hunter2' })
778
778
  // [{ field: 'again', message: 'Both passwords must match' }]
779
779
  ```
780
780
 
781
- **`custom` runs on an absent value too**, after every named rule, which is what makes "required once
781
+ **`custom` runs on an absent value too**, after every named rule, which is what makes "required after
782
782
  the sibling says yes" expressible without a second mechanism. An unanswered field can therefore
783
783
  carry a `required` message and this validator's own together, and each one is a separate
784
784
  `FieldError`.
@@ -829,7 +829,7 @@ rule name would ever be read for it.
829
829
 
830
830
  ### Patterns and where trust lives
831
831
 
832
- `pattern` is authored regular-expression source, so it is the one rule that can carry an attack.
832
+ `pattern` is authored regular-expression source, so its evaluation can cause excessive backtracking.
833
833
  `PATTERN_LIMIT` bounds the source this package will compile, and the wire boundary keeps a schema
834
834
  data only. Each is deliberate.
835
835
 
@@ -880,7 +880,7 @@ package checks against.
880
880
  They bind at the schema door and the value door, and which door a limit sits at is the whole story.
881
881
 
882
882
  **The schema door reports.** `auditSchema` counts fields, groups, choices, names, strings, total
883
- text, and total nodes — `meta` included, since it is retained like everything else — and returns one
883
+ text, and total nodes — `meta` included, because it is retained like everything else — and returns one
884
884
  human diagnostic per breach, beside `PATTERN_LIMIT`'s. `createForm` throws `SCHEMA` carrying them
885
885
  and `parseForm` refuses the schema, so no over-budget schema is ever held.
886
886
 
@@ -1380,7 +1380,7 @@ submit can see more than one.
1380
1380
  failed stays the answer even when a listener then repairs or disables the field that failed. So
1381
1381
  `submit()` can return `{ success: false, error: [...] }` while `form.errors` reads `[]` and `valid`
1382
1382
  reads `true` the line after. The returned result is what the submit decided; the form is what the
1383
- form holds now.
1383
+ form holds.
1384
1384
 
1385
1385
  **A settlement made during listener work wins.** A listener that repairs the form and calls `submit`
1386
1386
  itself settles it, and that settlement is what the outer call returns — one `submit` event, one
@@ -1408,7 +1408,7 @@ That gives one sequence, and it is short:
1408
1408
  3. **Report a refusal through `invalidate`, not through a submit.** The message lands as a
1409
1409
  `FieldError` on the field it belongs to, `valid` turns false, and the form is still open for the
1410
1410
  person to fix it and for the host to try again.
1411
- 4. **Call `submit` only once the attempt succeeded.** That commits: `answer` resolves, `submit`
1411
+ 4. **Call `submit` only after the attempt succeeded.** That commits: `answer` resolves, `submit`
1412
1412
  fires, and the form is terminal.
1413
1413
 
1414
1414
  **`idle`, `submitting`, `succeeded`, and `failed` are the host's request states, not the form's.**
@@ -2064,7 +2064,7 @@ These invariants hold across [`src/core`](../src/core) and this guide.
2064
2064
  disabled or not: it reads the schema alone, so no declaration and no runtime set changes a
2065
2065
  diagnostic, and a passing schema carries none of the faults it enumerates whatever is disabled
2066
2066
  at runtime. It claims nothing beyond that list, and `custom` is outside it.
2067
- 10. **Guards are total and parsers refuse.** No `is*` throws for any input — hostile prototype,
2067
+ 10. **Guards are total and parsers refuse.** No `is*` throws for any input — unexpected prototype,
2068
2068
  symbol key, cycle, or depth. No `parse*` throws; each returns `undefined` on refusal. A
2069
2069
  guard-valid value is never refused by its parser, and every parsed result satisfies its guard.
2070
2070
  A pattern within `PATTERN_LIMIT` can still backtrack catastrophically; this package applies no
@@ -2157,7 +2157,7 @@ next change knows what it is reopening. `Layer` names who owns the concept, and
2157
2157
  `defineEntry`, `freezeEntry`, `serializeForm`, `extractGroups`, `auditSchema`, the budgets, and
2158
2158
  the control-by-rule matrix.
2159
2159
  - [`tests/src/core/validators.test.ts`](../tests/src/core/validators.test.ts) — every guard against
2160
- valid, off-shape, and hostile input, plus guard/parser soundness in both directions.
2160
+ valid, off-shape, and untrusted input, plus guard/parser soundness in both directions.
2161
2161
  - [`tests/src/core/parsers.test.ts`](../tests/src/core/parsers.test.ts) — `parseValue`,
2162
2162
  `parseValues`, `parseForm`, the wire round trip, and answer parking.
2163
2163
  - [`tests/src/core/cloners.test.ts`](../tests/src/core/cloners.test.ts) — every clone is owned,