feat(ha-term-safety): restore controller build + wire vote/AE term wire fields (tasks 1.1, 1.2)

1.1: WalCatchupEntry gains term@4/prevLogIndex@5/prevLogTerm@6 (append-only).
1.2: RequestVote/PreVote gain lastLogTerm@4/lastLogIndex@5; cluster.c vote callers
fixed to the extended library arity (RESTORES xce_controller + controller_unit_test
compile+link, broken by the raft-commit-safety signature extension); ha.c emits the
candidate's last-log tuple on send.

5 minimal stub log/commit callbacks wired into s_real_cbs so raft_init's new
non-NULL requirement is satisfied — tasks 2.x replace them with real bodies; the
logOk freshness gate is inert until the term seam (1.3) + on_get_entry_term (2.2).

Pre-existing test_repl_unit.c wal_catchup -EAGAIN failures + ASAN leaks are an
overlayfs /tmp fsync env artifact (bug-850), not from this task (untouched paths;
append-only schema cannot affect the @3 entries-list decode). Build/baseline
isolation is blocked by a c-capnproto flake-hash drift — see Implementation Notes.
This commit is contained in:
Rongsong Shen 2026-06-22 03:41:49 +00:00
parent e8e41752c0
commit 004a40bb3b
9 changed files with 264 additions and 9 deletions

View file

@ -825,6 +825,13 @@ struct RequestVoteRequest $C.mapname("request_vote_req_t") {
candidateId @1 :Text $C.mapname("candidate_id");
configTag @2 :UInt64 $C.mapname("config_tag");
lastLogLsn @3 :UInt64 $C.mapname("last_log_lsn");
# Raft (lastLogTerm, lastLogIndex) freshness tuple (ha-term-safety task 1.2,
# Req 2.3/2.4/2.6). Distinct from the XCE freshness fields above: configTag /
# lastLogLsn drive the application-policy freshness gate (on_vote_eligible),
# while these two feed the library's logOk gate (raft.tla HandleRequestVoteRequest
# logOk). lastLogIndex == candidate WAL log_len; lastLogTerm == term of that entry.
lastLogTerm @4 :UInt64 $C.mapname("last_log_term");
lastLogIndex @5 :UInt64 $C.mapname("last_log_index");
}
struct RequestVoteReply $C.mapname("request_vote_reply_t") {
@ -878,6 +885,15 @@ struct WalCatchupEntry $C.mapname("wal_catchup_entry_t") {
entryType @1 :UInt8 $C.mapname("entry_type");
payload @2 :Data $C.mapname("payload");
entries @3 :List(WalCatchupEntry) $C.mapname("entries") $C.maplistcount("n_entries");
# Raft AppendEntries term fields (ha-term-safety task 1.1, Req 1.3/1.4).
# This envelope is the replication-carrying message (WAL catch-up); the four
# log callbacks (tasks 2.x) need prevLog{Index,Term} for the AppendEntries
# logOk / conflict-truncation decision and `term` to stamp the entry. lsn ==
# this entry's 1-based log index; prevLogIndex == lsn-1; prevLogTerm == term of
# the entry at prevLogIndex (0 if absent); term == this entry's term stamp.
term @4 :UInt64 $C.mapname("term");
prevLogIndex @5 :UInt64 $C.mapname("prev_log_index");
prevLogTerm @6 :UInt64 $C.mapname("prev_log_term");
}
struct CtrlHelloRequest $C.mapname("ctrl_hello_req_t") {