jsonl-board-header-guard-missing-tick-double-encoded-event
Diagnosed and verified against the real repo (get-h3/h3 @ 6b18679). Solution written to /workspace/solution.md (copy at ~/solution.md).
Root cause: Event 554 is double-encoded — its .detail JSON string decodes to an event-like wrapper whose nested detail object holds tick: 485. The guard only reads top-level tick_number, top-level tick, or one-level detail.tick, so the row is invisible and tick 485 appears as a hole.
Exact fix (append-only, no history rewrite):
boardctl -C . event --type audit --task-id "" --actor foreman --tick 485 \
--detail-text '{"type":"tick-event-shape-backfill","tick":485,"source_event_id":554,"summary":"..."}'
Then if the header tick changed, make board-close and commit board.jsonl + events.jsonl together (guard D fails on an uncommitted header edit).
Verification performed:
- Reproduced on pre-fix tree 5101b41: guard failed C ... 485 (window 476..487), exit 1.
- Applied append via boardctl: new row got tick_number=485, source_event_id=554; guard B/C/D PASS, VERDICT: VERIFIED, exit 0.
- Confirmed upstream committed fix: B total 488, C full window 477..488, D committed==worktree.
- boardctl validate → RESULT: OK (657 warning(s)) (baseline unchanged).
- make verify on committed tree → ALL PASS.
The document includes the guard's exact jq extractor, before/after console evidence, the do/don't list, and the note not to loosen the guard's intentional three-shape precedence.
# Evidence - Problem class: jsonl-board-header-guard-missing-tick-double-encoded-event - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-23T09:00:29.887Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Symptom: after board closeout, check-board-header-consistency reported tick 485 had no event although event id 554 visibly contained tick 485 evidence. Root cause: event 554's detail string decoded to an event-like wrapper whose nested detail object held tick=485; the guard intentionally reads only top-level tick_number, top-level tick, or one-level detail.tick, so the malformed double-nested row was invisible. Safe recovery: preserve history and append a new audit marker with boardctl event --tick 485 whose detail links source_event_id 554; do not rewrite the historical row. Commit the header/events together before the final make verify, because guard D correctly fails while the header edit is uncommitted. Verification: jq readback showed tick_number=485 on the new event; validator warning baseline stayed 657; committed-tree make verify passed B total, C full window 477..488, and D committed-equals-worktree.", "environment": "get-h3/h3 JSONL-canonical board on Linux", "language": "shell", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "jsonl-board-header-guard-missing-tick-double-encoded-event", "provider": "openrouter", "solved_at": "2026-09-23T09:00:29.888Z", "version": ""}Diagnosed and verified against the real repo (get-h3/h3 @ 6b18679). Solution written to /workspace/solution.md (copy at ~/solution.md).
Root cause: Event 554 is double-encoded — its .detail JSON string decodes to an event-like wrapper whose nested detail object holds tick: 485. The guard only reads top-level tick_number, top-level tick, or one-level detail.tick, so the row is invisible and tick 485 appears as a hole.
Exact fix (append-only, no history rewrite):
boardctl -C . event --type audit --task-id "" --actor foreman --tick 485 \
--detail-text '{"type":"tick-event-shape-backfill","tick":485,"source_event_id":554,"summary":"..."}'
Then if the header tick changed, make board-close and commit board.jsonl + events.jsonl together (guard D fails on an uncommitted header edit).
Verification performed:
- Reproduced on pre-fix tree 5101b41: guard failed C ... 485 (window 476..487), exit 1.
- Applied append via boardctl: new row got tick_number=485, source_event_id=554; guard B/C/D PASS, VERDICT: VERIFIED, exit 0.
- Confirmed upstream committed fix: B total 488, C full window 477..488, D committed==worktree.
- boardctl validate → RESULT: OK (657 warning(s)) (baseline unchanged).
- make verify on committed tree → ALL PASS.
The document includes the guard's exact jq extractor, before/after console evidence, the do/don't list, and the note not to loosen the guard's intentional three-shape precedence.
# Evidence - Problem class: jsonl-board-header-guard-missing-tick-double-encoded-event - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-23T09:00:29.887Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Symptom: after board closeout, check-board-header-consistency reported tick 485 had no event although event id 554 visibly contained tick 485 evidence. Root cause: event 554's detail string decoded to an event-like wrapper whose nested detail object held tick=485; the guard intentionally reads only top-level tick_number, top-level tick, or one-level detail.tick, so the malformed double-nested row was invisible. Safe recovery: preserve history and append a new audit marker with boardctl event --tick 485 whose detail links source_event_id 554; do not rewrite the historical row. Commit the header/events together before the final make verify, because guard D correctly fails while the header edit is uncommitted. Verification: jq readback showed tick_number=485 on the new event; validator warning baseline stayed 657; committed-tree make verify passed B total, C full window 477..488, and D committed-equals-worktree.", "environment": "get-h3/h3 JSONL-canonical board on Linux", "language": "shell", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "jsonl-board-header-guard-missing-tick-double-encoded-event", "provider": "openrouter", "solved_at": "2026-09-23T09:00:29.888Z", "version": ""}