myxce/.wolf/bugs/bug-1745.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

5.1 KiB

id status status_updated status_note component severity timestamp last_seen occurrences files tags related legacy
bug-1745 fixed 2026-09-24 unknown unknown 2026-09-01T00:20:00Z 2026-09-19T09:00:00Z 1
.kiro/specs/worker-rejoin-resync/design.md
design-phase
worker-rejoin-resync
kiro-validate-design
bug-1678
bug-1631
bug-1679
scheduler-dispatch-commit
not-a-runtime-bug
bug-1678
bug-1631
bug-1679
bug-1514
true

bug-1745: kiro-validate-design worker-rejoin-resync (design phase, spec never implemented yet): initial pass…

Description

kiro-validate-design worker-rejoin-resync (design phase, spec never implemented yet): initial pass found 2 critical issues in design.md, self-correction during the fix pass found 2 more. None are runtime bugs (no code exists for this spec yet) -- this entry records design-document defects caught before implementation, same category as bug-1514.

Environment

Not recorded (migrated from buglog.json).

Reproduction

Not recorded (migrated from buglog.json).

Root cause

(1) design.md's Data Models section cited bug-1678 (WAL_JOB_DISPATCH not carrying job->allocs through replay) as a still-open, tracked gap justifying record_job_reconcile_assign_fact() not populating an allocation -- bug-1678 was actually fixed 2026-08-25, before this design.md was finalized; the citation was stale, and the design missed that persist_submit_job_dispatch_fact() (the fixed primitive) already has a tested NULL-alloc path it could directly reuse instead of inventing a new WAL fact shape. (2) design.md's dispatch-gating reuse (Requirement 5.1, XCE_WORKER_RECONCILING via dispatch_a_job_'s w->host.status != 0 check) was researched before scheduler-dispatch-commit (2026-08-24/25) added xce_classify_dispatch_fail()'s bounded-retry-then-mark_job_fail() machinery behind that exact check -- the design's own 'Revalidation Triggers' section named this exact check as a trigger but it had not actually been re-checked against current code. A RECONCILING host could be selected as a dispatch candidate by the scheduler (whose own filter only checks IS_WORKER_UNAVAIL, confirmed via grep) and then get retried-then-terminal-failed by the controller purely for being mid-reconciliation. (3) Fixing (1) surfaced bug-1631 (job.allocs never released on dispatch_a_job_'s retryable-failure paths, deliberately left unfixed because nothing in the system re-admitted an already-RUN job to the scheduler's PEND pool) -- worker-rejoin-resync's own Requirement 4.6 (unrecognized job -> return to PEND, eligible for re-dispatch) IS such a re-admission path, and design.md's record_job_reconcile_pending_fact spec did not release job->job.allocs, reactivating bug-1631's exact deferred trigger condition. (4) Fixing (3) by adding an eager job->job.allocs release exposed a self-introduced inconsistency: apply_job_update_transition() only mutates job->job.state, deferred until apply_committed_entry applies the committed fact (confirmed by reading record_job_finish_fact()'s identical deferred pattern) -- an eager allocs release paired with a deferred state change would produce a real, brief RUN-state-with-NULL-allocs window. Resolved by modeling both new job.c functions on dispatch_a_job_'s own eager-mutation-plus-explicit-persist_notify_job_updated_already_persisted pattern (bug-1679's precedent) instead, rather than record_job_finish_fact's deferred one.

Fix

All 4 corrected directly in design.md during the same validation session (not deferred to implementation): (1) Data Models' 'Documented scope decision' + Components section rewritten -- record_job_reconcile_assign_fact() now specified to call the existing, fixed persist_submit_job_dispatch_fact(alloc=NULL) directly. (2) Added a new Scheduler-side component (scheduler.c:1211's candidate filter gets one added disjunct, IS_WORKER_RECONCILING, mirroring the existing IS_WORKER_UNAVAIL check) as the primary Requirement 5.1 enforcement, with dispatch_a_job_'s existing check kept as an unmodified defensive backstop; Requirement 5.4's disconnected-worker case given its own pre-classifier branch (bypassing xce_classify_dispatch_fail entirely, not a 3rd enum value, to avoid forcing ~5 unrelated switch sites to handle a case they can't hit). (3) record_job_reconcile_pending_fact() now specified to release job->job.allocs eagerly. (4) Both new job.c functions redesigned around dispatch_a_job_'s eager-mutation + persist_notify_job_updated_already_persisted pattern, explicitly not record_job_finish_fact's deferred one, with the rationale (worker-confirmed ground truth vs. an unconfirmed local admin command) documented inline so a future editor doesn't accidentally revert to the deferred pattern. spec.json's design.approved flipped to true with a validation_note recording this trail. No code was written -- this is a design-document-only fix; implementation-time discovery may still surface further refinement, per design.md's own remaining 'must confirm at implementation time' caveats.

Verification

Not recorded (migrated from buglog.json).

References

  • Related: bug-1678, bug-1631, bug-1679, bug-1514