Repository navigation
Commit 5b31fb9
governance(AGENTS.md PD15): carve the fleet-write relay's refresh stroke out of the release.yml dispatch prohibition (#23436)
Fixes #23393
Clause-②: no
Executes ruling **A** on #23193: ruling record `6160857949`, the
maintainer's word verbatim 「23209 A」, on the options put in
`6141962120`. #23193 remains open for PR #23209. #23177 remains open.
**Governed, Tier H** (`AGENTS.md`). This PR stays a draft until an
at-tier contract review and an authorized approval. Landing order per
the ruling: this PR first, then PR #23209 merges `main`, is re-checked
and lands. Only after that is ruling B item 5 on #23177 (`6139629628`)
executable.
Patch round 1 (`session_01B7mrh59UAGffd7s9asUfoY`, head `9b68a60e` to
`e7712a44`) adds edit 2 below. That is the seat's answer B (card comment
`6164269656`) to the report's open question.
## What changes
Two edits to `AGENTS.md` Prime Directive 15. Nothing else in the file
changes.
**1. The reserved-act clause.** This is the shape option A put to the
maintainer: "the reserved act becomes dispatching `release.yml` in any
lane except the relay's ... refresh stroke (... `refresh_version_pr:
true` alone)".
- Before: ⛔ `workflow_dispatch`-ing `release.yml` or any other
publish-capable workflow,
- After: ⛔ `workflow_dispatch`-ing `release.yml` in any lane but the
fleet-write relay's refresh stroke (`refresh_version_pr: true` alone),
or any other publish-capable workflow,
**2. The bold lead.** This aligns the lead with the amended list.
- Before: no AI seat publishes, tags, cuts a Release, or triggers a
release workflow, and none merges the Version Packages PR.
- After: no AI seat publishes, tags, cuts a Release, or triggers a
release, and none merges the Version Packages PR.
- Why: ruling A adopts the rationale in `6141962120`, "one rule text
that matches one mechanism". With only the clause amended, the lead
still forbade what the amended list admits, because the relay's refresh
stroke does trigger `release.yml`, which is a release workflow. That is
the same contradiction that held PR #23209. The seat's answer
(`6164269656`) treats aligning the lead as executing the ruling as
given, not as a new decision.
- Bound: the reserved-act list stays the definition. Every other
`release.yml` lane and every other publish-capable workflow stays
reserved there by name.
**Proof that nothing else moved.** Against merge base `4f81f31526`, `git
diff -w --word-diff` shows exactly two changes:
- the lead's `release workflow,` becomes `release,`, so one word
(`workflow`) is removed;
- the clause `in any lane but the fleet-write relay's refresh stroke
(refresh_version_pr: true alone),` is inserted.
A whitespace-normalised whole-file comparison of `AGENTS.md` at base and
at head `e7712a44` equals base with exactly those two edits applied. It
answers `true`. Control: the same edits without the clause's trailing
comma answer `false`. Lines 307-315 of the hunk are the forced re-flow
of the paragraph at its own typeset width (118 B). The lead edit
shortens line 302 in place and re-flows nothing.
Every other reserved act stays word for word:
- `changeset publish` / `pnpm run release`;
- the version tag, the GitHub Release and the runtime image;
- any other `release.yml` dispatch or input combination, and any other
publish-capable workflow;
- the `release` environment approval;
- merging, queueing or arming the Version Packages PR.
## True on the `main` it merges into (dependence on PR #23209)
- `WORKFLOW_DISPATCH_INPUTS` is not on `main`: `git grep -c
WORKFLOW_DISPATCH_INPUTS origin/main` answers nothing (exit 1) at
`4f81f31526`. PR #23209 (head `961ec7100a`) adds it in
`scripts/pm/fleet-write/ops.mjs` as `'release.yml': {
refresh_version_pr: true }`. So the clause states the rule (the relay's
stroke, with that one input alone) and names no constant.
- On `main` the relay's `WORKFLOW_DISPATCH_ALLOWLIST` is
`['shard-timings-refresh.yml']`. `validate.mjs --self-test` pins that a
`release.yml` dispatch is refused, and the refusal names that list. So
between this landing and PR #23209's, the relay refuses the admitted
stroke with zero writes. The rule lands before its mechanism, and it
fails closed.
- **This carve-out can be used only once PR #23209 lands.** Nothing here
edits `release.yml`, `scripts/pm/fleet-write/**` or PR #23209, and
nothing was dispatched.
## Why the stroke cannot publish: `release.yml` jobs on `main`
(`4f81f31526`)
- `version-pr` (`Version PR maintenance`) runs on `schedule`, or on a
dispatch with `inputs.refresh_version_pr` true. It is the only job the
stroke starts.
- `release-integrity` (`Release integrity (audit + no-mint backfill)`)
and `stale-prompts` (`Cancel publish prompts for versions already on
npm`) carry `!inputs.refresh_version_pr` in their own `if:` for a
dispatch.
- `full-battery` (`Full battery green at the version commit`) and
`publish` (`Publish ... to npm (awaiting approval)`) need
`release-integrity`, so a skipped audit makes `success()` false. Their
`force` branch also carries `!inputs.refresh_version_pr`.
- `docker` (`Docker image`) has no input guard. It runs only on a
`published` output from `release-integrity` or `publish`, and the stroke
leaves both unset.
So the card's "the publish lanes require `!inputs.refresh_version_pr`"
holds literally for two jobs and on the `force` branch for two more, and
`docker` is covered through its dependency. The two dispatches recorded
in `6141962120` (runs `38351525685` and `38357219168`) ran `Version PR
maintenance` and skipped the other five jobs.
## Line budget: why the ruling's clause and not a three-part sentence
- `AGENTS.md` has a line ceiling of 1116 in
`scripts/pm/check-skill-line-ratchet.mjs`, at headroom 0 on base.
Raising it takes a maintainer ruling quoted in the raising PR. Ruling A
ruled the text and named no line budget.
- I measured with that gate's own `wrapLine` at the paragraph's typeset
width (118 B). The base paragraph greedy-wraps to its current 15 lines,
so it has no lossless re-wrap headroom, and its last line has 99 B of
slack. With both edits (+91 B clause, -9 B lead) the paragraph is still
15 lines, with 12 B of slack on its last line. `AGENTS.md` stays at 1116
lines on head `e7712a44`.
- The three-part sentence the card sketched (the admitted dispatch, the
by-job warrant, and every other act unchanged; 367 B) measures **+3
lines (1116 to 1119)**. It would need its own ruling. The ratchet's
header refuses re-wrapping existing text to pay for it.
- The warrant above is recorded here, not in the rule. PD15's own second
paragraph holds that "the YAML is not a barrier that holds against you".
So the carve-out's authority is the ruling, and the job guards are only
the reason it is safe.
## Reviewer points
1. The bold lead is aligned in patch round 1, per the seat's answer B
(`6164269656`); see edit 2.
2. Mirror check: no file restates PD15's reserved-act list, so nothing
moves in step. The queries are listed under Acceptance notes.
3. Prime Directive 13: no ADR reserves the refresh stroke. ADR-0125 line
95 (PD15's "prohibitions stand as written") is the record of 2026-08-20,
and it predates `refresh_version_pr`. Nothing is superseded.
## Acceptance notes
- Mirror search over `.claude/**`, `skills/**`, `scripts/**` and
`docs/**`, with git grep -F at `9b68a60e`. Control: `publish-capable
workflow` in `AGENTS.md` = 1 hit.
- 0 hits in all four trees for each list phrase: `publish-capable
workflow`, `publish-capable`, `workflow_dispatch`-ing, `release act
itself`, `triggers a release workflow`, `PD15` and pending `release`
environment.
- `Prime Directive 15`: `scripts/release-github-releases.mjs` (2 hits;
it cites PD15 for not deleting Releases).
- `Prime Directive #15`: `scripts/pm/check-skill-line-ratchet.mjs` (1, a
historical ceiling comment), plus `docs/adr/0125-…` and
`docs/adr/0082-…` (7 in total, all citations).
- `refresh_version_pr`: `scripts/pm/check-expected-skips.mjs` (2) and
`docs/releases-maintenance.md` (3, the maintainer's runbook).
- `.claude/skills/pm-dispatch/SKILL.md:34` is a pointer ("发布动作的完整清单以
AGENTS.md 为权威").
- Pointers do not move, and there is no Tier S hunk.
- The card cites PD15 at `:300-312`. On base it is `:301-321`. The lead
edit is at `:302`, and the amended clause is at `:307-308`.
## Gates (head `e7712a44`)
Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` (no paths; 1 path vs merge base `4f81f3152`,
+10 / -10). This is the same 15-command list as on `9b68a60e`. All 15
exited 0, with exit codes captured before any pipe:
- `check-closing-keyword-parity` and its `--self-test`
- `check-comment-mask-corpus`
- `check:agent-test-spelling`
- `check:docs-audit-scope`
- `check:driver-memory-census`
- `check:gitlink-declared`
- `check:nul-bytes` ("no raw ASCII control bytes")
- `check:pm-governed-merges`
- `check:pm-governed-prose`
- `check:pm-skill-id-lint` ("87 file(s) clean")
- `check:pm-skill-ratchet` ("AGENTS.md is 1116 lines (ceiling 1116;
headroom 0)")
- `check:refd-timer-probe`
- `check:required-contexts`
- `check:watch-hint-literal`
Also run, outside the derivation: `check-published-list-mirrors` ("1
published list mirror(s) match"), exit 0.
Reconciliation with `--ran`: "15 derived, 15 run, 0 NOT-MEASURED, 0
UNRUN", a derived zero.
Not measured:
- `scripts/check-required-contexts.mjs --verify-required-set`, which
takes a value from the workflow.
- No package build or test: no package is touched.
No changeset: `AGENTS.md` ships in no package's `files[]`
(`skip-changeset`). GitHub reports the PR mergeable, so `main` was not
merged in.
## 维护者速读(草稿)
### 改了什么
AGENTS.md 第 15 条改了两处:
1. 保留动作清单。手动派发 `release.yml` 仍由维护者保留,只有一种例外:经 fleet-write 中继、只带
`refresh_version_pr: true` 的刷新,它只重生成 Version Packages PR。
2. 加粗首句。「triggers a release workflow」改成「triggers a release」,和清单对齐。
其余保留动作一字未改,包括发布、打 tag、Release、镜像、`release` 环境审批,以及合并或排队 Version Packages
PR。
### 为什么改
执行 #23193 的裁决 A(「23209 A」)。裁决 B 第 5 条要求席位在修复合入后立刻刷新 Version PR,但原文禁止任何
`release.yml` 派发,规则和机制互相矛盾,PR #23209
因此一直搁置。只改清单的话,首句仍会禁止清单已经允许的刷新,矛盾还在。所以按裁决 A
的理由「一条规则文本对应一种机制」,首句一并对齐。这是席位对报告问题的答复(B)。
### 风险与代价(含回滚)
这次刷新不会发布:它只跑 `Version PR
maintenance`,审计、发布、镜像任务都跳过,两次实跑可以作证。首句改短以后,其余发布类派发仍由清单逐项点名保留。PR #23209
合入之前,中继会直接拒绝 `release.yml`,例外暂时用不上,失败方向是关闭。行数仍是 1116,不需要抬上限。回滚方法:revert
本 PR 合入的 commit。
### 席位意见
### 你要做的
批准本 PR(Tier H)。
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 863213a commit 5b31fb9
1 file changed
Lines changed: 10 additions & 10 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
299 | 299 | | |
300 | 300 | | |
301 | 301 | | |
302 | | - | |
| 302 | + | |
303 | 303 | | |
304 | 304 | | |
305 | 305 | | |
306 | 306 | | |
307 | | - | |
308 | | - | |
309 | | - | |
310 | | - | |
311 | | - | |
312 | | - | |
313 | | - | |
314 | | - | |
315 | | - | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
316 | 316 | | |
317 | 317 | | |
318 | 318 | | |
| |||
0 commit comments