ci(nightly): promote verified rebased stack to main daily - #80
Merged
Conversation
incognitojam
force-pushed
the
ci/nightly-promote-main
branch
from
August 11, 2026 13:09
1f4d4cb to
eb660e3
Compare
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
force-pushed
the
ci/nightly-promote-main
branch
from
August 11, 2026 13:27
eb660e3 to
78cd635
Compare
This was referenced Aug 11, 2026
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.
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
Fork Nightly rebases the patch stack onto upstream, fully verifies it (check, typecheck, desktop builds, tests), and promotes it to
nightly— butorigin/mainwas never moved by automation. It only advanced when a maintainer rebased it manually, so fresh checkouts ofmainlagged upstream by days.Fix
On green nightlies, promote the verified rebased stack to
main, gated to once daily:promote_mainoutput: true only for the first scheduled run of the day (08:xx UTC of the five daily crons) or aworkflow_dispatchwith the newpromote_mainboolean input. Never true whendry_runis set.maincommit is pushed tobackup/main-YYYYMMDD(plain force, so a same-day re-run doesn't fail on the existing backup).git push --force-with-lease=refs/heads/main:${FORK_REF} origin <verified-sha>:refs/heads/mainpins 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 pushedmainmid-run — the step fails loudly and the existing Discord failure notification fires instead of overwriting their work.origin/nightly, so on a quiet overnight the promotion step there would never fire andmaincould stay stale indefinitely. When the gate is on but there are no new changes, the prepare job instead alignsmainto the existingorigin/nightlycommit — 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 whenorigin/nightlydoesn't exist ormainalready 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.mainas before. With new changes, promotion only runs after the release publishes, and dry runs promote nothing.Docs: added a "Keeping
maincurrent" section todocs/operations/fork-nightly.mddistinguishing 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
mainbenefit from it. Promoting the verified rebase (with a backup ref and a lease guarding manual pushes) keepsmaina 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.