Skip to content

ci(nightly): promote verified rebased stack to main daily - #80

Merged
incognitojam merged 2 commits into
mainfrom
ci/nightly-promote-main
Aug 11, 2026
Merged

ci(nightly): promote verified rebased stack to main daily#80
incognitojam merged 2 commits into
mainfrom
ci/nightly-promote-main

Conversation

@incognitojam

@incognitojam incognitojam commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Problem

Fork Nightly rebases the patch stack onto upstream, fully verifies it (check, typecheck, desktop builds, tests), and promotes it to nightly — but origin/main was never moved by automation. It only advanced when a maintainer rebased it manually, so fresh checkouts of main lagged upstream by days.

Fix

On green nightlies, promote the verified rebased stack to main, gated to once daily:

  • Once-daily gate. The prepare job computes a promote_main output: true only for the first scheduled run of the day (08:xx UTC of the five daily crons) or a workflow_dispatch with the new promote_main boolean input. Never true when dry_run is set.
  • Backup ref. Before promoting, the run's starting main commit is pushed to backup/main-YYYYMMDD (plain force, so a same-day re-run doesn't fail on the existing backup).
  • Leased force-push. git push --force-with-lease=refs/heads/main:${FORK_REF} origin <verified-sha>:refs/heads/main pins the lease to the exact commit the run started from. The workflow concurrency group already serializes nightly runs, so a failed lease means a human pushed main mid-run — the step fails loudly and the existing Discord failure notification fires instead of overwriting their work.
  • No-change days still promote. The release job only runs when the candidate differs from origin/nightly, so on a quiet overnight the promotion step there would never fire and main could stay stale indefinitely. When the gate is on but there are no new changes, the prepare job instead aligns main to the existing origin/nightly commit — its tree is identical to the freshly rebased candidate (that is exactly what the no-change check means) and it already shipped through a fully verified release, so no re-verification is needed. The step is a clean no-op when origin/nightly doesn't exist or main already matches it, avoiding daily backup/push churn across long quiet stretches; otherwise it uses the same backup-ref and leased-force-push mechanics as the release-job step.
  • Conflict path unchanged and human-owned. A rebase conflict still fails prepare before anything is promoted; maintainers resolve, verify, push a backup branch, and force-push main as before. With new changes, promotion only runs after the release publishes, and dry runs promote nothing.

Docs: added a "Keeping main current" section to docs/operations/fork-nightly.md distinguishing automated mechanical promotion (post-release, or prepare-time alignment to the released nightly on no-change days) from maintainer-reviewed conflict rebases.

Why this supersedes the merge-candidate proposal

Issue #63 proposed building candidates by merging upstream into the fork head so the workflow never owns rebase semantics. Since then the operational reality settled the boundary differently: the nightly already produces a fully verified rebased stack every run, and the only missing piece was letting main benefit from it. Promoting the verified rebase (with a backup ref and a lease guarding manual pushes) keeps main a clean patch stack — no merge commits to unwind at the next manual rebase — while conflicted rebases remain exactly the maintainer-reviewed operation they are today. The merge-candidate machinery would add a second candidate topology without removing any human responsibility.

Closes #63


Built by Fable 5 (claude-fable-5) on Claude Code.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:M labels Aug 11, 2026
@github-actions github-actions Bot added size:XXL and removed size:M labels Aug 11, 2026
@incognitojam
incognitojam force-pushed the ci/nightly-promote-main branch from 1f4d4cb to eb660e3 Compare August 11, 2026 13:09
@github-actions github-actions Bot added size:L and removed size:XXL labels Aug 11, 2026
The nightly rebases the patch stack onto upstream and verifies it, but
origin/main only moved when a maintainer rebased it manually, so fresh
checkouts lagged upstream. On the first scheduled run of the day (or a
dispatch with the new promote_main input), a green release now backs up
the pre-promotion main to backup/main-YYYYMMDD and force-pushes the
verified candidate to main with a lease pinned to the run's starting
ref, failing loudly if a human moved main mid-run. Dry runs never
promote, and conflicted rebases still fail before touching anything.

Closes #63
Promotion lived only in the release job, which is skipped whenever the
candidate tree matches origin/nightly, so a quiet overnight left main
unpromoted even when weeks behind nightly. When the promote gate is on
and there are no new changes, prepare now aligns main to the existing
origin/nightly commit instead: identical tree to the fresh rebase and
already shipped through a fully verified release. Skips as a no-op when
origin/nightly is missing or main already matches it; otherwise the
same backup ref and leased force-push as the release-job step.
@incognitojam
incognitojam force-pushed the ci/nightly-promote-main branch from eb660e3 to 78cd635 Compare August 11, 2026 13:27
@incognitojam
incognitojam merged commit 939bd10 into main Aug 11, 2026
12 checks passed
@incognitojam
incognitojam deleted the ci/nightly-promote-main branch August 11, 2026 13:34
incognitojam added a commit that referenced this pull request Aug 11, 2026
## Problem

Fork Nightly rebases the patch stack onto upstream, fully verifies it
(check, typecheck, desktop builds, tests), and promotes it to `nightly`
— but `origin/main` was never moved by automation. It only advanced when
a maintainer rebased it manually, so fresh checkouts of `main` lagged
upstream by days.

## Fix

On green nightlies, promote the verified rebased stack to `main`, gated
to once daily:

