myxce/.claude/skills/buglog/SKILL.md
Rongsong Shen d26ff8870d
feat(buglog): one Markdown record per bug, checked against a record standard
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>
2026-09-28 03:40:11 +00:00

4.8 KiB

name description argument-hint triggers
buglog Log a new bug, change a bug's status (fixed / partial / cannot-reproduce / ...), record a recurrence, or list open bugs. Bugs are Markdown records in .wolf/bugs/<id>.md checked against a record standard. Use whenever you log or fix a bug, or are asked for the open-bug list. new | status <id> <status> | note <id> | recur <id> | list [--open] | show <id> | check
/buglog
log a bug
open bug list
mark bug fixed

Buglog Skill

Each bug is one Markdown file, .wolf/bugs/<id>.md: short machine fields in front matter, # <id>: <summary>, then the sections of the record standard. Read bug-record.md (next to this file) before writing a record: it says what every section must contain (e.g. Environment needs the OS, the libc the failing binary loads, toolchain, build profile, commit and deployment).

  • .wolf/buglog.json is an index generated from the records (for OpenWolf's hooks, openwolf bug search and jq). Never edit it; every buglog.py write regenerates it, and python3 scripts/buglog.py index does it after a hand edit of a record.
  • .wolf/buglog-archive.json holds the retired OpenWolf hook auto-detections (710 entries, template messages like "Missing guard clause"). They are not bug reports; leave them there.
  • Records migrated from the old JSON log carry legacy: true and _Not recorded (migrated from buglog.json)._ where the old log had no such field. They are exempt from the reporting sections, but changing one to fixed/partial still needs the fix-time sections.

Status values and when to use each: .claude/rules/buglog-status.md.

Before fixing a bug

Search for prior art first (project rule): openwolf bug search "<error text>", or python3 scripts/buglog.py list --grep '<regex>'.

Commands

Task Command
Log a new bug python3 scripts/buglog.py new --summary "<symptom in component, ≤100 chars>" --component <c> --severity <s> [--binary <failing binary>] [--files a,b] [--tags x,y] [--related bug-N] → prints the file path. Environment is filled in from this machine (pass --binary so libc and build profile come from that binary). Then edit the file: replace every TODO in Description, Environment (Deployment) and Reproduction, and run check <id>.
Environment block only python3 scripts/buglog.py env [<binary>]
Check records python3 scripts/buglog.py check <id> … / check --all
Mark fixed Fill in Root cause, Fix and Verification (- Test: RED before/GREEN after, - Suites:, - Live:), then python3 scripts/buglog.py status <id> fixed --commit <sha> [--commit <sha2>]. Refused, and nothing written, until the record meets the standard; each --commit must be a real commit.
Mark partly fixed python3 scripts/buglog.py status <id> partial --note "<what remains>" (Root cause + Fix required)
Couldn't reproduce python3 scripts/buglog.py status <id> cannot-reproduce --repro "0/40 runs, 2026-09-24" --note "<what was tried>"
Real failure, cause unknown python3 scripts/buglog.py status <id> investigating --note "<next step>"
Not a bug / accepted python3 scripts/buglog.py status <id> wontfix --note "<why / who decided>"
Duplicate python3 scripts/buglog.py status <id> duplicate --duplicate-of <other-id> --note "<same defect as ...>"
Add findings python3 scripts/buglog.py note <id> "<text>" [--section "Root cause"] (appends UPDATE (date): …; default section Description)
Seen again python3 scripts/buglog.py recur <id> [--note "<where>"] (bumps occurrences/last_seen; reopens a fixed/wontfix/cannot-reproduce bug)
Open-bug list python3 scripts/buglog.py list --open (add --tag scheduler, --grep, --since YYYY-MM-DD)
One record python3 scripts/buglog.py show <id>
Front-matter field python3 scripts/buglog.py set <id> key=<json> ...

Components: controller, scheduler, worker, lib, harness, apiserver, xcecli, xceadmin, autoscaler, build, config, tooling. Severities: data-loss, crash, hang, wrong-result, leak, security, noise.

Rules

  • Ids: let new pick the id (one past the highest in records + archive).
  • Editing sections: edit the Markdown file directly (Edit tool), keeping the ## <Section> headings; then check <id> and index. Status changes go through status, never a hand edit of status:.
  • Enforcement: the pre-commit hook (scripts/git-hooks/pre-commit; install once per clone with ln -sf ../../scripts/git-hooks/pre-commit .git/hooks/pre-commit) runs check --staged: it refuses staged records that miss the standard, a legacy record hand-changed to fixed/partial without the fix-time sections, and a stale buglog.json.
  • Gitea: /gitea-sync mirrors status, and refreshes an issue's title and body whenever the record's text changes; fix commits are linked.