@vibe-commit/capture 0.8.0 → 0.10.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 (111) hide show
  1. package/README.md +149 -1
  2. package/dist/agents/claude_code.js +13 -0
  3. package/dist/agents/claude_code.js.map +1 -1
  4. package/dist/agents/codex_cli.js +11 -0
  5. package/dist/agents/codex_cli.js.map +1 -1
  6. package/dist/agents/cursor.js +7 -1
  7. package/dist/agents/cursor.js.map +1 -1
  8. package/dist/agents/registry.d.ts +7 -0
  9. package/dist/agents/registry.js +9 -0
  10. package/dist/agents/registry.js.map +1 -1
  11. package/dist/agents/types.d.ts +32 -0
  12. package/dist/agents/types.js.map +1 -1
  13. package/dist/bounded_id.d.ts +29 -0
  14. package/dist/bounded_id.js +42 -0
  15. package/dist/bounded_id.js.map +1 -0
  16. package/dist/codex_folders.d.ts +340 -0
  17. package/dist/codex_folders.js +1448 -0
  18. package/dist/codex_folders.js.map +1 -0
  19. package/dist/commands/backfill.d.ts +29 -7
  20. package/dist/commands/backfill.js +387 -109
  21. package/dist/commands/backfill.js.map +1 -1
  22. package/dist/commands/connect.d.ts +1 -1
  23. package/dist/commands/connect.js +1 -1
  24. package/dist/commands/connect.js.map +1 -1
  25. package/dist/commands/connect_picker.js +48 -7
  26. package/dist/commands/connect_picker.js.map +1 -1
  27. package/dist/commands/finalize.d.ts +67 -0
  28. package/dist/commands/finalize.js +452 -114
  29. package/dist/commands/finalize.js.map +1 -1
  30. package/dist/commands/scan.d.ts +28 -0
  31. package/dist/commands/scan.js +11 -0
  32. package/dist/commands/scan.js.map +1 -1
  33. package/dist/commands/status_machine.js +47 -10
  34. package/dist/commands/status_machine.js.map +1 -1
  35. package/dist/commands/why.d.ts +19 -1
  36. package/dist/commands/why.js +35 -3
  37. package/dist/commands/why.js.map +1 -1
  38. package/dist/commit_files.d.ts +64 -0
  39. package/dist/commit_files.js +83 -0
  40. package/dist/commit_files.js.map +1 -0
  41. package/dist/consent.d.ts +22 -0
  42. package/dist/consent.js +38 -1
  43. package/dist/consent.js.map +1 -1
  44. package/dist/copy/strings.d.ts +55 -9
  45. package/dist/copy/strings.js +60 -12
  46. package/dist/copy/strings.js.map +1 -1
  47. package/dist/folder_grants.d.ts +44 -0
  48. package/dist/folder_grants.js +101 -0
  49. package/dist/folder_grants.js.map +1 -0
  50. package/dist/git.d.ts +26 -4
  51. package/dist/git.js +82 -11
  52. package/dist/git.js.map +1 -1
  53. package/dist/hooks/entry.d.ts +30 -50
  54. package/dist/hooks/entry.js +595 -559
  55. package/dist/hooks/entry.js.map +1 -1
  56. package/dist/hooks/fire_lock.d.ts +31 -0
  57. package/dist/hooks/fire_lock.js +120 -12
  58. package/dist/hooks/fire_lock.js.map +1 -1
  59. package/dist/hooks/post_commit.d.ts +9 -0
  60. package/dist/hooks/post_commit.js +9 -5
  61. package/dist/hooks/post_commit.js.map +1 -1
  62. package/dist/machine_state.d.ts +44 -1
  63. package/dist/machine_state.js +75 -12
  64. package/dist/machine_state.js.map +1 -1
  65. package/dist/oauth/discovery.js +2 -1
  66. package/dist/oauth/discovery.js.map +1 -1
  67. package/dist/oauth/pkce.js +2 -1
  68. package/dist/oauth/pkce.js.map +1 -1
  69. package/dist/paths.d.ts +34 -1
  70. package/dist/paths.js +62 -12
  71. package/dist/paths.js.map +1 -1
  72. package/dist/physical_path.d.ts +46 -0
  73. package/dist/physical_path.js +151 -0
  74. package/dist/physical_path.js.map +1 -0
  75. package/dist/picker.d.ts +52 -3
  76. package/dist/picker.js +129 -5
  77. package/dist/picker.js.map +1 -1
  78. package/dist/picker_checklist.d.ts +9 -1
  79. package/dist/picker_checklist.js +41 -2
  80. package/dist/picker_checklist.js.map +1 -1
  81. package/dist/policy.d.ts +9 -1
  82. package/dist/policy.js +11 -2
  83. package/dist/policy.js.map +1 -1
  84. package/dist/post.d.ts +25 -0
  85. package/dist/post.js +49 -13
  86. package/dist/post.js.map +1 -1
  87. package/dist/project.d.ts +89 -0
  88. package/dist/project.js +123 -0
  89. package/dist/project.js.map +1 -1
  90. package/dist/redact.d.ts +77 -2
  91. package/dist/redact.js +713 -47
  92. package/dist/redact.js.map +1 -1
  93. package/dist/session_targets.d.ts +713 -0
  94. package/dist/session_targets.js +2602 -0
  95. package/dist/session_targets.js.map +1 -0
  96. package/dist/spool.d.ts +23 -5
  97. package/dist/spool.js +37 -6
  98. package/dist/spool.js.map +1 -1
  99. package/dist/spool_union.d.ts +51 -0
  100. package/dist/spool_union.js +57 -0
  101. package/dist/spool_union.js.map +1 -0
  102. package/dist/state.d.ts +5 -0
  103. package/dist/state.js +19 -1
  104. package/dist/state.js.map +1 -1
  105. package/dist/text_tail.d.ts +8 -0
  106. package/dist/text_tail.js +19 -0
  107. package/dist/text_tail.js.map +1 -0
  108. package/dist/version.d.ts +1 -1
  109. package/dist/version.js +1 -1
  110. package/dist/version.js.map +1 -1
  111. package/package.json +3 -3
