Skip to content

Create the Branches Before the Standup Writes Permanent History - #614

Merged
ptr727 merged 13 commits into
developfrom
feat/standup-branch-bootstrap
Aug 8, 2026
Merged

Create the Branches Before the Standup Writes Permanent History#614
ptr727 merged 13 commits into
developfrom
feat/standup-branch-bootstrap

Conversation

@ptr727

@ptr727 ptr727 commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Ships the Branch Bootstrap in the Standup cluster from TODO.md, selected by that file's own How to Select the Next Item procedure.

The gap

STANDUP.md section 0 requires signing to be live before the first commit, and section 0A hands the maintainer prerequisites over before step 1. Then it goes straight to classification. Nothing in the file says how main and develop come into being, so an agent commits onto whichever branch git init produced, and the exploratory standup becomes the repository's permanent history.

Verified on develop at 676a2bd: git init appears twice, both inside section 0 about the signing window, and a search for checkout -b, git branch, feature branch, branch from and root commit returns nothing.

What section 0B says

Create main empty, create develop from it, create the first feature branch from develop, run the whole standup there through the audit in step 5, add the repository and apply the configuration while still on that branch, then open a normal pull request into develop.

Carrying nothing means exactly one signed empty root commit, since a git branch cannot exist without a commit, and section 0's signing window applies to it like any other.

Why the cleanup is unavailable afterwards

Committing onto develop and squashing later is rejected, because non_fast_forward is set on both develop payloads and that squash is the rewrite the rule blocks.

The protection is uneven, which is the part worth stating in the file:

Payload Rules Blocks a direct commit
repo-config/develop.json deletion, non_fast_forward, required_linear_history, required_signatures, pull_request, required_status_checks, copilot_code_review yes, via pull_request
repo-config/operational/develop.json deletion, non_fast_forward, required_signatures no

So a conformant operational repository accepts the commit this step exists to prevent, and reports nothing wrong afterwards. On a public repository the squash is the one chance to leave a wrong secret value, a throwaway credential and a run of noise commits out of what gets published.

Scope

STANDUP.md is hub machinery and deliberately not carried, per spec/section-model.md, so this owes no re-vendor and adds nothing to the outstanding sweep. #490 covered the human-gated half and is closed, which left this half, so there is no issue to close here.

TODO.md drops the shipped cluster per step 9 of its own procedure, and the issue-490 link definition it was the only user of.

One departure from the cluster text, stated so it is a decision rather than an omission: the cluster names Blog as the repository that was blocked, and the section describes the case without naming it. The evidence is the mechanism, and STANDUP.md is read by agents standing up unrelated repositories.

Verification

  • prose_lint.py, both CI invocations plus sentence-split by name, which is in neither. Confirmed with --list-files that both files were actually read, rather than passing on an empty set.
  • editorconfig-checker, exit 0. Line endings checked independently too, since a scripted rewrite converts them silently: STANDUP.md is 191 of 191 CRLF lines and TODO.md 494 of 494.
  • markdownlint-cli2, 0 issues across 44 files.
  • cspell reads README.md and HISTORY.md only, neither of which this touches.

STANDUP.md tells an agent to verify signing before the first commit, and
to hand the maintainer prerequisites over before step 1, then goes
straight to classification. Nothing in it says how `main` and `develop`
come into being, so an agent commits onto whichever branch `git init`
produced and writes the exploratory standup into the repository's
permanent history.

## What section 0B says

Create `main` empty, create `develop` from it, create the first feature
branch from `develop`, run the whole standup there through the audit,
add the repository and apply the configuration while still on that
branch, and open a normal pull request into `develop` at the end.

Carrying nothing means exactly one signed empty root commit, since a git
branch cannot exist without a commit, and section 0's signing window
applies to it like any other.

## Why the cleanup is unavailable afterwards

Committing onto `develop` and squashing later is rejected, because
`non_fast_forward` is set on both `develop` payloads and that squash is
the rewrite the rule blocks.

The protection is uneven. `repo-config/develop.json` carries a
`pull_request` rule that blocks a direct commit outright, while
`repo-config/operational/develop.json` carries `deletion`,
`non_fast_forward` and `required_signatures`, and none of them stops
one. A conformant operational repository therefore accepts the commit
this step exists to prevent, and reports nothing wrong afterwards.

