Repository navigation
Closed
Labels
app/idPackage/app: id (pkgs/ or apps/ in this repo)Package/app: id (pkgs/ or apps/ in this repo)kind/bugSomething isn't working (prefixed form of the classic bug label)Something isn't working (prefixed form of the classic bug label)priority/normalOrdinary priority (the default)Ordinary priority (the default)source/creatorFiled by the new-issue-creator jobFiled by the new-issue-creator jobtask/triageQueue packet kind: verify, reproduce, and route this itemQueue packet kind: verify, reproduce, and route this item
Description
Problem
read_journal_entries — the raw journal reader behind id world fork — refuses a crash-torn final entry in a world journal that FileJournal::open on the very same file forgives: a world that opens, serves and verifies fine after a crash cannot be forked until someone hand-repairs its journal.
Evidence (verified this run on main 279c973, code reading)
pkgs/id/src/world_store.rs:452-466—read_journal_entriessplits the file bytes on\nand parses every non-empty chunk withserde_json::from_slice(...)?({path} is corrupt). The final chunk after a crash-torn append is an unterminated truncated fragment; it is parsed like any other entry and fails the whole read. There is no torn-tail special case.pkgs/id/src/world_store.rs:85-130—FileJournal::open, the normal open path for the same journal, treats exactly this case as recoverable: an unterminated last line is a torn append (the crash came before the entry was acknowledged), so it is dropped, the file is truncated togood_len, and a warning is logged. Only a newline-terminated unparseable line is corruption there.pkgs/id/src/world_store.rs:479—fork_worldstarts withread_journal_entries(&src_dir.join("journal.jsonl"))?. Forking a cold world (not currently open — e.g. after the crash that tore the tail, before anything reopens it) therefore fails withjournal.jsonl is corrupt, even though simply opening that world would have repaired the tail and proceeded.pkgs/id/src/world_store.rs:190— the second caller isFileJournal::append's version-bump path (Define rollback compatibility for world profile journal entries #227), which re-reads the journal through the same helper; it is normally shielded becauseopentruncates first, which shows the helper's strictness is an accident of reuse, not a ruling: the fork path has no such shield.- No test covers
read_journal_entries/fork_worldagainst a journal with an unterminated final fragment. - Dedup: id: a torn final line in petnames.jsonl bricks the whole world — Petnames::open refuses the crash-torn tail that FileJournal and Outbox drop and truncate #1499 (open) covers
Petnames::open; id(directory): a torn final line in directory.jsonl bricks the directory — Directory::replay refuses the crash-torn tail that ArtifactLog (loaded in the same open) drops and truncates #1521 / id(groups): a torn final line in groups.jsonl bricks every group command — GroupLog::open refuses the crash-torn tail that FileJournal and Outbox drop and truncate #1522 (filed 2026-10-27) cover the directory journal and the group log. No open or recently-closed issue mentionsread_journal_entries,fork_worldand a torn journal tail.
Why it matters
Forking (F12.2) is the template/backup path for worlds. The scenario where an admin most wants a fork — recovering or cloning a world after a crash — is exactly the scenario where the journal may carry a torn tail, and it is the one path that refuses it while the world's own open path quietly repairs it. The error message (is corrupt) also misdiagnoses a torn append as corruption, sending the admin toward discarding a journal that was never corrupt.
Acceptance criteria
-
read_journal_entries(or the fork path) treats a final unterminated fragment the wayFileJournal::opendoes: the fragment is excluded from the returned entries (and the exclusion is visible — a warning log or a fork note), sofork_worldsucceeds on a crash-torn source journal and the fork replays to the parent's last complete entry. - A newline-terminated unparseable line, anywhere including the last line, still fails with the corrupt-journal error — corruption is never silently dropped.
- New tests cover: fork of a journal with a torn final fragment (succeeds, fork state = last complete entry), fork of a journal with a complete-but-corrupt final line (fails).
-
FileJournal::append's version-bump caller (Define rollback compatibility for world profile journal entries #227) behaviour is unchanged for journals it has opened.
Metadata
Metadata
Assignees
Labels
app/idPackage/app: id (pkgs/ or apps/ in this repo)Package/app: id (pkgs/ or apps/ in this repo)kind/bugSomething isn't working (prefixed form of the classic bug label)Something isn't working (prefixed form of the classic bug label)priority/normalOrdinary priority (the default)Ordinary priority (the default)source/creatorFiled by the new-issue-creator jobFiled by the new-issue-creator jobtask/triageQueue packet kind: verify, reproduce, and route this itemQueue packet kind: verify, reproduce, and route this item
Activity
developing-today commentedon Oct 27, 2026
CODE-583
dezren39 commentedon Oct 27, 2026
🤖 Agent note · filed
22 remaining items
dezren39 commentedon Oct 31, 2026
🤖 Agent note · parked
read_journal_entriesnow drops an unterminated final fragment with a warning (mirroringFileJournal::open), so a crash-torn world can be forked; newline-terminated corruption stays fatal. Tests: fork-with-torn-tail succeeds, fork-with-corrupt-complete-final-line fails.world_fork4/4,world_storelib tests 21/21. Resume: CI green + Codex findings dispositioned → merge fix(id/world): let fork tolerate a crash-torn journal tail (#1523) #2933, close this issue, complete task 1828 as fixed_merged.queue/1828-1523-fork-torn-taildezren39 commentedon Oct 31, 2026
🤖 Agent note · picked up
Merge pull request #2933 from developing-today/queue/1828-1523-fork-t…
dezren39 commentedon Oct 31, 2026
🤖 Agent note · done
read_journal_entries/ fork path inpkgs/id/src/world_store.rstolerate a crash-torn journal tail likeFileJournal::opendoes.Merged PR #2933 into main:
read_journal_entriesexcludes unterminated final fragments with a warning, allowing crash-torn worlds to be forked while preserving fatal errors for complete corrupt lines. Verified with targeted tests (world_fork4/4 passed).