workflow-fix: atomic post_event append (events.jsonl partial-line corruption)
kind: infra#wf-fix#wf-fix-fp:postevent-atomic-append-corruption
track:Highlight text on any card (body, plan, or an event) to anchor a comment, or leave a whole-task comment here. Mention @claude to summon a reply.
No comments yet.
Overview / Motivation
Auto-filed by the /daily problem sweep (2026-06-27) from a workflow-surface bug
observed in the #653 autonomous session (transcript b8d3dbc3).
Goal
Make task_workflow.post_event crash-safe so a killed/OOM'd/cron-timed-out writer
cannot leave a truncated JSON line that breaks every downstream reader.
Workflow gap
- Bug observed:
post_eventappends an event line viawith path.open("a")under flock, but the write is NOT atomic against SIGKILL/OOM/cron-timeout mid-write. A watcher killed mid-append left a 129-byte partial JSON line (BAD line 374: Unterminated string) intasks/.../653/events.jsonl, which then crashed everytask.py view/list_events/ dashboard read and stalled the/issue 653resume for >2h. - Why it is a workflow gap:
events.jsonlis canonical task-workflow state; a single non-atomic append makes the entire task (and the dashboard) unreadable. - Confidence (emitter): high (reproduced corruption + reader crash in-session).
Proposed change (refine in planning)
Two complementary fixes (planner picks one or both):
- Atomic append: build the full
json.dumps(event) + "\n"in memory and write it in a singleos.write(fd, ...)(POSIX guarantees an atomic write for a buffer under PIPE_BUF; for larger lines, write to a temp + append, orO_APPENDsingle-syscall write) so a kill mid-write never leaves a partial line. - Tolerant reader:
list_events/ readers skip (and log) an unterminated trailing line instead of raising, so an already-corrupted file is still readable.
Add a concurrency/crash regression test under tests/test_task_workflow*.py
(simulate a truncated trailing line; assert readers tolerate it; assert a
concurrent append never interleaves a partial line).
Scope / surfaces
- Primary target:
src/explore_persona_space/task_workflow.py(post_event,list_events/ the events.jsonl reader). - Add a regression test in
tests/test_task_workflow*.py.
Constraints / invariants
- Preserve the existing
flockon~/.task-workflow/lock+ single-commit semantics. - Workflow-surface only — never experiment code.
uv run pytest tests/test_task_workflow*.pypasses; ruff on touched files passes.
Provenance
- workflow_fix_target: src/explore_persona_space/task_workflow.py
- fingerprint: postevent-atomic-append-corruption
Activity