On a public repository the squash is the one chance to leave a wrong
secret value, a throwaway credential and a run of noise commits out of
what gets published.

## Scope

STANDUP.md is hub machinery and deliberately not carried, per
`spec/section-model.md`, so this owes no re-vendor. #490 covered the
human-gated half and is closed, which left this half.

TODO.md drops the shipped cluster per its own selection procedure, and
the issue-490 link definition it was the only user of.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 8, 2026 03:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds explicit guidance to STANDUP.md for creating main/develop before any standup work is committed, so exploratory onboarding work lands only via a feature branch PR, and removes the now-shipped backlog cluster from TODO.md.

Changes:

  • Add STANDUP.md section 0B describing the branch bootstrap sequence (empty main, empty develop, standup on a feature branch, then PR into develop).
  • Document why post-hoc cleanup (commit-on-develop then squash) fails under non_fast_forward, and why operational repos are especially vulnerable.
  • Remove the shipped “Branch Bootstrap in the Standup” cluster and its unused issue link definition from TODO.md.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
STANDUP.md Adds section 0B documenting when/how to create main/develop and why the sequence matters for irreversible history.
TODO.md Removes the shipped backlog cluster and the now-unused issue-490 link definition.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread STANDUP.md
The sequence was prose only, so the ordering it exists to fix was left to
inference, which is the review finding. Section 0 and step 4 both carry
command blocks for the same reason.

Adds the four local commands, and two ordering facts they do not carry on
their own: section 0 checks fall between init and the empty root commit,
and the two branches are pushed before step 4 applies the rulesets, since
repo-config/main.json carries a pull_request rule and no bypass actors,
so an applied ruleset blocks the push that seeds the branch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 8, 2026 03:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (1)

STANDUP.md:66

  • The command block uses git switch --create, but the repository does not document a minimum Git version and git switch is only available in relatively recent Git releases. Using git checkout -b here (or explicitly stating the Git version requirement) would make the standup instructions more broadly copy/paste compatible.
git init --initial-branch main                       # Rather than relying on the host's init.defaultBranch.
git commit --allow-empty --message "Initial commit"  # The one signed empty root commit.
git branch develop                                   # From main, so the two start level.
git switch --create "<feature-branch>" develop       # Every step below runs here.

The suppressed round-2 finding named git switch, which arrived in 2.23.
The binding constraint was git init --initial-branch at 2.28, so
swapping only switch would have lowered nothing.

Every command in the block now predates both, and docs/host-setup.md
checks that git is present while stating no floor, so the block asks for
nothing that file guarantees. The unconditional rename replaces the
initial-branch flag and is correct on either host default, verified in a
scratch repository through the feature checkout.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 8, 2026 03:24
@ptr727

ptr727 commented Aug 8, 2026

Copy link
Copy Markdown
Owner Author

Answering the round 2 suppressed finding here, since a suppressed comment has no thread to resolve.

The command block uses git switch --create, but the repository does not document a minimum Git version and git switch is only available in relatively recent Git releases. Using git checkout -b here (or explicitly stating the Git version requirement) would make the standup instructions more broadly copy/paste compatible.

Accepted, and the premise checks out: docs/host-setup.md lists git --version as the command that proves git is present and states no floor anywhere.

One correction to the diagnosis, which changes the fix. git switch was not the binding constraint. It arrived in 2.23, while git init --initial-branch on the block's first line arrived in 2.28, so swapping only switch for checkout -b would have left the floor exactly where it was, one line higher up.

Fixed in d5c00d6 by removing both, so the block asks for nothing docs/host-setup.md does not already guarantee:

git init                                             # The host default may be master, which the rename below corrects.
git commit --allow-empty --message "Initial commit"  # The one signed empty root commit.
git branch --move --force main                       # Idempotent, so it is correct on either default.
git branch develop                                   # From main, so the two start level.
git checkout -b "<feature-branch>" develop           # Every step below runs here.

The unconditional --move --force replaces the --initial-branch flag rather than a test of init.defaultBranch, because forcing the rename is correct whether the host produced master or main, and a conditional is one more thing to get wrong. Verified in a scratch repository on a host whose default is master: the rename lands on main, a second run while already on main exits 0, and the three branches end up on the one empty root commit with the feature branch checked out.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (2)

