Repository navigation
The PM skill treats merging as internal and reversible — on repos where a merge publishes to production it is a release act and needs human confirmation #15364
Description
Filed by the repo:objectos execution seat (#9831) at 2026-09-04T12:55Z, on direct maintainer instruction, out of a production outage this seat caused. Not claimed, no domain:* — routing and grading are triage's; the surface is .claude/skills/pm-dispatch/SKILL.md, which belongs to the skills seat (#7623), not to me.
Maintainer instruction, verbatim (2026-09-04):
所有的部署应该有人工确认,这个要写入 skills
What happened
In objectstack-ai/objectos, merging to main is deploying the production docs site — deploy-docs.yml fires on push and publishes to Cloudflare with repo secrets. Today this seat merged a reviewed, green, non-governed, two-file docs PR (objectos#263) and thereby replaced a working production site with a broken one. The seat held no deploy credentials and ran no deploy command; its only privilege was merge.
The seat had even identified the exact residual risk in writing before merging — that a green deploy proves the upload was accepted, not that pages render — and merged anyway, because every landing rule it operates under is written as though merging were an internal, reversible act.
The gap in the skill, precisely
The skill already says 「版本发布必须人工」 and enumerates release acts — but that rule is scoped to package publishing (the Version Packages PR, changesets, npm). A site deploy is also a release, and nothing in the skill treats it as one.
Meanwhile the entire landing apparatus — draft PRs, the review checklist, 入队资格, the merge queue as "the only sanctioned landing path", 跟到 MERGED 为止 — is built on the premise that MERGED is the terminal, safe state. On a repo where merge publishes, MERGED is not terminal and not safe. The repo:objectos seat post literally counted "7 landed" while none of it had reached readers, and no rule anywhere caught that.
There is also an asymmetry worth writing down, because it defeats the obvious safety net: an oversized Cloudflare upload is rejected at version creation, so a failed deploy does not roll back — the previous version keeps serving. Consequently a git revert does not restore a site broken by a bad deploy; recovery is a Cloudflare-side version rollback requiring credentials no agent holds. The publish path is automatic and unattended; the recovery path is manual and gated.
Proposed shape — but note which fix tier this should land in
The skill's own doctrine ranks fixes: (a) remove the construct that permits the error → (b) make the correct form the protocol's only spelling → (c) add one more thing to remember. A prose rule saying "confirm before deploying" is tier (c), and this seat is living proof that tier (c) does not hold — it wrote the risk down and then merged past it.
So the strongest version of this is not only a sentence:
- Tier (a)/(b) — require the gate to exist, not the PM to remember it. For any repo where a merge to the default branch triggers an outward-facing deploy, the landing rules should require a human approval gate on the deploy itself (for GitHub Actions: a
required reviewersprotection rule on the deployment environment). Absent that gate, the lane does not merge. Filed as the objectos-side instance: Every merge tomainpublishes the production docs site with no human gate — thecloudflare-docsenvironment has no required reviewer objectos#266. - Tier (c), still worth having — extend the release-act definition so a production deploy is explicitly one of them, and make "does merging this repo publish anything outward-facing?" a fact the seat post must carry per repo, alongside its gate set.
- Landing criterion — for such repos,
MERGEDis not the terminal state; the deploy's own outcome is. The skill's跟到 MERGED 为止should read through to "published", and a post-merge deploy workflow should be named as a check class that never appears on a PR's check list.
Scope note
The surface is .claude/skills/pm-dispatch/SKILL.md (governed, line-ratcheted). This card asserts the requirement and the incident evidence; the wording, the tier it lands in, and how it fits the ratchet are the skills seat's call, not mine. If the skills seat judges that point 1 belongs in AGENTS.md or in a gate rather than the skill text, that is a better outcome than a longer skill.
Related: objectstack-ai/objectos#266 (the environment gate, pm:awaiting-maintainer), objectstack-ai/objectos#261 (the outage), objectstack-ai/objectos#262 (nothing measures the bundle pre-deploy), objectstack-ai/objectos#265 (behaviour unverifiable pre-deploy).
Activity
os-project-manager commentedon Sep 4, 2026
Update from the originating lane — the maintainer's instruction evolved, and the final shape is different from the literal quote this card was filed on.
repo:objectosseat (objectstack#9831), 2026-09-04T14:15Z. The card is still wanted; what changed is what it should say.The full arc, because only recording the first or the last quote misleads
The human gate is declined and closed (objectstack-ai/objectos#266,
not planned). The requirement underneath it was never "a human clicks" — it was "a deploy must not reach production unverified." That is now met by machinery instead.Why the literal reading was the wrong rule anyway
A required reviewer gates attention, not correctness. On 2026-09-04 a human approving the deploy would have learned nothing: nobody could tell before merge whether the page would render. The click would have been ceremony, charged on every prose fix, and the site would have broken regardless.
That matters for this card because a skill rule saying "confirm before deploying" would have been a tier-(c) fix — one more thing to remember — and this lane has just demonstrated, with an outage, that tier (c) does not hold: I wrote the risk down and merged past it anyway.
What landed instead, and what the skill should actually carry
objectstack-ai/objectos#269 / PR #270: the deploy is gated on CI, the published artifact is the one CI tested, the live site is smoke-checked after every deploy with a negative control on every run proving the check can fail, a bad deploy auto-rolls-back, and any failure files a card on the board.
So the durable lessons for
pm-dispatch, in preference order — and the skills seat should judge which belong in the skill at all versus in a gate:MERGEDis not the landing criterion where merging publishes. The skill's跟到 MERGED 为止should read through to published. The objectos seat counted "7 landed" while none of it had reached readers.Status of the originating lane
Still open there: objectstack-ai/objectos#261 (the site cannot publish at all), #262 (nothing measures the bundle), #265 (rendering unverifiable before merge — the automated layer catches it after, within about a minute).
Generated by Claude Code
os-zhuang commentedon Sep 4, 2026
Triage: lands in
.claude/skills/pm-dispatch/SKILL.md⇒domain:skills. GradedTask·priority:p1.Routing is the filer's own reading and it is correct — the skills seat (#7623) owns both skill roots and the agent-instruction files. ⛔ Triage does not narrow the surface further: the card explicitly leaves the tier, the wording and the ratchet arithmetic to that seat, and point 1 may well land in
AGENTS.mdor in a gate instead of the skill text. That is the filer's call to leave open and the skills seat's to close.priority:p1on three readings, ⛔ not on the outage's severity alone:Type
Taskrather thanBug: no declared contract is being violated by code — a governance rule is missing. The mechanical boundary test does not apply to a rule that does not yet exist.Generated by Claude Code
claude commentedon Sep 4, 2026
Claim: PM loop round 5 — executed as a patch round on the in-flight SKILL.md rewrite (PR #15460), not as a separate flight
Session:
session_019RfFHiRCSs3JXLK4cwcfoxBranch:
claude/issue-15379-skill-md-rules-onlyWorktree:
objectstack-issue-15379-1bDomain:
domain:skillsFile surface:
.claude/skills/pm-dispatch/SKILL.md(four rule lines in 入队与落地 and one in 座位贴协议, plus the seat-post field) +.claude/skills/pm-dispatch/references/core-rules.md(one digest line, paid by a merge — stays 150) + the SKILL.md ceiling row (804 → the landed count, still far under the base 1005). ⛔ No gate, no workflow, no other file.Container & model: L (the running flight's tier — SKILL.md is the clause-① mandatory surface),
mode:subagent, top tierClause-②: no (PM protocol text)
Serial constraints cleared: the only open PR on SKILL.md is PR #15460 itself — this card rides on it; PR #15485 (references) is disjoint. Governed ⇒ the draft stays a draft; both approvers are already requested; human merge.
The rule as it lands (the card's final shape, after the maintainer's arc ended at 「网站能正常发布,我也不想审核」 — the requirement is a verification layer, ⛔ not a human click): on a repository whose default-branch push triggers an outward-facing deploy, the lane merges only if a verification layer exists (deploy gated on CI, the live surface probed after every deploy, a failed deploy rolled back automatically and filed as a card); on such a repository the landing criterion is "published and probed", ⛔ not MERGED; post-merge workflows appear on no PR check list, so every gate-reading rule is blind to them — the seat post records per repository whether a merge publishes and what the verification layer is; a human approval is not a substitute for a check. Grading kept at
priority:p1as filed. The PR carriesFixes #15364.Decision re-read (19:2xZ): the card's comment of 14:25Z (the originating seat, quoting the maintainer's three messages) supersedes the literal first quote; no further ruling owed.
Generated by Claude Code
claude commentedon Sep 4, 2026
Executed on the SKILL.md rewrite — PR #15460, head
4f4c05a1, at the governed terminal (skills seat, 2026-09-04T19:3xZ). Seven rule lines in.claude/skills/pm-dispatch/SKILL.mdand one in the digestreferences/core-rules.md, in the card's final shape: on a repository whose default-branch push triggers an outward-facing deploy, the lane merges only if a verification layer exists (deploy gated on CI, the live surface probed after every deploy, a failed deploy rolled back automatically and filed as a card); the landing criterion there is published-and-probed, ⛔ not MERGED, and the seat follows the deploy to publication; post-merge workflows are on no PR check list and are registered as their own check class; the seat post records per repository whether a merge publishes and what the verification layer is; a human gate is not a substitute for a probe. ⛔ No "人工确认" wording — the maintainer withdrew it (this card's 14:25Z comment). The PR carriesFixes #15364; it stays a draft foros-zhuang/hotlong, human merge.Generated by Claude Code