feat: Log loop claim decisions: which candidate was picked and why others were skipped (#124) - #127
Conversation
…hers were skipped (#124)
There was a problem hiding this comment.
QA panel review — PASS
code-review · head bca95629776b · formal
[review-synthesizer completed: workflow code-review:report]
Brief
Overall risk: Low. The only finding from the panel (a correctness concern about intra-tick file collisions in loop.py) was refuted by verification — the verifier confirmed that busy |= files is still executed at the end of each successful iteration, so the guard continues to refresh per iteration as intended. No defects survive the verify pass.
Fix-first item: None — the finding was refuted, not retained.
Panel disagreement: The panel flagged a correctness issue with busy not being updated within the loop, but the verifier demonstrated that the busy |= files line at the end of each iteration (after selected.append(...)) does refresh busy before the next candidate is processed. The panel missed this line in their evidence review.
Verification changes: The verifier marked the sole finding as refuted with a clear note showing the diff evidence (busy |= files at line ~877, after selected.append(claimed['id'])) that contradicts the panel's claim that busy is never refreshed. No uncertain findings remain.
Coverage note: This was the only finding submitted by the panel. With no other findings to cross-check, I cannot confirm whether other heavily-changed files were under-read — the panel's report was singular in scope.
[]
Merge verdict — protoEngineer adjudicationVerdict: MERGE. CI: All SUCCESS on the current head. Operator independently verified the merged state against new Review gate: NOT RUN. This board's The tests assert content, not existence. The Manual merge — no |
Summary
The claim loop was silent about which Ready feature it picked and why it passed over others, leaving no way to tell a lost claim race from the hot-file guard from a
ready_queuemis-ordering._spawn_readynow emits exactly one structuredclaim_decisionlog.infoper tick: a JSON payload with the selected fid(s) and, for each candidate skipped, the reason —hot-file(naming the in-flight fid and files it collides with),claim-race(claim()returned None),blocked, orstate=<x>. The JSON is parseable without grepping log levels, so a future observer can trace exactly why a lower-priority card claimed ahead of a higher one. Two tests intests/test_loop.pyassert the line's content — that the selected fid and the passed-over candidate's skip reason (hot-file overlap and, separately, a claim race) are both recorded.Fixes #124