STANDUP.md:52

  • This sentence claims nothing reaches main/develop without review, but section 0B immediately instructs creating (and later pushing) an empty root commit on those branches. Reword to clarify that the standup work stays off long-lived branches until a PR, rather than implying absolutely no direct commits ever land there.
**Create both long-lived branches empty and do the whole standup on a feature branch off `develop`.** An agent that starts committing onto whichever branch `git init` produced is writing the repo's permanent history, and every step below is exploratory work that has no business being permanent. Doing this first means nothing ever has to be cleaned off `main` or `develop`, because nothing reaches either without review.

STANDUP.md:60

  • The text says "four commands", but the fenced block contains five commands (git init, empty commit, branch rename, create develop, create feature branch). This mismatch makes the procedure harder to follow and audit.
The three local steps are four commands, run before the repository exists on GitHub:

Two round-3 findings, both correct.

The opening claimed nothing reaches main or develop without review, four
lines above an instruction to put an empty root commit on both and push
them. It now says the only commit either carries is the empty one it
starts from, which is the claim the rest of the section actually
supports.

The command count said four and the block had grown to five, because the
previous commit added the rename and left the count behind it. The count
is gone rather than corrected, since a number restating what the block
shows has to be swept every time the block changes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 8, 2026 03:28
@ptr727

ptr727 commented Aug 8, 2026

Copy link
Copy Markdown
Owner Author

Answering both round 3 suppressed findings here, since a suppressed comment has no thread to resolve. Both are accepted, and both are fixed in 4adc9dd.

This sentence claims nothing reaches main/develop without review, but section 0B immediately instructs creating (and later pushing) an empty root commit on those branches. Reword to clarify that the standup work stays off long-lived branches until a PR, rather than implying absolutely no direct commits ever land there.

Correct, and the contradiction sat four lines above the instruction that falsifies it. The opening now reads that the only commit either branch carries is the empty one it starts from, and that every change after it arrives by pull request, which is the claim the rest of the section supports rather than a wider one it does not.

Worth recording that the wording came in verbatim from the backlog entry this pull request ships, so the imprecision was carried rather than introduced here. The entry is deleted by this same change, so there is nothing left to correct in it.

The text says "four commands", but the fenced block contains five commands (git init, empty commit, branch rename, create develop, create feature branch). This mismatch makes the procedure harder to follow and audit.

Correct, and mine: d5c00d6 added the rename to the block and left the count in the sentence above it.

The count is removed rather than corrected, which is the durable half of the fix. A number restating what the block already shows has to be swept every time the block changes, and this is the first change that could have got it wrong doing so. The line now reads that steps 1 through 3 are the block below.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (1)

STANDUP.md:68

  • The command block for steps 1-3 omits the git config --local --get user.email || true check that section 0 requires to run after git init and before the first commit (and the paragraph below this block explicitly says it belongs between the first and second lines). Including it in the block makes the copy/paste sequence mechanically correct and consistent with the earlier step ordering.
git init                                             # The host default may be master, which the rename below corrects.
git commit --allow-empty --message "Initial commit"  # The one signed empty root commit.
git branch --move --force main                       # Idempotent, so it is correct on either default.
git branch develop                                   # From main, so the two start level.
git checkout -b "<feature-branch>" develop           # Every step below runs here.
</details>

The round-4 finding is that the block presented itself as the copy-paste
sequence while the paragraph under it said a check belonged between two
of its lines. A reader following the block alone skipped it, and a reader
following the prose had to interpolate it.

The check is now the second line, and the prose says how section 0 reads
it rather than where it goes, since an unset key prints nothing and exits
non-zero, which is the passing case and not the failing one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 8, 2026 03:31
@ptr727

ptr727 commented Aug 8, 2026

Copy link
Copy Markdown
Owner Author

Answering the round 4 suppressed finding here, since a suppressed comment has no thread to resolve. Accepted, fixed in 9c138f7.

