Decision rules
A witness that guesses is worse than no witness at all. The rules below are deliberately narrow: the node decides only what it can decide correctly from the information a caller supplies.
→ POST /v1/vote
{
"cluster": "atlas-eu",
"candidate": "atlas-eu-2",
"term": 4472, // must exceed last seen term
"last_log_index": 918340,
"last_log_term": 4471
}
← 200
{
"granted": false,
"reason": "leader lease still valid",
"lease_expires_in_ms": 2740,
"term": 4471 // witness stays on the older term
}
| Condition | Response | Rationale |
|---|---|---|
| term ≤ last seen | deny | Stale candidate; granting would permit two leaders |
| leader lease unexpired | deny | A live leader exists regardless of what the candidate sees |
| log behind known index | deny | Committed entries would be lost |
| already voted this term | repeat prior | Idempotence; never contradict an earlier answer |
| clock skew > 50 ms | refuse | Lease arithmetic becomes unsound |
| none of the above | grant | Candidate is at least as current as anything we have seen |
The node grants at most one vote per cluster per term and persists that fact before answering. A crash between the decision and the response therefore cannot produce a second, contradictory vote.
Log entries never traverse this node. It sees indices and terms — enough to compare currency, not enough to reconstruct content.
An arbitration decision binds for exactly one lease period. If the partition heals, the cluster resumes deciding for itself without waiting for us to notice.
Each of these was requested at some point and declined. A witness with opinions is a single point of failure wearing a helpful hat.