Skip to content

feat(canary-rollout): gated scheduled fleet auto-promote (#1045 part b) + host-aware cross-repo tag moves (#1054) - #1056

Merged
don-petry merged 2 commits into
mainfrom
feat/canary-scheduled-autopromote
Jul 3, 2026
Merged

don-petry merged 2 commits into
mainfrom
feat/canary-scheduled-autopromote

Conversation

@don-petry

Copy link
Copy Markdown
Collaborator

What & why

Closes #1045 part b (gated scheduled auto-promote — the timer advances the fleet, no manual step) and #1054 (cross-repo PROMOTE failed with nonexistent object).

Part a (#1047) expanded the dispatch agent list. Part b makes the schedule do the promoting, gated by the soak standard (#548) — human approval is override-only, never a required gate.

Automation (#1045b)

  • promote-all (cmd_promote_all): iterates every registry agent and forwards to cmd_promote. Each PROMOTE-ready agent advances one ring per run; BLOCKED/REGRESSION agents are left untouched by the gate (no --override on the sweep). A per-agent failure is logged and skipped so one agent can't halt the fleet.
  • Workflow schedule: runs the gated auto-promote when the org variable CANARY_AUTO_PROMOTE == 'true' (promote-all, real move), else read-only evaluate-all. The arm variable is the single kill-switch. Dispatch gains evaluate-all/promote-all options (promote-all defaults to --dry-run).

Cross-repo fix (#1054)

  • _gh_move_tag: force-move/create a channel tag on a cross-repo agent's host via gh api (PATCH then POST) — the counterpart of git tag -f + push.
  • cmd_promote / cmd_rollback are now host-aware: THIS-repo agents move tags via local git; the 6 feat: implement issue #398 — Compliance: secret_scanning_ai_detection #482 reusables (hosted on petry-projects/.github) move via gh api. Local git tag -f failed with nonexistent object <sha> for a host commit absent from this checkout.

Tests

+3 bats — promote-all fleet iteration; cross-repo promote dry-run takes the host gh-api path (not local git); real cross-repo promote moves the host tag via gh api PATCH + records GITHUB_OUTPUT. 55/55 passing. bash -n + shellcheck clean; workflow YAML validated.

Rollout after merge

  1. Dispatch promote-all dry_run=true (observe verdicts), then dry_run=false — the two ring1→stable PROMOTE-ready reusables (dependabot-automerge, dependabot-rebase) advance on petry-projects/.github via cross-repo gh api.
  2. Arm the timer: gh variable set CANARY_AUTO_PROMOTE --org petry-projects --body true. Kill-switch = unset/flip to false.

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings July 3, 2026 17:19
@don-petry
don-petry requested a review from a team as a code owner July 3, 2026 17:19
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Jul 3, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

@don-petry, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 38 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: a738ef98-f884-443b-afc8-bdd14c367188

📥 Commits

Reviewing files that changed from the base of the PR and between 0e3fe87 and 27896e8.

📒 Files selected for processing (3)
  • .github/workflows/canary-rollout.yml
  • scripts/canary-rollout.sh
  • tests/canary_rollout.bats
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/canary-scheduled-autopromote

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@don-petry don-petry added the dev-lead For dev-lead agent pickup label Jul 3, 2026
@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — review-changes (no-changes)

No changes were needed for this PR.

@don-petry
don-petry enabled auto-merge (squash) July 3, 2026 17:20
@donpetry-bot

Copy link
Copy Markdown
Contributor

Advisory bots were rate-limited; auto-approval is withheld until they recover. pr-review-sweep will re-review this PR after 2026-07-03T18:22:10Z.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a fleet-wide promotion feature (promote-all) and adds support for cross-repository agents in canary-rollout.sh by moving channel tags on their respective hosts via the GitHub API instead of local git commands. Comprehensive tests have also been added to verify these changes. The review feedback highlights several critical shell scripting improvements: explicitly propagating failures in cmd_promote and cmd_rollback to prevent silent failures when set -e is suspended, validating positional parameters in _gh_move_tag to avoid crashes under set -u, and utilizing robust jq patterns (such as optional chaining and null-coalescing) to safely handle missing or null values in the JSON registry.

Comment thread scripts/canary-rollout.sh
Comment thread scripts/canary-rollout.sh
Comment thread scripts/canary-rollout.sh
Comment thread scripts/canary-rollout.sh
Comment thread scripts/canary-rollout.sh Outdated
Comment thread scripts/canary-rollout.sh

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the canary rollout automation to (1) support a gated, scheduled fleet-wide auto-promotion path and (2) correctly promote/rollback cross-repo agents by moving channel tags on the agent’s host repository via the GitHub API (fixing the nonexistent object failure mode for #482 reusables).

Changes:

  • Add promote-all orchestration to sweep all registry agents and attempt gated promotion (one ring per agent per run).
  • Make promote/rollback host-aware for cross-repo agents by introducing _gh_move_tag (PATCH then POST fallback) and using it when host != THIS_REPO.
  • Update the canary-rollout.yml schedule to run promote-all when vars.CANARY_AUTO_PROMOTE == 'true', otherwise run evaluate-all; add Bats coverage for fleet iteration and cross-repo tag moves.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
tests/canary_rollout.bats Adds Bats tests for promote-all fleet iteration and cross-repo promote behavior (dry-run + real tag move).
scripts/canary-rollout.sh Implements _gh_move_tag, host-aware promote/rollback paths, and new cmd_promote_all sweep command.
.github/workflows/canary-rollout.yml Arms the 4h schedule to run gated promote-all behind the CANARY_AUTO_PROMOTE org variable; expands dispatch commands accordingly.

Comment thread scripts/canary-rollout.sh Outdated
@don-petry
don-petry disabled auto-merge July 3, 2026 17:23
@don-petry
don-petry enabled auto-merge (squash) July 3, 2026 17:30
@don-petry
don-petry disabled auto-merge July 3, 2026 17:44
@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — rate-limited (intent: fix-reviews)

PR: #1056
The retry cron will re-attempt automatically.

@don-petry
don-petry enabled auto-merge (squash) July 3, 2026 17:51
@don-petry
don-petry disabled auto-merge July 3, 2026 19:46
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 3, 2026
@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — fix-reviews (applied)

Changes committed and pushed.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 3, 2026
@don-petry
don-petry disabled auto-merge July 3, 2026 19:52
@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — waiting on PR blockers (intent: fix-reviews)

PR: #1056
No changes were committed, but the PR still has blocking checks or reviews (failing or cancelled checks, or changes-requested reviews). The retry cron will re-attempt automatically. Next attempt after: 2026-07-03T20:22:30Z

@don-petry
don-petry enabled auto-merge (squash) July 3, 2026 19:52
@don-petry

Copy link
Copy Markdown
Collaborator Author

Auto-rebase failed — merge conflict — this branch has conflicts with main that must be resolved.

dev-lead will attempt to resolve this automatically. If it cannot, a follow-up comment will explain what needs manual attention.

To resolve manually instead:

git fetch origin
git merge origin/main
# resolve conflicts, then:
git add .
git commit
git push

@don-petry
don-petry disabled auto-merge July 3, 2026 19:53
@donpetry-bot

donpetry-bot commented Jul 3, 2026 •

Copy link
Copy Markdown
Contributor
Superseded by automated re-review at 3aea9b9790438beedc9f99ca5049ce8b8c3b2543 — click to expand prior review.

Review — fix requested (cycle 1/3)

The automated review identified the following issues. Please address each one:

Findings to fix

Automated review — NEEDS HUMAN REVIEW

Risk: MEDIUM
Reviewed commit: 3aea9b9790438beedc9f99ca5049ce8b8c3b2543
Cascade: triage → deep (triage: haiku 4.5 → deep: opus 4.8 + duck: o4-mini → audit: fable 5)

Summary

PR #1056 gates a scheduled fleet auto-promote (promote-all) and makes promote/rollback host-aware so cross-repo agents move channel tags via gh api instead of local git. The shell-safety findings the advisory bots raised (set -e suspension, null-unsafe jq host lookups, missing arg guards) are all addressed at the current head 3aea9b9 — git moves are explicitly guarded with || return 1, jq uses // "" | tostring, and _gh_move_tag validates arg count. Not approvable: the PR is CONFLICTING/DIRTY (merge-conflict gate failure) and must be rebased before merge. Downstream impact: (none).

Findings

  • MAJOR: PR is mergeable=CONFLICTING / mergeStateStatus=DIRTY — has merge conflicts against main and cannot be merged as-is. Blocking gate failure; requires rebase/conflict resolution before merge.
  • INFO: Advisory CRITICAL/HIGH findings (set -e suspension when cmd_promote runs under cmd_promote_all's || ) appear resolved: local git tag/push are guarded with && ... || { echo ::error...; return 1; }, so a git failure returns 1 explicitly instead of falling through to the success message and GITHUB_OUTPUT write.
  • INFO: Null-unsafe jq host lookups flagged by advisory bots are resolved: cmd_promote and cmd_rollback both use .agents[$a].host // "" | tostring, avoiding a literal "null" that would wrongly set cross=true.
  • INFO: _gh_move_tag guards against unbound positional params under set -u with [ $# -lt 3 ] && return 1, addressing the advisory arg-validation finding.
  • MINOR: Scheduled arm now performs REAL cross-repo tag force-moves (DRY_RUN=false) on the 4h timer whenever org var CANARY_AUTO_PROMOTE=='true'. Only kill-switch is that single org variable; only PROMOTE-ready agents advance (gate-guarded, no --override on the sweep). Intended per #1045b, but note the un-gated-by-human real-move path when reviewing.
  • INFO: CI is green (shellcheck, bats 55/55, CodeQL, gitleaks, SonarCloud quality gate all SUCCESS; CANCELLED checks are superseded reruns). coderabbitai APPROVED. run_secret_scanning MCP tool not exposed in this environment, so not invoked; no secrets present in the diff.

Reviewed by the PR-review cascade (triage: haiku 4.5 → deep: opus 4.8 + duck: o4-mini → audit: fable 5). Reply if you need a human review.

Additional tasks

  1. Resolve all unresolved review thread comments from other reviewers
  2. Ensure all CI checks pass after your changes
  3. Rebase on the target branch if behind
  4. Do NOT modify files unrelated to the findings above

The review cascade will automatically re-review after new commits are pushed.

@donpetry-bot

donpetry-bot commented Jul 3, 2026 •

Copy link
Copy Markdown
Contributor
Superseded by automated re-review at 27896e819399ae83b75b6335273dcd874a12a3eb — click to expand prior review.

Review — fix requested (cycle 1/3)

The automated review identified the following issues. Please address each one:

Findings to fix

Automated review — NEEDS HUMAN REVIEW

Risk: MEDIUM
Reviewed commit: 3aea9b9790438beedc9f99ca5049ce8b8c3b2543
Cascade: triage → deep (triage: haiku 4.5 → deep: opus 4.8 + duck: o4-mini → audit: fable 5)

Summary

Adds gated scheduled fleet auto-promote (cmd_promote_all) and host-aware cross-repo tag moves via gh api (_gh_move_tag) for canary-rollout, with +3 bats (55/55) and green CI. Verified against the head diff, every advisory finding triage escalated on is ALREADY fixed at head: the jq host lookup uses the // "" | tostring null guard in both cmd_promote and cmd_rollback, _gh_move_tag validates [ $# -lt 3 ] && return 1, and all local git and gh-api moves are explicitly guarded with || { ...; return 1; } so they cannot silently succeed under a suspended set -e in the promote-all sweep. Not approving because the PR is not mergeable — mergeStateStatus=DIRTY / mergeable=CONFLICTING (needs rebase onto main); no security escalation warranted. Downstream impact: (none). Secret-scanning MCP tool not available in this environment; skipped (diff is shell logic with no secret material).

Findings

  • MAJOR: PR is not mergeable: mergeStateStatus=DIRTY, mergeable=CONFLICTING. Must be rebased onto main and conflicts resolved before it can merge. This is the sole blocking gate; withhold approval until resolved.
  • INFO: Gemini HIGH (jq null handling, lines 505/570): RESOLVED at head. Code reads host="$(_jq -r --arg a "$agent" '.agents[$a].host // "" | tostring')" — the // "" fallback maps a missing agent/host to empty (not the literal "null"), so cross stays false. Also safer than the suggested string-interpolated jq because it uses --arg (no injection).
  • INFO: Gemini CRITICAL (silent failure under suspended set -e when promote-all calls cmd_promote ... || ..., line 522): RESOLVED at head. Both the cross-repo (_gh_move_tag ... || { ...; return 1; }) and local (git tag -f ... && git push ... || { ...; return 1; }) branches explicitly return 1 on failure, so a failed move can no longer fall through to the 'promoted' message or GITHUB_OUTPUT.
  • INFO: Gemini MEDIUM (cmd_rollback lacks explicit error guards, line 594): RESOLVED at head. cmd_rollback mirrors cmd_promote with the same || { ...; return 1; } guards on both the gh-api and local git move paths, and is host-aware for the target lookup (_gh_tag_commit for cross-repo).
  • INFO: Gemini HIGH (_gh_move_tag unbound-variable crash under set -u, line 106): RESOLVED at head. Function opens with [ $# -lt 3 ] && return 1 before positional assignment.
  • INFO: CI is effectively green: shellcheck, bats, unit-tests, CodeQL, SonarCloud, gitleaks, AgentShield all SUCCESS. The CANCELLED review/dev-lead checks are superseded concurrency duplicates, not failures.
  • MINOR: Behavioral note (not blocking): the schedule arm now performs REAL cross-repo force tag moves (DRY_RUN=false) when org var CANARY_AUTO_PROMOTE=='true'. Force-move via gh api PATCH .../git/refs/tags -F force=true on petry-projects/.github is intentional and gated by the kill-switch (defaults to read-only evaluate-all when unset). Dispatch inputs are choice-constrained / passed as quoted env vars — no command injection. Acceptable by design (#1045b/feat: implement issue #545 — Compliance: non-stub-dependency-audit.yml #548).

Reviewed by the PR-review cascade (triage: haiku 4.5 → deep: opus 4.8 + duck: o4-mini → audit: fable 5). Reply if you need a human review.

Additional tasks

  1. Resolve all unresolved review thread comments from other reviewers
  2. Ensure all CI checks pass after your changes
  3. Rebase on the target branch if behind
  4. Do NOT modify files unrelated to the findings above

The review cascade will automatically re-review after new commits are pushed.

@don-petry

Copy link
Copy Markdown
Collaborator Author

Auto-rebase failed — merge conflict — this branch has conflicts with main that must be resolved.

dev-lead will attempt to resolve this automatically. If it cannot, a follow-up comment will explain what needs manual attention.

To resolve manually instead:

git fetch origin
git merge origin/main
# resolve conflicts, then:
git add .
git commit
git push

@sonarqubecloud

sonarqubecloud Bot commented Jul 3, 2026

Copy link
Copy Markdown

@don-petry
don-petry disabled auto-merge July 3, 2026 20:03
@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — fix-bot-comment (no-changes)

Agent reasoning
2. **Review Threads**: All threads from automated reviewers (Gemini, Copilot) are marked as `isResolved: true`. The code changes already addressed all the feedback:
   - `cmd_promote` / `cmd_rollback` failure propagation with `|| return 1` guards ✅
   - `_gh_move_tag` parameter validation ✅
   - Safe jq patterns with `// ""` and `?` operators for null handling ✅
   - `cmd_promote_all` fleet iteration with optional chaining ✅
3. **CI Status**: All checks pass; the two "cancelled" dev-lead checks are documented as "superseded concurrency duplicates, not failures" in the PR comments.
4. **First-party Channel Refs**: No SHA-pinned mutable channel refs found in changed workflow files.
**Issues addressed:** 0  
**Files changed:** 0  
No action needed — the PR is clean and all review feedback has been addressed and resolved.

@don-petry
don-petry enabled auto-merge (squash) July 3, 2026 20:05
@don-petry
don-petry merged commit 851f25d into main Jul 3, 2026
29 of 31 checks passed
@don-petry
don-petry deleted the feat/canary-scheduled-autopromote branch July 3, 2026 20:05

@donpetry-bot donpetry-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review — APPROVED ✓

Risk: MEDIUM
Reviewed commit: 27896e819399ae83b75b6335273dcd874a12a3eb
Review mode: triage-approved (single reviewer)

Summary

Re-review at 27896e8 (cycle 2/3) after the cycle-1 fix-requested review at 3aea9b9. The sole blocking finding from the prior review — merge conflicts (mergeable=CONFLICTING / DIRTY) — is resolved: the branch was rebased onto main and is now MERGEABLE (state BEHIND, no conflicts). All shell-safety guards the prior review verified survive the rebase at the current head: _gh_move_tag validates arg count, cmd_promote/cmd_rollback use the null-safe jq host lookup (.agents[$a].host // "" | tostring) and explicitly guard both the gh-api and local git move paths with || { ...; return 1; } so failures cannot fall through under a suspended set -e in the promote-all sweep. All 7 review threads are resolved and CI is green (bats 55/55, shellcheck, CodeQL, gitleaks, SonarCloud quality gate).

Linked issue analysis

No formal closingIssuesReferences, but the PR body targets #1045 part b (gated scheduled fleet auto-promote) and #1054 (cross-repo PROMOTE via host gh api instead of local git). Both are substantively implemented: cmd_promote_all iterates the registry and forwards to the gated cmd_promote (one ring per run, per-agent failures logged and skipped), the schedule arm is gated on org var CANARY_AUTO_PROMOTE with read-only evaluate-all as the default, and cmd_promote/cmd_rollback are host-aware with _gh_move_tag (PATCH-then-POST) for cross-repo agents. Three new bats tests cover the fleet sweep, the cross-repo dry-run path, and the real cross-repo move + GITHUB_OUTPUT recording.

Findings

  • RESOLVED (prior MAJOR): merge conflicts against main — branch rebased and pushed (head 27896e8); PR is now MERGEABLE. mergeStateStatus is BEHIND (main moved again), which auto-rebase handles; not a blocking gate.
  • RESOLVED (prior advisory findings, verified at head): _gh_move_tag guards [ $# -lt 3 ] && return 1; jq host lookups use --arg with // "" | tostring (no literal "null" mis-setting cross=true); both promote and rollback move paths return 1 explicitly on failure with ::error output.
  • NO NEW ISSUES since the prior review: the rebase reconciled this PR with main's #1055 (which merged a first cut of the #1054 fix); this PR's simplified _gh_move_tag (PATCH-then-POST fallback instead of GET-then-PATCH/POST) is functionally equivalent with one fewer API call, and callers guard its failure.
  • MINOR (carried, by design): when org var CANARY_AUTO_PROMOTE=='true', the 4h schedule performs REAL force tag moves (DRY_RUN=false) gated only by the promotion gate; the single org variable is the kill-switch and dispatch promote/promote-all default to --dry-run. Intended per #1045b/#548.
  • Secret scan: run_secret_scanning MCP tool not available in this environment; skipped. Gitleaks CI check passed and the diff contains no secret material.

CI status

All required checks SUCCESS: shellcheck (x2), bats, unit-tests, Lint, CodeQL (actions + python), gitleaks, SonarCloud quality gate, AgentShield, Agent Security Scan, holdout-guard, template-drift, gh-aw-compile, validate-agent-profiles, CodeRabbit. CANCELLED entries (dev-lead / dispatch, dev-lead / ci-relay) are superseded automation reruns, not failures; dependency-audit language jobs SKIPPED (no matching ecosystems).


Reviewed automatically by the PR-review agent (single-reviewer mode: fable 5). Reply if you need a human review.

@donpetry-bot donpetry-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review — APPROVED ✓

Risk: MEDIUM
Reviewed commit: 27896e819399ae83b75b6335273dcd874a12a3eb
Review mode: triage-approved (single reviewer)

Summary

PR #1056 implements the gated scheduled fleet auto-promote (#1045 part b) and fixes cross-repo PROMOTE/rollback (#1054) by making tag moves host-aware (_gh_move_tag via gh api for cross-repo agents, local git otherwise). This is a cycle-2 re-review: the prior review's sole blocking finding (merge conflict against main) is resolved — the branch was rebased and is now MERGEABLE. All advisory-bot findings from cycle 1 remain fixed at the current head, all 7 review threads are resolved, and CI is green (shellcheck, bats 55/55, CodeQL, gitleaks, SonarCloud all SUCCESS).

Linked issue analysis

  • #1045 (part b): substantively addressed. The 4h schedule now runs promote-all when org var CANARY_AUTO_PROMOTE == 'true' (real move, gate-decided, one ring per run, no --override on the sweep) and falls back to read-only evaluate-all otherwise — the arm variable is the single kill-switch, matching the issue's gated-scheduled-promote model. Part a (dispatch agent list) was handled in #1047.
  • #1054: substantively addressed. cmd_promote and cmd_rollback are host-aware: cross-repo agents (host ≠ THIS_REPO) move channel tags on their host via gh api PATCH-then-POST (_gh_move_tag), fixing the "nonexistent object" failure; this-repo agents keep the local git path. Covered by 3 new bats tests including a real-move assertion that the host API is hit and local git never is.

Findings

  • RESOLVED (prior MAJOR): merge conflict against main — the branch was rebased (dev-lead rebase applied) and the PR is now mergeable=MERGEABLE. mergeStateStatus=BEHIND is not blocking; the repo's auto-rebase automation brings branches up to date before merge.
  • VERIFIED (prior cycle-1 advisory findings, still fixed at head): git/gh-api moves guarded with || { ::error; return 1; } so failures cannot fall through under promote-all's suspended set -e; jq host lookups use .agents[$a].host // "" | tostring (null-safe, --arg — no injection); _gh_move_tag validates arg count under set -u. All 7 gemini/copilot review threads are marked resolved.
  • MINOR (non-blocking): _gh_move_tag suppresses gh api stderr (2>&1 >/dev/null), so PATCH/POST error details are lost — callers do emit ::error with agent/tag context, which is sufficient for triage.
  • NOTE (by design): the scheduled arm performs REAL cross-repo force tag moves (DRY_RUN=false) whenever CANARY_AUTO_PROMOTE=='true'; only PROMOTE-ready agents advance and BLOCKED/REGRESSION agents are untouched. Intentional per #1045b/#548; dispatch inputs are choice-constrained and passed as quoted env vars — no injection surface.
  • Secret scan: run_secret_scanning MCP tool not available in this environment — skipped; gitleaks CI check is SUCCESS and the diff contains no secret material.

CI status

Green at head 27896e81: shellcheck, ShellCheck, bats, unit-tests, Lint, CodeQL, Analyze (actions/python), SonarCloud quality gate, Secret scan (gitleaks), AgentShield, Agent Security Scan, holdout-guard, template-drift, guard, gh-aw-compile, validate-agent-profiles — all SUCCESS. The two CANCELLED checks (dev-lead / dispatch, dev-lead / ci-relay) are superseded automation-agent concurrency duplicates, not correctness checks; dependency-audit jobs SKIPPED (no matching ecosystems).


Reviewed automatically by the PR-review agent (single-reviewer mode: fable 5). Reply if you need a human review.

don-petry added a commit that referenced this pull request Aug 2, 2026
…b) + host-aware cross-repo tag moves (#1054) (#1056)

* feat(canary-rollout): gated scheduled fleet auto-promote (#1045 part b) + host-aware cross-repo tag moves (#1054)

Implements #1045 part b — the timer advances the fleet, no manual step.

Automation:
- promote-all subcommand (cmd_promote_all): iterates every registry agent
  and forwards to cmd_promote, so each PROMOTE-ready agent advances exactly
  one ring per run while BLOCKED/REGRESSION agents are left untouched by the
  gate. A per-agent failure is logged and skipped so one agent cannot halt
  the fleet sweep. Human approval stays OVERRIDE-ONLY, never a required gate.
- workflow: schedule now runs the gated auto-promote when the org variable
  CANARY_AUTO_PROMOTE == 'true' (promote-all, real move), else read-only
  evaluate-all. The arm variable is the single kill-switch. dispatch gains
  evaluate-all/promote-all options (promote-all defaults to --dry-run).

Cross-repo fix (#1054):
- _gh_move_tag: force-move/create a channel tag on a cross-repo agent's HOST
  via gh api (PATCH then POST), the counterpart of `git tag -f` + push.
- cmd_promote / cmd_rollback are now host-aware: an agent hosted in THIS repo
  moves its tag via local git; a cross-repo agent (the 6 #482 reusables on
  petry-projects/.github) moves it on its host via gh api — local `git tag -f`
  failed with "nonexistent object" for a host commit absent from this checkout.

Tests: +3 bats (promote-all fleet iteration; cross-repo promote dry-run takes
the host gh-api path not local git; real cross-repo promote moves the host tag
via gh api PATCH + records the GITHUB_OUTPUT). 55/55 passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 3, 2026
…b) + host-aware cross-repo tag moves (#1054) (#1056)

* feat(canary-rollout): gated scheduled fleet auto-promote (#1045 part b) + host-aware cross-repo tag moves (#1054)

Implements #1045 part b — the timer advances the fleet, no manual step.

Automation:
- promote-all subcommand (cmd_promote_all): iterates every registry agent
  and forwards to cmd_promote, so each PROMOTE-ready agent advances exactly
  one ring per run while BLOCKED/REGRESSION agents are left untouched by the
  gate. A per-agent failure is logged and skipped so one agent cannot halt
  the fleet sweep. Human approval stays OVERRIDE-ONLY, never a required gate.
- workflow: schedule now runs the gated auto-promote when the org variable
  CANARY_AUTO_PROMOTE == 'true' (promote-all, real move), else read-only
  evaluate-all. The arm variable is the single kill-switch. dispatch gains
  evaluate-all/promote-all options (promote-all defaults to --dry-run).

Cross-repo fix (#1054):
- _gh_move_tag: force-move/create a channel tag on a cross-repo agent's HOST
  via gh api (PATCH then POST), the counterpart of `git tag -f` + push.
- cmd_promote / cmd_rollback are now host-aware: an agent hosted in THIS repo
  moves its tag via local git; a cross-repo agent (the 6 #482 reusables on
  petry-projects/.github) moves it on its host via gh api — local `git tag -f`
  failed with "nonexistent object" for a host commit absent from this checkout.

Tests: +3 bats (promote-all fleet iteration; cross-repo promote dry-run takes
the host gh-api path not local git; real cross-repo promote moves the host tag
via gh api PATCH + records the GITHUB_OUTPUT). 55/55 passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 3, 2026
…b) + host-aware cross-repo tag moves (#1054) (#1056)

* feat(canary-rollout): gated scheduled fleet auto-promote (#1045 part b) + host-aware cross-repo tag moves (#1054)

Implements #1045 part b — the timer advances the fleet, no manual step.

Automation:
- promote-all subcommand (cmd_promote_all): iterates every registry agent
  and forwards to cmd_promote, so each PROMOTE-ready agent advances exactly
  one ring per run while BLOCKED/REGRESSION agents are left untouched by the
  gate. A per-agent failure is logged and skipped so one agent cannot halt
  the fleet sweep. Human approval stays OVERRIDE-ONLY, never a required gate.
- workflow: schedule now runs the gated auto-promote when the org variable
  CANARY_AUTO_PROMOTE == 'true' (promote-all, real move), else read-only
  evaluate-all. The arm variable is the single kill-switch. dispatch gains
  evaluate-all/promote-all options (promote-all defaults to --dry-run).

Cross-repo fix (#1054):
- _gh_move_tag: force-move/create a channel tag on a cross-repo agent's HOST
  via gh api (PATCH then POST), the counterpart of `git tag -f` + push.
- cmd_promote / cmd_rollback are now host-aware: an agent hosted in THIS repo
  moves its tag via local git; a cross-repo agent (the 6 #482 reusables on
  petry-projects/.github) moves it on its host via gh api — local `git tag -f`
  failed with "nonexistent object" for a host commit absent from this checkout.

Tests: +3 bats (promote-all fleet iteration; cross-repo promote dry-run takes
the host gh-api path not local git; real cross-repo promote moves the host tag
via gh api PATCH + records the GITHUB_OUTPUT). 55/55 passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 3, 2026
…b) + host-aware cross-repo tag moves (#1054) (#1056)

* feat(canary-rollout): gated scheduled fleet auto-promote (#1045 part b) + host-aware cross-repo tag moves (#1054)

Implements #1045 part b — the timer advances the fleet, no manual step.

Automation:
- promote-all subcommand (cmd_promote_all): iterates every registry agent
  and forwards to cmd_promote, so each PROMOTE-ready agent advances exactly
  one ring per run while BLOCKED/REGRESSION agents are left untouched by the
  gate. A per-agent failure is logged and skipped so one agent cannot halt
  the fleet sweep. Human approval stays OVERRIDE-ONLY, never a required gate.
- workflow: schedule now runs the gated auto-promote when the org variable
  CANARY_AUTO_PROMOTE == 'true' (promote-all, real move), else read-only
  evaluate-all. The arm variable is the single kill-switch. dispatch gains
  evaluate-all/promote-all options (promote-all defaults to --dry-run).

Cross-repo fix (#1054):
- _gh_move_tag: force-move/create a channel tag on a cross-repo agent's HOST
  via gh api (PATCH then POST), the counterpart of `git tag -f` + push.
- cmd_promote / cmd_rollback are now host-aware: an agent hosted in THIS repo
  moves its tag via local git; a cross-repo agent (the 6 #482 reusables on
  petry-projects/.github) moves it on its host via gh api — local `git tag -f`
  failed with "nonexistent object" for a host commit absent from this checkout.

Tests: +3 bats (promote-all fleet iteration; cross-repo promote dry-run takes
the host gh-api path not local git; real cross-repo promote moves the host tag
via gh api PATCH + records the GITHUB_OUTPUT). 55/55 passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
…b) + host-aware cross-repo tag moves (#1054) (#1056)

* feat(canary-rollout): gated scheduled fleet auto-promote (#1045 part b) + host-aware cross-repo tag moves (#1054)

Implements #1045 part b — the timer advances the fleet, no manual step.

Automation:
- promote-all subcommand (cmd_promote_all): iterates every registry agent
  and forwards to cmd_promote, so each PROMOTE-ready agent advances exactly
  one ring per run while BLOCKED/REGRESSION agents are left untouched by the
  gate. A per-agent failure is logged and skipped so one agent cannot halt
  the fleet sweep. Human approval stays OVERRIDE-ONLY, never a required gate.
- workflow: schedule now runs the gated auto-promote when the org variable
  CANARY_AUTO_PROMOTE == 'true' (promote-all, real move), else read-only
  evaluate-all. The arm variable is the single kill-switch. dispatch gains
  evaluate-all/promote-all options (promote-all defaults to --dry-run).

Cross-repo fix (#1054):
- _gh_move_tag: force-move/create a channel tag on a cross-repo agent's HOST
  via gh api (PATCH then POST), the counterpart of `git tag -f` + push.
- cmd_promote / cmd_rollback are now host-aware: an agent hosted in THIS repo
  moves its tag via local git; a cross-repo agent (the 6 #482 reusables on
  petry-projects/.github) moves it on its host via gh api — local `git tag -f`
  failed with "nonexistent object" for a host commit absent from this checkout.

Tests: +3 bats (promote-all fleet iteration; cross-repo promote dry-run takes
the host gh-api path not local git; real cross-repo promote moves the host tag
via gh api PATCH + records the GITHUB_OUTPUT). 55/55 passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
…b) + host-aware cross-repo tag moves (#1054) (#1056)

* feat(canary-rollout): gated scheduled fleet auto-promote (#1045 part b) + host-aware cross-repo tag moves (#1054)

Implements #1045 part b — the timer advances the fleet, no manual step.

Automation:
- promote-all subcommand (cmd_promote_all): iterates every registry agent
  and forwards to cmd_promote, so each PROMOTE-ready agent advances exactly
  one ring per run while BLOCKED/REGRESSION agents are left untouched by the
  gate. A per-agent failure is logged and skipped so one agent cannot halt
  the fleet sweep. Human approval stays OVERRIDE-ONLY, never a required gate.
- workflow: schedule now runs the gated auto-promote when the org variable
  CANARY_AUTO_PROMOTE == 'true' (promote-all, real move), else read-only
  evaluate-all. The arm variable is the single kill-switch. dispatch gains
  evaluate-all/promote-all options (promote-all defaults to --dry-run).

Cross-repo fix (#1054):
- _gh_move_tag: force-move/create a channel tag on a cross-repo agent's HOST
  via gh api (PATCH then POST), the counterpart of `git tag -f` + push.
- cmd_promote / cmd_rollback are now host-aware: an agent hosted in THIS repo
  moves its tag via local git; a cross-repo agent (the 6 #482 reusables on
  petry-projects/.github) moves it on its host via gh api — local `git tag -f`
  failed with "nonexistent object" for a host commit absent from this checkout.

Tests: +3 bats (promote-all fleet iteration; cross-repo promote dry-run takes
the host gh-api path not local git; real cross-repo promote moves the host tag
via gh api PATCH + records the GITHUB_OUTPUT). 55/55 passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
…b) + host-aware cross-repo tag moves (#1054) (#1056)

* feat(canary-rollout): gated scheduled fleet auto-promote (#1045 part b) + host-aware cross-repo tag moves (#1054)

Implements #1045 part b — the timer advances the fleet, no manual step.

Automation:
- promote-all subcommand (cmd_promote_all): iterates every registry agent
  and forwards to cmd_promote, so each PROMOTE-ready agent advances exactly
  one ring per run while BLOCKED/REGRESSION agents are left untouched by the
  gate. A per-agent failure is logged and skipped so one agent cannot halt
  the fleet sweep. Human approval stays OVERRIDE-ONLY, never a required gate.
- workflow: schedule now runs the gated auto-promote when the org variable
  CANARY_AUTO_PROMOTE == 'true' (promote-all, real move), else read-only
  evaluate-all. The arm variable is the single kill-switch. dispatch gains
  evaluate-all/promote-all options (promote-all defaults to --dry-run).

Cross-repo fix (#1054):
- _gh_move_tag: force-move/create a channel tag on a cross-repo agent's HOST
  via gh api (PATCH then POST), the counterpart of `git tag -f` + push.
- cmd_promote / cmd_rollback are now host-aware: an agent hosted in THIS repo
  moves its tag via local git; a cross-repo agent (the 6 #482 reusables on
  petry-projects/.github) moves it on its host via gh api — local `git tag -f`
  failed with "nonexistent object" for a host commit absent from this checkout.

Tests: +3 bats (promote-all fleet iteration; cross-repo promote dry-run takes
the host gh-api path not local git; real cross-repo promote moves the host tag
via gh api PATCH + records the GITHUB_OUTPUT). 55/55 passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
…b) + host-aware cross-repo tag moves (#1054) (#1056)

* feat(canary-rollout): gated scheduled fleet auto-promote (#1045 part b) + host-aware cross-repo tag moves (#1054)

Implements #1045 part b — the timer advances the fleet, no manual step.

Automation:
- promote-all subcommand (cmd_promote_all): iterates every registry agent
  and forwards to cmd_promote, so each PROMOTE-ready agent advances exactly
  one ring per run while BLOCKED/REGRESSION agents are left untouched by the
  gate. A per-agent failure is logged and skipped so one agent cannot halt
  the fleet sweep. Human approval stays OVERRIDE-ONLY, never a required gate.
- workflow: schedule now runs the gated auto-promote when the org variable
  CANARY_AUTO_PROMOTE == 'true' (promote-all, real move), else read-only
  evaluate-all. The arm variable is the single kill-switch. dispatch gains
  evaluate-all/promote-all options (promote-all defaults to --dry-run).

Cross-repo fix (#1054):
- _gh_move_tag: force-move/create a channel tag on a cross-repo agent's HOST
  via gh api (PATCH then POST), the counterpart of `git tag -f` + push.
- cmd_promote / cmd_rollback are now host-aware: an agent hosted in THIS repo
  moves its tag via local git; a cross-repo agent (the 6 #482 reusables on
  petry-projects/.github) moves it on its host via gh api — local `git tag -f`
  failed with "nonexistent object" for a host commit absent from this checkout.

Tests: +3 bats (promote-all fleet iteration; cross-repo promote dry-run takes
the host gh-api path not local git; real cross-repo promote moves the host tag
via gh api PATCH + records the GITHUB_OUTPUT). 55/55 passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
…b) + host-aware cross-repo tag moves (#1054) (#1056)

* feat(canary-rollout): gated scheduled fleet auto-promote (#1045 part b) + host-aware cross-repo tag moves (#1054)

Implements #1045 part b — the timer advances the fleet, no manual step.

Automation:
- promote-all subcommand (cmd_promote_all): iterates every registry agent
  and forwards to cmd_promote, so each PROMOTE-ready agent advances exactly
  one ring per run while BLOCKED/REGRESSION agents are left untouched by the
  gate. A per-agent failure is logged and skipped so one agent cannot halt
  the fleet sweep. Human approval stays OVERRIDE-ONLY, never a required gate.
- workflow: schedule now runs the gated auto-promote when the org variable
  CANARY_AUTO_PROMOTE == 'true' (promote-all, real move), else read-only
  evaluate-all. The arm variable is the single kill-switch. dispatch gains
  evaluate-all/promote-all options (promote-all defaults to --dry-run).

Cross-repo fix (#1054):
- _gh_move_tag: force-move/create a channel tag on a cross-repo agent's HOST
  via gh api (PATCH then POST), the counterpart of `git tag -f` + push.
- cmd_promote / cmd_rollback are now host-aware: an agent hosted in THIS repo
  moves its tag via local git; a cross-repo agent (the 6 #482 reusables on
  petry-projects/.github) moves it on its host via gh api — local `git tag -f`
  failed with "nonexistent object" for a host commit absent from this checkout.

Tests: +3 bats (promote-all fleet iteration; cross-repo promote dry-run takes
the host gh-api path not local git; real cross-repo promote moves the host tag
via gh api PATCH + records the GITHUB_OUTPUT). 55/55 passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
…b) + host-aware cross-repo tag moves (#1054) (#1056)

* feat(canary-rollout): gated scheduled fleet auto-promote (#1045 part b) + host-aware cross-repo tag moves (#1054)

Implements #1045 part b — the timer advances the fleet, no manual step.

Automation:
- promote-all subcommand (cmd_promote_all): iterates every registry agent
  and forwards to cmd_promote, so each PROMOTE-ready agent advances exactly
  one ring per run while BLOCKED/REGRESSION agents are left untouched by the
  gate. A per-agent failure is logged and skipped so one agent cannot halt
  the fleet sweep. Human approval stays OVERRIDE-ONLY, never a required gate.
- workflow: schedule now runs the gated auto-promote when the org variable
  CANARY_AUTO_PROMOTE == 'true' (promote-all, real move), else read-only
  evaluate-all. The arm variable is the single kill-switch. dispatch gains
  evaluate-all/promote-all options (promote-all defaults to --dry-run).

Cross-repo fix (#1054):
- _gh_move_tag: force-move/create a channel tag on a cross-repo agent's HOST
  via gh api (PATCH then POST), the counterpart of `git tag -f` + push.
- cmd_promote / cmd_rollback are now host-aware: an agent hosted in THIS repo
  moves its tag via local git; a cross-repo agent (the 6 #482 reusables on
  petry-projects/.github) moves it on its host via gh api — local `git tag -f`
  failed with "nonexistent object" for a host commit absent from this checkout.

Tests: +3 bats (promote-all fleet iteration; cross-repo promote dry-run takes
the host gh-api path not local git; real cross-repo promote moves the host tag
via gh api PATCH + records the GITHUB_OUTPUT). 55/55 passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
…b) + host-aware cross-repo tag moves (#1054) (#1056)

* feat(canary-rollout): gated scheduled fleet auto-promote (#1045 part b) + host-aware cross-repo tag moves (#1054)

Implements #1045 part b — the timer advances the fleet, no manual step.

Automation:
- promote-all subcommand (cmd_promote_all): iterates every registry agent
  and forwards to cmd_promote, so each PROMOTE-ready agent advances exactly
  one ring per run while BLOCKED/REGRESSION agents are left untouched by the
  gate. A per-agent failure is logged and skipped so one agent cannot halt
  the fleet sweep. Human approval stays OVERRIDE-ONLY, never a required gate.
- workflow: schedule now runs the gated auto-promote when the org variable
  CANARY_AUTO_PROMOTE == 'true' (promote-all, real move), else read-only
  evaluate-all. The arm variable is the single kill-switch. dispatch gains
  evaluate-all/promote-all options (promote-all defaults to --dry-run).

Cross-repo fix (#1054):
- _gh_move_tag: force-move/create a channel tag on a cross-repo agent's HOST
  via gh api (PATCH then POST), the counterpart of `git tag -f` + push.
- cmd_promote / cmd_rollback are now host-aware: an agent hosted in THIS repo
  moves its tag via local git; a cross-repo agent (the 6 #482 reusables on
  petry-projects/.github) moves it on its host via gh api — local `git tag -f`
  failed with "nonexistent object" for a host commit absent from this checkout.

Tests: +3 bats (promote-all fleet iteration; cross-repo promote dry-run takes
the host gh-api path not local git; real cross-repo promote moves the host tag
via gh api PATCH + records the GITHUB_OUTPUT). 55/55 passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
…b) + host-aware cross-repo tag moves (#1054) (#1056)

* feat(canary-rollout): gated scheduled fleet auto-promote (#1045 part b) + host-aware cross-repo tag moves (#1054)

Implements #1045 part b — the timer advances the fleet, no manual step.

Automation:
- promote-all subcommand (cmd_promote_all): iterates every registry agent
  and forwards to cmd_promote, so each PROMOTE-ready agent advances exactly
  one ring per run while BLOCKED/REGRESSION agents are left untouched by the
  gate. A per-agent failure is logged and skipped so one agent cannot halt
  the fleet sweep. Human approval stays OVERRIDE-ONLY, never a required gate.
- workflow: schedule now runs the gated auto-promote when the org variable
  CANARY_AUTO_PROMOTE == 'true' (promote-all, real move), else read-only
  evaluate-all. The arm variable is the single kill-switch. dispatch gains
  evaluate-all/promote-all options (promote-all defaults to --dry-run).

Cross-repo fix (#1054):
- _gh_move_tag: force-move/create a channel tag on a cross-repo agent's HOST
  via gh api (PATCH then POST), the counterpart of `git tag -f` + push.
- cmd_promote / cmd_rollback are now host-aware: an agent hosted in THIS repo
  moves its tag via local git; a cross-repo agent (the 6 #482 reusables on
  petry-projects/.github) moves it on its host via gh api — local `git tag -f`
  failed with "nonexistent object" for a host commit absent from this checkout.

Tests: +3 bats (promote-all fleet iteration; cross-repo promote dry-run takes
the host gh-api path not local git; real cross-repo promote moves the host tag
via gh api PATCH + records the GITHUB_OUTPUT). 55/55 passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
…b) + host-aware cross-repo tag moves (#1054) (#1056)

* feat(canary-rollout): gated scheduled fleet auto-promote (#1045 part b) + host-aware cross-repo tag moves (#1054)

Implements #1045 part b — the timer advances the fleet, no manual step.

Automation:
- promote-all subcommand (cmd_promote_all): iterates every registry agent
  and forwards to cmd_promote, so each PROMOTE-ready agent advances exactly
  one ring per run while BLOCKED/REGRESSION agents are left untouched by the
  gate. A per-agent failure is logged and skipped so one agent cannot halt
  the fleet sweep. Human approval stays OVERRIDE-ONLY, never a required gate.
- workflow: schedule now runs the gated auto-promote when the org variable
  CANARY_AUTO_PROMOTE == 'true' (promote-all, real move), else read-only
  evaluate-all. The arm variable is the single kill-switch. dispatch gains
  evaluate-all/promote-all options (promote-all defaults to --dry-run).

Cross-repo fix (#1054):
- _gh_move_tag: force-move/create a channel tag on a cross-repo agent's HOST
  via gh api (PATCH then POST), the counterpart of `git tag -f` + push.
- cmd_promote / cmd_rollback are now host-aware: an agent hosted in THIS repo
  moves its tag via local git; a cross-repo agent (the 6 #482 reusables on
  petry-projects/.github) moves it on its host via gh api — local `git tag -f`
  failed with "nonexistent object" for a host commit absent from this checkout.

Tests: +3 bats (promote-all fleet iteration; cross-repo promote dry-run takes
the host gh-api path not local git; real cross-repo promote moves the host tag
via gh api PATCH + records the GITHUB_OUTPUT). 55/55 passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
…b) + host-aware cross-repo tag moves (#1054) (#1056)

* feat(canary-rollout): gated scheduled fleet auto-promote (#1045 part b) + host-aware cross-repo tag moves (#1054)

Implements #1045 part b — the timer advances the fleet, no manual step.

Automation:
- promote-all subcommand (cmd_promote_all): iterates every registry agent
  and forwards to cmd_promote, so each PROMOTE-ready agent advances exactly
  one ring per run while BLOCKED/REGRESSION agents are left untouched by the
  gate. A per-agent failure is logged and skipped so one agent cannot halt
  the fleet sweep. Human approval stays OVERRIDE-ONLY, never a required gate.
- workflow: schedule now runs the gated auto-promote when the org variable
  CANARY_AUTO_PROMOTE == 'true' (promote-all, real move), else read-only
  evaluate-all. The arm variable is the single kill-switch. dispatch gains
  evaluate-all/promote-all options (promote-all defaults to --dry-run).

Cross-repo fix (#1054):
- _gh_move_tag: force-move/create a channel tag on a cross-repo agent's HOST
  via gh api (PATCH then POST), the counterpart of `git tag -f` + push.
- cmd_promote / cmd_rollback are now host-aware: an agent hosted in THIS repo
  moves its tag via local git; a cross-repo agent (the 6 #482 reusables on
  petry-projects/.github) moves it on its host via gh api — local `git tag -f`
  failed with "nonexistent object" for a host commit absent from this checkout.

Tests: +3 bats (promote-all fleet iteration; cross-repo promote dry-run takes
the host gh-api path not local git; real cross-repo promote moves the host tag
via gh api PATCH + records the GITHUB_OUTPUT). 55/55 passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 8, 2026
…b) + host-aware cross-repo tag moves (#1054) (#1056)

* feat(canary-rollout): gated scheduled fleet auto-promote (#1045 part b) + host-aware cross-repo tag moves (#1054)

Implements #1045 part b — the timer advances the fleet, no manual step.

Automation:
- promote-all subcommand (cmd_promote_all): iterates every registry agent
  and forwards to cmd_promote, so each PROMOTE-ready agent advances exactly
  one ring per run while BLOCKED/REGRESSION agents are left untouched by the
  gate. A per-agent failure is logged and skipped so one agent cannot halt
  the fleet sweep. Human approval stays OVERRIDE-ONLY, never a required gate.
- workflow: schedule now runs the gated auto-promote when the org variable
  CANARY_AUTO_PROMOTE == 'true' (promote-all, real move), else read-only
  evaluate-all. The arm variable is the single kill-switch. dispatch gains
  evaluate-all/promote-all options (promote-all defaults to --dry-run).

Cross-repo fix (#1054):
- _gh_move_tag: force-move/create a channel tag on a cross-repo agent's HOST
  via gh api (PATCH then POST), the counterpart of `git tag -f` + push.
- cmd_promote / cmd_rollback are now host-aware: an agent hosted in THIS repo
  moves its tag via local git; a cross-repo agent (the 6 #482 reusables on
  petry-projects/.github) moves it on its host via gh api — local `git tag -f`
  failed with "nonexistent object" for a host commit absent from this checkout.

Tests: +3 bats (promote-all fleet iteration; cross-repo promote dry-run takes
the host gh-api path not local git; real cross-repo promote moves the host tag
via gh api PATCH + records the GITHUB_OUTPUT). 55/55 passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 8, 2026
…b) + host-aware cross-repo tag moves (#1054) (#1056)

* feat(canary-rollout): gated scheduled fleet auto-promote (#1045 part b) + host-aware cross-repo tag moves (#1054)

Implements #1045 part b — the timer advances the fleet, no manual step.

Automation:
- promote-all subcommand (cmd_promote_all): iterates every registry agent
  and forwards to cmd_promote, so each PROMOTE-ready agent advances exactly
  one ring per run while BLOCKED/REGRESSION agents are left untouched by the
  gate. A per-agent failure is logged and skipped so one agent cannot halt
  the fleet sweep. Human approval stays OVERRIDE-ONLY, never a required gate.
- workflow: schedule now runs the gated auto-promote when the org variable
  CANARY_AUTO_PROMOTE == 'true' (promote-all, real move), else read-only
  evaluate-all. The arm variable is the single kill-switch. dispatch gains
  evaluate-all/promote-all options (promote-all defaults to --dry-run).

Cross-repo fix (#1054):
- _gh_move_tag: force-move/create a channel tag on a cross-repo agent's HOST
  via gh api (PATCH then POST), the counterpart of `git tag -f` + push.
- cmd_promote / cmd_rollback are now host-aware: an agent hosted in THIS repo
  moves its tag via local git; a cross-repo agent (the 6 #482 reusables on
  petry-projects/.github) moves it on its host via gh api — local `git tag -f`
  failed with "nonexistent object" for a host commit absent from this checkout.

Tests: +3 bats (promote-all fleet iteration; cross-repo promote dry-run takes
the host gh-api path not local git; real cross-repo promote moves the host tag
via gh api PATCH + records the GITHUB_OUTPUT). 55/55 passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 8, 2026
…b) + host-aware cross-repo tag moves (#1054) (#1056)

* feat(canary-rollout): gated scheduled fleet auto-promote (#1045 part b) + host-aware cross-repo tag moves (#1054)

Implements #1045 part b — the timer advances the fleet, no manual step.

Automation:
- promote-all subcommand (cmd_promote_all): iterates every registry agent
  and forwards to cmd_promote, so each PROMOTE-ready agent advances exactly
  one ring per run while BLOCKED/REGRESSION agents are left untouched by the
  gate. A per-agent failure is logged and skipped so one agent cannot halt
  the fleet sweep. Human approval stays OVERRIDE-ONLY, never a required gate.
- workflow: schedule now runs the gated auto-promote when the org variable
  CANARY_AUTO_PROMOTE == 'true' (promote-all, real move), else read-only
  evaluate-all. The arm variable is the single kill-switch. dispatch gains
  evaluate-all/promote-all options (promote-all defaults to --dry-run).

Cross-repo fix (#1054):
- _gh_move_tag: force-move/create a channel tag on a cross-repo agent's HOST
  via gh api (PATCH then POST), the counterpart of `git tag -f` + push.
- cmd_promote / cmd_rollback are now host-aware: an agent hosted in THIS repo
  moves its tag via local git; a cross-repo agent (the 6 #482 reusables on
  petry-projects/.github) moves it on its host via gh api — local `git tag -f`
  failed with "nonexistent object" for a host commit absent from this checkout.

Tests: +3 bats (promote-all fleet iteration; cross-repo promote dry-run takes
the host gh-api path not local git; real cross-repo promote moves the host tag
via gh api PATCH + records the GITHUB_OUTPUT). 55/55 passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 8, 2026
…b) + host-aware cross-repo tag moves (#1054) (#1056)

* feat(canary-rollout): gated scheduled fleet auto-promote (#1045 part b) + host-aware cross-repo tag moves (#1054)

Implements #1045 part b — the timer advances the fleet, no manual step.

Automation:
- promote-all subcommand (cmd_promote_all): iterates every registry agent
  and forwards to cmd_promote, so each PROMOTE-ready agent advances exactly
  one ring per run while BLOCKED/REGRESSION agents are left untouched by the
  gate. A per-agent failure is logged and skipped so one agent cannot halt
  the fleet sweep. Human approval stays OVERRIDE-ONLY, never a required gate.
- workflow: schedule now runs the gated auto-promote when the org variable
  CANARY_AUTO_PROMOTE == 'true' (promote-all, real move), else read-only
  evaluate-all. The arm variable is the single kill-switch. dispatch gains
  evaluate-all/promote-all options (promote-all defaults to --dry-run).

Cross-repo fix (#1054):
- _gh_move_tag: force-move/create a channel tag on a cross-repo agent's HOST
  via gh api (PATCH then POST), the counterpart of `git tag -f` + push.
- cmd_promote / cmd_rollback are now host-aware: an agent hosted in THIS repo
  moves its tag via local git; a cross-repo agent (the 6 #482 reusables on
  petry-projects/.github) moves it on its host via gh api — local `git tag -f`
  failed with "nonexistent object" for a host commit absent from this checkout.

Tests: +3 bats (promote-all fleet iteration; cross-repo promote dry-run takes
the host gh-api path not local git; real cross-repo promote moves the host tag
via gh api PATCH + records the GITHUB_OUTPUT). 55/55 passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 18, 2026
…b) + host-aware cross-repo tag moves (#1054) (#1056)

* feat(canary-rollout): gated scheduled fleet auto-promote (#1045 part b) + host-aware cross-repo tag moves (#1054)

Implements #1045 part b — the timer advances the fleet, no manual step.

Automation:
- promote-all subcommand (cmd_promote_all): iterates every registry agent
  and forwards to cmd_promote, so each PROMOTE-ready agent advances exactly
  one ring per run while BLOCKED/REGRESSION agents are left untouched by the
  gate. A per-agent failure is logged and skipped so one agent cannot halt
  the fleet sweep. Human approval stays OVERRIDE-ONLY, never a required gate.
- workflow: schedule now runs the gated auto-promote when the org variable
  CANARY_AUTO_PROMOTE == 'true' (promote-all, real move), else read-only
  evaluate-all. The arm variable is the single kill-switch. dispatch gains
  evaluate-all/promote-all options (promote-all defaults to --dry-run).

Cross-repo fix (#1054):
- _gh_move_tag: force-move/create a channel tag on a cross-repo agent's HOST
  via gh api (PATCH then POST), the counterpart of `git tag -f` + push.
- cmd_promote / cmd_rollback are now host-aware: an agent hosted in THIS repo
  moves its tag via local git; a cross-repo agent (the 6 #482 reusables on
  petry-projects/.github) moves it on its host via gh api — local `git tag -f`
  failed with "nonexistent object" for a host commit absent from this checkout.

Tests: +3 bats (promote-all fleet iteration; cross-repo promote dry-run takes
the host gh-api path not local git; real cross-repo promote moves the host tag
via gh api PATCH + records the GITHUB_OUTPUT). 55/55 passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dev-lead For dev-lead agent pickup

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants