--- id: "bug-1855" status: "fixed" status_updated: "2026-09-24" status_note: "commit 'feat(buglog): status field, buglog skill, status-driven gitea-sync' (2026-09-24)" component: "tooling" severity: "unknown" timestamp: "2026-09-24T09:39:50Z" last_seen: "2026-09-24T09:39:50Z" occurrences: 1 files: ["scripts/gitea-sync.py", ".claude/skills/gitea-sync/SKILL.md"] tags: ["gitea-sync", "tooling", "buglog"] related: ["bug-1677"] legacy: true gitea_issue: 88 gitea_synced_status: "fixed" --- # bug-1855: gitea-sync mirrored unfixed bugs as closed + bug:fixed: an issue was closed whenever the buglog… ## Description gitea-sync mirrored unfixed bugs as closed + bug:fixed: an issue was closed whenever the buglog entry's fix text was non-empty, including fix texts reading 'NOT FIXED', 'PENDING' or 'PARTIALLY FIXED' (e.g. bug-1450 #25, bug-1451 #35, bug-1744 #47) ## Environment _Not recorded (migrated from buglog.json)._ ## Reproduction _Not recorded (migrated from buglog.json)._ ## Root cause buglog.json had no status field, so scripts/gitea-sync.py and the gitea-sync skill inferred open/closed from fix being non-empty. Same script also: crashed on entries whose fix is a list (.strip() on list); replaced an issue's whole label set with just bug:fixed on close (wiping bug/category/user labels); wrote gitea_issue back only after the whole loop via a full json.dumps rewrite (a mid-run failure lost issue numbers -> duplicate issues next run, and the rewrite churned ~1,200 unrelated lines); read approvals.implementation, which no spec.json has, so spec implementation/validation issues and milestones never closed; never reopened an issue whose bug came back. ## Fix Added a status field to every buglog entry (backfilled 2026-09-24) and made status the only open/closed source: STATUS_MAP -> state + one bug: label; entries sharing an issue take the most-open status; only status labels are swapped (other labels kept); reopen supported; gitea_synced_status tracks what was mirrored so unchanged entries make no API calls; per-entry surgical write-back via scripts/buglog.py set_fields; spec issues close on DONE_PHASES (implementation-complete/implemented/superseded). Skill doc updated to match. UPDATE (2026-09-24): Found during the first live run: DELETE/204 replies have an empty body (json.loads crashed the run after the first label removal), requests had no timeout (a stalled call hung the run), spec.json write-back reflowed 15 hand-formatted files, and the implementation-issue body showed the tasks approval flag as 'Tasks generated'. All fixed; first live run: bugs 20 created, 2 reopened (#25, #35), 14 relabelled; specs 65 milestones + 195 issues (158 closed at creation). ## Verification _Not recorded (migrated from buglog.json)._ ## References - Related: bug-1677 - Gitea: #88