The command block for steps 1-3 omits the git config --local --get user.email || true check that section 0 requires to run after git init and before the first commit (and the paragraph below this block explicitly says it belongs between the first and second lines). Including it in the block makes the copy/paste sequence mechanically correct and consistent with the earlier step ordering.

Correct, and the two halves disagreed in a way that hurt either reader. Someone following the block alone skipped the check, and someone following the prose had to interpolate a line into a block that presented itself as complete.

The check is now the second line of the block. The paragraph under it no longer says where the check goes, and says instead how section 0 reads it, because that is the part a reader still needs and the part the placement cannot convey: an unset key prints nothing and exits non-zero, so the passing case is empty output over a non-zero exit, and reading the exit status as failure inverts the check. That is section 0's own rule, applied here rather than restated.

The three earlier suppressed findings this round re-listed were answered above, on the rounds that raised them.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (1)

STANDUP.md:66

  • The inline comment says this rename is "Idempotent", but with --force it can overwrite an existing main branch if someone runs the block in a non-empty repo. Since this procedure is for a fresh git init, it would be clearer (and more accurate) to state that assumption instead of claiming general idempotence.
git branch --move --force main                       # Idempotent, so it is correct on either default.

The round-5 finding is that the comment claimed idempotence while the
line carries --force, which overwrites an existing main in a repository
that already has one. The claim was true only under the block's own
assumption, and the comment stated none.

The comment now says what the line does and where, and the prose says
what makes the force safe, a repository holding one branch and one
commit, so the rename has nothing to collide with. It also says what the
same line does in a repository that already carries main, since that is
the case the word idempotent was quietly excluding.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 8, 2026 03:36
@ptr727

ptr727 commented Aug 8, 2026

Copy link
Copy Markdown
Owner Author

Answering the round 5 suppressed finding here, since a suppressed comment has no thread to resolve. Accepted, fixed in 4f08872.

The inline comment says this rename is "Idempotent", but with --force it can overwrite an existing main branch if someone runs the block in a non-empty repo. Since this procedure is for a fresh git init, it would be clearer (and more accurate) to state that assumption instead of claiming general idempotence.

Correct. The word was accurate only inside the assumption the comment did not state, which is the shape worth fixing rather than the word.

What I verified before writing it, and what it was hiding: the rename is safe here because the repository holds one branch and one commit, so --force has nothing to collide with, and the second run I tested was a rename of main onto itself. Neither of those is the case the finding names. In a repository that already carries a main while HEAD is elsewhere, the same line overwrites that branch's ref.

So the comment now says what the line does and where, the prose says what bounds the force, and it names the repair case explicitly as the one this block is not for.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (1)

STANDUP.md:68

  • The step 0B command block creates the empty root commit but does not include section 0's required post-commit verification (git log -1 --format=...). Because that verification appears earlier in the document (before the 0B commands that create the commit), it is easy to miss or run out of order. Including the verification command directly in this block keeps the sequence linear and makes it harder to skip the signing/identity check for the empty root commit.
git init                                             # The host default may be master, which the rename below corrects.
git config --local --get user.email || true          # Section 0's check, whose passing case is no output.
git commit --allow-empty --message "Initial commit"  # The one signed empty root commit.
git branch --move --force main                       # Renames whichever branch git init produced, in a repo holding only it.
git branch develop                                   # From main, so the two start level.

The round-6 finding is the pair of the round-4 one. The block created the
empty root commit and left section 0's post-commit verification behind,
so a reader running the block linearly created the commit the signing
window exists for and never verified it.

The verification is now the fourth line, copied from section 0 rather
than paraphrased, so the two cannot drift into two different commands.
The prose under the block stops naming a position for either check and
says how each is read instead, which is the half the placement cannot
carry.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 8, 2026 03:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (1)

STANDUP.md:60

  • Section 0 already instructs running a git config --local --get user.email check after git init, and section 0B now includes a full git init block as well. As written, a reader following section 0 literally may run git init to satisfy the earlier check, then reach 0B and run git init again, which is confusing and makes the intended "one init" flow unclear. Consider clarifying here that the git init in the block is the one section 0 expects, so there is no separate init step before 0B.
Steps 1 through 3 are the block below, run before the repository exists on GitHub:

The round-9 finding is that section 0 refers to git init twice as
something already done, while 0B now carries the command itself, so a
reader following both literally inits twice.

The lead-in now says the block holds the only one, and how section 0
reads against it: the --global checks run ahead of the block and the two
repository-scoped checks sit inside it.

Section 0 is left alone. Its two references are correct as written once
the reader knows which init they name, and rewording a section this
change does not otherwise touch would carry into every downstream copy
for a clarification that belongs here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 8, 2026 03:55
@ptr727

ptr727 commented Aug 8, 2026

Copy link
Copy Markdown
Owner Author

Answering the round 9 suppressed finding here, since a suppressed comment has no thread to resolve. Accepted, fixed in c567ac6.

Section 0 already instructs running a git config --local --get user.email check after git init, and section 0B now includes a full git init block as well. As written, a reader following section 0 literally may run git init to satisfy the earlier check, then reach 0B and run git init again, which is confusing and makes the intended "one init" flow unclear. Consider clarifying here that the git init in the block is the one section 0 expects, so there is no separate init step before 0B.

Correct, and this is the last of the seam the previous three rounds opened. Moving section 0's checks into the block was right, and it left section 0 referring to an init that now happens later in the document than the text describing it.

The lead-in now says the block carries the procedure's only git init, and how section 0 reads against it: the --global checks run ahead of the block, and the two repository-scoped checks sit inside it.

Section 0 itself is left alone deliberately. Its two references are correct once a reader knows which init they name, and rewording a section this change does not otherwise touch would land in every downstream copy of a carried file for a clarification that belongs to the new section. If a later change reworks section 0 for its own reasons, that is the moment to fold this in.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (1)

STANDUP.md:72

  • Line 64 in the shell block includes || true, so the command's actual exit status is always 0. The surrounding prose says the passing case is a non-zero exit with empty output, which is true of the underlying git config --get but not of the full command as written, and can confuse readers who check $? while following the procedure.
The rename runs unconditionally rather than behind a test of `init.defaultBranch`, because forcing it is correct whether the host produced `master` or `main` and a conditional is one more thing to get wrong. What makes the force safe is where the block runs, in a repository holding one branch and one commit, so it is a rename with nothing to collide with rather than a general-purpose one. In a repository that already carries a `main` the same line overwrites that branch, which is why this block belongs to a fresh `git init` and never to a repair. Every command here predates `git switch` and `git init --initial-branch`, so the block needs no minimum version, which matters because [`docs/host-setup.md`][host-setup] checks that `git` is present and states no floor. The placeholder is quoted for the reason step 4 gives, that an unquoted `<` is input redirection. Both of section 0's checks sit in the block rather than beside it, placed where that section requires them rather than left to a reader to interpolate, and each is read as section 0 reads it. On the second line the finding is the printed value, so a non-zero exit over empty output is the passing case. On the fourth the passing result is `G` beside the noreply address in the author and the committer both, which reads the empty root commit as the first commit the signing window covers rather than as an exception to it. Push `main` and `develop` once the repository exists and **before** step 4 applies the rulesets, since [`repo-config/main.json`][repo-config-main] carries a `pull_request` rule, so an applied ruleset blocks the direct push that would otherwise seed the branch. Ordering it this way rather than relying on a bypass is deliberate, because who may bypass a ruleset is a human decision no payload declares, and `repo-config/configure.sh` reads the live list and preserves it rather than asserting one, so an agent cannot know from the payload whether a bypass exists.

The round-10 finding is that the prose called a non-zero exit the passing
case while the line it describes ends in a tolerant tail, so its actual
status is always zero. Measured both: the bare git config --get exits 1
on an unset key, and the same line with the tail exits 0.

Both places that said it are fixed, section 0B's summary and section 0's
own rule, since the imprecision came from the second and the first
inherited it. Each now says the passing result is empty output, that the
exit status answers nothing, and why the tail is there.

Section 0 is edited here after declining to touch it last round. The
reason given then was that it would reach downstream copies, which is
wrong: this file is hub machinery and carried nowhere, as the pull
request body says. The scope reason still held for a wording change that
was only about the new section, and does not hold for the same defect the
finding names.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 8, 2026 04:00
@ptr727

ptr727 commented Aug 8, 2026

Copy link
Copy Markdown
Owner Author

Answering the round 10 suppressed finding here, since a suppressed comment has no thread to resolve. Accepted, fixed in 83a519d.

Line 64 in the shell block includes || true, so the command's actual exit status is always 0. The surrounding prose says the passing case is a non-zero exit with empty output, which is true of the underlying git config --get but not of the full command as written, and can confuse readers who check $? while following the procedure.

Correct, and measured rather than reasoned about: the bare git config --local --get user.email exits 1 against an unset key, and the same line with the tolerant tail exits 0. The prose was describing the command inside the line rather than the line.

Fixed in both places that said it, section 0B's summary and section 0's own rule, since the wording originated in section 0 and the new section inherited it. Each now says the passing result is empty output, that reading $? there answers nothing either way, and why the tail is present, which is so a copy inside a set -e script does not abort on the expected case.

Correcting my own reasoning from the previous round. I declined to touch section 0 in the round 9 answer above and gave as the reason that rewording it would land in every downstream copy of a carried file. That is wrong. STANDUP.md is hub machinery and is carried nowhere, which this pull request's own body says and spec/section-model.md states. The decision itself was still right for that round, on the narrower ground that the clarification was about the new section rather than about section 0, and that ground does not extend to a defect the reviewer has now named in both.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (1)

STANDUP.md:33

  • Section 0 now has its only git init inside 0B, but this paragraph sits immediately after the repo-local override check and can be read as prompting a git init before 0B. Adding an explicit reference to 0B here would prevent readers from initializing (and potentially committing) too early, which would make the 0B bootstrap block unsafe to apply.
**The finding is a printed value, never the exit code.** An unset key prints nothing and makes `git config --get` exit `1`, so reading that as failure inverts the check, and the tolerant tail turns it into a zero exit in any case, which leaves empty output as the whole of the passing result. The tail is in the snippet above so a copy into a `set -e` script does not abort on the expected case.

The round-11 finding is that section 0 documents a check that runs after
git init while the init itself now lives in 0B, so the paragraph reads as
a prompt to init early, which is the state 0B exists to prevent.

Both of section 0's check paragraphs now say where the command runs, not
only the flagged one. The two are the same defect and the reviewer named
the first, so fixing that one alone would leave the second to a later
round.

The commands stay in section 0. It is where the reader learns what each
check means and how to read its result, and 0B is where they run, which
is the split both paragraphs now state.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 8, 2026 04:05
@ptr727

ptr727 commented Aug 8, 2026

Copy link
Copy Markdown
Owner Author

Answering the round 11 suppressed finding here, since a suppressed comment has no thread to resolve. Accepted, fixed in b5c739e.

Section 0 now has its only git init inside 0B, but this paragraph sits immediately after the repo-local override check and can be read as prompting a git init before 0B. Adding an explicit reference to 0B here would prevent readers from initializing (and potentially committing) too early, which would make the 0B bootstrap block unsafe to apply.

Accepted. Section 0 documents a check that happens after git init while the init now lives in 0B, so the paragraph reads as an instruction to init here, which is the state 0B exists to prevent.

Fixed in both of section 0's check paragraphs rather than the one flagged. The git log -1 verification below has the identical shape, and fixing only the named instance would have left the second for a later round. Each now says where the command runs.

The commands stay in section 0, since that is where a reader learns what each check means and how to read its result. 0B is where they run. Both paragraphs now state that split rather than implying a step of their own.

On the shape of this loop, recorded because it is measurable rather than as a complaint. Rounds 4, 6, 9, 10 and 11 were each caused by the previous fix, which is one section's content moving and the text around it not moving with it. Every one of them was a real defect at the moment it was raised.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (1)

STANDUP.md:25

  • Subject/verb agreement: "The agent check branches" should be "The agent checks branches".
The agent check branches rather than listing both forms, because they are alternatives and running the wrong one fails on a correctly configured host: an SSH host need not have `gpg` installed at all. Signing is **SSH or GPG**, so judge the format and its agent together rather than requiring `ssh`: what matters is that the configured format has a matching agent holding the key, which is the check [GOVERNANCE.md "Git and Commit Rules"][governance-git-and-commit-rules] prescribes. Any of these wrong or absent is a **host** misconfiguration to surface to the maintainer ([`docs/host-setup.md`][host-setup] is the setup procedure), not something to patch per repo. Patching it locally hides a broken host that then produces wrong identities in every other repo on that machine.

@ptr727

ptr727 commented Aug 8, 2026

Copy link
Copy Markdown
Owner Author

Answering the round 12 suppressed finding here, since a suppressed comment has no thread to resolve. Declined, with the reading that makes the sentence correct as it stands.

Subject/verb agreement: "The agent check branches" should be "The agent checks branches".

The subject is the noun phrase "the agent check", meaning the check for the signing agent, and "branches" is its verb. The sentence says that this check branches rather than listing both forms, which is exactly what the snippet it describes does:

if [ "$(git config --global --get gpg.format)" = ssh ]; then ssh-add -L; else gpg --list-secret-keys; fi

The suggested reading parses "the agent" as the subject and "check" as the verb, which leaves "branches" as a plural noun and turns the sentence into a claim that an agent inspects branches. There are no branches in that paragraph. It is section 0, before any repository exists, and the sentence's own subordinate clause names what the alternatives are, the SSH and GPG forms, not refs.

The line is also not this pull request's. It landed in 77be3a3 under #481 on 2026-07-31 and appears in the diff only as context beside the nearby edit in b5c739e. I am leaving it as written rather than rewording correct prose the change does not otherwise touch.

If the sentence is worth making harder to misparse, that is a separate observation about a garden-path noun phrase rather than a grammar defect, and it belongs in a change that has a reason to be in section 0.

The round-12 finding claimed a subject-verb disagreement in STANDUP.md
section 0. The subject is the noun phrase "the agent check" and
"branches" is its verb, describing the if/else that selects ssh-add or
gpg by the configured format, so the sentence is correct as written and
the finding is declined.

A decline that lives only in a pull request comment is re-derived the
next time the line is read, which is what the Disproved Claims record
exists to prevent, so the entry goes in with the reading, the revision it
was proved against, and what ends it.

The sentence itself is untouched. It landed in 77be3a3 under #481 and
this change reaches it only as diff context.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 8, 2026 04:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@ptr727
ptr727 merged commit f39e0c0 into develop Aug 8, 2026
7 checks passed
@ptr727
ptr727 deleted the feat/standup-branch-bootstrap branch August 8, 2026 04:21
ptr727 added a commit that referenced this pull request Aug 8, 2026
Fixes a finding Copilot raised on the promotion pull request [#615](#615), against the command block [#614](#614) added. A promotion's head is `develop`, so the fix lands here rather than there.

## The finding

> The branch rename uses long options (`--move --force`), but the paragraph below explicitly says the block "needs no minimum version". Using the long options may impose a newer Git requirement than the short form, so this can undermine the compatibility claim. Prefer the traditional `-M` form here to keep the bootstrap as version-agnostic as possible.

## What the source says

Checked against git's own option tables rather than taken on faith, since the claim is about when a spelling became available:

| Tag | `git branch` option table |
| --- | --- |
| `v1.5.4` | `OPT_BIT('m', NULL, ...)`, `OPT_BIT('M', NULL, ...)`, `OPT_BOOLEAN('f', NULL, ...)` |
| `v2.0.0` | `OPT_BIT('m', "move", ...)`, `OPT_BIT('M', NULL, ...)`, `OPT__FORCE(...)` |

So `--move` and `--force` did not exist in 1.5.4 and did by 2.0.0, and `-M` has no long equivalent in either. The finding has the direction right.

It also bounds how wrong the block was. The long forms are far older than `git switch` at 2.23 and `git init --initial-branch` at 2.28, which is what the prose named, so nothing here was going to break on a plausible host. The claim was **no floor at all** rather than a floor earlier than those two, and the long forms do carry one.

## The change

The line reads `git branch -M main`, and the paragraph says the short form is deliberate rather than terse, so a later edit does not restore the long form for consistency with the rest of the block.

## Verification

`prose_lint.py` both invocations plus `sentence-split`, `editorconfig-checker` exit 0, `markdownlint-cli2` 0 issues across 44 files, and `STANDUP.md` at 206 of 206 CRLF lines. The block's comment column is unchanged at 65.
ptr727 added a commit that referenced this pull request Aug 8, 2026
…-coverage remedy (#615)

Promotes `develop` to `main`, carrying five merged pull requests.

## What is being promoted

- **[#617](#617
`8515666`, the branch rename written `-M` rather than `--move --force`,
which git gained later, checked against git's own option tables at
`v1.5.4` and `v2.0.0`.
- **[#616](#616
`08cf819`, the partial-coverage status line counting the unread files
rather than asserting there is one.
- **[#614](#614
`f39e0c0`, the branch bootstrap step in [`STANDUP.md`](./STANDUP.md).
Section 0B states the sequence that keeps the exploratory standup off
`main` and `develop`, carries the procedure's only `git init` alongside
both of section 0's identity checks, and records why the post-hoc
cleanup is unavailable. It also carries one Disproved Claims entry and
the removal of the shipped backlog cluster.
- **[#613](#613
`676a2bd`, the partial-coverage remedy in `scripts/pr_review.py` and its
two documentation mirrors, corrected to what the record supports after
measuring 4 pull requests and 7 rounds with 0 recoveries.
- **[#612](#612
`1892d6f`, a Dependabot group bump of four actions.

#616 and #617 both answer findings raised by the review **on this
promotion**. A promotion's head is `develop`, so neither could be fixed
here, and each took its own pull request into `develop` and its own
review rounds before merging.

## Review state

Each of the five was reviewed and merged on its own pull request, so
this promotion carries no unreviewed change. #614 ran 13 rounds, 12
findings accepted and 1 declined and recorded under Disproved Claims.
#616 ran 3 rounds and #617 ran 2, all findings accepted.

## Merge shape

This is a promotion, so it merges as a **merge commit** rather than a
squash, per [`GOVERNANCE.md`](./GOVERNANCE.md) "Branching Model". Its
head is `develop` itself, so it must **not** be merged with
`--delete-branch`.
ptr727 added a commit that referenced this pull request Aug 8, 2026
…request sweep (#619)

Promotes `develop` to `main`, carrying two merged pull requests.

## What is being promoted

- **[#591](#591
`07ed74a`, reading why a merge is blocked instead of reporting one word.
`scripts/pr_review.py` gains the check rollup, the four stuck shapes it
tells apart, and exit `44` for a review loop that closed against a check
no waiting clears, plus the [`GOVERNANCE.md`](./GOVERNANCE.md) and
runbook wording that says `BLOCKED` never names its own cause.
- **[#618](#618
`dd5fc90`, the open pull request sweep in [`TODO.md`](./TODO.md)'s
selection procedure, plus an amendment recording the upstream ask for a
machine-readable Copilot review schema.

## The exit code, since it changed meaning between branches

#591 was authored before the outage of 2026-08-06 and defined exit `42`
for its check reading. #607, #608 and #613 took `42` for a round that
read fewer files than the pull request changed, and `43` for a shape the
reader does not know, while it sat. The forward-merge renumbered the
check reading to **44** and ranked it under both: `43` says no field can
be believed, `42` says part of the diff has no review, and only once
those are clear is a wedged required check the thing worth reporting.
`wait` returns the coverage and shape verdict where it has one and reads
the checks only where it does not.

## Review state

Both were reviewed and merged on their own pull requests, so this
promotion carries no unreviewed change. #591 ran 18 rounds across its
life, 5 of them after the revival, and #618 ran 5. Every finding was
accepted except one on #614, which was declined with evidence and
recorded under "Disproved Claims" in
[`.github/copilot-instructions.md`](./.github/copilot-instructions.md).

## Why #591 was open long enough to need reviving

It was parked correctly during the GitHub Actions major outage, with the
reason written on the pull request, and the reason then expired quietly.
Three days later it was 20 commits behind `develop`, conflicting in six
regions, and carrying an exit code that meant something else. #618 is
the procedural answer to that, and it is in this same promotion.

## Merge shape

This is a promotion, so it merges as a **merge commit** rather than a
squash, per [`GOVERNANCE.md`](./GOVERNANCE.md) "Branching Model". Its
head is `develop` itself, so it must **not** be merged with
`--delete-branch`.
Sign up for free to 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.

2 participants