Skip to content

ci(fork): report the full release scope, not just mobile - #349

Merged
patroza merged 1 commit into
fork/devfrom
fork-dev/release-summary-scope
Aug 6, 2026
Merged

ci(fork): report the full release scope, not just mobile#349
patroza merged 1 commit into
fork/devfrom
fork-dev/release-summary-scope

Conversation

@omegent-app

@omegent-app omegent-app Bot commented Aug 6, 2026

Copy link
Copy Markdown

The release summary asserted that server, Discord, desktop and VS Code are promoted by the poller,
but never said whether this SHA actually selects any of them. The one question worth asking — what
does this release move — still needed a trip to the smart host.

Change

Classify all seven keys instead of only mobile, using scripts/classify-deployment-diff.shthe
same script the poller runs
, so the report and the fleet cannot disagree about what a diff means.

The summary now renders, against the previous released SHA:

Target Selected Promoted by
Server (restart) yes smart-host poller
Discord bot yes smart-host poller
Desktop yes smart-host poller
VS Code yes smart-host poller
Mobile (EAS) yes this workflow

Plus the diffed range, the classification basis, a collapsed changed-file list, and:

  • web_hot_swap shown on the server row, because it changes promotion from a restart to a bundle
    swap — a materially different operation to read as "server: yes".
  • A non-runtime-only range called out explicitly, rather than five silent no rows that look like a
    bug.

Verified against real ranges, not by reading

Range Result
21badd04e..a5ff7e40c (upstream import, 37 runtime paths) deploy=true, every target selected
3a7e7a458..a5ff7e40c (workflow files only) deploy=false, nothing promoted

The caveat, stated in the summary itself

The poller diffs against the last SHA it actually deployed, which is not always the last
released SHA — a promotion it skipped, or one that failed part-way, leaves its baseline behind this
one. When they diverge the poller selects a superset of the reported rows, never a subset, so the
table cannot claim a target is moving when it is not. That direction is the safe one, and it is
written into the summary rather than left for someone to rediscover.

Making it exact would mean reading poller state that lives on the smart host and is not reachable
from CI, so the report is honest about being a faithful re-computation rather than a mirror.

Co-authored by @patroza

opened by Patrick Roza in chat thread Discord · Discord · T3

The release summary asserted that server, Discord, desktop and VS Code are
promoted by the poller but never said whether this SHA actually selects any of
them, so the one question worth asking — what does this release move — needed a
trip to the smart host to answer.

Classify all seven keys instead of only mobile, using
scripts/classify-deployment-diff.sh: the same script the poller runs, so the
report and the fleet cannot disagree about what a diff means. Render a table of
every target against the previous released SHA, note web_hot_swap on the server
row because it changes promotion from a restart to a bundle swap, and call out a
non-runtime-only range explicitly rather than showing five silent "no" rows.

Verified against real ranges rather than by reading. 21badd0..a5ff7e4 (the
upstream import, 37 runtime paths) reports every target selected;
3a7e7a4..a5ff7e4 (workflow files only) reports deploy=false and nothing
promoted.

The caveat is stated in the summary rather than left implicit: the poller diffs
against the last SHA it actually deployed, which is not always the last released
SHA, because a skipped or partly failed promotion leaves its baseline behind.
When they diverge the poller selects a superset of the reported rows, never a
subset, so the table cannot claim a target is moving when it is not.

Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
@patroza
patroza merged commit 885f127 into fork/dev Aug 6, 2026
5 checks passed
omegent-app Bot added a commit that referenced this pull request Aug 6, 2026
Records the `fork/dev` development and release model — **adopted and
live since 2026-08-06**. This
started as a proposal; the migration then ran ahead of it, so the
document is now the record rather
than the plan.

Documentation only. Every mechanism it describes is already merged and
running.

## The model

`fork/dev` is the default branch, the contributor target and the release
source. It is never rebased.
The provenance stack `main → fork/base → fork/tim → fork/candidates`
stays rebased and feeds
`fork/dev` through reviewed tree deltas, so contributor bases are never
invalidated by an upstream
update.

