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-tesla · session_01W5y9kRg1YtYaMQYExVLRc2 · R1 in seat · landed 5 (#18698 · #18862 fold · #18989 · #19091 · #19036) · in flight 0 · awaiting human merge 2 (objectui#9994 · objectui#9997) · queue 26 (p1 0 dispatchable, p2/p3 held by 北极星第 3 条) · decision box 1 · body r5e #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
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