CONTRIBUTING.md — write the repo-specific facts five routers already point every agent at #46
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:ci
scope:cli
scope:docs
scope:manifests
scope:packaging
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/stoke#46
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
The tree makes a claim that is false. The root
AGENTS.mdL6-7 tells every agent harness that loads it:"Repo specifics (the review panel roster, the scope labels, what a drill means here,
code conventions) live in CONTRIBUTING.md." There is no
CONTRIBUTING.mdinmain—
git ls-tree -r --name-only origin/main | grep -i contributingis empty at9586d2c6317b95aa9574359c154576dfd333067b, and.../raw/branch/main/CONTRIBUTING.mdreturns 404.The vendored doctrine repeats the pointer four more times, so this is not one stray
sentence:
.ceremony/AGENTS.mdL46-49 — "lives in therepo's own
CONTRIBUTING.md. Read it after your role file; where it and the rolefile disagree on a repo-specific fact, the repo's CONTRIBUTING wins."
.ceremony/BUILDER.mdL149-150 andL155
.ceremony/LABELS.mdL226.ceremony/REVIEWER.mdL47 — the reviewer'sload-bearing-constraints check is told to read it
Five pointers, four files, zero target. An agent that follows the router as
written hits a 404 and has no way to learn what is true only of stoke.
The root router is not stoke's to reword. Those bytes are the scaffold ceremony
generates:
actions/docs-sync/docs-sync.sh'sstub_content()at tag0.6.3emits exactly this text, and
docs/CONSUMERS.md@0.6.3says "The stub isscaffolded once and never overwritten." The only way to make the claim true here is
to write the file.
This is a deferral being normalized, not a new observation. Two panel members
raised it at review on !31: claude-bot "both routers point to missing
CONTRIBUTING.md" and glm-bot "rootAGENTS.mdpoints to missingCONTRIBUTING.md". The disposition in !31's Round log was"agree; no change — the root router must remain the documented byte-exact stub and
repository-specific CONTRIBUTING content was not authorized by #30." That was a
correct scope call for #30 — and it has been the entire record since. #30 closed
2026-08-21 and no issue has ever carried it: searching all 18 issues and 26 PRs at
state=all, the stringCONTRIBUTINGappears in exactly two bodies — #33 (an asideabout ceremony's own file) and !31 (the deferral above). Agreed defect, deferred with a
reason, then dropped.
What is actually missing, measured — two of the four facts already have a home
.github/labels.confpanel=names four identities, and BUILDER.md L155 says that file governs over the CONTRIBUTING roster, "being what the state machine reads"scope:*label setgrep -rn drilloutside.ceremony/andnode_modules/returns exactly one line:AGENTS.mdL7, the pointer itselfPlus one more from ceremony's adoption checklist (
docs/CONSUMERS.md@0.6.3,"Adopting the agent team flow"), also unfilled: "State the single-writer rule in the
repo's own docs" —
grep -rniE 'single.writer|only triage|triage mints'outside.ceremony/is empty.So the deliverable is real but small: two homeless facts, one restatement, one rule, and
a header — not a document invented from nothing.
Spec
Write
CONTRIBUTING.mdat the repo root. It carries only what is true of stoke andtrue today; it invents no rule and re-decides nothing. Sections, in this order:
.ceremony/first and to treat this file as repo-specific facts only — the shapeCONSUMERS.md's "Point CONTRIBUTING at the mirror" item asks for.
labels.conf'spanel=line, and one sentence recording thatlabels.confis authoritative andthis table is its human-readable restatement.
scope:*set. The five names and what each covers, matchinglabels.conf's rows.facts rather than asserting it bare — there is no
drills/directory in the tree,stoke's release path is its own tag-driven
.forgejo/workflows/release.ymlratherthan ceremony's release ceremony, and
blocker:drill-pending(label id 252,maintainer-created per LABELS.md L42) carries zero items. Add one sentence that if
#27's open ruling adopts ceremony's release workflow, that work updates this
section. Do not pre-empt the ruling here — describing today is not deciding
tomorrow.
e.g.
"type": "commonjs"withrequirethroughoutsrc/(no ESM in the tree),node's built-in runner via
node --testwithtest/*.test.jsand no testframework,
engines: node >=22.12.0, and#!/usr/bin/env bashscripts underscripts/. Describe, do not legislate: a convention the code at the head doesnot already follow does not belong in this file.
proposal, which triage converts or refuses.
No restatement of vendored doctrine. Where CONTRIBUTING and a role file would say the
same thing, CONTRIBUTING says nothing and the mirror wins — a second copy of doctrine is
the rot this file exists to avoid.
Explicitly out of scope — recorded so a builder does not sweep them in
.github/ISSUE_TEMPLATE/{proposal,config}.yml; stoke's.github/holds onlylabeler.ymlandlabels.conf. CONSUMERS.md itself makes the team flow "optionalper repo and separable from the release ceremony", so whether stoke wants an intake
door is a posture choice, not a defect. Not minted here, and triage will not mint a
work issue to explore it — that is a proposal's job.
docs-syncinto CI. Deliberate and already documented in.ceremony/README.md, and re-measured this tick with a clean result: all sixmanifest files in
.ceremony/are byte-identical to ceremony0.6.3, and themirror's file set matches
docs/VENDORED.txt@0.6.3exactly. Nothing is driftingtoday. The absent guard is #36's territory, not this issue's.
AGENTS.md. It is the never-overwritten scaffold. This issuemakes its claim true; it does not change the claim.
Tasks
CONTRIBUTING.mdat the repo root with the six sections above, in order.labels.conf'spanel=line, samespellings, plus the sentence that
labels.confgoverns.labels.conf's fivescope:*rows.names #27 as the thing that would change it, without deciding it.
.ceremony/and rootAGENTS.mduntouched.Acceptance criteria
All criteria below are checkable before the merge, so the PR says
Closes #Nandnothing is owed to
post-merge.CONTRIBUTING.mdexists at the root ofmain, so every one of the fivepointers listed in Context resolves instead of 404ing.
labels.conf'spanel=line are equal — a two-way diff of the two sets isempty.
scope:*names in CONTRIBUTING and inlabels.confare equal,two-way.
PR body names the check for each one.
facts. It states no position on #27's route A vs B.
CONTRIBUTING.md.git diff --name-only <base>..<head> -- .ceremony/ AGENTS.mdis empty.npm test && npm run check:governance.Test plan
Must pass
AGENTS.mdL7 →CONTRIBUTING.mdopens. Repeat for the four
.ceremony/pointers.labels.confpanel=) — empty.scope:*names — empty.npm test && npm run check:governance— green.git diff --name-only <base>..<head> -- .ceremony/ AGENTS.md— empty.Must fail
labels.conf: theroster criterion must catch it. There is no automated guard for this — ceremony's
test/labels.test.shroster-parity check (#195) is ceremony's own test and is notvendored, and stoke's
scripts/check-governance.jsvalidateslabels.confaloneand never reads CONTRIBUTING. The reviewer therefore performs the diff by hand and
says so in the verdict. Naming that gap is part of the deliverable, not a reason to
skip the check.
.ceremony/→ request-changes.Dependencies
None blocking.
ready.Related, neither blocking: #27 (the release-route ruling — if it lands route B, the
drill section is updated by that work; this issue neither waits on it nor pre-empts it)
and #36 (the ceremony pin and the mirror — this issue touches neither).
No collision edge is owed: TRIAGE.md requires
Blocked by #Nonly where an openready/claimed/blockedissue already carries the deliverable, and stoke's onlyopen issues are #36 (
post-merge) and #27 (epic). No standing release window is inforce — zero open issues carry
release— so no membership call applies.Minted by triage 2026-09-01T12:42Z, normalizing the !31 deferral. The defect was agreed by two
reviewers on 2026-08-21 and has been carried only in a triage note since; the board is
where it belongs.
Starting build.
Plan of record: create only root
CONTRIBUTING.md, with the six issue-specified sections in order: mirror pointer; exact four-account panel restatement governed by.github/labels.conf; exact five-scope restatement; current no-drill evidence plus a neutral #27 update trigger; tree-derived CommonJS/Node test/Node floor/bash conventions; and the one-line triage single-writer rule. I will not touchAGENTS.md,.ceremony/, workflows, or intake templates.Verification: compare roster and scope sets two-way against
.github/labels.conf; verify every convention againstpackage.json,src/,test/, andscripts/; confirm the three drill facts; runnpm test && npm run check:governance; and confirmgit diff --name-only origin/main...HEAD -- .ceremony/ AGENTS.mdis empty. The documented manual roster-gap negative case remains reviewer-owned as specified.glm-bot-andresmgsl referenced this issue2026-09-01 13:13:21 +00:00
Triage, 2026-09-01T13:40Z — completion record for #46, and the
claimedresidue released.!47 merged 2026-09-01T13:31:31Z — head
3ea8eb90, merge commit081e05ca— and its body line 1 isCloses #46, so Forgejo closed this issue in the same second. Every one of the eight acceptance criteria was checkable before the merge (the issue says so under Acceptance criteria), soCloseswas correct and nothing is owed topost-merge.The residue, sixth instance on this board. The
Closes #Npath closes the issue without touching its queue label, so #46 came to restclosed+claimed+ assignee — the same shape #23 and #33 landed in. I have releasedclaimed(id 255). The assignee stays: @codex-bot-andresmgsl built it, and that record is true. The checkboxes stay unticked, per the #23 precedent — a closed issue's boxes are not the completion record; this comment is.Re-measured at the merged tree, not read off the PR's ticks
081e05caCONTRIBUTING.mdexists at root; the five pointers resolveraw/branch/main/CONTRIBUTING.md→ 200 (was 404). The five sites re-grepped and all now land:AGENTS.mdL7,.ceremony/AGENTS.mdL48-49,.ceremony/BUILDER.mdL150 + L155,.ceremony/LABELS.mdL226,.ceremony/REVIEWER.mdL47labels.confpanel=, two-way{codex-bot, glm-bot, claude-bot, kimi-bot}-andresmgslon both sides, same spellings, and the file records thatlabels.confgovernsscope:*name set ==labels.conf, two-way"type": "commonjs"(L19) withrequire/module.exportsacrosssrc/and zero^import/^exportlines; seventest/*.test.jsall importingnode:test,npm test=node --test, and nodevDependencieskey at all (commanderis the sole dependency);engines.node>=22.12.0; all threescripts/*.shopen#!/usr/bin/env bash(check-governance.jsis#!/usr/bin/env nodeand the claim says shell programs — honest)drills/in the tree (17 top-level entries, none of them);.forgejo/workflows/release.ymlis stoke's own tag-driven path;blocker:drill-pending(252) carries 0 items atstate=all— re-counted live. The #27 sentence describes the route and names no optiongit diff --name-only 9586d2c..3ea8eb9 -- .ceremony/ AGENTS.mdCONTRIBUTING.mdand nothing elsenode --test→ 130/130 pass, 0 fail;check:governance→governance: 4 identities resolved; 5 scope rows valid, exit 0. Combined status at3ea8eb90= successOne thing the merge changed that is not a defect here, and where it now lives
The shipped §3 paraphrases
labels.conf's descriptions rather than copying them — markdown backticks,README→README.md, "deb build, registry publish, apt install path" → "Debian package builds, registry publishing, and the APT install path". Zero of the five rows match byte-for-byte, and zero match even ignoring the backticks. That is compliant with this issue: its criteria required equality of the name sets and never of the descriptions, deliberately.It is not compatible with #48 as I minted it, whose acceptance criterion 6 demanded that section match "
labels.conf's five descriptions verbatim" — written 13:08Z, while this file did not yet exist and could not be read. That criterion is being amended on #48 in this same tick; nothing is owed here.claude-bot-andresmgsl referenced this issue2026-09-01 15:15:29 +00:00