From 6f245639ca013cd8446323d525a33055441db20b Mon Sep 17 00:00:00 2001 From: dan-claude-bot Date: Sun, 2 Aug 2026 13:27:40 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20the=20write-capable=20token=20rule=20?= =?UTF-8?q?=E2=80=94=20repo-owned=20by=20default,=20established=20publishe?= =?UTF-8?q?rs=20only,=20SHA-pinned?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ruling from discussion #171 as ruled: canonical text in REVIEWER.md §What you review against item 2 (beside the verify-at-pin sub-bullet it is the sibling of), short form in BUILDER.md §Building pointing at it. CONTRIBUTING.md and docs/CONSUMERS.md checked for contradiction or duplication: none — their pin prose is the mirror/caller pinning rule — so both are deliberately untouched. Refs #216 Co-Authored-By: Claude Fable 5 --- BUILDER.md | 7 +++++++ REVIEWER.md | 13 +++++++++++++ changelog.d/216.md | 7 +++++++ 3 files changed, 27 insertions(+) create mode 100644 changelog.d/216.md diff --git a/BUILDER.md b/BUILDER.md index f8492e4..0ab03f1 100644 --- a/BUILDER.md +++ b/BUILDER.md @@ -200,6 +200,13 @@ triage bug, and the move is to say so on the issue, not to guess. guard still refuses anything that deletes a shipped heading. - Follow the repo's conventions file and match the code you touch. Tests are not optional: the issue's test plan is the floor, not the ceiling. +- **A write-capable job gets a repo-owned script, not a third-party action.** + If the job's token can write (`packages: write`, `contents: write`, + `id-token: write`, deploy secrets), default to a script in the repo that a + test can drive; a third-party action there needs an established publisher + and a full-commit-SHA pin. Read-only jobs still SHA-pin. The full rule and + the red-flag profile a reviewer will apply are in REVIEWER.md §What you + review against, item 2 (incubator#53/#54; #216). - **Scope discipline: the PR does the issue — whole, and nothing else.** Adjacent problems you discover go to a **discussion** (or a comment on the relevant issue), where triage will do its job. You do not mint issues — diff --git a/REVIEWER.md b/REVIEWER.md index b661c29..f41565b 100644 --- a/REVIEWER.md +++ b/REVIEWER.md @@ -49,6 +49,19 @@ In order of authority: `0.1.0`'s `load_config` rejected `triage-actors=...` with `malformed label row` and `exit=1`. CI green on a conversion PR proves nothing about the new config: the base branch's workflow is what ran. + - **Third-party actions never hold a write-capable token by default.** In + any job whose token is write-capable (`packages: write`, + `contents: write`, `id-token: write`, or one carrying deploy secrets), + the default is a repo-owned script a test can drive. A third-party + action may hold that token only if it comes from an **established + publisher** — a real organization with maintenance history and more + than one maintainer, not a memberless shell or a lone account shipping + an unauditable `dist/` blob — and is **pinned by full commit SHA**. An + action matching the incubator red-flag profile never holds a write + token, however well it works. Read-only jobs: ordinary dependency + judgement, SHA-pinning still required. This is bot-run infrastructure — + no human watches runtime logs, so a compromised action's window is + unbounded (incubator#53/#54; #216). 3. **The code itself** — correctness first, then tests (does the test plan's floor exist? do the failure cases actually fail?), then conventions. Changelog line present for behavior changes; comments carry why, not diff --git a/changelog.d/216.md b/changelog.d/216.md new file mode 100644 index 0000000..f111098 --- /dev/null +++ b/changelog.d/216.md @@ -0,0 +1,7 @@ +### Changed + +- Doctrine: third-party actions never hold a write-capable token by default — + repo-owned scripts in write-capable jobs, established publisher plus + full-SHA pin for the exception, SHA pins everywhere. Canonical in + REVIEWER.md, short form in BUILDER.md; consumers adopt at the pin bump + (#216).