PRD numbering: adopt prd-new placeholder + post-merge workflow to eliminate merge-time conflicts #213
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
PRD numbers are assigned at branch-creation time and collide when multiple branches are open simultaneously. This session required renumbering six PRDs after the fact (0051→0054, three branches all claiming 0053, etc.) because there is no mechanism to defer numbering until merge.
Proposed conventions
1. Drop PRD numbers from branch names
Branch names should not include a PRD number. Use a short descriptive slug instead:
This is the highest-value change and has zero infrastructure cost. Dropping the number from branch names alone would have prevented most of the friction this pattern causes.
2. Use
prd-newas a placeholder filename until mergePRD files on a branch are named
prd-new-<slug>.md(e.g.prd-new-install-script.md). The header reads# PRD NEW: <Title>andStatus: Draft. The number is not assigned until the file lands onmain.PR titles use the slug, not a number:
egress-extended-outbound-scan: extend DLP scan surfaces.3. A post-merge workflow on
mainassigns the number and flips StatusOn every push to
mainthat adds aprd-new-*.mdfile, a Gitea Actions workflow:docs/prds/at that commit.prd-new-<slug>.md→NNNN-<slug>.md.# PRD NEW:with# PRD NNNN:in the file header.docs/prds/. If yes (implementation shipped in the same PR), flipsStatus: Draft→Status: Active. If no (PRD-only PR — implementation follows separately), leaves Status as Draft.docs(prd): number prd-new-<slug> → PRD NNNN.Numbering is serialised through
main's linear history, so two PRDs merging in quick succession get different numbers based on push order — no human coordination needed. PRs continue to targetmaindirectly; no staging branch is needed.4. (Ideal) Block direct merges to
mainthat include aprd-newfile via a required PR status checkA required Gitea Actions status check on PRs targeting
mainfails if the PR diff adds anyprd-new-*.mdfile and the PR was not opened by the numbering workflow itself. This prevents the bypass path where a developer manually numbers a PRD and pushes directly.A required status check is easier to maintain than a server-side
pre-receivehook — it lives in.gitea/workflows/alongside the rest of CI and does not require server configuration.Scope
AGENTS.mdanddocs/prds/README.mdwith the new naming convention..gitea/workflows/prd-number.yml(post-merge numbering + Status workflow)..gitea/workflows/prd-check.yml(PR status check that rejects rawprd-newfiles targetingmaindirectly).Non-goals
main.prd-promotionstaging branch (unnecessary given post-merge numbering onmain).PRD numbering: adopt prd-new + promotion-branch workflow to eliminate merge-time conflictsto PRD numbering: adopt prd-new placeholder + post-merge workflow to eliminate merge-time conflictsI think status should be auto updated as well: is a little awkward/introduces a brief period post merge when a prd thats implemented might be marked “draft”, but its already a bit awkward to keep the “new” tag. Avoids risk of forgetting to flip the status, which is high for manual prs.
Agreed — the "brief Draft window" argument is weaker than the "will definitely forget" argument, especially for agent-opened PRs where there's no natural moment to go back and flip the status.
The one edge case worth calling out: a PRD can land on
mainbefore its implementation does (PRD-only PR merges first, implementation follows in a separate PR). In that case auto-flipping to Active at numbering time would be wrong — the PRD would be marked Active before anything ships.Two options:
Flip on numbering, accept the edge case — simple rule, easy to automate, occasionally inaccurate for split PRD+implementation workflows. Since most PRDs here ship in the same PR as the implementation, this is usually correct.
Flip on numbering only when the PR also contains non-PRD file changes — the workflow checks whether the merged commit touches anything outside
docs/prds/; if yes, flip to Active; if no (PRD-only PR), leave as Draft. Slightly more logic in the workflow but closer to the semantic intent.Option 2 seems worth the small extra complexity given that PRD-only PRs are a real pattern here. Leaning toward that — does that match your expectation?
RE #213 (comment)
Option 2 is a good idea, add it
Done — updating the issue now to incorporate option 2 into the workflow spec.