Skip to content

docs(pm,agents): write identity follows the channel, not the account — REST-only content writes, the ACCEPT refuses MCP writes, a stale shared checkout re-seats (#18205) - #18216

Merged
os-zhuang merged 2 commits into
mainfrom
claude/issue-18205-write-channel-propagation
Sep 14, 2026
Merged

os-zhuang merged 2 commits into
mainfrom
claude/issue-18205-write-channel-propagation

Conversation

@claude

@claude claude Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Fixes #18205

The maintainer's order (verbatim, ⛔ not translated)

「派发令硬性指定 REST 通道:建议改。 你应该修改skills吧?」 and 「不只是 objectui 仓库,其他第三方元数据app仓库怎么办」 — the maintainer, 2026-09-14, in the skills seat's chat (audit comment 5666103417 on the card). Lock 1 (PR #18072, 7ef05f9973) stays in force as the channel rule; this PR corrects its identity claims and does not weaken it. Landing is governed by ruling C (#17971): 「C. approve 后不管后续改动都由席位落地:」 — this PR is a DRAFT and stays one; the seat does the four-piece after ACCEPT and lands only after an authorized approval.

What changed — equal-line under every ratchet, every touched line at or under 120 bytes

Line numbers are on this branch at 7103d0b09f; B = bytes of the line as stored. Readings taken 2026-09-14T16:27Z.

file line after B
.claude/agents/os-dev.md :51 GitHub 写一律走 REST 代理(curlGITHUB_TOKEN);归属 = 文本里的 session ID,非 user.login 116
.claude/agents/os-dev.md :53 ⛔ 不用 MCP GitHub 写工具;令牌按会话定:installation ⇒ claude[bot],user-to-server ⇒ 用户。 115
.claude/agents/os-dev.md :369 "mcp_calls": "N — MCP GitHub calls with tool names; a write tool in the list = this report is refused", (the file spells the placeholder N inside angle brackets, as the template always has) 109
SKILL.md :91 (new) 同读 harness 载入面 .claude/{settings.json,agents/*.md,hooks/*} 的最新触碰是否已在共享检出 HEAD。 120
SKILL.md :92 (new) 否 ⇒ 收班、换新会话再派,⛔ 不推进共享检出;读数走 scripts/pm/check-harness-current.mjs 115
SKILL.md :97 用户账号仅三用:assignee、授权批准、维护者亲手;批准账号永不跑席位或作其关联用户。 117
SKILL.md :98 内容写只走 REST 代理,⛔ 无 MCP 写;user.login 记令牌不记席位,归属 = 文本里的 session ID。 116
SKILL.md :195 新仓登记是一张清单:座位贴、标签、类别归属、门禁盘点、写身份锁移植(deny + hooks)。 116
SKILL.md :537 (merged) 终报要求随派发词带一句:只收机器可核字段(gates / line_budget / deviations / files_changed)。 113
SKILL.md :538 (new) 派发令恒带 Writes: 行:只走 REST 代理、写预算(端点清单)、mcp_calls 计数,dev 两数都报。 117
SKILL.md :556 (merged) mode:cloud 只保留给 L/XL、活过 PM 会话的工作、浏览器/dogfood 验证;build 重的 M 卡逐卡判。 118
SKILL.md :567 (merged) 标记两种拼写等效(HTML 注释形、首行 os-dev-report);⛔ 永不把没收到失败通知读作还在跑。 120
SKILL.md :602 (new) mcp_calls 点名写工具(settings.json deny 清单 + update_pull_request)⇒ 拒收,⛔ 不带注放行。 115
SKILL.md :775 (merged) 终报 JSON 的权威形状住 .claude/agents/os-dev.md 终报消息节,⛔ 本文不抄第二份。 104
references/core-rules.md :25 用户账号仅三用:assignee、授权批准、维护者亲手;写只走 REST 代理,署名随令牌非席位。 115
references/platform-readings.md :129 容器 curl 的 REST 通道令牌按会话定:installation(claude[bot])或 user-to-server(用户),core 15,000/时。 120
references/rest-channel.md :54 直合仓 PUT .../pulls/{n}/merge;actor 记通道令牌:REST 按会话为 claude[bot] 或用户,MCP 恒用户。 118

SKILL.md and references/ are .claude/skills/pm-dispatch/. The two os-dev.md rule lines carry their 3-space list indent inside the count.

  • (a) facts and invariants: content writes go only through the REST proxy; ⛔ no MCP content write; user.login on a write names the channel's token — installation ⇒ claude[bot], user-to-server ⇒ the bound user — per session, not the seat's to choose, never the actor; attribution is the session ID in the text carrier. os-dev.md :51/:53, SKILL.md :97–:98, core-rules :25, platform-readings :129, rest-channel :54.
  • (b) dispatch order and acceptance: SKILL.md :538 — every dispatch order carries a Writes: line (REST proxy only, the write budget as an endpoint list, mcp_calls counted, the dev reports both numbers); SKILL.md :602 — a report whose mcp_calls names a write tool (the settings.json deny list plus update_pull_request, which that list does not carry) is refused, ⛔ not accepted with a note; os-dev.md :369 says the same from the dev side.
  • (c) propagation: SKILL.md :91–:92 beside the three-charter-file reading — at fire time the seat also reads the latest origin/main touch of .claude/settings.json, .claude/agents/*.md, .claude/hooks/* against the shared checkout's HEAD; a touch not in HEAD ⇒ close the shift and re-seat in a fresh session before the next dispatch, ⛔ never advance the shared checkout in place. The reading is scripts/pm/check-harness-current.mjs (59 lines, git only, seat-side, ⛔ not wired into CI): exit 0 CURRENT, 1 STALE (each stale path with its touch), 2 UNDECIDED (shallow-clone negative that is not date-decided).
  • (d) fleet: SKILL.md :195 — the new-repo registration checklist gains the write-identity locks port (deny + hooks). The four repos without a port today: cloud, objectos, hotcrm, www.objectos.ai. Named here only; no cards from this PR — the seat that can reach each files its card (recorded on [PM seat] domain:skills — 🟢 os-elon-musk · R2 · 在飞 1 / 3 (#18425) · 落地 7 (PR #18423 · #18444 · #18450 · #18449 · #18457 · #18436 · #18437) · 待批准 1 (PR #18447 ← #18384) · 决策箱 1 (#18434) · queue 2 (维护者门控 #17163 · #18290) #7623 until then).
  • (e) the managed-settings fact row: not landed in platform-readings (454/454, no payable pair in that file without deleting a ruled clause); recorded under Acceptance notes below with the doc sentences verbatim.

Premise readings (falsified against the tree before writing; all UTC)

  • P1 (16:12Z, base af3add1601): all seven quoted lines read exactly as the dispatch quotes them — os-dev.md :51 「- GitHub 写一律走 REST 代理(curl 带环境 GITHUB_TOKEN),署名恒 App 的 claude[bot]。」 and :53 「- ⛔ 不用任何 MCP GitHub 写工具:用户账号署名,封号即隐;⛔ 不枚举板面、不宽词搜。」; SKILL.md :95 「- 用户账号仅三用:assignee、授权批准、维护者亲手;⛔ 席位与 dev 永不以用户账号写内容。」 and :96 「- 内容恒经 REST 代理(claude[bot]);批准账号永不跑席位、不作席位 claude.ai 的关联用户。」; core-rules :25 「- 用户账号仅三用:assignee、授权批准、维护者亲手;写恒经 REST 代理;批准账号永不跑席位。」; platform-readings :129 「- 容器 curl 的 REST 通道 = App installation token,core 15,000/时,与 GraphQL 池独立计。」; rest-channel :54 「- 直合仓另有 PUT .../pulls/{n}/merge;ccr 的 timeline actor 记 claude[bot],MCP 记席位账号。」. Holds.
  • P2 (16:11:37Z): git -C /home/user/objectstack rev-parse HEAD = 84e6b05b6d295f1c744d236921300f447cf7791e, log -1 --format=%cI = 2026-09-13T06:14:23+00:00; merge-base --is-ancestor 7ef05f9973 HEAD exit 1. Control legs for the negative (shallow checkout, rev-list --count HEAD = 4024): is-ancestor 84e6b05b6d HEAD exit 0 and, twelve commits deep, is-ancestor d88a47d766 HEAD (committed 2026-09-12T22:39:41Z) exit 0 at 16:12:17Z; the negative is also date-decided — 7ef05f9973 was committed 2026-09-13T23:27:23Z, seventeen hours after the shared HEAD. grep -c 'mcp__github__' .claude/settings.json: shared 1, worktree 15. Holds — with one sharpening: the shared file's single hit is a PreToolUse hook matcher (mcp__github__enable_pr_auto_merge|mcp__github__merge_pull_request), and the shared file has no permissions.deny key at all (grep -c '"deny"' = 0 against 1 on origin/main), so in this session no deny list was ever loaded, not a pre-lock-1 one.
  • P3 (16:12:09Z, origin/main = af3add1601): the grep hits are SKILL.md :31 (never edit the shared checkout), :160 (never verify main from its worktree), :506/:606/:774 (paths named as protocol/governed surfaces or as the report authority); core-rules :44/:149 (the same two); dispatch-runbook :215 (frontmatter model: exemption); platform-readings :30–:33 (merge-driver registration per clone), :214 (deny documented-not-measured), :344/:373/:415 (footer, transcript, sleep) and :413 (shallow-clone deepen); app-platform-boundary :60 and contract-review :57 (the word harness in other senses). None prescribes re-seating when a harness-loaded file lands after the session's clone; SKILL.md :86–:90 re-READS the three charter files, and reading does not reload the harness. Control git grep -c '收班简报' on SKILL.md = 5. Holds.
  • P4 (16:12:09Z): 派发令 hits are SKILL.md :153/:164/:214/:433/:444/:461/:478/:540/:543/:715/:790 and dispatch-runbook :184/:205/:232/:236 — all rule lines about what the order carries; 〈模板与表〉 holds only the claim-comment template. No fixed shape exists, so the Writes: mandate lands as a rule line (SKILL.md :538). Holds.
  • P5: os-dev.md :369–:370 are the mcp_calls / api_writes report fields; :57 already orders both counts. Holds; :369 rewritten, :370 untouched.
  • P6 (16:17:26Z on the base): check-skill-line-ratchet exit 0 with every one of the five files at its ceiling (812 / 403 / 454 / 82 / 151, headroom 0, table-row pins 342 / 0 / 0 / 0 / 0); check:skill-frame-sync exit 0; git ls-remote --heads origin matched only this branch for issue-17497/18205/18181/18158. Holds.
  • P7: scripts/pm/dispatch-gates.mjs is untouched; dispatch-gates: STAGE-THEN-RUN reaches a program by an edge neither follow traverses — check:objectui-changeset inherits nothing from scripts/bump-objectui.sh #14290's Restart-touch surface is left alone; the seat-side check is the sibling file scripts/pm/check-harness-current.mjs.

The mechanism, measured in this session (16:25Z)

  • The os-dev.md this dev runs under is the shared checkout's copy: its line 「通道先探后选…」 is in git show 84e6b05b6d:.claude/agents/os-dev.md (1 hit) and absent on origin/main (0); api_writes is the inverse (0 in the old copy, 2 on origin/main); control Worktree-first 1 / 1.
  • node scripts/pm/check-harness-current.mjs from this worktree (shared checkout resolved through --git-common-dir): exit 1 — .claude/settings.json and .claude/agents/*.md latest touch 7ef05f9973 NOT in shared HEAD 84e6b05b6d, .claude/hooks/* latest touch d79f249915 (2026-09-12T09:41:28Z) in HEAD. --shared /home/user/objectstack-issue-18205: exit 0 CURRENT at af3add1601. --shared /nonexistent: exit 2.

Gates (final head 7103d0b09f, 16:28Z–16:37Z)

node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths; change set derived from git, 6 paths, committed 6 / working tree 0 / untracked 0) printed 40 commands. All 40 run with redirect-then-capture, each recorded as CMD :: exit N:

  • 39 exit 0 on the first pass, including check:pm-skill-ratchet, check:skill-frame-sync, check:pm-governed-prose, check:pm-skill-id-lint, check:nul-bytes, check:agent-model-declared, check:entry-guard, check:parse-guard, check-self-test-wired, check-scripts-symbol-anchors, check:commit-card-trailers, check:pm-governed-merges.
  • pnpm --filter @objectstack/lint run check:doc-formula-expressions first read exit 3 = PREREQUISITE NOT MET (compiled @objectstack/formula and @objectstack/lint absent in the fresh worktree; the gate says "Nothing was measured"). Prerequisite cleared under the verify lock — os-verify-lock.sh -c 'pnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint --concurrency=2': VERDICT command-exit 0, held the lock 172 s, waited 0 s — then rerun: exit 0, "22 record-scoped formula example(s) across 438 files / 1377 TS blocks judged clean by @objectstack/formula."
  • Reconciliation: dispatch-gates --ran ran.list --repo objectstack-ai/objectstack at 16:37:21Z on 7103d0b09f: "Run reconciliation — 40 derived, 40 run, 0 NOT-MEASURED, 0 UNRUN." (exit 0; the derived 40 is recomputed by the tool from the tree, never read back from the record).
  • Ratchet on the final head: every one of the five files at its ceiling, headroom 0, pins unchanged (SKILL.md widest table row 342). First pass on the working tree had caught os-dev.md :51 at 122 B (the list indent was outside the draft measurement); fixed in the second commit to 116 B.
  • Lint, narrowed and measured: the checked population is eslint's own config (files: ['**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}'], which covers scripts/pm/*.mjs); the only non-markdown file in the diff is scripts/pm/check-harness-current.mjs; eslint --no-inline-config --format json on it: 1 file, 0 errors, 0 warnings (exit 0); invariance: eslint.config.mjs states it "never enables type-aware linting (no parserOptions.project, no typed @typescript-eslint rules) for ANY file", so a one-file addition cannot move any untouched file's verdict. The repo-wide pnpm lint is CI's run.
  • Not run here, declared to CI: nothing else — the diff touches no package, so there is no ① build closure or ② package test suite; .claude/** and scripts/pm/** publish nothing, so skip-changeset applies (fast lane: .claude/** · scripts/pm/**). The seat writes the label; this container does not.

Density paid inside each file

  • SKILL.md (four new lines, four merges): 终报要求 + 机器可核字段 → one line (drops only the implied 「⛔ 复述 PR body 叙事」); mode:cloud + build-heavy-M → one line (drops 「必须」); marker spellings + missing-notification → one line (the dropped 「仅凭 HTML 注释形式缺失永不读作报告未达」 is what 「两种拼写等效」 states); 报告契约 authority + no-second-copy → one line (drops the implied 「字段与拼写以那里为准」).
  • os-dev.md :53 drops 「⛔ 不枚举板面、不宽词搜」 — :50 (「⛔ 不扫 open issues、不拉板」) and :54 (single-card reads only) already carry it.
  • core-rules :25 (the compressed mirror) now carries the channel + identity reading; the approval-account clause could not fit beside it in 120 B and stays where it is authoritative, SKILL.md :97.

维护者速读(草稿)

  • 改了什么:① 署名跟令牌走、不跟账号走 —— GitHub 上写回读到的 user.login 只说明这条会话的令牌是 App 的还是用户的,不说明是谁在写;身份看文本里的 session ID。② dev 报告里出现任何 MCP 写工具即拒收,不带注放行。③ harness 读的文件(settings.json、agents、hooks)在 main 上动了而共享检出没跟上时,席位收班、换新会话再派,永不原地推进共享检出。
  • 为什么改:锁 1 落地后 objectui 仍出现一条经 MCP 建的 PR,原因是运行中的会话只在克隆那一刻读一次这些文件;同时章程里「署名恒 claude[bot]」被四个会话的实测证伪。
  • 风险与代价(含回滚):纯规则文本 + 一个只读 git 的席位脚本,零 CI 接线;回滚即 revert 这一个 PR。代价是每次开轮多一次 git 读数,与一次可能的换会话。
  • 席位意见:(留空)
  • 你要做的:一个动作 —— 批准这份草稿,席位落地。

Acceptance notes

  • Item (e), recorded here instead of a fact row: code.claude.com/docs/en/settings 「Settings in cloud sessions」 states, verbatim: "Shared project settings (.claude/settings.json): read, because the file is part of the clone." / "User and project local settings (~/.claude/settings.json and .claude/settings.local.json): not read. Both stay on your machine, and the local file isn't in the clone." / "Managed settings: only server-managed settings reach a cloud session; a managed-settings.json file or MDM profile on your device doesn't." And code.claude.com/docs/en/server-managed-settings: "Server-managed settings are available for Claude for Teams and Claude for Enterprise customers." So a personal account has no managed tier, and the maintainer-level lever the card names (a user-level file written by the environment setup script inside the cloud VM) is not the file those sentences describe — the docs speak of the file on the user's own machine; whether a user file written inside the VM is read is not stated. Bearer: the round report (the card already routes the lever there).
  • The card's "1 mcp__github__* entry (pre-lock-1)" in the shared checkout's settings is a hook matcher, not a deny entry; the shared file has no permissions.deny at all. Whether a deny list loaded from the clone takes effect in a cloud session therefore remains documented-not-measured (platform-readings :214 stands); the first session cloned after 7ef05f9973 measures it by tool-table absence. Bearer: the skills seat's next fresh session.
  • mcp__github__update_pull_request edits PR bodies and titles through MCP and is not in .claude/settings.json's deny list; the ACCEPT line names it explicitly for that reason. Reported in the dev report for the seat to file or fold (⛔ not changed here: .claude/settings.json is outside this card).
  • The script has no --self-test on purpose: it is not CI-wired (check-self-test-wired populates from workflows), it exports nothing (check:entry-guard rule two does not apply), and its three readings above are the measurement. Bearer: whoever wires it into a workflow later owes the self-test then.
  • #18181 remains open (os-dev.md :287 label write is not addressed here); #18158 remains open (the identity reading itself); the objectui port (PR fix(devx): the objectui pin guard tests walk completeness, not object presence #9448) is untouched.

Clause-②: no


Generated by Claude Code

…— REST-only content writes, the ACCEPT refuses MCP writes, a stale shared checkout re-seats

Equal-line edits under every ratchet (SKILL.md 812, os-dev.md 403,
platform-readings 454, rest-channel 82, core-rules 151), every touched
line at or under 120 bytes.

- facts and invariants: content writes go only through the REST proxy,
  never an MCP content-write tool; `user.login` on a write names the
  channel's token (installation ⇒ `claude[bot]`, user-to-server ⇒ the
  bound user — per session, not the seat's to choose), never the actor;
  attribution is the session ID in the text carrier. Rewritten in
  os-dev.md :51/:53, SKILL.md :97–:98, core-rules :25,
  platform-readings :129, rest-channel :54.
- dispatch order and acceptance: every dispatch order carries a
  `Writes:` line; an os-dev-report whose `mcp_calls` names a write tool
  (the settings deny list + `update_pull_request`) is refused, on both
  the seat side (SKILL.md 复核) and the dev side (os-dev.md :369).
- propagation: at fire time the seat also reads the latest origin/main
  touch of the harness-loaded files (.claude/settings.json,
  .claude/agents/*.md, .claude/hooks/*) against the shared checkout's
  HEAD; a touch not in HEAD ⇒ close the shift and re-seat in a fresh
  session, never advance the shared checkout in place. The reading is
  scripts/pm/check-harness-current.mjs (git only, seat-side, not CI).
- fleet: the new-repo registration checklist gains the write-identity
  locks port (deny + hooks).

Density paid inside each file: four SKILL.md bullet pairs merged
(终报要求/机器可核字段, mode:cloud/build-heavy, marker spellings/
missing-notification, 报告契约 authority/second-copy); os-dev.md :53
drops the board/wide-search clause already carried by :50 and :54.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DAcomhvR9kKizeYgg89Vo8
The list indent under 基本规则 3 costs three bytes the draft measurement
left out; `带环境` becomes `带`, 122 → 116 bytes, same content.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DAcomhvR9kKizeYgg89Vo8
@claude

claude Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: 4/4 CONTRACT_REVIEW_TIER
Head-sha: 7103d0b09fedba5b121bb15c5067bc764067aaaa

In-seat record on the GOVERNED rules layer (.claude/skills/pm-dispatch/SKILL.md, .claude/agents/os-dev.md, references/{core-rules,platform-readings,rest-channel}.md, plus a seat-side script under scripts/pm/ — one of the four pieces; the landing waits for an authorized approval under ruling C), domain:skills execution PM seat, 2026-09-14T16:45Z. Spelled from node scripts/pm/check-clause2-carriers.mjs --template on origin/main; the stamp control is the reviewing round's own count off the seat's transcript. The dev's os-dev-report is 5667412043 on #18205; the judgments below are the seat's own reading of the diff and of the head in its own worktree.

① Derived judgments

  • Equal-line under every ratchet (git diff --numstat against merge-base af3add1601: os-dev.md 3/3, SKILL.md 11/11, core-rules 1/1, platform-readings 1/1, rest-channel 1/1, one new 59-line script): the constant-claude[bot] claims are replaced by the channel reading — os-dev.md :51 (attribution = the session ID in the text, not user.login, 116 B), :53 (no MCP write tool; the token is per session: installation ⇒ claude[bot], user-to-server ⇒ the user, 115 B), SKILL.md :97–:98 (117 / 116 B), core-rules :25 (115 B), platform-readings :129 (120 B), rest-channel :54 (118 B). The dispatch order gains the Writes: mandate (:538, 117 B); the ACCEPT gains the refusal on a write tool in mcp_calls (:602, 115 B) mirrored in the report contract (os-dev.md :369, 109 B); the fire-time reading of the harness-loaded paths against the shared checkout with re-seating as the remedy lands at :91–:92 (120 / 115 B); the new-repo checklist gains the locks port (:195, 116 B). Every line ≤ 120 B as check-skill-line-ratchet.mjs measures.
  • Ratchets and frame, seat's own run on the head: SKILL.md 812/812 (widest row 342/342), os-dev.md 403/403, platform-readings 454/454, rest-channel 82/82, core-rules 151/151; check:skill-frame-sync exit 0 (the frame block moved to :734–:755 by the net +1 line before it; md5 3327d02c56f8a0eca88569dad2270f32 — identical to main's :733–:754 block (shifted by the net +1 line before it)); check-governed-prose, check-skill-id-lint exit 0; check-clause2-carriers --pair 18216 exit 0.
  • The script, read and run: scripts/pm/check-harness-current.mjs reads git only (latest origin/main touch of .claude/settings.json, .claude/agents/*.md, .claude/hooks/* vs merge-base --is-ancestor on the shared checkout's HEAD, with a shallow-clone UNDECIDED leg), defaults the shared dir from --git-common-dir, exits 0 / 1 / 2; the seat reproduced STALE on /home/user/objectstack (84e6b05b6d, both paths at 7ef05f9973), CURRENT on a worktree at origin/main, 2 on a missing dir. ⛔ Not wired into CI; a seat-side reading only. ESLint on the one non-markdown file: 0 errors (dev's run, config non-type-aware so untouched verdicts cannot move).
  • The card's measurement corrected by the dev: the shared checkout's settings.json has no permissions.deny key at all (its one mcp__github__ hit is a hook matcher) — so this session loaded no deny list; the propagation reading stands and is stronger. Recorded on the card's ACCEPT.
  • Gates as reported by the dev: 40 derived commands, all exit 0 after one PREREQUISITE build under the verify lock, reconciled 40/40 with --ran; 0 MCP calls, 5 REST writes. CI on the head at the seat's read: 15 success, 10 skipped, 4 in progress, no failure on a latest run (the changeset check's first run predates the seat's skip-changeset) — the landing step re-reads it green before anything moves.

② Semver level

None. .claude/** and scripts/pm/** only; skip-changeset applied and read back; nothing published.

③ Boundary flags

  • Governed rules layer (SKILL.md, os-dev.md, three references) + PM tooling. Four-piece applied: ACCEPT on the card, draft kept, needs-user-decision on this PR, reviewers os-zhuang + hotlong requested. ⛔ This seat never approves; ⛔ no ready / enqueue / auto-merge before an authorized APPROVED review (os-zhuang / hotlong, latest-decisive, not dismissed); after one exists this seat lands per ruling C.
  • Clause ②: no, judged the same. Rules-layer lines state a measured platform fact and a channel mandate the charter already carried (lock 1 stays, its identity claims corrected); the ACCEPT refusal is a seat rule; the script is seat-side; no accepted set, contract or CI gate strength moves.
  • Deviations adopted: core-rules :25 no longer carries 「批准账号永不跑席位」 (authoritative at SKILL.md :97); os-dev.md :53 no longer carries 「不枚举板面、不宽词搜」 (:50 / :54 do); the :565 merge keeps the equivalence and drops its corollary sentence; two density merges (:553, :773) lose no content.
  • Vocabulary for later controls: 归属 = 文本里的 session ID, 令牌按会话定, check-harness-current, 写身份锁移植, 派发令恒带 \Writes:` 行; a post-landing grep fires on 令牌按会话定/check-harness-current`.
  • Owed onward: finding(settings): permissions.deny omits mcp__github__update_pull_request — an MCP content write (title/body/draft) the charter now declares closed, and the seat's ready-flip fallback names the same tool #18218 (the update_pull_request deny gap vs the seat's ready-flip fallback) graded by this lane after landing; the maintainer-level lever (server-managed settings for Teams / Enterprise; a user-level file written inside the VM is not addressed by the docs) stays in the round report; the four repos without the locks port (cloud, objectos, hotcrm, www.objectos.ai) wait on a seat that can reach them.

Implemented-by: claude/issue-18205-write-channel-propagation
Reviewed-by: session_01DAcomhvR9kKizeYgg89Vo8

VERDICT: PASS


Generated by Claude Code

@claude

claude Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

维护者速读

改了什么:三件,全部等行、五个文件都顶着行数上限:① 章程里「署名恒 claude[bot]」的几行改成实测的读数——署名跟令牌走(安装令牌落 claude[bot],用户令牌落用户名),令牌由代理按会话发,不是席位能选的;写谁写的看正文里的 session ID,user.login 不作施动者读数。② 派发令必须带一行 Writes:(只走 REST 代理、写预算、mcp_calls 计数);dev 报告里 mcp_calls 出现任何写工具即拒收,不带注放行。③ 席位开轮时多读一个数:settings.jsonagents/*.mdhooks/* 在 main 上的最新改动是否已在共享检出里;不在就收班换新会话再派,永不原地推进共享检出;配一个只读 git 的席位脚本 check-harness-current.mjs,不接 CI。另外新仓登记清单加一项「写身份锁移植」。

为什么改:锁 1 落地之后 objectui 仍出现经 MCP 建的 PR,原因是 harness 只在克隆那一刻读一次这些文件;dev 顺手测出本会话的共享检出里根本没有 permissions.deny 这个键。你的两句话(硬指定 REST 通道;其他仓怎么办)是这张卡的授权。

风险与代价(含回滚):纯规则文本加一个 59 行的只读脚本,零 CI 接线;回滚即 revert。代价是每次开轮多一次 git 读数,以及可能的换会话。

席位意见:dev 为付行数把 core-rules :25 的「批准账号永不跑席位」并回 SKILL.md :97 保留,os-dev.md :53 的「不枚举板面、不宽词搜」由 :50/:54 承担,本席采信。dev 另报一个空子:deny 名单漏了 update_pull_request(它能改 PR 标题正文),而席位翻 ready 的兜底又点名同一个工具,已立 #18218,等这个 PR 落地后再定级。

你要做的:os-zhuang 或 hotlong 一次 approve;之后由本席落地。是 / 否?


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review September 14, 2026 23:24
@os-zhuang
os-zhuang added this pull request to the merge queue Sep 14, 2026
Merged via the queue into main with commit 8c657f7 Sep 14, 2026
40 of 41 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-18205-write-channel-propagation branch September 14, 2026 23:50
This was referenced Sep 15, 2026
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 needs-user-decision size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants