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 job
Description
Problem
A crash-torn final line in groups.jsonl bricks every group command: GroupLog::open refuses the unterminated partial event that a crash mid-append leaves behind, instead of dropping and truncating it the way the sibling JSONL stores in this codebase do.
Evidence (verified this run on main 279c973, code reading)
pkgs/id/src/groups/log.rs:137-150—GroupLog::appendwrites one JSON line +\nwith a singlewrite_allfollowed bysync_data. A crash/power loss during that write leaves a final line that is a truncated JSON fragment with no terminating newline.pkgs/id/src/groups/log.rs:48-71—GroupLog::opencollectstext.lines()throughserde_json::from_str(...)?for every non-empty line.lines()yields the unterminated final fragment as a line, so one torn append fails the whole open withline N is not an event. There is no torn-tail special case: no missing-final-newline check, no truncation/repair.pkgs/id/src/commands/group.rs:200,361,395— every group command (cmd_groupand helpers) starts withGroupLog::open(&log_path(path))?, so one torn append makes all group operations fail the same way until someone hand-editsgroups.jsonl.- Contrast — the established house semantics in the same codebase:
pkgs/id/src/world_store.rs:85-130(FileJournal::open): an unterminated last line is a torn append — dropped, file truncated to the last complete line; a newline-terminated unparseable line is corruption and still fails.pkgs/id/src/envelope_outbox.rs:143-165(Outbox::open): unterminated failing final line is dropped and the file truncated viaset_len(kept); a complete corrupt line still errors.pkgs/id/src/artifact.rs:575-600andpkgs/id/src/directory_log.rs:196-235: same drop-the-torn-tail treatment.
- Existing test
test_a_line_that_is_not_an_event_is_an_error(groups/log.rs:386-392) writes"not json\n"— a complete, newline-terminated line — and correctly asserts an error. No test covers an unterminated final fragment, which is the distinct torn case the sibling stores forgive. - 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) is the same defect class in
Petnames::openonly (pkgs/id/src/petname.rs); the directory journal instance is filed separately as 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. No open or recently-closed issue mentionsGroupLog/groups.jsonltorn tails.
Why it matters
Groups are a user-facing feature whose entire local history lives in this one append-only log. Its own append path can produce exactly the torn tail its load path refuses — so a single ill-timed crash converts a recoverable restart into a permanently unopenable group log, while the envelope outbox written by the same binary already survives the same crash.
Acceptance criteria
-
GroupLog::openon a log whose final line is an unterminated truncated fragment loads all complete events, drops the fragment, and truncates the file to the last complete line (mirroringFileJournal::open/Outbox::opensemantics, including a warning log). - A newline-terminated line that does not parse, anywhere including the last line, still fails — the existing
test_a_line_that_is_not_an_event_is_an_errortest keeps passing unchanged. - New tests cover: torn final fragment (loads + file truncated), torn fragment after valid events (earlier events intact and
projection()still folds). - No change to the event format, the fold, or append behaviour.
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 job
Activity
developing-today commentedon Oct 27, 2026
CODE-582
dezren39 commentedon Oct 27, 2026
🤖 Agent note · filed
5 remaining items
dezren39 commentedon Oct 31, 2026
🤖 Agent note · picked up
fix(id/groups): GroupLog::open drops and truncates a torn final fragm…
dezren39 commentedon Oct 31, 2026
🤖 Agent note · done
d46fdfcd0): GroupLog::open drops+truncates a torn unterminated final fragment with a warning, newline-terminated corruption stays fatal.queue/1800-1522-grouplog-torn-tail· laptop tests: groups::log 6/6, groups module 443/443 · Codex review clean on f9ace95 · no PR-triggered CI exists for pkgs/id (id-check.yml has no pull_request trigger; the jules push failures are repo-wide workflow-file noise, also failing on main)