Skip to content

Commit de49740

Browse files
committed
Post-meeting propagation: merge draft-v8 into draft-v9
2 parents d68b04d + af9d23e commit de49740

34 files changed

Lines changed: 569 additions & 92 deletions
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
mode: agent
3+
description: (Stub) Converge a finished version's draft and alpha branches.
4+
---
5+
6+
# Post-meeting: converge draft and alpha for a completed version
7+
8+
> **Status: not finalized.** The exact end-state for converging `draft-vN` and `vN-alpha` when version N is finished has not been decided by the committee. **Do not run this prompt yet.** Ask the user for the intended target state first, then update this prompt with the agreed procedure before executing anything.
9+
10+
## Open questions to resolve before implementing
11+
12+
- When v8 is finalized, does `draft-v8` become `standard-v8`, and is `v8-alpha` deleted? Or is `v8-alpha` merged into `draft-v8` first(and if so, which way do feature-PR conflicts resolve)? Note that v8 currently has no alpha branch.
13+
- What renames or branch-protection updates are needed?
14+
- What needs to happen to in-flight feature PRs whose base was the retired `vN-alpha`?
15+
- Is there a Word/PDF artifact step to run at convergence?
16+
- How do we reconcile feature PRs whose `draft-vN` head differs from the version already merged into `vN-alpha`? See the alpha-drift handling in `post-meeting-rebase-prs.prompt.md` (Step 0). Convergence must define whether the canonical text is the alpha version, the draft version, or requires per-file manual reconciliation.
17+
- How do we audit that no committee-approved deletion on `vN-alpha` was silently resurrected during the version's propagation history? Suggested: a final `git log --diff-filter=D` review against the `standard-v(N-1)` baseline at convergence time.
18+
- Disposition of any unrouted or still-unresolved vNext HTML comments remaining in `standard/*.md` when version N converges (see Step 0.5 of `post-meeting-rebase-prs.prompt.md`). Do they get applied, deferred to v(N+1), or deleted?
19+
20+
## Outline (to be fleshed out once decided)
21+
22+
1. Verify all feature PRs targeting `vN-alpha` and `draft-vN` are merged or reassigned to a later branch.
23+
2. Reconcile `draft-vN` and `vN-alpha` per the committee's decision.
24+
3. Rename / retire branches as decided.
25+
4. Update `admin/branch-diagram.md`, `README.md`, and the propagate prompt's chain to remove the retired branches.
26+
5. Update branch protection rules and `.github/workflows/update-on-merge.yaml`.
27+
28+
When the semantics are decided, replace this stub with a full procedure modeled on `post-meeting-propagate.prompt.md`.
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
---
2+
mode: agent
3+
description: Propagate post-meeting changes through all draft and alpha branches.
4+
---
5+
6+
# Post-meeting: propagate changes through draft & alpha branches
7+
8+
You are propagating the changes merged into the current "starting" draft branch (after a TC49-TG2 committee meeting) forward through every future draft and alpha branch. See `admin/branch-diagram.md` for the rationale.
9+
10+
## Assumptions
11+
12+
- The committee secretary has already merged all approved PRs into the starting branch (default: `draft-v8`). Do **not** merge any other open PRs.
13+
- The `.github/workflows/update-on-merge.yaml` workflow will open an automated PR titled "Automated Section renumber and grammar extraction" on each branch that receives a push. These auto-PRs **must be merged** before the next propagation hop.
14+
- You have `git` and `gh` available, and push permission to this repo.
15+
16+
## Propagation chain
17+
18+
Walk these branches in order. Each step merges the previous branch into the next with a regular merge commit and pushes.
19+
20+
1. `draft-v8` (starting branch — no merge in; just merge its auto-PR)
21+
2. `draft-v9` ← merges `draft-v8`
22+
3. `v9-alpha` ← merges `draft-v9`
23+
4. `draft-v10` ← merges `v9-alpha`
24+
5. `v10-alpha` ← merges `draft-v10`
25+
6. `draft-v11` ← merges `v10-alpha`
26+
7. `v11-alpha` ← merges `draft-v11`
27+
8. `draft-v12` ← merges `v11-alpha`
28+
29+
> When new version branches are added (v12-alpha, draft-v13, etc.), append
30+
> them here in the same pattern: each `draft-v(N+1)` merges `vN-alpha`, and
31+
> each `vN-alpha` merges `draft-vN`. Also add the new branches to
32+
> `.github/workflows/update-on-merge.yaml` `on.push.branches`.
33+
34+
If the user names a different starting branch, start there and propagate to
35+
every later branch in the list.
36+
37+
## Pre-flight (run once, before walking the chain)
38+
39+
These artifacts are referenced by Step B (conflict resolution) and Step B.6
40+
(future-version comment inventory). Capture them up front and persist them
41+
for the duration of the run.
42+
43+
1. **Baseline.** Determine the SHA on each branch in the chain at the
44+
*previous* propagation. A reliable proxy is the most recent merge commit whose subject begins with `Post-meeting propagation:` on that branch (`git log --grep '^Post-meeting propagation:' -1 --format=%H origin/<branch>`). Record `BASE_<branch>` for each branch. If a branch has no such commit yet, fall back to the branch point and warn the user.
45+
46+
2. **Deletion inventory** for the starting branch. Identify text the
47+
committee removed in this cycle so Step B can recognize resurrection:
48+
49+
```bash
50+
# Files where lines were removed since the previous propagation:
51+
git log "$BASE_<starting>"..origin/<starting> --diff-filter=MD \
52+
--name-only --pretty=format: -- standard/ | sort -u
53+
54+
# Hunks (negative lines) for review:
55+
git log "$BASE_<starting>"..origin/<starting> -p -- standard/ \
56+
> /tmp/starting-deletions.patch
57+
```
58+
59+
Show the user the list of PRs merged this cycle (`gh pr list --base <starting> --state merged --search 'merged:>=<last-meeting-date>'`) and ask which performed substantive prose removals. Persist that list.
60+
61+
3. **vNext-comment baseline** for every branch in the chain. Snapshot the current set of HTML comments in `standard/*.md` mentioning a future version, so Step B.6 can diff against it after each merge:
62+
63+
```bash
64+
for b in <chain>; do
65+
git --no-pager grep -nE '<!--[^>]*(vNext|v[0-9]+|future|upcoming|TODO)' \
66+
"origin/$b" -- 'standard/*.md' > /tmp/vnext-baseline-$b.txt || true
67+
done
68+
```
69+
70+
The grep is intentionally loose (false positives are fine — Phase 4 surfaces them for human triage; nothing is auto-applied).
71+
72+
## Procedure
73+
74+
Before starting, confirm the chain with the user and show which branches will be touched. Confirm the pre-flight artifacts above are captured. Then for each branch in order:
75+
76+
### Step A — Process auto-PR on the current branch
77+
78+
1. `git fetch --all --prune`
79+
2. `git checkout <branch>` and `git pull --ff-only`
80+
3. Find the auto-PR opened by `update-on-merge.yaml`:
81+
82+
```bash
83+
gh pr list --base <branch> --state open \
84+
--search 'in:title "Automated Section renumber and grammar extraction"' \
85+
--json number,headRefName,mergeable,mergeStateStatus
86+
```
87+
88+
4. If found:
89+
- Wait until checks pass (`gh pr checks <num> --watch` is acceptable, with a reasonable timeout — if it doesn't go green within a few minutes, stop and ask the user).
90+
- The auto-PR's checks include the `StandardAnchorTags` job. If that job reports any `TOC002` ("`<ref>` not found") diagnostic, **stop** even if `gh pr checks` reports the PR overall as mergeable — broken cross-references must be resolved before merging.
91+
- Merge it with a **merge commit**: `gh pr merge <num> --merge --delete-branch`.
92+
- `git pull --ff-only` on the branch.
93+
5. If not found and this is the starting branch, ask the user whether to wait, run the tools locally (`tools/run-smarten.sh`, `tools/run-section-renumber.sh`), or proceed without them. Do not run tools locally without explicit consent.
94+
6. If not found on a downstream branch (it should appear after the merge in step B below), continue.
95+
96+
### Step B — Merge from previous branch (skip on the starting branch)
97+
98+
1. Still on `<branch>`, run:
99+
100+
```bash
101+
git merge --no-ff origin/<previous-branch> \
102+
-m "Post-meeting propagation: merge <previous-branch> into <branch>"
103+
```
104+
105+
2. **Conflicts:**
106+
- **Never blanket "take upstream"** on a conflict whose hunks touch
107+
prose in `standard/*.md`. Doing so can silently resurrect text the
108+
committee deleted on the downstream branch in this cycle or a prior
109+
one.
110+
- For each conflicted hunk in `standard/*.md`:
111+
a. Cross-check the hunk's file and line range against the deletion inventory captured in Pre-flight (`/tmp/starting-deletions.patch`) **and** against any prior `Post-meeting propagation:` merges on the downstream branch (`git log --grep '^Post-meeting propagation:' -p origin/<branch> -- <file>`).
112+
b. If the downstream side intentionally removed the text, keep the deletion and re-apply only non-overlapping upstream edits to the surrounding region.
113+
c. If unclear, **abort the merge** (`git merge --abort`) and report to the user with the file, line range, and both sides of the hunk.
114+
- Mechanical "take upstream" is acceptable **only** for:
115+
- regenerated `standard/grammar.md`,
116+
- TOC blocks below the `<!-- The remaining text is generated by a tool. Do not hand edit -->`marker,
117+
- the generated TOC in `standard/README.md`.
118+
- For any conflict in `tools/`, `.github/`, or any prose conflict you are not 100% sure is mechanical: **abort the merge** and stop.
119+
3. After conflicts are resolved (or if the merge was clean), **do not push yet**. Run Steps B.5 and B.6 below first.
120+
121+
### Step B.5 — Cross-reference validation
122+
123+
Run the section-renumber tool in dry-run mode against the post-merge working tree to surface broken or drifted cross-references *before* pushing:
124+
125+
```bash
126+
( cd tools && dotnet run --project StandardAnchorTags -- \
127+
--owner dotnet --repo csharpstandard --dryrun )
128+
```
129+
130+
1. **Broken references.** Any `TOC002` ("`<ref>` not found") diagnostic is a **hard stop**. Reset the merge commit (`git reset --hard origin/<branch>`), report the failing references to the user, and do not push.
131+
2. **Concept drift.** Count how many section numbers the dry run would change (lines beginning with `§` in the tool's diff output). If more than ~25 sections shift, sections have drifted enough that surviving cross-references like `§X.Y (Foo)` may now point at a different concept — the renumber tool fixes the *number* but cannot detect when the *concept* (parenthetical name, surrounding prose) is now wrong. Pause, list the affected references to the user, and proceed only on explicit confirmation.
132+
3. The actual renumber/grammar regeneration runs in the auto-PR opened by `update-on-merge.yaml` after push (Step A on the next iteration); do not commit dry-run output.
133+
134+
### Step B.6 — Future-version comment inventory
135+
136+
Diff the current branch's HTML comments mentioning future versions
137+
against the Pre-flight baseline to surface anything new this propagation brought in (these are notes the committee left for upcoming versions and need to be routed to the appropriate feature PRs by `post-meeting-rebase-prs.prompt.md`):
138+
139+
```bash
140+
git --no-pager grep -nE '<!--[^>]*(vNext|v[0-9]+|future|upcoming|TODO)' \
141+
HEAD -- 'standard/*.md' > /tmp/vnext-current-<branch>.txt
142+
diff /tmp/vnext-baseline-<branch>.txt /tmp/vnext-current-<branch>.txt \
143+
> /tmp/vnext-delta-<branch>.txt || true
144+
```
145+
146+
For each *new* comment in the delta, record:
147+
148+
- file path and line number,
149+
- full comment text,
150+
- branch where it appeared (`<branch>`),
151+
- best-guess target version parsed from the comment (e.g. `v10` from `<!-- v10: tighten wording -->`); leave blank if not parseable.
152+
153+
Persist the accumulated list across the whole run. Include it in the final report so `post-meeting-rebase-prs.prompt.md` can consume it. **Do not edit `standard/*.md` to remove or apply these comments.**
154+
155+
### Step B.7 — Push
156+
157+
1. Push: `git push origin <branch>`.
158+
2. The push triggers `update-on-merge.yaml`, which will open a fresh auto-PR. Loop back to Step A for this branch before moving on.
159+
160+
### Step C — Move to the next branch
161+
162+
Repeat A–B for the next branch in the chain. Continue until the chain is done.
163+
164+
## Reporting
165+
166+
When finished (or when stopped on a conflict), produce a short report:
167+
168+
- For each branch: action taken (auto-PR merged, propagation merge SHA, skipped).
169+
- Any branches where you stopped and why.
170+
- The deletion inventory captured in Pre-flight (file list + originating PR numbers).
171+
- The accumulated future-version comment inventory from Step B.6 (file:line, comment text, source branch, best-guess target version). Hand this to `post-meeting-rebase-prs.prompt.md`.
172+
- A reminder to the user to run `post-meeting-rebase-prs.prompt.md` next.
173+
174+
## Safety rules
175+
176+
- Never force-push to any `draft-v*` or `v*-alpha` branch.
177+
- Never use `git reset --hard` on a tracked branch.
178+
- Never merge any PR other than the automated renumber/grammar PR.
179+
- If `gh` shows the auto-PR's checks failing, stop and ask the user.
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
---
2+
mode: agent
3+
description: Rebase same-repo feature PRs and notify fork PR authors after propagation.
4+
---
5+
6+
# Post-meeting: rebase / notify feature PRs
7+
8+
After `post-meeting-propagate.prompt.md` has updated all draft/alpha branches, every open feature PR is now stale relative to its base. Update each PR according to whether its head branch is in this repo or on a fork.
9+
10+
This prompt also consumes two artifacts from the propagate run:
11+
12+
- the **future-version comment inventory** (Step B.6 of the propagate prompt) — used by Step 0.5 below to route those notes to the appropriate feature PRs;
13+
- the deletion inventory — used as context when judging rebase conflicts.
14+
15+
Ask the user for the propagate report (or its location) before starting.
16+
17+
## Procedure
18+
19+
### Step 0 — Detect feature-PR drift across cycles
20+
21+
A feature PR open against `draft-vN` may have been edited between meetings, while an *earlier* version of the same feature was already merged into `vN-alpha` at a previous meeting. Plain propagation will not carry the new edits onto `vN-alpha` until the next meeting. Surface these so authors can decide whether to open a separate alpha-targeted PR sooner.
22+
23+
For every open PR P with base `draft-vN`:
24+
25+
1. Read its files: `gh pr view <num> --json files,author,number,headRefOid`.
26+
2. Look for prior commits on `vN-alpha` by the same author touching the same files:
27+
28+
```bash
29+
git log origin/vN-alpha --author='<login>' -- <files…>
30+
```
31+
32+
3. If prior commits exist and the current PR head SHA introduces changes to those files not yet on `vN-alpha`, record P as **"alpha has stale version"**.
33+
34+
Surface the list to the user. **Do not** cherry-pick or push to `vN-alpha`. Instead, post the **alpha-drift notice** comment template (below) on each affected PR; the marker dedupes on rerun.
35+
36+
### Step 0.5 — Route future-version comments to feature PRs
37+
38+
Consume the future-version comment inventory from the propagate prompt's report. For each entry (file:line, comment text, source branch, best-guess target `vN`):
39+
40+
1. List candidate open PRs:
41+
42+
```bash
43+
gh pr list --base draft-vN --state open --json number,title,files,url
44+
gh pr list --base vN-alpha --state open --json number,title,files,url
45+
```
46+
47+
2. Match the comment to candidate PRs by:
48+
- **file path**: the comment's file appears in the PR's changed files;
49+
- **proximity**: the comment's line is within or near a hunk modified by the PR (best-effort; surface multiple candidates rather than guessing).
50+
51+
3. For each (comment, candidate-PR) pair, post the **vNext-routing** comment template (below) on the PR. The HTML marker `<!-- post-meeting-vnext-routing -->` includes the source `file:line` so re-runs do not duplicate (skip if a comment with that marker and the same `file:line` already exists on the PR).
52+
53+
4. Comments with **no** candidate PR are listed in the final report under "unrouted vNext comments" for the user to triage.
54+
55+
If `vN` is missing or unparseable from the comment, list the entry as unrouted and surface it in the report.
56+
57+
**This step never edits `standard/*.md`.** The prompts neither apply nor remove these comments; the matched PR's author decides whether to fold the change in or open a new PR.
58+
59+
### Step 1 — List target base branches
60+
61+
List target base branches (the propagation chain — see the propagate prompt). Default: `draft-v8 draft-v9 v9-alpha draft-v10 v10-alpha draft-v11 v11-alpha draft-v12`. Allow the user to override.
62+
63+
### Step 2 — For each base branch, list and process open PRs
64+
65+
For each base branch, list open PRs:
66+
67+
```bash
68+
gh pr list --base <base> --state open \
69+
--json number,title,headRefName,headRepositoryOwner,isDraft,author,url
70+
```
71+
72+
For each PR returned:
73+
74+
- If `headRepositoryOwner.login` matches this repo's owner (`dotnet`), the head is in this repo. **Rebase it:**
75+
1. `gh pr checkout <num>`
76+
2. **Capture the pre-rebase SHA** so we can recover if the post-rebase cross-reference check fails: `PRE=$(git rev-parse HEAD)`.
77+
3. `git fetch origin <base>`
78+
4. `git rebase origin/<base>`
79+
5. **If the rebase has conflicts:** `git rebase --abort`, record the PR as "needs manual rebase", post the **attempted-rebase** comment below, and move on. Do not attempt to resolve feature-text conflicts.
80+
6. **Cross-reference check before push.** Run the renumber tool in dry-run mode against the rebased worktree:
81+
82+
```bash
83+
( cd tools && dotnet run --project StandardAnchorTags -- \
84+
--owner dotnet --repo csharpstandard --dryrun )
85+
```
86+
87+
If any `TOC002` diagnostic fires, the rebase has produced broken cross-references. Recover with `git reset --hard "$PRE"`, record the PR as "needs manual rebase", and post the **attempted-rebase** comment below with the failing references quoted in the body. Do not push.
88+
7. Otherwise: `git push --force-with-lease`. Record success with the new SHA.
89+
90+
- If the head is on a fork, **do not attempt to rebase.** Post the
91+
**please-rebase** comment below. Avoid duplicate comments: skip if any existing comment on the PR already contains the marker `<!-- post-meeting-rebase-notice -->`.
92+
93+
## Comment templates
94+
95+
The HTML comment is a marker so re-runs don't duplicate.
96+
97+
**Please-rebase (fork PRs and any PR not yet notified):**
98+
99+
```markdown
100+
<!-- post-meeting-rebase-notice -->
101+
The base branch `{{base}}` has been updated following the latest TC49-TG2 committee meeting. Please rebase this PR onto the latest `{{base}}` and resolve any conflicts. Thanks!
102+
```
103+
104+
**Attempted-rebase (same-repo PRs that hit conflicts):**
105+
106+
```markdown
107+
<!-- post-meeting-rebase-notice -->
108+
I attempted to rebase this PR onto the updated `{{base}}` after the latest TC49-TG2 committee meeting but encountered conflicts. Please rebase locally and resolve them. Thanks!
109+
```
110+
111+
**Alpha-drift notice (feature PRs whose alpha branch already has an older version of this feature):**
112+
113+
```markdown
114+
<!-- post-meeting-rebase-notice -->
115+
An earlier version of this feature is already present on `{{alpha}}` from a prior meeting. Edits made to this PR since then are **not** yet on `{{alpha}}`; they will land at the next propagation. If you need them on `{{alpha}}` sooner, please open a separate PR targeting `{{alpha}}`.
116+
Thanks!
117+
```
118+
119+
**vNext-routing (notes left on an older version that target this PR's
120+
version):**
121+
122+
```markdown
123+
<!-- post-meeting-vnext-routing source={{file}}:{{line}} -->
124+
While propagating post-meeting changes, the following note targeting `{{target_version}}` was found on `{{source_branch}}` at `{{file}}:{{line}}`:
125+
126+
> {{comment_text}}
127+
128+
This PR appears to touch the same area. Please consider whether this note applies — either fold the change into this PR or open a follow-up. The note in `standard/*.md` was **not** edited or removed by tooling.
129+
```
130+
131+
Post via `gh pr comment <num> --body-file <tempfile>`.
132+
133+
## Reporting
134+
135+
At the end, output a table grouped by base branch:
136+
137+
- PRs successfully rebased + force-pushed (with new SHA)
138+
- PRs left for manual rebase (with reason — including any failing `TOC002` references from the post-rebase cross-reference check)
139+
- Fork PRs commented on
140+
- PRs that already had the notice (skipped)
141+
- PRs flagged with the **alpha-drift notice** (Step 0)
142+
- vNext comments routed (PR number + source `file:line`) and any **unrouted vNext comments** for human triage (Step 0.5)
143+
144+
## Safety rules
145+
146+
- Never close or merge a feature PR.
147+
- Never push to a fork.
148+
- Always use `--force-with-lease`, never `--force`.
149+
- If `gh pr checkout` fails (e.g. permissions), record and skip.
-115 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)