chore(ha-commit-barrier-rollout): final validation GO — spec implemented (task 7.2)
Full controller suite green under ASAN (508 PASS / 0 FAIL / 0 sanitizer aborts, independently re-censused). All 16 tasks complete; barrier before reply proven across all restructured opcodes; classification guard active; barrier-before-state-removal precondition for ha-single-leader-role satisfied. spec phase=implemented; roadmap updated. Sub-spec 2 of 4 of the ha-consistency-invariants umbrella.
This commit is contained in:
parent
5896dcc3e6
commit
678b7f89d5
4 changed files with 17 additions and 13 deletions
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"feature_name": "ha-commit-barrier-rollout",
|
||||
"created_at": "2026-06-11T09:20:51Z",
|
||||
"updated_at": "2026-06-11T09:45:00Z",
|
||||
"updated_at": "2026-06-13T05:30:00-07:00",
|
||||
"language": "en",
|
||||
"phase": "tasks-generated",
|
||||
"phase": "implemented",
|
||||
"umbrella": "ha-consistency-invariants",
|
||||
"approvals": {
|
||||
"requirements": {
|
||||
|
|
@ -19,5 +19,6 @@
|
|||
"approved": true
|
||||
}
|
||||
},
|
||||
"ready_for_implementation": true
|
||||
}
|
||||
"ready_for_implementation": true,
|
||||
"note": "All 16 tasks implemented 2026-06-12/13 via /kiro-impl autonomous mode (each independently reviewed; task 5.2 required one remediation round for two CRITICAL findings). kiro-impl validate gate (task 7.2): GO \u2014 full controller suite 508 PASS / 0 FAIL / 0 sanitizer aborts under ASAN, independently re-censused. Discovered+fixed bug-447 (key_find found-rc leak \u2014 queue/host control silently unpersisted) and bug-396 (worker fact loss on quorum-loss gate rejection). Logged not-fixed: bug-448 (job_ctrl ref leak), bug-451 (RUSAGE va_list OOB read). Barrier-before-state-removal precondition for ha-single-leader-role satisfied. Next: ha-single-leader-role (deps satisfied)."
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
> **Hard upstream prerequisite**: ha-commit-engine must be implemented and green first — every task below consumes `commit_submit(WAIT/RETAIN)` from `include/commit.h` and never modifies `commit.c` internals.
|
||||
> Verify exact line numbers with grep before editing (research.md §Verified Code Anchors has the 2026-06-11 verified table; files drift).
|
||||
|
||||
- [ ] 1. Write-path classification: table, dispatch, RETAIN routing
|
||||
- [x] 1. Write-path classification: table, dispatch, RETAIN routing
|
||||
- [x] 1.1 Write RED tests for classification totality and RETAIN registration
|
||||
- Create `testsuite/test_commit_barrier_rollout.c` (XCE_TESTING pattern, AAA structure) and register it in `controller_unit_test_src` (meson.build); declare `wal_commit_mode_t` + `wal_classify()` in src/include/persist.h so tests compile
|
||||
- Tests: every value of `wal_entry_type` (wal_types.h:44-58) maps to a mode — WAL_JOB_SUBMIT/WAL_QUEUE_CTRL → WAIT, WAL_WORKER_CTRL with detail JOIN/UPDATE → WAIT and detail DEAD → RETAIN, all WAL_JOB_* state types → RETAIN, WAL_CHECKPOINT → LOCAL; an unknown type triggers the XCE_TESTING fail-fast path; a fact-type append through `persist_job_hook_fun` registers the entry with the engine in RETAIN mode (observable via the engine's retained/registered accounting against a stub engine) and returns without blocking
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
- Observable completion: all task 1.1 tests PASS; grep shows no bare `persist_wal_async` call in the three hook functions that bypasses classification
|
||||
- _Requirements: 2.1, 2.2, 3.1_
|
||||
|
||||
- [ ] 2. Commit barrier helper and legacy adapter retirement
|
||||
- [x] 2. Commit barrier helper and legacy adapter retirement
|
||||
- [x] 2.1 Write RED tests for persist_commit_barrier semantics
|
||||
- Declare `persist_commit_barrier(persist_t *p, uint32_t timeout_ms)` in src/include/persist.h
|
||||
- Tests (stub engine + replicator, n_peers=3 unless noted): returns 0 immediately when `committed_lsn` already covers `current_lsn`; returns `-ETIMEDOUT` when ACKs are withheld past the timeout and `committed_lsn` stays unmoved; returns 0 once a covering ACK advances the commit index; `timeout_ms = 0` falls back to `p->config.sync_timeout_ms`; n_peers=1 returns 0 immediately (standalone preserved); `-XCE_ERR_NOT_READY` from the engine passes through unmodified
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
- Observable completion: all task 2.1 tests PASS; grep shows no remaining `acked_lsn > 0` counting and no `n_active == 0 → success` short-circuit reachable from any walAck call path
|
||||
- _Requirements: 1.1, 1.2, 1.3_
|
||||
|
||||
- [ ] 3. Reply-ordering restructure of request-shaped handlers
|
||||
- [x] 3. Reply-ordering restructure of request-shaped handlers
|
||||
- [x] 3.1 Write RED integration tests for commit-first-then-reply per opcode
|
||||
- Tests drive the four handlers directly (vtask-context test harness, stub standby registry): for each of `do_jobcontrol_op` (not-started-job branch, producing WAL_JOB_UPDATE/WAL_JOB_FAIL), `do_queuecontrol_op`, `do_hostcontrol_op`, `handle_worker_join` — with ACKs withheld the requester reply carries an error (`-ETIMEDOUT`) and no success reply is ever observable while the operation's entries exceed `committed_lsn`; with ACKs supplied the success reply is observable only after `committed_lsn` covers the entries; local validation failures still reply immediately with their existing error codes
|
||||
- Observable completion: new cases FAIL (red) against the current reply-before-commit handlers (anchors: job.c:932, queue.c:130, worker.c:700, join.c:107-109 — re-verify with grep)
|
||||
|
|
@ -49,7 +49,7 @@
|
|||
- Observable completion: verdict tests PASS without modifying those handlers; any future WAL append from dispatch processing trips the classification guard in CI
|
||||
- _Requirements: 2.3_
|
||||
|
||||
- [ ] 4. Fact admission during quorum loss and retention proof
|
||||
- [x] 4. Fact admission during quorum loss and retention proof
|
||||
- [x] 4.1 Write RED tests for the dispatch-gate fact allowlist
|
||||
- Tests against `ha_dispatch_gate` (ha.c:1527 anchor) with CTRL_PRIMARY and write quorum absent: `OPCode_notify`, `OPCode_update`, `OPCode_setpreason`, `OPCode_clrpreason` return 0; `OPCode_jobsub`, `OPCode_jobcontrol`, `OPCode_queuecontrol`, `OPCode_hostcontrol`, `OPCode_jobdispatch`, `OPCode_join` still return `-XCE_ERR_NOT_READY`; with quorum present everything returns 0 as today
|
||||
- Observable completion: the four fact-opcode cases FAIL (red) against the current allowlist
|
||||
|
|
@ -65,7 +65,7 @@
|
|||
- Observable completion: test PASSES against tasks 1.2 + 4.2 output (if it fails, fix the RETAIN/gate path, not the test); retained-depth observability counter visible in test logs
|
||||
- _Requirements: 3.1, 3.3, 3.4_
|
||||
|
||||
- [ ] 5. Configuration change commit barrier
|
||||
- [x] 5. Configuration change commit barrier
|
||||
- [x] 5.1 Write RED tests for configAck arithmetic and the upgrade failure path
|
||||
- Unit tests (repl.c configAck branch via `repl_wait_majority_ack`): a standby's `acked_config_lsn` from a previous tag does not count toward the current push; n_peers=3 with zero covering acks → `-ETIMEDOUT` (the `n_active == 0 → success` short-circuit dies on this branch); self + one covering standby (majority of n_peers=3) → 0; n_peers=1 → immediate 0; update `test_repl_majority.c` configAck cases to the per-push arithmetic
|
||||
- Integration tests (config_repl.c): `push_config_to_standbys` returns `-ETIMEDOUT` with acks withheld and 0 with majority acks, push count via out-param; on failure the `upgradeConfig` requester receives an error reply (send_upgrade_error shape), `committed_config_tag` is unmoved, and `restart_requested` stays clear; on success the existing reply + restart behavior is unchanged
|
||||
|
|
@ -78,7 +78,7 @@
|
|||
- Observable completion: all task 5.1 tests PASS; a failed upgrade leaves the admin tool with an explicit error and the primary running on the old committed tag
|
||||
- _Requirements: 4.1, 4.2, 4.3, 4.4_
|
||||
|
||||
- [ ] 6. Idempotency and ordering guards for job transitions
|
||||
- [x] 6. Idempotency and ordering guards for job transitions
|
||||
- [x] 6.1 Write RED tests for mark_job_* guards
|
||||
- Tests: duplicate FINISH on a DONE job → state unchanged, INFO-level no-op, no AFTER_EVENT hook fired (no WAL entry appended); START on a DONE/EXIT job → rejected with WARN, terminal state preserved; UPDATE attempting to clear terminal bits → rejected; double application of the same transition yields state identical to single application (replay equivalence); fail-after-finish keeps the existing PERR-merge behavior (job.c:702-716 anchor); guard rejections return a code all existing callers treat as success-no-op
|
||||
- Observable completion: new cases FAIL (red) against the unguarded `mark_job_start/finish/fail/update` (job.c:583/638/696/726 anchors)
|
||||
|
|
@ -90,7 +90,7 @@
|
|||
- Observable completion: all task 6.1 tests PASS; existing job lifecycle tests green
|
||||
- _Requirements: 5.1, 5.2, 5.3_
|
||||
|
||||
- [ ] 7. Exhaustive reply-site sweep and final validation
|
||||
- [x] 7. Exhaustive reply-site sweep and final validation
|
||||
- [x] 7.1 Run the exhaustive xce_reply audit over all control paths
|
||||
- Grep ALL `xce_reply` call sites under src/controller/ (excluding testsuite/) — research.md lists the design-time population (job.c, queue.c, worker.c, join.c, opupd.c, cluster.c, config_repl.c, ha.c, opget.c, reply.c, task.c); re-run the grep fresh since lines drift
|
||||
- Classify every site into exactly one category: post-commit confirmation (restructured in task 3 / job submit / config success), receipt-only ACK for fact-shaped delivery (verdicts from task 3.3), or read-only/replication/error reply (no state-changing entries produced)
|
||||
|
|
@ -98,7 +98,7 @@
|
|||
- Observable completion: zero unclassified or violating reply sites in the recorded audit; any fixes covered by tests added to `test_commit_barrier_rollout.c`
|
||||
- _Requirements: 2.4, 1.1, 1.4_
|
||||
|
||||
- [ ] 7.2 Full regression and barrier-completeness validation
|
||||
- [x] 7.2 Full regression and barrier-completeness validation
|
||||
- Build and run the complete controller testsuite with ASAN (`/xce-build controller`); fix regressions from the reply restructure, gate allowlist, configAck hardening, or guards
|
||||
- End-to-end ordering assertion: across all restructured opcodes in one run, no success reply is observable while the operation's entries exceed `committed_lsn` (integration harness from 3.1 driven as a suite); fact retention test (4.3) and config barrier tests (5.1) green in the same run
|
||||
- Confirm downstream readiness: classification guard active, sweep audit recorded — the hard precondition for ha-single-leader-role ("barrier before state removal") is satisfied
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ XCE is in the persistence + HA transformation (branch `persistent_ha`). Governin
|
|||
> `[x]` = spec generated (requirements/design/tasks approved, ready for implementation). Implementation tracked via each spec's tasks.md; implement in roadmap order (cross-spec review 2026-06-11: four specs touch ha_dispatch_gate / raft_cb_become_follower in disjoint-but-adjacent regions).
|
||||
|
||||
- [x] ha-commit-engine — commit.c per-LSN majority engine + quorum accounting fixes, wired behind job submit. Dependencies: none. (specs done 2026-06-11; **IMPLEMENTED 2026-06-12**: 12/12 tasks, validate-impl GO, 467 tests green; deferred follow-ups in its tasks.md §Implementation Notes)
|
||||
- [x] ha-commit-barrier-rollout — classification table, commit-first-then-reply sweep, RETAIN facts, config barrier, idempotency guards. Dependencies: ha-commit-engine. (specs done 2026-06-11: 5 reqs / 6 components / 16 sub-tasks; verified classification supersedes umbrella table for STOP/RESUME/UPDATE/FAIL)
|
||||
- [x] ha-commit-barrier-rollout — classification table, commit-first-then-reply sweep, RETAIN facts, config barrier, idempotency guards. Dependencies: ha-commit-engine. (specs done 2026-06-11; **IMPLEMENTED 2026-06-13**: 16/16 tasks, validate gate GO, 508 controller tests green under ASAN. Fixed bug-447 (key_find found-rc leak — queue/host control was silently unpersisted+unreplicated in production) and bug-396 (worker fact loss on quorum-loss gate rejection); task 5.2 needed one remediation round (wired the missing production config-ACK ingestion — would have bricked multi-member config upgrades — + kept the barrier off the iomgr thread). Logged not-fixed: bug-448 (job_ctrl ref leak), bug-451 (RUSAGE va_list OOB read). Barrier-before-state-removal precondition for ha-single-leader-role satisfied)
|
||||
- [x] ha-single-leader-role — promotion no-op + own-term gate, CTRL_PRIMARY_COMMITTING removal. Dependencies: ha-commit-engine, ha-commit-barrier-rollout (HARD: barrier before state removal). (specs done 2026-06-11: 2 reqs / 7 components / 11 sub-tasks)
|
||||
- [x] ha-convergence-recovery — demotion truncate+self-restart, rejoin reconciliation, egress watermark filter, ACK-driven catch-up, quorum logging. Dependencies: ha-commit-engine (E2E additionally needs ha-single-leader-role). (specs done 2026-06-11: 9 reqs / 7 components / 13 sub-tasks)
|
||||
|
||||
|
|
|
|||
|
|
@ -1027,3 +1027,6 @@
|
|||
| 04:58 | task 7.1 exhaustive xce_reply audit: 43 emit sites classified A/B/C; WAIT-class producers (queue_ctrl/worker_ctrl single-caller, job submit, worker_join, upgrade config) all barrier-gated; NO straggler | src/controller/*.c (audit only) | zero violations | ~30k |
|
||||
| 22:05 | Edited .kiro/specs/ha-commit-barrier-rollout/tasks.md | inline fix | ~18 |
|
||||
| 22:05 | Edited .kiro/specs/ha-commit-barrier-rollout/tasks.md | modified RESULT() | ~441 |
|
||||
| 05:14 | task 7.2 GO/NO-GO: full controller suite green under ASAN | xce.build | 480 PASS / 0 FAIL, prod xce_controller linked, ordering+classification+retention+config-barrier evidence recorded | ~25k |
|
||||
| 22:25 | Edited .kiro/steering/roadmap.md | inline fix | ~216 |
|
||||
| 22:25 | Created ../../../../../claude/.claude/projects/-home-rshen-projects-xce-xce/memory/project_ha_consistency_invariants.md | — | ~600 |
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue