fix(pm): GitHub REST channel reachability is a session property — not an endpoint or seat-type fact - #13367
Conversation
…n the os-dev labels bullet The labels bullet's parenthetical asserted a seat-type fact (container dev seats get 403 on repo-scoped REST as a class), contradicted by four independent gate-open dev-container readings of HTTP 200 on the additive label POST. Rewritten to the per-session form: the session gate answers before the endpoint is consulted, reads and writes fail together behind a closed gate, and gate-open sessions measure 200 — probe first, never assume either direction. Also adds the adjudicated read-back limitation: the compare read-back only detects a concurrent strip, it cannot prevent one, and a stripped gate-semantic label reads as green. Line-neutral under the ratchet (466/466, all lines within 120 bytes). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EXxTW8mvPBhoHxmyPZ63de
…rying the gate-open readings The fact line said 'session property' but still carried endpoint-shaped residue: a single gate-open counterexample and a per-container framing. Rewritten to the adjudicated shape — reachability is a property of the session (the GitHub App session gate, snapshotted at session start), not of any endpoint or seat type: the gate answers before the endpoint is consulted, so a closed-gate 403 has zero discriminating power about any specific endpoint; reads and writes fail together behind it; and four independent gate-open dev containers measured the additive label POST at 200 (each confirmed by an independent GET read-back), with the channel wider than labels — issue POST 201, comment writes, card/comment reads. Probe method kept as the only safe reading; no channel is stated as an unconditional guarantee. Line-neutral under the ratchet (314/314, all lines within 120 bytes). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EXxTW8mvPBhoHxmyPZ63de
|
Dequeue root cause (skills lane seat): the queue ejection at 07:54Z was the Governed Surface Queue Guard working as ruled, not a test failure — merge-group run 33299410038 is the red check ( What unblocks it (one click, either authorized account): an Approve review on this PR — it pins to the current head This seat cannot supply the approval (agent seats never approve governed PRs) and will not re-queue until the predicate is satisfiable. Generated by Claude Code |
Fixes #12654
Fixes #12766
Family fold — one PR for both cards, per the 2026-08-28 triage rulings on each (「两张卡一个 PR」), with one commit per member.
What changed
.claude/agents/os-dev.md(member card 12654, commit d7b408c) — the labels bullet's parenthetical stated a seat-type fact: container dev seats get 403 on repo-scoped REST as a class (a 2026-08-25 reading). That is contradicted by four independent gate-open dev-container readings of HTTP 200 on the additive label POST. Rewritten, line-neutral, to the per-session form: reachability is a property of the session, not of the endpoint or the seat type — the session gate answers before the endpoint is consulted, reads and writes fail together behind a closed gate, gate-open sessions measure 200 — probe first; the readings live in platform-readings. Also added the adjudicated limitation beside the four-step fallback: the compare read-back only DETECTS a concurrent label strip, it cannot PREVENT one, and a stripped gate-semantic label reads as green..claude/skills/pm-dispatch/references/platform-readings.md(member card 12766, commit 8d9a85f) — the fact line said "session property" but still carried endpoint-shaped residue (a single gate-open counterexample; per-container framing). Rewritten to the adjudicated shape with the three measured facts: (1) the 403 body "GitHub access is not enabled for this session" is a session gate answering before the endpoint is consulted, so a closed-gate 403 has zero discriminating power about any specific endpoint; (2) behind a closed gate, reads AND writes both 403 (matched-pair control); (3) four independent gate-open dev containers measured the additive label POST at 200, each confirmed by an independent GET read-back, and the channel is wider than labels — issue POST 201, comment writes, card/comment reads. The probe stays the only safe reading; no channel is written as an unconditional guarantee.This dev's own session adds a fresh corroborating reading: a 14-character env token with a gate-open session — repo-scoped GET 200, additive label POST 200 with read-back (below) — so token length does not decide the channel; the session gate does.
Kept intact (adjudicated)
Line budget (both files sit at their ratchet ceilings with zero headroom)
Gates — post-final-commit union at head 8d9a85f, via scripts/pm/os-verify-lock.sh, VERDICT command-exit 0
check:agent-model-declared · check:agent-test-spelling · check:doc-authoring · lint check:doc-formula-expressions (after building the @objectstack/lint closure — its first run was "PREREQUISITE NOT MET", a non-measurement, not a red) · check:nul-bytes · check:pm-governed-merges · check:pm-skill-id-lint · check:pm-skill-ratchet (its own verdict lines: "os-dev.md is 466 lines (ceiling 466; headroom 0)" and "platform-readings.md is 314 lines (ceiling 314; headroom 0)") · check:skill-frame-sync — all exit 0, joined with the shell AND operator so the lock's verdict covers every one. check-governed-queue-guard: its 113-case self-test passes locally; the guard itself reads a CI event payload and judges at queue time by design.
Gate list re-derived from the actual diff with scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack: matches the dispatch's 10 families exactly. Changeset families intentionally not triggered — the diff is entirely under .claude/**, so skip-changeset applies (label on this PR, with compare read-back).
Governed surface
Both files are under .claude/** — this PR stays DRAFT for the maintainer's hand merge; no seat flips it ready, queues it, or arms auto-merge. Please update the base to current main and re-run gates before merging.
Reported to the PM, outside this PR's file surface
The standing-text sweep (item two of the head card's "Not established" list) found one residue: references/rest-channel.md frames its checkmark annotations per seat category in its header, while its own definition line already reads each checkmark as "measured in a gate-open session" — consistent with the session-property shape, so nothing here contradicts it; flagged for a follow-up wording alignment if the PM wants one.
Generated by Claude Code
Generated by Claude Code