Skip to content

release-train: develop -> staging - #322

Merged
tracebloc-release-train[bot] merged 5 commits into
stagingfrom
release-train/to-staging
Aug 24, 2026
Merged

release-train: develop -> staging#322
tracebloc-release-train[bot] merged 5 commits into
stagingfrom
release-train/to-staging

Conversation

@LukasWodka

@LukasWodkaLukasWodka commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Automated promotion by the release train (RFC-0008 D14). Head is the train-managed release-train/to-staging branch (a mirror of develop), so it never collides with a human PR. Merged only when the fr-gate is green.


Note

Medium Risk
Org-wide CI that mints a GitHub App token and reads cross-repo issue graphs on every PR open/reopen. The new job is not a required check, but a false fail-open would leave kanban cards unmoved behind a green pipeline.

Overview
When a PR title names a ticket, the body must now create a real GitHub closing link (Closes owner/repo#N). That link is what closes the issue on merge to develop and what kanban-closure-router uses to move the card — title-only refs were inert, so boards stayed stale behind green checks.

The check is a second job on the existing set-pr-status reusable (same event, org-scoped App token, no new inventory row). It is on by default, required nowhere. Drafts and titles with no ticket pass. Bare numbers match any repo at that number; a spelled repo that links the same number elsewhere is wrong-repo. API/permission failures exit 2 even under soft-fail. PR template and org-standards branch-model bullets are updated to match.

Separately, this repo gets a customer-priority-bump-caller.yml and the last customer_priority_bump_caller_missing exemptions are flipped to required (anchor deleted). Bug-labelled issues here can now land in Ready instead of Backlog.

Reviewed by Cursor Bugbot for commit 26bb09d. Bugbot is set up for automated code reviews on this repo. Configure here.

LukasWodkaand others added 4 commits August 24, 2026 10:35
…its caller (#320)
The conformance audit went red and blocked the .github prod promotion (#318):
release-train: customer-priority-bump.yml is marked `exempt` but a caller
exists (customer-priority-bump.yml). The exemption is stale - promote it to
`required` or delete the caller.
backend#2396 wired that caller in release-train this morning (c0c6cf7, 'so a bug
lands in Ready'); this file still claimed the repo had none. The audit is right
and the inventory was wrong.
Flipped release-train's entry to `required`. The shared anchor STAYS: it is still
cited by two other repos that genuinely have no caller, so deleting it would be
wrong -- this is the opposite of the kanban_closure_router case documented a few
lines below, where the anchor is cited once and a flip orphans it.
Also corrected the citation count in that neighbouring comment from 3x to 2x, and
recorded why the anchor survives. That count is the only thing telling the next
person whether a flip orphans the anchor, and nothing checks it -- no check flags
an orphaned YAML anchor, as the same comment says. A stale count there is how the
next flip deletes a live anchor or keeps a dead one.
Sequencing is per this file's own note: land the caller first, flip the entry
after. The caller is already on release-train's develop.
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…#314)
* ci(2364): a PR whose title names a ticket must link it (backend#2364)
Merging a fix never closed or advanced its ticket. `closingIssuesReferences`
was 0 on 7 of 7 sampled merged PRs (release-train#109/#108, .github#304/#300,
backend#2266, client#774, docs#131). The house convention puts the ticket in
the PR TITLE; GitHub creates a closing link ONLY from a keyword in the BODY, so
a title reference is inert. `kanban-closure-router.yml` fires, finds no linked
issue, and correctly does nothing -- every kanban workflow green, every card
unmoved.
Adds a `closing-ref` job to the EXISTING `set-pr-status.yml` reusable: parse the
real title, assert the real `closingIssuesReferences` contains what it names.
Derived, not restated (rule 1): two live reads, no list of tickets, repos or
authors. The four title forms are measured, not imagined. A bare `#N` outside
parentheses is deliberately NOT read as a ticket -- backend#2309's `#2271` is
prose about a PR, and scanning loose `#N` would redden a compliant PR.
Fails closed (rule 3): a blank title, a GraphQL error, `pullRequest: null`, a
null/ownerless node, or `totalCount > len(nodes)` all exit 2 as "cannot tell",
never a pass and never a finding against the author. The truncation test is
load-bearing beyond pagination -- a link to an issue the token cannot read comes
back missing from `nodes` while `totalCount` still counts it, which is
indistinguishable from "not linked".
The cross-repo trap is its own verdict: `WRONG_REPO` is reported apart from
`MISSING` because the remedies differ -- a bare `Closes#304` in `.github` links
`.github#304`, closing the wrong issue on merge, and needs the line rewritten
rather than added.
Fixtures are measured bytes (the backend#2114 lesson), captured with
`gh api graphql` and re-verified against the live API before commit.
Tests: 102 selftest assertions; 34 mutations, 0 stale, 0 uncaught. The mutation
harness edits the real gate and re-runs the real suite -- no inline copy of any
rule (rule 9, .github#114/#115). Every anchor must match exactly once, which is
the assertion that it actually applied. Refusals are asserted by their own
message, never a catch-all (rule 10). The commit-type vocabulary is derived out
of org-standards.md and the derivation fails closed if it finds nothing (rule 6).
Arming: `closing-ref` is a required status check NOWHERE -- measured across 19
repos x develop/staging/main/master x both classic protection and rulesets -- so
a finding blocks no merge (rule 4). Callers trigger on
opened/reopened/ready_for_review/converted_to_draft, not `synchronize`, so the
13 open PRs that would report a finding are not reddened by a push.
Touches no file in `conformance-gate.yml`'s GUARDED list, and needs no
`repo-inventory.yml` row: the inventory tracks callers, one row per reusable,
and `set-pr-status.yml` already has its rows.
Closestracebloc/backend#2364
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(2364): the remedy stops guessing a repo it cannot know (backend#2364)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(2364): the scope pattern admits a leading dot too, so .github stops depending on a coincidence (backend#2364)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…restating it (backend#2422) (#321)
The bullet named its own exceptions -- "`docs` and `rfcs` are main-only" --
one sentence after naming `repo-inventory.yml` as the authority and saying
"this line follows it, not the reverse." It then drifted from that authority
on BOTH examples:
* `docs` has been on the release train since 2026-08-04 (release_train:
true, develop: required, staging present) while this line called it
main-only.
* `rfcs` had a `develop` taking merges, measured 2026-08-22 in backend#2242
/ .github#306, while this line called it main-only.
That is the restated-rule defect the file's own meta-rule warns about, and it
is not theoretical: I read this line on 2026-08-19, concluded `rfcs` should be
main-only, created a `develop` there to satisfy the first bullet, and forked
the repo -- 9 commits on develop against 5 on main over four days, both sides
editing README.md, reconciled by hand in rfcs#50.
So the enumeration is removed rather than corrected. A list of repo names in
prose will drift again; a pointer to the file that is measured will not.
Also records the trap the inventory found and no check catches: a `develop`
created on a non-train repo and left unprotected is invisible to the guards
(`develop_unprotected_non_train` -- "a `develop` created and left UNPROTECTED
is not flagged ... no check was going to surface it"). Creating one to satisfy
the train bullet forks the repo silently. Stating it here because the guard
cannot, which is exactly what this file is for.
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…f the flip (backend#2396) (#316)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@LukasWodka

Copy link
Copy Markdown
ContributorAuthor

bugbot run

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 78f6b6b. Configure here.

…ey emptied (#319)
* fix(2396): release-train rides the label trigger, so its exemption stops being stale (backend#2396)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* ci(2396): flip .github and rfcs to required, and delete the anchor they emptied
Both callers are live on their default branches (.github#316, rfcs#47), so the
`exempt` rows became the stale-exemption finding caller-drift.py:2309 exists to
catch. Flipping them takes the anchor to zero citations, so its definition is
deleted in the same PR rather than left as dead prose.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@LukasWodka

Copy link
Copy Markdown
ContributorAuthor

bugbot run

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 26bb09d. Configure here.

@tracebloc-release-traintracebloc-release-trainBot added gate-nudge Toggled by the release train to (re-)fire the fr-gate and removed gate-nudge Toggled by the release train to (re-)fire the fr-gate labels Aug 24, 2026
@tracebloc-release-train
tracebloc-release-trainBot merged commit 2700b9e into stagingAug 24, 2026
27 checks passed
@tracebloc-release-train
tracebloc-release-trainBot deleted the release-train/to-staging branch August 24, 2026 10:55
@tracebloc-release-train
tracebloc-release-trainBot restored the release-train/to-staging branch August 24, 2026 11:21
Sign up for freeto 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

@LukasWodka