@@ -0,0 +1,340 @@
1
+ /**
2
+ * Codex record isolation (any-folder capture, part (b)): the EFFECTIVE FOLDER of a Codex rollout record.
3
+ *
4
+ * A Codex record names a folder on very few types (`session_meta` and `turn_context` carry `payload.cwd`, a finished command item carries `item.cwd` as a
5
+ * `file://` URL, `thread_settings_applied` carries `thread_settings.cwd`). Everything else (the user's prompt, the agent's prose, a command's output) runs
6
+ * "somewhere" without saying where, so a copy for repo A of a session that also worked in repo B would carry B's turns. Every record therefore gets an
7
+ * effective folder, told by these rules:
8
+ *
9
+ * 1. a record that carries its OWN folder (`payload.cwd`, `payload.item.cwd`, `payload.thread_settings.cwd`) takes it; an unreadable one is UNKNOWN. Only
10
+ * `session_meta` and `turn_context` CHANGE the turn folder.
11
+ * 2. a CALL takes the folders its tool ran in. The rule is per tool name and DEFAULT DENY: `exec_command` / `shell` / `local_shell_call` (workdir, else the
12
+ * turn folder, plus the files of a patch they carry), `apply_patch` (the files it changes), `exec` (the whole-literal workdirs of the program, the turn
13
+ * folder, and the folders of the sessions it polls), `write_stdin` (the folders of the session it polls), `wait` (the folders of the cell it waits on),
14
+ * `view_image` (its path), `update_plan` (the turn folder). ANY OTHER tool name, in either call form, is UNKNOWN.
15
+ * 3. an OUTPUT takes the folders of its call, matched by `call_id`; an output whose call is not known is UNKNOWN. A process an `exec_command` started and a
16
+ * cell an `exec` program started are named in the output (`Process running with session ID <n>`, `Script running with cell ID <id>`, a `"session_id"`
17
+ * field): the SESSION and CELL maps learned from those lines are how a later `write_stdin` or `wait` is placed.
18
+ * 4. otherwise the TURN FOLDER in force, the latest `session_meta` / `turn_context` cwd at or before the record in the SAME stream.
19
+ *
20
+ * The common failure the rules are built against: a record whose folder cannot actually be read must come out UNKNOWN, never as a KNOWN but wrong folder
21
+ * (usually the turn folder), because UNKNOWN is withheld from a multi-repo copy and a wrong known folder is kept.
22
+ *
23
+ * Pure: no filesystem, no clock. The caller supplies the turn folder, the call table and the two maps, so the resolver's scan (which writes the checkpoint)
24
+ * and the redactor (which reads it) share ONE definition of "where a record ran".
25
+ */
26
+ /** A folder given as a `file://` URL (a finished command item's `cwd`) or as a path, as a plain absolute path; null when it is neither. */
27
+ export declare function folderFromValue(value: unknown): string | null;
28
+ /** EVERY readable folder a record carries on its own (C49 (7): discovery reads folders by this one definition, `file://` decoded). */
29
+ export declare function ownFoldersOf(record: Record<string, unknown>): string[];
30
+ /** Folders as a set where an EMPTY list means "cannot be told" and absorbs the rest. */
31
+ export declare function unionDirs(a: readonly string[], b: readonly string[]): string[];
32
+ /**
33
+ * C48 (10): only a MEASURED record kind takes the turn folder. Everything else is UNKNOWN (kept in a single-repo copy, withheld in a multi-repo one), so a
34
+ * kind Codex adds later, a `compacted` summary of earlier turns (which can describe another repo's work), or an old-format item with no `payload` is never
35
+ * placed by a guess. The kinds C40 (2) withholds from every copy (`world_state`, `additional_tools`, `entered_review_mode`, a user or developer message)
36
+ * need no placing: nothing of theirs is sent.
37
+ */
38
+ export declare function takesTurnFolder(record: Record<string, unknown>): boolean;
39
+ /** A "file" that lies inside no copy's tree: a record whose named files could not all be judged names it, so it is withheld from every copy. */
40
+ export declare const UNJUDGED_FILE = "\0unjudged";
41
+ /** The folders of a process or script a call started, and which of them are files the call named (C49 (4): the call's FULL placement). */
42
+ export interface Place {
43
+ readonly paths: readonly string[];
44
+ readonly files: readonly string[];
45
+ /** C54 (3): the id is UNKNOWN (`paths` is `[]`); `files` and `evidence` are what the calls that announced it still named. */
46
+ readonly unknown?: true;
47
+ readonly evidence?: readonly string[];
48
+ }
49
+ /** What a call needs to be placed. */
50
+ export interface CallContext {
51
+ /** The turn folder in force at the call. */
52
+ readonly turn: string | null;
53
+ /** The placement of session `id` (a process an `exec_command` started); undefined when it is not known. */
54
+ session(id: string): Place | undefined;
55
+ /** The placement of cell `id` (a script an `exec` program started); undefined when it is not known. */
56
+ cell(id: string): Place | undefined;
57
+ /** C56 (13): the placement of EVERY session entry known at the call that carries something (folders, files); for a program that polls a session it cannot name. */
58
+ allSessions?(): readonly Place[];
59
+ }
60
+ /**
61
+ * What a CALL touches. `paths`: the places it ran (workdirs, the turn folder) AND the files it names, for evidence and for the work-tree check. `files`: the
62
+ * subset of `paths` that are FILES (a patch's headers, `view_image`'s path): judged like a Claude path, by the copy's roots and holes, for the call AND its
63
+ * output (C48 (11)). `inputFiles`: places that only the call's own INPUT is judged by (an `exec` program's whole-literal workdirs: the program is source
64
+ * text, so it is withheld for parity, while its output is the stated residual).
65
+ */
66
+ export interface Placed {
67
+ readonly paths: string[];
68
+ readonly files: string[];
69
+ readonly inputFiles: string[];
70
+ }
71
+ /**
72
+ * The places a CALL ran in and the files it names, or null when they cannot be told (DEFAULT DENY: a tool this module has no rule for, a malformed argument
73
+ * document, a `workdir` that is not a string, a relative path with no turn folder, an id that names no known session or cell).
74
+ */
75
+ export declare function placeCall(record: Record<string, unknown>, ctx: CallContext): Placed | null;
76
+ /**
77
+ * What a call whose placement CANNOT be fully told still names that can be read (C53): `evidence` (every readable folder and file, kept as discovery
78
+ * evidence so a work tree it lies in is found), `files` (the files it names, judged per copy for the call AND its output) and `inputFiles` (an `exec`
79
+ * program's whole-literal workdirs, judged for its own input). The verdict stays UNKNOWN; this is only what it must not throw away.
80
+ */
81
+ export interface Readable {
82
+ readonly evidence: string[];
83
+ readonly files: string[];
84
+ readonly inputFiles: string[];
85
+ /**
86
+ * C54 (1): the call named more places than are kept (`files` then carries UNJUDGED_FILE), or (C56 (10)) named a folder the client could not read (a workdir
87
+ * that is not a string, a program workdir that is not a whole literal): the evidence is incomplete, so the session is multi. The verdict stays UNKNOWN.
88
+ */
89
+ readonly overflow?: true;
90
+ }
91
+ export declare function readableOf(record: Record<string, unknown>, ctx: CallContext): Readable;
92
+ /** The places a call ran in (see `placeCall`), or null when they cannot be told. */
93
+ export declare function callFolders(record: Record<string, unknown>, ctx: CallContext): string[] | null;
94
+ /**
95
+ * The text of an output record. `header`: the part that can teach an id (before the first `\nOutput:\n` of the FIRST block); `all`: every block's text. A
96
+ * `custom_tool_call_output` and a `wait` output are real arrays of `{type:"input_text", text}` blocks (C49 (1)); a function output is a string. An array
97
+ * is read from its TEXT blocks only (C56 (6): an image block is skipped), the header from the first of them. `undefined`: no readable text.
98
+ */
99
+ export interface OutputText {
100
+ readonly header: string;
101
+ readonly all: string;
102
+ }
103
+ export declare function outputTextOf(record: Record<string, unknown>): OutputText | undefined;
104
+ /**
105
+ * What an output teaches about the processes and scripts its call started (C48 (1)): from an `exec_command` / `write_stdin` output, the session id in the
106
+ * header line `Process running with session ID <n>` (never from the body, where a printed log could remap an id); from an `exec` program's output, a
107
+ * `"session_id": <n>` field (either JSON escaping, anywhere in the text) and the header line `Script running with cell ID <id>`.
108
+ */
109
+ export declare function learnFromOutput(tool: string, text: OutputText): {
110
+ sessions: string[];
111
+ cells: string[];
112
+ };
113
+ /** The most entries a session or cell map keeps; the oldest is evicted, and an evicted id is UNKNOWN. */
114
+ export declare const MAX_ID_MAP = 4096;
115
+ /** C75 (9) / C76: the bytes of freeable path text ONE id map (the session map, or the cell map) may store per stream (`dirs`, `files` and `evidence` of live entries and tombstones). */
116
+ export declare const ID_MAP_BUDGET_BYTES: number;
117
+ /** The most distinct folders one id keeps (C49 (10)); past it the id is UNKNOWN for good. */
118
+ export declare const MAX_ID_FOLDERS = 64;
119
+ /** One folder an id was learned to run in, and the byte offset of the output that announced it. */
120
+ export interface Learned {
121
+ readonly dir: string;
122
+ readonly at: number;
123
+ /** The folder is a FILE the call named (a patch's header): judged per copy like a Claude path. */
124
+ readonly file?: true;
125
+ }
126
+ /** Everything a session or cell id is known to run in, each with where it was learned (C49 (2): a lookup uses only what came BEFORE its position). */
127
+ export interface IdEntry {
128
+ readonly dirs: readonly Learned[];
129
+ /** From this offset the id is UNKNOWN: a call whose folders could not be told announced it, or it grew past `MAX_ID_FOLDERS`. */
130
+ readonly unknownAt?: number;
131
+ /** C50 (5): the entry was EVICTED from the bounded map; the id is UNKNOWN for good (a re-announcement does not bring it back). */
132
+ readonly tomb?: true;
133
+ /** C54 (3): the files (and folders, as evidence) that the UNKNOWN calls which announced this id still named: an unknown id lookup carries them. */
134
+ readonly files?: readonly string[];
135
+ readonly evidence?: readonly string[];
136
+ }
137
+ /** The most tombstones (evicted ids) a map keeps; past that the whole map is UNKNOWN from that offset (sticky). */
138
+ export declare const MAX_ID_TOMBS = 4096;
139
+ /** The map key that holds the "whole map is unknown from `unknownAt`" mark. */
140
+ export declare const ALL_UNKNOWN = "\0all-unknown";
141
+ /**
142
+ * A session or cell map with the checkpoint's bounds: at most `MAX_ID_MAP` live entries; the oldest live entry that is evicted becomes a TOMBSTONE (UNKNOWN
143
+ * for good), at most `MAX_ID_TOMBS` of those; past that the whole map is UNKNOWN from that offset. It is a `Map`, so it persists as an array of entries.
144
+ */
145
+ export declare class IdMap extends Map<string, IdEntry> {
146
+ live: number;
147
+ tombs: number;
148
+ /**
149
+ * C75 (9) / C76: the FREEABLE text the entries store (the path text of `dirs`, `files` and `evidence` with their quoting), live entries and tombstones alike. The byte budget compares only
150
+ * this: the fixed cost of an entry (its key and field names) is bounded by the count caps (`MAX_ID_MAP` + `MAX_ID_TOMBS`) and is its own term of the record's worst case.
151
+ */
152
+ text: number;
153
+ /** C75 (9): the byte budget collapsed an entry since the flag was last taken: evidence was LOST (the session counts as multi from that offset). */
154
+ collapsed: boolean;
155
+ private readonly liveOrder;
156
+ private readonly tombOrder;
157
+ private readonly liveTextOrder;
158
+ private readonly tombTextOrder;
159
+ constructor(entries?: Iterable<readonly [string, IdEntry]>);
160
+ /** Remove an entry, keeping the text count and the order indexes (the live and tombstone counts are kept by the callers). */
161
+ delete(id: string): boolean;
162
+ /** Set an entry, keeping the live, tombstone and text counts and the order indexes. */
163
+ put(id: string, entry: IdEntry): void;
164
+ /** Read and clear the "the byte budget collapsed an entry" flag. */
165
+ takeCollapsed(): boolean;
166
+ /**
167
+ * C75 (9): the map's byte budget. Past `ID_MAP_BUDGET_BYTES` of freeable text the OLDEST entry that stores any is collapsed to a tombstone whose only file is `UNJUDGED_FILE` (its
168
+ * polls and outputs are withheld from every copy), live entries first, then tombstones that kept files. A collapse loses evidence: the caller counts the session as multi (C54 (1)).
169
+ * C76: each step takes the oldest text-bearing entry from an index, so learning one id costs O(1) amortized whatever the map holds.
170
+ */
171
+ fit(at: number): void;
172
+ /** The oldest entry that holds freeable text (a live one first), or undefined. */
173
+ oldestText(): string | undefined;
174
+ /** Store `id` as a tombstone that withholds its polls and outputs, whatever it held. */
175
+ collapse(id: string, at: number): void;
176
+ /** Enforce the bounds after a learning at offset `at`. */
177
+ bound(at: number): void;
178
+ /**
179
+ * Forget the OLDEST tombstone: the id is no longer remembered as evicted, so the whole map is marked UNKNOWN from `at` (`ALL_UNKNOWN`) and every lookup past it fails closed.
180
+ * Returns the forgotten [id, entry], or undefined when there is none.
181
+ */
182
+ evictOldestTomb(at: number): [string, IdEntry] | undefined;
183
+ }
184
+ /**
185
+ * C56 (12): the entries of an id map as they are persisted. The tracker bounds the map (live entries, tombstones and the whole-map mark), so the limit below
186
+ * is never reached; if it ever were, the oldest entries would be CUT, and a cut loses their files: the whole map is marked UNKNOWN from the start instead.
187
+ */
188
+ export declare function boundedIdEntries(entries: readonly (readonly [string, IdEntry])[]): [string, IdEntry][];
189
+ /** The placement of `id` in `map` at `position` (see `lookupId`), UNKNOWN when the whole map has been marked unknown from before `position`. */
190
+ export declare function lookupIn(map: ReadonlyMap<string, IdEntry> | undefined, id: string, position?: number): Place | undefined;
191
+ /**
192
+ * C56 (13): the placement of EVERY entry of `map` at `position` that carries something (folders or files), for a program that polls an id it cannot name:
193
+ * it may reach any of them. A whole-map mark that is in force returns the one unknown-and-unjudged place (every entry's files are lost).
194
+ */
195
+ export declare function placesIn(map: ReadonlyMap<string, IdEntry> | undefined, position?: number): Place[];
196
+ /** The placement of an id at `position` (`undefined`: the whole entry), or `undefined` when it is unknown there. */
197
+ export declare function lookupId(entry: IdEntry | undefined, position?: number): Place | undefined;
198
+ /** What the caller knows about the position of the record being judged. */
199
+ export interface CodexFolderEnv {
200
+ /** The turn folder in force at the record (the latest `session_meta` / `turn_context` cwd at or before it, in this stream); null when none is known. */
201
+ turnFolder(): string | null;
202
+ /** The folders of the call `id`; `undefined` when that call is not known. An empty list means the call's folder could not be told. */
203
+ callFolders(id: string): readonly string[] | undefined;
204
+ /** The subset of the call's places that are FILES (a patch's headers, `view_image`'s path); empty when none or when the call is not known. */
205
+ callFiles(id: string): readonly string[];
206
+ /** The checkpoint's own entry for the CALL record being judged, when there is one (C49 (2): the same source its output uses). */
207
+ ownCall?(id: string): CallInfo | undefined;
208
+ /**
209
+ * C56 (8)(9): true when a call unknown at this record may have been LOST rather than never made: a line before the record was skipped (too long to be read),
210
+ * or the record lies at or below the call log's horizon and the view does not start at the stream's first byte. An output whose call is unknown there is unjudged.
211
+ */
212
+ callsLost?(): boolean;
213
+ /** The placement of session `id` / cell `id` as learned BEFORE the record being judged; `undefined` when unknown. */
214
+ session(id: string): Place | undefined;
215
+ cell(id: string): Place | undefined;
216
+ /** C56 (13): every session entry known at the record, as places (see `placesIn`). */
217
+ sessionPlaces?(): readonly Place[];
218
+ }
219
+ /**
220
+ * `dirs`: the places the record ran (files it names included). `files`: the subset that are files, judged by the copy's roots and holes (C48 (11)), on a
221
+ * call AND its output. `inputFiles`: places only a call's own input is judged by. `unknown`: it cannot be told.
222
+ */
223
+ export type RecordFolders = {
224
+ readonly dirs: readonly string[];
225
+ readonly files?: readonly string[];
226
+ readonly inputFiles?: readonly string[];
227
+ } | {
228
+ readonly unknown: true;
229
+ readonly files?: readonly string[];
230
+ readonly inputFiles?: readonly string[];
231
+ readonly evidence?: readonly string[];
232
+ readonly overflow?: true;
233
+ };
234
+ /** The effective folder(s) of `record` (see the module note). The guard stage first, then the placement. */
235
+ export declare function recordFolders(record: Record<string, unknown>, env: CodexFolderEnv): RecordFolders;
236
+ /** C56 (1): a call whose files were lost (it was evicted from a bounded table, or its entry is gone): its output and the ids it started are unjudged. */
237
+ export declare const DROPPED_CALL: CallInfo;
238
+ /**
239
+ * C62 (3): a call that opens an id ALREADY KNOWN in its stream (still open, closed, dropped, or in the checkpoint) POISONS it: from that call on the id's entry
240
+ * carries the unjudged mark and `named`, so the repeated call, every later output with the id and every id learned from such an output are withheld from
241
+ * every copy. ONE function, shared by the checkpoint fold and `CodexTracker`, so the two views agree.
242
+ */
243
+ export declare function poisonRepeated<T extends {
244
+ readonly files?: readonly string[];
245
+ }>(info: T): T & {
246
+ readonly files: readonly string[];
247
+ readonly named: true;
248
+ };
249
+ /** The call carried files or evidence (so evicting it loses something). */
250
+ export declare function carriesNames(info: {
251
+ readonly files?: readonly string[];
252
+ readonly evidence?: readonly string[];
253
+ readonly named?: true;
254
+ }): boolean;
255
+ /** A call known to the tracker. */
256
+ export interface CallInfo {
257
+ readonly tool: string;
258
+ /** The folders it ran in; `[]` when they could not be told. */
259
+ readonly paths: readonly string[];
260
+ /** The subset of `paths` that are files the call named (C48 (11)). With `paths` `[]` (unknown) these are the files that could still be read. */
261
+ readonly files?: readonly string[];
262
+ /** C53: every folder and file a call whose placement is unknown still named that could be read: discovery evidence. */
263
+ readonly evidence?: readonly string[];
264
+ /** C61 (2): the checkpoint does not keep a call's evidence, only that it HAD some (or files): evicting a call rebuilt from the checkpoint must still leave a mark. */
265
+ readonly named?: true;
266
+ }
267
+ /** What one record contributed. */
268
+ export interface StepResult {
269
+ /** The record set a new turn folder (`null`: an UNREADABLE header, the turn folder is unknown from here). */
270
+ readonly turnChange?: string | null;
271
+ /** The record opened a call. */
272
+ readonly open?: {
273
+ readonly id: string;
274
+ readonly tool: string;
275
+ readonly paths: string[];
276
+ readonly files?: string[];
277
+ readonly evidence?: string[];
278
+ readonly overflow?: true;
279
+ };
280
+ /** The record is the output of this call. */
281
+ readonly close?: string;
282
+ /** C75 (9): the output's announcements passed an id map's byte budget and an entry was collapsed (evidence lost): the session counts as multi from here. */
283
+ readonly collapsed?: true;
284
+ /** The record's folder could not be told (a call whose folder is unreadable, an output whose call is unknown, a record before any turn folder). */
285
+ readonly unknown: boolean;
286
+ }
287
+ /** The bounds the checkpoint's call log keeps, which the tracker mirrors so the scan and the delivery agree (C49 (9)). */
288
+ export interface CallBounds {
289
+ readonly open: number;
290
+ readonly closed: number;
291
+ readonly dropped: number;
292
+ }
293
+ /**
294
+ * The in-order state of one Codex stream: the turn folder, the session map, the cell map and the call table. The resolver's scan and the delivery's observer
295
+ * both walk records through it, so the checkpoint and the in-span view are built by the same code. The call table has the CHECKPOINT's bounds: at most
296
+ * `bounds.open` open calls (the oldest is dropped, and its output is UNKNOWN), calls closed on their output, `bounds.closed` of those kept.
297
+ */
298
+ export declare class CodexTracker {
299
+ /** The calls known from before this tracker started (the persisted table). */
300
+ private readonly known;
301
+ private readonly bounds;
302
+ /** C62 (3): has the checkpoint seen a call with this id (an entry, or one it dropped)? Exact membership: the sticky all-mark does not count. */
303
+ private readonly seen;
304
+ turn: string | null;
305
+ readonly sessions: IdMap;
306
+ readonly cells: IdMap;
307
+ private readonly open;
308
+ private readonly closed;
309
+ private readonly dropped;
310
+ /** C56 (1): the evicted calls that carried files or evidence (bounded by `bounds.dropped`): their outputs are UNJUDGED. */
311
+ private readonly droppedNamed;
312
+ /** C56 (1): `droppedNamed` overflowed: every output whose call cannot be found is unjudged from here on. */
313
+ private droppedNamedAll;
314
+ constructor(init: {
315
+ readonly turn: string | null;
316
+ readonly sessions: Iterable<readonly [string, IdEntry]>;
317
+ readonly cells: Iterable<readonly [string, IdEntry]>;
318
+ /** The calls still waiting for an output when this tracker starts, oldest first. */
319
+ readonly openCalls?: Iterable<readonly [string, CallInfo]>;
320
+ },
321
+ /** The calls known from before this tracker started (the persisted table). */
322
+ known: (id: string) => CallInfo | undefined, bounds: CallBounds,
323
+ /** C62 (3): has the checkpoint seen a call with this id (an entry, or one it dropped)? Exact membership: the sticky all-mark does not count. */
324
+ seen?: (id: string) => boolean);
325
+ /**
326
+ * C65 (1): an independent copy of this tracker's state (the delivery observer snapshots it before a read and restores it when the same bytes are read again).
327
+ * The persisted lookups are shared; every map and set is copied. Id entries and call infos are never mutated in place (`learnInto` and `register` replace
328
+ * them), so they are shared too.
329
+ */
330
+ clone(): CodexTracker;
331
+ /** A call this tracker has seen, else one the persisted table knows; a dropped one is not known. */
332
+ callInfo(id: string): CallInfo | undefined;
333
+ /** An evicted call: remembered as unknown, and (C56 (1)) as unjudged when it carried files or evidence. */
334
+ private evict;
335
+ /** C62 (3): is `id` already known in this stream? */
336
+ private repeated;
337
+ private register;
338
+ private close;
339
+ step(record: Record<string, unknown>, at?: number): StepResult;
340
+ }