| In place | |
| --- | --- |
| `fork/dev` cut from green `fork/integration` `21badd04e`, trees proven
identical | tag `fork-dev/2026-08-06.1` |
| Default branch, ruleset, squash-only, required checks | live |
| CI for `fork/dev` PRs and merges | #343 |
| Deployment promoting exact green `fork/dev` SHAs | ops `deploy.env` |
| Validation and release split | #347, #349 |
| First provenance sync, upstream `2a04db134..a2ca89a` | #345, tag
`fork-dev/2026-08-06.2` |
| Upstream ancestry recorded so "behind" reads true | `3a7e7a458` |
| Overlays drained and deregistered | #348 |

## What this revision corrects

The document had drifted from what was actually built:

- **Release is two workflows, not one.** `fork-ci` decides whether a SHA
is valid; `fork-release`
acts on that verdict via `workflow_run`. A release action must never be
able to veto a validation
verdict — when mobile dispatch lived inside `fork-ci`, one failed EAS
call marked a valid SHA
  unapprovable and stranded the whole fleet.
- **Check selection is *not* path-inferred**, and the document
previously implied it should be. Every
PR runs all four required checks; only *release* scope is classified. A
path filter that errs
narrow silently skips a check on a protected branch, which is worse than
a slightly slower suite.
- **`fork/changes` and `fork/integration` are frozen**, not fallbacks.
- Ops parameterization and the `deploy.env` cutover are **done**, not
pending.
- Steps that were "do now" are recorded as done, with real SHAs, tags
and ruleset contents.

## What the cutover surfaced

Added as a section, because each cost a round trip and the old path hid
all of them:

- `fork/dev` had **no CI path at all** — no `push` trigger, not listed
as a `pull_request` base.
- **Mobile releases would have stopped silently**; nothing errors when a
gated job just never fires.
- Both mobile workflows **hardcoded `ref: fork/integration`** and
rejected every `fork/dev` SHA.
- A release failure could **strand the fleet**.
- **Every PR based on `fork/changes` was already broken** by earlier
rebases — GitHub reported them
as 60–100 commits and 629–741 files. Each was one commit of real work on
stale history, fixed by
  cherry-picking that commit rather than replaying the branch.

That last one is the clearest evidence for the whole premise: the old
model was silently corrupting
in-flight work, and nobody could see it.

## Deliberately not done

Clean downstream projection is deferred indefinitely and nothing depends
on it. Provenance sync stays
manual. The overlay machinery is still present and still passes its
tests with an empty manifest;
removing it touches ~20 files and is a separate decision.

## Still open

PRs #317, #226 and #185 conflict when cherry-picked onto `fork/dev`;
#237 and #238 live in an
external fork and need their author. `fork/changes` and
`fork/integration` can be deleted once those
are drained.

## Also: no guidance targets an overlay any more

The overlays were drained in #348, but the instructions an agent or
contributor actually reads before
opening a PR still sent them at `fork/discord`, `fork/vscode`,
`fork/identity`, the desktop
deep-links branch, or `fork/changes`. Left alone, the next client-owned
change would have been opened
against a **closed overlay on a frozen branch**.

- **`CLAUDE.md`** (`AGENTS.md` symlinks to it): branch from and target
`fork/dev` for every kind of
work; `main`, `fork/changes` and `fork/integration` named as bases never
to use; the
"register an `integrationOverlays` entry" instructions replaced with a
record that it is empty.
- **`apps/discord-bot/docs/agent-turn-rules.md`**: recovery branches
pointed at *"the correct base
  (`fork/discord` overlay / `fork/changes` / etc.)"* → `fork/dev`.
- **`fork-stack.md`, `stack-ship-path.md`, `client-overlays.md`**:
bannered as superseded rather than
rewritten — the provenance stack they document is still current and they
are the record of how the
fork worked before the cutover. The two lines that literally instructed
a base are corrected.

Verified by grep: nothing in the repository still directs a PR anywhere
but `fork/dev`.

## Validation


`vp fmt --check` clean; internal anchors checked. Documentation only —
no code, tooling or workflow
changes in this PR.

Co-authored by [@patroza](https://github.com/patroza)

opened by [Patrick Roza](https://discord.com/users/95218063095377920) in
chat thread **Discord** ·
[Discord](https://discord.com/channels/1083767712431480922/1534783738322485399/1534783738322485399)
· [T3](https://t3vm/?thread=584a9ad3-243e-4308-8a13-49acdd758b17)

---------

Co-authored-by: T3 Code PR Stack <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: omegent-app[bot] <306514130+omegent-app[bot]@users.noreply.github.com>
Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant