Skip to content

docs(pm): rest-channel names the fleet-write relay as the channel to the App identity - #19770

Merged
os-support-ai merged 1 commit into
mainfrom
claude/issue-19739-fleet-write-channel-text
Sep 23, 2026
Merged

os-support-ai merged 1 commit into
mainfrom
claude/issue-19739-fleet-write-channel-text

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Part of #19739

Clause-②: no

What changed

One file, .claude/skills/pm-dispatch/references/rest-channel.md, section 〈通道边界〉: one paragraph of nine rule lines stating how the App identity is reached.

  • objectstack-fleet[bot] is reached through the fleet-write relay; the four write tools (post-stamped, label-write, issue-create, close-cards) and with-fleet.sh --via auto share one selector.
  • dispatch only when three conditions hold — CCR_AGENT_PROXY_ENABLED=1, a session id, a live relay — otherwise direct, with one printed line.
  • The session id is derived from the container's CLAUDE_CODE_REMOTE_SESSION_ID; OS_FLEET_SESSION overrides it for local checkouts and tests only.
  • ⛔ Never prefix a command with it: the allow rules are literal prefixes, a prefixed write drops onto the classifier and the seat stalls.
  • Live = the workflow file on main AND its Actions state active; the maintainer disabling it in the Actions UI turns the whole fleet back to direct.
  • The dispatch goes to objectstack with the session token; the run executes on the runner with a per-run App token narrowed to the target repo.
  • The closed op list lives in scripts/pm/fleet-write/ops.mjs; reads stay direct.
  • A post-stamped body over 60,000 bytes takes direct for that one write, with one printed line, as the seat's own user.
  • A failed run (post-stamped/close-cards 4, label-write/issue-create 5) and UNCONFIRMED (6) are read, ⛔ never retried.

Spellings are taken from the #19755 branch claude/issue-19755-fleet-write-derive-session at 6470e4e (PR #19760): sessionSource in scripts/pm/fleet-write/dispatch.mjs, CONTAINER_SESSION_ENV in ops.mjs, relayLive's Actions-state read, the with-fleet.sh --via auto paragraph, and sizeRoute / MAX_BODY_BYTES in post-stamped.mjs. Everything else is read from main at 544767d (.github/workflows/fleet-write.yml: repositories: = the validated target, permission-issues: write, permission-pull-requests: write, permission-metadata: read).

One correction to the card's item 3 wording. The failed-run exit is not 4 fleet-wide. Each tool books it in its own register on that branch: post-stamped 4 (EXIT_NOT_STORED, via relayExitFor), close-cards 4 (EXIT_HALF_WRITE, and the same 4 for an unconfirmed close), label-write and issue-create 5 (exitForResult → EXIT_PLATFORM_REFUSAL). UNCONFIRMED is 6 in every tool that takes the relay. The paragraph states the registers as they are on that branch; the rule — read, never retry — is the same in all four.

Line budget — ceiling 82, headroom 0, paid in place (+9 / −9)

Nine lines are retired. Each is a restatement; the line that keeps the rule is named beside it (line numbers on main at 544767d).

retired (rest-channel.md line) the rule survives at
9 — closed session gate: repo-scoped 403, no gh, MCP and git fine platform-readings.md 108 (the 403 shape), 114–115 (git first, MCP third), 142 (no gh in the container)
10 — run one repo-scoped probe before choosing a channel platform-readings.md 107, 127
13 — a rate-limit refusal binds to the refused identity; switching channels is a retry platform-readings.md 122, 125
14 — the other side is a way out only under a different identity (GET /user vs the refused id) platform-readings.md 125 (the GET /user test), 96 (one identity inside a seat)
38 — label/assignee writes go through label-write.mjs (four steps, read-back) SKILL.md 394; os-dev.md 304; the tool's own header
44 — every write carries Content-Type: application/json; the 415 and its discriminant platform-readings.md 119–120
54 — never MCP update_pull_request; ready/draft and auto-merge take the ccr routes .claude/settings.json deny list; SKILL.md 610; the ccr rows at 48 and 52 of this file
60 — a REST-gated seat falls back to one targeted MCP search_issues platform-readings.md 115, 211
72 — whether auto-merge goes through the queue is answered by trying the action, not a field platform-readings.md 9; rows 73–75 of this file keep the three criteria

No line was re-wrapped; every line is ≤ 120 bytes (check:pm-skill-ratchet green on the head).

Landing order

⛔ This PR lands only after #19755 (PR #19760) merges: the paragraph states what that PR makes true (the container-derived session, the Actions-state half of the liveness read, the size route). Not enqueued by this dispatch. Tier S (.claude/**), CONTRACT_REVIEW_TIER — the director seat renders the ## Contract review of record. skip-changeset: nothing published from any released package; this dispatch forbids label writes, so the label is the seat's to apply.

Verification

Gates derived by node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands on the edited tree at 9f49c33; each run alone, exit captured before any pipe (cmd > log 2>&1; ec=$?).

command exit verdict line
node scripts/check-closing-keyword-parity.mjs 0 • packages/spec/CHANGELOG.md -- 6080503 bytes exceeds the sweep's 2097152-byte cutoff for UNREGISTERED files
node scripts/check-closing-keyword-parity.mjs --self-test 0 ✓ check-closing-keyword-parity --self-test: 40 assertions, 5 mutations of the shipped parsers each driven to r
node scripts/check-comment-mask-corpus.mjs 0 ✓ comment-mask corpus sweep [scripts/js-comment-mask.mjs]: 7011 files, 0 disagree, 0 unparseable, 92.9s (compa
node scripts/pm/check-harness-current.mjs --self-test 0 check-harness-current --self-test: all 26 cases passed.
pnpm --filter @objectstack/lint run check:doc-formula-expressions 0 #11673).
pnpm check:agent-test-spelling 0 which drives this same sweep RED over a temp tree on disk.
pnpm check:cross-package-test-inputs 0 OK: 29 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob (6 of them
pnpm check:doc-authoring 0 ✓ doc authoring guard: sibling-package prose ids hold the baseline — 819 pinned site(s) across 231 file(s), 90
pnpm check:driver-memory-census 0 check-driver-memory-census: OK — every declaration is ledgered, every ledger entry is live, and every ruled fi
pnpm check:gitlink-declared 0 check-gitlink-declared: OK (9246 index entries -- 0 gitlink(s) at mode 160000; no .gitmodules in the index, so
pnpm check:nul-bytes 0 check-nul-bytes: OK (scanned 9239 text file(s) -- 9239 tracked, 0 untracked-not-ignored; skipped 7 binary; no
pnpm check:pm-governed-merges 0 live: the real generator declared 9 output(s) and certified this tree
pnpm check:pm-skill-id-lint 0 ✓ check-skill-id-lint: 30 file(s) clean (pattern /#[0-9]{3,}/g).
pnpm check:pm-skill-ratchet 0 ✓ check-skill-line-ratchet: declared cross-file moves: 1, total ceilings down 9 lines.
pnpm check:refd-timer-probe 0 1 code site(s), all inside the approved module, which is present and still reads it.
pnpm check:skill-frame-sync 0 binding sentence present in it; 1 count mention(s) agree; 77 markdown files scanned for undeclared copies.
pnpm check:watch-hint-literal 0 ✓ check-watch-hint-literal: 71 declaration(s) across 4 rostered name(s) -- ROOT_DIR_WATCH_HINTS 47, ROOT_FILE_

Also run on this tree, named by the dispatch and not in the derived list: pnpm check:skill-frame-freshness exit 0 · pnpm check:pm-governed-prose exit 0. --ran reconciliation: ✓ dispatch-gates --ran: 17 derived famil(ies) accounted for — 17 run, 0 NOT-MEASURED (a DERIVED zero — all 17 recorded an exit code and none of them is 3).

Acceptance notes

  • scripts/pm/with-fleet.sh --read -- true in this cloud container (a probe of the direct path before opening the PRs): the mint POST /app/installations/{id}/access_tokens is refused by the egress proxy (HTTP 403 "not permitted through this proxy"), classifyHttp read that 403 as ratelimit, and write-pace wrote a 30-minute STOP MARKER for the App token's key (f665bb8f6447). A proxy path refusal is not a back-off signal; the marker blocks nothing this session writes (the session token's key f07d7417ce88 carries no marker), but it would block a seat that can mint. Reported on the card for the seat to file; not fixed here (scripts/pm/**, outside this diff).
  • #19755 remains open; its PR fix(pm): fleet-write derives the seat session from the container; the workflow’s Actions state is the kill switch; size-routed direct for post-stamped #19760 is the head this text was read from. If that branch changes the reason text, exit registers or the cap before it merges, this paragraph is re-read against the merged text before the contract review.

Generated by Claude Code

The App identity `objectstack-fleet[bot]` is reached through the
`fleet-write` relay: the four write tools and `with-fleet.sh --via auto`
share one selector that takes `dispatch` only under the cloud
discriminator, a session id derived from the container (with
`OS_FLEET_SESSION` as the override, never a command prefix) and a relay
that is live on main (file present and Actions state active). The
dispatch carries the session token; the run executes on the runner with
a per-run App token narrowed to the target repo; the closed op list is
`scripts/pm/fleet-write/ops.mjs`; reads stay direct; an over-cap body
goes direct for that write with one printed line; a failed run and an
UNCONFIRMED outcome are read, never retried.

Nine lines are retired to pay the file's ceiling in place, each one
restated elsewhere: the closed-gate 403 shape and the probe rule
(platform-readings quota rows), the two identity-bound rate-limit rows
(platform-readings quota rows), the label-write recipe (SKILL.md), the
Content-Type 415 rule (platform-readings), the MCP update_pull_request
ban (settings deny list and the ccr rows above it), the MCP search
fallback (platform-readings degradation ladder) and the try-the-action
queue reading (platform-readings queue section).

Claude-Session: https://claude.ai/code/session_01XPUwWGnmky4PXPofNsf2w7
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation labels Sep 23, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 9f49c33322e70d35b69d4d8b4f221aca1168bee7

① Derived judgments

Rendered in-seat by the director seat (summon #27, session_0129ZpnaBcYZZ51rCvQiXg6C, served model read from get_session this shift: the fable tier). The contract is #19739's re-ruled body (items 3–4 as re-scoped at 2026-09-23T00:14Z): one paragraph in references/rest-channel.md 〈通道边界〉 stating the channel to the App identity, ⛔ no SKILL.md edit, ⛔ no new rule beyond the channel fact, line budget paid in place.

  • (a) One file, +9 / −9, ceiling 82 held — right. git diff main...9f49c33 touches rest-channel.md only; check:pm-skill-ratchet green on the head (the dev's table; re-read by the seat on the compare API).
  • (b) The nine added lines state what main now makes true — right. Read against the merged fix(pm): fleet-write derives the seat session from the container; the workflow’s Actions state is the kill switch; size-routed direct for post-stamped #19760 (ed4b655e): the three conditions; the session derived from CLAUDE_CODE_REMOTE_SESSION_ID with OS_FLEET_SESSION as the override; ⛔ never a prefix (the allow-rule fact measured on the triage seat); live = file on main AND Actions state active, the UI toggle as the kill switch; the per-run narrowed App token; ops.mjs as the closed op list; reads direct; the 60,000-byte size route to direct; failed run / UNCONFIRMED read, never retried. The exit registers (post-stamped/close-cards 4, label-write/issue-create 5, UNCONFIRMED 6) are the dev's measurement on the branch and correct the card's 「exit 4」 — accepted; the card is not the authority on a register the tools define.
  • (c) The nine retired lines are restatements, sampled by the seat on origin/main — right. label-write as the only label/assignee channel survives at SKILL.md :394; the update_pull_request refusal at .claude/settings.json :67 and SKILL.md :610; Content-Type / the 415 discriminant at platform-readings.md :119–120; the rate-limit identity rule and the GET /user test at :122 / :125. The remaining five rows of the dev's table name their survivors by line and were not re-sampled.
  • (d) Accept set unchanged; no gate, hook or ratchet added — right. Docs only; Clause-②: no is correct (no published payload).

② Verdict

PASS. Lands through the queue after ACCEPT on the card; skip-changeset. Landing order honoured: #19760 merged before this review.


Generated by Claude Code

@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 23, 2026
@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review September 23, 2026 02:03
@os-support-ai
os-support-ai added this pull request to the merge queue Sep 23, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Sep 23, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Record of record for this head, re-posted with the Reviewed-by: line and the **VERDICT: PASS** spelling the queue guard reads (the 02:04Z record lacked both — the guard removed PR #19770 from the queue at 02:05Z on that omission). Judgments unchanged.

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 9f49c33322e70d35b69d4d8b4f221aca1168bee7

① Derived judgments

Rendered in-seat by the director seat (summon #27, session_0129ZpnaBcYZZ51rCvQiXg6C, served model read from get_session this shift: the fable tier). The contract is #19739's re-ruled body (items 3–4 as re-scoped at 2026-09-23T00:14Z): one paragraph in references/rest-channel.md 〈通道边界〉 stating the channel to the App identity, ⛔ no SKILL.md edit, ⛔ no new rule beyond the channel fact, line budget paid in place.

  • (a) One file, +9 / −9, ceiling 82 held — right. git diff main...9f49c33 touches rest-channel.md only; check:pm-skill-ratchet green on the head (the dev's table; re-read by the seat on the compare API).
  • (b) The nine added lines state what main now makes true — right. Read against the merged fix(pm): fleet-write derives the seat session from the container; the workflow’s Actions state is the kill switch; size-routed direct for post-stamped #19760 (ed4b655e): the three conditions; the session derived from CLAUDE_CODE_REMOTE_SESSION_ID with OS_FLEET_SESSION as the override; ⛔ never a prefix (the allow-rule fact measured on the triage seat); live = file on main AND Actions state active, the UI toggle as the kill switch; the per-run narrowed App token; ops.mjs as the closed op list; reads direct; the 60,000-byte size route to direct; failed run / UNCONFIRMED read, never retried. The exit registers (post-stamped/close-cards 4, label-write/issue-create 5, UNCONFIRMED 6) are the dev's measurement on the branch and correct the card's 「exit 4」 — accepted; the card is not the authority on a register the tools define.
  • (c) The nine retired lines are restatements, sampled by the seat on origin/main — right. label-write as the only label/assignee channel survives at SKILL.md :394; the update_pull_request refusal at .claude/settings.json :67 and SKILL.md :610; Content-Type / the 415 discriminant at platform-readings.md :119–120; the rate-limit identity rule and the GET /user test at :122 / :125. The remaining five rows of the dev's table name their survivors by line and were not re-sampled.
  • (d) Accept set unchanged; no gate, hook or ratchet added — right. Docs only; Clause-②: no is correct (no published payload).

② Verdict

Reviewed-by: session_0129ZpnaBcYZZ51rCvQiXg6C

VERDICT: PASS — lands through the queue after ACCEPT on the card; skip-changeset. Landing order honoured: #19760 merged before this review.


Generated by Claude Code

Merged via the queue into main with commit 70a2e75 Sep 23, 2026
37 of 39 checks passed
@os-support-ai
os-support-ai deleted the claude/issue-19739-fleet-write-channel-text branch September 23, 2026 03:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants