Skip to content

ci: restore workflow changes dropped by stale stack promotion - #93

Merged
incognitojam merged 4 commits into
mainfrom
ci/restore-workflow-commits
Aug 11, 2026
Merged

ci: restore workflow changes dropped by stale stack promotion#93
incognitojam merged 4 commits into
mainfrom
ci/restore-workflow-commits

Conversation

@incognitojam

Copy link
Copy Markdown
Collaborator

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).

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
incognitojam enabled auto-merge (squash) August 11, 2026 18:56
@github-actions github-actions Bot added size:L vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. labels Aug 11, 2026
@incognitojam
incognitojam merged commit 206d440 into main Aug 11, 2026
10 checks passed
@incognitojam
incognitojam deleted the ci/restore-workflow-commits branch August 11, 2026 19:00
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).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant