Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
139 commits
Select commit Hold shift + click to select a range
1d3987d
feat: implement issue #1103 — cmd_rollback moves the bare <agent>/<ri…
don-petry Sep 13, 2026
ecd3875
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
donpetry-bot Sep 13, 2026
a547522
fix(reviews): address review comments [skip ci-relay]
don-petry Sep 13, 2026
de3b3f2
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Sep 13, 2026
dbac61d
fix(tests): add v-scoped channel anchors to rollback test fixtures
don-petry Sep 13, 2026
088231d
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Sep 13, 2026
359abbb
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Sep 13, 2026
e2850dd
fix: cmd_rollback falls back to bare ring tag when v-scoped tag doesn…
don-petry Sep 13, 2026
15e9fc3
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Sep 16, 2026
723aefd
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Sep 16, 2026
2c96cd1
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Sep 20, 2026
c61fea4
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Sep 20, 2026
22b0e96
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Sep 20, 2026
4045089
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Sep 20, 2026
2e303ce
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Sep 21, 2026
1b18267
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Sep 23, 2026
39559d9
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Sep 23, 2026
c05d547
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Sep 23, 2026
8c2afff
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Sep 23, 2026
b9cc376
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Sep 24, 2026
afbd68c
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Sep 27, 2026
44323d9
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Sep 30, 2026
ae7b4c5
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Sep 30, 2026
7d05098
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 2, 2026
7fe7de8
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 2, 2026
77671cb
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 2, 2026
2a47934
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 3, 2026
2b40efa
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 3, 2026
358af14
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 3, 2026
dc16e07
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 3, 2026
4019de9
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 3, 2026
c32dba2
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 3, 2026
d4b6eb6
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 4, 2026
4455b08
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 4, 2026
1e4a3a6
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 4, 2026
b931e21
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 5, 2026
c2e68ef
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 7, 2026
f52ba49
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 8, 2026
9d3decb
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 9, 2026
8ee5e4a
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 10, 2026
7f399ce
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 10, 2026
483a8cf
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 10, 2026
5eed5f0
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 10, 2026
fb8828a
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 10, 2026
03f546d
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 10, 2026
3cfffa6
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 10, 2026
e7fce0c
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 10, 2026
812fa9a
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 10, 2026
d5a8ee5
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 11, 2026
196e17f
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 11, 2026
9c9d84e
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 11, 2026
d86a772
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 11, 2026
8ec1ee2
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 11, 2026
c07f182
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 11, 2026
2e48467
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 11, 2026
3fec3e8
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 11, 2026
09af8c1
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 11, 2026
c51cb12
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 11, 2026
2fa53bd
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 11, 2026
1151c62
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 11, 2026
c3a8de0
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 11, 2026
54e8f53
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 11, 2026
e45fcc6
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 11, 2026
23bd68b
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 12, 2026
8abde5f
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 12, 2026
f7fe1a1
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 12, 2026
6bf53ff
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 13, 2026
256c5fd
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 14, 2026
55300a2
Merge main (org renamed to combsmith) into dev-lead/issue-1103-202609…
don-petry Oct 14, 2026
db8f5fd
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 14, 2026
50fa41a
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 14, 2026
df15a1e
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 14, 2026
43be74f
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 16, 2026
38a624e
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 18, 2026
d3cd164
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 18, 2026
f69ceea
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 18, 2026
b522430
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 20, 2026
10bbd87
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 20, 2026
2995419
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 20, 2026
777d07c
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 20, 2026
84703d3
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 20, 2026
67ae476
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 20, 2026
4e880af
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 21, 2026
ece7fcc
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 21, 2026
155c551
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 21, 2026
a3340cf
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 22, 2026
f6a5c3a
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 25, 2026
8563bd5
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 25, 2026
c31c8b1
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 25, 2026
180555d
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 26, 2026
6779748
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 28, 2026
19d9870
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 28, 2026
3ba8bbc
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 28, 2026
538d988
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 28, 2026
78aa551
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 28, 2026
a5be8e8
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 28, 2026
1f62cb0
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 28, 2026
7255d82
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 29, 2026
17136d2
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 29, 2026
e911574
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 29, 2026
323f345
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 30, 2026
27b5f3e
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 30, 2026
ffa122b
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 31, 2026
1911bfa
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Oct 31, 2026
f73a804
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 1, 2026
21ea8c5
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 1, 2026
8035759
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 2, 2026
1757600
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 2, 2026
3a992e2
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 2, 2026
295ada1
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 3, 2026
483fe5c
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 3, 2026
4e933a9
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 3, 2026
fa4d924
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 3, 2026
a58ec93
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 3, 2026
126dec5
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 3, 2026
13c1ecf
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 3, 2026
9a65a33
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 4, 2026
bb846d0
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 4, 2026
dbea3b3
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 4, 2026
4ca7009
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 5, 2026
e7c0e54
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 5, 2026
65d1e3b
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 5, 2026
b1854a0
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 6, 2026
103c627
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 6, 2026
40685e9
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 8, 2026
4fe0e6d
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 8, 2026
f15dad4
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 9, 2026
15d32c0
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 9, 2026
72498ea
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 9, 2026
d87367f
fix(reviews): rollback fails closed on tag lookup errors and uses onl…
don-petry Nov 9, 2026
356a5a0
fix(rollback): use [[ ... ]] syntax consistently in conditional checks
don-petry Nov 10, 2026
fb39f48
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 10, 2026
46c09a3
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 12, 2026
fdfc112
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 12, 2026
b5d1982
fix(reviews): fail closed on matching-refs listing error in canary ro…
don-petry Nov 12, 2026
0b22641
fix(reviews): resolve explicit v-scoped ring exactly; propagate unrec…
don-petry Nov 12, 2026
fd693ea
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 12, 2026
cb49111
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 13, 2026
b0bc6fd
Merge branch 'main' into dev-lead/issue-1103-20260913-0329
don-petry Nov 15, 2026
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
26 changes: 21 additions & 5 deletions scripts/canary-rollout.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1360,14 +1360,30 @@ cmd_rollback() {
local target
target="$(_gh_tag_commit "$host" "$agent/$to")"
[ -z "$target" ] && { echo "::error::release tag $agent/$to not found on $host" >&2; return 1; }
echo "rolling back $agent/$ring -> $to (${target:0:12}) on $host"
# Resolve the RING tag the SAME way cmd_promote/_resolved_channel do (major-scoped-channels
# epic #657 F4): PREFER the v-scoped `<agent>/v<M>-<ring>` within the agent's current major
# line when it exists, else the legacy bare `<agent>/<ring>`. Moving the bare tag on a
# v-scoped fleet relocated a tag no caller pins and still exited 0 — a silent no-op on the
# emergency lever (#1103). _resolved_channel returns the resolved tag AND its current commit.
# (The `--to` release tag above is always the bare immutable `<agent>/vX.Y.Z`, so it is
# correctly resolved without a major.)
local ring_tag ring_commit
IFS=$'\t' read -r ring_tag ring_commit < <(_resolved_channel "$agent" "$ring")
Comment thread
don-petry marked this conversation as resolved.
Resolved
Comment thread
don-petry marked this conversation as resolved.
Resolved
# Fail loudly rather than no-op (#1103): a resolved ring tag with no commit does not exist on
# the host. Creating-and-moving it would relocate a channel tag nobody pins while reporting
# success — the worst failure mode for a rollback. Refuse and say so.
if [ -z "$ring_commit" ]; then
echo "::error::rollback target ring tag $ring_tag does not exist on $host — refusing to create-and-move a channel tag nobody pins (that would be a silent no-op). Check the ring name and the agent's major line." >&2
return 1
fi
Comment thread
don-petry marked this conversation as resolved.
Resolved
echo "rolling back $ring_tag -> $to (${target:0:12}) on $host"
if [ "$dry" = true ]; then
echo "[DRY-RUN] would: gh api PATCH repos/$host/git/refs/tags/$agent/$ring sha=$target (force)"
echo "[DRY-RUN] would: gh api PATCH repos/$host/git/refs/tags/$ring_tag sha=$target (force)"
return 0
fi
_gh_move_tag "$host" "$agent/$ring" "$target" \
|| { echo "::error::failed to move $agent/$ring -> $to on $host" >&2; return 1; }
echo "rolled back $agent/$ring -> $to"
_gh_move_tag "$host" "$ring_tag" "$target" \
|| { echo "::error::failed to move $ring_tag -> $to on $host" >&2; return 1; }
echo "rolled back $ring_tag -> $to"
}