- **Once-daily gate.** The prepare job computes a `promote_main` output:
true only for the first scheduled run of the day (08:xx UTC of the five
daily crons) or a `workflow_dispatch` with the new `promote_main`
boolean input. Never true when `dry_run` is set.
- **Backup ref.** Before promoting, the run's starting `main` commit is
pushed to `backup/main-YYYYMMDD` (plain force, so a same-day re-run
doesn't fail on the existing backup).
- **Leased force-push.** `git push
--force-with-lease=refs/heads/main:${FORK_REF} origin
<verified-sha>:refs/heads/main` pins the lease to the exact commit the
run started from. The workflow concurrency group already serializes
nightly runs, so a failed lease means a human pushed `main` mid-run —
the step fails loudly and the existing Discord failure notification
fires instead of overwriting their work.
- **No-change days still promote.** The release job only runs when the
candidate differs from `origin/nightly`, so on a quiet overnight the
promotion step there would never fire and `main` could stay stale
indefinitely. When the gate is on but there are no new changes, the
prepare job instead aligns `main` to the existing `origin/nightly`
commit — its tree is identical to the freshly rebased candidate (that is
exactly what the no-change check means) and it already shipped through a
fully verified release, so no re-verification is needed. The step is a
clean no-op when `origin/nightly` doesn't exist or `main` already
matches it, avoiding daily backup/push churn across long quiet
stretches; otherwise it uses the same backup-ref and leased-force-push
mechanics as the release-job step.
- **Conflict path unchanged and human-owned.** A rebase conflict still
fails prepare before anything is promoted; maintainers resolve, verify,
push a backup branch, and force-push `main` as before. With new changes,
promotion only runs after the release publishes, and dry runs promote
nothing.

Docs: added a "Keeping `main` current" section to
`docs/operations/fork-nightly.md` distinguishing automated mechanical
promotion (post-release, or prepare-time alignment to the released
nightly on no-change days) from maintainer-reviewed conflict rebases.

## Why this supersedes the merge-candidate proposal

Issue #63 proposed building candidates by merging upstream into the fork
head so the workflow never owns rebase semantics. Since then the
operational reality settled the boundary differently: the nightly
already produces a fully verified rebased stack every run, and the only
missing piece was letting `main` benefit from it. Promoting the verified
rebase (with a backup ref and a lease guarding manual pushes) keeps
`main` a clean patch stack — no merge commits to unwind at the next
manual rebase — while conflicted rebases remain exactly the
maintainer-reviewed operation they are today. The merge-candidate
machinery would add a second candidate topology without removing any
human responsibility.

Closes #63

---

Built by Fable 5 (claude-fable-5) on Claude Code.
yngatech-nightly Bot pushed a commit that referenced this pull request Aug 11, 2026
## Problem

Fork Nightly rebases the patch stack onto upstream, fully verifies it
(check, typecheck, desktop builds, tests), and promotes it to `nightly`
— but `origin/main` was never moved by automation. It only advanced when
a maintainer rebased it manually, so fresh checkouts of `main` lagged
upstream by days.

## Fix

On green nightlies, promote the verified rebased stack to `main`, gated
to once daily:

- **Once-daily gate.** The prepare job computes a `promote_main` output:
true only for the first scheduled run of the day (08:xx UTC of the five
daily crons) or a `workflow_dispatch` with the new `promote_main`
boolean input. Never true when `dry_run` is set.
- **Backup ref.** Before promoting, the run's starting `main` commit is
pushed to `backup/main-YYYYMMDD` (plain force, so a same-day re-run
doesn't fail on the existing backup).
- **Leased force-push.** `git push
--force-with-lease=refs/heads/main:${FORK_REF} origin
<verified-sha>:refs/heads/main` pins the lease to the exact commit the
run started from. The workflow concurrency group already serializes
nightly runs, so a failed lease means a human pushed `main` mid-run —
the step fails loudly and the existing Discord failure notification
fires instead of overwriting their work.
- **No-change days still promote.** The release job only runs when the
candidate differs from `origin/nightly`, so on a quiet overnight the
promotion step there would never fire and `main` could stay stale
indefinitely. When the gate is on but there are no new changes, the
prepare job instead aligns `main` to the existing `origin/nightly`
commit — its tree is identical to the freshly rebased candidate (that is
exactly what the no-change check means) and it already shipped through a
fully verified release, so no re-verification is needed. The step is a
clean no-op when `origin/nightly` doesn't exist or `main` already
matches it, avoiding daily backup/push churn across long quiet
stretches; otherwise it uses the same backup-ref and leased-force-push
mechanics as the release-job step.
- **Conflict path unchanged and human-owned.** A rebase conflict still
fails prepare before anything is promoted; maintainers resolve, verify,
push a backup branch, and force-push `main` as before. With new changes,
promotion only runs after the release publishes, and dry runs promote
nothing.

Docs: added a "Keeping `main` current" section to
`docs/operations/fork-nightly.md` distinguishing automated mechanical
promotion (post-release, or prepare-time alignment to the released
nightly on no-change days) from maintainer-reviewed conflict rebases.

## Why this supersedes the merge-candidate proposal

Issue #63 proposed building candidates by merging upstream into the fork
head so the workflow never owns rebase semantics. Since then the
operational reality settled the boundary differently: the nightly
already produces a fully verified rebased stack every run, and the only
missing piece was letting `main` benefit from it. Promoting the verified
rebase (with a backup ref and a lease guarding manual pushes) keeps
`main` a clean patch stack — no merge commits to unwind at the next
manual rebase — while conflicted rebases remain exactly the
maintainer-reviewed operation they are today. The merge-candidate
machinery would add a second candidate topology without removing any
human responsibility.

Closes #63

---

Built by Fable 5 (claude-fable-5) on Claude Code.
yngatech-nightly Bot pushed a commit that referenced this pull request Aug 12, 2026
## Problem

Fork Nightly rebases the patch stack onto upstream, fully verifies it
(check, typecheck, desktop builds, tests), and promotes it to `nightly`
— but `origin/main` was never moved by automation. It only advanced when
a maintainer rebased it manually, so fresh checkouts of `main` lagged
upstream by days.

## Fix

On green nightlies, promote the verified rebased stack to `main`, gated
to once daily:

- **Once-daily gate.** The prepare job computes a `promote_main` output:
true only for the first scheduled run of the day (08:xx UTC of the five
daily crons) or a `workflow_dispatch` with the new `promote_main`
boolean input. Never true when `dry_run` is set.
- **Backup ref.** Before promoting, the run's starting `main` commit is
pushed to `backup/main-YYYYMMDD` (plain force, so a same-day re-run
doesn't fail on the existing backup).
- **Leased force-push.** `git push
--force-with-lease=refs/heads/main:${FORK_REF} origin
<verified-sha>:refs/heads/main` pins the lease to the exact commit the
run started from. The workflow concurrency group already serializes
nightly runs, so a failed lease means a human pushed `main` mid-run —
the step fails loudly and the existing Discord failure notification
fires instead of overwriting their work.
- **No-change days still promote.** The release job only runs when the
candidate differs from `origin/nightly`, so on a quiet overnight the
promotion step there would never fire and `main` could stay stale
indefinitely. When the gate is on but there are no new changes, the
prepare job instead aligns `main` to the existing `origin/nightly`
commit — its tree is identical to the freshly rebased candidate (that is
exactly what the no-change check means) and it already shipped through a
fully verified release, so no re-verification is needed. The step is a
clean no-op when `origin/nightly` doesn't exist or `main` already
matches it, avoiding daily backup/push churn across long quiet
stretches; otherwise it uses the same backup-ref and leased-force-push
mechanics as the release-job step.
- **Conflict path unchanged and human-owned.** A rebase conflict still
fails prepare before anything is promoted; maintainers resolve, verify,
push a backup branch, and force-push `main` as before. With new changes,
promotion only runs after the release publishes, and dry runs promote
nothing.

Docs: added a "Keeping `main` current" section to
`docs/operations/fork-nightly.md` distinguishing automated mechanical
promotion (post-release, or prepare-time alignment to the released
nightly on no-change days) from maintainer-reviewed conflict rebases.

## Why this supersedes the merge-candidate proposal

Issue #63 proposed building candidates by merging upstream into the fork
head so the workflow never owns rebase semantics. Since then the
operational reality settled the boundary differently: the nightly
already produces a fully verified rebased stack every run, and the only
missing piece was letting `main` benefit from it. Promoting the verified
rebase (with a backup ref and a lease guarding manual pushes) keeps
`main` a clean patch stack — no merge commits to unwind at the next
manual rebase — while conflicted rebases remain exactly the
maintainer-reviewed operation they are today. The merge-candidate
machinery would add a second candidate topology without removing any
human responsibility.

Closes #63

---

Built by Fable 5 (claude-fable-5) on Claude Code.
yngatech-nightly Bot pushed a commit that referenced this pull request Aug 12, 2026
## Problem

Fork Nightly rebases the patch stack onto upstream, fully verifies it
(check, typecheck, desktop builds, tests), and promotes it to `nightly`
— but `origin/main` was never moved by automation. It only advanced when
a maintainer rebased it manually, so fresh checkouts of `main` lagged
upstream by days.

## Fix

On green nightlies, promote the verified rebased stack to `main`, gated
to once daily:

- **Once-daily gate.** The prepare job computes a `promote_main` output:
true only for the first scheduled run of the day (08:xx UTC of the five
daily crons) or a `workflow_dispatch` with the new `promote_main`
boolean input. Never true when `dry_run` is set.
- **Backup ref.** Before promoting, the run's starting `main` commit is
pushed to `backup/main-YYYYMMDD` (plain force, so a same-day re-run
doesn't fail on the existing backup).
- **Leased force-push.** `git push
--force-with-lease=refs/heads/main:${FORK_REF} origin
<verified-sha>:refs/heads/main` pins the lease to the exact commit the
run started from. The workflow concurrency group already serializes
nightly runs, so a failed lease means a human pushed `main` mid-run —
the step fails loudly and the existing Discord failure notification
fires instead of overwriting their work.
- **No-change days still promote.** The release job only runs when the
candidate differs from `origin/nightly`, so on a quiet overnight the
promotion step there would never fire and `main` could stay stale
indefinitely. When the gate is on but there are no new changes, the
prepare job instead aligns `main` to the existing `origin/nightly`
commit — its tree is identical to the freshly rebased candidate (that is
exactly what the no-change check means) and it already shipped through a
fully verified release, so no re-verification is needed. The step is a
clean no-op when `origin/nightly` doesn't exist or `main` already
matches it, avoiding daily backup/push churn across long quiet
stretches; otherwise it uses the same backup-ref and leased-force-push
mechanics as the release-job step.
- **Conflict path unchanged and human-owned.** A rebase conflict still
fails prepare before anything is promoted; maintainers resolve, verify,
push a backup branch, and force-push `main` as before. With new changes,
promotion only runs after the release publishes, and dry runs promote
nothing.

Docs: added a "Keeping `main` current" section to
`docs/operations/fork-nightly.md` distinguishing automated mechanical
promotion (post-release, or prepare-time alignment to the released
nightly on no-change days) from maintainer-reviewed conflict rebases.

## Why this supersedes the merge-candidate proposal

Issue #63 proposed building candidates by merging upstream into the fork
head so the workflow never owns rebase semantics. Since then the
operational reality settled the boundary differently: the nightly
already produces a fully verified rebased stack every run, and the only
missing piece was letting `main` benefit from it. Promoting the verified
rebase (with a backup ref and a lease guarding manual pushes) keeps
`main` a clean patch stack — no merge commits to unwind at the next
manual rebase — while conflicted rebases remain exactly the
maintainer-reviewed operation they are today. The merge-candidate
machinery would add a second candidate topology without removing any
human responsibility.

Closes #63

---

Built by Fable 5 (claude-fable-5) on Claude Code.
yngatech-nightly Bot pushed a commit that referenced this pull request Aug 12, 2026
## Problem

Fork Nightly rebases the patch stack onto upstream, fully verifies it
(check, typecheck, desktop builds, tests), and promotes it to `nightly`
— but `origin/main` was never moved by automation. It only advanced when
a maintainer rebased it manually, so fresh checkouts of `main` lagged
upstream by days.

## Fix

On green nightlies, promote the verified rebased stack to `main`, gated
to once daily:

- **Once-daily gate.** The prepare job computes a `promote_main` output:
true only for the first scheduled run of the day (08:xx UTC of the five
daily crons) or a `workflow_dispatch` with the new `promote_main`
boolean input. Never true when `dry_run` is set.
- **Backup ref.** Before promoting, the run's starting `main` commit is
pushed to `backup/main-YYYYMMDD` (plain force, so a same-day re-run
doesn't fail on the existing backup).
- **Leased force-push.** `git push
--force-with-lease=refs/heads/main:${FORK_REF} origin
<verified-sha>:refs/heads/main` pins the lease to the exact commit the
run started from. The workflow concurrency group already serializes
nightly runs, so a failed lease means a human pushed `main` mid-run —
the step fails loudly and the existing Discord failure notification
fires instead of overwriting their work.
- **No-change days still promote.** The release job only runs when the
candidate differs from `origin/nightly`, so on a quiet overnight the
promotion step there would never fire and `main` could stay stale
indefinitely. When the gate is on but there are no new changes, the
prepare job instead aligns `main` to the existing `origin/nightly`
commit — its tree is identical to the freshly rebased candidate (that is
exactly what the no-change check means) and it already shipped through a
fully verified release, so no re-verification is needed. The step is a
clean no-op when `origin/nightly` doesn't exist or `main` already
matches it, avoiding daily backup/push churn across long quiet
stretches; otherwise it uses the same backup-ref and leased-force-push
mechanics as the release-job step.
- **Conflict path unchanged and human-owned.** A rebase conflict still
fails prepare before anything is promoted; maintainers resolve, verify,
push a backup branch, and force-push `main` as before. With new changes,
promotion only runs after the release publishes, and dry runs promote
nothing.

Docs: added a "Keeping `main` current" section to
`docs/operations/fork-nightly.md` distinguishing automated mechanical
promotion (post-release, or prepare-time alignment to the released
nightly on no-change days) from maintainer-reviewed conflict rebases.

## Why this supersedes the merge-candidate proposal

Issue #63 proposed building candidates by merging upstream into the fork
head so the workflow never owns rebase semantics. Since then the
operational reality settled the boundary differently: the nightly
already produces a fully verified rebased stack every run, and the only
missing piece was letting `main` benefit from it. Promoting the verified
rebase (with a backup ref and a lease guarding manual pushes) keeps
`main` a clean patch stack — no merge commits to unwind at the next
manual rebase — while conflicted rebases remain exactly the
maintainer-reviewed operation they are today. The merge-candidate
machinery would add a second candidate topology without removing any
human responsibility.

Closes #63

---

Built by Fable 5 (claude-fable-5) on Claude Code.
yngatech-nightly Bot pushed a commit that referenced this pull request Aug 13, 2026
## Problem

Fork Nightly rebases the patch stack onto upstream, fully verifies it
(check, typecheck, desktop builds, tests), and promotes it to `nightly`
— but `origin/main` was never moved by automation. It only advanced when
a maintainer rebased it manually, so fresh checkouts of `main` lagged
upstream by days.

## Fix

On green nightlies, promote the verified rebased stack to `main`, gated
to once daily:

- **Once-daily gate.** The prepare job computes a `promote_main` output:
true only for the first scheduled run of the day (08:xx UTC of the five
daily crons) or a `workflow_dispatch` with the new `promote_main`
boolean input. Never true when `dry_run` is set.
- **Backup ref.** Before promoting, the run's starting `main` commit is
pushed to `backup/main-YYYYMMDD` (plain force, so a same-day re-run
doesn't fail on the existing backup).
- **Leased force-push.** `git push
--force-with-lease=refs/heads/main:${FORK_REF} origin
<verified-sha>:refs/heads/main` pins the lease to the exact commit the
run started from. The workflow concurrency group already serializes
nightly runs, so a failed lease means a human pushed `main` mid-run —
the step fails loudly and the existing Discord failure notification
fires instead of overwriting their work.
- **No-change days still promote.** The release job only runs when the
candidate differs from `origin/nightly`, so on a quiet overnight the
promotion step there would never fire and `main` could stay stale
indefinitely. When the gate is on but there are no new changes, the
prepare job instead aligns `main` to the existing `origin/nightly`
commit — its tree is identical to the freshly rebased candidate (that is
exactly what the no-change check means) and it already shipped through a
fully verified release, so no re-verification is needed. The step is a
clean no-op when `origin/nightly` doesn't exist or `main` already
matches it, avoiding daily backup/push churn across long quiet
stretches; otherwise it uses the same backup-ref and leased-force-push
mechanics as the release-job step.
- **Conflict path unchanged and human-owned.** A rebase conflict still
fails prepare before anything is promoted; maintainers resolve, verify,
push a backup branch, and force-push `main` as before. With new changes,
promotion only runs after the release publishes, and dry runs promote
nothing.

Docs: added a "Keeping `main` current" section to
`docs/operations/fork-nightly.md` distinguishing automated mechanical
promotion (post-release, or prepare-time alignment to the released
nightly on no-change days) from maintainer-reviewed conflict rebases.

## Why this supersedes the merge-candidate proposal

Issue #63 proposed building candidates by merging upstream into the fork
head so the workflow never owns rebase semantics. Since then the
operational reality settled the boundary differently: the nightly
already produces a fully verified rebased stack every run, and the only
missing piece was letting `main` benefit from it. Promoting the verified
rebase (with a backup ref and a lease guarding manual pushes) keeps
`main` a clean patch stack — no merge commits to unwind at the next
manual rebase — while conflicted rebases remain exactly the
maintainer-reviewed operation they are today. The merge-candidate
machinery would add a second candidate topology without removing any
human responsibility.

Closes #63

---

Built by Fable 5 (claude-fable-5) on Claude Code.
yngatech-nightly Bot pushed a commit that referenced this pull request Aug 13, 2026
## Problem

Fork Nightly rebases the patch stack onto upstream, fully verifies it
(check, typecheck, desktop builds, tests), and promotes it to `nightly`
— but `origin/main` was never moved by automation. It only advanced when
a maintainer rebased it manually, so fresh checkouts of `main` lagged
upstream by days.

## Fix

On green nightlies, promote the verified rebased stack to `main`, gated
to once daily:

- **Once-daily gate.** The prepare job computes a `promote_main` output:
true only for the first scheduled run of the day (08:xx UTC of the five
daily crons) or a `workflow_dispatch` with the new `promote_main`
boolean input. Never true when `dry_run` is set.
- **Backup ref.** Before promoting, the run's starting `main` commit is
pushed to `backup/main-YYYYMMDD` (plain force, so a same-day re-run
doesn't fail on the existing backup).
- **Leased force-push.** `git push
--force-with-lease=refs/heads/main:${FORK_REF} origin
<verified-sha>:refs/heads/main` pins the lease to the exact commit the
run started from. The workflow concurrency group already serializes
nightly runs, so a failed lease means a human pushed `main` mid-run —
the step fails loudly and the existing Discord failure notification
fires instead of overwriting their work.
- **No-change days still promote.** The release job only runs when the
candidate differs from `origin/nightly`, so on a quiet overnight the
promotion step there would never fire and `main` could stay stale
indefinitely. When the gate is on but there are no new changes, the
prepare job instead aligns `main` to the existing `origin/nightly`
commit — its tree is identical to the freshly rebased candidate (that is
exactly what the no-change check means) and it already shipped through a
fully verified release, so no re-verification is needed. The step is a
clean no-op when `origin/nightly` doesn't exist or `main` already
matches it, avoiding daily backup/push churn across long quiet
stretches; otherwise it uses the same backup-ref and leased-force-push
mechanics as the release-job step.
- **Conflict path unchanged and human-owned.** A rebase conflict still
fails prepare before anything is promoted; maintainers resolve, verify,
push a backup branch, and force-push `main` as before. With new changes,
promotion only runs after the release publishes, and dry runs promote
nothing.

Docs: added a "Keeping `main` current" section to
`docs/operations/fork-nightly.md` distinguishing automated mechanical
promotion (post-release, or prepare-time alignment to the released
nightly on no-change days) from maintainer-reviewed conflict rebases.

## Why this supersedes the merge-candidate proposal

Issue #63 proposed building candidates by merging upstream into the fork
head so the workflow never owns rebase semantics. Since then the
operational reality settled the boundary differently: the nightly
already produces a fully verified rebased stack every run, and the only
missing piece was letting `main` benefit from it. Promoting the verified
rebase (with a backup ref and a lease guarding manual pushes) keeps
`main` a clean patch stack — no merge commits to unwind at the next
manual rebase — while conflicted rebases remain exactly the
maintainer-reviewed operation they are today. The merge-candidate
machinery would add a second candidate topology without removing any
human responsibility.

Closes #63

---

Built by Fable 5 (claude-fable-5) on Claude Code.
yngatech-nightly Bot pushed a commit that referenced this pull request Aug 13, 2026
## Problem

Fork Nightly rebases the patch stack onto upstream, fully verifies it
(check, typecheck, desktop builds, tests), and promotes it to `nightly`
— but `origin/main` was never moved by automation. It only advanced when
a maintainer rebased it manually, so fresh checkouts of `main` lagged
upstream by days.

## Fix

On green nightlies, promote the verified rebased stack to `main`, gated
to once daily:

- **Once-daily gate.** The prepare job computes a `promote_main` output:
true only for the first scheduled run of the day (08:xx UTC of the five
daily crons) or a `workflow_dispatch` with the new `promote_main`
boolean input. Never true when `dry_run` is set.
- **Backup ref.** Before promoting, the run's starting `main` commit is
pushed to `backup/main-YYYYMMDD` (plain force, so a same-day re-run
doesn't fail on the existing backup).
- **Leased force-push.** `git push
--force-with-lease=refs/heads/main:${FORK_REF} origin
<verified-sha>:refs/heads/main` pins the lease to the exact commit the
run started from. The workflow concurrency group already serializes
nightly runs, so a failed lease means a human pushed `main` mid-run —
the step fails loudly and the existing Discord failure notification
fires instead of overwriting their work.
- **No-change days still promote.** The release job only runs when the
candidate differs from `origin/nightly`, so on a quiet overnight the
promotion step there would never fire and `main` could stay stale
indefinitely. When the gate is on but there are no new changes, the
prepare job instead aligns `main` to the existing `origin/nightly`
commit — its tree is identical to the freshly rebased candidate (that is
exactly what the no-change check means) and it already shipped through a
fully verified release, so no re-verification is needed. The step is a
clean no-op when `origin/nightly` doesn't exist or `main` already
matches it, avoiding daily backup/push churn across long quiet
stretches; otherwise it uses the same backup-ref and leased-force-push
mechanics as the release-job step.
- **Conflict path unchanged and human-owned.** A rebase conflict still
fails prepare before anything is promoted; maintainers resolve, verify,
push a backup branch, and force-push `main` as before. With new changes,
promotion only runs after the release publishes, and dry runs promote
nothing.

Docs: added a "Keeping `main` current" section to
`docs/operations/fork-nightly.md` distinguishing automated mechanical
promotion (post-release, or prepare-time alignment to the released
nightly on no-change days) from maintainer-reviewed conflict rebases.

## Why this supersedes the merge-candidate proposal

Issue #63 proposed building candidates by merging upstream into the fork
head so the workflow never owns rebase semantics. Since then the
operational reality settled the boundary differently: the nightly
already produces a fully verified rebased stack every run, and the only
missing piece was letting `main` benefit from it. Promoting the verified
rebase (with a backup ref and a lease guarding manual pushes) keeps
`main` a clean patch stack — no merge commits to unwind at the next
manual rebase — while conflicted rebases remain exactly the
maintainer-reviewed operation they are today. The merge-candidate
machinery would add a second candidate topology without removing any
human responsibility.

Closes #63

---

Built by Fable 5 (claude-fable-5) on Claude Code.
yngatech-nightly Bot pushed a commit that referenced this pull request Aug 13, 2026
## Problem

Fork Nightly rebases the patch stack onto upstream, fully verifies it
(check, typecheck, desktop builds, tests), and promotes it to `nightly`
— but `origin/main` was never moved by automation. It only advanced when
a maintainer rebased it manually, so fresh checkouts of `main` lagged
upstream by days.

## Fix

On green nightlies, promote the verified rebased stack to `main`, gated
to once daily:

- **Once-daily gate.** The prepare job computes a `promote_main` output:
true only for the first scheduled run of the day (08:xx UTC of the five
daily crons) or a `workflow_dispatch` with the new `promote_main`
boolean input. Never true when `dry_run` is set.
- **Backup ref.** Before promoting, the run's starting `main` commit is
pushed to `backup/main-YYYYMMDD` (plain force, so a same-day re-run
doesn't fail on the existing backup).
- **Leased force-push.** `git push
--force-with-lease=refs/heads/main:${FORK_REF} origin
<verified-sha>:refs/heads/main` pins the lease to the exact commit the
run started from. The workflow concurrency group already serializes
nightly runs, so a failed lease means a human pushed `main` mid-run —
the step fails loudly and the existing Discord failure notification
fires instead of overwriting their work.
- **No-change days still promote.** The release job only runs when the
candidate differs from `origin/nightly`, so on a quiet overnight the
promotion step there would never fire and `main` could stay stale
indefinitely. When the gate is on but there are no new changes, the
prepare job instead aligns `main` to the existing `origin/nightly`
commit — its tree is identical to the freshly rebased candidate (that is
exactly what the no-change check means) and it already shipped through a
fully verified release, so no re-verification is needed. The step is a
clean no-op when `origin/nightly` doesn't exist or `main` already
matches it, avoiding daily backup/push churn across long quiet
stretches; otherwise it uses the same backup-ref and leased-force-push
mechanics as the release-job step.
- **Conflict path unchanged and human-owned.** A rebase conflict still
fails prepare before anything is promoted; maintainers resolve, verify,
push a backup branch, and force-push `main` as before. With new changes,
promotion only runs after the release publishes, and dry runs promote
nothing.

Docs: added a "Keeping `main` current" section to
`docs/operations/fork-nightly.md` distinguishing automated mechanical
promotion (post-release, or prepare-time alignment to the released
nightly on no-change days) from maintainer-reviewed conflict rebases.

## Why this supersedes the merge-candidate proposal

Issue #63 proposed building candidates by merging upstream into the fork
head so the workflow never owns rebase semantics. Since then the
operational reality settled the boundary differently: the nightly
already produces a fully verified rebased stack every run, and the only
missing piece was letting `main` benefit from it. Promoting the verified
rebase (with a backup ref and a lease guarding manual pushes) keeps
`main` a clean patch stack — no merge commits to unwind at the next
manual rebase — while conflicted rebases remain exactly the
maintainer-reviewed operation they are today. The merge-candidate
machinery would add a second candidate topology without removing any
human responsibility.

Closes #63

---

Built by Fable 5 (claude-fable-5) on Claude Code.
yngatech-nightly Bot pushed a commit that referenced this pull request Aug 14, 2026
## Problem

Fork Nightly rebases the patch stack onto upstream, fully verifies it
(check, typecheck, desktop builds, tests), and promotes it to `nightly`
— but `origin/main` was never moved by automation. It only advanced when
a maintainer rebased it manually, so fresh checkouts of `main` lagged
upstream by days.

## Fix

On green nightlies, promote the verified rebased stack to `main`, gated
to once daily:

- **Once-daily gate.** The prepare job computes a `promote_main` output:
true only for the first scheduled run of the day (08:xx UTC of the five
daily crons) or a `workflow_dispatch` with the new `promote_main`
boolean input. Never true when `dry_run` is set.
- **Backup ref.** Before promoting, the run's starting `main` commit is
pushed to `backup/main-YYYYMMDD` (plain force, so a same-day re-run
doesn't fail on the existing backup).
- **Leased force-push.** `git push
--force-with-lease=refs/heads/main:${FORK_REF} origin
<verified-sha>:refs/heads/main` pins the lease to the exact commit the
run started from. The workflow concurrency group already serializes
nightly runs, so a failed lease means a human pushed `main` mid-run —
the step fails loudly and the existing Discord failure notification
fires instead of overwriting their work.
- **No-change days still promote.** The release job only runs when the
candidate differs from `origin/nightly`, so on a quiet overnight the
promotion step there would never fire and `main` could stay stale
indefinitely. When the gate is on but there are no new changes, the
prepare job instead aligns `main` to the existing `origin/nightly`
commit — its tree is identical to the freshly rebased candidate (that is
exactly what the no-change check means) and it already shipped through a
fully verified release, so no re-verification is needed. The step is a
clean no-op when `origin/nightly` doesn't exist or `main` already
matches it, avoiding daily backup/push churn across long quiet
stretches; otherwise it uses the same backup-ref and leased-force-push
mechanics as the release-job step.
- **Conflict path unchanged and human-owned.** A rebase conflict still
fails prepare before anything is promoted; maintainers resolve, verify,
push a backup branch, and force-push `main` as before. With new changes,
promotion only runs after the release publishes, and dry runs promote
nothing.

Docs: added a "Keeping `main` current" section to
`docs/operations/fork-nightly.md` distinguishing automated mechanical
promotion (post-release, or prepare-time alignment to the released
nightly on no-change days) from maintainer-reviewed conflict rebases.

## Why this supersedes the merge-candidate proposal

Issue #63 proposed building candidates by merging upstream into the fork
head so the workflow never owns rebase semantics. Since then the
operational reality settled the boundary differently: the nightly
already produces a fully verified rebased stack every run, and the only
missing piece was letting `main` benefit from it. Promoting the verified
rebase (with a backup ref and a lease guarding manual pushes) keeps
`main` a clean patch stack — no merge commits to unwind at the next
manual rebase — while conflicted rebases remain exactly the
maintainer-reviewed operation they are today. The merge-candidate
machinery would add a second candidate topology without removing any
human responsibility.

Closes #63

---

Built by Fable 5 (claude-fable-5) on Claude Code.
yngatech-nightly Bot pushed a commit that referenced this pull request Aug 14, 2026
## Problem

Fork Nightly rebases the patch stack onto upstream, fully verifies it
(check, typecheck, desktop builds, tests), and promotes it to `nightly`
— but `origin/main` was never moved by automation. It only advanced when
a maintainer rebased it manually, so fresh checkouts of `main` lagged
upstream by days.

## Fix

On green nightlies, promote the verified rebased stack to `main`, gated
to once daily:

- **Once-daily gate.** The prepare job computes a `promote_main` output:
true only for the first scheduled run of the day (08:xx UTC of the five
daily crons) or a `workflow_dispatch` with the new `promote_main`
boolean input. Never true when `dry_run` is set.
- **Backup ref.** Before promoting, the run's starting `main` commit is
pushed to `backup/main-YYYYMMDD` (plain force, so a same-day re-run
doesn't fail on the existing backup).
- **Leased force-push.** `git push
--force-with-lease=refs/heads/main:${FORK_REF} origin
<verified-sha>:refs/heads/main` pins the lease to the exact commit the
run started from. The workflow concurrency group already serializes
nightly runs, so a failed lease means a human pushed `main` mid-run —
the step fails loudly and the existing Discord failure notification
fires instead of overwriting their work.
- **No-change days still promote.** The release job only runs when the
candidate differs from `origin/nightly`, so on a quiet overnight the
promotion step there would never fire and `main` could stay stale
indefinitely. When the gate is on but there are no new changes, the
prepare job instead aligns `main` to the existing `origin/nightly`
commit — its tree is identical to the freshly rebased candidate (that is
exactly what the no-change check means) and it already shipped through a
fully verified release, so no re-verification is needed. The step is a
clean no-op when `origin/nightly` doesn't exist or `main` already
matches it, avoiding daily backup/push churn across long quiet
stretches; otherwise it uses the same backup-ref and leased-force-push
mechanics as the release-job step.
- **Conflict path unchanged and human-owned.** A rebase conflict still
fails prepare before anything is promoted; maintainers resolve, verify,
push a backup branch, and force-push `main` as before. With new changes,
promotion only runs after the release publishes, and dry runs promote
nothing.

Docs: added a "Keeping `main` current" section to
`docs/operations/fork-nightly.md` distinguishing automated mechanical
promotion (post-release, or prepare-time alignment to the released
nightly on no-change days) from maintainer-reviewed conflict rebases.

## Why this supersedes the merge-candidate proposal

Issue #63 proposed building candidates by merging upstream into the fork
head so the workflow never owns rebase semantics. Since then the
operational reality settled the boundary differently: the nightly
already produces a fully verified rebased stack every run, and the only
missing piece was letting `main` benefit from it. Promoting the verified
rebase (with a backup ref and a lease guarding manual pushes) keeps
`main` a clean patch stack — no merge commits to unwind at the next
manual rebase — while conflicted rebases remain exactly the
maintainer-reviewed operation they are today. The merge-candidate
machinery would add a second candidate topology without removing any
human responsibility.

Closes #63

---

Built by Fable 5 (claude-fable-5) on Claude Code.
incognitojam added a commit that referenced this pull request Aug 15, 2026
## Problem

Fork Nightly rebases the patch stack onto upstream, fully verifies it
(check, typecheck, desktop builds, tests), and promotes it to `nightly`
— but `origin/main` was never moved by automation. It only advanced when
a maintainer rebased it manually, so fresh checkouts of `main` lagged
upstream by days.

## Fix

On green nightlies, promote the verified rebased stack to `main`, gated
to once daily:

- **Once-daily gate.** The prepare job computes a `promote_main` output:
true only for the first scheduled run of the day (08:xx UTC of the five
daily crons) or a `workflow_dispatch` with the new `promote_main`
boolean input. Never true when `dry_run` is set.
- **Backup ref.** Before promoting, the run's starting `main` commit is
pushed to `backup/main-YYYYMMDD` (plain force, so a same-day re-run
doesn't fail on the existing backup).
- **Leased force-push.** `git push
--force-with-lease=refs/heads/main:${FORK_REF} origin
<verified-sha>:refs/heads/main` pins the lease to the exact commit the
run started from. The workflow concurrency group already serializes
nightly runs, so a failed lease means a human pushed `main` mid-run —
the step fails loudly and the existing Discord failure notification
fires instead of overwriting their work.
- **No-change days still promote.** The release job only runs when the
candidate differs from `origin/nightly`, so on a quiet overnight the
promotion step there would never fire and `main` could stay stale
indefinitely. When the gate is on but there are no new changes, the
prepare job instead aligns `main` to the existing `origin/nightly`
commit — its tree is identical to the freshly rebased candidate (that is
exactly what the no-change check means) and it already shipped through a
fully verified release, so no re-verification is needed. The step is a
clean no-op when `origin/nightly` doesn't exist or `main` already
matches it, avoiding daily backup/push churn across long quiet
stretches; otherwise it uses the same backup-ref and leased-force-push
mechanics as the release-job step.
- **Conflict path unchanged and human-owned.** A rebase conflict still
fails prepare before anything is promoted; maintainers resolve, verify,
push a backup branch, and force-push `main` as before. With new changes,
promotion only runs after the release publishes, and dry runs promote
nothing.

Docs: added a "Keeping `main` current" section to
`docs/operations/fork-nightly.md` distinguishing automated mechanical
promotion (post-release, or prepare-time alignment to the released
nightly on no-change days) from maintainer-reviewed conflict rebases.

## Why this supersedes the merge-candidate proposal

Issue #63 proposed building candidates by merging upstream into the fork
head so the workflow never owns rebase semantics. Since then the
operational reality settled the boundary differently: the nightly
already produces a fully verified rebased stack every run, and the only
missing piece was letting `main` benefit from it. Promoting the verified
rebase (with a backup ref and a lease guarding manual pushes) keeps
`main` a clean patch stack — no merge commits to unwind at the next
manual rebase — while conflicted rebases remain exactly the
maintainer-reviewed operation they are today. The merge-candidate
machinery would add a second candidate topology without removing any
human responsibility.

Closes #63

---

Built by Fable 5 (claude-fable-5) on Claude Code.
yngatech-nightly Bot pushed a commit that referenced this pull request Aug 18, 2026
## Problem

Fork Nightly rebases the patch stack onto upstream, fully verifies it
(check, typecheck, desktop builds, tests), and promotes it to `nightly`
— but `origin/main` was never moved by automation. It only advanced when
a maintainer rebased it manually, so fresh checkouts of `main` lagged
upstream by days.

## Fix

On green nightlies, promote the verified rebased stack to `main`, gated
to once daily:

- **Once-daily gate.** The prepare job computes a `promote_main` output:
true only for the first scheduled run of the day (08:xx UTC of the five
daily crons) or a `workflow_dispatch` with the new `promote_main`
boolean input. Never true when `dry_run` is set.
- **Backup ref.** Before promoting, the run's starting `main` commit is
pushed to `backup/main-YYYYMMDD` (plain force, so a same-day re-run
doesn't fail on the existing backup).
- **Leased force-push.** `git push
--force-with-lease=refs/heads/main:${FORK_REF} origin
<verified-sha>:refs/heads/main` pins the lease to the exact commit the
run started from. The workflow concurrency group already serializes
nightly runs, so a failed lease means a human pushed `main` mid-run —
the step fails loudly and the existing Discord failure notification
fires instead of overwriting their work.
- **No-change days still promote.** The release job only runs when the
candidate differs from `origin/nightly`, so on a quiet overnight the
promotion step there would never fire and `main` could stay stale
indefinitely. When the gate is on but there are no new changes, the
prepare job instead aligns `main` to the existing `origin/nightly`
commit — its tree is identical to the freshly rebased candidate (that is
exactly what the no-change check means) and it already shipped through a
fully verified release, so no re-verification is needed. The step is a
clean no-op when `origin/nightly` doesn't exist or `main` already
matches it, avoiding daily backup/push churn across long quiet
stretches; otherwise it uses the same backup-ref and leased-force-push
mechanics as the release-job step.
- **Conflict path unchanged and human-owned.** A rebase conflict still
fails prepare before anything is promoted; maintainers resolve, verify,
push a backup branch, and force-push `main` as before. With new changes,
promotion only runs after the release publishes, and dry runs promote
nothing.

Docs: added a "Keeping `main` current" section to
`docs/operations/fork-nightly.md` distinguishing automated mechanical
promotion (post-release, or prepare-time alignment to the released
nightly on no-change days) from maintainer-reviewed conflict rebases.

## Why this supersedes the merge-candidate proposal

Issue #63 proposed building candidates by merging upstream into the fork
head so the workflow never owns rebase semantics. Since then the
operational reality settled the boundary differently: the nightly
already produces a fully verified rebased stack every run, and the only
missing piece was letting `main` benefit from it. Promoting the verified
rebase (with a backup ref and a lease guarding manual pushes) keeps
`main` a clean patch stack — no merge commits to unwind at the next
manual rebase — while conflicted rebases remain exactly the
maintainer-reviewed operation they are today. The merge-candidate
machinery would add a second candidate topology without removing any
human responsibility.

Closes #63

---

Built by Fable 5 (claude-fable-5) on Claude Code.
yngatech-nightly Bot pushed a commit that referenced this pull request Aug 18, 2026
## Problem

Fork Nightly rebases the patch stack onto upstream, fully verifies it
(check, typecheck, desktop builds, tests), and promotes it to `nightly`
— but `origin/main` was never moved by automation. It only advanced when
a maintainer rebased it manually, so fresh checkouts of `main` lagged
upstream by days.

## Fix

On green nightlies, promote the verified rebased stack to `main`, gated
to once daily:

- **Once-daily gate.** The prepare job computes a `promote_main` output:
true only for the first scheduled run of the day (08:xx UTC of the five
daily crons) or a `workflow_dispatch` with the new `promote_main`
boolean input. Never true when `dry_run` is set.
- **Backup ref.** Before promoting, the run's starting `main` commit is
pushed to `backup/main-YYYYMMDD` (plain force, so a same-day re-run
doesn't fail on the existing backup).
- **Leased force-push.** `git push
--force-with-lease=refs/heads/main:${FORK_REF} origin
<verified-sha>:refs/heads/main` pins the lease to the exact commit the
run started from. The workflow concurrency group already serializes
nightly runs, so a failed lease means a human pushed `main` mid-run —
the step fails loudly and the existing Discord failure notification
fires instead of overwriting their work.
- **No-change days still promote.** The release job only runs when the
candidate differs from `origin/nightly`, so on a quiet overnight the
promotion step there would never fire and `main` could stay stale
indefinitely. When the gate is on but there are no new changes, the
prepare job instead aligns `main` to the existing `origin/nightly`
commit — its tree is identical to the freshly rebased candidate (that is
exactly what the no-change check means) and it already shipped through a
fully verified release, so no re-verification is needed. The step is a
clean no-op when `origin/nightly` doesn't exist or `main` already
matches it, avoiding daily backup/push churn across long quiet
stretches; otherwise it uses the same backup-ref and leased-force-push
mechanics as the release-job step.
- **Conflict path unchanged and human-owned.** A rebase conflict still
fails prepare before anything is promoted; maintainers resolve, verify,
push a backup branch, and force-push `main` as before. With new changes,
promotion only runs after the release publishes, and dry runs promote
nothing.

Docs: added a "Keeping `main` current" section to
`docs/operations/fork-nightly.md` distinguishing automated mechanical
promotion (post-release, or prepare-time alignment to the released
nightly on no-change days) from maintainer-reviewed conflict rebases.

## Why this supersedes the merge-candidate proposal

Issue #63 proposed building candidates by merging upstream into the fork
head so the workflow never owns rebase semantics. Since then the
operational reality settled the boundary differently: the nightly
already produces a fully verified rebased stack every run, and the only
missing piece was letting `main` benefit from it. Promoting the verified
rebase (with a backup ref and a lease guarding manual pushes) keeps
`main` a clean patch stack — no merge commits to unwind at the next
manual rebase — while conflicted rebases remain exactly the
maintainer-reviewed operation they are today. The merge-candidate
machinery would add a second candidate topology without removing any
human responsibility.

Closes #63

---

Built by Fable 5 (claude-fable-5) on Claude Code.
yngatech-nightly Bot pushed a commit that referenced this pull request Aug 18, 2026
## Problem

Fork Nightly rebases the patch stack onto upstream, fully verifies it
(check, typecheck, desktop builds, tests), and promotes it to `nightly`
— but `origin/main` was never moved by automation. It only advanced when
a maintainer rebased it manually, so fresh checkouts of `main` lagged
upstream by days.

## Fix

On green nightlies, promote the verified rebased stack to `main`, gated
to once daily:

- **Once-daily gate.** The prepare job computes a `promote_main` output:
true only for the first scheduled run of the day (08:xx UTC of the five
daily crons) or a `workflow_dispatch` with the new `promote_main`
boolean input. Never true when `dry_run` is set.
- **Backup ref.** Before promoting, the run's starting `main` commit is
pushed to `backup/main-YYYYMMDD` (plain force, so a same-day re-run
doesn't fail on the existing backup).
- **Leased force-push.** `git push
--force-with-lease=refs/heads/main:${FORK_REF} origin
<verified-sha>:refs/heads/main` pins the lease to the exact commit the
run started from. The workflow concurrency group already serializes
nightly runs, so a failed lease means a human pushed `main` mid-run —
the step fails loudly and the existing Discord failure notification
fires instead of overwriting their work.
- **No-change days still promote.** The release job only runs when the
candidate differs from `origin/nightly`, so on a quiet overnight the
promotion step there would never fire and `main` could stay stale
indefinitely. When the gate is on but there are no new changes, the
prepare job instead aligns `main` to the existing `origin/nightly`
commit — its tree is identical to the freshly rebased candidate (that is
exactly what the no-change check means) and it already shipped through a
fully verified release, so no re-verification is needed. The step is a
clean no-op when `origin/nightly` doesn't exist or `main` already
matches it, avoiding daily backup/push churn across long quiet
stretches; otherwise it uses the same backup-ref and leased-force-push
mechanics as the release-job step.
- **Conflict path unchanged and human-owned.** A rebase conflict still
fails prepare before anything is promoted; maintainers resolve, verify,
push a backup branch, and force-push `main` as before. With new changes,
promotion only runs after the release publishes, and dry runs promote
nothing.

Docs: added a "Keeping `main` current" section to
`docs/operations/fork-nightly.md` distinguishing automated mechanical
promotion (post-release, or prepare-time alignment to the released
nightly on no-change days) from maintainer-reviewed conflict rebases.

## Why this supersedes the merge-candidate proposal

Issue #63 proposed building candidates by merging upstream into the fork
head so the workflow never owns rebase semantics. Since then the
operational reality settled the boundary differently: the nightly
already produces a fully verified rebased stack every run, and the only
missing piece was letting `main` benefit from it. Promoting the verified
rebase (with a backup ref and a lease guarding manual pushes) keeps
`main` a clean patch stack — no merge commits to unwind at the next
manual rebase — while conflicted rebases remain exactly the
maintainer-reviewed operation they are today. The merge-candidate
machinery would add a second candidate topology without removing any
human responsibility.

Closes #63

---

Built by Fable 5 (claude-fable-5) on Claude Code.
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.

ci(fork): build nightly candidates by merging upstream

1 participant