diff --git a/.kiro/specs/ha-commit-barrier-rollout/tasks.md b/.kiro/specs/ha-commit-barrier-rollout/tasks.md index 9481d53d..88d0f8d4 100644 --- a/.kiro/specs/ha-commit-barrier-rollout/tasks.md +++ b/.kiro/specs/ha-commit-barrier-rollout/tasks.md @@ -43,7 +43,7 @@ - Observable completion: all task 3.1 tests PASS; `handle_jobsubmit` untouched (reference implementation) - _Requirements: 1.1, 1.2, 1.3, 1.4_ -- [ ] 3.3 Pin the receipt-ACK verdicts with tests +- [x] 3.3 Pin the receipt-ACK verdicts with tests - Tests: `handle_jobdispatch` (job.c:459-491) replies immediately AND dispatch processing appends no WAL entries (classification guard stays silent through a dispatch cycle; `notify_dispatch` outcomes unaffected); `do_set_preason`/`do_clr_preason` and the `do_update_op` rusage path remain receipt-style replies whose subsequent fact appends are RETAIN-registered - Document the verdict in the test comments with the umbrella Reply-Ordering Contract reference - Observable completion: verdict tests PASS without modifying those handlers; any future WAL append from dispatch processing trips the classification guard in CI @@ -112,6 +112,7 @@ - (1.1) wal_entry_type has 13 values (wal_types.h:44-58), no WAL_NOOP yet (lands in ha-single-leader-role, which must add a classification row + sweep entry — the totality sweep will catch it). - (1.1) Suite baseline is ZERO failures since ha-commit-engine 6.1. detect_leaks=0 remains the harness norm (6 inventoried pre-existing leak groups). - (1.2) CENSUS METHOD: only ~9 of 48 groups emit Unity summary blocks; the rest report per-test PASS lines only — count distinct Unity results (~465) and grep FAIL lines, never sum summary blocks. commit_submit(RETAIN) early-returns BEFORE taking ce->lock (commit.c:233-239) — registration is lock-free, safe with entity write locks held. wal_hook_append_classified is the single classified-append seam; appended_lsn read = current_lsn - 1 under p->lock (benign race, commented). +- (3.3) **bug-451 DISCOVERED (reviewer-verified byte-precise, NOT fixed — boundary)**: update_job_rusages fires HOOK_DETAIL_JOB_RUSAGE_UPDATE with (cluster_t*, xce_job_rusages_t*) (job.c:1014-1015) but persist_job_hook_fun's default arm (persist.c:1355-1359) reads vararg 2 as job_t* and dereferences j->job.state at offset 56 — one past the end of the exactly-56-byte xce_job_rusages_t → 4-byte OOB read + garbage state field in every WAL_JOB_RUSAGE payload (jobid lines up by accident). Production fix candidate for task 7.1's sweep or a follow-up: persist arm needs a RUSAGE-specific va_list signature. Census now 488. - (3.2) bug-447 FIXED via rc normalization inside the three ctrl fns (real errors/misses preserved; reviewer-verified per-fn). Semantics change shipped intentionally: idempotent no-op control actions now return 0 (was leaked 1); queue/host mutations now append WAL + replicate. Join barrier failure → error reply + on_worker_join SKIPPED (coherent reading of design; worker retries via idempotent rejoin; documented at join.c:108-113). PRE-EXISTING ref leak: job_ctrl takes reference(j) (job.c:317) but normal exit never dereferences (bug-448) — out of scope, future fix. - (3.1) **bug-447 CONFIRMED (reviewer-verified to librtti disassembly)**: key_find returns 1 on found (unnormalized from xkvmgr_find/kvtab_find); queue_ctrl (queue.c:61, gate :106) and worker_ctrl (worker.c:644, gate :678) leak rc=1 → AFTER_EVENT never fires on the found path → **queue/host control silently unpersisted+unreplicated in production today**; job_ctrl appends via mark_job_* hooks but still replies status 1. Fix point = 3.2's handler rc normalization (key_find is in binary librtti, out of repo). RED tests pin it. - (3.1) Test link gained job.c/queue.c/join.c (test-only meson change) + 8 inert link stubs in test_commit_barrier_reply.c (none on tested paths — reviewer-traced). Reply capture = zeroed stack endpoint ep->outq inspection (test_config_repl.c:2210 precedent; endpoint_update_epoll no-ops when iomgr NULL). RED-window orphaned fsync threads self-resolve at GREEN (reviewer finding 5). diff --git a/.wolf/anatomy.md b/.wolf/anatomy.md index 690d92a4..c2dd9022 100644 --- a/.wolf/anatomy.md +++ b/.wolf/anatomy.md @@ -1,7 +1,7 @@ # anatomy.md -> Auto-maintained by OpenWolf. Last scanned: 2026-06-12T10:00:34.785Z -> Files: 509 tracked | Anatomy hits: 0 | Misses: 0 +> Auto-maintained by OpenWolf. Last scanned: 2026-06-12T11:16:47.642Z +> Files: 513 tracked | Anatomy hits: 0 | Misses: 0 ## ./ @@ -253,7 +253,7 @@ - `requirements.md` — Requirements Document (~3181 tok) - `research.md` — Research & Design Decisions: ha-commit-barrier-rollout (~3672 tok) - `spec.json` (~143 tok) -- `tasks.md` — Implementation Plan: ha-commit-barrier-rollout (~4337 tok) +- `tasks.md` — Implementation Plan: ha-commit-barrier-rollout (~4653 tok) ## .kiro/specs/ha-commit-engine/ @@ -706,9 +706,13 @@ ## src/controller/ -- `meson.build` (~1130 tok) +- `job.c` — include (~8196 tok) +- `join.c` — include "config.h" (~2530 tok) +- `meson.build` (~1134 tok) +- `queue.c` — include (~1451 tok) +- `worker.c` — include (~5124 tok) ## src/controller/testsuite/ - `controller_test.c` — include (~1368 tok) -- `test_commit_barrier_reply.c` — Task 3.1 RED integration tests: commit-first-then-reply per opcode (jobctrl/queuectrl/hostctrl/worker-join) via endpoint outq reply capture + pthread handler runner; pins the key_find rc==1 hook-skip gap (~8639 tok) +- `test_commit_barrier_reply.c` — Task 3.1 commit-first-then-reply integration tests + task 3.3 receipt-ACK verdict pins (jobdispatch/preason/rusage); cluster harness w/ real persist, wired commit engine, stub standbys, reply-capture endpoint, notify/get_ep_worker capture stubs (~17500 tok) diff --git a/.wolf/buglog.json b/.wolf/buglog.json index ed78d7fd..16d3d5cb 100644 --- a/.wolf/buglog.json +++ b/.wolf/buglog.json @@ -7,7 +7,7 @@ "error_message": "Significant refactor of ", "file": "CLAUDE.md", "root_cause": "3 lines replaced/restructured", - "fix": "Rewrote 23\u219230 lines (3 removed)", + "fix": "Rewrote 23→30 lines (3 removed)", "tags": [ "auto-detected", "refactor", @@ -39,7 +39,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/testsuite/test_config_repl.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 14\u219219 lines (2 removed)", + "fix": "Rewrote 14→19 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -55,7 +55,7 @@ "error_message": "Wrong reference: g_tmpdir should be g_instdir", "file": "src/controller/testsuite/test_config_repl.c", "root_cause": "Used \"g_tmpdir\" instead of \"g_instdir\"", - "fix": "Changed g_tmpdir \u2192 g_instdir", + "fix": "Changed g_tmpdir → g_instdir", "tags": [ "auto-detected", "wrong-reference", @@ -87,7 +87,7 @@ "error_message": "Significant refactor of ", "file": "src/docs/config-replication-design.md", "root_cause": "7 lines replaced/restructured", - "fix": "Rewrote 17\u219220 lines (7 removed)", + "fix": "Rewrote 17→20 lines (7 removed)", "tags": [ "auto-detected", "refactor", @@ -135,7 +135,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/config_repl.h", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 6\u21929 lines (2 removed)", + "fix": "Rewrote 6→9 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -151,7 +151,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/config_repl.c", "root_cause": "5 lines replaced/restructured", - "fix": "Rewrote 11\u21925 lines (5 removed)", + "fix": "Rewrote 11→5 lines (5 removed)", "tags": [ "auto-detected", "refactor", @@ -167,7 +167,7 @@ "error_message": "Significant refactor of ", "file": "src/docs/config-replication-impl-status.md", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 10\u219212 lines (4 removed) | Also: | `handle_config_request()` (primary handler) | \u2705 ; | `fetch_config_from_primary()` (standby fetch) | | Also: | `handle_upgrade_config()` | \u2705 Compiled, gated | ; | `push_config_to_standbys()` | \u26a0 Stub (returns 0)", + "fix": "Rewrote 10→12 lines (4 removed) | Also: | `handle_config_request()` (primary handler) | ✅ ; | `fetch_config_from_primary()` (standby fetch) | | Also: | `handle_upgrade_config()` | ✅ Compiled, gated | ; | `push_config_to_standbys()` | ⚠ Stub (returns 0)", "tags": [ "auto-detected", "refactor", @@ -183,7 +183,7 @@ "error_message": "Significant refactor of ", "file": "src/docs/config-replication-impl-status.md", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 17\u219221 lines (4 removed)", + "fix": "Rewrote 17→21 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -199,7 +199,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "3 lines replaced/restructured", - "fix": "Rewrote 6\u21927 lines (3 removed)", + "fix": "Rewrote 6→7 lines (3 removed)", "tags": [ "auto-detected", "refactor", @@ -215,7 +215,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/ha-config-bootstrap/brief.md", "root_cause": "6 lines replaced/restructured", - "fix": "Rewrote 13\u219224 lines (6 removed)", + "fix": "Rewrote 13→24 lines (6 removed)", "tags": [ "auto-detected", "refactor", @@ -231,7 +231,7 @@ "error_message": "Significant refactor of ", "file": "../../../../../claude/.claude/plans/prancy-herding-nest.md", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 4\u219210 lines (4 removed)", + "fix": "Rewrote 4→10 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -247,7 +247,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/ha-config-bootstrap/brief.md", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 8\u21929 lines (4 removed)", + "fix": "Rewrote 8→9 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -262,7 +262,7 @@ "timestamp": "2026-05-25T11:05:06.112Z", "error_message": "Missing error handling in send", "file": ".kiro/specs/ha-config-bootstrap/brief.md", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -278,7 +278,7 @@ "timestamp": "2026-05-25T11:06:26.871Z", "error_message": "Missing error handling in unknown", "file": "../../../../../claude/.claude/plans/prancy-herding-nest.md", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -295,7 +295,7 @@ "error_message": "Significant refactor of ", "file": "../../../../../claude/.claude/plans/prancy-herding-nest.md", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 23\u219240 lines (2 removed)", + "fix": "Rewrote 23→40 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -326,7 +326,7 @@ "timestamp": "2026-05-25T11:32:18.221Z", "error_message": "Missing error handling in types", "file": "../../../../../claude/.claude/plans/prancy-herding-nest.md", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -343,7 +343,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/ha-config-bootstrap/brief.md", "root_cause": "36 lines replaced/restructured", - "fix": "Rewrote 63\u219279 lines (36 removed) | Also: 6. **No simultaneous primaries**: Only one node ca; 7. **Majority-commit WAL replication (CP writes)** | Also: - `handle_request_vote()` handler on all peers; - Config tag + LSN comparison for vote decision", + "fix": "Rewrote 63→79 lines (36 removed) | Also: 6. **No simultaneous primaries**: Only one node ca; 7. **Majority-commit WAL replication (CP writes)** | Also: - `handle_request_vote()` handler on all peers; - Config tag + LSN comparison for vote decision", "tags": [ "auto-detected", "refactor", @@ -391,7 +391,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/ha-config-bootstrap/brief.md", "root_cause": "3 lines replaced/restructured", - "fix": "Rewrote 11\u219228 lines (3 removed)", + "fix": "Rewrote 11→28 lines (3 removed)", "tags": [ "auto-detected", "refactor", @@ -439,7 +439,7 @@ "error_message": "Significant refactor of ", "file": "../../../../../claude/.claude/plans/prancy-herding-nest.md", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 13\u219228 lines (2 removed)", + "fix": "Rewrote 13→28 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -471,7 +471,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/ha-config-bootstrap/brief.md", "root_cause": "11 lines replaced/restructured", - "fix": "Rewrote 17\u219228 lines (11 removed)", + "fix": "Rewrote 17→28 lines (11 removed)", "tags": [ "auto-detected", "refactor", @@ -487,7 +487,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/ha-config-bootstrap/brief.md", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 28\u219245 lines (4 removed)", + "fix": "Rewrote 28→45 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -519,7 +519,7 @@ "error_message": "Significant refactor of ", "file": "../../../../../claude/.claude/plans/prancy-herding-nest.md", "root_cause": "13 lines replaced/restructured", - "fix": "Rewrote 22\u219235 lines (13 removed) | Also: **Files**: `src/controller/main.c`, `src/lib/netio; 1. **Peer-count validation in `main.c`** (before `", + "fix": "Rewrote 22→35 lines (13 removed) | Also: **Files**: `src/controller/main.c`, `src/lib/netio; 1. **Peer-count validation in `main.c`** (before `", "tags": [ "auto-detected", "refactor", @@ -567,7 +567,7 @@ "error_message": "Significant refactor of ", "file": "../../../../../claude/.claude/plans/prancy-herding-nest.md", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 4\u21927 lines (2 removed)", + "fix": "Rewrote 4→7 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -583,7 +583,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/ha-config-bootstrap/brief.md", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 9\u219211 lines (2 removed)", + "fix": "Rewrote 9→11 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -631,7 +631,7 @@ "error_message": "Significant refactor of ", "file": "../../../../../claude/.claude/plans/prancy-herding-nest.md", "root_cause": "18 lines replaced/restructured", - "fix": "Rewrote 29\u219234 lines (18 removed)", + "fix": "Rewrote 29→34 lines (18 removed)", "tags": [ "auto-detected", "refactor", @@ -679,7 +679,7 @@ "error_message": "Significant refactor of ", "file": "../../../../../claude/.claude/plans/prancy-herding-nest.md", "root_cause": "8 lines replaced/restructured", - "fix": "Rewrote 13\u219229 lines (8 removed) | Also: 8. **Register OP_requestVote handler** in cluster'; switch at line ~195): since vtaskmgr and iomgr run", + "fix": "Rewrote 13→29 lines (8 removed) | Also: 8. **Register OP_requestVote handler** in cluster'; switch at line ~195): since vtaskmgr and iomgr run", "tags": [ "auto-detected", "refactor", @@ -695,7 +695,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/ha-config-bootstrap/brief.md", "root_cause": "9 lines replaced/restructured", - "fix": "Rewrote 13\u219260 lines (9 removed) | Also: 3. **Replace timestamp polling with `EPOLLRDHUP`**; is replaced by an epoll event handler. On `EPOLLRD | Also: - **Split vote recovery**: After failing quorum, s; (using existing `jitter_seed` xorshift64), retry o", + "fix": "Rewrote 13→60 lines (9 removed) | Also: 3. **Replace timestamp polling with `EPOLLRDHUP`**; is replaced by an epoll event handler. On `EPOLLRD | Also: - **Split vote recovery**: After failing quorum, s; (using existing `jitter_seed` xorshift64), retry o", "tags": [ "auto-detected", "refactor", @@ -711,7 +711,7 @@ "error_message": "Significant refactor of ", "file": "../../../../../claude/.claude/plans/prancy-herding-nest.md", "root_cause": "8 lines replaced/restructured", - "fix": "Rewrote 8\u219234 lines (8 removed) | Also: 2. **Replace `ha_check_heartbeat_nocluster()` with; - On `EPOLLRDHUP` from `primary_ctrl_fd`: **close ", + "fix": "Rewrote 8→34 lines (8 removed) | Also: 2. **Replace `ha_check_heartbeat_nocluster()` with; - On `EPOLLRDHUP` from `primary_ctrl_fd`: **close ", "tags": [ "auto-detected", "refactor", @@ -726,7 +726,7 @@ "timestamp": "2026-05-26T13:51:32.274Z", "error_message": "Missing error handling in unknown", "file": "../../../../../claude/.claude/plans/prancy-herding-nest.md", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block | Also: - [ ] `test_heartbeat_carries_committed_lsn`: heartbeat payl; `committed_lsn`; standby updates `ha.last_known_committed_ls", "tags": [ "auto-detected", @@ -742,7 +742,7 @@ "timestamp": "2026-05-26T13:52:49.044Z", "error_message": "Missing error handling in unknown", "file": ".kiro/specs/ha-config-bootstrap/brief.md", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block | Also: // Catch-up gate (Clarification 6): behind nodes must not in; if (c->ha.in_catch_up) {", "tags": [ "auto-detected", @@ -758,7 +758,7 @@ "timestamp": "2026-05-27T03:02:34.912Z", "error_message": "Missing error handling in unknown", "file": "../../../../../claude/.claude/plans/prancy-herding-nest.md", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block | Also: name, key, applied_lsn, and config_tag immediately after TCP; - [ ] `test_ctrl_hello_registers_standby_in_repl`: handle_ct", "tags": [ "auto-detected", @@ -774,7 +774,7 @@ "timestamp": "2026-05-27T03:03:26.016Z", "error_message": "Missing error handling in unknown", "file": ".kiro/specs/ha-config-bootstrap/brief.md", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -791,7 +791,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/ha-config-bootstrap/brief.md", "root_cause": "9 lines replaced/restructured", - "fix": "Rewrote 37\u219251 lines (9 removed)", + "fix": "Rewrote 37→51 lines (9 removed)", "tags": [ "auto-detected", "refactor", @@ -807,7 +807,7 @@ "error_message": "Significant refactor of ", "file": "../../../../../claude/.claude/plans/prancy-herding-nest.md", "root_cause": "8 lines replaced/restructured", - "fix": "Rewrote 8\u219223 lines (8 removed) | Also: - [ ] `test_persistent_conn_single_node_noop`: ha_; when n_peers == 1; primary_ctrl_fd remains -1 (uni", + "fix": "Rewrote 8→23 lines (8 removed) | Also: - [ ] `test_persistent_conn_single_node_noop`: ha_; when n_peers == 1; primary_ctrl_fd remains -1 (uni", "tags": [ "auto-detected", "refactor", @@ -823,7 +823,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/ha-config-bootstrap/brief.md", "root_cause": "10 lines replaced/restructured", - "fix": "Rewrote 34\u219251 lines (10 removed)", + "fix": "Rewrote 34→51 lines (10 removed)", "tags": [ "auto-detected", "refactor", @@ -838,7 +838,7 @@ "timestamp": "2026-05-27T03:56:41.037Z", "error_message": "Missing error handling in unknown", "file": ".kiro/specs/ha-config-bootstrap/brief.md", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -855,7 +855,7 @@ "error_message": "Significant refactor of ", "file": "../../../../../claude/.claude/plans/prancy-herding-nest.md", "root_cause": "11 lines replaced/restructured", - "fix": "Rewrote 21\u219228 lines (11 removed)", + "fix": "Rewrote 21→28 lines (11 removed)", "tags": [ "auto-detected", "refactor", @@ -870,7 +870,7 @@ "timestamp": "2026-05-27T03:59:16.145Z", "error_message": "Missing error handling in unknown", "file": "../../../../../claude/.claude/plans/prancy-herding-nest.md", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -887,7 +887,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/ha-config-bootstrap/brief.md", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 10\u219213 lines (2 removed) | Also: **Replace LSF priority election with Raft-style qu; Five focused changes: | Also: 8. **Hard SSL/cert gate**: Controller refuses to b; 9. **Observable via logs**: Election results, vote", + "fix": "Rewrote 10→13 lines (2 removed) | Also: **Replace LSF priority election with Raft-style qu; Five focused changes: | Also: 8. **Hard SSL/cert gate**: Controller refuses to b; 9. **Observable via logs**: Election results, vote", "tags": [ "auto-detected", "refactor", @@ -902,7 +902,7 @@ "timestamp": "2026-05-27T06:45:34.951Z", "error_message": "Missing error handling in unknown", "file": ".kiro/specs/ha-config-bootstrap/brief.md", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -919,7 +919,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/ha-config-bootstrap/brief.md", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 8\u219211 lines (2 removed)", + "fix": "Rewrote 8→11 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -967,7 +967,7 @@ "error_message": "Significant refactor of ", "file": "src/schema/controller.capnp", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 5\u21927 lines (2 removed)", + "fix": "Rewrote 5→7 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -982,7 +982,7 @@ "timestamp": "2026-05-28T02:55:40.362Z", "error_message": "Missing error handling in unknown", "file": "src/schema/controller.capnp", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -999,7 +999,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.h", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 5\u219240 lines (2 removed)", + "fix": "Rewrote 5→40 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -1014,7 +1014,7 @@ "timestamp": "2026-05-28T03:39:14.341Z", "error_message": "Missing error handling in struct", "file": "src/controller/ha.h", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -1030,7 +1030,7 @@ "timestamp": "2026-05-28T03:40:17.891Z", "error_message": "Missing error handling in struct", "file": "src/include/typemap.h", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -1047,7 +1047,7 @@ "error_message": "Significant refactor of ", "file": "src/include/typemap.h", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 4\u21926 lines (2 removed)", + "fix": "Rewrote 4→6 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -1095,7 +1095,7 @@ "error_message": "Wrong reference: vcpus should be nres", "file": "src/include/clusterconfig.h", "root_cause": "Used \"vcpus\" instead of \"nres\"", - "fix": "Changed vcpus \u2192 nres", + "fix": "Changed vcpus → nres", "tags": [ "auto-detected", "wrong-reference", @@ -1111,7 +1111,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/cluster.c", "root_cause": "8 lines replaced/restructured", - "fix": "Rewrote 12\u21926 lines (8 removed)", + "fix": "Rewrote 12→6 lines (8 removed)", "tags": [ "auto-detected", "refactor", @@ -1143,7 +1143,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/testsuite/test_ha_startup.c", "root_cause": "8 lines replaced/restructured", - "fix": "Rewrote 12\u219218 lines (8 removed)", + "fix": "Rewrote 12→18 lines (8 removed)", "tags": [ "auto-detected", "refactor", @@ -1159,7 +1159,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/cluster.c", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 109\u2192144 lines (4 removed)", + "fix": "Rewrote 109→144 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -1206,7 +1206,7 @@ "timestamp": "2026-05-28T07:13:42.089Z", "error_message": "Missing error handling in struct", "file": "src/controller/ha.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -1222,7 +1222,7 @@ "timestamp": "2026-05-28T07:14:03.724Z", "error_message": "Missing error handling in unknown", "file": "src/controller/ha.h", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -1255,7 +1255,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "14 lines replaced/restructured", - "fix": "Rewrote 92\u2192344 lines (14 removed)", + "fix": "Rewrote 92→344 lines (14 removed)", "tags": [ "auto-detected", "refactor", @@ -1271,7 +1271,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/myapp.c", "root_cause": "6 lines replaced/restructured", - "fix": "Rewrote 25\u219249 lines (6 removed)", + "fix": "Rewrote 25→49 lines (6 removed)", "tags": [ "auto-detected", "refactor", @@ -1335,7 +1335,7 @@ "error_message": "Wrong reference: capn_str_null should be str", "file": "src/controller/config_repl.c", "root_cause": "Used \"capn_str_null\" instead of \"str\"", - "fix": "Changed capn_str_null \u2192 str", + "fix": "Changed capn_str_null → str", "tags": [ "auto-detected", "wrong-reference", @@ -1351,7 +1351,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/config_repl.c", "root_cause": "7 lines replaced/restructured", - "fix": "Rewrote 17\u219284 lines (7 removed)", + "fix": "Rewrote 17→84 lines (7 removed)", "tags": [ "auto-detected", "refactor", @@ -1398,7 +1398,7 @@ "timestamp": "2026-05-28T13:34:49.513Z", "error_message": "Missing error handling in unknown", "file": "src/controller/repl.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -1415,7 +1415,7 @@ "error_message": "Significant refactor of ", "file": "src/include/repl.h", "root_cause": "3 lines replaced/restructured", - "fix": "Rewrote 3\u21924 lines (3 removed) | Also: /* ACK handling \u2014 call from io_worker read callbac; /* Majority-quorum ACK wait \u2014 stub until task 7.3 ", + "fix": "Rewrote 3→4 lines (3 removed) | Also: /* ACK handling — call from io_worker read callbac; /* Majority-quorum ACK wait — stub until task 7.3 ", "tags": [ "auto-detected", "refactor", @@ -1430,7 +1430,7 @@ "timestamp": "2026-05-28T13:52:52.636Z", "error_message": "Missing error handling in unknown", "file": "src/controller/repl.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -1447,7 +1447,7 @@ "error_message": "Wrong reference: in_catch_up should be acked_config_lsn", "file": "src/controller/repl.c", "root_cause": "Used \"in_catch_up\" instead of \"acked_config_lsn\"", - "fix": "Changed in_catch_up \u2192 acked_config_lsn", + "fix": "Changed in_catch_up → acked_config_lsn", "tags": [ "auto-detected", "wrong-reference", @@ -1479,7 +1479,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/persist.c", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 20\u219229 lines (4 removed)", + "fix": "Rewrote 20→29 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -1495,7 +1495,7 @@ "error_message": "Wrong reference: ha_state_t should be _Atomic", "file": "src/controller/ha.h", "root_cause": "Used \"ha_state_t\" instead of \"_Atomic\"", - "fix": "Changed ha_state_t \u2192 _Atomic", + "fix": "Changed ha_state_t → _Atomic", "tags": [ "auto-detected", "wrong-reference", @@ -1511,7 +1511,7 @@ "error_message": "Wrong reference: socket should be epoll", "file": "src/controller/ha.c", "root_cause": "Used \"socket\" instead of \"epoll\"", - "fix": "Changed socket \u2192 epoll", + "fix": "Changed socket → epoll", "tags": [ "auto-detected", "wrong-reference", @@ -1559,7 +1559,7 @@ "error_message": "Wrong reference: XCE_ERR_STANDBY should be E_XCE_STANDBY", "file": "src/lib/request.c", "root_cause": "Used \"XCE_ERR_STANDBY\" instead of \"E_XCE_STANDBY\"", - "fix": "Changed XCE_ERR_STANDBY \u2192 E_XCE_STANDBY", + "fix": "Changed XCE_ERR_STANDBY → E_XCE_STANDBY", "tags": [ "auto-detected", "wrong-reference", @@ -1575,7 +1575,7 @@ "error_message": "Wrong reference: XCE_ERR_NOT_READY should be E_XCE_NOT_READY", "file": "src/lib/testsuite/test_libxce_retry.c", "root_cause": "Used \"XCE_ERR_NOT_READY\" instead of \"E_XCE_NOT_READY\"", - "fix": "Changed XCE_ERR_NOT_READY \u2192 E_XCE_NOT_READY", + "fix": "Changed XCE_ERR_NOT_READY → E_XCE_NOT_READY", "tags": [ "auto-detected", "wrong-reference", @@ -1590,7 +1590,7 @@ "timestamp": "2026-05-29T03:27:20.556Z", "error_message": "Missing error handling in unknown", "file": "src/controller/ha.h", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -1606,7 +1606,7 @@ "timestamp": "2026-05-29T03:29:44.753Z", "error_message": "Missing error handling in unknown", "file": "src/controller/config_repl.h", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -1623,7 +1623,7 @@ "error_message": "Wrong reference: data should be ctrl_hello_reply_t", "file": "src/include/typemap.h", "root_cause": "Used \"data\" instead of \"ctrl_hello_reply_t\"", - "fix": "Changed data \u2192 ctrl_hello_reply_t", + "fix": "Changed data → ctrl_hello_reply_t", "tags": [ "auto-detected", "wrong-reference", @@ -1638,7 +1638,7 @@ "timestamp": "2026-05-29T03:53:48.559Z", "error_message": "Missing error handling in unknown", "file": "src/schema/controller.capnp", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -1654,7 +1654,7 @@ "timestamp": "2026-05-29T03:54:23.205Z", "error_message": "Missing error handling in struct", "file": "src/include/typemap.h", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block | Also: wal_catchup_entry_t* walcatchupentrymsg;; snapshot_transfer_t* snapshottransfermsg; | Also: /* Forward declarations for types defined later in this file; typedef struct snapshot_transfer_t snapshot_transfer_fw", "tags": [ "auto-detected", @@ -1671,7 +1671,7 @@ "error_message": "Significant refactor of ", "file": "src/include/typemap.h", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 5\u21925 lines (2 removed)", + "fix": "Rewrote 5→5 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -1687,7 +1687,7 @@ "error_message": "Significant refactor of ", "file": "src/schema/controller.capnp", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 5\u21923 lines (2 removed)", + "fix": "Rewrote 5→3 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -1702,7 +1702,7 @@ "timestamp": "2026-05-29T04:04:12.693Z", "error_message": "Missing error handling in unknown", "file": "src/controller/config_repl.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -1719,7 +1719,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/config_repl.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 10\u219212 lines (2 removed)", + "fix": "Rewrote 10→12 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -1751,7 +1751,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "5 lines replaced/restructured", - "fix": "Rewrote 10\u219220 lines (5 removed)", + "fix": "Rewrote 10→20 lines (5 removed)", "tags": [ "auto-detected", "refactor", @@ -1783,7 +1783,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/ha-config-bootstrap/manual-tests.md", "root_cause": "9 lines replaced/restructured", - "fix": "Rewrote 18\u219220 lines (9 removed)", + "fix": "Rewrote 18→20 lines (9 removed)", "tags": [ "auto-detected", "refactor", @@ -1798,7 +1798,7 @@ "timestamp": "2026-05-29T10:59:37.144Z", "error_message": "Missing error handling in unknown", "file": ".kiro/specs/ha-config-bootstrap/manual-tests.md", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -1815,7 +1815,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/ha-config-bootstrap/manual-tests.md", "root_cause": "10 lines replaced/restructured", - "fix": "Rewrote 20\u219236 lines (10 removed) | Also: ### 11.1 Concurrent Startup (3 nodes); - Result: PASS / FAIL", + "fix": "Rewrote 20→36 lines (10 removed) | Also: ### 11.1 Concurrent Startup (3 nodes); - Result: PASS / FAIL", "tags": [ "auto-detected", "refactor", @@ -1831,7 +1831,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/config_repl.c", "root_cause": "5 lines replaced/restructured", - "fix": "Rewrote 29\u219245 lines (5 removed)", + "fix": "Rewrote 29→45 lines (5 removed)", "tags": [ "auto-detected", "refactor", @@ -1847,7 +1847,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/testsuite/test_ha_bootstrap.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 4\u21928 lines (2 removed)", + "fix": "Rewrote 4→8 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -1879,7 +1879,7 @@ "error_message": "Wrong reference: nres should be vcpus", "file": "src/include/clusterconfig.h", "root_cause": "Used \"nres\" instead of \"vcpus\"", - "fix": "Changed nres \u2192 vcpus", + "fix": "Changed nres → vcpus", "tags": [ "auto-detected", "wrong-reference", @@ -1895,7 +1895,7 @@ "error_message": "Wrong reference: data should be request_vote_reply_t", "file": "src/include/typemap.h", "root_cause": "Used \"data\" instead of \"request_vote_reply_t\"", - "fix": "Changed data \u2192 request_vote_reply_t", + "fix": "Changed data → request_vote_reply_t", "tags": [ "auto-detected", "wrong-reference", @@ -1911,7 +1911,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "10 lines replaced/restructured", - "fix": "Rewrote 19\u219225 lines (10 removed)", + "fix": "Rewrote 19→25 lines (10 removed)", "tags": [ "auto-detected", "refactor", @@ -1926,7 +1926,7 @@ "timestamp": "2026-05-29T16:36:41.731Z", "error_message": "Missing error handling in unknown", "file": "src/controller/cluster.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -1943,7 +1943,7 @@ "error_message": "Wrong reference: cluster_init_phase2 should be cluster_register_listener", "file": "src/controller/include/cluster.h", "root_cause": "Used \"cluster_init_phase2\" instead of \"cluster_register_listener\"", - "fix": "Changed cluster_init_phase2 \u2192 cluster_register_listener", + "fix": "Changed cluster_init_phase2 → cluster_register_listener", "tags": [ "auto-detected", "wrong-reference", @@ -1975,7 +1975,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/myapp.c", "root_cause": "30 lines replaced/restructured", - "fix": "Rewrote 79\u219261 lines (30 removed)", + "fix": "Rewrote 79→61 lines (30 removed)", "tags": [ "auto-detected", "refactor", @@ -1991,7 +1991,7 @@ "error_message": "Significant refactor of ", "file": "src/include/xce/cluster_def.h", "root_cause": "5 lines replaced/restructured", - "fix": "Rewrote 8\u219215 lines (5 removed)", + "fix": "Rewrote 8→15 lines (5 removed)", "tags": [ "auto-detected", "refactor", @@ -2007,7 +2007,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/cluster.c", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 7\u219216 lines (4 removed)", + "fix": "Rewrote 7→16 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -2023,7 +2023,7 @@ "error_message": "Wrong reference: CTRL_PERF_NHASH should be c", "file": "src/controller/cluster.c", "root_cause": "Used \"CTRL_PERF_NHASH\" instead of \"c\"", - "fix": "Changed CTRL_PERF_NHASH \u2192 c", + "fix": "Changed CTRL_PERF_NHASH → c", "tags": [ "auto-detected", "wrong-reference", @@ -2039,7 +2039,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/cluster.c", "root_cause": "36 lines replaced/restructured", - "fix": "Rewrote 77\u219241 lines (36 removed)", + "fix": "Rewrote 77→41 lines (36 removed)", "tags": [ "auto-detected", "refactor", @@ -2055,7 +2055,7 @@ "error_message": "Wrong reference: true should be false", "file": ".claude/skills/xce-build/SKILL.md", "root_cause": "Used \"true\" instead of \"false\"", - "fix": "Changed true \u2192 false", + "fix": "Changed true → false", "tags": [ "auto-detected", "wrong-reference", @@ -2071,7 +2071,7 @@ "error_message": "Wrong reference: 120 should be 300", "file": "src/controller/meson.build", "root_cause": "Used \"120\" instead of \"300\"", - "fix": "Changed 120 \u2192 300", + "fix": "Changed 120 → 300", "tags": [ "auto-detected", "wrong-reference", @@ -2086,7 +2086,7 @@ "timestamp": "2026-05-30T02:37:40.267Z", "error_message": "Missing error handling in unknown", "file": "src/controller/myapp.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -2103,7 +2103,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 15\u219221 lines (2 removed)", + "fix": "Rewrote 15→21 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -2119,7 +2119,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 9\u219213 lines (2 removed)", + "fix": "Rewrote 9→13 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -2135,7 +2135,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/election-iomgr-refactor/design.md", "root_cause": "3 lines replaced/restructured", - "fix": "Rewrote 10\u219227 lines (3 removed)", + "fix": "Rewrote 10→27 lines (3 removed)", "tags": [ "auto-detected", "refactor", @@ -2166,8 +2166,8 @@ "timestamp": "2026-05-30T06:38:09.325Z", "error_message": "Missing error handling in unknown", "file": ".kiro/specs/election-iomgr-refactor/design.md", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", - "fix": "Added try/catch block | Also: /* After election determines role: */; int is_first_boot = !c->running; /* running=1 only after cl | Also: #### `ha_dispatch_gate` \u2014 CTRL_PRIMARY_COMMITTING case; ```c | Also: ### 3-node startup \u2014 ctrl-a wins (with COMMITTING phase); participant PeerC as ctrl-c endpoint | Also: - **`ha_start_election_async()` is fully non-blocking**: Arm; - *Initial startup* (`ha->phase2_done == 0`): calls `cluster", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", + "fix": "Added try/catch block | Also: /* After election determines role: */; int is_first_boot = !c->running; /* running=1 only after cl | Also: #### `ha_dispatch_gate` — CTRL_PRIMARY_COMMITTING case; ```c | Also: ### 3-node startup — ctrl-a wins (with COMMITTING phase); participant PeerC as ctrl-c endpoint | Also: - **`ha_start_election_async()` is fully non-blocking**: Arm; - *Initial startup* (`ha->phase2_done == 0`): calls `cluster", "tags": [ "auto-detected", "error-handling", @@ -2183,7 +2183,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/election-iomgr-refactor/design.md", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 19\u219226 lines (4 removed) | Also: \u251c\u2500\u2500 ha.h # Add to ha_state_t: clie; \u2502 # ha_repl_ack_re | Also: \u2514\u2500\u2500 myapp.c # Restructured: phase1 + ; # for(;;) retry loop, cluster_init_phase2,", + "fix": "Rewrote 19→26 lines (4 removed) | Also: ├── ha.h # Add to ha_state_t: clie; │ # ha_repl_ack_re | Also: └── myapp.c # Restructured: phase1 + ; # for(;;) retry loop, cluster_init_phase2,", "tags": [ "auto-detected", "refactor", @@ -2199,7 +2199,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/election-iomgr-refactor/design.md", "root_cause": "12 lines replaced/restructured", - "fix": "Rewrote 15\u219220 lines (12 removed) | Also: - `src/controller/ha.h` \u2014 Add `client_ssl_ctx`, `r; - `src/controller/ha.c` \u2014 Main changes above; `ha_ | Also: \u251c\u2500\u2500 delay.c # Add delay_task_ms() (ms; \u2502 # Add delay_task_cancel()", + "fix": "Rewrote 15→20 lines (12 removed) | Also: - `src/controller/ha.h` — Add `client_ssl_ctx`, `r; - `src/controller/ha.c` — Main changes above; `ha_ | Also: ├── delay.c # Add delay_task_ms() (ms; │ # Add delay_task_cancel()", "tags": [ "auto-detected", "refactor", @@ -2231,7 +2231,7 @@ "error_message": "Significant refactor of ", "file": "src/lib/delay.c", "root_cause": "3 lines replaced/restructured", - "fix": "Rewrote 53\u219285 lines (3 removed)", + "fix": "Rewrote 53→85 lines (3 removed)", "tags": [ "auto-detected", "refactor", @@ -2247,7 +2247,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.h", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 7\u21928 lines (4 removed)", + "fix": "Rewrote 7→8 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -2327,7 +2327,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "3 lines replaced/restructured", - "fix": "Rewrote 14\u219217 lines (3 removed)", + "fix": "Rewrote 14→17 lines (3 removed)", "tags": [ "auto-detected", "refactor", @@ -2359,7 +2359,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/testsuite/test_ha_start_election_async.c", "root_cause": "8 lines replaced/restructured", - "fix": "Rewrote 24\u219242 lines (8 removed)", + "fix": "Rewrote 24→42 lines (8 removed)", "tags": [ "auto-detected", "refactor", @@ -2390,7 +2390,7 @@ "timestamp": "2026-05-30T11:08:59.808Z", "error_message": "Missing error handling in XCE_TESTING", "file": "src/controller/ha.h", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -2406,7 +2406,7 @@ "timestamp": "2026-05-30T11:09:47.905Z", "error_message": "Missing error handling in unknown", "file": "src/controller/ha.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -2423,7 +2423,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "8 lines replaced/restructured", - "fix": "Rewrote 62\u2192164 lines (8 removed) | Also: /* Store candidate own tag/lsn in votes[0] for eva; * n_peers==1 \u2192 n_other==0, so votes[] has 0 entrie | Also: * election_timeout_ctx_t: argument for the delay_t; * ha_elect_evaluate_and_signal when the election d", + "fix": "Rewrote 62→164 lines (8 removed) | Also: /* Store candidate own tag/lsn in votes[0] for eva; * n_peers==1 → n_other==0, so votes[] has 0 entrie | Also: * election_timeout_ctx_t: argument for the delay_t; * ha_elect_evaluate_and_signal when the election d", "tags": [ "auto-detected", "refactor", @@ -2454,7 +2454,7 @@ "timestamp": "2026-05-30T11:43:44.829Z", "error_message": "Missing error handling in XCE_TESTING", "file": "src/controller/ha.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block | Also: /* Push config to standbys with lower config_tag (Req 7.1) *; #ifdef XCE_TESTING", "tags": [ "auto-detected", @@ -2470,7 +2470,7 @@ "timestamp": "2026-05-30T11:44:15.059Z", "error_message": "Missing error handling in XCE_TESTING", "file": "src/controller/ha.h", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -2486,7 +2486,7 @@ "timestamp": "2026-05-30T11:45:24.946Z", "error_message": "Missing error handling in unknown", "file": "src/controller/cluster.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -2519,7 +2519,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/cluster.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 22\u219232 lines (2 removed)", + "fix": "Rewrote 22→32 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -2631,7 +2631,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "10 lines replaced/restructured", - "fix": "Rewrote 15\u21925 lines (10 removed)", + "fix": "Rewrote 15→5 lines (10 removed)", "tags": [ "auto-detected", "refactor", @@ -2695,7 +2695,7 @@ "error_message": "Wrong reference: third should be second", "file": "src/controller/testsuite/test_ha_repl_ack.c", "root_cause": "Used \"third\" instead of \"second\"", - "fix": "Changed third \u2192 second", + "fix": "Changed third → second", "tags": [ "auto-detected", "wrong-reference", @@ -2727,7 +2727,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/myapp.c", "root_cause": "5 lines replaced/restructured", - "fix": "Rewrote 10\u219215 lines (5 removed)", + "fix": "Rewrote 10→15 lines (5 removed)", "tags": [ "auto-detected", "refactor", @@ -2759,7 +2759,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "15 lines replaced/restructured", - "fix": "Rewrote 23\u219210 lines (15 removed)", + "fix": "Rewrote 23→10 lines (15 removed)", "tags": [ "auto-detected", "refactor", @@ -2775,7 +2775,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/config_repl.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 5\u21929 lines (2 removed)", + "fix": "Rewrote 5→9 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -2791,7 +2791,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/cluster.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 14\u219216 lines (2 removed)", + "fix": "Rewrote 14→16 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -2823,7 +2823,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "12 lines replaced/restructured", - "fix": "Rewrote 15\u219220 lines (12 removed)", + "fix": "Rewrote 15→20 lines (12 removed)", "tags": [ "auto-detected", "refactor", @@ -2839,7 +2839,7 @@ "error_message": "Significant refactor of ", "file": "src/include/typemap.h", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 4\u21928 lines (2 removed)", + "fix": "Rewrote 4→8 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -2855,7 +2855,7 @@ "error_message": "Significant refactor of ", "file": "src/xce.build/lib/controller.capnp.c", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 11\u219219 lines (4 removed) | Also: encode_Data_ptr(cs, &(d->sha256), s->sha256);; encode_Data_ptr(cs, &(d->bytes), s->bytes);", + "fix": "Rewrote 11→19 lines (4 removed) | Also: encode_Data_ptr(cs, &(d->sha256), s->sha256);; encode_Data_ptr(cs, &(d->bytes), s->bytes);", "tags": [ "auto-detected", "refactor", @@ -2871,7 +2871,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/cluster.c", "root_cause": "28 lines replaced/restructured", - "fix": "Rewrote 31\u21924 lines (28 removed)", + "fix": "Rewrote 31→4 lines (28 removed)", "tags": [ "auto-detected", "refactor", @@ -2887,7 +2887,7 @@ "error_message": "Significant refactor of ", "file": "src/include/typemap.h", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 8\u219218 lines (4 removed)", + "fix": "Rewrote 8→18 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -2903,7 +2903,7 @@ "error_message": "Significant refactor of ", "file": "src/include/request.h", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 10\u219219 lines (4 removed)", + "fix": "Rewrote 10→19 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -2935,7 +2935,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 5\u219210 lines (2 removed)", + "fix": "Rewrote 5→10 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -2951,7 +2951,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 9\u219211 lines (2 removed)", + "fix": "Rewrote 9→11 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -2966,7 +2966,7 @@ "timestamp": "2026-05-31T04:11:45.534Z", "error_message": "Missing error handling in struct", "file": ".kiro/specs/raft-library/design.md", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block | Also: Caller->>RaftSM: raft_on_vote_request(state, from, term); alt term < current_term", "tags": [ "auto-detected", @@ -2983,7 +2983,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/raft-library/design.md", "root_cause": "5 lines replaced/restructured", - "fix": "Rewrote 8\u219226 lines (5 removed) | Also: * raft_init: initialize state for a node.; * All required callbacks (except on_trace and on_v | Also: - C standard library only (`stdint.h`, `pthread.h`; - `raft.c` may include `` for lock-fr | Also: | Threading | `pthread_mutex_t` (caller-owned) | P; | Atomics | None in library | Caller uses atomics ", + "fix": "Rewrote 8→26 lines (5 removed) | Also: * raft_init: initialize state for a node.; * All required callbacks (except on_trace and on_v | Also: - C standard library only (`stdint.h`, `pthread.h`; - `raft.c` may include `` for lock-fr | Also: | Threading | `pthread_mutex_t` (caller-owned) | P; | Atomics | None in library | Caller uses atomics ", "tags": [ "auto-detected", "refactor", @@ -3014,7 +3014,7 @@ "timestamp": "2026-05-31T04:58:21.609Z", "error_message": "Missing error handling in RAFT_H", "file": "src/lib/raft/raft.h", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -3063,7 +3063,7 @@ "error_message": "Significant refactor of ", "file": "src/lib/testsuite/test_raft.c", "root_cause": "8 lines replaced/restructured", - "fix": "Rewrote 77\u2192107 lines (8 removed)", + "fix": "Rewrote 77→107 lines (8 removed)", "tags": [ "auto-detected", "refactor", @@ -3079,7 +3079,7 @@ "error_message": "Significant refactor of ", "file": "src/lib/raft/raft.c", "root_cause": "5 lines replaced/restructured", - "fix": "Rewrote 9\u219262 lines (5 removed)", + "fix": "Rewrote 9→62 lines (5 removed)", "tags": [ "auto-detected", "refactor", @@ -3095,7 +3095,7 @@ "error_message": "Significant refactor of ", "file": "src/lib/raft/raft.c", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 8\u219257 lines (4 removed)", + "fix": "Rewrote 8→57 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -3111,7 +3111,7 @@ "error_message": "Significant refactor of ", "file": "src/lib/raft/raft.c", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 15\u219238 lines (4 removed)", + "fix": "Rewrote 15→38 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -3127,7 +3127,7 @@ "error_message": "Significant refactor of ", "file": "src/lib/raft/raft_sim.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 6\u21923 lines (2 removed)", + "fix": "Rewrote 6→3 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -3159,7 +3159,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "32 lines replaced/restructured", - "fix": "Rewrote 49\u219216 lines (32 removed)", + "fix": "Rewrote 49→16 lines (32 removed)", "tags": [ "auto-detected", "refactor", @@ -3174,7 +3174,7 @@ "timestamp": "2026-05-31T07:26:39.758Z", "error_message": "Missing error handling in before", "file": "src/controller/ha.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -3191,7 +3191,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "3 lines replaced/restructured", - "fix": "Rewrote 6\u219219 lines (3 removed) | Also: typedef struct {; ha_state_t *ha; | Also: /* \u2500\u2500 Type definitions needed by ha_elect_evaluate; *", + "fix": "Rewrote 6→19 lines (3 removed) | Also: typedef struct {; ha_state_t *ha; | Also: /* ── Type definitions needed by ha_elect_evaluate; *", "tags": [ "auto-detected", "refactor", @@ -3207,7 +3207,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "167 lines replaced/restructured", - "fix": "Rewrote 291\u2192137 lines (167 removed) | Also: /* Clear voted_for: the old primary is dead; any v; * is stale and must not block the new election. */", + "fix": "Rewrote 291→137 lines (167 removed) | Also: /* Clear voted_for: the old primary is dead; any v; * is stale and must not block the new election. */", "tags": [ "auto-detected", "refactor", @@ -3223,7 +3223,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/cluster.c", "root_cause": "12 lines replaced/restructured", - "fix": "Rewrote 28\u219268 lines (12 removed)", + "fix": "Rewrote 28→68 lines (12 removed)", "tags": [ "auto-detected", "refactor", @@ -3239,7 +3239,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 16\u219221 lines (2 removed) | Also: /* Task 6.3: delegate vote reply accumulation to r; * raft_on_vote_reply owns quorum tracking and fire", + "fix": "Rewrote 16→21 lines (2 removed) | Also: /* Task 6.3: delegate vote reply accumulation to r; * raft_on_vote_reply owns quorum tracking and fire", "tags": [ "auto-detected", "refactor", @@ -3255,7 +3255,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "7 lines replaced/restructured", - "fix": "Rewrote 10\u21924 lines (7 removed)", + "fix": "Rewrote 10→4 lines (7 removed)", "tags": [ "auto-detected", "refactor", @@ -3271,7 +3271,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 5\u219214 lines (2 removed)", + "fix": "Rewrote 5→14 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -3284,7 +3284,7 @@ { "id": "bug-206", "timestamp": "2026-05-31T08:40:00.000Z", - "error_message": "test_vote_reply_handler_term_fencing FAIL: Expected 10 Was 3 \u2014 ha->term must be atomically updated to peer term when peer term > ours", + "error_message": "test_vote_reply_handler_term_fencing FAIL: Expected 10 Was 3 — ha->term must be atomically updated to peer term when peer term > ours", "file": "src/controller/ha.c", "root_cause": "vote_reply_msg_handler delegated term fencing entirely to raft_cb_become_follower (via raft_on_vote_reply). In XCE_TESTING builds, vote_reply_dispatch calls xce_vote_reply_hook and returns early, bypassing raft_on_vote_reply and thus never updating ha->term.", "fix": "Added explicit CAS loop in vote_reply_msg_handler before vote_reply_dispatch to advance ha->term when vr_term > ha->term. This applies on both the production path and the XCE_TESTING hook path.", @@ -3306,7 +3306,7 @@ "error_message": "Wrong reference: test_raft_init_zero_peers_returns_einval should be test_raft_init_even_peers_returns_einval", "file": "src/lib/testsuite/test_raft.c", "root_cause": "Used \"test_raft_init_zero_peers_returns_einval\" instead of \"test_raft_init_even_peers_returns_einval\"", - "fix": "Changed test_raft_init_zero_peers_returns_einval \u2192 test_raft_init_even_peers_returns_einval", + "fix": "Changed test_raft_init_zero_peers_returns_einval → test_raft_init_even_peers_returns_einval", "tags": [ "auto-detected", "wrong-reference", @@ -3319,7 +3319,7 @@ { "id": "bug-208", "timestamp": "2026-05-31", - "error_message": "ASAN LeakSanitizer: detected memory leaks in scheduler testsuite \u2014 build exits with error code", + "error_message": "ASAN LeakSanitizer: detected memory leaks in scheduler testsuite — build exits with error code", "file": "src/scheduler/testsuite/test.c", "root_cause": "sched_meet_host_selection() lazily allocates w->host_eval_ctx via build_host_eval_ctx(). Four test functions (test_meet_host_selection_always_true_passes, test_meet_host_selection_always_false_fails, test_meet_host_selection_numeric_match, test_meet_host_selection_string_match) called zarray_fini() without first calling sched_worker_release_host_ctx() to free the lazily-allocated host_eval_ctx.", "fix": "Added sched_worker_release_host_ctx(&w) calls before zarray_fini() in all four affected test functions.", @@ -3356,7 +3356,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "24 lines replaced/restructured", - "fix": "Rewrote 28\u21923 lines (24 removed) | Also: if (my_config_tag == 0) {; INFO(\"ha_start_election_async: no local config (ta", + "fix": "Rewrote 28→3 lines (24 removed) | Also: if (my_config_tag == 0) {; INFO(\"ha_start_election_async: no local config (ta", "tags": [ "auto-detected", "refactor", @@ -3372,7 +3372,7 @@ "error_message": "Wrong reference: 2000 should be 5000", "file": "src/controller/ha.h", "root_cause": "Used \"2000\" instead of \"5000\"", - "fix": "Changed 2000 \u2192 5000", + "fix": "Changed 2000 → 5000", "tags": [ "auto-detected", "wrong-reference", @@ -3388,7 +3388,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/myapp.c", "root_cause": "3 lines replaced/restructured", - "fix": "Rewrote 15\u219225 lines (3 removed)", + "fix": "Rewrote 15→25 lines (3 removed)", "tags": [ "auto-detected", "refactor", @@ -3404,7 +3404,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.h", "root_cause": "8 lines replaced/restructured", - "fix": "Rewrote 10\u219214 lines (8 removed)", + "fix": "Rewrote 10→14 lines (8 removed)", "tags": [ "auto-detected", "refactor", @@ -3420,7 +3420,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 7\u219217 lines (4 removed) | Also: /* Trigger async config fetch from primary so stan; #ifndef XCE_TESTING | Also: handle_request_vote_reply(vctx->ha, vctx->ctx, vct; /* Fix 5 (HIGH): do NOT free vctx here.", + "fix": "Rewrote 7→17 lines (4 removed) | Also: /* Trigger async config fetch from primary so stan; #ifndef XCE_TESTING | Also: handle_request_vote_reply(vctx->ha, vctx->ctx, vct; /* Fix 5 (HIGH): do NOT free vctx here.", "tags": [ "auto-detected", "refactor", @@ -3467,7 +3467,7 @@ "timestamp": "2026-05-31T12:54:26.372Z", "error_message": "Missing error handling in unknown", "file": "src/controller/ha.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -3484,7 +3484,7 @@ "error_message": "Wrong reference: Request_body_nodata should be Request_body_nomsg", "file": "src/controller/ha.c", "root_cause": "Used \"Request_body_nodata\" instead of \"Request_body_nomsg\"", - "fix": "Changed Request_body_nodata \u2192 Request_body_nomsg", + "fix": "Changed Request_body_nodata → Request_body_nomsg", "tags": [ "auto-detected", "wrong-reference", @@ -3500,7 +3500,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 10\u219218 lines (4 removed)", + "fix": "Rewrote 10→18 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -3516,7 +3516,7 @@ "error_message": "Wrong reference: vote_reply_msg_handler should be vote_reply_msg_handler_for_test", "file": "src/controller/ha.c", "root_cause": "Used \"vote_reply_msg_handler\" instead of \"vote_reply_msg_handler_for_test\"", - "fix": "Changed vote_reply_msg_handler \u2192 vote_reply_msg_handler_for_test", + "fix": "Changed vote_reply_msg_handler → vote_reply_msg_handler_for_test", "tags": [ "auto-detected", "wrong-reference", @@ -3532,7 +3532,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/config_repl.c", "root_cause": "3 lines replaced/restructured", - "fix": "Rewrote 13\u219236 lines (3 removed)", + "fix": "Rewrote 13→36 lines (3 removed)", "tags": [ "auto-detected", "refactor", @@ -3548,7 +3548,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/config_repl.c", "root_cause": "20 lines replaced/restructured", - "fix": "Rewrote 36\u219213 lines (20 removed)", + "fix": "Rewrote 36→13 lines (20 removed)", "tags": [ "auto-detected", "refactor", @@ -3563,7 +3563,7 @@ "timestamp": "2026-06-01T01:49:30.537Z", "error_message": "Missing error handling in unknown", "file": "src/controller/cluster.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -3596,7 +3596,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/cluster.c", "root_cause": "42 lines replaced/restructured", - "fix": "Rewrote 64\u219219 lines (42 removed)", + "fix": "Rewrote 64→19 lines (42 removed)", "tags": [ "auto-detected", "refactor", @@ -3611,7 +3611,7 @@ "timestamp": "2026-06-01T02:27:55.942Z", "error_message": "Missing error handling in struct", "file": "src/controller/ha.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -3628,7 +3628,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "5 lines replaced/restructured", - "fix": "Rewrote 10\u219214 lines (5 removed)", + "fix": "Rewrote 10→14 lines (5 removed)", "tags": [ "auto-detected", "refactor", @@ -3644,7 +3644,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/CLAUDE.md", "root_cause": "5 lines replaced/restructured", - "fix": "Rewrote 5\u219215 lines (5 removed)", + "fix": "Rewrote 5→15 lines (5 removed)", "tags": [ "auto-detected", "refactor", @@ -3660,7 +3660,7 @@ "error_message": "Wrong operator: && should be !=", "file": "src/controller/ha.c", "root_cause": "Used \"&&\" instead of \"!=\"", - "fix": "Changed operator && \u2192 !=", + "fix": "Changed operator && → !=", "tags": [ "auto-detected", "operator-fix", @@ -3676,7 +3676,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "10 lines replaced/restructured", - "fix": "Rewrote 16\u21927 lines (10 removed)", + "fix": "Rewrote 16→7 lines (10 removed)", "tags": [ "auto-detected", "refactor", @@ -3692,7 +3692,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "140 lines replaced/restructured", - "fix": "Rewrote 173\u219211 lines (140 removed)", + "fix": "Rewrote 173→11 lines (140 removed)", "tags": [ "auto-detected", "refactor", @@ -3708,7 +3708,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/myapp.c", "root_cause": "16 lines replaced/restructured", - "fix": "Rewrote 25\u219212 lines (16 removed)", + "fix": "Rewrote 25→12 lines (16 removed)", "tags": [ "auto-detected", "refactor", @@ -3740,7 +3740,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/config_repl.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 31\u219237 lines (2 removed)", + "fix": "Rewrote 31→37 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -3788,7 +3788,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.h", "root_cause": "21 lines replaced/restructured", - "fix": "Rewrote 28\u21925 lines (21 removed)", + "fix": "Rewrote 28→5 lines (21 removed)", "tags": [ "auto-detected", "refactor", @@ -3852,7 +3852,7 @@ "error_message": "Wrong reference: test_ha_connect should be test_ha_ctrlhello", "file": "src/controller/testsuite/controller_test.c", "root_cause": "Used \"test_ha_connect\" instead of \"test_ha_ctrlhello\"", - "fix": "Changed test_ha_connect \u2192 test_ha_ctrlhello", + "fix": "Changed test_ha_connect → test_ha_ctrlhello", "tags": [ "auto-detected", "wrong-reference", @@ -3868,7 +3868,7 @@ "error_message": "Wrong reference: vcpu should be vcpus", "file": "src/tools/deploy-ha.sh", "root_cause": "Used \"vcpu\" instead of \"vcpus\"", - "fix": "Changed vcpu \u2192 vcpus", + "fix": "Changed vcpu → vcpus", "tags": [ "auto-detected", "wrong-reference", @@ -3884,7 +3884,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/cluster.c", "root_cause": "10 lines replaced/restructured", - "fix": "Rewrote 10\u21926 lines (10 removed)", + "fix": "Rewrote 10→6 lines (10 removed)", "tags": [ "auto-detected", "refactor", @@ -3900,7 +3900,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 7\u219222 lines (2 removed)", + "fix": "Rewrote 7→22 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -3916,7 +3916,7 @@ "error_message": "Significant refactor of ", "file": "src/include/typemap.h", "root_cause": "3 lines replaced/restructured", - "fix": "Rewrote 5\u219210 lines (3 removed)", + "fix": "Rewrote 5→10 lines (3 removed)", "tags": [ "auto-detected", "refactor", @@ -3932,7 +3932,7 @@ "error_message": "Significant refactor of ", "file": "src/lib/request.c", "root_cause": "32 lines replaced/restructured", - "fix": "Rewrote 49\u219260 lines (32 removed)", + "fix": "Rewrote 49→60 lines (32 removed)", "tags": [ "auto-detected", "refactor", @@ -3948,7 +3948,7 @@ "error_message": "Significant refactor of ", "file": ".claude/skills/xce-deploy-ha/SKILL.md", "root_cause": "7 lines replaced/restructured", - "fix": "Rewrote 17\u219232 lines (7 removed)", + "fix": "Rewrote 17→32 lines (7 removed)", "tags": [ "auto-detected", "refactor", @@ -3964,7 +3964,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/CLAUDE.md", "root_cause": "3 lines replaced/restructured", - "fix": "Rewrote 6\u21929 lines (3 removed)", + "fix": "Rewrote 6→9 lines (3 removed)", "tags": [ "auto-detected", "refactor", @@ -3979,7 +3979,7 @@ "timestamp": "2026-06-01T07:28:15.703Z", "error_message": "Missing error handling in unknown", "file": "src/controller/testsuite/test_ha_connection_reuse.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -4012,7 +4012,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/testsuite/test_ha_connection_reuse.c", "root_cause": "19 lines replaced/restructured", - "fix": "Rewrote 67\u219286 lines (19 removed)", + "fix": "Rewrote 67→86 lines (19 removed)", "tags": [ "auto-detected", "refactor", @@ -4044,7 +4044,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/ha-heartbeat-liveness/requirements.md", "root_cause": "5 lines replaced/restructured", - "fix": "Rewrote 10\u219217 lines (5 removed)", + "fix": "Rewrote 10→17 lines (5 removed)", "tags": [ "auto-detected", "refactor", @@ -4060,7 +4060,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 6\u219210 lines (2 removed)", + "fix": "Rewrote 6→10 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -4092,7 +4092,7 @@ "error_message": "Wrong reference: startup_validation should be testsuite_test_ha_liveness", "file": "src/xce.build/build.ninja", "root_cause": "Used \"startup_validation\" instead of \"testsuite_test_ha_liveness\"", - "fix": "Changed startup_validation \u2192 testsuite_test_ha_liveness", + "fix": "Changed startup_validation → testsuite_test_ha_liveness", "tags": [ "auto-detected", "wrong-reference", @@ -4108,7 +4108,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "76 lines replaced/restructured", - "fix": "Rewrote 112\u2192155 lines (76 removed)", + "fix": "Rewrote 112→155 lines (76 removed)", "tags": [ "auto-detected", "refactor", @@ -4124,7 +4124,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/testsuite/test_ha_liveness.c", "root_cause": "5 lines replaced/restructured", - "fix": "Rewrote 21\u219224 lines (5 removed)", + "fix": "Rewrote 21→24 lines (5 removed)", "tags": [ "auto-detected", "refactor", @@ -4140,7 +4140,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/testsuite/test_ha_failover.c", "root_cause": "7 lines replaced/restructured", - "fix": "Rewrote 29\u219247 lines (7 removed)", + "fix": "Rewrote 29→47 lines (7 removed)", "tags": [ "auto-detected", "refactor", @@ -4172,7 +4172,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "22 lines replaced/restructured", - "fix": "Rewrote 53\u219221 lines (22 removed)", + "fix": "Rewrote 53→21 lines (22 removed)", "tags": [ "auto-detected", "refactor", @@ -4188,7 +4188,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/cluster.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 8\u219210 lines (2 removed)", + "fix": "Rewrote 8→10 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -4219,7 +4219,7 @@ "timestamp": "2026-06-03T05:20:44.299Z", "error_message": "Missing error handling in lives", "file": ".kiro/specs/ha-config-bootstrap/research.md", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -4268,7 +4268,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.h", "root_cause": "11 lines replaced/restructured", - "fix": "Rewrote 14\u21923 lines (11 removed)", + "fix": "Rewrote 14→3 lines (11 removed)", "tags": [ "auto-detected", "refactor", @@ -4284,7 +4284,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/testsuite/test_ha_role.c", "root_cause": "79 lines replaced/restructured", - "fix": "Rewrote 87\u21923 lines (79 removed)", + "fix": "Rewrote 87→3 lines (79 removed)", "tags": [ "auto-detected", "refactor", @@ -4300,7 +4300,7 @@ "error_message": "Wrong reference: test_am_i_primary should be test_ha_cluster", "file": "src/controller/testsuite/controller_test.c", "root_cause": "Used \"test_am_i_primary\" instead of \"test_ha_cluster\"", - "fix": "Changed test_am_i_primary \u2192 test_ha_cluster", + "fix": "Changed test_am_i_primary → test_ha_cluster", "tags": [ "auto-detected", "wrong-reference", @@ -4316,7 +4316,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.h", "root_cause": "8 lines replaced/restructured", - "fix": "Rewrote 10\u21923 lines (8 removed)", + "fix": "Rewrote 10→3 lines (8 removed)", "tags": [ "auto-detected", "refactor", @@ -4332,7 +4332,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "21 lines replaced/restructured", - "fix": "Rewrote 26\u21924 lines (21 removed) | Also: /* ha_check_heartbeat_nocluster() removed from the; * ha_watchdog_thread(). XCE_TESTING shim preserve", + "fix": "Rewrote 26→4 lines (21 removed) | Also: /* ha_check_heartbeat_nocluster() removed from the; * ha_watchdog_thread(). XCE_TESTING shim preserve", "tags": [ "auto-detected", "refactor", @@ -4348,7 +4348,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/testsuite/test_ha_role.c", "root_cause": "63 lines replaced/restructured", - "fix": "Rewrote 68\u21924 lines (63 removed) | Also: /* SIGUSR1 must set failover_requested via async-s; static void test_sigusr1_sets_failover_requested(v | Also: RUN_TEST(test_watchdog_starts_and_stops);; RUN_TEST(test_heartbeat_no_action_when_no_primary)", + "fix": "Rewrote 68→4 lines (63 removed) | Also: /* SIGUSR1 must set failover_requested via async-s; static void test_sigusr1_sets_failover_requested(v | Also: RUN_TEST(test_watchdog_starts_and_stops);; RUN_TEST(test_heartbeat_no_action_when_no_primary)", "tags": [ "auto-detected", "refactor", @@ -4364,7 +4364,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/ha-config-bootstrap/manual-tests.md", "root_cause": "6 lines replaced/restructured", - "fix": "Rewrote 8\u21928 lines (6 removed) | Also: **Expected within 1 second on both standbys:**; **Expected on the winner (needs 1 vote from the ot | Also: defer_config_fetch=1; Config fetch successful from primary (tag=...) | Also: Date:; Commit: (run: cd /home/rshen/projects/xce/worktree", + "fix": "Rewrote 8→8 lines (6 removed) | Also: **Expected within 1 second on both standbys:**; **Expected on the winner (needs 1 vote from the ot | Also: defer_config_fetch=1; Config fetch successful from primary (tag=...) | Also: Date:; Commit: (run: cd /home/rshen/projects/xce/worktree", "tags": [ "auto-detected", "refactor", @@ -4380,7 +4380,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/ha-config-bootstrap/manual-tests.md", "root_cause": "95 lines replaced/restructured", - "fix": "Rewrote 158\u219265 lines (95 removed) | Also: - [ ] `ha-term.bin` file exists after election; - [ ] Magic bytes are `0xDEADBEEFCAFEBABE` (little", + "fix": "Rewrote 158→65 lines (95 removed) | Also: - [ ] `ha-term.bin` file exists after election; - [ ] Magic bytes are `0xDEADBEEFCAFEBABE` (little", "tags": [ "auto-detected", "refactor", @@ -4396,7 +4396,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "6 lines replaced/restructured", - "fix": "Rewrote 45\u219262 lines (6 removed)", + "fix": "Rewrote 45→62 lines (6 removed)", "tags": [ "auto-detected", "refactor", @@ -4411,7 +4411,7 @@ "timestamp": "2026-06-04T00:24:46.380Z", "error_message": "Missing error handling in unknown", "file": "src/controller/myapp.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -4428,7 +4428,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/CLAUDE.md", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 5\u21927 lines (4 removed)", + "fix": "Rewrote 5→7 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -4443,7 +4443,7 @@ "timestamp": "2026-06-04T09:46:14.610Z", "error_message": "Missing error handling in unknown", "file": ".kiro/specs/ha-repl-hardening/design.md", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -4476,7 +4476,7 @@ "error_message": "Significant refactor of ", "file": "src/schema/controller.capnp", "root_cause": "3 lines replaced/restructured", - "fix": "Rewrote 4\u21924 lines (3 removed)", + "fix": "Rewrote 4→4 lines (3 removed)", "tags": [ "auto-detected", "refactor", @@ -4492,7 +4492,7 @@ "error_message": "Significant refactor of ", "file": "src/include/typemap.h", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 5\u21927 lines (4 removed)", + "fix": "Rewrote 5→7 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -4508,7 +4508,7 @@ "error_message": "Significant refactor of ", "file": "src/schema/controller.capnp", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 4\u219213 lines (2 removed)", + "fix": "Rewrote 4→13 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -4524,7 +4524,7 @@ "error_message": "Significant refactor of ", "file": "src/include/typemap.h", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 4\u21928 lines (2 removed)", + "fix": "Rewrote 4→8 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -4539,8 +4539,8 @@ "timestamp": "2026-06-04T14:33:03.464Z", "error_message": "Missing error handling in XCE_TESTING", "file": "src/controller/testsuite/test_config_repl.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", - "fix": "Added try/catch block | Also: /* \u2500\u2500 Task 2.1: OPCode_walCatchupEntry handler \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500; #ifdef XCE_TESTING | Also: /* Task 2.1: OPCode_walCatchupEntry handler */; RUN_TEST(test_wal_catchup_entry_advances_applied_lsn);", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", + "fix": "Added try/catch block | Also: /* ── Task 2.1: OPCode_walCatchupEntry handler ─────────────; #ifdef XCE_TESTING | Also: /* Task 2.1: OPCode_walCatchupEntry handler */; RUN_TEST(test_wal_catchup_entry_advances_applied_lsn);", "tags": [ "auto-detected", "error-handling", @@ -4555,7 +4555,7 @@ "timestamp": "2026-06-04T14:41:35.073Z", "error_message": "Missing error handling in XCE_TESTING", "file": "src/controller/cluster.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block | Also: case OPCode_walCatchupEntry:; /* Task 2.1: standby applies a single WAL catch-up entry fro", "tags": [ "auto-detected", @@ -4572,7 +4572,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/cluster.c", "root_cause": "57 lines replaced/restructured", - "fix": "Rewrote 82\u219216 lines (57 removed)", + "fix": "Rewrote 82→16 lines (57 removed)", "tags": [ "auto-detected", "refactor", @@ -4587,7 +4587,7 @@ "timestamp": "2026-06-04T14:45:42.730Z", "error_message": "Missing error handling in unknown", "file": "src/controller/ha.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -4603,7 +4603,7 @@ "timestamp": "2026-06-04T14:46:44.652Z", "error_message": "Missing error handling in unknown", "file": "src/controller/ha.h", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block | Also: #include \"persist.h\" /* persist_t, apply_wal_entry */; #include \"typemap.h\" /* wal_catchup_entry_t */", "tags": [ "auto-detected", @@ -4619,7 +4619,7 @@ "timestamp": "2026-06-04T15:09:54.280Z", "error_message": "Missing error handling in unknown", "file": "src/controller/testsuite/test_config_repl.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -4636,7 +4636,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "22 lines replaced/restructured", - "fix": "Rewrote 58\u2192114 lines (22 removed)", + "fix": "Rewrote 58→114 lines (22 removed)", "tags": [ "auto-detected", "refactor", @@ -4652,7 +4652,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/cluster.c", "root_cause": "3 lines replaced/restructured", - "fix": "Rewrote 10\u219215 lines (3 removed)", + "fix": "Rewrote 10→15 lines (3 removed)", "tags": [ "auto-detected", "refactor", @@ -4684,7 +4684,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 44\u219289 lines (4 removed) | Also: /* Decode stateReport and call convergence tracker; memset(&sr, 0, sizeof(sr));", + "fix": "Rewrote 44→89 lines (4 removed) | Also: /* Decode stateReport and call convergence tracker; memset(&sr, 0, sizeof(sr));", "tags": [ "auto-detected", "refactor", @@ -4732,7 +4732,7 @@ "error_message": "Wrong reference: test_evaluate_repl_action_stream_wal_from_zero should be test_evaluate_repl_action_send_snapshot_lsn_zero", "file": "src/controller/testsuite/test_ha_role.c", "root_cause": "Used \"test_evaluate_repl_action_stream_wal_from_zero\" instead of \"test_evaluate_repl_action_send_snapshot_lsn_zero\"", - "fix": "Changed test_evaluate_repl_action_stream_wal_from_zero \u2192 test_evaluate_repl_action_send_snapshot_lsn_zero", + "fix": "Changed test_evaluate_repl_action_stream_wal_from_zero → test_evaluate_repl_action_send_snapshot_lsn_zero", "tags": [ "auto-detected", "wrong-reference", @@ -4763,7 +4763,7 @@ "timestamp": "2026-06-04T17:34:23.150Z", "error_message": "Missing error handling in XCE_TESTING", "file": "src/controller/testsuite/test_config_repl.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -4780,7 +4780,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 71\u219293 lines (4 removed)", + "fix": "Rewrote 71→93 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -4795,7 +4795,7 @@ "timestamp": "2026-06-04T17:40:05.798Z", "error_message": "Missing error handling in XCE_TESTING", "file": "src/controller/config_repl.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -4844,7 +4844,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 6\u219215 lines (2 removed)", + "fix": "Rewrote 6→15 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -4859,7 +4859,7 @@ "timestamp": "2026-06-04T23:21:45.737Z", "error_message": "Missing error handling in XCE_TESTING", "file": "src/controller/config_repl.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -4876,7 +4876,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/testsuite/test_config_repl.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 9\u219212 lines (2 removed)", + "fix": "Rewrote 9→12 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -4892,7 +4892,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/ha-repl-hardening/tasks.md", "root_cause": "9 lines replaced/restructured", - "fix": "Rewrote 9\u219235 lines (9 removed)", + "fix": "Rewrote 9→35 lines (9 removed)", "tags": [ "auto-detected", "refactor", @@ -4908,7 +4908,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 7\u219210 lines (4 removed) | Also: /* Task 3.5: snapshot transfer.; * Creates a checkpoint in the delaymgr thread (not", + "fix": "Rewrote 7→10 lines (4 removed) | Also: /* Task 3.5: snapshot transfer.; * Creates a checkpoint in the delaymgr thread (not", "tags": [ "auto-detected", "refactor", @@ -4988,7 +4988,7 @@ "error_message": "Wrong reference: uintptr_t should be void", "file": "src/controller/testsuite/test_ha_evaluate_committing.c", "root_cause": "Used \"uintptr_t\" instead of \"void\"", - "fix": "Changed uintptr_t \u2192 void", + "fix": "Changed uintptr_t → void", "tags": [ "auto-detected", "wrong-reference", @@ -5004,7 +5004,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/config_repl.c", "root_cause": "149 lines replaced/restructured", - "fix": "Rewrote 207\u219238 lines (149 removed)", + "fix": "Rewrote 207→38 lines (149 removed)", "tags": [ "auto-detected", "refactor", @@ -5036,7 +5036,7 @@ "error_message": "Wrong reference: 10000 should be 60000", "file": "src/controller/ha.h", "root_cause": "Used \"10000\" instead of \"60000\"", - "fix": "Changed 10000 \u2192 60000", + "fix": "Changed 10000 → 60000", "tags": [ "auto-detected", "wrong-reference", @@ -5052,7 +5052,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "5 lines replaced/restructured", - "fix": "Rewrote 24\u219242 lines (5 removed)", + "fix": "Rewrote 24→42 lines (5 removed)", "tags": [ "auto-detected", "refactor", @@ -5068,7 +5068,7 @@ "error_message": "Wrong reference: 10000 should be HA_DEFAULT_COMMITTING_TIMEOUT_MS", "file": "src/controller/testsuite/test_ha_evaluate_committing.c", "root_cause": "Used \"10000\" instead of \"HA_DEFAULT_COMMITTING_TIMEOUT_MS\"", - "fix": "Changed 10000 \u2192 HA_DEFAULT_COMMITTING_TIMEOUT_MS", + "fix": "Changed 10000 → HA_DEFAULT_COMMITTING_TIMEOUT_MS", "tags": [ "auto-detected", "wrong-reference", @@ -5083,7 +5083,7 @@ "timestamp": "2026-06-05T05:10:13.646Z", "error_message": "Missing error handling in unknown", "file": "src/controller/config_repl.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -5099,7 +5099,7 @@ "timestamp": "2026-06-05T05:39:48.707Z", "error_message": "Missing error handling in unknown", "file": "src/controller/testsuite/test_config_repl.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -5115,7 +5115,7 @@ "timestamp": "2026-06-05T06:50:00Z", "error_message": "3-node startup: majority convergence never fires; cluster falls through to committing_timeout degraded-mode WARN", "file": "src/controller/ha.c", - "root_cause": "ha->n_peers was set to candidates_count (3, total including self) in ha_start_election_async. ha_check_majority_convergence loops i=0..n_peers-1 checking standby_converged[], but standby_converged[] is indexed by votes_idx (relative, self excluded: 0..n_other-1). With n_peers=3, it checked standby_converged[2] which is never set, so n_converged (2) < n_peers (3) always \u2014 majority convergence path could never succeed.", + "root_cause": "ha->n_peers was set to candidates_count (3, total including self) in ha_start_election_async. ha_check_majority_convergence loops i=0..n_peers-1 checking standby_converged[], but standby_converged[] is indexed by votes_idx (relative, self excluded: 0..n_other-1). With n_peers=3, it checked standby_converged[2] which is never set, so n_converged (2) < n_peers (3) always — majority convergence path could never succeed.", "fix": "Changed ha->n_peers = n_peers to ha->n_peers = n_other (= n_peers-1 = other-node count). Moved the assignment after n_other is computed. ha_repl_ack_received quorum formula (ha->n_peers+2)/2 still yields correct majority for both old and new value.", "tags": [ "ha", @@ -5134,7 +5134,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 7\u219212 lines (2 removed) | Also: /* Disarm any existing poll ctx */; free(old);", + "fix": "Rewrote 7→12 lines (2 removed) | Also: /* Disarm any existing poll ctx */; free(old);", "tags": [ "auto-detected", "refactor", @@ -5149,7 +5149,7 @@ "timestamp": "2026-06-05T07:23:00.000Z", "error_message": "AddressSanitizer: attempting double-free on sctx in ha_connect_to_peer", "file": "src/controller/ha.c", - "root_cause": "endpoint_fini calls FREEUP(ep->data) which frees sctx, then ha_connect_to_peer also calls free(sctx) \u2014 double-free at lines 3594-3595 and 3600-3601", + "root_cause": "endpoint_fini calls FREEUP(ep->data) which frees sctx, then ha_connect_to_peer also calls free(sctx) — double-free at lines 3594-3595 and 3600-3601", "fix": "Set ep->data = NULL before endpoint_fini so FREEUP becomes a no-op; then free(sctx) explicitly in the error paths", "tags": [ "double-free", @@ -5165,7 +5165,7 @@ { "id": "bug-007", "timestamp": "2026-06-05T07:23:00.000Z", - "error_message": "AddressSanitizer: heap-use-after-free in liveness_poll_fn at ha.c:3293 \u2014 reading ctx->cancelled after ha_arm_heartbeat_timeout_vtask freed the old ctx", + "error_message": "AddressSanitizer: heap-use-after-free in liveness_poll_fn at ha.c:3293 — reading ctx->cancelled after ha_arm_heartbeat_timeout_vtask freed the old ctx", "file": "src/controller/ha.c", "root_cause": "ha_arm_heartbeat_timeout_vtask freed the old liveness_poll_ctx_t immediately after setting cancelled=1, but the delaymgr task was already in flight reading ctx->cancelled=0 and then continued to read ctx->ha after free", "fix": "ha_arm_heartbeat_timeout_vtask no longer frees old ctx; liveness_poll_fn now frees ctx when it fires with cancelled=1 (guarded by #ifndef XCE_TESTING to avoid bad-free on stack-allocated test ctxs)", @@ -5187,7 +5187,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 41\u219287 lines (2 removed)", + "fix": "Rewrote 41→87 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -5203,7 +5203,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "6 lines replaced/restructured", - "fix": "Rewrote 8\u21925 lines (6 removed)", + "fix": "Rewrote 8→5 lines (6 removed)", "tags": [ "auto-detected", "refactor", @@ -5219,7 +5219,7 @@ "error_message": "Wrong reference: DEBUG2 should be INFO", "file": "src/controller/ha.c", "root_cause": "Used \"DEBUG2\" instead of \"INFO\"", - "fix": "Changed DEBUG2 \u2192 INFO", + "fix": "Changed DEBUG2 → INFO", "tags": [ "auto-detected", "wrong-reference", @@ -5283,7 +5283,7 @@ "error_message": "Significant refactor of ", "file": "src/docs/cluster-config-split-analysis.md", "root_cause": "8 lines replaced/restructured", - "fix": "Rewrote 11\u219221 lines (8 removed) | Also: ### Phase 1: Schema split (wire-compatible); 4. **Keep the old `ClusterConfig` fields intact** ", + "fix": "Rewrote 11→21 lines (8 removed) | Also: ### Phase 1: Schema split (wire-compatible); 4. **Keep the old `ClusterConfig` fields intact** ", "tags": [ "auto-detected", "refactor", @@ -5299,7 +5299,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/myapp.c", "root_cause": "5 lines replaced/restructured", - "fix": "Rewrote 27\u219236 lines (5 removed)", + "fix": "Rewrote 27→36 lines (5 removed)", "tags": [ "auto-detected", "refactor", @@ -5315,7 +5315,7 @@ "error_message": "Significant refactor of ", "file": "src/lib/raft/raft.c", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 9\u219215 lines (4 removed)", + "fix": "Rewrote 9→15 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -5331,7 +5331,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "37 lines replaced/restructured", - "fix": "Rewrote 41\u21924 lines (37 removed)", + "fix": "Rewrote 41→4 lines (37 removed)", "tags": [ "auto-detected", "refactor", @@ -5471,7 +5471,7 @@ "error_message": "Wrong reference: last_heartbeat should be voted_for_term", "file": "src/controller/ha.h", "root_cause": "Used \"last_heartbeat\" instead of \"voted_for_term\"", - "fix": "Changed last_heartbeat \u2192 voted_for_term", + "fix": "Changed last_heartbeat → voted_for_term", "tags": [ "auto-detected", "wrong-reference", @@ -5487,7 +5487,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/myapp.c", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 13\u219217 lines (4 removed)", + "fix": "Rewrote 13→17 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -5538,7 +5538,7 @@ "timestamp": "2026-06-10T01:36:59.112Z", "error_message": "Missing error handling in unknown", "file": "src/schema/controller.capnp", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -5554,7 +5554,7 @@ "timestamp": "2026-06-10T01:37:29.771Z", "error_message": "Missing error handling in struct", "file": "src/include/typemap.h", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -5571,7 +5571,7 @@ "error_message": "Significant refactor of ", "file": "src/include/typemap.h", "root_cause": "6 lines replaced/restructured", - "fix": "Rewrote 16\u219231 lines (6 removed)", + "fix": "Rewrote 16→31 lines (6 removed)", "tags": [ "auto-detected", "refactor", @@ -5586,7 +5586,7 @@ "timestamp": "2026-06-10T01:38:31.262Z", "error_message": "Missing error handling in unknown", "file": "src/include/request.h", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -5618,7 +5618,7 @@ "timestamp": "2026-06-10T01:39:31.683Z", "error_message": "Missing error handling in unknown", "file": "src/lib/request.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block | Also: if (req->body_which == Request_body_walcatchupentrymsg; && req->body.walcatchupentrymsg != NULL) { | Also: /* wal_entry_to_wire: fill a wire WalCatchupEntry from a C e; * fields and raw payload bytes. Sub-entry nesting is one le", "tags": [ "auto-detected", @@ -5653,7 +5653,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/config_repl.c", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 29\u219232 lines (4 removed)", + "fix": "Rewrote 29→32 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -5669,7 +5669,7 @@ "error_message": "Wrong reference: payload should be raw_payload", "file": "src/controller/config_repl.c", "root_cause": "Used \"payload\" instead of \"raw_payload\"", - "fix": "Changed payload \u2192 raw_payload", + "fix": "Changed payload → raw_payload", "tags": [ "auto-detected", "wrong-reference", @@ -5685,7 +5685,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 13\u219216 lines (2 removed)", + "fix": "Rewrote 13→16 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -5701,7 +5701,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/testsuite/test_ha_role.c", "root_cause": "7 lines replaced/restructured", - "fix": "Rewrote 49\u2192137 lines (7 removed)", + "fix": "Rewrote 49→137 lines (7 removed)", "tags": [ "auto-detected", "refactor", @@ -5716,7 +5716,7 @@ "timestamp": "2026-06-10T01:49:36.997Z", "error_message": "Missing error handling in unknown", "file": "src/controller/ha.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -5785,7 +5785,7 @@ "error_message": "Significant refactor of ", "file": "src/scheduler/src/scheduler.c", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 4\u21926 lines (4 removed)", + "fix": "Rewrote 4→6 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -5838,7 +5838,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.c", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 9\u219215 lines (4 removed)", + "fix": "Rewrote 9→15 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -5870,7 +5870,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/cluster.c", "root_cause": "3 lines replaced/restructured", - "fix": "Rewrote 8\u219213 lines (3 removed) | Also: /* Req 4.1: ctrlhello counts as primary activity \u2014; if ((ctrl_role_t)atomic_load_explicit(&c->ha.role,", + "fix": "Rewrote 8→13 lines (3 removed) | Also: /* Req 4.1: ctrlhello counts as primary activity —; if ((ctrl_role_t)atomic_load_explicit(&c->ha.role,", "tags": [ "auto-detected", "refactor", @@ -5886,7 +5886,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/config_repl.c", "root_cause": "3 lines replaced/restructured", - "fix": "Rewrote 6\u219212 lines (3 removed)", + "fix": "Rewrote 6→12 lines (3 removed)", "tags": [ "auto-detected", "refactor", @@ -5901,7 +5901,7 @@ "timestamp": "2026-06-10T07:56:21.347Z", "error_message": "Missing error handling in XCE_TESTING", "file": "src/controller/testsuite/test_repl_unit.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block | Also: /* =========================================================; * Task 1.1: repl_broadcast send path tests", "tags": [ "auto-detected", @@ -5918,7 +5918,7 @@ "error_message": "Wrong reference: WAL_JOB should be WAL_JOB_SUBMIT", "file": "src/controller/testsuite/test_repl_unit.c", "root_cause": "Used \"WAL_JOB\" instead of \"WAL_JOB_SUBMIT\"", - "fix": "Changed WAL_JOB \u2192 WAL_JOB_SUBMIT", + "fix": "Changed WAL_JOB → WAL_JOB_SUBMIT", "tags": [ "auto-detected", "wrong-reference", @@ -5933,7 +5933,7 @@ "timestamp": "2026-06-10T07:58:15.167Z", "error_message": "Missing error handling in XCE_TESTING", "file": "src/controller/repl.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -5950,7 +5950,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/repl.c", "root_cause": "3 lines replaced/restructured", - "fix": "Rewrote 42\u219265 lines (3 removed)", + "fix": "Rewrote 42→65 lines (3 removed)", "tags": [ "auto-detected", "refactor", @@ -5966,7 +5966,7 @@ "error_message": "Wrong reference: DEBUG3 should be TRACE", "file": "src/controller/repl.c", "root_cause": "Used \"DEBUG3\" instead of \"TRACE\"", - "fix": "Changed DEBUG3 \u2192 TRACE", + "fix": "Changed DEBUG3 → TRACE", "tags": [ "auto-detected", "wrong-reference", @@ -5982,7 +5982,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/ha.h", "root_cause": "3 lines replaced/restructured", - "fix": "Rewrote 12\u219216 lines (3 removed)", + "fix": "Rewrote 12→16 lines (3 removed)", "tags": [ "auto-detected", "refactor", @@ -5998,7 +5998,7 @@ "error_message": "Wrong reference: request should be ep", "file": "src/controller/cluster.c", "root_cause": "Used \"request\" instead of \"ep\"", - "fix": "Changed request \u2192 ep", + "fix": "Changed request → ep", "tags": [ "auto-detected", "wrong-reference", @@ -6013,7 +6013,7 @@ "timestamp": "2026-06-10T08:47:48.296Z", "error_message": "Missing error handling in unknown", "file": "src/controller/testsuite/test_ha_role.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block | Also: /* Task 3.3 (ha-wal-replication): dispatch gate standby-role; RUN_TEST(test_dispatch_gate_allows_wal_catchup_in_standby_ro", "tags": [ "auto-detected", @@ -6029,7 +6029,7 @@ "timestamp": "2026-06-10T08:50:27.397Z", "error_message": "Missing error handling in struct", "file": "src/include/typemap.h", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -6061,7 +6061,7 @@ "timestamp": "2026-06-10T09:59:08.979Z", "error_message": "Missing error handling in XCE_TESTING", "file": "src/controller/testsuite/test_p2_integration.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -6096,7 +6096,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/testsuite/test_p2_integration.c", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 50\u219272 lines (4 removed)", + "fix": "Rewrote 50→72 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -6112,7 +6112,7 @@ "error_message": "Wrong reference: test_catchup_full_lifecycle_integration should be test_single_node_committed_lsn_unchanged", "file": "src/controller/testsuite/test_p2_integration.c", "root_cause": "Used \"test_catchup_full_lifecycle_integration\" instead of \"test_single_node_committed_lsn_unchanged\"", - "fix": "Changed test_catchup_full_lifecycle_integration \u2192 test_single_node_committed_lsn_unchanged", + "fix": "Changed test_catchup_full_lifecycle_integration → test_single_node_committed_lsn_unchanged", "tags": [ "auto-detected", "wrong-reference", @@ -6127,7 +6127,7 @@ "timestamp": "2026-06-10T10:37:49.028Z", "error_message": "Missing error handling in unknown", "file": "src/controller/testsuite/test_repl_unit.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -6160,7 +6160,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/steering/product.md", "root_cause": "5 lines replaced/restructured", - "fix": "Rewrote 13\u219222 lines (5 removed)", + "fix": "Rewrote 13→22 lines (5 removed)", "tags": [ "auto-detected", "refactor", @@ -6192,7 +6192,7 @@ "error_message": "Significant refactor of ", "file": "CLAUDE.md", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 5\u21925 lines (4 removed)", + "fix": "Rewrote 5→5 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -6224,7 +6224,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/CLAUDE.md", "root_cause": "3 lines replaced/restructured", - "fix": "Rewrote 6\u21925 lines (3 removed) | Also: ### Controllers; - Struct: `type {Resource}Controller struct{}`", + "fix": "Rewrote 6→5 lines (3 removed) | Also: ### Controllers; - Struct: `type {Resource}Controller struct{}`", "tags": [ "auto-detected", "refactor", @@ -6256,7 +6256,7 @@ "error_message": "Wrong reference: signal should be stdio", "file": "src/lib/delay.c", "root_cause": "Used \"signal\" instead of \"stdio\"", - "fix": "Changed signal \u2192 stdio", + "fix": "Changed signal → stdio", "tags": [ "auto-detected", "wrong-reference", @@ -6271,7 +6271,7 @@ "timestamp": "2026-06-11T03:30:54.341Z", "error_message": "Missing error handling in XCE_TESTING", "file": "src/controller/ha.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -6320,7 +6320,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/job.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 15\u219228 lines (2 removed)", + "fix": "Rewrote 15→28 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -6352,7 +6352,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/ha-consistency-invariants/research.md", "root_cause": "3 lines replaced/restructured", - "fix": "Rewrote 7\u21927 lines (3 removed)", + "fix": "Rewrote 7→7 lines (3 removed)", "tags": [ "auto-detected", "refactor", @@ -6387,7 +6387,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/specs/ha-consistency-invariants/requirements.md", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 3\u21924 lines (2 removed)", + "fix": "Rewrote 3→4 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -6466,7 +6466,7 @@ "timestamp": "2026-06-11T07:53:43.868Z", "error_message": "Missing error handling in unknown", "file": ".kiro/specs/ha-consistency-invariants/research.md", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -6498,7 +6498,7 @@ "timestamp": "2026-06-11T08:46:20.815Z", "error_message": "Missing error handling in unknown", "file": ".kiro/steering/roadmap.md", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -6579,7 +6579,7 @@ "error_message": "Significant refactor of ", "file": ".kiro/steering/roadmap.md", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 6\u21928 lines (4 removed)", + "fix": "Rewrote 6→8 lines (4 removed)", "tags": [ "auto-detected", "refactor", @@ -6594,7 +6594,7 @@ "timestamp": "2026-06-11T13:30:00Z", "error_message": "test_commit_engine fixture: Expected 0 Was 1 from repl_add_standby", "file": "src/controller/testsuite/test_commit_engine.c", - "root_cause": "repl_add_standby returns the slot index (>=0) on success, not 0 \u2014 second add legitimately returns 1", + "root_cause": "repl_add_standby returns the slot index (>=0) on success, not 0 — second add legitimately returns 1", "fix": "fixture asserts TEST_ASSERT_EQUAL_INT(i, repl_add_standby(...)) per standby slot", "tags": [ "controller", @@ -6611,8 +6611,8 @@ "timestamp": "2026-06-11T13:35:00Z", "error_message": "3 pre-existing controller testsuite failures masked by exit code 0: test_committed_lsn_does_not_advance_on_timeout (-110), test_repl_ack_after_promote_gate_allows_jobsub (-10013), test_rdhup_primary_dispatch_gate_opens (-10013)", "file": "src/controller/testsuite/controller_test.c", - "root_cause": "each test group calls UNITY_BEGIN/UNITY_END internally, resetting Unity counters \u2014 main()'s final UNITY_END returns 0 unless the LAST group fails, so meson reported the suite green despite 3 real failures; Unity also misattributes failure FILE names to whichever file's UNITY_BEGIN ran (e.g. reports test_repl_unit.c for a test living in test_p2_integration.c)", - "fix": "not fixed (out of task 1.1 boundary) \u2014 documented; failures exist identically on baseline without ha-commit-engine changes (verified by stash/rebuild). persist_wal_sync_append returns -ETIMEDOUT while the test expects rc==0 with sync_rc==-ETIMEDOUT; the two gate tests fail ha_has_write_quorum (standby_endpoints empty with n_peers=2)", + "root_cause": "each test group calls UNITY_BEGIN/UNITY_END internally, resetting Unity counters — main()'s final UNITY_END returns 0 unless the LAST group fails, so meson reported the suite green despite 3 real failures; Unity also misattributes failure FILE names to whichever file's UNITY_BEGIN ran (e.g. reports test_repl_unit.c for a test living in test_p2_integration.c)", + "fix": "not fixed (out of task 1.1 boundary) — documented; failures exist identically on baseline without ha-commit-engine changes (verified by stash/rebuild). persist_wal_sync_append returns -ETIMEDOUT while the test expects rc==0 with sync_rc==-ETIMEDOUT; the two gate tests fail ha_has_write_quorum (standby_endpoints empty with n_peers=2)", "tags": [ "controller", "testsuite", @@ -6631,7 +6631,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/commit.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 11\u219221 lines (2 removed) | Also: (void)timeout_ms; /* RETAIN never honors the timeo; * via commit_on_ack (Req 2.1). */", + "fix": "Rewrote 11→21 lines (2 removed) | Also: (void)timeout_ms; /* RETAIN never honors the timeo; * via commit_on_ack (Req 2.1). */", "tags": [ "auto-detected", "refactor", @@ -6646,8 +6646,8 @@ "timestamp": "2026-06-11T15:28:35.990Z", "error_message": "Missing error handling in unknown", "file": "src/controller/testsuite/test_commit_engine.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", - "fix": "Added try/catch block | Also: /* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550; * Task 3.1 \u2014 membership re-evaluation (commit_on_membership_ | Also: /* Task 3.1 \u2014 membership re-evaluation */; RUN_TEST(test_catchup_standby_ack_does_not_count_toward_pend", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", + "fix": "Added try/catch block | Also: /* ═════════════════════════════════════════════════════════; * Task 3.1 — membership re-evaluation (commit_on_membership_ | Also: /* Task 3.1 — membership re-evaluation */; RUN_TEST(test_catchup_standby_ack_does_not_count_toward_pend", "tags": [ "auto-detected", "error-handling", @@ -6662,7 +6662,7 @@ "timestamp": "2026-06-11T15:55:52.451Z", "error_message": "Missing error handling in unknown", "file": "src/include/repl.h", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -6678,7 +6678,7 @@ "timestamp": "2026-06-11T15:56:20.945Z", "error_message": "Missing error handling in unknown", "file": "src/controller/repl.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -6695,7 +6695,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/testsuite/test_commit_engine.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 10\u219215 lines (2 removed)", + "fix": "Rewrote 10→15 lines (2 removed)", "tags": [ "auto-detected", "refactor", @@ -6710,7 +6710,7 @@ "timestamp": "2026-06-11T15:57:43.900Z", "error_message": "Missing error handling in unknown", "file": "src/controller/testsuite/test_commit_engine.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -6726,7 +6726,7 @@ "timestamp": "2026-06-11T16:15:06.660Z", "error_message": "Missing error handling in unknown", "file": ".kiro/specs/ha-commit-engine/tasks.md", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -6742,7 +6742,7 @@ "timestamp": "2026-06-11T16:19:30.370Z", "error_message": "Missing error handling in unknown", "file": "src/controller/ha.h", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -6758,8 +6758,8 @@ "timestamp": "2026-06-11T16:19:51.195Z", "error_message": "Missing error handling in unknown", "file": "src/controller/testsuite/test_commit_engine.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", - "fix": "Added try/catch block | Also: /* Task 4.2 \u2014 wired gate: registry truth at ha_dispatch_gate; RUN_TEST(test_gate_wired_registry_catchup_standby_rejects_th", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", + "fix": "Added try/catch block | Also: /* Task 4.2 — wired gate: registry truth at ha_dispatch_gate; RUN_TEST(test_gate_wired_registry_catchup_standby_rejects_th", "tags": [ "auto-detected", "error-handling", @@ -6790,7 +6790,7 @@ "timestamp": "2026-06-11T16:23:59.453Z", "error_message": "Missing error handling in unknown", "file": "src/controller/ha.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -6806,8 +6806,8 @@ "timestamp": "2026-06-11T22:39:24.704Z", "error_message": "Missing error handling in unknown", "file": "src/controller/testsuite/test_commit_engine.c", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", - "fix": "Added try/catch block | Also: /* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550; * Task 5.1 \u2014 integration: ACK feed and the job-submit sync-a | Also: #include \"typemap.h\" /* wal_catchup_entry_t (task 5; #include \"wal_types.h\" /* WAL_JOB_SUBMIT (task 5.1 sy", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", + "fix": "Added try/catch block | Also: /* ═════════════════════════════════════════════════════════; * Task 5.1 — integration: ACK feed and the job-submit sync-a | Also: #include \"typemap.h\" /* wal_catchup_entry_t (task 5; #include \"wal_types.h\" /* WAL_JOB_SUBMIT (task 5.1 sy", "tags": [ "auto-detected", "error-handling", @@ -6855,7 +6855,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/repl.c", "root_cause": "5 lines replaced/restructured", - "fix": "Rewrote 13\u219227 lines (5 removed)", + "fix": "Rewrote 13→27 lines (5 removed)", "tags": [ "auto-detected", "refactor", @@ -6870,7 +6870,7 @@ "timestamp": "2026-06-11T23:32:42.365Z", "error_message": "Missing error handling in unknown", "file": ".kiro/specs/ha-commit-engine/tasks.md", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -6919,7 +6919,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/persist.c", "root_cause": "16 lines replaced/restructured", - "fix": "Rewrote 40\u219267 lines (16 removed)", + "fix": "Rewrote 40→67 lines (16 removed)", "tags": [ "auto-detected", "refactor", @@ -6967,7 +6967,7 @@ "error_message": "Wrong reference: test_single_node_committed_lsn_unchanged should be test_single_node_committed_lsn_advances", "file": "src/controller/testsuite/test_p2_integration.c", "root_cause": "Used \"test_single_node_committed_lsn_unchanged\" instead of \"test_single_node_committed_lsn_advances\"", - "fix": "Changed test_single_node_committed_lsn_unchanged \u2192 test_single_node_committed_lsn_advances", + "fix": "Changed test_single_node_committed_lsn_unchanged → test_single_node_committed_lsn_advances", "tags": [ "auto-detected", "wrong-reference", @@ -7068,7 +7068,7 @@ "timestamp": "2026-06-12T04:13:06.326Z", "error_message": "Missing error handling in unknown", "file": ".kiro/specs/ha-commit-barrier-rollout/tasks.md", - "root_cause": "Code path had no error handling \u2014 exceptions would propagate uncaught", + "root_cause": "Code path had no error handling — exceptions would propagate uncaught", "fix": "Added try/catch block", "tags": [ "auto-detected", @@ -7101,7 +7101,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/persist.c", "root_cause": "4 lines replaced/restructured", - "fix": "Rewrote 7\u219212 lines (4 removed) | Also: return persist_wal_async(p, wal_type, &js, sizeof(; persist_t* p = cls; | Also: int rc = persist_wal_async(p, wal_type, pkt, (uint; persist_t* p = cls;", + "fix": "Rewrote 7→12 lines (4 removed) | Also: return persist_wal_async(p, wal_type, &js, sizeof(; persist_t* p = cls; | Also: int rc = persist_wal_async(p, wal_type, pkt, (uint; persist_t* p = cls;", "tags": [ "auto-detected", "refactor", @@ -7149,7 +7149,7 @@ "error_message": "Significant refactor of ", "file": "src/controller/testsuite/test_commit_barrier_reply.c", "root_cause": "2 lines replaced/restructured", - "fix": "Rewrote 3\u21925 lines (2 removed) | Also: static xce_signal_t g_sigkill = { .signo = SIGKIL; static xce_jobctrl_t g_jobctrl;", + "fix": "Rewrote 3→5 lines (2 removed) | Also: static xce_signal_t g_sigkill = { .signo = SIGKIL; static xce_jobctrl_t g_jobctrl;", "tags": [ "auto-detected", "refactor", @@ -7250,6 +7250,46 @@ ], "occurrences": 1, "last_seen": "2026-06-12T10:30:00-07:00" + }, + { + "id": "bug-450", + "timestamp": "2026-06-12T10:48:27.053Z", + "error_message": "Significant refactor of ", + "file": "src/controller/testsuite/test_commit_barrier_reply.c", + "root_cause": "7 lines replaced/restructured", + "fix": "Rewrote 12→56 lines (7 removed) | Also: xce_job_t jdef;; static int jobobj_ready; /* jobj module tables — o", + "tags": [ + "auto-detected", + "refactor", + "c" + ], + "related_bugs": [], + "occurrences": 2, + "last_seen": "2026-06-12T10:48:47.855Z" + }, + { + "id": "bug-451", + "timestamp": "2026-06-12T11:05:00-07:00", + "error_message": "va_list type confusion: WAL_JOB_RUSAGE hook payload reads job_t fields from an xce_job_rusages_t*", + "file": "src/controller/job.c (caller) / src/controller/persist.c (consumer)", + "root_cause": "update_job_rusages fires AFTER_EVENT HOOK_DETAIL_JOB_RUSAGE_UPDATE with (cluster_t*, xce_job_rusages_t*) at job.c:1015-1016, but persist_job_hook_fun's default arm (persist.c:1354-1359) reads the second vararg as job_t* and dereferences j->job.state at offset 56 == sizeof(xce_job_rusages_t) — an out-of-bounds read on an exactly-sized allocation; the WAL_JOB_RUSAGE payload state field is garbage (jobid at offset 0 lines up by accident)", + "fix": "NOT FIXED (discovered while writing task 3.3 receipt-ACK verdict pins; production out of boundary). Test test_update_op_rusage_receipt_reply_facts_retained uses a padded union so the pin stays in-bounds under ASAN without masking the bug; fix candidates: dedicated RUSAGE arm in persist_job_hook_fun reading xce_job_rusages_t*, or fire the hook with (c, j) like the other job hooks", + "tags": [ + "pre-existing", + "type-confusion", + "va_list", + "wal", + "rusage", + "asan", + "oob-read", + "ha-commit-barrier-rollout" + ], + "related_bugs": [ + "bug-447", + "bug-448" + ], + "occurrences": 1, + "last_seen": "2026-06-12T11:05:00-07:00" } ] } \ No newline at end of file diff --git a/.wolf/memory.md b/.wolf/memory.md index 15822986..106f21ac 100644 --- a/.wolf/memory.md +++ b/.wolf/memory.md @@ -937,3 +937,14 @@ | 11:00 | Task 3.2 ha-commit-barrier-rollout: commit barrier in 4 handlers + bug-447 rc normalization in queue_ctrl/worker_ctrl/job_ctrl | src/controller/{job,queue,worker,join}.c | 12/12 barrier-reply tests PASS, full suite 0 FAIL, no sanitizer reports | ~60k | | 03:28 | Edited .kiro/specs/ha-commit-barrier-rollout/tasks.md | inline fix | ~32 | | 03:28 | Edited .kiro/specs/ha-commit-barrier-rollout/tasks.md | 1→2 lines | ~172 | +| 03:48 | Edited src/controller/testsuite/test_commit_barrier_reply.c | modified HOSTS() | ~231 | +| 03:48 | Edited src/controller/testsuite/test_commit_barrier_reply.c | added 2 condition(s) | ~685 | +| 03:48 | Edited src/controller/testsuite/test_commit_barrier_reply.c | modified cbrp_make_job() | ~213 | +| 03:49 | Edited src/controller/testsuite/test_commit_barrier_reply.c | 4→6 lines | ~64 | +| 03:50 | Edited src/controller/testsuite/test_commit_barrier_reply.c | modified reference() | ~4973 | +| 03:50 | Edited src/controller/testsuite/test_commit_barrier_reply.c | 6→11 lines | ~154 | +| 03:51 | Edited src/controller/testsuite/test_commit_barrier_reply.c | 3→4 lines | ~22 | +| 03:52 | Edited src/controller/meson.build | 12→13 lines | ~48 | +| 11:06 | Task 3.3 receipt-ACK verdict pins: 4 GREEN pins (jobdispatch no-WAL receipt ACK, set/clr_preason, do_update_op rusage RETAIN) added to test_commit_barrier_reply.c; opupd.c added to test link | src/controller/testsuite/test_commit_barrier_reply.c, src/controller/meson.build | suite green 488 distinct PASS / 0 FAIL; discovered bug-451 (rusage hook va-arg type confusion) | ~95k | +| 04:16 | Edited .kiro/specs/ha-commit-barrier-rollout/tasks.md | inline fix | ~14 | +| 04:16 | Edited .kiro/specs/ha-commit-barrier-rollout/tasks.md | 1→2 lines | ~184 | diff --git a/src/controller/meson.build b/src/controller/meson.build index 5a9cdf45..87433af6 100644 --- a/src/controller/meson.build +++ b/src/controller/meson.build @@ -127,6 +127,7 @@ controller_unit_test_src = [ 'job.c', 'queue.c', 'join.c', + 'opupd.c', 'startup_validation.c', 'worker.c', 'persist.c', diff --git a/src/controller/testsuite/test_commit_barrier_reply.c b/src/controller/testsuite/test_commit_barrier_reply.c index dac880cf..eadebf3f 100644 --- a/src/controller/testsuite/test_commit_barrier_reply.c +++ b/src/controller/testsuite/test_commit_barrier_reply.c @@ -5,6 +5,14 @@ * timeout → -ETIMEDOUT error reply), 1.3 (barrier rejection → error reply, * never success), 1.4 (no success-interpretable reply pre-commit). * + * ALSO HOSTS (task 3.3, Req 2.3): the receipt-ACK verdict pins for + * handle_jobdispatch, do_set_preason / do_clr_preason, and the + * do_update_op rusage path — see the "Receipt-ACK verdict pins" section. + * These land GREEN by design (pins of current correct behavior, like the + * 3.1 validation pins); they live here, not in a new file, because they + * reuse this file's entire harness: cluster + real persist + wired engine + * + stub standby registry + reply-capture endpoint + the job.c link. + * * Drives the four request-shaped handlers DIRECTLY on a worker pthread * (vtask-context stand-in; production dispatch: cluster.c:325-363) against * a real tmpdir persist_t embedded in a test cluster_t with registered @@ -83,21 +91,66 @@ #include "typemap.h" #include "wal_types.h" #include "wobj.h" +#include "xcealloc.h" #include "xstring.h" #include "zarray.h" /* ── Link stubs ────────────────────────────────────────────────────────── - * job.c / join.c reference these cross-module functions (opupd.c, sched.c, - * apiserver.c — not part of the unit-test link). None of them sits on the - * four code paths under test (jobctrl not-started branch, queue/host ctrl, - * worker join); stubbed so the binary links, same precedent as - * test_worker_join.c's collect_confvars stub. */ + * job.c / join.c / opupd.c reference these cross-module functions (dataex.c, + * misc.c, sched.c, apiserver.c — not part of the unit-test link). For the + * 3.1 paths (jobctrl not-started branch, queue/host ctrl, worker join) all + * stubs are inert; for the 3.3 verdict pins two of them gained test + * controls with NULL/no-op defaults that preserve the 3.1 behavior: + * notify() — captures dispatch-outcome notifications (jobdispatch + * verdict pin observes notify_dispatch through it) + * get_ep_worker() — returns g_stub_ep_worker (rusage verdict pin needs a + * reporting worker; production impl is misc.c:49) */ + +static endpoint_t g_req_ep; /* requester endpoint (capture; set up below) */ + +/* notify() capture — records each xce_notify_data_t delivery. For + * jobDispatchFail events (the shared ok/fail event of notify_dispatch, + * job.c) jobid + code are unpacked; reply_already_enqueued snapshots + * whether the receipt ACK was already sitting on the requester outq when + * the outcome notification fired (single-threaded handler call → exact + * ordering observation, no race). */ +#define CBRP_MAX_NOTIFY 8 +static int g_notify_count; +static int g_notify_events[CBRP_MAX_NOTIFY]; +static uint64_t g_notify_jobids[CBRP_MAX_NOTIFY]; +static int g_notify_codes[CBRP_MAX_NOTIFY]; +static int g_notify_reply_already_enqueued[CBRP_MAX_NOTIFY]; + +static void cbrp_notify_capture_reset(void) +{ + g_notify_count = 0; + memset(g_notify_events, 0, sizeof(g_notify_events)); + memset(g_notify_jobids, 0, sizeof(g_notify_jobids)); + memset(g_notify_codes, 0, sizeof(g_notify_codes)); + memset(g_notify_reply_already_enqueued, 0, + sizeof(g_notify_reply_already_enqueued)); +} + +static worker_t *g_stub_ep_worker; /* NULL by default (3.1 behavior) */ /* clang-format off */ int notify(cluster_t *c, endpoint_t *e, xce_notify_data_t *d) -{ (void)c; (void)e; (void)d; return 0; } +{ + (void)c; (void)e; + if (g_notify_count < CBRP_MAX_NOTIFY) { + g_notify_events[g_notify_count] = d->event; + if (d->event == NotifyData_data_jobDispatchFail) { + g_notify_jobids[g_notify_count] = d->data.dispatchfail->jobid; + g_notify_codes[g_notify_count] = d->data.dispatchfail->code; + } + g_notify_reply_already_enqueued[g_notify_count] = + !DATAQ_EMPTY(&g_req_ep.outq); + } + g_notify_count++; + return 0; +} worker_t *get_ep_worker(cluster_t *c, endpoint_t *e) -{ (void)c; (void)e; return NULL; } +{ (void)c; (void)e; return g_stub_ep_worker; } int update_host_runusage(xce_job_runusage_t **r, char *h, int n, xce_rusage_t **u) { (void)r; (void)h; (void)n; (void)u; return 0; } @@ -277,6 +330,8 @@ static void cbrp_setup(uint32_t sync_timeout_ms) memset(&g_req_ep, 0, sizeof(g_req_ep)); memset(&g_req_priv, 0, sizeof(g_req_priv)); memset(&g_req_from, 0, sizeof(g_req_from)); + cbrp_notify_capture_reset(); + g_stub_ep_worker = NULL; /* Requester endpoint: zeroed, no iomgr — xce_reply packets stay on * ep->outq (see file header). */ @@ -385,21 +440,30 @@ static xce_jobctrl_t g_jobctrl; static xce_request_t g_jobctrl_req; static job_submit_data_t g_job_submit; /* job_init requires submit != NULL */ +static int g_jobobj_ready; /* jobj module tables — once per process */ + +/* Create a pending (never-started) job in g_hc.jobmgr. submit may carry + * queue/user/start_info (deep-copied by makeJob via makeJobsub). */ +static void cbrp_make_job(uint64_t jobid, job_submit_data_t *submit) +{ + xce_job_t jdef; + + if (!g_jobobj_ready) { + TEST_ASSERT_EQUAL_INT(0, job_obj_init(64, 64)); + g_jobobj_ready = 1; + } + memset(&jdef, 0, sizeof(jdef)); + jdef.jobid = jobid; + jdef.state = JOB_STAT_PEND; + jdef.submit = submit; + TEST_ASSERT_NOT_NULL(makeJob(g_hc.jobmgr, &jdef)); +} + static void cbrp_arrange_jobctrl(uint64_t jobid, int create_job) { if (create_job) { - xce_job_t jdef; - static int jobobj_ready; /* jobj module tables — once per process */ - if (!jobobj_ready) { - TEST_ASSERT_EQUAL_INT(0, job_obj_init(64, 64)); - jobobj_ready = 1; - } memset(&g_job_submit, 0, sizeof(g_job_submit)); - memset(&jdef, 0, sizeof(jdef)); - jdef.jobid = jobid; - jdef.state = JOB_STAT_PEND; - jdef.submit = &g_job_submit; - TEST_ASSERT_NOT_NULL(makeJob(g_hc.jobmgr, &jdef)); + cbrp_make_job(jobid, &g_job_submit); } memset(&g_jobctrl, 0, sizeof(g_jobctrl)); g_jobctrl.action = JobControl_u_siginfo; @@ -768,6 +832,418 @@ static void test_worker_join_no_hostconfig_error_reply_immediate(void) printf("test_worker_join_no_hostconfig_error_reply_immediate: PASS\n"); } +/* ════════════════════════════════════════════════════════════════════════ + * Receipt-ACK verdict pins (ha-commit-barrier-rollout task 3.3, Req 2.3) + * + * Umbrella Reply-Ordering Contract reference (ha-consistency-invariants + * design.md §Write-Path Classification ▸ Reply-Ordering Contract): + * handle_jobdispatch's early reply is an ACK-of-receipt and MAY STAND, + * because dispatch outcomes are fact-shaped — per-job results are + * delivered via notify_dispatch, and the resulting job-state changes + * arrive later as worker-reported facts. The same verdict covers + * do_set_preason / do_clr_preason (scheduler-origin WAL_JOB_PREASON + * facts, RETAIN) and the do_update_op rusage path (worker-origin + * WAL_JOB_UPDATE + WAL_JOB_RUSAGE facts, RETAIN): their replies + * acknowledge RECEIPT of the report, never commitment of any + * state-changing log entry. + * + * These are PINS of current correct behavior — green on landing, no RED + * phase exists (task-stated design, like the 3.1 validation pins). They + * run with ACKs withheld throughout, so any future regression that makes + * one of these handlers wait on the commit barrier trips the latency + * bound, and any future WAL append from dispatch processing trips either + * the unchanged-LSN pin or (for an unclassified type) the XCE_TESTING + * abort in wal_classify — the classification guard stays silent through + * a clean dispatch cycle. + * ════════════════════════════════════════════════════════════════════════ */ + +/* ── handle_jobdispatch fixture ──────────────────────────────────────── */ + +static endpoint_t g_wkr_disp_ep; /* dispatch worker endpoint */ +static job_submit_data_t g_disp_submit; +static job_startinfo_t g_disp_startinfo; +static xce_job_dispatch_t g_dispatchmsg; +static xce_job_alloc_t *g_dispatch_allocs[2]; +static xce_request_t g_dispatch_req; + +#define CBRP_DISP_JOBID 60u + +/* Full dispatch fixture: queue (get_queue_exec), pending job with a real + * submit (dispatch_a_job_ reads submit->queue and submit->start_info), + * worker with a live no-iomgr endpoint (the startjob request must be + * enqueueable), and a 2-job dispatch message exercising BOTH outcomes: + * allocs[0] — dispatchable to wkr-disp → notify_dispatch(ok, code 0) + * allocs[1] — nhosts == 0 → notify_dispatch(fail, -EINVAL) + * The allocs are heap-built via xcealloc helpers because the handler + * takes ownership (MOVE_PTR + free_JobAlloc_ptr per job). */ +static void cbrp_arrange_jobdispatch(void) +{ + xce_queue_t qdef; + xce_worker_t wdef; + hostattrs_t *attrs = NULL; + worker_t *w = NULL; + + memset(&qdef, 0, sizeof(qdef)); + qdef.queue = (char *)"qd"; + TEST_ASSERT_NOT_NULL(makeQueue(g_hc.qmgr, &qdef)); + + memset(&g_disp_startinfo, 0, sizeof(g_disp_startinfo)); + g_disp_startinfo.cmdline = (char *)"/bin/true"; + memset(&g_disp_submit, 0, sizeof(g_disp_submit)); + g_disp_submit.queue = (char *)"qd"; + g_disp_submit.user = (char *)"tester"; + g_disp_submit.start_info = &g_disp_startinfo; + cbrp_make_job(CBRP_DISP_JOBID, &g_disp_submit); + + attrs = calloc(1, sizeof(*attrs)); + TEST_ASSERT_NOT_NULL(attrs); + attrs->hosttype = makeString("LINUX"); + attrs->hostmodel = makeString("x86"); + attrs->cpufactor = 1.0f; + attrs->maxcpus = 4; + memset(&wdef, 0, sizeof(wdef)); + wdef.name = (char *)"wkr-disp"; + wdef.attrs = attrs; + TEST_ASSERT_NOT_NULL(makeWorker(g_hc.workermgr, &wdef)); + + /* dispatch gate: worker must have an endpoint and status 0 */ + memset(&g_wkr_disp_ep, 0, sizeof(g_wkr_disp_ep)); + g_wkr_disp_ep.fd = -1; + lock(g_hc.workermgr, RTTI_LOCK_READ); + key_find(g_hc.workermgr, (void *)"wkr-disp", (void **)&w); + unlock(g_hc.workermgr); + TEST_ASSERT_NOT_NULL(w); + w->ep = &g_wkr_disp_ep; + + g_dispatch_allocs[0] = make_job_alloc( + CBRP_DISP_JOBID, 1, + make_host_allocs(1, + make_host_alloc((char *)"wkr-disp", 1, + make_allocs(1, + make_alloc((char *)"slots", NULL, 0, 1.0f, 0))))); + TEST_ASSERT_NOT_NULL(g_dispatch_allocs[0]); + g_dispatch_allocs[1] = make_job_alloc(CBRP_DISP_JOBID, 0, NULL); + TEST_ASSERT_NOT_NULL(g_dispatch_allocs[1]); + + memset(&g_dispatchmsg, 0, sizeof(g_dispatchmsg)); + g_dispatchmsg.njobs = 2; + g_dispatchmsg.allocs = g_dispatch_allocs; + memset(&g_dispatch_req, 0, sizeof(g_dispatch_req)); + g_dispatch_req.opcode = OPCode_jobdispatch; + g_dispatch_req.seq = 15; + g_dispatch_req.from = &g_req_from; + g_dispatch_req.body_which = Request_body_dispatchmsg; + g_dispatch_req.body.dispatchmsg = &g_dispatchmsg; +} + +/* VERDICT PIN (Req 2.3): handle_jobdispatch (job.c:468-500, re-verified + * 2026-06-12) replies status=0 IMMEDIATELY — an ACK-of-receipt per the + * umbrella Reply-Ordering Contract (see section header) — and a full + * dispatch cycle (one successful + one failed allocation) appends NO WAL + * entries: allocation results return via notify_dispatch and job-state + * changes arrive later as worker facts. ACKs are withheld for the whole + * test, so a regression that adds a barrier wait trips the latency bound + * and any WAL append from dispatch processing trips the unchanged-LSN + * assert (an unclassified type would abort in wal_classify first). */ +static void test_jobdispatch_receipt_ack_no_wal_append(void) +{ + cbrp_reply_obs_t obs = { 0 }; + uint64_t lsn_before, lsn_after, t0, elapsed_ms; + int rc; + + cbrp_setup(3000); + cbrp_arrange_jobdispatch(); + cbrp_notify_capture_reset(); /* drop any arrange-time noise */ + + pthread_mutex_lock(&g_hc.persist.lock); + lsn_before = g_hc.persist.current_lsn; + pthread_mutex_unlock(&g_hc.persist.lock); + + /* Act: synchronous — the receipt ACK must never block on commit */ + t0 = cbrp_mono_ms(); + rc = handle_jobdispatch(&g_hc, &g_req_ep, &g_dispatch_req); + elapsed_ms = cbrp_mono_ms() - t0; + + pthread_mutex_lock(&g_hc.persist.lock); + lsn_after = g_hc.persist.current_lsn; + pthread_mutex_unlock(&g_hc.persist.lock); + cbrp_scan_replies(&g_req_ep, &obs); + + TEST_ASSERT_EQUAL_INT_MESSAGE(0, rc, "handle_jobdispatch rc"); + TEST_ASSERT_TRUE_MESSAGE(elapsed_ms < 1000, + "receipt ACK must be latency-bounded — no commit barrier wait " + "(Req 2.3: the dispatch reply confirms receipt only)"); + TEST_ASSERT_EQUAL_INT_MESSAGE(1, obs.n_replies, + "scheduler must receive exactly the one receipt ACK"); + TEST_ASSERT_EQUAL_INT_MESSAGE(0, obs.last_status, + "the receipt ACK reports acceptance of the message (status 0)"); + + /* THE classification pin: dispatch processing appends no WAL entries, + * so there is nothing the receipt ACK could have falsely confirmed */ + TEST_ASSERT_EQUAL_UINT64_MESSAGE(lsn_before, lsn_after, + "a dispatch cycle must append NO WAL entries (Req 2.3 — any " + "future append from dispatch processing must move behind the " + "barrier or be re-classified; the wal_classify XCE_TESTING " + "guard backstops unclassified types)"); + + /* notify_dispatch outcomes unaffected: one ok + one fail, in order */ + TEST_ASSERT_EQUAL_INT_MESSAGE(2, g_notify_count, + "both allocations must produce their per-job outcome notification"); + TEST_ASSERT_EQUAL_INT(NotifyData_data_jobDispatchFail, + g_notify_events[0]); + TEST_ASSERT_EQUAL_INT(NotifyData_data_jobDispatchFail, + g_notify_events[1]); + TEST_ASSERT_EQUAL_UINT64(CBRP_DISP_JOBID, g_notify_jobids[0]); + TEST_ASSERT_EQUAL_INT_MESSAGE(0, g_notify_codes[0], + "allocs[0] dispatch to the live worker must succeed (code 0)"); + TEST_ASSERT_EQUAL_UINT64(CBRP_DISP_JOBID, g_notify_jobids[1]); + TEST_ASSERT_EQUAL_INT_MESSAGE(-EINVAL, g_notify_codes[1], + "allocs[1] (nhosts == 0) must fail with -EINVAL"); + + /* Ordering: the receipt ACK was already enqueued when the FIRST + * dispatch outcome fired — reply precedes processing (ACK-of-receipt, + * not ACK-of-outcome) */ + TEST_ASSERT_TRUE_MESSAGE(g_notify_reply_already_enqueued[0], + "the receipt ACK must be enqueued before any dispatch outcome " + "notification (reply-before-processing is the verdict)"); + + /* drain the startjob request enqueued on the worker endpoint */ + { + cbrp_reply_obs_t wdrain = { 0 }; + cbrp_scan_replies(&g_wkr_disp_ep, &wdrain); + } + cbrp_teardown(); + printf("test_jobdispatch_receipt_ack_no_wal_append: PASS\n"); +} + +/* ── do_set_preason / do_clr_preason fixtures ────────────────────────── */ + +static xce_pendreason_t g_pendreason; +static xce_pendreason_t *g_pendreasons[1]; +static xce_preason_set_t g_preason_set; +static xce_request_t g_preason_req; +static uint64_t g_clr_jobs[1]; +static xce_clear_reason_t g_clrreason; +static xce_request_t g_clrpreason_req; + +/* set_preason MOVEs the inner xce_job_preason_t into the job (job.c + * MOVE_PTR(job->pend_reasons, ...)) and the job/do_clr_preason frees it + * later — so it must be heap-allocated; the carrier structs stay static. */ +static void cbrp_arrange_set_preason(uint64_t jobid) +{ + xce_job_preason_t *jpr = calloc(1, sizeof(*jpr)); + + TEST_ASSERT_NOT_NULL(jpr); + jpr->main_reason = 7; /* arbitrary scheduler pend reason */ + + memset(&g_pendreason, 0, sizeof(g_pendreason)); + g_pendreason.jobid = jobid; + g_pendreason.reasons = jpr; + g_pendreasons[0] = &g_pendreason; + memset(&g_preason_set, 0, sizeof(g_preason_set)); + g_preason_set.nreasons = 1; + g_preason_set.reasons = g_pendreasons; + memset(&g_preason_req, 0, sizeof(g_preason_req)); + g_preason_req.opcode = OPCode_setpreason; + g_preason_req.seq = 16; + g_preason_req.from = &g_req_from; + g_preason_req.body_which = Request_body_preasonmsg; + g_preason_req.body.preasonmsg = &g_preason_set; +} + +static void cbrp_arrange_clr_preason(uint64_t jobid) +{ + g_clr_jobs[0] = jobid; + memset(&g_clrreason, 0, sizeof(g_clrreason)); + g_clrreason.njobs = 1; + g_clrreason.jobs = g_clr_jobs; + memset(&g_clrpreason_req, 0, sizeof(g_clrpreason_req)); + g_clrpreason_req.opcode = OPCode_clrpreason; + g_clrpreason_req.seq = 17; + g_clrpreason_req.from = &g_req_from; + g_clrpreason_req.body_which = Request_body_clrpreasonmsg; + g_clrpreason_req.body.clrpreasonmsg = &g_clrreason; +} + +/* Shared receipt-style fact-handler driver: with ACKs withheld the + * handler must (a) reply status 0 latency-bounded — receipt only, no + * barrier wait — (b) append exactly expect_appends fact entries that + * remain PENDING (lsn > committed_lsn: the reply confirmed nothing about + * commitment), and (c) once a covering ACK arrives the retained suffix + * commits with no redelivery (the RETAIN contract observable per spec + * Implementation Notes 1.1: registration-free, pending purely by + * lsn > committed_lsn, ACK-driven advance). */ +static void cbrp_drive_receipt_fact(cbrp_op_fn_t fn, xce_request_t *req, + uint64_t expect_appends) +{ + cbrp_reply_obs_t obs = { 0 }; + uint64_t lsn_before, lsn_after, watermark, t0, elapsed_ms; + uint64_t deadline; + int rc; + + pthread_mutex_lock(&g_hc.persist.lock); + lsn_before = g_hc.persist.current_lsn; + pthread_mutex_unlock(&g_hc.persist.lock); + + /* Act: synchronous — receipt-style handlers must never block */ + t0 = cbrp_mono_ms(); + rc = fn(&g_hc, &g_req_ep, req); + elapsed_ms = cbrp_mono_ms() - t0; + + pthread_mutex_lock(&g_hc.persist.lock); + lsn_after = g_hc.persist.current_lsn; + pthread_mutex_unlock(&g_hc.persist.lock); + watermark = lsn_after - 1; /* last appended entry */ + cbrp_scan_replies(&g_req_ep, &obs); + + TEST_ASSERT_EQUAL_INT_MESSAGE(0, rc, "fact handler rc"); + TEST_ASSERT_TRUE_MESSAGE(elapsed_ms < 1000, + "receipt-style reply must be latency-bounded — no commit barrier " + "wait with ACKs withheld (facts have no commit timeout, Req 2.3)"); + TEST_ASSERT_EQUAL_INT_MESSAGE(1, obs.n_replies, + "the reporter must receive exactly one receipt reply"); + TEST_ASSERT_EQUAL_INT_MESSAGE(0, obs.last_status, + "the receipt reply reports acceptance (status 0)"); + + /* the fact appends happened ... */ + TEST_ASSERT_EQUAL_UINT64_MESSAGE(lsn_before + expect_appends, lsn_after, + "the handler must append exactly its fact entries"); + /* ... and are RETAIN-pending: the receipt reply coexists with the + * uncommitted suffix, proving it confirmed receipt, not commitment */ + TEST_ASSERT_TRUE_MESSAGE( + atomic_load(&g_hc.persist.committed_lsn) < watermark, + "fact entries must remain pending (lsn > committed_lsn) — the " + "receipt reply must not imply commitment (Req 2.3)"); + TEST_ASSERT_TRUE_MESSAGE(obs.committed_at_obs < watermark, + "the receipt reply was observable while the fact entries were " + "still uncommitted — receipt-only semantics pinned"); + + /* RETAIN completion: a covering ACK (self + 1 standby = majority of + * n_peers=3) advances committed_lsn over the retained suffix with no + * redelivery from the reporter */ + repl_on_ack(&g_hc.persist.repl, &g_hep_a, watermark); + deadline = cbrp_mono_ms() + 2000; + while (atomic_load(&g_hc.persist.committed_lsn) < watermark + && cbrp_mono_ms() < deadline) + cbrp_sleep_ms(5); + TEST_ASSERT_TRUE_MESSAGE( + atomic_load(&g_hc.persist.committed_lsn) >= watermark, + "a covering ACK must commit the retained fact entries " + "(RETAIN registration contract)"); +} + +/* VERDICT PIN (Req 2.3): do_set_preason (job.c:1062) replies status=0 + * receipt-style BEFORE applying the scheduler-reported pend reasons; the + * subsequent WAL_JOB_PREASON fact append (HOOK_DETAIL_SETPREASON → + * persist_job_hook_fun, RETAIN per wal_classify) stays pending until + * ACK-covered. Umbrella Reply-Ordering Contract: receipt-only ACK for a + * fact-shaped delivery (see section header). */ +static void test_set_preason_receipt_reply_fact_retained(void) +{ + cbrp_setup(3000); + cbrp_arrange_jobctrl(70, 1); /* job 70 exists; jobctrl req unused */ + cbrp_arrange_set_preason(70); + cbrp_drive_receipt_fact(do_set_preason, &g_preason_req, 1); + cbrp_teardown(); + printf("test_set_preason_receipt_reply_fact_retained: PASS\n"); +} + +/* VERDICT PIN (Req 2.3): do_clr_preason (job.c:1090) — same receipt-style + * verdict as do_set_preason; the clear is also a scheduler-origin + * WAL_JOB_PREASON fact (HOOK_DETAIL_CLRPREASON, RETAIN). */ +static void test_clr_preason_receipt_reply_fact_retained(void) +{ + cbrp_reply_obs_t drain = { 0 }; + + cbrp_setup(3000); + cbrp_arrange_jobctrl(71, 1); + /* seed pend reasons so the clear exercises the real erase path */ + cbrp_arrange_set_preason(71); + TEST_ASSERT_EQUAL_INT(0, do_set_preason(&g_hc, &g_req_ep, + &g_preason_req)); + cbrp_scan_replies(&g_req_ep, &drain); /* drop the seeding reply */ + + cbrp_arrange_clr_preason(71); + cbrp_drive_receipt_fact(do_clr_preason, &g_clrpreason_req, 1); + cbrp_teardown(); + printf("test_clr_preason_receipt_reply_fact_retained: PASS\n"); +} + +/* ── do_update_op rusage path fixture ────────────────────────────────── */ + +/* KNOWN PRE-EXISTING MISMATCH (discovered while pinning, reported in the + * task evidence — NOT fixed here, production is out of boundary): + * update_job_rusages fires the AFTER_EVENT HOOK_DETAIL_JOB_RUSAGE_UPDATE + * hook with (cluster_t*, xce_job_rusages_t*) [job.c:1015-1016], but + * persist_job_hook_fun's default arm reads the second vararg as a job_t* + * [persist.c:1354-1359] and dereferences j->job.state at offset 56 — + * exactly sizeof(xce_job_rusages_t) — an out-of-bounds read on an + * exactly-sized allocation (the WAL_JOB_RUSAGE payload's state field is + * garbage). The padded box below keeps THIS pin's read in-bounds under + * ASAN without masking the report; the jobid field (offset 0 in both + * types) lines up by accident. */ +static union { + xce_job_rusages_t r; + unsigned char pad[sizeof(xce_job_rusages_t) + 64]; +} g_rusages_box; + +static xce_update_data_t g_updatemsg; +static xce_request_t g_update_req; + +static void cbrp_arrange_update_rusage(uint64_t jobid) +{ + xce_worker_t wdef; + hostattrs_t *attrs = NULL; + worker_t *w = NULL; + + /* reporting worker — get_ep_worker (stubbed) must return it */ + attrs = calloc(1, sizeof(*attrs)); + TEST_ASSERT_NOT_NULL(attrs); + attrs->hosttype = makeString("LINUX"); + attrs->hostmodel = makeString("x86"); + attrs->cpufactor = 1.0f; + attrs->maxcpus = 4; + memset(&wdef, 0, sizeof(wdef)); + wdef.name = (char *)"wkr-rus"; + wdef.attrs = attrs; + TEST_ASSERT_NOT_NULL(makeWorker(g_hc.workermgr, &wdef)); + lock(g_hc.workermgr, RTTI_LOCK_READ); + key_find(g_hc.workermgr, (void *)"wkr-rus", (void **)&w); + unlock(g_hc.workermgr); + TEST_ASSERT_NOT_NULL(w); + g_stub_ep_worker = w; + + memset(&g_rusages_box, 0, sizeof(g_rusages_box)); + g_rusages_box.r.jobid = jobid; /* count/npids/npgids 0 — stubs no-op */ + memset(&g_updatemsg, 0, sizeof(g_updatemsg)); + g_updatemsg.table = Update_data_jobrusages; + g_updatemsg.data.jobrusages = &g_rusages_box.r; + memset(&g_update_req, 0, sizeof(g_update_req)); + g_update_req.opcode = OPCode_update; + g_update_req.seq = 18; + g_update_req.from = &g_req_from; + g_update_req.body_which = Request_body_updatemsg; + g_update_req.body.updatemsg = &g_updatemsg; +} + +/* VERDICT PIN (Req 2.3): the do_update_op rusage path (opupd.c:69 → + * do_update_jobrusage → update_job_rusages) replies receipt-style — the + * reply carries the LOCAL application result, never a commit barrier + * result — and its two fact appends (HOOK_DETAIL_JOB_UPDATE → + * WAL_JOB_UPDATE, HOOK_DETAIL_JOB_RUSAGE_UPDATE → WAL_JOB_RUSAGE, both + * RETAIN per wal_classify) stay pending until ACK-covered. Umbrella + * Reply-Ordering Contract: receipt-only ACK for fact-shaped delivery. */ +static void test_update_op_rusage_receipt_reply_facts_retained(void) +{ + cbrp_setup(3000); + cbrp_arrange_jobctrl(72, 1); /* job 72 exists; jobctrl req unused */ + cbrp_arrange_update_rusage(72); + cbrp_drive_receipt_fact(do_update_op, &g_update_req, 2); + g_stub_ep_worker = NULL; + cbrp_teardown(); + printf("test_update_op_rusage_receipt_reply_facts_retained: PASS\n"); +} + /* ── Test group entry point ──────────────────────────────────────────── */ void test_commit_barrier_reply(void) @@ -796,5 +1272,10 @@ void test_commit_barrier_reply(void) RUN_TEST(test_worker_join_withheld_acks_replies_error); RUN_TEST(test_worker_join_success_reply_only_after_commit); RUN_TEST(test_worker_join_no_hostconfig_error_reply_immediate); + /* Receipt-ACK verdict pins (task 3.3, Req 2.3) — green on landing */ + RUN_TEST(test_jobdispatch_receipt_ack_no_wal_append); + RUN_TEST(test_set_preason_receipt_reply_fact_retained); + RUN_TEST(test_clr_preason_receipt_reply_fact_retained); + RUN_TEST(test_update_op_rusage_receipt_reply_facts_retained); UNITY_END(); }