# ── blocker-issue + fleet-status automation (auto-triage of held promotions) ────
Expand Down
83 changes: 83 additions & 0 deletions tests/canary_rollout.bats
Original file line number Diff line number Diff line change
Expand Up @@ -1012,6 +1012,89 @@ GITEOF
! grep -Ev '^[[:space:]]*#' "$ORCH" | grep -Eq '\bgit[[:space:]]+(tag|push)\b'
}

# ── orchestrator: rollback resolves the ring tag v-scope-aware, like promote (#1103) ──
# cmd_rollback used to move the BARE <agent>/<ring> tag regardless of the agent's major
# line. On a v-scoped fleet (all stubs pin <agent>/v<M>-<ring>) that moved a tag nobody
# reads and still exited 0 — a silent no-op on the emergency lever. It must resolve the
# ring tag the SAME way cmd_promote/_resolved_channel do: prefer <agent>/v<M>-<ring>.

@test "orchestrator: rollback targets the v-scoped ring tag on a v-scoped agent, not the bare tier (#1103)" {
# The real shape from the issue: dev-lead on major 139, the v139-* family present.
# `rollback dev-lead stable --to v139.8.0` MUST target dev-lead/v139-stable — the tag the
# fleet stubs actually pin — never the bare dev-lead/stable that nobody reads.
_make_stub_bin
cat > "$STUB_BIN/gh" <<'GHEOF'
#!/usr/bin/env bash
case "$*" in
*"matching-refs/tags/dev-lead/v"*) echo "refs/tags/dev-lead/v139.8.0" ;; # → current major = 139
*"git/ref/tags/dev-lead/v139-stable"*) echo "90dcc01ca854d7acd65044bb8defcc32789a8335 commit" ;; # the pinned channel tag
*"git/ref/tags/dev-lead/v139.8.0"*) echo "90dcc01ca854d7acd65044bb8defcc32789a8335 commit" ;; # the release --to target
*"git/ref/tags/dev-lead/stable"*) echo "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef commit" ;; # bare tier — must NOT be targeted
*) echo "" ;;
esac
GHEOF
chmod +x "$STUB_BIN/gh"

