Context
PR #11335 exposed a high-severity substrate gap: an agent-authored PR temporarily targeted main instead of dev, producing a GitHub UI surface with 10,000 commits and 8,398 changed files even though the real delta against dev was only three files.
Live verification after the incident:
neomjs/neo repository default branch is dev.
- PR #11335 was not caused by GitHub defaulting to
main; it was explicitly or contextually aimed at main despite the repo default.
buildScripts/release/publish.mjs is the intentional release path that writes to main: it requires starting on dev, creates an atomic commit-tree commit using the current dev tree and origin/main parent, then pushes that single commit to refs/heads/main.
.agents/skills/pull-request/references/pull-request-workflow.md already mandates --base dev, but this rule lives in a conditionally-loaded skill payload rather than the always-loaded critical-gate layer.
- #11336 covers Layer 4 mechanical enforcement. This ticket covers Layer 1 only:
AGENTS.md §0 invariant elevation.
The Problem
AGENTS.md §0 currently forbids agent merges and direct commits/pushes to main or dev, but it does not explicitly forbid agent-authored PRs targeting main.
That leaves a gap between two protections:
- The human-only merge rule prevents agents from executing the actual merge.
- The pull-request workflow tells agents to target
dev, but only if /pull-request is loaded and followed correctly.
A wrong-base PR can still be opened, reviewed incorrectly, and create urgent swarm friction before the human merge gate catches it. Since main is the release line and publish.mjs is the special atomic release bridge, the PR-target rule belongs in the always-loaded critical gates.
The Architectural Reality
Layered defense after #11335:
| Layer |
Mechanism |
Surface |
Owner |
| 1 |
Always-loaded invariant |
AGENTS.md §0 |
This ticket |
| 2 |
Author workflow discipline |
.agents/skills/pull-request/references/pull-request-workflow.md |
Existing / possible follow-up |
| 3 |
Reviewer Cycle-0 base gate |
.agents/skills/pr-review/** |
Separate available lane |
| 4 |
Mechanical CI/MCP guard |
GitHub workflow or github-workflow MCP wrapper |
#11336 |
This ticket must stay small: add the missing always-loaded invariant and preserve the release exception for buildScripts/release/publish.mjs.
The Fix
Update AGENTS.md §0 Critical Gates with a concise invariant:
- Agent-authored PRs must target
dev.
- PRs targeting
main are release-line operations and require an explicit operator release directive.
- The dedicated release exception is
buildScripts/release/publish.mjs, which performs the low-level atomic squash-to-main workflow.
Also update nearby wording/counting if needed so the §0 invariant list remains internally consistent.
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
AGENTS.md §0 Critical Gates |
PR #11335 incident + operator clarification on publish.mjs |
Always-loaded rule forbids agent-authored PRs targeting main, except explicit release operation through publish.mjs / operator directive |
Lower-layer /pull-request rule remains but is no longer the only guard |
AGENTS.md |
Static grep plus PR-body evidence citing #11335 |
| Release-line exception |
buildScripts/release/publish.mjs |
Preserve main mutation only for atomic release flow from dev to main |
Human operator can still direct release work explicitly |
buildScripts/release/publish.mjs comments |
Source inspection of commit-tree / refs/heads/main path |
Acceptance Criteria
Out of Scope
- Implementing the mechanical CI/MCP guard from #11336.
- Updating
/pr-review Cycle-0 baseRefName gates.
- Retargeting or reviewing PR #11335.
- Changing the repository default branch.
- Changing
buildScripts/release/publish.mjs behavior.
Avoided Traps / Gold Standards Rejected
- Bundling all four layers: rejected because it collapses distinct review surfaces and repeats the bloat problem this session is trying to prevent.
- Banning all
main writes: rejected because publish.mjs intentionally creates the release-line atomic diff commit on main.
- Relying only on prose in
/pull-request: rejected because #11335 showed conditionally-loaded workflow prose is insufficient as the first line of defense.
Related
- Incident PR: #11335
- Mechanical guard: #11336
- Release path:
buildScripts/release/publish.mjs
Origin Session ID: d6d89930-f408-42a0-b60e-ec4487a8cc46
Retrieval Hint: "PR #11335 base-main incident AGENTS §0 agent-authored PR target dev publish.mjs release exception"
Context
PR #11335 exposed a high-severity substrate gap: an agent-authored PR temporarily targeted
maininstead ofdev, producing a GitHub UI surface with 10,000 commits and 8,398 changed files even though the real delta againstdevwas only three files.Live verification after the incident:
neomjs/neorepository default branch isdev.main; it was explicitly or contextually aimed atmaindespite the repo default.buildScripts/release/publish.mjsis the intentional release path that writes tomain: it requires starting ondev, creates an atomiccommit-treecommit using the currentdevtree andorigin/mainparent, then pushes that single commit torefs/heads/main..agents/skills/pull-request/references/pull-request-workflow.mdalready mandates--base dev, but this rule lives in a conditionally-loaded skill payload rather than the always-loaded critical-gate layer.AGENTS.md§0 invariant elevation.The Problem
AGENTS.md §0currently forbids agent merges and direct commits/pushes tomainordev, but it does not explicitly forbid agent-authored PRs targetingmain.That leaves a gap between two protections:
dev, but only if/pull-requestis loaded and followed correctly.A wrong-base PR can still be opened, reviewed incorrectly, and create urgent swarm friction before the human merge gate catches it. Since
mainis the release line andpublish.mjsis the special atomic release bridge, the PR-target rule belongs in the always-loaded critical gates.The Architectural Reality
Layered defense after #11335:
AGENTS.md §0.agents/skills/pull-request/references/pull-request-workflow.md.agents/skills/pr-review/**This ticket must stay small: add the missing always-loaded invariant and preserve the release exception for
buildScripts/release/publish.mjs.The Fix
Update
AGENTS.md §0 Critical Gateswith a concise invariant:dev.mainare release-line operations and require an explicit operator release directive.buildScripts/release/publish.mjs, which performs the low-level atomic squash-to-main workflow.Also update nearby wording/counting if needed so the §0 invariant list remains internally consistent.
Contract Ledger Matrix
AGENTS.md §0 Critical Gatespublish.mjsmain, except explicit release operation throughpublish.mjs/ operator directive/pull-requestrule remains but is no longer the only guardAGENTS.mdbuildScripts/release/publish.mjsmainmutation only for atomic release flow fromdevtomainbuildScripts/release/publish.mjscommentscommit-tree/refs/heads/mainpathAcceptance Criteria
AGENTS.md §0contains an explicit invariant that agent-authored PRs must targetdev.mainis release-only and requires explicit operator release direction.buildScripts/release/publish.mjsas the dedicated atomic release path that may push tomain.AGENTS.md.Out of Scope
/pr-reviewCycle-0 baseRefName gates.buildScripts/release/publish.mjsbehavior.Avoided Traps / Gold Standards Rejected
mainwrites: rejected becausepublish.mjsintentionally creates the release-line atomic diff commit onmain./pull-request: rejected because #11335 showed conditionally-loaded workflow prose is insufficient as the first line of defense.Related
buildScripts/release/publish.mjsOrigin Session ID: d6d89930-f408-42a0-b60e-ec4487a8cc46 Retrieval Hint: "PR #11335 base-main incident AGENTS §0 agent-authored PR target dev publish.mjs release exception"