docs(agents): record that seats cannot delete remote branches (proxy 403, false Everything-up-to-date receipt) - #7242

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-6756-branch-delete-403-fact
Sep 2, 2026
Merged

docs(agents): record that seats cannot delete remote branches (proxy 403, false Everything-up-to-date receipt)#7242
os-zhuang merged 1 commit into
mainfrom
claude/issue-6756-branch-delete-403-fact

Conversation

@os-litant

@os-litantos-litant commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Fixes#6756

One knowledge line in AGENTS.md, per triage grading comment 5460872090. No code, no branch touched.

落点

AGENTS.md, section ### 多 agent 协作纪律(并行修改本仓库,务必遵守) under ## 9. Operational Rules — inserted as line 276, directly after the 绝不 git push --force / 绝不推 main bullet. That neighbour is the closest kin: both are "what a seat's push may and may not do against the shared remote", and the card itself cites the force-push ban (#5239) and the shared refs/stash fact (#3430) as its own family. ⛔ Deliberately not a new file — triage ruled the home is this section.

before

The section had no line at all about ref deletion. A seat that tried to delete its own probe branch had to rediscover the refusal by attempting it; the card records one dev seat spending four attempts doing exactly that.

after

One bullet (one physical line, matching the section's unwrapped-bullet format). It carries five things, all required by the ruling:

  1. The fact — a seat can push a branch but cannot delete a remote ref; the agent proxy refuses every ref-deletion push with error: RPC failed; HTTP 403. No bypass: the GitHub MCP tool surface has create_branch with no delete counterpart, and there is no gh CLI in the container.
  2. The false-success receipt, verbatim — after the 403, git prints Everything up-to-date. Triage called this the most valuable sentence on the card, above the 403 itself, and the reason is in the line: a caller that reads only the tail of the output, or treats a non-empty last line as success, reads a refused deletion as a completed one. Knowing it 403s does not protect you from that.
  3. The claim-signal consequence (from comment 5468280978) — the cost is not tidiness. An orphan sibling branch left by a rename-and-retry on one card is invisible from every surface a seat normally reads: not on the card, not in the PR list, not in any queue view. Only a per-card prefix glob shows it, and the line carries that command. The measured near-miss on card 4934 read for a moment as a second seat working the same card concurrently — the one thing the claim discipline exists to prevent.
  4. The four unmeasured points kept unmeasured, marked as such in the line itself: which layer returns the 403 (proxy policy / token scope / branch protection), whether other seats or environments can delete, whether tags are restricted the same way, and how many stale claude/* branches exist. ⛔ None was converted into an assertion.
  5. An explicit non-authorization — the line records a capability gap and authorizes no branch cleanup, no census, and no lifecycle policy. Those are the maintainer's.

In the line, the card number inside the glob is written as this repo's usual angle-bracket placeholder, matching the neighbouring bullets' own placeholder style (the objectui-TASK worktree path and the PATHS argument in the stash-alternative recipes). Spelled as placeholder words here on purpose — see the sanitizer note below.

Measured, not assumed

  • No line ratchet over AGENTS.md. The dispatch flagged this as an assumption to test. Verified: nothing under scripts/ computes a line budget or ratchet over this file, so the new line owes no compensating deletion. What does exist and was NOT anticipated: scripts/check-governed-queue-guard.mjs (governed-surface, AGENTS.md is row agents-md) and scripts/check-shell-escape-residue.mjs (scans this file's fences). Both are content/policy gates, not size gates.
  • The gate union was derived, not guessed.scripts/check-shell-escape-residue.mjs's own header documents the derived union for a change to AGENTS.md; the governed-surface guard was added to it later by Machine-enforce human review on governed-surface paths — so the no-bypass rule stops resting on seat discipline alone #6596.
  • No changeset is owed, and that is the gate's own verdict rather than my reading: check-changeset-presence reports 0 of them published source of a package the release covers for this diff. ⛔ No label was requested — objectui has no skip-changeset mechanism.
  • The bullet was written with the Write tool, not a shell heredoc.scripts/check-shell-escape-residue.mjs exists because a git commit -F - example in this very section shipped with its heredoc terminator wrapped in a shell escape run (AGENTS.md §9 的 git commit -F - 示例带着 shell 转义残留落地(<<'\"'\"'EOF'\"'\"'),照抄得到一条不会终止的 heredoc #5150). Repeating that mechanism to author a line in the same section seemed like a poor idea.
  • The GitHub body sanitizer ate two placeholder fragments from the first version of this description — the angle-bracket spellings were removed even inside backticks, leaving an empty pair of backticks. Caught by reading the stored body back after creating the PR; this revision spells them as words. The file itself is unaffected: the sanitizer touches GitHub bodies, not the committed diff.

Gates run — all on head e362056

gateexitverdict line
check-control-bytes0✅ OK (scanned 5996 tracked text file(s); skipped 85 binary).
check-doc-links0Links are valid across 17 scan roots.
check-changeset-presence0✅ No source or published contract of a released package changed in this range, so no changeset is owed.
check-changeset-no-major0✅ No changeset declares a major bump.
check-shell-escape-residue0✅ OK (4/4 root(s) resolved -- AGENTS.md: 1 file(s), 15 fence(s) ... 0 occurrence(s) outside a fence)
check-governed-queue-guard --self-test0OK ... 132 cases pass
check-governed-queue-guard --test AGENTS.md3One governed path governs the WHOLE pull request

Exit codes captured by redirecting to a file first, then reading $? — never through a pipe.

⛔ This PR STAYS DRAFT

The exit 3 above is the correct verdict, not a red gate. AGENTS.md is a governed surface, and the guard states the disposition itself:

⛔ Do not flip it ready, enqueue it, or arm auto-merge. Park it as a DRAFT and leave the merge to the maintainer; a human merge IS the review record for a governed surface.

⛔ Not marking ready, not enqueueing, not arming auto-merge. The merge is the maintainer's.

Note on the one body edit above: governed-surface-guard.yml's header records that on PR #6183 an MCP update_pull_request call passing only reviewers silently set draft: false, and the PR entered the queue and landed unreviewed. The revision was therefore sent with draft: true passed explicitly, and the stored state read back afterwards to confirm it is still a draft.

Out of scope, untouched

claude/probe-6716a-writecheck is still there. Deleting it needs someone with a working delete path — which, per the line this PR adds, is not this seat. Triage already routed it to the maintainer.


🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1

Seats can push a branch but every ref-deletion push is refused by the agent
proxy with HTTP 403, and git then prints `Everything up-to-date` — a success
receipt on a refused deletion. Records the capability gap, the verbatim false
receipt, and the claim-signal consequence (an orphan sibling branch for one
card is invisible from every seat surface and reads as a competing claim;
only a per-card prefix glob shows it).
The card's four unmeasured points are kept unmeasured. No branch cleanup, no
census, no lifecycle policy — those are the maintainer's.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 11:26
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit 1e30554Sep 2, 2026
28 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-6756-branch-delete-403-fact branch September 2, 2026 11:41
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentation

Projects

None yet

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

docs(agents): record that seats cannot delete remote branches (proxy 403, false Everything-up-to-date receipt) - #7242

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-6756-branch-delete-403-fact
Sep 2, 2026
Merged

docs(agents): record that seats cannot delete remote branches (proxy 403, false Everything-up-to-date receipt)#7242
os-zhuang merged 1 commit into
mainfrom
claude/issue-6756-branch-delete-403-fact

Conversation

@os-litant

@os-litantos-litant commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Fixes#6756

One knowledge line in AGENTS.md, per triage grading comment 5460872090. No code, no branch touched.

落点

AGENTS.md, section ### 多 agent 协作纪律(并行修改本仓库,务必遵守) under ## 9. Operational Rules — inserted as line 276, directly after the 绝不 git push --force / 绝不推 main bullet. That neighbour is the closest kin: both are "what a seat's push may and may not do against the shared remote", and the card itself cites the force-push ban (#5239) and the shared refs/stash fact (#3430) as its own family. ⛔ Deliberately not a new file — triage ruled the home is this section.

before

The section had no line at all about ref deletion. A seat that tried to delete its own probe branch had to rediscover the refusal by attempting it; the card records one dev seat spending four attempts doing exactly that.

after

One bullet (one physical line, matching the section's unwrapped-bullet format). It carries five things, all required by the ruling:

  1. The fact — a seat can push a branch but cannot delete a remote ref; the agent proxy refuses every ref-deletion push with error: RPC failed; HTTP 403. No bypass: the GitHub MCP tool surface has create_branch with no delete counterpart, and there is no gh CLI in the container.
  2. The false-success receipt, verbatim — after the 403, git prints Everything up-to-date. Triage called this the most valuable sentence on the card, above the 403 itself, and the reason is in the line: a caller that reads only the tail of the output, or treats a non-empty last line as success, reads a refused deletion as a completed one. Knowing it 403s does not protect you from that.
  3. The claim-signal consequence (from comment 5468280978) — the cost is not tidiness. An orphan sibling branch left by a rename-and-retry on one card is invisible from every surface a seat normally reads: not on the card, not in the PR list, not in any queue view. Only a per-card prefix glob shows it, and the line carries that command. The measured near-miss on card 4934 read for a moment as a second seat working the same card concurrently — the one thing the claim discipline exists to prevent.
  4. The four unmeasured points kept unmeasured, marked as such in the line itself: which layer returns the 403 (proxy policy / token scope / branch protection), whether other seats or environments can delete, whether tags are restricted the same way, and how many stale claude/* branches exist. ⛔ None was converted into an assertion.
  5. An explicit non-authorization — the line records a capability gap and authorizes no branch cleanup, no census, and no lifecycle policy. Those are the maintainer's.

In the line, the card number inside the glob is written as this repo's usual angle-bracket placeholder, matching the neighbouring bullets' own placeholder style (the objectui-TASK worktree path and the PATHS argument in the stash-alternative recipes). Spelled as placeholder words here on purpose — see the sanitizer note below.

Measured, not assumed

  • No line ratchet over AGENTS.md. The dispatch flagged this as an assumption to test. Verified: nothing under scripts/ computes a line budget or ratchet over this file, so the new line owes no compensating deletion. What does exist and was NOT anticipated: scripts/check-governed-queue-guard.mjs (governed-surface, AGENTS.md is row agents-md) and scripts/check-shell-escape-residue.mjs (scans this file's fences). Both are content/policy gates, not size gates.
  • The gate union was derived, not guessed.scripts/check-shell-escape-residue.mjs's own header documents the derived union for a change to AGENTS.md; the governed-surface guard was added to it later by Machine-enforce human review on governed-surface paths — so the no-bypass rule stops resting on seat discipline alone #6596.
  • No changeset is owed, and that is the gate's own verdict rather than my reading: check-changeset-presence reports 0 of them published source of a package the release covers for this diff. ⛔ No label was requested — objectui has no skip-changeset mechanism.
  • The bullet was written with the Write tool, not a shell heredoc.scripts/check-shell-escape-residue.mjs exists because a git commit -F - example in this very section shipped with its heredoc terminator wrapped in a shell escape run (AGENTS.md §9 的 git commit -F - 示例带着 shell 转义残留落地(&lt;&lt;'\"'\"'EOF'\"'\"'),照抄得到一条不会终止的 heredoc #5150). Repeating that mechanism to author a line in the same section seemed like a poor idea.
  • The GitHub body sanitizer ate two placeholder fragments from the first version of this description — the angle-bracket spellings were removed even inside backticks, leaving an empty pair of backticks. Caught by reading the stored body back after creating the PR; this revision spells them as words. The file itself is unaffected: the sanitizer touches GitHub bodies, not the committed diff.

Gates run — all on head e362056

gateexitverdict line
check-control-bytes0✅ OK (scanned 5996 tracked text file(s); skipped 85 binary).
check-doc-links0Links are valid across 17 scan roots.
check-changeset-presence0✅ No source or published contract of a released package changed in this range, so no changeset is owed.
check-changeset-no-major0✅ No changeset declares a major bump.
check-shell-escape-residue0✅ OK (4/4 root(s) resolved -- AGENTS.md: 1 file(s), 15 fence(s) ... 0 occurrence(s) outside a fence)
check-governed-queue-guard --self-test0OK ... 132 cases pass
check-governed-queue-guard --test AGENTS.md3One governed path governs the WHOLE pull request

Exit codes captured by redirecting to a file first, then reading $? — never through a pipe.

⛔ This PR STAYS DRAFT

The exit 3 above is the correct verdict, not a red gate. AGENTS.md is a governed surface, and the guard states the disposition itself:

⛔ Do not flip it ready, enqueue it, or arm auto-merge. Park it as a DRAFT and leave the merge to the maintainer; a human merge IS the review record for a governed surface.

⛔ Not marking ready, not enqueueing, not arming auto-merge. The merge is the maintainer's.

Note on the one body edit above: governed-surface-guard.yml's header records that on PR #6183 an MCP update_pull_request call passing only reviewers silently set draft: false, and the PR entered the queue and landed unreviewed. The revision was therefore sent with draft: true passed explicitly, and the stored state read back afterwards to confirm it is still a draft.

Out of scope, untouched

claude/probe-6716a-writecheck is still there. Deleting it needs someone with a working delete path — which, per the line this PR adds, is not this seat. Triage already routed it to the maintainer.


🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1

Seats can push a branch but every ref-deletion push is refused by the agent
proxy with HTTP 403, and git then prints `Everything up-to-date` — a success
receipt on a refused deletion. Records the capability gap, the verbatim false
receipt, and the claim-signal consequence (an orphan sibling branch for one
card is invisible from every seat surface and reads as a competing claim;
only a per-card prefix glob shows it).
The card's four unmeasured points are kept unmeasured. No branch cleanup, no
census, no lifecycle policy — those are the maintainer's.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 11:26
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit 1e30554Sep 2, 2026
28 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-6756-branch-delete-403-fact branch September 2, 2026 11:41
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentation

Projects

None yet

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(agents): record that seats cannot delete remote branches (proxy 403, false Everything-up-to-date receipt) - #7242

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-6756-branch-delete-403-fact
Sep 2, 2026
Merged

docs(agents): record that seats cannot delete remote branches (proxy 403, false Everything-up-to-date receipt)#7242
os-zhuang merged 1 commit into
mainfrom
claude/issue-6756-branch-delete-403-fact

Conversation

@os-litant

@os-litantos-litant commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Fixes#6756

One knowledge line in AGENTS.md, per triage grading comment 5460872090. No code, no branch touched.

落点

AGENTS.md, section ### 多 agent 协作纪律(并行修改本仓库,务必遵守) under ## 9. Operational Rules — inserted as line 276, directly after the 绝不 git push --force / 绝不推 main bullet. That neighbour is the closest kin: both are "what a seat's push may and may not do against the shared remote", and the card itself cites the force-push ban (#5239) and the shared refs/stash fact (#3430) as its own family. ⛔ Deliberately not a new file — triage ruled the home is this section.

before

The section had no line at all about ref deletion. A seat that tried to delete its own probe branch had to rediscover the refusal by attempting it; the card records one dev seat spending four attempts doing exactly that.

after

One bullet (one physical line, matching the section's unwrapped-bullet format). It carries five things, all required by the ruling:

  1. The fact — a seat can push a branch but cannot delete a remote ref; the agent proxy refuses every ref-deletion push with error: RPC failed; HTTP 403. No bypass: the GitHub MCP tool surface has create_branch with no delete counterpart, and there is no gh CLI in the container.
  2. The false-success receipt, verbatim — after the 403, git prints Everything up-to-date. Triage called this the most valuable sentence on the card, above the 403 itself, and the reason is in the line: a caller that reads only the tail of the output, or treats a non-empty last line as success, reads a refused deletion as a completed one. Knowing it 403s does not protect you from that.
  3. The claim-signal consequence (from comment 5468280978) — the cost is not tidiness. An orphan sibling branch left by a rename-and-retry on one card is invisible from every surface a seat normally reads: not on the card, not in the PR list, not in any queue view. Only a per-card prefix glob shows it, and the line carries that command. The measured near-miss on card 4934 read for a moment as a second seat working the same card concurrently — the one thing the claim discipline exists to prevent.
  4. The four unmeasured points kept unmeasured, marked as such in the line itself: which layer returns the 403 (proxy policy / token scope / branch protection), whether other seats or environments can delete, whether tags are restricted the same way, and how many stale claude/* branches exist. ⛔ None was converted into an assertion.
  5. An explicit non-authorization — the line records a capability gap and authorizes no branch cleanup, no census, and no lifecycle policy. Those are the maintainer's.

In the line, the card number inside the glob is written as this repo's usual angle-bracket placeholder, matching the neighbouring bullets' own placeholder style (the objectui-TASK worktree path and the PATHS argument in the stash-alternative recipes). Spelled as placeholder words here on purpose — see the sanitizer note below.

Measured, not assumed

  • No line ratchet over AGENTS.md. The dispatch flagged this as an assumption to test. Verified: nothing under scripts/ computes a line budget or ratchet over this file, so the new line owes no compensating deletion. What does exist and was NOT anticipated: scripts/check-governed-queue-guard.mjs (governed-surface, AGENTS.md is row agents-md) and scripts/check-shell-escape-residue.mjs (scans this file's fences). Both are content/policy gates, not size gates.
  • The gate union was derived, not guessed.scripts/check-shell-escape-residue.mjs's own header documents the derived union for a change to AGENTS.md; the governed-surface guard was added to it later by Machine-enforce human review on governed-surface paths — so the no-bypass rule stops resting on seat discipline alone #6596.
  • No changeset is owed, and that is the gate's own verdict rather than my reading: check-changeset-presence reports 0 of them published source of a package the release covers for this diff. ⛔ No label was requested — objectui has no skip-changeset mechanism.
  • The bullet was written with the Write tool, not a shell heredoc.scripts/check-shell-escape-residue.mjs exists because a git commit -F - example in this very section shipped with its heredoc terminator wrapped in a shell escape run (AGENTS.md §9 的 git commit -F - 示例带着 shell 转义残留落地(&lt;&lt;'\"'\"'EOF'\"'\"'),照抄得到一条不会终止的 heredoc #5150). Repeating that mechanism to author a line in the same section seemed like a poor idea.
  • The GitHub body sanitizer ate two placeholder fragments from the first version of this description — the angle-bracket spellings were removed even inside backticks, leaving an empty pair of backticks. Caught by reading the stored body back after creating the PR; this revision spells them as words. The file itself is unaffected: the sanitizer touches GitHub bodies, not the committed diff.

Gates run — all on head e362056

gateexitverdict line
check-control-bytes0✅ OK (scanned 5996 tracked text file(s); skipped 85 binary).
check-doc-links0Links are valid across 17 scan roots.
check-changeset-presence0✅ No source or published contract of a released package changed in this range, so no changeset is owed.
check-changeset-no-major0✅ No changeset declares a major bump.
check-shell-escape-residue0✅ OK (4/4 root(s) resolved -- AGENTS.md: 1 file(s), 15 fence(s) ... 0 occurrence(s) outside a fence)
check-governed-queue-guard --self-test0OK ... 132 cases pass
check-governed-queue-guard --test AGENTS.md3One governed path governs the WHOLE pull request

Exit codes captured by redirecting to a file first, then reading $? — never through a pipe.

⛔ This PR STAYS DRAFT

The exit 3 above is the correct verdict, not a red gate. AGENTS.md is a governed surface, and the guard states the disposition itself:

⛔ Do not flip it ready, enqueue it, or arm auto-merge. Park it as a DRAFT and leave the merge to the maintainer; a human merge IS the review record for a governed surface.

⛔ Not marking ready, not enqueueing, not arming auto-merge. The merge is the maintainer's.

Note on the one body edit above: governed-surface-guard.yml's header records that on PR #6183 an MCP update_pull_request call passing only reviewers silently set draft: false, and the PR entered the queue and landed unreviewed. The revision was therefore sent with draft: true passed explicitly, and the stored state read back afterwards to confirm it is still a draft.

Out of scope, untouched

claude/probe-6716a-writecheck is still there. Deleting it needs someone with a working delete path — which, per the line this PR adds, is not this seat. Triage already routed it to the maintainer.


🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1

Seats can push a branch but every ref-deletion push is refused by the agent
proxy with HTTP 403, and git then prints `Everything up-to-date` — a success
receipt on a refused deletion. Records the capability gap, the verbatim false
receipt, and the claim-signal consequence (an orphan sibling branch for one
card is invisible from every seat surface and reads as a competing claim;
only a per-card prefix glob shows it).
The card's four unmeasured points are kept unmeasured. No branch cleanup, no
census, no lifecycle policy — those are the maintainer's.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 11:26
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit 1e30554Sep 2, 2026
28 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-6756-branch-delete-403-fact branch September 2, 2026 11:41
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentation

Projects

None yet

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(agents): record that seats cannot delete remote branches (proxy 403, false Everything-up-to-date receipt) - #7242

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-6756-branch-delete-403-fact
Sep 2, 2026
Merged

docs(agents): record that seats cannot delete remote branches (proxy 403, false Everything-up-to-date receipt)#7242
os-zhuang merged 1 commit into
mainfrom
claude/issue-6756-branch-delete-403-fact

Conversation

@os-litant

@os-litantos-litant commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Fixes#6756

One knowledge line in AGENTS.md, per triage grading comment 5460872090. No code, no branch touched.

落点

AGENTS.md, section ### 多 agent 协作纪律(并行修改本仓库,务必遵守) under ## 9. Operational Rules — inserted as line 276, directly after the 绝不 git push --force / 绝不推 main bullet. That neighbour is the closest kin: both are "what a seat's push may and may not do against the shared remote", and the card itself cites the force-push ban (#5239) and the shared refs/stash fact (#3430) as its own family. ⛔ Deliberately not a new file — triage ruled the home is this section.

before

The section had no line at all about ref deletion. A seat that tried to delete its own probe branch had to rediscover the refusal by attempting it; the card records one dev seat spending four attempts doing exactly that.

after

One bullet (one physical line, matching the section's unwrapped-bullet format). It carries five things, all required by the ruling:

  1. The fact — a seat can push a branch but cannot delete a remote ref; the agent proxy refuses every ref-deletion push with error: RPC failed; HTTP 403. No bypass: the GitHub MCP tool surface has create_branch with no delete counterpart, and there is no gh CLI in the container.
  2. The false-success receipt, verbatim — after the 403, git prints Everything up-to-date. Triage called this the most valuable sentence on the card, above the 403 itself, and the reason is in the line: a caller that reads only the tail of the output, or treats a non-empty last line as success, reads a refused deletion as a completed one. Knowing it 403s does not protect you from that.
  3. The claim-signal consequence (from comment 5468280978) — the cost is not tidiness. An orphan sibling branch left by a rename-and-retry on one card is invisible from every surface a seat normally reads: not on the card, not in the PR list, not in any queue view. Only a per-card prefix glob shows it, and the line carries that command. The measured near-miss on card 4934 read for a moment as a second seat working the same card concurrently — the one thing the claim discipline exists to prevent.
  4. The four unmeasured points kept unmeasured, marked as such in the line itself: which layer returns the 403 (proxy policy / token scope / branch protection), whether other seats or environments can delete, whether tags are restricted the same way, and how many stale claude/* branches exist. ⛔ None was converted into an assertion.
  5. An explicit non-authorization — the line records a capability gap and authorizes no branch cleanup, no census, and no lifecycle policy. Those are the maintainer's.

In the line, the card number inside the glob is written as this repo's usual angle-bracket placeholder, matching the neighbouring bullets' own placeholder style (the objectui-TASK worktree path and the PATHS argument in the stash-alternative recipes). Spelled as placeholder words here on purpose — see the sanitizer note below.

Measured, not assumed

  • No line ratchet over AGENTS.md. The dispatch flagged this as an assumption to test. Verified: nothing under scripts/ computes a line budget or ratchet over this file, so the new line owes no compensating deletion. What does exist and was NOT anticipated: scripts/check-governed-queue-guard.mjs (governed-surface, AGENTS.md is row agents-md) and scripts/check-shell-escape-residue.mjs (scans this file's fences). Both are content/policy gates, not size gates.
  • The gate union was derived, not guessed.scripts/check-shell-escape-residue.mjs's own header documents the derived union for a change to AGENTS.md; the governed-surface guard was added to it later by Machine-enforce human review on governed-surface paths — so the no-bypass rule stops resting on seat discipline alone #6596.
  • No changeset is owed, and that is the gate's own verdict rather than my reading: check-changeset-presence reports 0 of them published source of a package the release covers for this diff. ⛔ No label was requested — objectui has no skip-changeset mechanism.
  • The bullet was written with the Write tool, not a shell heredoc.scripts/check-shell-escape-residue.mjs exists because a git commit -F - example in this very section shipped with its heredoc terminator wrapped in a shell escape run (AGENTS.md §9 的 git commit -F - 示例带着 shell 转义残留落地(&lt;&lt;'\"'\"'EOF'\"'\"'),照抄得到一条不会终止的 heredoc #5150). Repeating that mechanism to author a line in the same section seemed like a poor idea.
  • The GitHub body sanitizer ate two placeholder fragments from the first version of this description — the angle-bracket spellings were removed even inside backticks, leaving an empty pair of backticks. Caught by reading the stored body back after creating the PR; this revision spells them as words. The file itself is unaffected: the sanitizer touches GitHub bodies, not the committed diff.

Gates run — all on head e362056

gateexitverdict line
check-control-bytes0✅ OK (scanned 5996 tracked text file(s); skipped 85 binary).
check-doc-links0Links are valid across 17 scan roots.
check-changeset-presence0✅ No source or published contract of a released package changed in this range, so no changeset is owed.
check-changeset-no-major0✅ No changeset declares a major bump.
check-shell-escape-residue0✅ OK (4/4 root(s) resolved -- AGENTS.md: 1 file(s), 15 fence(s) ... 0 occurrence(s) outside a fence)
check-governed-queue-guard --self-test0OK ... 132 cases pass
check-governed-queue-guard --test AGENTS.md3One governed path governs the WHOLE pull request

Exit codes captured by redirecting to a file first, then reading $? — never through a pipe.

⛔ This PR STAYS DRAFT

The exit 3 above is the correct verdict, not a red gate. AGENTS.md is a governed surface, and the guard states the disposition itself:

⛔ Do not flip it ready, enqueue it, or arm auto-merge. Park it as a DRAFT and leave the merge to the maintainer; a human merge IS the review record for a governed surface.

⛔ Not marking ready, not enqueueing, not arming auto-merge. The merge is the maintainer's.

Note on the one body edit above: governed-surface-guard.yml's header records that on PR #6183 an MCP update_pull_request call passing only reviewers silently set draft: false, and the PR entered the queue and landed unreviewed. The revision was therefore sent with draft: true passed explicitly, and the stored state read back afterwards to confirm it is still a draft.

Out of scope, untouched

claude/probe-6716a-writecheck is still there. Deleting it needs someone with a working delete path — which, per the line this PR adds, is not this seat. Triage already routed it to the maintainer.


🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1

Seats can push a branch but every ref-deletion push is refused by the agent
proxy with HTTP 403, and git then prints `Everything up-to-date` — a success
receipt on a refused deletion. Records the capability gap, the verbatim false
receipt, and the claim-signal consequence (an orphan sibling branch for one
card is invisible from every seat surface and reads as a competing claim;
only a per-card prefix glob shows it).
The card's four unmeasured points are kept unmeasured. No branch cleanup, no
census, no lifecycle policy — those are the maintainer's.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 11:26
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit 1e30554Sep 2, 2026
28 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-6756-branch-delete-403-fact branch September 2, 2026 11:41
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentation

Projects

None yet

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

docs(agents): record that seats cannot delete remote branches (proxy 403, false Everything-up-to-date receipt) - #7242

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-6756-branch-delete-403-fact
Sep 2, 2026
Merged

docs(agents): record that seats cannot delete remote branches (proxy 403, false Everything-up-to-date receipt)#7242
os-zhuang merged 1 commit into
mainfrom
claude/issue-6756-branch-delete-403-fact

Conversation

@os-litant

@os-litantos-litant commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Fixes#6756

One knowledge line in AGENTS.md, per triage grading comment 5460872090. No code, no branch touched.

落点

AGENTS.md, section ### 多 agent 协作纪律(并行修改本仓库,务必遵守) under ## 9. Operational Rules — inserted as line 276, directly after the 绝不 git push --force / 绝不推 main bullet. That neighbour is the closest kin: both are "what a seat's push may and may not do against the shared remote", and the card itself cites the force-push ban (#5239) and the shared refs/stash fact (#3430) as its own family. ⛔ Deliberately not a new file — triage ruled the home is this section.

before

The section had no line at all about ref deletion. A seat that tried to delete its own probe branch had to rediscover the refusal by attempting it; the card records one dev seat spending four attempts doing exactly that.

after

One bullet (one physical line, matching the section's unwrapped-bullet format). It carries five things, all required by the ruling:

  1. The fact — a seat can push a branch but cannot delete a remote ref; the agent proxy refuses every ref-deletion push with error: RPC failed; HTTP 403. No bypass: the GitHub MCP tool surface has create_branch with no delete counterpart, and there is no gh CLI in the container.
  2. The false-success receipt, verbatim — after the 403, git prints Everything up-to-date. Triage called this the most valuable sentence on the card, above the 403 itself, and the reason is in the line: a caller that reads only the tail of the output, or treats a non-empty last line as success, reads a refused deletion as a completed one. Knowing it 403s does not protect you from that.
  3. The claim-signal consequence (from comment 5468280978) — the cost is not tidiness. An orphan sibling branch left by a rename-and-retry on one card is invisible from every surface a seat normally reads: not on the card, not in the PR list, not in any queue view. Only a per-card prefix glob shows it, and the line carries that command. The measured near-miss on card 4934 read for a moment as a second seat working the same card concurrently — the one thing the claim discipline exists to prevent.
  4. The four unmeasured points kept unmeasured, marked as such in the line itself: which layer returns the 403 (proxy policy / token scope / branch protection), whether other seats or environments can delete, whether tags are restricted the same way, and how many stale claude/* branches exist. ⛔ None was converted into an assertion.
  5. An explicit non-authorization — the line records a capability gap and authorizes no branch cleanup, no census, and no lifecycle policy. Those are the maintainer's.

In the line, the card number inside the glob is written as this repo's usual angle-bracket placeholder, matching the neighbouring bullets' own placeholder style (the objectui-TASK worktree path and the PATHS argument in the stash-alternative recipes). Spelled as placeholder words here on purpose — see the sanitizer note below.

Measured, not assumed

  • No line ratchet over AGENTS.md. The dispatch flagged this as an assumption to test. Verified: nothing under scripts/ computes a line budget or ratchet over this file, so the new line owes no compensating deletion. What does exist and was NOT anticipated: scripts/check-governed-queue-guard.mjs (governed-surface, AGENTS.md is row agents-md) and scripts/check-shell-escape-residue.mjs (scans this file's fences). Both are content/policy gates, not size gates.
  • The gate union was derived, not guessed.scripts/check-shell-escape-residue.mjs's own header documents the derived union for a change to AGENTS.md; the governed-surface guard was added to it later by Machine-enforce human review on governed-surface paths — so the no-bypass rule stops resting on seat discipline alone #6596.
  • No changeset is owed, and that is the gate's own verdict rather than my reading: check-changeset-presence reports 0 of them published source of a package the release covers for this diff. ⛔ No label was requested — objectui has no skip-changeset mechanism.
  • The bullet was written with the Write tool, not a shell heredoc.scripts/check-shell-escape-residue.mjs exists because a git commit -F - example in this very section shipped with its heredoc terminator wrapped in a shell escape run (AGENTS.md §9 的 git commit -F - 示例带着 shell 转义残留落地(&lt;&lt;'\"'\"'EOF'\"'\"'),照抄得到一条不会终止的 heredoc #5150). Repeating that mechanism to author a line in the same section seemed like a poor idea.
  • The GitHub body sanitizer ate two placeholder fragments from the first version of this description — the angle-bracket spellings were removed even inside backticks, leaving an empty pair of backticks. Caught by reading the stored body back after creating the PR; this revision spells them as words. The file itself is unaffected: the sanitizer touches GitHub bodies, not the committed diff.

Gates run — all on head e362056

gateexitverdict line
check-control-bytes0✅ OK (scanned 5996 tracked text file(s); skipped 85 binary).
check-doc-links0Links are valid across 17 scan roots.
check-changeset-presence0✅ No source or published contract of a released package changed in this range, so no changeset is owed.
check-changeset-no-major0✅ No changeset declares a major bump.
check-shell-escape-residue0✅ OK (4/4 root(s) resolved -- AGENTS.md: 1 file(s), 15 fence(s) ... 0 occurrence(s) outside a fence)
check-governed-queue-guard --self-test0OK ... 132 cases pass
check-governed-queue-guard --test AGENTS.md3One governed path governs the WHOLE pull request

Exit codes captured by redirecting to a file first, then reading $? — never through a pipe.

⛔ This PR STAYS DRAFT

The exit 3 above is the correct verdict, not a red gate. AGENTS.md is a governed surface, and the guard states the disposition itself:

⛔ Do not flip it ready, enqueue it, or arm auto-merge. Park it as a DRAFT and leave the merge to the maintainer; a human merge IS the review record for a governed surface.

⛔ Not marking ready, not enqueueing, not arming auto-merge. The merge is the maintainer's.

Note on the one body edit above: governed-surface-guard.yml's header records that on PR #6183 an MCP update_pull_request call passing only reviewers silently set draft: false, and the PR entered the queue and landed unreviewed. The revision was therefore sent with draft: true passed explicitly, and the stored state read back afterwards to confirm it is still a draft.

Out of scope, untouched

claude/probe-6716a-writecheck is still there. Deleting it needs someone with a working delete path — which, per the line this PR adds, is not this seat. Triage already routed it to the maintainer.


🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1

Seats can push a branch but every ref-deletion push is refused by the agent
proxy with HTTP 403, and git then prints `Everything up-to-date` — a success
receipt on a refused deletion. Records the capability gap, the verbatim false
receipt, and the claim-signal consequence (an orphan sibling branch for one
card is invisible from every seat surface and reads as a competing claim;
only a per-card prefix glob shows it).
The card's four unmeasured points are kept unmeasured. No branch cleanup, no
census, no lifecycle policy — those are the maintainer's.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 11:26
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit 1e30554Sep 2, 2026
28 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-6756-branch-delete-403-fact branch September 2, 2026 11:41
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentation

Projects

None yet

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(agents): record that seats cannot delete remote branches (proxy 403, false Everything-up-to-date receipt) - #7242

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-6756-branch-delete-403-fact
Sep 2, 2026
Merged

docs(agents): record that seats cannot delete remote branches (proxy 403, false Everything-up-to-date receipt)#7242
os-zhuang merged 1 commit into
mainfrom
claude/issue-6756-branch-delete-403-fact

Conversation

@os-litant

@os-litantos-litant commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Fixes#6756

One knowledge line in AGENTS.md, per triage grading comment 5460872090. No code, no branch touched.

落点

AGENTS.md, section ### 多 agent 协作纪律(并行修改本仓库,务必遵守) under ## 9. Operational Rules — inserted as line 276, directly after the 绝不 git push --force / 绝不推 main bullet. That neighbour is the closest kin: both are "what a seat's push may and may not do against the shared remote", and the card itself cites the force-push ban (#5239) and the shared refs/stash fact (#3430) as its own family. ⛔ Deliberately not a new file — triage ruled the home is this section.

before

The section had no line at all about ref deletion. A seat that tried to delete its own probe branch had to rediscover the refusal by attempting it; the card records one dev seat spending four attempts doing exactly that.

after

One bullet (one physical line, matching the section's unwrapped-bullet format). It carries five things, all required by the ruling:

  1. The fact — a seat can push a branch but cannot delete a remote ref; the agent proxy refuses every ref-deletion push with error: RPC failed; HTTP 403. No bypass: the GitHub MCP tool surface has create_branch with no delete counterpart, and there is no gh CLI in the container.
  2. The false-success receipt, verbatim — after the 403, git prints Everything up-to-date. Triage called this the most valuable sentence on the card, above the 403 itself, and the reason is in the line: a caller that reads only the tail of the output, or treats a non-empty last line as success, reads a refused deletion as a completed one. Knowing it 403s does not protect you from that.
  3. The claim-signal consequence (from comment 5468280978) — the cost is not tidiness. An orphan sibling branch left by a rename-and-retry on one card is invisible from every surface a seat normally reads: not on the card, not in the PR list, not in any queue view. Only a per-card prefix glob shows it, and the line carries that command. The measured near-miss on card 4934 read for a moment as a second seat working the same card concurrently — the one thing the claim discipline exists to prevent.
  4. The four unmeasured points kept unmeasured, marked as such in the line itself: which layer returns the 403 (proxy policy / token scope / branch protection), whether other seats or environments can delete, whether tags are restricted the same way, and how many stale claude/* branches exist. ⛔ None was converted into an assertion.
  5. An explicit non-authorization — the line records a capability gap and authorizes no branch cleanup, no census, and no lifecycle policy. Those are the maintainer's.

In the line, the card number inside the glob is written as this repo's usual angle-bracket placeholder, matching the neighbouring bullets' own placeholder style (the objectui-TASK worktree path and the PATHS argument in the stash-alternative recipes). Spelled as placeholder words here on purpose — see the sanitizer note below.

Measured, not assumed

  • No line ratchet over AGENTS.md. The dispatch flagged this as an assumption to test. Verified: nothing under scripts/ computes a line budget or ratchet over this file, so the new line owes no compensating deletion. What does exist and was NOT anticipated: scripts/check-governed-queue-guard.mjs (governed-surface, AGENTS.md is row agents-md) and scripts/check-shell-escape-residue.mjs (scans this file's fences). Both are content/policy gates, not size gates.
  • The gate union was derived, not guessed.scripts/check-shell-escape-residue.mjs's own header documents the derived union for a change to AGENTS.md; the governed-surface guard was added to it later by Machine-enforce human review on governed-surface paths — so the no-bypass rule stops resting on seat discipline alone #6596.
  • No changeset is owed, and that is the gate's own verdict rather than my reading: check-changeset-presence reports 0 of them published source of a package the release covers for this diff. ⛔ No label was requested — objectui has no skip-changeset mechanism.
  • The bullet was written with the Write tool, not a shell heredoc.scripts/check-shell-escape-residue.mjs exists because a git commit -F - example in this very section shipped with its heredoc terminator wrapped in a shell escape run (AGENTS.md §9 的 git commit -F - 示例带着 shell 转义残留落地(&lt;&lt;'\"'\"'EOF'\"'\"'),照抄得到一条不会终止的 heredoc #5150). Repeating that mechanism to author a line in the same section seemed like a poor idea.
  • The GitHub body sanitizer ate two placeholder fragments from the first version of this description — the angle-bracket spellings were removed even inside backticks, leaving an empty pair of backticks. Caught by reading the stored body back after creating the PR; this revision spells them as words. The file itself is unaffected: the sanitizer touches GitHub bodies, not the committed diff.

Gates run — all on head e362056

gateexitverdict line
check-control-bytes0✅ OK (scanned 5996 tracked text file(s); skipped 85 binary).
check-doc-links0Links are valid across 17 scan roots.
check-changeset-presence0✅ No source or published contract of a released package changed in this range, so no changeset is owed.
check-changeset-no-major0✅ No changeset declares a major bump.
check-shell-escape-residue0✅ OK (4/4 root(s) resolved -- AGENTS.md: 1 file(s), 15 fence(s) ... 0 occurrence(s) outside a fence)
check-governed-queue-guard --self-test0OK ... 132 cases pass
check-governed-queue-guard --test AGENTS.md3One governed path governs the WHOLE pull request

Exit codes captured by redirecting to a file first, then reading $? — never through a pipe.

⛔ This PR STAYS DRAFT

The exit 3 above is the correct verdict, not a red gate. AGENTS.md is a governed surface, and the guard states the disposition itself:

⛔ Do not flip it ready, enqueue it, or arm auto-merge. Park it as a DRAFT and leave the merge to the maintainer; a human merge IS the review record for a governed surface.

⛔ Not marking ready, not enqueueing, not arming auto-merge. The merge is the maintainer's.

Note on the one body edit above: governed-surface-guard.yml's header records that on PR #6183 an MCP update_pull_request call passing only reviewers silently set draft: false, and the PR entered the queue and landed unreviewed. The revision was therefore sent with draft: true passed explicitly, and the stored state read back afterwards to confirm it is still a draft.

Out of scope, untouched

claude/probe-6716a-writecheck is still there. Deleting it needs someone with a working delete path — which, per the line this PR adds, is not this seat. Triage already routed it to the maintainer.


🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1

Seats can push a branch but every ref-deletion push is refused by the agent
proxy with HTTP 403, and git then prints `Everything up-to-date` — a success
receipt on a refused deletion. Records the capability gap, the verbatim false
receipt, and the claim-signal consequence (an orphan sibling branch for one
card is invisible from every seat surface and reads as a competing claim;
only a per-card prefix glob shows it).
The card's four unmeasured points are kept unmeasured. No branch cleanup, no
census, no lifecycle policy — those are the maintainer's.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 11:26
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit 1e30554Sep 2, 2026
28 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-6756-branch-delete-403-fact branch September 2, 2026 11:41
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentation

Projects

None yet

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(agents): record that seats cannot delete remote branches (proxy 403, false Everything-up-to-date receipt) - #7242

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-6756-branch-delete-403-fact
Sep 2, 2026
Merged

docs(agents): record that seats cannot delete remote branches (proxy 403, false Everything-up-to-date receipt)#7242
os-zhuang merged 1 commit into
mainfrom
claude/issue-6756-branch-delete-403-fact

Conversation

@os-litant

@os-litantos-litant commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Fixes#6756

One knowledge line in AGENTS.md, per triage grading comment 5460872090. No code, no branch touched.

落点

AGENTS.md, section ### 多 agent 协作纪律(并行修改本仓库,务必遵守) under ## 9. Operational Rules — inserted as line 276, directly after the 绝不 git push --force / 绝不推 main bullet. That neighbour is the closest kin: both are "what a seat's push may and may not do against the shared remote", and the card itself cites the force-push ban (#5239) and the shared refs/stash fact (#3430) as its own family. ⛔ Deliberately not a new file — triage ruled the home is this section.

before

The section had no line at all about ref deletion. A seat that tried to delete its own probe branch had to rediscover the refusal by attempting it; the card records one dev seat spending four attempts doing exactly that.

after

One bullet (one physical line, matching the section's unwrapped-bullet format). It carries five things, all required by the ruling:

  1. The fact — a seat can push a branch but cannot delete a remote ref; the agent proxy refuses every ref-deletion push with error: RPC failed; HTTP 403. No bypass: the GitHub MCP tool surface has create_branch with no delete counterpart, and there is no gh CLI in the container.
  2. The false-success receipt, verbatim — after the 403, git prints Everything up-to-date. Triage called this the most valuable sentence on the card, above the 403 itself, and the reason is in the line: a caller that reads only the tail of the output, or treats a non-empty last line as success, reads a refused deletion as a completed one. Knowing it 403s does not protect you from that.
  3. The claim-signal consequence (from comment 5468280978) — the cost is not tidiness. An orphan sibling branch left by a rename-and-retry on one card is invisible from every surface a seat normally reads: not on the card, not in the PR list, not in any queue view. Only a per-card prefix glob shows it, and the line carries that command. The measured near-miss on card 4934 read for a moment as a second seat working the same card concurrently — the one thing the claim discipline exists to prevent.
  4. The four unmeasured points kept unmeasured, marked as such in the line itself: which layer returns the 403 (proxy policy / token scope / branch protection), whether other seats or environments can delete, whether tags are restricted the same way, and how many stale claude/* branches exist. ⛔ None was converted into an assertion.
  5. An explicit non-authorization — the line records a capability gap and authorizes no branch cleanup, no census, and no lifecycle policy. Those are the maintainer's.

In the line, the card number inside the glob is written as this repo's usual angle-bracket placeholder, matching the neighbouring bullets' own placeholder style (the objectui-TASK worktree path and the PATHS argument in the stash-alternative recipes). Spelled as placeholder words here on purpose — see the sanitizer note below.

Measured, not assumed

  • No line ratchet over AGENTS.md. The dispatch flagged this as an assumption to test. Verified: nothing under scripts/ computes a line budget or ratchet over this file, so the new line owes no compensating deletion. What does exist and was NOT anticipated: scripts/check-governed-queue-guard.mjs (governed-surface, AGENTS.md is row agents-md) and scripts/check-shell-escape-residue.mjs (scans this file's fences). Both are content/policy gates, not size gates.
  • The gate union was derived, not guessed.scripts/check-shell-escape-residue.mjs's own header documents the derived union for a change to AGENTS.md; the governed-surface guard was added to it later by Machine-enforce human review on governed-surface paths — so the no-bypass rule stops resting on seat discipline alone #6596.
  • No changeset is owed, and that is the gate's own verdict rather than my reading: check-changeset-presence reports 0 of them published source of a package the release covers for this diff. ⛔ No label was requested — objectui has no skip-changeset mechanism.
  • The bullet was written with the Write tool, not a shell heredoc.scripts/check-shell-escape-residue.mjs exists because a git commit -F - example in this very section shipped with its heredoc terminator wrapped in a shell escape run (AGENTS.md §9 的 git commit -F - 示例带着 shell 转义残留落地(&lt;&lt;'\"'\"'EOF'\"'\"'),照抄得到一条不会终止的 heredoc #5150). Repeating that mechanism to author a line in the same section seemed like a poor idea.
  • The GitHub body sanitizer ate two placeholder fragments from the first version of this description — the angle-bracket spellings were removed even inside backticks, leaving an empty pair of backticks. Caught by reading the stored body back after creating the PR; this revision spells them as words. The file itself is unaffected: the sanitizer touches GitHub bodies, not the committed diff.

Gates run — all on head e362056

gateexitverdict line
check-control-bytes0✅ OK (scanned 5996 tracked text file(s); skipped 85 binary).
check-doc-links0Links are valid across 17 scan roots.
check-changeset-presence0✅ No source or published contract of a released package changed in this range, so no changeset is owed.
check-changeset-no-major0✅ No changeset declares a major bump.
check-shell-escape-residue0✅ OK (4/4 root(s) resolved -- AGENTS.md: 1 file(s), 15 fence(s) ... 0 occurrence(s) outside a fence)
check-governed-queue-guard --self-test0OK ... 132 cases pass
check-governed-queue-guard --test AGENTS.md3One governed path governs the WHOLE pull request

Exit codes captured by redirecting to a file first, then reading $? — never through a pipe.

⛔ This PR STAYS DRAFT

The exit 3 above is the correct verdict, not a red gate. AGENTS.md is a governed surface, and the guard states the disposition itself:

⛔ Do not flip it ready, enqueue it, or arm auto-merge. Park it as a DRAFT and leave the merge to the maintainer; a human merge IS the review record for a governed surface.

⛔ Not marking ready, not enqueueing, not arming auto-merge. The merge is the maintainer's.

Note on the one body edit above: governed-surface-guard.yml's header records that on PR #6183 an MCP update_pull_request call passing only reviewers silently set draft: false, and the PR entered the queue and landed unreviewed. The revision was therefore sent with draft: true passed explicitly, and the stored state read back afterwards to confirm it is still a draft.

Out of scope, untouched

claude/probe-6716a-writecheck is still there. Deleting it needs someone with a working delete path — which, per the line this PR adds, is not this seat. Triage already routed it to the maintainer.


🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1

Seats can push a branch but every ref-deletion push is refused by the agent
proxy with HTTP 403, and git then prints `Everything up-to-date` — a success
receipt on a refused deletion. Records the capability gap, the verbatim false
receipt, and the claim-signal consequence (an orphan sibling branch for one
card is invisible from every seat surface and reads as a competing claim;
only a per-card prefix glob shows it).
The card's four unmeasured points are kept unmeasured. No branch cleanup, no
census, no lifecycle policy — those are the maintainer's.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 11:26
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit 1e30554Sep 2, 2026
28 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-6756-branch-delete-403-fact branch September 2, 2026 11:41
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentation

Projects

None yet

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

docs(agents): record that seats cannot delete remote branches (proxy 403, false Everything-up-to-date receipt) - #7242

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-6756-branch-delete-403-fact
Sep 2, 2026
Merged

docs(agents): record that seats cannot delete remote branches (proxy 403, false Everything-up-to-date receipt)#7242
os-zhuang merged 1 commit into
mainfrom
claude/issue-6756-branch-delete-403-fact

Conversation

@os-litant

@os-litantos-litant commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Fixes#6756

One knowledge line in AGENTS.md, per triage grading comment 5460872090. No code, no branch touched.

落点

AGENTS.md, section ### 多 agent 协作纪律(并行修改本仓库,务必遵守) under ## 9. Operational Rules — inserted as line 276, directly after the 绝不 git push --force / 绝不推 main bullet. That neighbour is the closest kin: both are "what a seat's push may and may not do against the shared remote", and the card itself cites the force-push ban (#5239) and the shared refs/stash fact (#3430) as its own family. ⛔ Deliberately not a new file — triage ruled the home is this section.

before

The section had no line at all about ref deletion. A seat that tried to delete its own probe branch had to rediscover the refusal by attempting it; the card records one dev seat spending four attempts doing exactly that.

after

One bullet (one physical line, matching the section's unwrapped-bullet format). It carries five things, all required by the ruling:

  1. The fact — a seat can push a branch but cannot delete a remote ref; the agent proxy refuses every ref-deletion push with error: RPC failed; HTTP 403. No bypass: the GitHub MCP tool surface has create_branch with no delete counterpart, and there is no gh CLI in the container.
  2. The false-success receipt, verbatim — after the 403, git prints Everything up-to-date. Triage called this the most valuable sentence on the card, above the 403 itself, and the reason is in the line: a caller that reads only the tail of the output, or treats a non-empty last line as success, reads a refused deletion as a completed one. Knowing it 403s does not protect you from that.
  3. The claim-signal consequence (from comment 5468280978) — the cost is not tidiness. An orphan sibling branch left by a rename-and-retry on one card is invisible from every surface a seat normally reads: not on the card, not in the PR list, not in any queue view. Only a per-card prefix glob shows it, and the line carries that command. The measured near-miss on card 4934 read for a moment as a second seat working the same card concurrently — the one thing the claim discipline exists to prevent.
  4. The four unmeasured points kept unmeasured, marked as such in the line itself: which layer returns the 403 (proxy policy / token scope / branch protection), whether other seats or environments can delete, whether tags are restricted the same way, and how many stale claude/* branches exist. ⛔ None was converted into an assertion.
  5. An explicit non-authorization — the line records a capability gap and authorizes no branch cleanup, no census, and no lifecycle policy. Those are the maintainer's.

In the line, the card number inside the glob is written as this repo's usual angle-bracket placeholder, matching the neighbouring bullets' own placeholder style (the objectui-TASK worktree path and the PATHS argument in the stash-alternative recipes). Spelled as placeholder words here on purpose — see the sanitizer note below.

Measured, not assumed

  • No line ratchet over AGENTS.md. The dispatch flagged this as an assumption to test. Verified: nothing under scripts/ computes a line budget or ratchet over this file, so the new line owes no compensating deletion. What does exist and was NOT anticipated: scripts/check-governed-queue-guard.mjs (governed-surface, AGENTS.md is row agents-md) and scripts/check-shell-escape-residue.mjs (scans this file's fences). Both are content/policy gates, not size gates.
  • The gate union was derived, not guessed.scripts/check-shell-escape-residue.mjs's own header documents the derived union for a change to AGENTS.md; the governed-surface guard was added to it later by Machine-enforce human review on governed-surface paths — so the no-bypass rule stops resting on seat discipline alone #6596.
  • No changeset is owed, and that is the gate's own verdict rather than my reading: check-changeset-presence reports 0 of them published source of a package the release covers for this diff. ⛔ No label was requested — objectui has no skip-changeset mechanism.
  • The bullet was written with the Write tool, not a shell heredoc.scripts/check-shell-escape-residue.mjs exists because a git commit -F - example in this very section shipped with its heredoc terminator wrapped in a shell escape run (AGENTS.md §9 的 git commit -F - 示例带着 shell 转义残留落地(&lt;&lt;'\"'\"'EOF'\"'\"'),照抄得到一条不会终止的 heredoc #5150). Repeating that mechanism to author a line in the same section seemed like a poor idea.
  • The GitHub body sanitizer ate two placeholder fragments from the first version of this description — the angle-bracket spellings were removed even inside backticks, leaving an empty pair of backticks. Caught by reading the stored body back after creating the PR; this revision spells them as words. The file itself is unaffected: the sanitizer touches GitHub bodies, not the committed diff.

Gates run — all on head e362056

gateexitverdict line
check-control-bytes0✅ OK (scanned 5996 tracked text file(s); skipped 85 binary).
check-doc-links0Links are valid across 17 scan roots.
check-changeset-presence0✅ No source or published contract of a released package changed in this range, so no changeset is owed.
check-changeset-no-major0✅ No changeset declares a major bump.
check-shell-escape-residue0✅ OK (4/4 root(s) resolved -- AGENTS.md: 1 file(s), 15 fence(s) ... 0 occurrence(s) outside a fence)
check-governed-queue-guard --self-test0OK ... 132 cases pass
check-governed-queue-guard --test AGENTS.md3One governed path governs the WHOLE pull request

Exit codes captured by redirecting to a file first, then reading $? — never through a pipe.

⛔ This PR STAYS DRAFT

The exit 3 above is the correct verdict, not a red gate. AGENTS.md is a governed surface, and the guard states the disposition itself:

⛔ Do not flip it ready, enqueue it, or arm auto-merge. Park it as a DRAFT and leave the merge to the maintainer; a human merge IS the review record for a governed surface.

⛔ Not marking ready, not enqueueing, not arming auto-merge. The merge is the maintainer's.

Note on the one body edit above: governed-surface-guard.yml's header records that on PR #6183 an MCP update_pull_request call passing only reviewers silently set draft: false, and the PR entered the queue and landed unreviewed. The revision was therefore sent with draft: true passed explicitly, and the stored state read back afterwards to confirm it is still a draft.

Out of scope, untouched

claude/probe-6716a-writecheck is still there. Deleting it needs someone with a working delete path — which, per the line this PR adds, is not this seat. Triage already routed it to the maintainer.


🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1

Seats can push a branch but every ref-deletion push is refused by the agent
proxy with HTTP 403, and git then prints `Everything up-to-date` — a success
receipt on a refused deletion. Records the capability gap, the verbatim false
receipt, and the claim-signal consequence (an orphan sibling branch for one
card is invisible from every seat surface and reads as a competing claim;
only a per-card prefix glob shows it).
The card's four unmeasured points are kept unmeasured. No branch cleanup, no
census, no lifecycle policy — those are the maintainer's.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 11:26
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit 1e30554Sep 2, 2026
28 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-6756-branch-delete-403-fact branch September 2, 2026 11:41
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentation

Projects

None yet

3 participants

@os-litant@os-zhuang@claude