@wrenautomation/birdwatch 0.0.0-stage → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/LICENSE.md +61 -0
  2. package/README.md +320 -2
  3. package/dist/app/cli.d.ts +4 -0
  4. package/dist/app/cli.js +149 -0
  5. package/dist/app/cli.js.map +1 -0
  6. package/dist/app/engine-cli.d.ts +44 -0
  7. package/dist/app/engine-cli.js +596 -0
  8. package/dist/app/engine-cli.js.map +1 -0
  9. package/dist/app/index.d.ts +6 -0
  10. package/dist/app/index.js +7 -0
  11. package/dist/app/index.js.map +1 -0
  12. package/dist/app/serve.d.ts +14 -0
  13. package/dist/app/serve.js +102 -0
  14. package/dist/app/serve.js.map +1 -0
  15. package/dist/document/body.d.ts +6 -0
  16. package/dist/document/body.js +18 -0
  17. package/dist/document/body.js.map +1 -0
  18. package/dist/document/check.d.ts +35 -0
  19. package/dist/document/check.js +68 -0
  20. package/dist/document/check.js.map +1 -0
  21. package/dist/document/extract.d.ts +81 -0
  22. package/dist/document/extract.js +226 -0
  23. package/dist/document/extract.js.map +1 -0
  24. package/dist/document/index.d.ts +11 -0
  25. package/dist/document/index.js +12 -0
  26. package/dist/document/index.js.map +1 -0
  27. package/dist/document/model.d.ts +10 -0
  28. package/dist/document/model.js +2 -0
  29. package/dist/document/model.js.map +1 -0
  30. package/dist/document/readers.d.ts +24 -0
  31. package/dist/document/readers.js +87 -0
  32. package/dist/document/readers.js.map +1 -0
  33. package/dist/document/types.d.ts +99 -0
  34. package/dist/document/types.js +93 -0
  35. package/dist/document/types.js.map +1 -0
  36. package/dist/engine/agent.d.ts +475 -0
  37. package/dist/engine/agent.js +990 -0
  38. package/dist/engine/agent.js.map +1 -0
  39. package/dist/engine/canonical.d.ts +4 -0
  40. package/dist/engine/canonical.js +55 -0
  41. package/dist/engine/canonical.js.map +1 -0
  42. package/dist/engine/context.d.ts +9 -0
  43. package/dist/engine/context.js +141 -0
  44. package/dist/engine/context.js.map +1 -0
  45. package/dist/engine/cost.d.ts +13 -0
  46. package/dist/engine/cost.js +31 -0
  47. package/dist/engine/cost.js.map +1 -0
  48. package/dist/engine/index.d.ts +16 -0
  49. package/dist/engine/index.js +17 -0
  50. package/dist/engine/index.js.map +1 -0
  51. package/dist/engine/judge.d.ts +158 -0
  52. package/dist/engine/judge.js +323 -0
  53. package/dist/engine/judge.js.map +1 -0
  54. package/dist/engine/people.d.ts +34 -0
  55. package/dist/engine/people.js +125 -0
  56. package/dist/engine/people.js.map +1 -0
  57. package/dist/engine/plan.d.ts +6 -0
  58. package/dist/engine/plan.js +7 -0
  59. package/dist/engine/plan.js.map +1 -0
  60. package/dist/engine/plans/index.d.ts +19 -0
  61. package/dist/engine/plans/index.js +104 -0
  62. package/dist/engine/plans/index.js.map +1 -0
  63. package/dist/engine/ports.d.ts +76 -0
  64. package/dist/engine/ports.js +28 -0
  65. package/dist/engine/ports.js.map +1 -0
  66. package/dist/engine/recall.d.ts +42 -0
  67. package/dist/engine/recall.js +71 -0
  68. package/dist/engine/recall.js.map +1 -0
  69. package/dist/engine/state.d.ts +96 -0
  70. package/dist/engine/state.js +162 -0
  71. package/dist/engine/state.js.map +1 -0
  72. package/dist/engine/steps.d.ts +98 -0
  73. package/dist/engine/steps.js +435 -0
  74. package/dist/engine/steps.js.map +1 -0
  75. package/dist/engine/tree.d.ts +76 -0
  76. package/dist/engine/tree.js +148 -0
  77. package/dist/engine/tree.js.map +1 -0
  78. package/dist/engine/types.d.ts +250 -0
  79. package/dist/engine/types.js +168 -0
  80. package/dist/engine/types.js.map +1 -0
  81. package/dist/engine/view.d.ts +138 -0
  82. package/dist/engine/view.js +188 -0
  83. package/dist/engine/view.js.map +1 -0
  84. package/dist/index.d.ts +15 -0
  85. package/dist/index.js +16 -0
  86. package/dist/index.js.map +1 -0
  87. package/dist/ledger/files.d.ts +39 -0
  88. package/dist/ledger/files.js +113 -0
  89. package/dist/ledger/files.js.map +1 -0
  90. package/dist/ledger/ids.d.ts +4 -0
  91. package/dist/ledger/ids.js +9 -0
  92. package/dist/ledger/ids.js.map +1 -0
  93. package/dist/ledger/index.d.ts +11 -0
  94. package/dist/ledger/index.js +12 -0
  95. package/dist/ledger/index.js.map +1 -0
  96. package/dist/ledger/ledger.d.ts +46 -0
  97. package/dist/ledger/ledger.js +105 -0
  98. package/dist/ledger/ledger.js.map +1 -0
  99. package/dist/ledger/memory.d.ts +19 -0
  100. package/dist/ledger/memory.js +19 -0
  101. package/dist/ledger/memory.js.map +1 -0
  102. package/dist/ledger/records.d.ts +1424 -0
  103. package/dist/ledger/records.js +292 -0
  104. package/dist/ledger/records.js.map +1 -0
  105. package/dist/sources/arxiv.d.ts +105 -0
  106. package/dist/sources/arxiv.js +321 -0
  107. package/dist/sources/arxiv.js.map +1 -0
  108. package/dist/sources/exa.d.ts +19 -0
  109. package/dist/sources/exa.js +59 -0
  110. package/dist/sources/exa.js.map +1 -0
  111. package/dist/sources/fetcher.d.ts +35 -0
  112. package/dist/sources/fetcher.js +67 -0
  113. package/dist/sources/fetcher.js.map +1 -0
  114. package/dist/sources/google.d.ts +16 -0
  115. package/dist/sources/google.js +64 -0
  116. package/dist/sources/google.js.map +1 -0
  117. package/dist/sources/index.d.ts +17 -0
  118. package/dist/sources/index.js +18 -0
  119. package/dist/sources/index.js.map +1 -0
  120. package/dist/sources/junk.d.ts +10 -0
  121. package/dist/sources/junk.js +16 -0
  122. package/dist/sources/junk.js.map +1 -0
  123. package/dist/sources/ladder.d.ts +47 -0
  124. package/dist/sources/ladder.js +158 -0
  125. package/dist/sources/ladder.js.map +1 -0
  126. package/dist/sources/ledger.d.ts +7 -0
  127. package/dist/sources/ledger.js +35 -0
  128. package/dist/sources/ledger.js.map +1 -0
  129. package/dist/sources/paste.d.ts +8 -0
  130. package/dist/sources/paste.js +22 -0
  131. package/dist/sources/paste.js.map +1 -0
  132. package/dist/sources/searxng.d.ts +11 -0
  133. package/dist/sources/searxng.js +38 -0
  134. package/dist/sources/searxng.js.map +1 -0
  135. package/dist/sources/sites.d.ts +53 -0
  136. package/dist/sources/sites.js +285 -0
  137. package/dist/sources/sites.js.map +1 -0
  138. package/dist/sources/ytdlp.d.ts +43 -0
  139. package/dist/sources/ytdlp.js +117 -0
  140. package/dist/sources/ytdlp.js.map +1 -0
  141. package/package.json +61 -3
