myxce/.claude/rules/buglog-status.md
Rongsong Shen 19104f1940
feat(buglog): status field, buglog skill, status-driven gitea-sync
The buglog had no status field, so "is this bug open?" meant reading free
text, and gitea-sync closed any issue whose `fix` text was non-empty --
including "NOT FIXED"/"PENDING"/"PARTIALLY FIXED" ones (bug-1855).

- Backfill `status` (+ status_updated) on all 1,193 entries. The 85 entries
  whose text said not-fixed/pending/out-of-scope were checked against HEAD
  and git history; the rest are `fixed`. Result: 36 open, 10 partial,
  2 investigating, 5 cannot-reproduce, 4 wontfix, 1 duplicate.
  Insert-only diff: existing lines are untouched.
- .claude/rules/buglog-status.md defines the status values (kept out of
  openwolf.md, which `openwolf update` overwrites).
- scripts/buglog.py + buglog skill: add (next free id), status, note,
  recur, list, show, triage. Edits only the touched entry's lines; a full
  json.dumps rewrite churns ~1,200 lines of mixed \u-escaping.
- gitea-sync (script + skill): state and a single bug:<status> label come
  from `status`; reopen supported; issues shared by several entries follow
  the most-open one; only status labels are swapped; per-entry write-back
  with gitea_synced_status so unchanged entries cost no API calls; list-typed
  `fix` no longer crashes; spec issues close on done phases (spec.json has
  no implementation approval); --since no longer floods Gitea after the
  backfill.
- Disable OpenWolf buglog auto-detection: its hook numbers new entries
  len(bugs)+1, which collides with existing ids (bug-1856, upstream).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-24 09:40:48 +00:00

2.1 KiB

Buglog status field

Kept separate from openwolf.md because openwolf update overwrites that file. OpenWolf itself ignores this field (search, pre-write hints and the hook-created entries don't read or set it), so the convention is enforced only by this rule.

  • Every .wolf/buglog.json entry carries a status, and it is the only source of truth for whether a bug is open. Never infer it from fix: many entries have a populated fix that says "NOT FIXED", "PENDING" or "PARTIAL".
  • Values:
    • open: defect confirmed and still in the code. Intermittent test failures that do still recur count as open, not cannot-reproduce.
    • partial: part fixed; status_note says what remains.
    • investigating: real failure observed, root cause not found yet or waiting for a reproduction.
    • fixed: fix committed; cite the commit in fix or status_note.
    • cannot-reproduce: reproduction was attempted and failed; record what was tried in repro_attempts (e.g. "0/40 runs, 2026-08-01").
    • wontfix: not a bug, accepted limitation, or deferred with no plan.
    • duplicate: same defect as another entry; set duplicate_of.
  • Whenever you log a bug or change its state, set status and status_updated (YYYY-MM-DD), plus status_note unless the status is fixed with the commit already in fix. Put them right after "id".
  • A cannot-reproduce bug that recurs: bump occurrences/last_seen and set status back to investigating.
  • Use the buglog skill (scripts/buglog.py) to add entries and change status: add, status, note, recur, list, triage. It picks the next free id and edits only the touched entry's lines. Don't re-serialize the whole file with json.dumps/jq; that rewrites ~1,200 unrelated lines.
  • Open-bug list: jq -r '.bugs[] | select(.status | IN("open","partial","investigating")) | "\(.id) [\(.status)] \(.status_note // .error_message[0:90])"' .wolf/buglog.json
  • Entries with no status (hand-written without it, or created by an OpenWolf hook) need triage: jq -r '.bugs[] | select(.status == null) | .id' .wolf/buglog.json