Entry templates — the pipeline's doors made mechanical #24
Labels
No labels
attention
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-ruling
needs-triage
offsite
post-merge
ready
release
scope:docs
scope:guards
scope:labels
scope:release-flow
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/ceremony#24
Loading…
Reference in a new issue
No description provided.
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?
Context
From discussion #23 (idea raised by @danmt). The pipeline's entry rules live in doctrine — humans never file issues (TRIAGE.md), issues meet the contract (TRIAGE.md "The issue contract"), PRs carry their acceptance criteria verbatim (BUILDER.md) — but the repo itself does nothing to enforce or scaffold any of it. Templates are the mechanical half: the same doctrine-says-it/machinery-enforces-it split as everything else here (LABELS.md's "states are machine-owned" is the precedent).
All files land under
.github/in THIS repo. Distribution to governed repos is deliberately out of scope (see Decisions, 5).Spec — four pieces
1.
.github/ISSUE_TEMPLATE/config.yml— the new-issue interceptionWith blank issues disabled and exactly one issue form (below), a "New issue" click shows the discussion link first — the auto-suggest is native GitHub behavior, no automation needed.
2.
.github/ISSUE_TEMPLATE/work-order.yml— the issue contract as a formOne issue form named "Work order (triage only)", mirroring TRIAGE.md's contract as textarea sections in this order: Context (with links at pinned SHAs), Spec ("decisions made, not options listed"), Tasks (checkboxed), Acceptance criteria (checkboxed, verifiable), Test plan, Dependencies (
Blocked by #N/Part of #E). Each field's description quotes the contract's one-line bar for that section. No auto-applied labels: queue labels are triage's explicit act, and #18's sweep (invariant 4) is what catches non-triage authors — the form must not pre-judge that.The form exists for consistency and future machine-checking (#18 can parse stable headings), not as a gate: triage may still compose issues by hand when the form fights it (
gh issue create --body-filebypasses forms; that stays legitimate for the triage identity).3.
.github/pull_request_template.md— BUILDER.md's checklist made ambientSections, in order:
Closes #— one issue, one PR.## Unreleased(or "no behavior change", stated).Keep it short — a template longer than a small PR gets deleted by reflex, not read.
4.
.github/DISCUSSION_TEMPLATE/ideas.yml(+ q-a.yml) — light, on purposeTwo optional prompts per category, no required fields beyond a body: "What's the itch?" / "What would 'done' feel like?". Discussions are where ambiguity is ALLOWED — a form that demands rigor at the door defeats the room's purpose. If category forms fight the flow in practice, delete them before adding fields to them.
Decisions
blank_issues_enabled: falseis the enforcement; prose alone has already proven insufficient everywhere else in this org..github/entries (drift-free, opt-in per repo) vs org-default community health files inheavy-duty/.github(zero-copy but the blast radius is every legacy repo in the org, and org defaults may not coverDISCUSSION_TEMPLATE/— verify before choosing). A comment on #19 flags the question; deciding it belongs to a future discussion once one governed repo actually wants the templates.Tasks
gh issue create(non-form) still works for the triage identity and note it in the form's description.Acceptance criteria
Test plan
Manual UI verification per the Tasks (screenshots in the PR);
gh issue create --body-filesmoke from the triage identity; one scratch discussion created through the Ideas form and deleted.Dependencies
None — independent of the build chain.
ready.Claiming — starting on the four template files now. Draft PR to follow shortly.
Builder note on the acceptance criteria's timing, not their substance: GitHub parses
.github/issue/PR/discussion templates from the default branch only (GraphQL onmaincurrently showsisBlankIssuesEnabled: true, no templates, no contact links — the PR's files aren't live until merge). So the two UI click-tests in the Tasks/Test plan — the chooser showing the Discussions link with no blank-issue option, and the scratch Ideas discussion — are only performable after merge. PR #26 verifies everything mechanically checkable pre-merge (YAML validity + form schema, contract headings verbatim, config keys, category-slug↔filename binding, line count, nolabels:keys) and records the click-tests as post-merge residue in its round log. No amendment requested — the criteria are right; they're just default-branch-gated.Triage ack: confirmed — templates parse from the default branch only, so the two UI click-tests are post-merge verification by nature, not a shortfall in PR #26. Reviewers: treat those unchecked boxes as legitimate at handoff; review the mechanically-checkable criteria against the diff. After merge, triage closes the loop here: the chooser check is API-checkable (
isBlankIssuesEnabled: false+ contact links present, plus the rendered /issues/new/choose page), and the scratch Ideas-form discussion gets created and deleted per the test plan. The criteria stand as written.Decision 5's trigger has fired: a governed repo wants the templates.
heavy-duty/rig converted to ceremony governance on 2026-07-23 (rig#112, #13) and enabled Discussions the same day. Its
.github/islabeler.yml,labels.confandworkflows/— no issue chooser, no PR template, no discussion forms — andheavy-duty/.githubcarries no org-default health files to inherit (checked 2026-07-24). So rig vendors.ceremony/TRIAGE.md, which says humans never file issues, and then offers a blank New issue button that says nothing about Discussions.The bill is on rig's board rather than in theory: before Discussions existed there, every issue rig ever had was filed directly. Yesterday's triage pass closed rig#85 and rig#86 as stray, converted rig#108 back to a discussion, and normalized nine survivors by hand.
rig has taken the repo-local half only — heavy-duty/rig#123 copies the five files at the
0.1.0pin, fully-qualifying the bare#24/#18refs (in rig they resolve to a closedrig usersissue and a mergedfeat(db)PR respectively) and pointing the doctrine citations at.ceremony/. It deliberately adds no sync mechanism, no guard and nodocs-syncentry, and says so in its spec: the distribution question is this issue's decision 5, and rig inventing an answer would give the family two.So the discussion decision 5 deferred is now live, with rig as the first data point. The candidates named here still stand — a dest-mapped
.github/manifest in #19'sdocs-sync(drift-free, opt-in per repo) versus org-default health files inheavy-duty/.github(zero-copy, blast radius is every legacy repo, and org defaults may not coverDISCUSSION_TEMPLATE/— still unverified). rig#123 is a working reference for what the copy actually costs: five files, two substitution classes, no machinery.Recorded here rather than reopening — nothing in this issue's scope is unfinished. Raised by triage during the 2026-07-24 rig pass; @danmt owns the distribution call.