-
Notifications
You must be signed in to change notification settings - Fork 1
Enforce source-atomic release backports #142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -60,6 +60,26 @@ The single lane still gets a Lane Card, claim/heartbeat behavior when configured | |
| a one-row file-touch map, a Batch QA Lane decision, current-head review and CI | ||
| checks, and the canonical terminal state and handoff evidence. | ||
|
|
||
| ## Release Backport Granularity | ||
|
|
||
| When consumer policy selects merged base-branch work for a release branch, | ||
| default to **one merged source PR per release backport PR**. Give each source its | ||
| own target, lane, branch, validation, and release PR. Serialize work to the same | ||
| release line: merge one, refresh the release tip, then branch the next. Do not | ||
| combine independent sources because they share a destination, component, | ||
| milestone, or changelog. A shared changelog is a serialization reason, not a | ||
| bundling reason. | ||
|
|
||
| Combine only behaviorally inseparable sources that cannot be reviewed, tested, | ||
| or reverted safely alone; record the exact refs, dependency proof, and | ||
| maintainer-approved exception rationale first. | ||
| Use the consumer's cherry-pick/provenance method, preserve release-only | ||
| divergence, and stamp release notes after accepted backports. | ||
|
|
||
| If an aggregate backport PR already exists, do not keep extending it by default. | ||
| Recommend separate replacements; close the aggregate only with explicit write | ||
| authorization, and retain its branch unless branch deletion was also authorized. | ||
|
Comment on lines
+63
to
+81
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This section fully restates the "Release Backport Granularity" policy from The restatement has already drifted from the canonical version in
Since this is a safety policy meant to stop agents from re-creating the exact bundling mistake described in the PR description, an agent that only loads this SKILL.md (per the "entry point" note above) could miss the eligibility/search steps or misjudge who can authorize a close. Consider replacing this section with a short pointer to |
||
|
|
||
| Resolve the target repo's `base_branch` from `.agents/agent-workflow.yml` when present, otherwise from the `AGENTS.md` | ||
| **Agent Workflow Configuration** seam. If neither declares it, report | ||
| `base_branch: UNKNOWN` and stop before branching. Run | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,10 @@ def assert(condition, message) | |
| abort("FAIL: #{message}") unless condition | ||
| end | ||
|
|
||
| def includes_words?(text, phrase) | ||
| text.gsub(/\s+/, " ").include?(phrase) | ||
| end | ||
|
Comment on lines
+13
to
+15
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: |
||
|
|
||
| batch = read_repo_file("skills/pr-batch/SKILL.md") | ||
| guide = read_repo_file("docs/pr-batch-skills.md") | ||
| workflow = read_repo_file("workflows/pr-processing.md") | ||
|
|
@@ -60,6 +64,17 @@ def assert(condition, message) | |
| assert(workflow.include?("coordination target or explicit no-backend single-operator approval"), "ad-hoc degraded coordination must stop for a safe ownership decision") | ||
| assert(workflow.include?("or inline `AGENTS.md` configuration"), "canonical goal handoff must support inline AGENTS configuration") | ||
|
|
||
| assert(batch.include?("one merged source PR per release backport PR"), "pr-batch must keep release backports source-atomic") | ||
| assert(includes_words?(batch, "refresh the release tip, then branch the next"), "pr-batch must refresh the release tip between backports") | ||
| assert(includes_words?(batch, "A shared changelog is a serialization reason, not a bundling reason"), "pr-batch must serialize shared-changelog backports") | ||
| assert(workflow.include?("### Release Backport Granularity"), "canonical processing must define release backport granularity") | ||
| assert(includes_words?(workflow, "Assign that source PR its own lane, branch, provenance record, release PR"), "canonical processing must preserve one source per release lane") | ||
| assert(includes_words?(workflow, "branch the next backport from that exact tip"), "canonical processing must branch from the refreshed release tip") | ||
| assert(includes_words?(workflow, "close it only when the user or maintainer explicitly authorizes that write"), "canonical processing must require authority to close aggregate PRs") | ||
| assert(guide.include?("one source PR -> one release PR"), "guide must document source-atomic release backports") | ||
| assert(includes_words?(guide, "explicit maintainer-approved exception"), "guide must require approval to combine backports") | ||
| assert(guide.include?("Closing the aggregate is a GitHub write"), "guide must preserve aggregate-PR close authority") | ||
|
|
||
| assert(batch.include?("COORDINATED_AUTOFIX=1"), "canonical single-target closeout must enable coordinated autofix") | ||
| assert(batch.include?("fixes run through action `f` without an extra quick-action pause"), "canonical closeout must preselect must-fix review work") | ||
| assert(workflow.include?("set trusted parent state\n`COORDINATED_AUTOFIX=1`"), "canonical processing must pass coordinated autofix explicitly") | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -231,6 +231,36 @@ Worker path: | |
| 4. If the published phase and the tracker disagree, treat it as a | ||
| `release-mode-conflict` per `AGENTS.md`, report it, and do not auto-merge. | ||
|
|
||
| ### Release Backport Granularity | ||
|
|
||
| When the consumer repo permits a merged base-branch fix to enter a release | ||
| branch, use one source PR per release backport PR unless the consumer policy is | ||
| stricter: | ||
|
|
||
| 1. Verify the source PR is merged, belongs on the selected release line, is not | ||
| already present or superseded there, and can be validated independently. | ||
| 2. Assign that source PR its own lane, branch, provenance record, release PR, | ||
| review cycle, QA evidence, and rollback boundary. | ||
| 3. Serialize backports to the same release line. Re-fetch the release branch | ||
| after each merge and branch the next backport from that exact tip. | ||
| 4. Do not combine independent source PRs merely because they target the same | ||
| release, touch related code, or edit the same changelog. A shared changelog is | ||
| a serialization reason, not a bundling reason; stamp or regenerate release | ||
| notes after all selected backports land. | ||
| 5. Combine source PRs only when they are behaviorally inseparable and separate | ||
| review, validation, or rollback would be unsafe. Record the constituent | ||
| source refs, dependency proof, and maintainer-approved exception before | ||
| implementation. | ||
| 6. Apply the consumer repo's required cherry-pick/provenance method. Preserve | ||
| release-only divergence instead of replacing files with base-branch | ||
| post-images, and document every conflict resolution. | ||
|
|
||
| Before creating a release branch, search open release-targeted PRs for an | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When backporting to an existing release line, agents normally create a short-lived backport branch/PR, not a new release branch; elsewhere in this section “release branch” means the target release line. Gating the aggregate-PR search on “creating a release branch” lets the intended duplicate/aggregate detection be skipped for normal backports, so please make the search happen before creating each backport branch/PR. Useful? React with 👍 / 👎. |
||
| existing aggregate of the selected sources. Do not extend or silently adopt an | ||
| aggregate PR that violates this rule. Recommend closing it in favor of separate | ||
| backports; close it only when the user or maintainer explicitly authorizes that | ||
| write, and do not delete its branch without separate authorization. | ||
|
|
||
| ### Tracker Update Safety | ||
|
|
||
| Tracker issue bodies are shared mutable state. Avoid clobbering another agent's update: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: unlike neighboring sections in this guide (e.g. the pause/cancellation links a few lines up), this new "Release backports" section doesn't link to the canonical detail in
workflows/pr-processing.md(### Release Backport Granularity). Adding[Release Backport Granularity](../workflows/pr-processing.md#release-backport-granularity)would keep this guide consistent with its own established cross-linking convention and reduce the chance of the three copies of this policy (guide, SKILL.md, workflow.md) drifting apart — see the related comment onskills/pr-batch/SKILL.md.