Repository navigation
feat(history): COD-549 read saved Codex conversations offline - #707
Conversation
|
Thanks, Aamer, for this. It adds an offline Two things need to change before this can merge. 1. Forked threads are refused, and one forked child blocks the whole family (
2. The id selectors stop working on larger stores ( Each lookup reads every rollout's Smaller things, fine in the same revision:
Two design points are still open on my side and are not yours to resolve: whether the codeman skill should advertise this offline reader in its description and relax its "refuse to act outside a Codeman session" guard (the skill is often installed user-level, so its description fires in unrelated sessions), and whether a Codex-only reader should take the top-level Once the two numbered items are addressed this is close to merge. |
…ry readers The Past Sessions scanner and the offline history reader each parsed Codex rollouts with their own shape helpers, their own CODEX_HOME resolution and different injected-context rules. Move the store location, the three message shapes and the injected-context rule into codex-rollout-format.ts. The scanner's behaviour is unchanged; the offline reader adopts its rule in the next commit.
A forked or spawned thread's rollout carries its own session_meta followed by its parent's and a copy of the parent's history. A later session_meta for a declared ancestor now opens an inherited prefix that is dropped: by ordinal below subagent_history_start_ordinal in paginated history, and up to the thread_settings_applied event Codex appends after the copy in legacy history, checked against the parent's own messages when the copy holds more than one candidate. An unrelated id still refuses the file. Store attribution now has its own budget (--metadata-bytes) separate from the transcript budget (--scan-bytes), reads each head in 32 KiB steps, and --max-entries is a flag, so id lookups work on stores of thousands of rollouts. An unattributable store file or unreadable directory is counted instead of aborting the lookup, and a rollout that a running Codex appends to is read as a snapshot up to its last complete line. User records carry no phase, date bounds are UTC calendar dates, the injected-context rule is the shared one, a symlinked sessions root is followed as the Past Sessions scanner follows it, and --json with --format text is refused.
Replace docs/offline-history.md, which repeated the skill reference and was linked from nowhere, with a README section and a wiki section beside the codeman agent commands. Bring the skill reference, its plugin mirror, the Codeman Skill wiki page and the changeset in line with the reader: forks, the separate budgets and their flags, UTC dates, phases and complete:false.
|
Thanks for the careful review, and for running it against your store. Everything below is pushed. 1. Forked threads. Agreed, and the refusal test pinned the wrong behaviour. A later
A copy that never reaches its end (initialisation died) is reported as 2. Large stores. Attribution now has its own budget, Smaller items:
|
|
Thanks, Aamer, for the second round. The PR adds an offline Both numbered items from the first review are resolved. I checked the fork handling against codex-rs: Smaller things, fine in the same revision:
Two design points are still open on my side, and merging waits on them:
Nothing is needed from you on those two. The four items above fit the next push; after that, the two design points are what stands between this PR and merge. |
… an unreadable parent Codex's local_thread_store_compression rewrites cold rollouts to *.jsonl.zst, which the store scan skipped without a trace. Each one is now counted in compressedFiles (complete: false), skipped only when its plain .jsonl sibling exists, as Codex's own discovery does, and a lookup that misses names the compressed file whose name carries the wanted id. A Zstandard file given to --file, or sitting in the store under a .jsonl name, is recognised by its magic number. Each selected rollout is parsed once into every view later needed of it, so a legacy copy's boundary proof reuses the parent's own read instead of charging it to --scan-bytes a second time (and counting its malformed or inherited records twice). A parent read that fails for any reason other than a budget now leaves the boundary unproven (cut at the last candidate, unverifiedPrefixes, complete: false) instead of failing a child whose own file is intact. A budget error still fails the read. --max-bytes is validated before the first file is read, next to the other budgets, and every budget flag accepts plain decimal integers only.
|
Thanks for the third round. All four items are in 17b2edc:
The skill reference (and its plugin mirror), the README line, the wiki page and the changeset describe the new counter and the single read. I have not touched the two design points: the skill description and guard, and the top-level |
|
Thanks, Aamer, for the fourth round. The PR adds an offline All four items from the last review are in 17b2edc, and each is pinned by a test:
I also ran it against the Codex store here from outside a Codeman session: all 58 Two design points are still open on my side, and merging waits on them:
Nothing is needed from you on those two. |
|
Merged in 1.46.0 (https://github.com/Ark0N/Codeman/releases/tag/codeman%401.46.0). Thank you for four careful rounds. Both design points are settled the way you built it: |
Saved Codex conversations currently require manual JSONL parsing to retrieve a thread and its children. Add
codeman history readwith file/native-ID/root selectors and topic/date filters that preserve complete matching turns.The command runs locally without a Codeman server. It bounds scans and output separately, checks native identity and file consistency, and reports incomplete evidence or unproven ancestry explicitly. It adds no HTTP endpoints. Includes CLI documentation, skill routing before the managed-session guard, the synchronized plugin reference, and a minor changeset.
Validation:
Codex JSONL only. Explicit path parent directories must be trusted; this is not a filesystem sandbox. Store completeness does not imply every historical conversation was retained.