a rendered stable lane shifts the managers and calls it activation #346

Open
opened 2026-08-18 17:07:02 +00:00 by PerishFire · 0 comments
Owner

sidecar v0.8.0 went out through a rendered stable lane. Every object published,
the managers moved, the run reported activation, and the stable pointer never
changed. The four smoke jobs then failed for the reason that follows from that,
and the release job failed with them.

What the public authority holds now

object state last-modified
v1/releases/stable/v0.8.0/seal.json published today
manage.sh, manage.ps1 rewritten today 16:58
v1/channels/stable.json still v0.7.0 30 July

The pointer is not a caching artifact: cf-cache-status: DYNAMIC, and its
last-modified is three weeks old.

The two deeds are different and the lane runs one of them

crates/cli/src/dispatch/release/storage.rs:

pub fn activate(...) { ... remote.activate(pointer, &root)?; verify::consensus(...)
                       Ok(format!("activated stable {}", capsule.version)) }

pub fn shift(...)    { ... for manager in &capsule.roots { remote.shift(...) }
                       verify::projection(...)
                       Ok(format!("activated stable binary {}", capsule.version)) }

and the verbs map to different ones:

crates/cli/src/dispatch/ship.rs:245
    Binary::Activate => storage::shift(&capsule(release)?, &rig.activate),

crates/cli/src/dispatch/release/mod.rs:73
    Deed::Activate   => storage::activate(&capsule(release)?, &rig.activate),

The rendered ship.yml seal job runs plumb ship binary activate under a step
named "Activate the stable consensus". That resolves to shift — managers only.
Nothing in the rendered lane ever runs the deed that writes the pointer, so a
rendered stable release cannot reach consensus.

The log line the run leaves behind is activated stable binary v0.8.0. The
only thing separating it from activated stable v0.8.0 is the word binary.

Why the smokes fail, and why that is a symptom

plumb ship: sidecar version mismatch: expected sidecar v0.8.0, got sidecar v0.7.0

Smoke installs through the stable manager, the manager resolves the pointer, the
pointer still names v0.7.0. All four platforms failed identically. They are
reporting the missing activation, not a platform problem.

Where this leaves a release

Safe, but split. Consumers on sidecar update stay on v0.7.0, which is correct
behaviour for a pointer that did not move. The exact objects for v0.8.0 are
published and sealed. The module attachment published independently, so
@perish/sidecar@0.8.0 carries latest while the binary channel does not,
and the two halves of one release disagree.

Repair from an operator seat is not available: plumb release activate needs
PLUMB_ACTIVATE_*, which exist only as forge secrets, and reading them back is
not possible by design. Completing this release needs either a lane that runs
the deed, or hand-authored release machinery of exactly the kind rendering
exists to remove.

This is the class from #274

A mechanism reported success for something it did not do, and the gate that
would have caught it is the one that was skipped. The difference here is that
verify::consensus exists and would have refused — it just never ran, because
the deed that calls it was never invoked.

Sidecar is on v0.26.0 with lanes rendered by that version, and this was its
first stable release through them.

`sidecar v0.8.0` went out through a rendered stable lane. Every object published, the managers moved, the run reported activation, and the stable pointer never changed. The four smoke jobs then failed for the reason that follows from that, and the release job failed with them. ## What the public authority holds now | object | state | last-modified | | --- | --- | --- | | `v1/releases/stable/v0.8.0/seal.json` | published | today | | `manage.sh`, `manage.ps1` | rewritten | today 16:58 | | `v1/channels/stable.json` | **still v0.7.0** | **30 July** | The pointer is not a caching artifact: `cf-cache-status: DYNAMIC`, and its `last-modified` is three weeks old. ## The two deeds are different and the lane runs one of them `crates/cli/src/dispatch/release/storage.rs`: ```rust pub fn activate(...) { ... remote.activate(pointer, &root)?; verify::consensus(...) Ok(format!("activated stable {}", capsule.version)) } pub fn shift(...) { ... for manager in &capsule.roots { remote.shift(...) } verify::projection(...) Ok(format!("activated stable binary {}", capsule.version)) } ``` and the verbs map to different ones: ```rust crates/cli/src/dispatch/ship.rs:245 Binary::Activate => storage::shift(&capsule(release)?, &rig.activate), crates/cli/src/dispatch/release/mod.rs:73 Deed::Activate => storage::activate(&capsule(release)?, &rig.activate), ``` The rendered `ship.yml` seal job runs `plumb ship binary activate` under a step named "Activate the stable consensus". That resolves to `shift` — managers only. Nothing in the rendered lane ever runs the deed that writes the pointer, so a rendered stable release cannot reach consensus. The log line the run leaves behind is `activated stable binary v0.8.0`. The only thing separating it from `activated stable v0.8.0` is the word `binary`. ## Why the smokes fail, and why that is a symptom ``` plumb ship: sidecar version mismatch: expected sidecar v0.8.0, got sidecar v0.7.0 ``` Smoke installs through the stable manager, the manager resolves the pointer, the pointer still names v0.7.0. All four platforms failed identically. They are reporting the missing activation, not a platform problem. ## Where this leaves a release Safe, but split. Consumers on `sidecar update` stay on v0.7.0, which is correct behaviour for a pointer that did not move. The exact objects for v0.8.0 are published and sealed. The module attachment published independently, so `@perish/sidecar@0.8.0` carries `latest` while the binary channel does not, and the two halves of one release disagree. Repair from an operator seat is not available: `plumb release activate` needs `PLUMB_ACTIVATE_*`, which exist only as forge secrets, and reading them back is not possible by design. Completing this release needs either a lane that runs the deed, or hand-authored release machinery of exactly the kind rendering exists to remove. ## This is the class from #274 A mechanism reported success for something it did not do, and the gate that would have caught it is the one that was skipped. The difference here is that `verify::consensus` exists and would have refused — it just never ran, because the deed that calls it was never invoked. Sidecar is on `v0.26.0` with lanes rendered by that version, and this was its first stable release through them.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
PerishLab/plumb#346
No description provided.