The buglog was one 27K-line JSON file whose fields covered only symptom,
root cause and fix, as free text: 2% of entries named the code version a
bug was found on, 12% the build profile, 36% a way to reproduce, and 58% of
the file was OpenWolf hook auto-detections ("Missing guard clause",
"Function not marked async" on .md files).
- .claude/skills/buglog/bug-record.md: the record standard. Eight
sections (Summary as the title, Description, Environment, Reproduction;
Root cause, Fix, Verification, References once fixed), each with the
content it must contain -- e.g. Environment needs the OS, the libc the
failing binary loads (from its ELF interpreter: glibc 2.42 in the nix
shell vs 2.40 on the host), toolchain, build profile and commit.
- .wolf/bugs/<id>.md: 500 records migrated from buglog.json; every field
verified to round-trip. They carry legacy: true and an explicit "not
recorded" where the old log had no such field; component derived from
file paths, severity from keywords (else unknown), fix_commits from
hashes in status_note/fix that git resolves (91 of 463 fixed).
- .wolf/buglog-archive.json: the 710 hook auto-detections, verbatim.
- .wolf/buglog.json is now an index generated from the records, keeping
the fields OpenWolf's hooks and `openwolf bug search` read.
- scripts/buglog.py rewritten: new (template + Environment collected from
the machine and --binary), check, status (refuses a status the record
doesn't support; fixed needs Root cause, Fix, Verification and
--commit hashes git resolves), note, recur, set, show, list, triage,
env, index. 29 unittest cases in scripts/tests/test_buglog.py.
- scripts/git-hooks/pre-commit runs `check --staged`: incomplete staged
records, a legacy record hand-changed to fixed without the fix-time
sections, a new record claiming legacy: true, or a stale index refuse
the commit.
- scripts/gitea-sync.py reads the records: issue body = the record's
sections plus linked fix commits (origin remote, GITEA_COMMIT_REPO to
override), and a body hash so an issue's text is refreshed when the
record changes.
- bug-1866 rewritten to the full standard as the worked example.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
3.5 KiB
| id | status | status_updated | status_note | component | severity | timestamp | last_seen | occurrences | files | tags | related | legacy | gitea_issue | gitea_synced_status | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| bug-1802 | fixed | 2026-09-24 | scheduler | unknown | 2026-09-11T08:35:00Z | 2026-09-19T09:00:00Z | 1 |
|
|
true | 271 | fixed |
bug-1802: User request (same live replay session as bug-1799/1800): 'how can we step to the next session…
Description
User request (same live replay session as bug-1799/1800): 'how can we step to the next session which is not dummy(something occurs)?' -- the REPL's break <EVENT_TYPE> vocabulary required setting all ten per-event breakpoint kinds individually to catch 'the next session with ANY event at all,' with no single convenience kind for that common workflow.
Environment
Not recorded (migrated from buglog.json).
Reproduction
Not recorded (migrated from buglog.json).
Root cause
Not a bug -- a missing convenience feature. BP_KIND_TABLE (repl_break.c) only offered the ten specific per-event kinds (CONFIG_PUSH/JOB_PUSH/.../JOB_RUSAGE) plus BEGIN_ROUND/DECISION; repl_breakpoint_matches_event() compared bp->kind for exact equality against repl_bp_kind_for_core_event(ev->type), with no wildcard option.
Fix
FIXED (2026-09-11). Added a new XCE_REPL_BP_ANY enum member (repl_internal.h) and a {"ANY", XCE_REPL_BP_ANY} BP_KIND_TABLE entry (listed first for discoverability). repl_breakpoint_matches_event() (repl_break.c) now special-cases bp->kind == XCE_REPL_BP_ANY to match any event whose type maps to a real per-event kind (repl_bp_kind_for_core_event() returning nonzero) instead of requiring exact kind equality -- still subject to the breakpoint's own filters (though a bare break ANY, the intended usage, has none). Deliberately does NOT match BEGIN_ROUND (fires on every session including dummy ones -- matching it would defeat the whole point) or DECISION (a separate drained-decision hook). break ANY + continue now stops the REPL at the very next session that decodes at least one real event, transparently skipping any number of dummy (virtual-clock-only) sessions in between, in one command instead of ten. TDD: added test_any_breakpoint_skips_dummy_sessions_to_first_real_event (test_repl_breakpoints_inspection.c, full replay-file + REPL-script Group D fixture) -- two dummy sessions (rounds 1000/2000, zero events each) followed by one JOB_STATE_CHANGE event, break ANY + continue must land exactly at event #1 having processed both dummy rounds as 'idle' (round-rollup evidence), and must never print BEGIN_ROUND. Also extended the two existing BP_KIND_TABLE token-enumeration tests (test_repl_help.c's help-text test, test_repl_breakpoints_inspection.c's unrecognized-event-type-error test) to include "ANY" so both stay genuinely exhaustive against the real table. RED confirmed (the new test failed on the FIRST attempt for an unrelated reason -- the hit message names the breakpoint's own user-typed token, "ANY", not the underlying event's type name "JOB_STATE_CHANGE", which the test's first draft wrongly assumed; corrected the expected string, not the implementation, which was already correct). GREEN confirmed: 77/77 Ok, zero regressions, alongside bug-1801's fix in the same build.
Verification
Not recorded (migrated from buglog.json).
References
- Gitea: #271