@@ -0,0 +1,475 @@
1
+ /**
2
+ * The engine driven by an agent: each step as one call over a run's ledger. Claude Code (or any
3
+ * agent) plans, triages, reviews and stops in its own head; the engine does the fixed work
4
+ * (search, open, extract through the quote gate, check) and keeps the records. Every record the
5
+ * agent writes carries its id and, on a decision, a why; the person's words come through it
6
+ * marked `from: human`. The budget is a guard rail: the brief shows it, nothing cuts a query or
7
+ * stops a round by it.
8
+ */
9
+ import { type DocumentRecord, type DraftRecord, type FollowAs, type From, type HitRecord, LedgerRecord, type SourceClass, type Step } from "../ledger/records.js";
10
+ import { costOf } from "./cost.js";
11
+ import { type JudgeStats } from "./judge.js";
12
+ import { type PersonView, type Unfollowed } from "./people.js";
13
+ import { type AskKind, type Criterion, type Edge, PlanFile, QueryTree, type TreeGuide, type YieldRow } from "./plan.js";
14
+ import type { Deps } from "./ports.js";
15
+ import { type Pointer, type RunState } from "./state.js";
16
+ import { type ChildView } from "./tree.js";
17
+ /** Who a record is from: the agent (`ai`, its id) or the person through it (`human`, their name). */
18
+ export interface Who {
19
+ from: From;
20
+ by: string;
21
+ }
22
+ /** What one command did: the step's word and every record it wrote, in order. */
23
+ export interface Did {
24
+ run: string;
25
+ round: number;
26
+ step: Step;
27
+ ok: boolean;
28
+ note?: string;
29
+ wrote: Shown[];
30
+ }
31
+ /** A record as a command prints it: a document's text replaced by its length. */
32
+ export type Shown = LedgerRecord | (Omit<DocumentRecord, "text"> & {
33
+ chars: number;
34
+ });
35
+ export declare const shown: (r: LedgerRecord) => Shown;
36
+ export interface AskInput {
37
+ text: string;
38
+ kind: AskKind;
39
+ known?: readonly string[];
40
+ /** What the ask takes as given: the tree tests each in a `premise` facet. */
41
+ premises?: readonly string[];
42
+ /** The person's tests of a good source: the judge asks each on every hit and page. */
43
+ criteria?: readonly Criterion[];
44
+ site?: string;
45
+ }
46
+ export interface PlanInput {
47
+ /** Absent: a new run. Present: the next round of it, after an edge that said again. */
48
+ run?: string;
49
+ /** A new run's ask; a later round takes the last snapshot's. */
50
+ ask?: AskInput;
51
+ /** Its `sources` are the run's allow-list, every name one this machine has. */
52
+ planFile: PlanFile;
53
+ /** Openers let in only to open and follow, never to search. Absent: the last snapshot's. */
54
+ opens?: readonly string[];
55
+ /** The model id the extract will use, for the snapshot; null when none. */
56
+ model: string | null;
57
+ /** A new run's parent, and why this child. */
58
+ parent?: {
59
+ run: string;
60
+ why: string;
61
+ };
62
+ }
63
+ /**
64
+ * Opens a round: writes its snapshot (the ask, with what is known and what the last round left
65
+ * open, the allow-list, the budget) and the plan step's `done`. No queries: the agent's come
66
+ * through `search`, never capped.
67
+ */
68
+ export declare function planRound(deps: Deps, input: PlanInput): Promise<Did>;
69
+ export interface QueryInput {
70
+ terms: string;
71
+ why: string;
72
+ site?: string;
73
+ /** The tree's facet it serves, when the agent adds one more leaf by hand. */
74
+ facet?: string;
75
+ }
76
+ /** Writes the agent's queries, then runs the fetch step: every searcher on every unsearched query of the round. */
77
+ export declare function search(deps: Deps, run: string, queries: readonly QueryInput[], who: Who): Promise<Did>;
78
+ export interface FollowInput {
79
+ as: FollowAs;
80
+ why: string;
81
+ /** Where to start: a page or a profile. Absent: the document's URL. */
82
+ url?: string;
83
+ /** The read page that led here. */
84
+ document?: string;
85
+ /** Follow sources this machine has that the run lacks: they join to follow, never to search. */
86
+ with?: readonly string[];
87
+ }
88
+ /**
89
+ * What a person does after a good page: its channel's or author's own posts, or pages like it.
90
+ * Writes a query with `follow`, then runs the fetch step: its hits go through the same calls,
91
+ * reads and checks, and the tree's read cap bounds them.
92
+ */
93
+ export declare function follow(deps: Deps, run: string, input: FollowInput, who: Who): Promise<Did>;
94
+ /** One try of a facet as the brief shows it: its queries, each with the hits it wrote and the known ones it found again. */
95
+ export interface TryView {
96
+ tier: number;
97
+ queries: {
98
+ id: string;
99
+ terms: string;
100
+ hits: number;
101
+ again: number;
102
+ }[];
103
+ /** New hits the try wrote, summed. */
104
+ hits: number;
105
+ }
106
+ export interface FacetView {
107
+ name: string;
108
+ tries: TryView[];
109
+ /** New hits over every try. */
110
+ hits: number;
111
+ /** Hits a query of this facet found (written or found again) that triage kept. */
112
+ kept: number;
113
+ /** Hits of this facet no call has named yet: the next try waits on them. */
114
+ uncalled: number;
115
+ /** The facet reached the guide's `thin` in kept hits: no more tries. */
116
+ enough: boolean;
117
+ /** The source classes it needs, as its queries say. */
118
+ needs: string[];
119
+ /** Kept hits whose class (the agent's, else the judge's guess) is one it needs. */
120
+ fit: number;
121
+ /** Kept hits with any class known or guessed: `fit` counts only when one is. */
122
+ guessed: number;
123
+ /** Read pages with a kept finding, per class. */
124
+ classes: Partial<Record<SourceClass | "unclassed", number>>;
125
+ /** It needs classes; pages were read and none is of one. */
126
+ lacks: boolean;
127
+ }
128
+ export interface TreeView {
129
+ thin: number;
130
+ facets: FacetView[];
131
+ /** Facets the guide names that no query of the round served, dead ones left out. */
132
+ uncovered: string[];
133
+ /** Facets the agent gave up on: no try runs for them again. */
134
+ dead: string[];
135
+ }
136
+ /** The round's queries by facet and try, with what each wrote and what triage kept: rebuilt from the records. */
137
+ export declare function treeView(state: RunState, round: number, guide: TreeGuide): TreeView;
138
+ export interface TreeDid extends Did {
139
+ tree: TreeView;
140
+ }
141
+ export interface TreeOptions {
142
+ /** The next try of every facet that has one, whatever triage kept: no thin rule, no wait. */
143
+ all?: boolean;
144
+ }
145
+ /**
146
+ * One tier of the round's query tree: for each facet in the tree, its next try, in one fetch.
147
+ * A facet with no query yet this round runs its first try. A facet that ran one waits for
148
+ * triage (a call on each of its hits); then, under the guide's `thin` in kept hits, it runs the
149
+ * next try; at `thin` it is done; out of tries, it is a gap. So the agent runs the same tree
150
+ * again after each triage, and the tree falls through on what the agent kept, never on what a
151
+ * searcher returned (every searcher returns a page). `all` runs every facet's next try at once.
152
+ * A page two facets reached is a `found` on the first facet's hit, and the brief ranks it above
153
+ * one facet's. Never capped: the agent wrote the tree.
154
+ */
155
+ export declare function searchTree(deps: Deps, run: string, tree: QueryTree, who: Who, options?: TreeOptions): Promise<TreeDid>;
156
+ export interface OpenInput {
157
+ /** Hits to keep (a call in the agent's name) and read. */
158
+ hits?: readonly string[];
159
+ /** Pages the agent names itself: a hit each, kept and read. */
160
+ urls?: readonly string[];
161
+ /** Why these: required with `hits` or `urls`. */
162
+ why?: string;
163
+ /**
164
+ * Open sources this machine has that the run's allow-list lacks (a ladder that came after the
165
+ * plan). Written as a new snapshot in the agent's name, so the ledger says when the list grew.
166
+ */
167
+ with?: readonly string[];
168
+ }
169
+ /** Kept hits of any round with no document yet. */
170
+ export declare const unread: (state: RunState) => HitRecord[];
171
+ /**
172
+ * Keeps the hits named (and writes a hit per URL named), then runs the read step over every
173
+ * kept hit of the run that has no document. No names: the reads alone.
174
+ */
175
+ export declare function open(deps: Deps, run: string, input: OpenInput, who: Who): Promise<Did>;
176
+ /** Documents of any round the extractor has no verdict on. */
177
+ export declare const unjudged: (state: RunState) => DocumentRecord[];
178
+ /** The extract step over the documents named, else every one of the run without a verdict. */
179
+ export declare function extract(deps: Deps, run: string, documents?: readonly string[]): Promise<Did>;
180
+ /** Kept findings the run's patterns rest on that no check has read. */
181
+ export declare const uncheckedOf: (state: RunState, ids: readonly string[]) => string[];
182
+ /** Findings the judge says credit another named source. */
183
+ export declare const citesOf: (state: RunState, ids: readonly string[]) => string[];
184
+ /**
185
+ * The check over the findings named; else, with `patterns`, every unchecked finding a pattern
186
+ * rests on; else a sample spread over documents: `n`, or the budget's `checks` or a tenth of
187
+ * the kept findings, whichever is more.
188
+ */
189
+ export declare function check(deps: Deps, run: string, input?: {
190
+ findings?: readonly string[];
191
+ n?: number;
192
+ patterns?: boolean;
193
+ }): Promise<Did>;
194
+ /** What the agent or the person adds by hand. */
195
+ export type Addition = {
196
+ type: "query";
197
+ terms: string;
198
+ why: string;
199
+ site?: string;
200
+ facet?: string;
201
+ } | {
202
+ type: "finding";
203
+ document: string;
204
+ text: string;
205
+ quote: string;
206
+ } | {
207
+ type: "check";
208
+ on: string;
209
+ ok: boolean;
210
+ why: string;
211
+ } | {
212
+ type: "call";
213
+ on: string;
214
+ verdict: "keep" | "drop";
215
+ why: string;
216
+ } | {
217
+ type: "edge";
218
+ next: Edge["next"];
219
+ to?: Edge["to"];
220
+ why: string;
221
+ } | {
222
+ type: "steer";
223
+ text: string;
224
+ } | {
225
+ type: "gap";
226
+ note: string;
227
+ on?: string;
228
+ } | {
229
+ type: "pattern";
230
+ text: string;
231
+ findings: string[];
232
+ } | {
233
+ type: "draft";
234
+ for: string;
235
+ items: DraftInput[];
236
+ } | {
237
+ type: "class";
238
+ on: string;
239
+ class: SourceClass;
240
+ why: string;
241
+ } | {
242
+ type: "dead";
243
+ facet: string;
244
+ why: string;
245
+ } | {
246
+ type: "person";
247
+ name: string;
248
+ profiles: string[];
249
+ aka: string[];
250
+ why: string;
251
+ };
252
+ /** One item of a draft as the agent writes it: cites are finding or pattern ids. */
253
+ export interface DraftInput {
254
+ title?: string | null;
255
+ body?: string | null;
256
+ cites?: string[] | null;
257
+ }
258
+ export interface Added {
259
+ record: Shown;
260
+ /** What the agent should know: an edge past the budget, a finding on a dropped document. */
261
+ warnings: string[];
262
+ }
263
+ /**
264
+ * One record in the agent's or the person's name. A query, finding or pattern lands in the
265
+ * current round; a call, edge, steer or gap in the round it is about (the one just reviewed,
266
+ * between rounds). A finding goes through the quote gate: its quote must be on the document,
267
+ * word for word, or the add fails with the gate's why. A pattern names kept findings; its
268
+ * source count is counted here, never claimed. No `step`: a hand-written record has none.
269
+ */
270
+ export declare function add(deps: Deps, run: string, a: Addition, who: Who): Promise<Added>;
271
+ /** What the agent takes from the judge in bulk: classes over a bar, or calls on uncalled hits. */
272
+ export type Acceptance = {
273
+ take: "class";
274
+ min: number;
275
+ why: string;
276
+ } | {
277
+ take: "keep";
278
+ over: number;
279
+ why: string;
280
+ } | {
281
+ take: "drop";
282
+ under: number;
283
+ why: string;
284
+ };
285
+ /**
286
+ * The judge's guesses over a bar, written in the agent's name with its why and the judge's
287
+ * number: a class on each document with none, or a keep or drop on each uncalled hit by how
288
+ * likely it serves the ask. The agent sets the bar and owns the records; the judge decides none.
289
+ */
290
+ export declare function accept(deps: Deps, run: string, a: Acceptance, who: Who): Promise<{
291
+ wrote: Shown[];
292
+ skipped: number;
293
+ }>;
294
+ /** What `learn` changes on a plan file. Every field is optional; the version always moves. */
295
+ export interface PlanChanges {
296
+ sources?: string[];
297
+ budget?: Partial<PlanFile["budget"]>;
298
+ age?: string;
299
+ rules?: string[];
300
+ tree?: TreeGuide;
301
+ runs?: PlanFile["runs"];
302
+ }
303
+ /**
304
+ * The next version of a plan file: the current one with the changes, version plus one. Pure:
305
+ * the ledger writes it (`birdwatch learn`), at the end of a run the agent and the person agreed
306
+ * was good. The sources stay an allow-list a run narrows, never widens; `learn` is how it widens.
307
+ */
308
+ export declare function tunePlan(current: PlanFile, changes: PlanChanges): PlanFile;
309
+ /** A hit as the brief shows it: the view, its id, round and queries. */
310
+ export type HitBrief = Omit<HitRecord, "type" | "run" | "step" | "at" | "from" | "by" | "key"> & {
311
+ /** The facets whose queries found it. */
312
+ facets: string[];
313
+ /**
314
+ * The judge's hint: how likely it serves the ask, whose side wrote it, its class. The brief
315
+ * lists hits by facets plus `serves`, most first. A hint: the agent calls each.
316
+ */
317
+ judge?: {
318
+ serves: number;
319
+ side: string;
320
+ class: string;
321
+ criteria?: Record<string, number>;
322
+ };
323
+ };
324
+ export interface Brief {
325
+ run: string;
326
+ round: number;
327
+ /** The next step the fold points at; null when an edge said stop. */
328
+ next: Pointer | null;
329
+ /** The last edge's why, or the step that gave up. */
330
+ note: string | null;
331
+ ask: NonNullable<RunState["snapshot"]>["ask"] | null;
332
+ budget: NonNullable<RunState["snapshot"]>["budget"] | null;
333
+ sources: string[];
334
+ planFile: NonNullable<RunState["snapshot"]>["planFile"] | null;
335
+ /** The kind's word for the agent, from its plan file: how much a source's age counts, and the rules to heed when it plans and triages. */
336
+ guide: {
337
+ age: string | null;
338
+ rules: string[];
339
+ } | null;
340
+ /** What the person said, oldest first. */
341
+ steer: string[];
342
+ /** What the last round left open: its edge's why, its gaps, the person's calls. */
343
+ open: string[];
344
+ /** This round's gaps, as lines. */
345
+ gaps: string[];
346
+ findings: {
347
+ kept: {
348
+ id: string;
349
+ round: number;
350
+ text: string;
351
+ quote?: string;
352
+ url: string;
353
+ date?: string;
354
+ /** The failed finding this one narrows. */
355
+ fixes?: string;
356
+ }[];
357
+ dropped: number;
358
+ };
359
+ checks: {
360
+ on: string;
361
+ ok: boolean;
362
+ why: string;
363
+ }[];
364
+ /** What the agent says several findings say together, its sources counted now over kept findings. */
365
+ patterns: {
366
+ id: string;
367
+ round: number;
368
+ text: string;
369
+ findings: string[];
370
+ /** Distinct sites over its kept findings; each forum thread counts on its own. */
371
+ sources: number;
372
+ /** Sources per class; `unclassed` counts the sites with none. */
373
+ classes: Partial<Record<SourceClass | "unclassed", number>>;
374
+ /** Every classed source is a vendor. */
375
+ echo: boolean;
376
+ /** Kept findings it rests on that no check has read. */
377
+ unchecked: string[];
378
+ /** Findings the judge says credit another source (a survey, a report): read that one. */
379
+ cites: string[];
380
+ }[];
381
+ /** The run this one is a child of. */
382
+ parent: {
383
+ run: string;
384
+ round: number;
385
+ why: string;
386
+ } | null;
387
+ /** The runs that name this one as parent, and what the tree under it read and cost. */
388
+ children: ChildView[];
389
+ treeCost: ReturnType<typeof costOf> | null;
390
+ /** The asks from the root down to this run's parent, each with why it began: to see drift. */
391
+ lineage: {
392
+ run: string;
393
+ ask: string;
394
+ why?: string;
395
+ }[];
396
+ /** Pages the whole tree may still read: the one hard stop. Null on a run with no cap. */
397
+ treeRoom: {
398
+ root: string;
399
+ cap: number;
400
+ read: number;
401
+ left: number;
402
+ } | null;
403
+ /** Facets given up on, with why. */
404
+ dead: {
405
+ facet: string;
406
+ why: string;
407
+ }[];
408
+ /** People across platforms, most kept findings first. */
409
+ people: PersonView[];
410
+ /** Kept pages no follow started from and no person owns: `follow` their author's posts or pages like them; a paper's refs or citers. */
411
+ unfollowed: Unfollowed[];
412
+ /** The latest rough draft, or null: never the final. */
413
+ draft: {
414
+ id: string;
415
+ round: number;
416
+ for: string;
417
+ items: DraftRecord["items"];
418
+ } | null;
419
+ verdicts: {
420
+ document: string;
421
+ url: string;
422
+ quality: string;
423
+ gap?: string;
424
+ }[];
425
+ /** This round's query tree with what each try wrote; null when the round's queries are flat. */
426
+ tree: TreeView | null;
427
+ hits: {
428
+ uncalled: HitBrief[];
429
+ toRead: {
430
+ id: string;
431
+ url: string;
432
+ }[];
433
+ read: number;
434
+ total: number;
435
+ };
436
+ documents: {
437
+ /**
438
+ * Best first by the judge: the mean of its criteria yeses when the ask has criteria, else
439
+ * `worth` (its trial score); pages it has not judged last. A hint only: the agent picks.
440
+ */
441
+ toExtract: {
442
+ id: string;
443
+ url: string;
444
+ worth?: number;
445
+ criteria?: Record<string, number>;
446
+ }[];
447
+ /**
448
+ * Documents with a kept finding and no class: class them before the patterns count. `guess`
449
+ * is the judge's; `accept <run> class` takes every guess over a bar.
450
+ */
451
+ unclassed: {
452
+ id: string;
453
+ url: string;
454
+ guess?: {
455
+ class: string;
456
+ p: number;
457
+ };
458
+ }[];
459
+ total: number;
460
+ };
461
+ edges: {
462
+ round: number;
463
+ next: string;
464
+ to?: string;
465
+ why: string;
466
+ by: string;
467
+ }[];
468
+ /** What the allow-list's sources yielded over every run. */
469
+ yield: YieldRow[];
470
+ /** What the judge did and how often the agent and the check agreed with it. */
471
+ judge: JudgeStats;
472
+ cost: ReturnType<typeof costOf>;
473
+ }
474
+ /** The brief, as JSON: everything the agent needs to plan, triage, review and stop. */
475
+ export declare function brief(deps: Deps, run: string): Promise<Brief>;