diff --git a/.github/prompts/post-meeting-propagate.prompt.md b/.github/prompts/post-meeting-propagate.prompt.md index 3168964a5..a206be59c 100644 --- a/.github/prompts/post-meeting-propagate.prompt.md +++ b/.github/prompts/post-meeting-propagate.prompt.md @@ -51,10 +51,17 @@ head-movement checks defined below. - A numbered heading can retain a stale symbolic anchor such as `§xx` or `§some-placeholder`. +- An alpha can retain feature-branch placeholder headings because only a + dry-run renumber was performed. - A feature PR can move after the patch cutoff, making the recorded patch stale even when it still applies cleanly. +- Example projects can silently compile with an SDK default language version + or the wrong target framework. - A downstream conflict resolution can preserve older normative structure or wording instead of the intended later-version language. +- A malformed feature-source block quote, fence, heading, or grammar line can + make downstream renumbering or conversion fail even when an aggregate-only + patch appears to repair the symptom. ## Assumptions @@ -62,6 +69,9 @@ head-movement checks defined below. - 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. - Auto-PRs may show a `BLOCKED` merge state due to branch protection rules requiring review approval — this is normal and not a CI failure. Wait for checks to pass, then merge. - You have `git` and `gh` available, and push permission to this repo. +- An alpha/aggregate branch represents a complete feature set. Do not create, + infer, reconstruct, or push a missing alpha branch unless the user confirms + that the feature set is complete and explicitly authorizes the aggregate. ## Authoritative remote (set and validate once) @@ -110,6 +120,9 @@ Do not rely on a fixed list or assume every alpha is named `alpha-vN`. followed by its discovered alpha when one exists. Confirm the order against `admin/branch-diagram.md` and remote ancestry. Report the exact discovered chain before changing anything. +4. Treat a version with no discovered alpha as draft-and-feature-only. Stop + at that version unless the user explicitly authorizes creating an + aggregate after confirming that its feature set is complete. > **Walk this chain as a per-version, atomic-per-version sweep.** For each > version N, finish `draft-vN` (propagate committee changes + renumber + @@ -150,14 +163,27 @@ for the duration of the run. count differs from a fresh enumeration of open PRs on the discovered target draft branches. -2. **Baseline.** Determine the SHA on each branch in the chain at the +2. **Workspace integrity.** Record the main checkout's branch, `HEAD`, status, + worktree list, and stash list. Perform branch rewrites and validation in + isolated worktrees. Do not switch, reset, clean, stash, or apply/drop + stashes in the protected main checkout. At closeout, prove that its files + and stash identities/order are unchanged. + +3. **Version-validation plan.** For every version N in scope, record the + intended target framework and require ordinary example templates to + contain both an explicit `` and + `N`. Identify any intentionally isolated legacy + template and prove that no version-N feature selects it. Do not accept SDK + defaults as proof of the effective language version. + +4. **Baseline.** Determine the SHA on each branch in the chain at the *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 "$REMOTE/"`). Record `BASE_` for each branch. If a branch has no such commit yet, fall back to the branch point and warn the user. -3. **Deletion inventory** for the starting branch. Identify text the +5. **Deletion inventory** for the starting branch. Identify text the committee removed in this cycle so Step B can recognize resurrection: ```bash @@ -172,7 +198,7 @@ for the duration of the run. Show the user the list of PRs merged this cycle (`gh pr list --base --state merged --search 'merged:>='`) and ask which performed substantive prose removals. Persist that list. -4. **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: +6. **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: ```bash for b in ; do @@ -249,6 +275,9 @@ Before starting, confirm the chain with the user and show which branches will be - TOC blocks below the ``marker, - the generated TOC in `standard/README.md`. - For any conflict in `tools/`, `.github/`, or any prose conflict you are not 100% sure is mechanical: **abort the merge** and stop. + - Correct shared defects at the earliest branch that contains them, then + restart propagation from that branch. Do not apply a downstream-only + patch when the same malformed source would remain in an ancestor. 3. After conflicts are resolved (or if the merge was clean), **do not push yet**. Run Steps B.5 and B.6 below first. 4. **Section-number drift in alpha branches.** Alpha branches often have additional sections inserted (e.g. new feature clauses), which shift @@ -271,9 +300,9 @@ Run the section-renumber tool in dry-run mode against the post-merge working tre 1. **Broken references.** Any *new* `TOC002` ("`` not found") diagnostic that was not already present on `"$REMOTE/"` before the merge is a **hard stop**. Compare the tool output against a pre-merge - run (or `git stash && run && git stash pop`) to distinguish new from - pre-existing. Pre-existing TOC002s from incomplete feature PRs on alpha - branches are expected and should be reported but do not block the merge. + run in an isolated worktree to distinguish new from pre-existing. + Pre-existing TOC002s may be inventoried while integration is in progress, + but they must be resolved before the branch is finalized or pushed. 2. **Mandatory raw symbolic-reference audit.** Run this independently of the tool and save the output: @@ -283,9 +312,9 @@ Run the section-renumber tool in dry-run mode against the post-merge working tre > "$RUN_DIR/symbolic-refs-.txt" || true ``` - Review every match. A retained placeholder is a hard stop unless the - branch intentionally permits that exact pre-merge placeholder and it is - recorded in the report. This raw audit is mandatory because + Review every match. Feature PR source branches may retain a valid + placeholder while authoring is incomplete; draft and alpha branches may + not. This raw audit is mandatory because `StandardAnchorTags` and its `TOC002` diagnostics previously missed placeholders that remained in otherwise valid text, including symbolic anchors left after headings had already been numbered. @@ -391,6 +420,9 @@ feature deltas**, built in ONE pass: replace an alpha file with the feature PR's version. Preserve branch-specific later-version language and structure unless the feature itself intentionally changes it. + If malformed markup originates on a feature PR branch, stop, fix and push + that source branch first, refresh its manifest SHA and patch, and only then + integrate it. Do not hide a source defect with an aggregate-only edit. 3. **Perform a semantic three-way comparison for every high-conflict normative section.** Compare: - the section in the prior finalized alpha (`BASE_`), @@ -410,23 +442,26 @@ feature deltas**, built in ONE pass: error. For each drifted ref, read the intended concept from the merged anchor slug, find that concept's actual number on this branch, and set BOTH the number and the anchor manually. -5. **Dry-run and raw-reference validate.** Alpha branches commonly get no - auto-PR, so do **not** commit renumber/grammar output; revert only that - generated validation output after checking it, without reverting the - surgical feature-delta edits: +5. **Run the exact renumber and prove idempotence.** Feature PR branches may + retain valid placeholder headings while their text is under review. + Alpha and aggregate branches may not: every standard heading must be fully + numeric before the alpha is complete. Run the same non-dry-run command + used by the renumber workflow: ```bash ( cd tools && dotnet run --project StandardAnchorTags -- \ - --owner dotnet --repo csharpstandard --dryrun ) + --owner dotnet --repo csharpstandard ) ``` - Any *new* `TOC002` diagnostic relative to the pre-rebuild baseline is a - **hard stop**. Also repeat the mandatory raw `rg` audit from Step B.5 - across all `standard/*.md`; any unexplained `§[a-z][a-z0-9-]*`, `§xx`, - or `#xx` match is a hard stop. + Save the resulting diff, verify heading hierarchy and duplicates, and + require zero placeholder headings. Run the exact command a second time + and require no further semantic or tree change. Any new `TOC002`, + malformed heading, duplicate, skipped hierarchy, or second-run change is + a hard stop. Also repeat the mandatory raw `rg` audit from Step B.5 across + all `standard/*.md`; any symbolic placeholder on an alpha is a hard stop. 6. **Commit the complete alpha delta before any alpha push.** Review `git status --short`, `git diff --check`, and the full diff. Stage only - the intentional surgical feature-delta files, inspect + the intentional feature-delta and generated renumber files, inspect `git diff --cached`, and create a normal commit: ```bash @@ -452,6 +487,47 @@ the discovered alpha is finalized per Step D — **the ordering invariant forbids building `draft-v(N+1)` on an unfinalized alpha.** Repeat A–D for the next branch in the chain. Continue until the chain is done. +If an earlier draft, alpha, or feature-source correction changes content +already propagated downstream, rebuild from the oldest corrected root and +carry that exact correction into the next draft and every affected +descendant. An ancestry-only merge is sufficient only when tree equality +proves the corrected content is already present. + +## Completion validation gate + +Run this gate on every final draft, alpha, and changed feature head. Record +commands and results in `$RUN_DIR/ledger.txt`; a summary without command +output or terminal GitHub state is not sufficient evidence. + +1. Run the exact pinned Markdown lint command (currently + `npx --yes markdownlint-cli2@0.23.2 'standard/*.md'`). +2. Run `StandardAnchorTags` in dry-run mode on drafts and feature branches. + On alphas, retain the non-dry-run plus second-run idempotence evidence from + Step D. +3. Run all non-example tool unit tests: + `dotnet test tools.sln --filter 'Name!~ExampleTests'`. +4. Run `tools/run-converter.sh` and `tools/test-examples.sh` from `tools` + in the shell expected by those scripts. +5. Run `git diff --check`, require a clean status after committed output, + and audit conflict markers and symbolic references. +6. Extract representative and aggregate example projects. Prove that every + ordinary generated project uses the recorded target framework and + `LangVersion N`; count and explain every legacy exception. +7. Exercise `FastCsprojCompilationParser` (or its current replacement) and + record Roslyn's specified/effective `LanguageVersion` enum name and + numeric value for N. Run the corresponding framework-default unit test. +8. For every affected PR, require `OPEN`, the expected base/head, remote SHA + equality, and `MERGEABLE`. Wait until every applicable GitHub check is + terminal. All must succeed except an explicitly allowed ANTLR + `grammar-validator` failure; pending, queued, missing, cancelled, or + silently skipped required checks are not success. + +Stop and escalate with the branch, command, and evidence when topology is +ambiguous, a feature set is incomplete, authorization is absent, source +intent is unclear, a PR head moves unexpectedly, a non-ANTLR check does not +pass, renumbering is not idempotent, or remote equality/ancestry cannot be +proved. + ## Reporting When finished (or when stopped on a conflict), produce a short report: @@ -460,10 +536,19 @@ When finished (or when stopped on a conflict), produce a short report: - The validated authoritative remote name and repository used for every discovery, baseline, merge, comparison, and push. - The dynamically enumerated feature-PR count and the manifest cutoff time. -- For each version N: whether its discovered alpha branch was **finalized** (committee changes + fresh vN deltas applied surgically, semantic comparison complete, dry-run and raw-reference audits clean) before `draft-v(N+1)` was started, and the list of vN PR numbers, pinned SHAs, and patches applied (Step D / Step B.8). +- For each version N: whether its discovered alpha branch was **finalized** + (committee changes + fresh vN deltas applied surgically, semantic + comparison complete, exact renumber idempotent, and raw-reference audits + clean) before `draft-v(N+1)` was started, and the list of vN PR numbers, + pinned SHAs, and patches applied (Step D / Step B.8). - Any PR head that moved after cutoff and how it was refreshed or why work stopped. - The high-conflict normative sections compared and any unresolved semantic differences. - Any raw symbolic-reference matches and their disposition. +- Per-version target framework, explicit `LangVersion`, generated-project + evidence, and Roslyn enum name/value. +- Exact local validation commands/results and terminal GitHub check, + mergeability, base/head, and remote-equality snapshots. +- The ledger path and enough evidence to resume or audit every write. - Any branches where you stopped and why. - The deletion inventory captured in Pre-flight (file list + originating PR numbers). - 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`. @@ -472,10 +557,17 @@ When finished (or when stopped on a conflict), produce a short report: ## Safety rules -- Never force-push to any `draft-v*`, `alpha-v*`, or `v*-alpha` branch. +- Do not force-push any `draft-v*`, `alpha-v*`, or `v*-alpha` branch by + default. Rewrite one only with explicit user authorization. Re-read its + remote SHA immediately before the write, use + `--force-with-lease=:` when a rewrite is authorized, + then fetch and require local/remote SHA equality. Never use unguarded + `--force`. - Never use `git reset --hard` on a tracked branch. - Never merge any PR other than the automated renumber/grammar PR. - Never change `REMOTE` or substitute another remote during the run. - Never advance past an alpha until its `ALPHA_FINAL_SHA` is present on the verified authoritative remote branch. - If `gh` shows the auto-PR's checks failing, stop and ask the user. +- Preserve the protected main checkout, all pre-existing worktrees, and every + stash unless the user explicitly authorizes changing them. diff --git a/.github/prompts/post-meeting-rebase-prs.prompt.md b/.github/prompts/post-meeting-rebase-prs.prompt.md index 4dbbf7d2e..298b0db68 100644 --- a/.github/prompts/post-meeting-rebase-prs.prompt.md +++ b/.github/prompts/post-meeting-rebase-prs.prompt.md @@ -99,6 +99,9 @@ Do not use a fixed branch list or PR count. `v11-alpha` is valid. Stop if both alpha spellings exist for a version or the topology is ambiguous. Confirm the result against `admin/branch-diagram.md`. + A missing alpha is not permission to create one. Record the version as + draft-and-feature-only unless the user confirms that its feature set is + complete and explicitly authorizes an aggregate. 3. Feature PRs target draft branches. For every discovered target `draft-vN`, list all open PRs with an explicit high limit and capture `number`, `baseRefName`, `headRefOid`, `headRefName`, @@ -193,12 +196,39 @@ For each manifest PR: the PR as "needs manual rebase", and move on. To distinguish new from pre-existing: check the same ref against `"$REMOTE/"` (the pre-rebase state). Pre-existing - TOC002s from incomplete feature work are expected and do not block - the push. - 7. Immediately before push, query `headRefOid` again. If it differs from + TOC002s may be inventoried during the comparison, but they must be + resolved before the completion gate permits a push. + Feature PR source trees may retain valid placeholder headings. Do not + replace them with aggregate numbering. Conversely, malformed headings, + blockquoted fences, grammar lines, or other source markup must be fixed + on this originating feature branch before it is integrated downstream; + do not defer the defect to an alpha-only patch. + 7. **Run the feature-source completion gate before push.** Use the exact + pinned commands and record their output in the run manifest + or ledger: + + ```bash + npx --yes markdownlint-cli2@0.23.2 'standard/*.md' + ( cd tools && dotnet run --project StandardAnchorTags -- \ + --owner dotnet --repo csharpstandard --dryrun ) + ( cd tools && dotnet test tools.sln --filter 'Name!~ExampleTests' ) + ( cd tools && ./run-converter.sh ) + ( cd tools && ./test-examples.sh ) + git diff --check + ``` + + Require the branch's ordinary templates and generated projects to use + the target framework recorded for version N and explicit + `N`. Prove the parser resolves Roslyn's + specified/effective version-N enum name and numeric value. Explain every + intentionally isolated legacy template and prove the feature does not + select it. Any non-ANTLR failure is a hard stop. + 8. Immediately before push, query `headRefOid` again. If it differs from the remote SHA captured immediately before checkout, stop and restart - this PR; the author moved it during the run. Otherwise: - `git push --force-with-lease "$REMOTE" HEAD:`. Then verify: + this PR; the author moved it during the run. Otherwise set + `EXPECTED` to that freshly verified remote SHA and push: + `git push --force-with-lease=:$EXPECTED "$REMOTE" + HEAD:`. Then verify: ```bash git fetch "$REMOTE" @@ -207,7 +237,14 @@ For each manifest PR: ``` Record success with that verified SHA. - 8. **Produce the per-PR patch (Phase B input).** Capture the PR's commits + After the push, wait for all applicable GitHub checks to reach a + terminal state. Require every check to succeed except an explicitly + allowed ANTLR `grammar-validator` failure. Pending, queued, missing, + cancelled, or silently skipped required checks are not success. Also + require the PR to remain `OPEN`, target the expected base, report the + verified head SHA, and be `MERGEABLE`; `BLOCKED` is acceptable only when + it reflects review or the allowed grammar policy rather than conflicts. + 9. **Produce the per-PR patch (Phase B input).** Capture the PR's commits relative to its base as a patch file so Phase B can surgically apply them onto `alpha-vN`: @@ -239,6 +276,10 @@ time. If any head moved during the long run, refresh it. Otherwise set that record's `cutoffTime`, then set the top-level `finalizedAt`. Report the final PR count and cutoff range. +If a shared defect is found on an earlier draft or feature branch, repair the +earliest source and propagate root-first. Do not keep a downstream-only fix +when descendants still inherit malformed source. + ## Phase A2 — notify and route after Phase B ### Step 4 — Detect feature-PR drift across cycles @@ -355,6 +396,9 @@ At the end, output a table grouped by base branch: - Any PR head that moved during the run and how its manifest entry was refreshed - PRs left for manual rebase (with reason — including any failing `TOC002` references from the post-rebase cross-reference check) +- Exact local gate results, target-framework/`LangVersion` and Roslyn enum + evidence, terminal GitHub check state, mergeability, and remote-SHA + equality for every changed PR - Fork PRs commented on - PRs that already had the notice (skipped) - PRs flagged with the **alpha-drift notice** (Step 4) @@ -365,5 +409,7 @@ At the end, output a table grouped by base branch: - Never close or merge a feature PR. - Never push to a fork. - Always use `--force-with-lease`, never `--force`. +- Preserve the main checkout, existing worktrees, and stashes. Perform + rewrites in isolated worktrees and record before/after integrity evidence. - Never change `REMOTE` or substitute another remote during the run. - If `gh pr checkout` fails (e.g. permissions), record and skip.