From bb984de1339bf05539fec9c999194b75c10de809 Mon Sep 17 00:00:00 2001 From: codex-bot-andresmgsl Date: Tue, 25 Aug 2026 12:15:47 +0000 Subject: [PATCH] docs: add proposal intake --- .github/DISCUSSION_TEMPLATE/ideas.yml | 19 --------------- .github/DISCUSSION_TEMPLATE/q-a.yml | 15 ------------ .github/ISSUE_TEMPLATE/config.yml | 13 +++++----- .github/ISSUE_TEMPLATE/proposal.yml | 34 +++++++++++++++++++++++++++ .github/ISSUE_TEMPLATE/work-order.yml | 6 ++--- AGENTS.md | 10 ++++---- BUILDER.md | 2 +- CONTRIBUTING.md | 23 +++++++++--------- FLEET.md | 2 +- LABELS.md | 4 ++-- REVIEWER.md | 4 ++-- TRIAGE.md | 26 ++++++++++---------- changelog.d/247.md | 3 +++ docs/CONSUMERS.md | 10 ++++---- 14 files changed, 89 insertions(+), 82 deletions(-) delete mode 100644 .github/DISCUSSION_TEMPLATE/ideas.yml delete mode 100644 .github/DISCUSSION_TEMPLATE/q-a.yml create mode 100644 .github/ISSUE_TEMPLATE/proposal.yml create mode 100644 changelog.d/247.md diff --git a/.github/DISCUSSION_TEMPLATE/ideas.yml b/.github/DISCUSSION_TEMPLATE/ideas.yml deleted file mode 100644 index 561125f..0000000 --- a/.github/DISCUSSION_TEMPLATE/ideas.yml +++ /dev/null @@ -1,19 +0,0 @@ -# Light on purpose: discussions are where ambiguity is ALLOWED — a form -# that demands rigor at the door defeats the room's purpose (issue #24, -# decision 4). If these prompts fight the flow in practice, delete them -# before adding fields to them. -body: - - type: textarea - attributes: - label: What's the itch? - description: >- - Vague is fine — a bug, an idea, a "we should…". Triage turns this - into work (or an answer); you don't have to. - validations: - required: false - - type: textarea - attributes: - label: What would "done" feel like? - description: Optional — a sketch of the outcome, if you can already see it. - validations: - required: false diff --git a/.github/DISCUSSION_TEMPLATE/q-a.yml b/.github/DISCUSSION_TEMPLATE/q-a.yml deleted file mode 100644 index b3c9b52..0000000 --- a/.github/DISCUSSION_TEMPLATE/q-a.yml +++ /dev/null @@ -1,15 +0,0 @@ -# Light on purpose — same reasoning as ideas.yml (issue #24, decision 4): -# optional prompts only, delete before hardening. -body: - - type: textarea - attributes: - label: What's the question? - description: Ask it plainly — context and links help, none are required. - validations: - required: false - - type: textarea - attributes: - label: What have you tried or read already? - description: Optional — saves the answerer a lap. - validations: - required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 7a9b1ff..86fe263 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,13 +1,12 @@ # The new-issue interception (issue #24, decision 1): interception over # instruction — prose alone has already proven insufficient everywhere else # in this org. With blank issues disabled and exactly one form, a "New -# issue" click shows the discussion link first; that auto-suggest is native -# GitHub behavior, no automation needed. +# issue" click shows the proposal route first; that auto-suggest is native +# forge behavior, no automation needed. blank_issues_enabled: false contact_links: - - name: Ideas, bugs, questions — start a Discussion - url: https://github.com/heavy-duty/ceremony/discussions + - name: Ideas, bugs, questions — file a Proposal + url: https://forgejo.heavyduty.builders/heavy-duty/ceremony/issues/new?template=proposal.yml about: >- - Humans (and agents) never file issues here — discussions are where - intent lives. Triage converges every discussion to an outcome, and - only triage mints issues (TRIAGE.md). + Anyone may file a proposal. Triage converts it into a work issue or + refuses it with reasons; only triage mints work issues (TRIAGE.md). diff --git a/.github/ISSUE_TEMPLATE/proposal.yml b/.github/ISSUE_TEMPLATE/proposal.yml new file mode 100644 index 0000000..4dc3472 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/proposal.yml @@ -0,0 +1,34 @@ +# This intake form applies no labels: queue labels are triage's explicit act +# (LABELS.md), and the issue-flow sweep catches non-triage authors, so the form +# must not pre-judge the proposal's queue state (#24 D2). +name: Proposal (anyone) +description: >- + Share an idea, bug, question, or rough "we should…" for triage to convert + into work or refuse with reasons. +body: + - type: markdown + attributes: + value: >- + Proposals are the low-bar intake door. Say what you noticed and why it + might matter; triage will decide whether it becomes a work issue. + - type: textarea + id: noticed + attributes: + label: What did you notice? + description: A rough idea, bug, question, or "we should…" is enough. + validations: + required: true + - type: textarea + id: why-it-matters + attributes: + label: Why might it matter? + description: Optional — describe the impact or opportunity if you can. + validations: + required: false + - type: textarea + id: known-context + attributes: + label: What do you already know? + description: Optional — add links, examples, constraints, or prior art. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/work-order.yml b/.github/ISSUE_TEMPLATE/work-order.yml index 723ea8c..2d6cde0 100644 --- a/.github/ISSUE_TEMPLATE/work-order.yml +++ b/.github/ISSUE_TEMPLATE/work-order.yml @@ -6,8 +6,8 @@ # that (issue #24, decision 2). name: Work order (triage only) description: >- - The issue contract (TRIAGE.md) as a form. Only triage mints issues — - everyone else starts a Discussion. Triage may still compose by hand when + The issue contract (TRIAGE.md) as a form. Only triage mints work issues — + everyone else files a proposal. Triage may still compose by hand when the form fights it: `gh issue create --body-file` bypasses forms and stays legitimate for the triage identity. body: @@ -25,7 +25,7 @@ body: attributes: label: Context description: >- - Why this exists, with links — the discussion it came from, the code + Why this exists, with links — the proposal it came from, the code it touches (permalinks at a pinned SHA, so line references cannot rot), prior art in sibling repos. validations: diff --git a/AGENTS.md b/AGENTS.md index b8af0fa..4c235c0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -14,7 +14,7 @@ reviewer here"). That one word is your whole onboarding: | you are the… | read | your job in one line | |---|---|---| -| **triage** agent | [TRIAGE.md](TRIAGE.md) | turn discussions into buildable issues — or refuse well; you are the only door issues come through | +| **triage** agent | [TRIAGE.md](TRIAGE.md) | turn proposals into buildable work issues — or refuse well; you are the only door work issues come through | | **builder** agent | [BUILDER.md](BUILDER.md) | turn one `ready` issue into one PR that meets its acceptance criteria | | **reviewer** agent | [REVIEWER.md](REVIEWER.md) | verdicts on PRs — approve or request-changes, converge, hand to the human | @@ -23,7 +23,7 @@ are the shared state machine, and misusing one lies to every other agent on the board. **Not told a role?** Infer it from the task: asked to review a PR → reviewer; -asked to implement an issue → builder; asked to process discussions or the +asked to implement an issue → builder; asked to process proposals or the backlog → triage. Still ambiguous → ask before acting. Do not free-lance across roles in one session: a builder reviewing its own PR, or a reviewer pushing fixes, breaks the separation the pipeline depends on. @@ -31,13 +31,13 @@ pushing fixes, breaks the separation the pipeline depends on. ## The pipeline you are part of ``` -discussion ──▶ triage ──▶ issue ──▶ build ──▶ review ──▶ human merge ──▶ release - (anyone) (agent) (queue) (agent) (agents) (human) (ceremony) +proposal ──▶ triage ──▶ work issue ──▶ build ──▶ review ──▶ human merge ──▶ release + (anyone) (agent) (queue) (agent) (agents) (human) (ceremony) ``` Two rules bind every role: -- **Only triage mints issues.** Found work? Open or extend a discussion. +- **Only triage mints work issues.** Found work? File or extend a proposal. - **Only humans merge.** Convergence ends at `state:needs-human`, never at a merge button. diff --git a/BUILDER.md b/BUILDER.md index ec916c5..532e541 100644 --- a/BUILDER.md +++ b/BUILDER.md @@ -140,7 +140,7 @@ triage bug, and the move is to say so on the issue, not to guess. its red-flag profile are in REVIEWER.md §What you review against, item 2 (#216). - **Scope discipline: the PR does the issue — whole, and nothing else.** - Adjacent problems go to a discussion, or a comment on the relevant issue; + Adjacent problems go to a proposal, or a comment on the relevant issue; you do not mint issues — nobody but triage does — and you do not fix drive-by findings in the same PR. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2207731..dfb5e80 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,22 +10,22 @@ the two is a bug. Work moves through one pipeline, and every stage has an owner: ``` -discussion ──▶ triage ──▶ issue ──▶ build ──▶ review ──▶ human merge ──▶ release - (anyone) (agent) (queue) (agent) (agents) (human) (ceremony) +proposal ──▶ triage ──▶ work issue ──▶ build ──▶ review ──▶ human merge ──▶ release + (anyone) (agent) (queue) (agent) (agents) (human) (ceremony) ``` -- **Discussions are where intent lives.** Anyone — human or agent — who has an - idea, a bug, a question, or a "we should…" opens a **discussion**, not an - issue. Discussions are allowed to be vague; that is what they are for. -- **Issues are minted only by triage.** Nobody else writes issues — not - humans, not builders, not reviewers. An issue is a work order with a quality +- **Proposals are where intent lives.** Anyone — human or agent — who has an + idea, a bug, a question, or a "we should…" files a **proposal**, not a work + issue. Proposals are allowed to be vague; that is what they are for. +- **Work issues are minted only by triage.** Nobody else writes work issues — + not humans, not builders, not reviewers. A work issue is a work order with a quality bar (the issue contract in [TRIAGE.md](TRIAGE.md)), and the bar holds because exactly one role is accountable for it. An issue that appears through any other door gets `needs-triage` and is normalized or converted - back into a discussion. + back into a proposal. - **Builders turn one issue into one PR.** [BUILDER.md](BUILDER.md). - **Reviewers converge on a verdict.** [REVIEWER.md](REVIEWER.md). -- **Humans decide twice**: in the discussion (what is worth doing, and any +- **Humans decide twice**: in the proposal (what is worth doing, and any call triage escalates back) and at the merge (whether it ships). Everything between those two points is agent work by default. - **Merging a release PR ships it** — the release ceremony this repo's @@ -62,7 +62,7 @@ panel-minus-author, and three is what it currently comes to, not a second rule. Builders and triage default to different models so the issue contract is honestly exercised — a spec gap should surface as a question on the issue, not be silently filled by shared priors. Humans (`andres`) decide in -discussions and merge; the roster is config, not doctrine — swapping a +proposals and merge; the roster is config, not doctrine — swapping a vendor is an edit to this table (and to `panel=` in `.github/labels.conf` once #10 lands), nothing more. @@ -143,7 +143,8 @@ A governed repo (box, rig, cast, incubator, …) therefore carries: - the **`scope:*` label set** (`.github/labels.conf` + `.github/labeler.yml`), - the **drill meaning** (`drills/README.md`), - the repo's own code conventions; -- **Discussions enabled**, so the triage door exists. +- **An intake door is open**: install the proposal form and `needs-triage` + flow, or use a forge-native intake surface. One pin governs both the machinery and the doctrine: the ref a repo's workflows call is the ref its `.ceremony/` mirror is verified against. diff --git a/FLEET.md b/FLEET.md index 24ab681..6fad032 100644 --- a/FLEET.md +++ b/FLEET.md @@ -136,7 +136,7 @@ The earlier form of this file folded handoff and rebase into the other builder wakes; they are duties of their own. - **Triage signals**, per registry repo: `needs-triage` issues, - queue-unlabeled strays, discussions without triage's voice, unread + queue-unlabeled strays, proposals without triage's voice, unread `@`-mentions (their own session), and `blocked` issues whose named blockers have all landed — a lead the session verifies, never a label the engine flips. Backlog hygiene (stale claims, label invariants) runs hourly, diff --git a/LABELS.md b/LABELS.md index 46a7f08..3d56b6b 100644 --- a/LABELS.md +++ b/LABELS.md @@ -51,7 +51,7 @@ strips it on sight). | Label | Color | Means | Set by | |---|---|---|---| -| `needs-triage` | `#FBCA04` | an issue that did not come through triage — it owes normalization or conversion back to a discussion | anyone who spots one; cleared by triage | +| `needs-triage` | `#FBCA04` | a proposal or stray issue that did not come through triage — it owes normalization into work or a reasoned refusal | anyone who spots one; cleared by triage | | `ready` | `#0E8A16` | triaged, spec complete, unblocked — a builder can start now and succeed | triage | | `claimed` | `#1D76DB` | a builder owns it: assignee set, a draft PR expected shortly | the claiming builder | | `blocked` | `#6A737D` | waiting on another issue or PR (`Blocked by #N` in the body names it) | triage; anyone may correct it | @@ -242,4 +242,4 @@ full-board reconcile. The sweep warns when the core taxonomy declares a label the repository lacks. The same workflow reconciles issue-flow labels on issue events and during the scheduled sweep. Default GitHub labels (`duplicate`, `invalid`, `question`, `wontfix`, `help wanted`, `good first issue`) are -deleted at bootstrap — a `question` is a discussion, not an issue. +deleted at bootstrap — a `question` belongs in a proposal, not a work issue. diff --git a/REVIEWER.md b/REVIEWER.md index 17e8b77..a2315f9 100644 --- a/REVIEWER.md +++ b/REVIEWER.md @@ -123,9 +123,9 @@ saw Y" outranks one that says "this looks like it might". ## What you do not do - **Re-litigate the spec.** The issue's decisions were made in triage and, - above it, in a discussion where humans had their say. If you think the + above it, in a proposal where humans had their say. If you think the spec itself is wrong, say so with reasons — as a comment pointing at the - discussion, while still reviewing the implementation against the spec as + proposal, while still reviewing the implementation against the spec as written. Spec changes go through triage, not through a review round. - **Merge, or tell the builder to merge.** Convergence hands the PR to a human; only humans merge. diff --git a/TRIAGE.md b/TRIAGE.md index 43b656a..967dd33 100644 --- a/TRIAGE.md +++ b/TRIAGE.md @@ -1,22 +1,24 @@ # TRIAGE.md — the triage role -You are the only door issues come through. Humans and agents open **discussions**; -you decide what becomes work and set the quality builders and reviewers receive. +You are the only door work issues come through. Humans and agents file +**proposals**; you decide what becomes work and set the quality builders and +reviewers receive. ## Why this door exists -Discussions may be ambiguous; issues may not: a builder must be able to execute -one **without asking anything**. One accountable role keeps builders from guessing. +Proposals may be ambiguous; work issues may not: a builder must be able to +execute one **without asking anything**. One accountable role keeps builders +from guessing. ## Your inputs -- **Every open discussion** in the repo you serve. +- **Every open proposal** in the repo you serve. - **Stray issues** — anything filed directly, by anyone. Label it `needs-triage`, then either bring it up to contract (below) or convert its - substance back into a discussion and close it, saying why. Route the work + substance into a proposal and close it, saying why. Route the work without shaming the filer. -## For each discussion, converge on exactly one outcome +## For each proposal, converge on exactly one outcome 1. **Answer.** The question has an answer, the bug is not one, the idea is already shipped or tracked. Link the code, doc, or issue; mark answered. @@ -32,9 +34,9 @@ one **without asking anything**. One accountable role keeps builders from guessi [BUILDER.md's canonical ruling template](BUILDER.md#the-ruling-ask), including its options, recommendation, blocked/continues statement, and reversible-only default rules (#50 D12–D13). - The discussion is where humans decide; wait there. When the decision + The proposal is where humans decide; wait there. When the decision blocks something already on the board — an existing issue, or minted work - a discussion's ruling gates — set `needs-ruling` on it too, so the board + a proposal's ruling gates — set `needs-ruling` on it too, so the board shows where the human's turn is; the issue keeps its queue label. When you direct a builder to hold a claim, say the claim is **parked**, name what it waits on, and set `attention` so the assignee's ack is visible @@ -61,7 +63,7 @@ one **without asking anything**. One accountable role keeps builders from guessi This is not a substitute for minting work or for `needs-ruling`. 4. **Decline.** Real idea, wrong repo or wrong time. Say why plainly, link where it belongs if anywhere, close. A refusal with reasons is a good - outcome; a zombie discussion is not. + outcome; a zombie proposal is not. 5. **Accept.** It justifies work → mint the issue(s). The contract below is the bar. @@ -71,7 +73,7 @@ Every issue you mint carries, in this order: - **A title that names the deliverable** — "lib/version.sh — one version abstraction, two backends", never "improve version handling". -- **Context**: why this exists, with links — the discussion it came from, +- **Context**: why this exists, with links — the proposal it came from, the code it touches (permalinks at a pinned SHA, so line references cannot rot), prior art in sibling repos. - **The spec**: decisions made, not options listed. If the spec still has an @@ -159,4 +161,4 @@ Repositories that adopt version epics follow [RELEASES.md](RELEASES.md). - Assign a builder — builders pick and claim ([BUILDER.md](BUILDER.md)). - Make the human's decisions (outcome 3 exists for those), or soften a refusal into a vague issue to avoid saying no. -- Mint an issue to "discuss" something — that is a discussion. +- Mint a work issue to explore an idea — file a proposal instead. diff --git a/changelog.d/247.md b/changelog.d/247.md new file mode 100644 index 0000000..77e3d1b --- /dev/null +++ b/changelog.d/247.md @@ -0,0 +1,3 @@ +### Changed + +- Replace the unavailable intake rule with a proposal form that triage converts into work or refuses with reasons (#247). diff --git a/docs/CONSUMERS.md b/docs/CONSUMERS.md index ce3d17e..c317ad5 100644 --- a/docs/CONSUMERS.md +++ b/docs/CONSUMERS.md @@ -851,15 +851,16 @@ published release. ## Adopting the agent team flow -The team flow (discussion → triage → issue → build → review → human +The team flow (proposal → triage → work issue → build → review → human merge) is **optional per repo and separable from the release ceremony**: a repo can adopt release-only and take the team flow later — incubator's initial posture (#16). The model is this repo's own [CONTRIBUTING](../CONTRIBUTING.md) ("How the other repos use this"); this is the checklist: -- [ ] **Enable Discussions** — the triage door exists or the pipeline - has no intake. +- [ ] **Open the intake door** — install `proposal.yml` and the automatic + `needs-triage` flow. A repo whose forge provides Discussions may keep + them as its intake door and point `config.yml`'s contact link there. - [ ] **Vendor the doctrine**: run `docs-sync --fix` (#19) to materialize `.ceremony/{AGENTS,TRIAGE,BUILDER,REVIEWER,LABELS}.md` — byte-identical to this repo at the pinned ref — plus the generated @@ -893,7 +894,8 @@ this is the checklist: `workflow_dispatch` once ([above](#labels-automation)), or the hand commands in [LABELS.md](../LABELS.md). - [ ] **State the single-writer rule** in the repo's own docs: only - triage mints issues; everyone else opens discussions. + triage mints work issues; anyone may file a proposal, which triage + converts or refuses. ### The pin-bump procedure