Skip to content

refs(pm-dispatch): qualify the REST prescriptions as per-session, and bank four platform readings - #12091

Merged
hotlong merged 2 commits into
mainfrom
claude/issue-11835-platform-readings-pack
Aug 25, 2026
Merged

refs(pm-dispatch): qualify the REST prescriptions as per-session, and bank four platform readings#12091
hotlong merged 2 commits into
mainfrom
claude/issue-11835-platform-readings-pack

Conversation

@claude

@claudeclaudeBot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Closes#11835, closes#11573, closes#11577, closes#11114

Part of #11604

One file: .claude/skills/pm-dispatch/references/platform-readings.md (plus one ceiling
number in the ratchet). #11604 stays open — only its REST-403-per-session item lands here.

The unifying edit (#11835)

The table prescribed REST in three places as if it were always available, while recording
one bullet earlier that the direct-REST gate is a session-start authorization
snapshot
. Both measurements stand; what was missing is the modality. A seat reading in
order learned the fallback existed, reached for it mid-outage, and got a 403 with no next
step named — exactly when it had the least room to improvise.

The three prescriptions no longer each re-derive a channel choice. One new bullet carries
the probe and the ladder; the others point at it.

Per-item checklist

#落点beforeafter
#11835 (a)new bullet, §API 配额, ahead of 默认读序403-gate recorded once as a boundary note buried in the MCP list/search bulletnamed bullet: REST availability is a session property; probe once at shift start (the round-opening /rate_limit curl doubles as it), bank per shift, ⛔ never infer from another seat's reading (2026-08-24, three seats in one window: two 403, one 200)
#11835 (a)默认读序 · MCP list/search · search_issues 归零 · MCP 参数两陷阱each prescribed "改走 REST" unconditionallyeach now qualified — 默认读序 states the probe as its precondition; the other three route through the ladder
#11835 (b)same new bulletno ladder; the endgame ("pure-MCP session + exhausted pool = nothing left") sat unconnectedordered ladder ① git-first ② single-label MCP list + local intersect (with the OR-trap note) ③ wait for reset
#11835 (c)search_issues 归零 bullet"诊断:结果可疑时先跑一个…控制词"an empty dedupe is not a reading until a known-hit control answered in-session — unconditional, with the 2026-08-24 occurrence (control returned 0 for a card dispatched minutes earlier)
#11577 §1new bullet, §队列成员资格table said undraft is GraphQL-onlyundraft has exactly one working path: MCP update_pull_request draft:false (three PRs, read back each time); raw GraphQL refused in-session and its own "use REST" advice is wrong here; raw REST PATCH answers 200 and does nothing
#11577 §2enable_pr_auto_merge bullet"显式传 SQUASH 回显 MERGE" recorded as an unreliable echothe parameter itself is inert — REST read-back of auto_merge.merge_method is merge too; harmless because the queue performs the merge and its method governs, this repo being squash-only ⇒ ⛔ don't burn calls toggling it
#11577 §3默认读序 bullet"the lane inventory has a REST fallback"qualified per #11835, and carries #11573's independent numbers (GraphQL 0 / core 4999 with the whole dispatch loop finishing on REST)
#11573 fact 2after the downgrade-fuse bullet, §读数陷阱fuse reading stated as if get_session existed everywherethe reading forks by host: where the ccd host's session-mgmt MCP excludes the current session by contract the fuse has no input (2026-08-24), while another ccd/web host answered normally (2026-08-25) ⇒ ⛔ don't generalize from one host. Substitute: the transcript-JSONL "model": field, host-authored, own-session only
#11573 fact 1默认读序 bulletsame row as #11577 §3 above (one fact, one home)
#11114new one-line bullet, §读数陷阱absentclassifier verdicts are shape-sensitive, not capability boundaries (chained/piped push refused, bare push permitted the same minute; a label POST flipped across days) ⇒ retry the core action bare before reporting blocked; permissions.allow is the only deterministic channel
#11604 item 2rides the #11835 qualification (same fact, third independent seat). Its OR-trap re-confirmation is folded into MCP 参数两陷阱 as the mechanical criterion: 判据 = 结果比任一输入都宽 (135 returned against a 132-card lane)

Ceiling: paid by compression, and LOWERED

platform-readings.md was at 315 / 315, headroom 0. It lands at 314, and the
ceiling in scripts/pm/check-skill-line-ratchet.mjs is lowered 315 → 314 to bank it.
Nothing was raised.

Two commits, deliberately separate, because they want different kinds of review:

1. bd7e064 — canonical re-wrap, whitespace only (315 → 299). Changes no words. It
joins each paragraph back to one logical line and re-wraps it with the ratchet gate's own
exported wrapLine, which by construction only moves whitespace. Multi-line 「…」 ruling
quotations are left byte-for-byte alone, so no quoted maintainer ruling stops being
greppable on one line. Proven before the write, both directions, and re-checked after:

  • every paragraph collapsed back to one logical line is byte-identical before/after;
  • the whitespace-stripped whole file is byte-identical before/after — this is the one
    that catches a space wrongly inserted or dropped at a join.

2. 01bcccae — the content diff. Review this one. Against the base, 17 paragraphs
changed and 4 bullets are new
; everything else in the file is untouched content. To see
only that, compare the two joined forms rather than the wrapped diff.

Where the ~26 lines of content were paid from — all inside the channel/quota family this
edit unifies, every measured fact and every date retained, restatement removed:

  • the API-quota section stated the channel prescription four times over (默认读序, MCP
    list/search, gh CLI, 红窗调度, and again inside git 先行). Consolidated to one gate
    bullet plus pointers — that redundancy is the purse.
  • search_issues 归零 lost its duplicated REST recipe and its "don't hand-scan" clause was
    merged into ladder rung ②, where it had read as opposed advice.
  • narrative whose rule survives without it was trimmed in 读数五坑, 判截断, 配额枯竭 and
    两个瘦身参数 (the ratchet's own doctrine: provenance is one line, stories live on cards).

Gates

Union run after the final commit, at 01bcccae4. Exit codes captured before any pipe;
verdict lines are the gates' own:

  • check:pm-skill-ratchet✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/platform-readings.md is 314 lines (ceiling 314; headroom 0).
  • check:doc-authoring✓ doc authoring guard: 389 files clean — no bare metadata literals.
  • check:nul-bytescheck-nul-bytes: OK (scanned 6704 text file(s) -- 6704 tracked, 0 untracked-not-ignored; skipped 6 binary; no raw ASCII control bytes).
  • check:skill-frame-sync✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files
  • check:pm-skill-id-lint✓ check-skill-id-lint: 22 file(s) clean (pattern /#[0-9]{3,}/g).

scripts/pm/dispatch-gates.mjs (run with no paths, so it derives its own change set) added
families the dispatch word did not name, because this branch also edits scripts/**. All
green at the same head: check:agent-test-spelling, check:cross-package-test-inputs,
check:entry-guard, check:parse-guard, check:pm-governed-merges,
check:pnpm-filter-targets, check:doc-formula-expressions,
scripts/check-ci-filter-parity.mjs, scripts/check-cross-package-test-inputs.mjs.

Two of those first reported PREREQUISITE NOT MET rather than a finding (a fresh worktree
has no node_modules; @objectstack/formula and @objectstack/lint were not built).
Both were green once installed and built — recorded because the un-run state exits 1 and
would read as a failure.

Also self-scanned beyond the gate for raw control bytes in both changed files: no match.

No changeset — nothing here is published; .claude/** and scripts/** ship to nobody.

Governed surface (.claude/skills/**) ⇒ draft, human merge. #11604 is not addressed here
beyond its item 2 and remains open.


Generated by Claude Code

…-> 299)
Pays for the platform-readings consolidation without raising the ratchet
ceiling. This commit changes NO words: it joins each paragraph back to one
logical line and re-wraps it with the ratchet gate's own exported `wrapLine`,
which by construction only ever moves whitespace (a space becomes a newline,
or a newline is inserted between two wide characters).
Multi-line 「…」 ruling quotations are left byte-for-byte alone -- their line
structure is the author's and the gate exempts it, so the re-wrap never makes
a quoted maintainer ruling un-greppable.
Proof, both directions, run before the write:
- every paragraph collapsed back to one logical line is byte-identical
before and after;
- the whitespace-stripped whole file is byte-identical before and after
(this is what catches a space wrongly inserted or dropped at a join).
Gates on this commit: check:pm-skill-ratchet, check:doc-authoring,
check:nul-bytes, check:skill-frame-sync, check:pm-skill-id-lint all green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RMTpSRF5CjMmQBFfPtPCwJ
…atform readings
platform-readings.md prescribed REST in three places as if it were always
available, while recording one bullet earlier that the direct-REST gate is a
per-session authorization snapshot. A seat that read in order learned the
fallback existed, reached for it mid-outage, and got a 403 with no next step
named. Both measurements stand -- the correction is the modality.
Landed on this branch:
- REST availability is a SESSION property: probe once at shift start (the
round-opening /rate_limit curl doubles as it), bank it for the shift, and
read the degradation ladder when the gate is shut -- git-first, then a
SINGLE-label MCP list plus a local intersect (the labels array is OR, so a
multi-label request only ever comes back wider than either input), then
wait for reset. The three prescriptions now point at it instead of each
re-deriving a channel choice.
- An empty dedupe is NOT a reading until a known-hit control answered in the
same session -- unconditional, not "verify when the result looks odd".
- undraft goes through the MCP update_pull_request draft:false and nowhere
else: raw GraphQL is refused in-session (and the refusal's own advice to
use REST is wrong here), raw REST PATCH answers 200 and does nothing.
- enable_pr_auto_merge's mergeMethod is inert -- SQUASH reads back as
`merge`; harmless because the queue performs the merge and its own method
governs, this repo being squash-only.
- The downgrade fuse's get_session reading forks by host: where the ccd host
excludes the current session by contract, the transcript-JSONL "model":
field is the valid substitute, own-session only.
- The auto-mode classifier's verdicts are shape-sensitive, not capability
boundaries: retry the core action BARE before reporting blocked.
Paid entirely by compression, no ceiling raised. The API-quota section stated
the channel prescription four times over; consolidating it into one gate
bullet plus pointers is the purse. The ceiling is LOWERED 315 -> 314.
Gates (verdict lines quoted in the PR body): check:pm-skill-ratchet,
check:doc-authoring, check:nul-bytes, check:skill-frame-sync,
check:pm-skill-id-lint, plus the families the changeset re-derivation added
for scripts/**.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RMTpSRF5CjMmQBFfPtPCwJ
@github-actionsgithub-actionsBot added size/m documentation Improvements or additions to documentation labels Aug 25, 2026
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 25, 2026
@hotlong
hotlong marked this pull request as ready for review August 25, 2026 09:16
@hotlong
hotlong added this pull request to the merge queueAug 25, 2026
Merged via the queue into main with commit 2ba4329Aug 25, 2026
32 checks passed
@hotlong
hotlong deleted the claude/issue-11835-platform-readings-pack branch August 25, 2026 09:34
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment