Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ant-node"
version = "0.17.1"
version = "0.17.2"
edition = "2021"
authors = ["David Irvine <david.irvine@maidsafe.net>"]
description = "Pure quantum-proof network node for the Autonomi decentralized network"
Expand Down Expand Up @@ -39,10 +39,10 @@ mimalloc = "0.1"
# Until then, the git pin tracks the matching saorsa-core lineage
# (the rc-2026.4.2 branch) so Cargo can unify the wire types here
# with ant-protocol's re-exports.
ant-protocol = "2.3.2"
ant-protocol = "2.3.3"

# Core (provides EVERYTHING: networking, DHT, security, trust, storage)
saorsa-core = "0.27.0"
saorsa-core = "0.27.1"
saorsa-pqc = "0.5"

# Payment verification - autonomi network lookup + EVM payment
Expand Down
54 changes: 53 additions & 1 deletion docs/adr/ADR-0010-beta-upgrade-channel-semantics.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,49 @@ the public `UpgradeMonitor::version_matches_channel`.
Option 3 is deliberately deferred rather than rejected: nothing here prevents adding an `rc` channel
later, and the exact-identifier rule means doing so is an additive change.

### Amendment: a beta node skips its own promotion

Channel eligibility alone produced an unwanted hop. Semver ranks a final above its own
pre-release, so a node running `0.18.0-beta.1` treated the promoted `0.18.0` as an upgrade — a
binary swap and a network restart for what is the same code re-tagged. Because the train promotes
on every cycle, this would have happened on every train, to every beta node.

Eligibility is therefore refined: **on the beta channel, a final release is not a candidate when the
running version is a `beta.*` pre-release of the same `major.minor.patch`.** The skip is narrow by
design:

- A genuinely newer final is still taken (`0.19.0` while running `0.18.0-beta.1`), so a beta node
does not stagnate if the beta line stalls.
- A later beta of the same version is still taken (`0.18.0-beta.2`).
- It applies to the beta channel only. A node running a beta build while configured for `stable`
still takes the final, since that is its route back onto the stable line.

This is a rule about the *pair* (candidate, running version) rather than about the candidate alone,
so it lives beside the channel predicate rather than inside it.

The skip is safe because of how the train is shaped, not because the node can verify it. Promotion
does change the build: dependency references flip from git branch pins to published crates.io
versions (`ant-protocol = { git = ..., branch = "rc-2026.8.3" }` becomes `ant-protocol = "2.3.2"`),
so a final is not byte-identical to the beta it came from. What makes it the *same code* is that any
change landing on the RC branch produces a **new** beta release, and the final is promoted from the
most recent beta. There is therefore no window in which the final carries code that no beta carries.

Two consequences follow, and both matter:

- A node holding `X.Y.Z-beta.N` when `X.Y.Z-beta.N+1` and the final `X.Y.Z` are all published does
not strand. The later beta is eligible and outranks the one it is running, while the final is
skipped, so it converges on `beta.N+1` — the code that became the final. This depends on old beta
releases remaining published after promotion, which is the current policy.
- The comparison must be against the build the node is **committed to**, not the one it is running.
During a staged rollout those differ: a node that has selected `0.19.0-beta.1` but not yet applied
it is still running `0.18.0-beta.1`, whose core differs from `0.19.0`. Comparing against the
running version would let the final through and retarget the node onto it, so whether a node kept
its beta identity would depend on where its rollout jitter happened to fall. Selection therefore
takes the pending staged-rollout target when there is one.

The "is it newer" guard deliberately stays on the running version, so that a withdrawn pending
release cannot leave a node refusing everything still published.

## Consequences

### Positive
Expand All @@ -79,6 +122,8 @@ later, and the exact-identifier rule means doing so is an additive change.
- A beta node holds its soak build until a higher `-beta.N` or a final release appears.
- The rule exists in one place, so the selection path and the predicate cannot diverge.
- The `stable` channel is unchanged, so the production fleet is unaffected.
- Beta nodes restart once per train rather than twice, and keep their identity as beta builds
instead of being silently converted to stable ones on every promotion.

### Negative / Trade-offs

Expand All @@ -87,6 +132,10 @@ later, and the exact-identifier rule means doing so is an additive change.
capability reduction and is the main thing a reviewer should weigh.
- Any future pre-release suffix is rejected by default. That is the safe direction, but it means a
new suffix requires a deliberate code change rather than working implicitly.
- The skip depends on two properties of the release process that the node cannot verify: that any
change after `beta.N` produces a `beta.N+1` which is what gets promoted, and that old beta
releases stay published so a node on a stale beta can converge through them. Neither is
mechanically enforced today; if either slips, a beta node holds an older build than it should.

### Neutral / Operational

Expand All @@ -102,7 +151,10 @@ later, and the exact-identifier rule means doing so is an additive change.
accepting `-beta.N` and finals while rejecting `-rc.N`, `-alpha.N` and `-betax.N`; selection over a
mixed list (`0.16.0`, `0.17.0-beta.1`, `0.17.0-rc.1`) resolving to `0.16.0` on stable and
`0.17.0-beta.1` on beta; and the ship-and-promote-same-day case hopping from `0.16.0-beta.1`
straight to `0.17.0-beta.1`.
straight to `0.17.0-beta.1`. For the amendment: a beta node ignoring its own promotion, still
taking a newer final, still taking a later beta of the same version, preferring the next beta over
its own promotion, a stable-channel node still taking the promotion of a beta it is running, and a
node holding its pending beta when that beta's final is published mid-rollout.
- End-to-end validation is tracked separately as V2-1012: a dev testnet where the cohort pulls a fake
`-beta.N` release and demonstrably ignores a real rc published in the same window.
- Review trigger: revisit this ADR if a new pre-release suffix is introduced, if internal rc soaking
Expand Down
Loading
Loading