# GITHUB_REPOSITORY=.github forces THIS_REPO=.github → dev-lead (host=.github-private) is cross-repo.
run env GITHUB_REPOSITORY="petry-projects/.github" CANARY_RINGS="$RINGS" \
bash "$ORCH" rollback dev-lead stable --to v139.8.0 --dry-run
[ "$status" -eq 0 ]
[[ "$output" == *"rolling back dev-lead/v139-stable"* ]]
[[ "$output" == *"refs/tags/dev-lead/v139-stable"* ]]
# The exact defect: the bare ring tag must never be the PATCH target.
[[ "$output" != *"refs/tags/dev-lead/stable"* ]]
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved

@test "orchestrator: rollback fails loudly when the resolved ring tag does not exist (no silent no-op) (#1103)" {
# dev-lead on major 139, release v139.8.0 present, but NEITHER the v-scoped channel tag
# v139-stable NOR the bare stable exists. Rollback must NOT create-and-move a tag nobody
# pins and exit 0 — it must fail with a clear error.
_make_stub_bin
cat > "$STUB_BIN/gh" <<'GHEOF'
#!/usr/bin/env bash
case "$*" in
*"matching-refs/tags/dev-lead/v"*) echo "refs/tags/dev-lead/v139.8.0" ;; # → current major = 139
*"git/ref/tags/dev-lead/v139.8.0"*) echo "90dcc01ca854d7acd65044bb8defcc32789a8335 commit" ;; # release --to resolves
*) echo "" ;; # every channel tag is absent
esac
GHEOF
chmod +x "$STUB_BIN/gh"

run env GITHUB_REPOSITORY="petry-projects/.github" CANARY_RINGS="$RINGS" \
bash "$ORCH" rollback dev-lead stable --to v139.8.0 --dry-run
[ "$status" -eq 1 ]
[[ "$output" == *"::error::"* ]]
# The resolution falls back to the bare tier (v-scoped absent), so the loud error names the
# resolved-but-absent tag and refuses — never a "[DRY-RUN] would … (force)" success line.
[[ "$output" == *"dev-lead/stable does not exist"* ]]
[[ "$output" != *"DRY-RUN"* ]]
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved

@test "orchestrator: rollback falls back to the bare ring tag when no v-scoped channel tag exists (#1103)" {
# Pre-F4 shape: releases exist (so a current major is derived) but the CHANNEL tags are
# still bare — v139-stable is absent, dev-lead/stable is what the fleet pins. Rollback must
# then move the bare tag, byte-identical to _resolved_channel's fall-back (matches promote).
_make_stub_bin
cat > "$STUB_BIN/gh" <<'GHEOF'
#!/usr/bin/env bash
case "$*" in
*"matching-refs/tags/dev-lead/v"*) echo "refs/tags/dev-lead/v139.8.0" ;; # → current major = 139
*"git/ref/tags/dev-lead/v139.8.0"*) echo "90dcc01ca854d7acd65044bb8defcc32789a8335 commit" ;; # release --to target
*"git/ref/tags/dev-lead/v139-stable"*) echo "" ;; # v-scoped channel tag ABSENT
*"git/ref/tags/dev-lead/stable"*) echo "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef commit" ;; # bare channel tag present
*) echo "" ;;
esac
GHEOF
chmod +x "$STUB_BIN/gh"

run env GITHUB_REPOSITORY="petry-projects/.github" CANARY_RINGS="$RINGS" \
bash "$ORCH" rollback dev-lead stable --to v139.8.0 --dry-run
[ "$status" -eq 0 ]
[[ "$output" == *"rolling back dev-lead/stable"* ]]
[[ "$output" == *"refs/tags/dev-lead/stable"* ]]
[[ "$output" != *"v139-stable"* ]]
}

# ── orchestrator: full graduated verdicts (cut date + gh run data → gate state) ─
# Lay out next = candidate (cccc); ring0/ring1/stable = prior (bbbb): frontier = ring0,
# transition next->ring0, source = next. The release tag cccc is dated `cut_days` ago,
Expand Down
Loading