Skip to content

Local release trains: fold tooling that closes superseded PRs and cancels their runs, tied to local cross-repo packages #25

Open

Description

@woksin

Local release trains combine several branches into one PR, one CI run and one release. Today the steps around a train are manual and get forgotten. On 2026-10-23, six Chronicle PRs (#5319, #5316, #5315, #5314, #5312, #5303) stayed open for hours after their branches were already merged into the local train for #5296. They would have rerun CI on every update. Folding is also not connected to local cross-repository verification (the cratis-engineering-local-cross-repo-verification skill in Cratis/AI), so downstream repositories verify against per-PR packages instead of the train's code state.

woksin (2026-10-23): "when this is decided and we know which already existing Prs that will be superseeded that we close these PRs and stop the running workflows associated with them as soon as possible" and "The clossing of PRs and stopping of workflows associated should be a rule / system in the local PI systems we have when we are merging and "release traninging" locally ... this also in someway needs to play nicely together with the "local packaging" system that we have for downstream and upstream package dependency local testing".

Rule (AGENTS.md, "Shipping finished work")

  • Bundle branches locally before any PR exists. A PR is opened only for a train, never for a single delivery that will be folded.
  • As soon as an existing PR's branch is merged into a local train branch, or it is decided that it will be, close that PR with "Folded into ". Cancel its queued and in-progress runs and move its release-note bullet into the train's note. Do this immediately, not at train push.
  • Never push to a branch whose PR is folded or is going to be folded.

System (tooling)

A small pi-train tool, or lane subcommands, backed by a per-repository train manifest (for example .ai-work/trains/<repo>/<train>.json, holding the train branch, base SHA, folded branches with their SHAs and PRs, release bullets, the local package version, and upstream and downstream links):

  • init <repo> <train-branch>: cut the train from current origin/main and create the manifest.
  • fold <PR|branch>:
    • Merge the branch into the train locally.
    • Record it in the manifest.
    • If a PR exists: close it with the standard comment, cancel every non-completed run for its head branch, and copy its release-note bullets into the train note draft.
    • Refuse a PR that has unresolved review requests from people other than the author.
  • planned <PR> <train>: for a fold decided for a later train. Close the PR now with "Will be folded into " and cancel its runs.
  • status: folded, planned and pending items, open PRs whose branch is an ancestor of a train without being closed (anomalies), and runs still active on folded branches.
  • ship: push the train once, open or update the train PR with the aggregated note, and run the repo's PR-body check.
  • A guard (pre-push hook or pi extension) that refuses a push to a folded branch.

Local packages (works with cross-repo verification)

  • Each train code state builds its local packages once, with a train-unique prerelease version such as <next>-train.<short-sha>. This uses the pi-phase ledger, so an unchanged train state is never rebuilt.
  • Downstream repositories verify against the train's packages, not per-PR packages. The manifest records which downstream trains or lanes consume which upstream train version.
  • Upstream-first ordering: when a downstream train depends on an upstream train, status shows the order. The downstream ships only after the upstream releases and the pin is bumped to the released version. Local versions never reach a commit or PR, and the existing guard is reused.
  • A fold into an upstream train marks the downstream verification stale, and the downstream owner re-verifies against the new train packages.

Done when

  • The rule is in ~/.pi/agent/AGENTS.md and matches the L0 rules file (rule 10).
  • pi-train (init, fold, planned, status, ship, guard) works and has tests, including cancel and close on a sandbox repository or with a mocked gh.
  • lanes status and the repo-orchestrator brief (Repo orchestrator: one coordinating session per repository when several lanes work in it #20) use the manifest. The cratis-engineering-local-cross-repo-verification skill in Cratis/AI references train packages; that part is a separate Cratis/AI issue.
  • It is released in pi-setup.

Status

State: Paused — Not being worked now. Remaining: slice (c) train packages (waits for Cratis/AI#881, now in AI candidate 8) and lanes status reading the train manifest.
Branch: -
Scope: Rule in AGENTS.md first; pi-train tool in slices (a) fold/planned/status, (b) ship + push guard, (c) train packages and ordering.
Delivered: Nothing yet.
Remaining: To be confirmed.
Follow-ups: None.

Activity

  1. self-assigned this
    on Oct 23, 2026
  2. woksin commented on Oct 23, 2026

    @woksin
    OwnerAuthor

    Slice (a) is released in v2026.10.23.23 and installed live: pi-train init, fold, planned and status. The AGENTS.md rule shipped in v2026.10.23.22. Next is slice (b): ship, the push guard, and init --adopt for train branches that were assembled by hand. Slice (c) after that covers train packages; the Cratis/AI side is Cratis/AI#881.

  3. woksin commented on Oct 23, 2026

    @woksin
    OwnerAuthor

    Slice (b) is released in v2026.10.23.25 and installed live. It adds pi-train ship, init --adopt, the trains push guard extension, and an opt-in pre-push hook that lets the push through when the guard itself fails. Remaining: slice (c), train packages and upstream/downstream ordering, together with Cratis/AI#881, and lanes status plus the repo-orchestrator brief reading the manifest.

  4. woksin commented on Oct 23, 2026

    @woksin
    OwnerAuthor

    Added to scope (L0, ALL-RULES rule 11, woksin: "prefer as big chunks as makes sense to do in terms of completed time / when they are ready to merge, but it is at least good for the CI pipeline to reduce stress on it"): pi-train fold and planned take a per-delivery --eta that is stored in the manifest. pi-train status shows a cut recommendation: hold when a pending delivery is due within one gate duration, where the gate duration comes from the pi-phase ledger. The AGENTS.md rule ("Size trains by readiness") is committed and ships with the next release.

  5. woksin commented on Oct 23, 2026

    @woksin
    OwnerAuthor

    Released in v2026.10.23.30 and .31, and installed live:

    • fold and planned take --eta; pi-train eta updates or clears an ETA.
    • status gives a hold or cut recommendation, using a gate duration taken from the pi-phase ledger.
    • pi-train close [--shipped PR#] [--head sha] | [--abandoned] marks a train finished.
    • status --all keeps going when a train's worktree is missing.

    Remaining:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

P2Wanted, not nowtype: featureCategory: feature

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions