docs: declare PR delivery shape in every OpenSpec proposal - #76
Conversation
|
@claude /review |
|
Claude finished @thecodedrift's task in 3m 1s —— View job Review complete
Overall assessmentThis is a clean, well-scoped documentation change (docs-only, correctly labeled
Two non-blocking nits posted inline:
No correctness, security, or test-adequacy issues — this is a pure prose/policy change with no executable surface. |
| Committing a branch straight to `main` is the norm — stacks are optional. When PRs _do_ stack, the **stack-breadcrumb workflow** (`.github/workflows/stack-breadcrumb.yml`) keeps their cross-links and carried-forward bodies in sync automatically; there is no git-town or other stacking tool in the loop. Branch protection lives on `main` only (`Validate` required, `strict_up_to_date: true`, 0 required reviews); child branches are unprotected. When you do land a stack, follow these practices. | ||
| When PRs stack, the **stack-breadcrumb workflow** (`.github/workflows/stack-breadcrumb.yml`) keeps their cross-links and carried-forward bodies in sync automatically; there is no git-town or other stacking tool in the loop. Branch protection lives on `main` only (`Validate` required, `strict_up_to_date: true`, 0 required reviews); child branches are unprotected. When you do land a stack, follow these practices. | ||
|
|
||
| ### Every OpenSpec proposal declares its delivery shape |
There was a problem hiding this comment.
Nit: every sibling ### heading in this section names an action or scenario the reader is doing (Landing a stack…, Never --delete-branch mid-stack, Use merge-commit, not squash…, Recovery if a child PR gets closed…). This one is phrased as a standing fact about proposals instead (Every OpenSpec proposal declares…). Not wrong, just a slightly different register — something like Declare the delivery shape would match the surrounding headings' voice. Non-blocking.
| ## Stacked PRs | ||
|
|
||
| Committing a branch straight to `main` is the norm — stacks are optional. When PRs _do_ stack, the **stack-breadcrumb workflow** (`.github/workflows/stack-breadcrumb.yml`) keeps their cross-links and carried-forward bodies in sync automatically; there is no git-town or other stacking tool in the loop. Branch protection lives on `main` only (`Validate` required, `strict_up_to_date: true`, 0 required reviews); child branches are unprotected. When you do land a stack, follow these practices. | ||
| When PRs stack, the **stack-breadcrumb workflow** (`.github/workflows/stack-breadcrumb.yml`) keeps their cross-links and carried-forward bodies in sync automatically; there is no git-town or other stacking tool in the loop. Branch protection lives on `main` only (`Validate` required, `strict_up_to_date: true`, 0 required reviews); child branches are unprotected. When you do land a stack, follow these practices. | ||
|
|
||
| ### Every OpenSpec proposal declares its delivery shape |
There was a problem hiding this comment.
Minor structural point: this new subsection is filed under ## Stacked PRs, but its first table row (Single PR) and its whole purpose (deciding whether to stack) are logically prior to that heading rather than a subtopic of it. Reads fine as-is since the stacking mechanics live right below it, but if this section grows it might read more naturally as its own top-level heading. Not a blocker.
Single PR, stacked merging forward, or stacked merging down — decided while writing the proposal rather than when the diff has already grown past reviewing. Prefer stacking, aiming under ~300 lines per diff. The forward/down distinction is one question: can each unit reach production alone without breaking anything? partition-rules-by-engine is the worked example — its first task group leaves 20 tests failing because the migration moves rules out from under readers that later groups update, so it can only merge down. Also drops "stacks are optional" from the opening, which now contradicts the preference stated below it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CDv57zHq7abms3RReSQw6q
85f7149 to
bc40a65
Compare
Every OpenSpec proposal now has to say how it intends to land: a single PR, a stack that merges forward, or a stack that merges down. The point is to decide it while writing the proposal, when the change is still an outline, rather than discovering at review time that the diff is 900 lines and nobody wants to read it.
The distinction between the two stacked shapes is one question, and it is a question about behavior rather than intent: can each unit reach production on its own without breaking anything? If yes, the PRs merge forward to
mainone at a time. If landing unit 1 alone would leavecheckbroken, tests failing, or a migration half-applied, the answer is no and the stack merges down into its bottom branch to reachmainatomically.We already have a worked example.
partition-rules-by-engine's first task group is implemented and leaves 20 tests failing — migration0004moves rules out from under readers that later groups update. Nothing is wrong with that work; it simply cannot be a forward stack, and the proposal should have said so before the code existed rather than after.The guidance is to prefer stacking and aim under ~300 lines per diff, with the caveat that tests count toward the total but never get split from the code they cover — a unit that is oversized because of its tests is usually a unit that should have been smaller.
Also removes "stacks are optional" from the section opening, which contradicted the preference now stated a few lines below it.
Nothing here changes the mechanics of landing a stack; the existing merge-down instructions and the archive-gate interaction are unchanged, and the new section points at both.