ci: restore workflow changes dropped by stale stack promotion - #93
Merged
Conversation
The fork ruleset now requires the individual CI jobs directly, so the aggregate `Fork CI Required` job adds an extra runner invocation without providing additional protection. Remove the aggregate job while leaving the underlying change detection, upstream rebase, check, test, and release smoke jobs unchanged. The ruleset must include `Fork Upstream Rebase` alongside the four checks already configured. --- Written by an agent (T3 Code, gpt-5.6-sol).
## Problem The daily `main` promotion gate (from #80) decided "first run of the day" by checking `date -u +%H == 08` at prepare start. The cron fires at 08:23 UTC, but the check runs when the job actually starts — so a first run that sat queued past 09:00 UTC computed hour 09 and silently skipped that day's promotion (the Aug 11 first run started 09:16 after a 53-minute queue delay). ## Fix Per review discussion: drop the once-daily gating entirely and promote on every verified run. There's nothing to ration — the push is a no-op when upstream hasn't advanced, and every candidate is fully verified before it gets near `main`. - **Gate deleted.** No `promote_gate` step, no `promote_main` prepare output, and no `promote_main` dispatch input — a `workflow_dispatch` promotes like any run. Dry runs still never promote (both promotion steps are gated on `inputs.dry_run != true`, and dry runs also force `has_changes=true` away from the alignment path). - **Quiet no-ops.** The release-job step exits early when the rebase was a no-op (`fork_ref == candidate`); the prepare alignment step keeps its existing no-op checks (no `origin/nightly`, or `main` already aligned). - **Expected skip when `main` moved.** Both steps compare `git ls-remote origin refs/heads/main` to the run's starting ref first; if a PR merged mid-run, they log and skip — the next run's candidate includes it. That's a normal outcome, not an error. The leased force-push remains the real guard: a lease failure after that check is a genuine seconds-wide race and stays a loud failure that fires the Discord alert. - **First-of-day backup preserved.** `backup/main-YYYYMMDD` is created only if absent (plain push, no force), so the day's first actual promotion snapshots the pre-promotion `main` and later promotions that day leave it alone. Docs updated to match in `docs/operations/fork-nightly.md`. Verified with actionlint (only the pre-existing Blacksmith runner-label warning) and a branch-by-branch simulation of both step bodies: normal promote (backup created, leased push), rebase-no-op quiet exit, moved-main expected skip, backup-exists (kept, main still pushed), ls-remote hard failure fails the step, and the alignment no-op paths unchanged. --- Built by Fable 5 (claude-fable-5) on Claude Code.
When the nightly rebase onto `pingdotgg/t3code` conflicts, the run fails in prepare and a maintainer resolves the stack locally — but the ruleset blocks force-pushing `main` from the CLI, so there was no way to get the resolved stack back onto `main`. This adds an optional `source_ref` dispatch input. The run checks out that ref (a branch or SHA pushed to origin holding the resolved stack) instead of `main`, rebases it onto upstream (a no-op when nothing moved since, a loud conflict failure when it did), runs the full verification, publishes the release, and promotes it to `main` through the existing backup and lease mechanics. An invalid `source_ref` fails in a pre-checkout validation step with a readable message. Pairing `source_ref` with `dry_run` verifies a resolution without publishing or promoting anything. ## The `fork_ref` split Today the run always checks out `main`, so one commit serves every role. With `source_ref` there are three: **M** = `origin/main`'s tip, **R** = the provided stack, **C** = the candidate after the rebase. `fork_ref` keeps its meaning as the stack source (R) and a new `main_ref` output carries M, resolved once in prepare so every later check compares against the same snapshot. | Role | Commit | Why | | --- | --- | --- | | Checkout ref | R | The stack being rebased and verified. | | `FORK_SOURCE_REF` in both changelog steps | R | Release notes must enumerate the stack that ships. | | Backup snapshot source | M | The backup captures the commit being replaced; R already exists as the maintainer's branch. | | Moved-main skip comparison | M | Compares live `main` against the run-start snapshot. | | Lease (`--force-with-lease=refs/heads/main:…`) | M | Pins `main`'s expected value. | | Nothing-to-promote short-circuit | C == M | Was C == R, meaning "the rebase was a no-op". On a `source_ref` run C == R is the normal case and promotion still has work to do; the real question is whether `main` is already the candidate. | The prepare job's no-change alignment step gets the same treatment (all four of its uses are M). On scheduled runs `fork_ref` and `main_ref` are the same commit, so behaviour is unchanged. Verified with actionlint (only the pre-existing blacksmith runner-label warning) and by extracting every `run:` body from both this workflow and the pre-change one and replaying them against stubbed `git`/`gh`: scheduled runs produce identical command sequences, and the `source_ref` paths cover promote, C == M no-op, moved main, `dry_run`, and invalid ref. Model: Claude Opus 5, harness: T3 Code
## Problem
Fork Nightly authenticates its pushes through the checkout token, which
was `secrets.FORK_RELEASE_TOKEN` — a personal access token. The "PR +
CI" ruleset on `main` has exactly one bypass actor: the
`yngatech-nightly` GitHub App. The PAT has no bypass, so the promotion
push to `main` fails with GH013. Run 31514413207 demonstrated the full
failure shape: release published, `nightly` promoted, `main` promotion
rejected.
## Fix
Mint an installation token for the `yngatech-nightly` app at the start
of each job that pushes, and check out with it:
- Both the prepare job (its alignment step can force-push `main` on
no-change days, plus the `nightly-candidate` push) and the release job
(`nightly`, the daily backup ref, and `main`) get an `app_token` step
using `actions/create-github-app-token`, SHA-pinned to v3.2.0 per repo
convention, followed by `token: ${{ steps.app_token.outputs.token }}` on
the checkout.
- Minting per job is deliberate: installation tokens expire after one
hour, and the desktop builds sit between prepare and release. Noted in
step comments.
- v3 of the action deprecates `app-id` in favor of `client-id`, which is
what the pre-provisioned `YNGATECH_NIGHTLY_APP_CLIENT_ID` variable
holds, so the step uses `client-id` directly (verified against the
action's v3.2.0 `action.yml`).
Cameron pre-provisioned the app, the `YNGATECH_NIGHTLY_APP_CLIENT_ID`
variable, and the `YNGATECH_NIGHTLY_APP_PRIVATE_KEY` secret; only the
workflow wiring was missing. No other behavior changes. After this
lands, `FORK_RELEASE_TOKEN` is referenced nowhere in `.github/` — these
two checkouts were its only uses.
Verified with actionlint (only the pre-existing Blacksmith runner-label
warning) and by tracing every push in the workflow to one of the two
app-token checkouts; the remaining `github.token` uses (release notes,
draft release, issue edit) touch no protected refs.
---
Built by Fable 5 (claude-fable-5) on Claude Code.
incognitojam
enabled auto-merge (squash)
August 11, 2026 18:56
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 11, 2026
## Problem The `source_ref` dispatch that fixed the conflicted patch stack promoted a resolution cut before today's workflow PRs merged, rolling `main`'s workflow state back: #87 (promote every verified run), #90 (require workflow jobs directly), #91 (`source_ref` input), and #92 (yngatech-nightly app token) were dropped. The moved-main lease only guards movement during a run, not whether the provided stack already contained everything on `main`. ## Fix Cherry-pick the four squash commits back onto the promoted stack, in original merge order. The restored `.github/workflows/fork-nightly.yml`, `.github/workflows/fork-ci.yml`, and `docs/operations/fork-nightly.md` are byte-identical to their pre-rollback state (verified with `git diff` against the old `main` tip). A follow-up should make `source_ref` runs fail when the provided stack is missing patches present on `main` (patch-id comparison in prepare). --- Written by an agent (Claude Code, claude-fable-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 12, 2026
## Problem The `source_ref` dispatch that fixed the conflicted patch stack promoted a resolution cut before today's workflow PRs merged, rolling `main`'s workflow state back: #87 (promote every verified run), #90 (require workflow jobs directly), #91 (`source_ref` input), and #92 (yngatech-nightly app token) were dropped. The moved-main lease only guards movement during a run, not whether the provided stack already contained everything on `main`. ## Fix Cherry-pick the four squash commits back onto the promoted stack, in original merge order. The restored `.github/workflows/fork-nightly.yml`, `.github/workflows/fork-ci.yml`, and `docs/operations/fork-nightly.md` are byte-identical to their pre-rollback state (verified with `git diff` against the old `main` tip). A follow-up should make `source_ref` runs fail when the provided stack is missing patches present on `main` (patch-id comparison in prepare). --- Written by an agent (Claude Code, claude-fable-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 12, 2026
## Problem The `source_ref` dispatch that fixed the conflicted patch stack promoted a resolution cut before today's workflow PRs merged, rolling `main`'s workflow state back: #87 (promote every verified run), #90 (require workflow jobs directly), #91 (`source_ref` input), and #92 (yngatech-nightly app token) were dropped. The moved-main lease only guards movement during a run, not whether the provided stack already contained everything on `main`. ## Fix Cherry-pick the four squash commits back onto the promoted stack, in original merge order. The restored `.github/workflows/fork-nightly.yml`, `.github/workflows/fork-ci.yml`, and `docs/operations/fork-nightly.md` are byte-identical to their pre-rollback state (verified with `git diff` against the old `main` tip). A follow-up should make `source_ref` runs fail when the provided stack is missing patches present on `main` (patch-id comparison in prepare). --- Written by an agent (Claude Code, claude-fable-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 12, 2026
## Problem The `source_ref` dispatch that fixed the conflicted patch stack promoted a resolution cut before today's workflow PRs merged, rolling `main`'s workflow state back: #87 (promote every verified run), #90 (require workflow jobs directly), #91 (`source_ref` input), and #92 (yngatech-nightly app token) were dropped. The moved-main lease only guards movement during a run, not whether the provided stack already contained everything on `main`. ## Fix Cherry-pick the four squash commits back onto the promoted stack, in original merge order. The restored `.github/workflows/fork-nightly.yml`, `.github/workflows/fork-ci.yml`, and `docs/operations/fork-nightly.md` are byte-identical to their pre-rollback state (verified with `git diff` against the old `main` tip). A follow-up should make `source_ref` runs fail when the provided stack is missing patches present on `main` (patch-id comparison in prepare). --- Written by an agent (Claude Code, claude-fable-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 13, 2026
## Problem The `source_ref` dispatch that fixed the conflicted patch stack promoted a resolution cut before today's workflow PRs merged, rolling `main`'s workflow state back: #87 (promote every verified run), #90 (require workflow jobs directly), #91 (`source_ref` input), and #92 (yngatech-nightly app token) were dropped. The moved-main lease only guards movement during a run, not whether the provided stack already contained everything on `main`. ## Fix Cherry-pick the four squash commits back onto the promoted stack, in original merge order. The restored `.github/workflows/fork-nightly.yml`, `.github/workflows/fork-ci.yml`, and `docs/operations/fork-nightly.md` are byte-identical to their pre-rollback state (verified with `git diff` against the old `main` tip). A follow-up should make `source_ref` runs fail when the provided stack is missing patches present on `main` (patch-id comparison in prepare). --- Written by an agent (Claude Code, claude-fable-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 13, 2026
## Problem The `source_ref` dispatch that fixed the conflicted patch stack promoted a resolution cut before today's workflow PRs merged, rolling `main`'s workflow state back: #87 (promote every verified run), #90 (require workflow jobs directly), #91 (`source_ref` input), and #92 (yngatech-nightly app token) were dropped. The moved-main lease only guards movement during a run, not whether the provided stack already contained everything on `main`. ## Fix Cherry-pick the four squash commits back onto the promoted stack, in original merge order. The restored `.github/workflows/fork-nightly.yml`, `.github/workflows/fork-ci.yml`, and `docs/operations/fork-nightly.md` are byte-identical to their pre-rollback state (verified with `git diff` against the old `main` tip). A follow-up should make `source_ref` runs fail when the provided stack is missing patches present on `main` (patch-id comparison in prepare). --- Written by an agent (Claude Code, claude-fable-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 13, 2026
## Problem The `source_ref` dispatch that fixed the conflicted patch stack promoted a resolution cut before today's workflow PRs merged, rolling `main`'s workflow state back: #87 (promote every verified run), #90 (require workflow jobs directly), #91 (`source_ref` input), and #92 (yngatech-nightly app token) were dropped. The moved-main lease only guards movement during a run, not whether the provided stack already contained everything on `main`. ## Fix Cherry-pick the four squash commits back onto the promoted stack, in original merge order. The restored `.github/workflows/fork-nightly.yml`, `.github/workflows/fork-ci.yml`, and `docs/operations/fork-nightly.md` are byte-identical to their pre-rollback state (verified with `git diff` against the old `main` tip). A follow-up should make `source_ref` runs fail when the provided stack is missing patches present on `main` (patch-id comparison in prepare). --- Written by an agent (Claude Code, claude-fable-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 13, 2026
## Problem The `source_ref` dispatch that fixed the conflicted patch stack promoted a resolution cut before today's workflow PRs merged, rolling `main`'s workflow state back: #87 (promote every verified run), #90 (require workflow jobs directly), #91 (`source_ref` input), and #92 (yngatech-nightly app token) were dropped. The moved-main lease only guards movement during a run, not whether the provided stack already contained everything on `main`. ## Fix Cherry-pick the four squash commits back onto the promoted stack, in original merge order. The restored `.github/workflows/fork-nightly.yml`, `.github/workflows/fork-ci.yml`, and `docs/operations/fork-nightly.md` are byte-identical to their pre-rollback state (verified with `git diff` against the old `main` tip). A follow-up should make `source_ref` runs fail when the provided stack is missing patches present on `main` (patch-id comparison in prepare). --- Written by an agent (Claude Code, claude-fable-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 14, 2026
## Problem The `source_ref` dispatch that fixed the conflicted patch stack promoted a resolution cut before today's workflow PRs merged, rolling `main`'s workflow state back: #87 (promote every verified run), #90 (require workflow jobs directly), #91 (`source_ref` input), and #92 (yngatech-nightly app token) were dropped. The moved-main lease only guards movement during a run, not whether the provided stack already contained everything on `main`. ## Fix Cherry-pick the four squash commits back onto the promoted stack, in original merge order. The restored `.github/workflows/fork-nightly.yml`, `.github/workflows/fork-ci.yml`, and `docs/operations/fork-nightly.md` are byte-identical to their pre-rollback state (verified with `git diff` against the old `main` tip). A follow-up should make `source_ref` runs fail when the provided stack is missing patches present on `main` (patch-id comparison in prepare). --- Written by an agent (Claude Code, claude-fable-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 14, 2026
## Problem The `source_ref` dispatch that fixed the conflicted patch stack promoted a resolution cut before today's workflow PRs merged, rolling `main`'s workflow state back: #87 (promote every verified run), #90 (require workflow jobs directly), #91 (`source_ref` input), and #92 (yngatech-nightly app token) were dropped. The moved-main lease only guards movement during a run, not whether the provided stack already contained everything on `main`. ## Fix Cherry-pick the four squash commits back onto the promoted stack, in original merge order. The restored `.github/workflows/fork-nightly.yml`, `.github/workflows/fork-ci.yml`, and `docs/operations/fork-nightly.md` are byte-identical to their pre-rollback state (verified with `git diff` against the old `main` tip). A follow-up should make `source_ref` runs fail when the provided stack is missing patches present on `main` (patch-id comparison in prepare). --- Written by an agent (Claude Code, claude-fable-5).
incognitojam
added a commit
that referenced
this pull request
Aug 15, 2026
## Problem The `source_ref` dispatch that fixed the conflicted patch stack promoted a resolution cut before today's workflow PRs merged, rolling `main`'s workflow state back: #87 (promote every verified run), #90 (require workflow jobs directly), #91 (`source_ref` input), and #92 (yngatech-nightly app token) were dropped. The moved-main lease only guards movement during a run, not whether the provided stack already contained everything on `main`. ## Fix Cherry-pick the four squash commits back onto the promoted stack, in original merge order. The restored `.github/workflows/fork-nightly.yml`, `.github/workflows/fork-ci.yml`, and `docs/operations/fork-nightly.md` are byte-identical to their pre-rollback state (verified with `git diff` against the old `main` tip). A follow-up should make `source_ref` runs fail when the provided stack is missing patches present on `main` (patch-id comparison in prepare). --- Written by an agent (Claude Code, claude-fable-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 18, 2026
## Problem The `source_ref` dispatch that fixed the conflicted patch stack promoted a resolution cut before today's workflow PRs merged, rolling `main`'s workflow state back: #87 (promote every verified run), #90 (require workflow jobs directly), #91 (`source_ref` input), and #92 (yngatech-nightly app token) were dropped. The moved-main lease only guards movement during a run, not whether the provided stack already contained everything on `main`. ## Fix Cherry-pick the four squash commits back onto the promoted stack, in original merge order. The restored `.github/workflows/fork-nightly.yml`, `.github/workflows/fork-ci.yml`, and `docs/operations/fork-nightly.md` are byte-identical to their pre-rollback state (verified with `git diff` against the old `main` tip). A follow-up should make `source_ref` runs fail when the provided stack is missing patches present on `main` (patch-id comparison in prepare). --- Written by an agent (Claude Code, claude-fable-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 18, 2026
## Problem The `source_ref` dispatch that fixed the conflicted patch stack promoted a resolution cut before today's workflow PRs merged, rolling `main`'s workflow state back: #87 (promote every verified run), #90 (require workflow jobs directly), #91 (`source_ref` input), and #92 (yngatech-nightly app token) were dropped. The moved-main lease only guards movement during a run, not whether the provided stack already contained everything on `main`. ## Fix Cherry-pick the four squash commits back onto the promoted stack, in original merge order. The restored `.github/workflows/fork-nightly.yml`, `.github/workflows/fork-ci.yml`, and `docs/operations/fork-nightly.md` are byte-identical to their pre-rollback state (verified with `git diff` against the old `main` tip). A follow-up should make `source_ref` runs fail when the provided stack is missing patches present on `main` (patch-id comparison in prepare). --- Written by an agent (Claude Code, claude-fable-5).
yngatech-nightly Bot
pushed a commit
that referenced
this pull request
Aug 18, 2026
## Problem The `source_ref` dispatch that fixed the conflicted patch stack promoted a resolution cut before today's workflow PRs merged, rolling `main`'s workflow state back: #87 (promote every verified run), #90 (require workflow jobs directly), #91 (`source_ref` input), and #92 (yngatech-nightly app token) were dropped. The moved-main lease only guards movement during a run, not whether the provided stack already contained everything on `main`. ## Fix Cherry-pick the four squash commits back onto the promoted stack, in original merge order. The restored `.github/workflows/fork-nightly.yml`, `.github/workflows/fork-ci.yml`, and `docs/operations/fork-nightly.md` are byte-identical to their pre-rollback state (verified with `git diff` against the old `main` tip). A follow-up should make `source_ref` runs fail when the provided stack is missing patches present on `main` (patch-id comparison in prepare). --- Written by an agent (Claude Code, claude-fable-5).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The
source_refdispatch that fixed the conflicted patch stack promoted a resolution cut before today's workflow PRs merged, rollingmain's workflow state back: #87 (promote every verified run), #90 (require workflow jobs directly), #91 (source_refinput), and #92 (yngatech-nightly app token) were dropped. The moved-main lease only guards movement during a run, not whether the provided stack already contained everything onmain.Fix
Cherry-pick the four squash commits back onto the promoted stack, in original merge order. The restored
.github/workflows/fork-nightly.yml,.github/workflows/fork-ci.yml, anddocs/operations/fork-nightly.mdare byte-identical to their pre-rollback state (verified withgit diffagainst the oldmaintip).A follow-up should make
source_refruns fail when the provided stack is missing patches present onmain(patch-id comparison in prepare).Written by an agent (Claude Code, claude-fable-5).