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/highImportant and time-sensitiveImportant and time-sensitivesource/creatorFiled by the new-issue-creator jobFiled by the new-issue-creator jobstatus:donetask/triageQueue packet kind: verify, reproduce, and route this itemQueue packet kind: verify, reproduce, and route this item
Description
Problem
A crash-torn final line in the directory journal bricks the directory permanently: Directory::open / Directory::replay refuse the unterminated partial entry 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/directory.rs:527-543—Directory::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/directory.rs:505-525—Directory::replayiteratestext.lines()(which yields the unterminated final fragment as a line) and propagates any parse failure with?at:516-517(directory journal line N is malformed). There is no torn-tail special case: no check for a missing final newline, no truncation/repair.pkgs/id/src/directory.rs:471-473—Directory::open(the production load path) isSelf::replay(path)?first, so one torn append makes every subsequent open fail the same way; the directory never recovers without manual file surgery.- 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 togood_len, with a comment explaining that a newline-terminated unparseable line is corruption and must still fail.pkgs/id/src/artifact.rs:575-600(ArtifactLog::open— the very logDirectory::openloads immediately after the journal): drops and truncates a final line cut short by a crash.pkgs/id/src/envelope_outbox.rs:143-165andpkgs/id/src/directory_log.rs:196-235: same drop-the-torn-tail treatment.
- Existing test
replay_rebuilds_the_directory_and_refuses_a_broken_journal(directory.rs:2601) covers an apply-refused complete entry, not a torn tail; no test covers 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) is the same defect class in
Petnames::openonly (pkgs/id/src/petname.rs); it names FileJournal and Outbox as the good examples and does not cover the directory journal. No open or recently-closed issue mentions the directory journal /Directory::replaytorn tail.
Why it matters
The directory journal is the durable record of accounts, friendships and group membership for the directory service. 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 directory, while the artifact log sitting next to it (loaded in the same open) already survives the same crash.
Acceptance criteria
-
Directory::replay/openon a journal whose final line is an unterminated truncated fragment loads all complete entries, drops the fragment, and truncates the file to the last complete line (mirroringFileJournal::open/ArtifactLog::opensemantics, including a warning log). - A newline-terminated line that does not parse, anywhere including the last line, still fails with the existing
directory journal line N is malformederror — corruption is never silently dropped. - A complete entry that
applyrefuses still fails replay (existing test atdirectory.rs:2601keeps passing). - New tests cover: torn final fragment (loads + file truncated), complete-but-corrupt final line (errors), torn fragment after valid entries (earlier entries intact).
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/highImportant and time-sensitiveImportant and time-sensitivesource/creatorFiled by the new-issue-creator jobFiled by the new-issue-creator jobstatus:donetask/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-581
dezren39 commentedon Oct 27, 2026
🤖 Agent note · filed
114 remaining items
dezren39 commentedon Oct 28, 2026
agent-note:v1 — parked
nix flake checkjob (122669656041) remains, queued without a runner since 06:31Z.dezren39 commentedon Oct 28, 2026
🤖 Agent note · picked up
Merge pull request #1563 from developing-today/queue/1622-1521-direct…
dezren39 commentedon Oct 28, 2026
🤖 Agent note · done