Commit 7ef05f9
docs(pm,agents,settings): write-identity locks 1–4 — deny MCP content writes, REST-only dev writes with
Fixes #18068
Dev session `session_01DAcomhvR9kKizeYgg89Vo8` on branch
`claude/issue-18068-write-identity-locks` (worktree
`objectstack-issue-18068`), off `origin/main` 6d64785, merged e248c4d
before opening (no incoming commit touched these files). One commit per
lock; each quotes its ruling.
## Rulings (verbatim, untranslated)
- Maintainer, skills seat chat, 2026-09-13T16:14Z: 「机制层的五道锁 现在就派发处理」 —
the whole card.
- Maintainer to the services seat, 2026-09-13: 「当前任务处理完,后续并发降到2」 — lock
3.
- Triage ruling ③: 「立卡者不查重,只在卡面附 3–5 个查重词」 — why os-dev.md :51–:58 were
stale (lock 2's payment).
- Standing exception, pm-dispatch SKILL.md: 「唯一例外:`platform-readings.md`
增量抬上限到落地行数,免决策卡,记 `ruledRaises`
引常设裁决。条件:席位验收评论逐条核实、去重计数(候选/落地/已有/拒收)、一事一行、不计重排」 — the +2 on
platform-readings.
## What landed
1. **Lock 1** `.claude/settings.json`: `permissions.deny` with the 14
content-writing `mcp__github__*` tools the card lists; `allow` and hooks
untouched; `JSON.parse` passes. Docs reading
(code.claude.com/docs/en/permissions and /settings): rules evaluate
deny, then ask, then allow; a deny at any scope beats an allow at any
scope; `mcp__server__tool` is the per-tool spelling; the shared
`.claude/settings.json` is read in cloud sessions and deny needs no
workspace trust — lock 1 is ENFORCED, and a denied tool is removed from
the roster. Recorded as two 文档载明未实测 lines in
`references/platform-readings.md` (references tier, declared): 451 →
453, THIRTEENTH `ruledRaises` record; candidates 2 / landed 2 / already
present 0 / refused 0, one matter per line.
2. **Lock 2** `.claude/agents/os-dev.md` 403/403: :51–:58 replaced by
the REST-proxy write rule (`curl` + environment `GITHUB_TOKEN`, authored
`claude[bot]`), the four-write budget, ⛔ no MCP GitHub write tool and no
board enumeration, payload-or-single-card reads, findings reported for
the seat to file, zero writes outside the budget (no PR-body `PATCH`),
the rest-channel pointer (kept), and `api_writes` + `mcp_calls` in the
report; the report template gains `"api_writes"`. In place, net 0: the
control-word rule now sits under rule 6; resource rule 6 routes late
results to the report; the label-write fallback no longer prescribes an
MCP `issue_write`; the `out_of_scope_findings` example no longer shows a
dev-filed card number.
3. **Lock 3** SKILL.md :60 「默认 `3`」 → 「默认 `2`」; ceiling `5` unchanged;
core-rules :11 states no default, so nothing mirrored.
4. **Lock 4** SKILL.md 〈全体座位的不变量〉 +2 lines (account roles; REST-proxy
content and approver never seats), paid in the section (state and resume
lines merged; the four Chinese channels named inline, dropping two
parentheticals restated in 复核 and 升级与决策); the 〈认领〉 shared-identity line
now reads 「身份只认正文 session ID,⛔ 不认作者字段」. core-rules 〈全体座位的不变量〉 one mirror
line, paid by folding the three language lines into two. 812/812 (widest
row 342 B), 151/151, frame :733–:754 md5
`3327d02c56f8a0eca88569dad2270f32` unchanged.
## Executable criterion, BASE 6d64785 → HEAD 7e1aeca
`grep -c mcp__github__issue_write .claude/settings.json` 0 → 1 (inside
`deny`); SKILL.md 「默认 `2`」 0 → 1 and 「默认 `3`」 1 → 0; os-dev.md
`api_writes` 0 → 2 (rule + template), `search_issues` 1 → 0; SKILL.md
「批准账号」 / 「永不跑席位」 0 → 1, core-rules 「批准账号」 0 → 1. Lit controls unchanged:
「每个方案必须沿四条固定评估轴分析」 1 → 1, 「一座位一车道双射」 1 → 1 in both files, os-dev.md
`mcp_calls` 2 → 2.
## Gates
`node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` at 88e0610: 42 families, every one exit 0
in the foreground with the code captured before any pipe; `--ran`: 42
derived, 42 run, 0 NOT-MEASURED, 0 UNRUN.
`check:doc-formula-expressions` first answered exit 3 (PREREQUISITE NOT
MET, lint/formula unbuilt) — built under the verify lock (187 s held)
and re-run: exit 0. Rule ⑤ for the ratchet-script edit: its
`--self-test` (inside `check:pm-skill-ratchet`),
`check:ratchet-remedy-authority`,
`scripts/check-published-list-mirrors.mjs` and
`scripts/check-skills-token-ratchet.mjs` all exit 0. Re-run at 7e1aeca
after the merge: `pm-skill-ratchet`, `pm-skill-id-lint`,
`skill-frame-sync`, `pm-governed-prose`, `nul-bytes`,
`agent-model-declared` exit 0. Every added prose line ≤ 120 B (the one
longer added line is inside the report's JSON fence, structurally
exempt); SKILL.md over-120 baseline 23 → 23; control-character scan
empty. `skip-changeset`: nothing published moves (`.claude/**`,
`scripts/pm/**` only).
## Deviations, declared
- Lock 4 is two SKILL.md lines, not one: the card's four clauses do not
fit one 120-byte line; both are paid inside the section.
- Lock 2 edits four lines outside :51–:58 (rule 6 premise line, resource
rule 6, the label fallback, the report template), each net 0, each of
which would otherwise contradict the budget.
- The card's budget has no PR-body `PATCH`; the rule says so explicitly
and routes late gate results to the report comment. Allowing a body
refresh would be one clause on that line, the seat's call.
- PR #18051 (open draft) edits os-dev.md :50, adjacent to this diff's
:51 — whichever lands second takes a one-hunk merge; its SKILL.md
:106/:113 lines do not overlap.
## Acceptance notes
- noted, not filed (承接者: the skills seat reviewing this PR):
`mcp__github__update_pull_request_branch` writes merge commits, and
`request_copilot_review` writes a review request, yet neither is on the
card's list, so both stay allowed.
- noted, not filed (承接者: the skills seat): SKILL.md :778 still reads
「只列三类立卡与 noted, not filed」; under lock 2 the dev lists findings to file
and the seat files them.
## 维护者速读(草稿)
**改了什么**:四道机制锁。① 仓库的 Claude 设置里禁掉所有"以用户账号写内容"的 MCP GitHub 工具(建 issue、开
PR、评论、审查、推文件、合并等 14 个),状态类与只读工具照旧;② 开发 agent 对 GitHub 的写只走 REST 代理(署名
`claude[bot]`),预算固定四笔,报告新增 `api_writes` 供席位核对;③ 并发默认 3 → 2,天花板 5 不变;④
写明用户账号只做三件事(assignee、授权批准、维护者亲手),批准账号永不跑席位,内容身份只认正文里的 session ID。
**为什么改**:今天的封号事故证明,用 MCP 工具写的内容署在关联用户名下,用户一被停,内容整批消失;走 REST 代理的内容署在 App
名下不受影响。并发只是放大器,身份才是被封的对象。
**风险与代价(含回滚)**:deny 名单在会话启动时读入,已开的会话不受影响;席位仍可用 `update_pull_request`
等状态工具翻 ready、挂 auto-merge。回滚 = revert 本 PR 的任一 commit(每锁一个
commit,互不依赖)。platform-readings 上限 +2 走常设例外,不另开决策卡。
**席位意见**:(留空,由席位定稿)
**你要做的**:一个动作 —— 在本 PR 上给出授权批准;受管面,席位按裁决 C 落地。
---
_Generated by [Claude
Code](https://claude.ai/code/session_01DAcomhvR9kKizeYgg89Vo8)_
---------
Co-authored-by: Claude <noreply@anthropic.com>api_writes, batch default 2, user-account roles (#18072)1 parent c54d8d6 commit 7ef05f9
6 files changed
Lines changed: 70 additions & 21 deletions
File tree
- .claude
- agents
- skills/pm-dispatch
- references
- scripts/pm
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
48 | 48 | | |
49 | 49 | | |
50 | 50 | | |
51 | | - | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
52 | 56 | | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
57 | | - | |
58 | | - | |
| 57 | + | |
59 | 58 | | |
60 | 59 | | |
61 | 60 | | |
| |||
70 | 69 | | |
71 | 70 | | |
72 | 71 | | |
73 | | - | |
| 72 | + | |
74 | 73 | | |
75 | 74 | | |
76 | 75 | | |
| |||
92 | 91 | | |
93 | 92 | | |
94 | 93 | | |
95 | | - | |
| 94 | + | |
96 | 95 | | |
97 | 96 | | |
98 | 97 | | |
| |||
299 | 298 | | |
300 | 299 | | |
301 | 300 | | |
302 | | - | |
| 301 | + | |
303 | 302 | | |
304 | 303 | | |
305 | 304 | | |
| |||
368 | 367 | | |
369 | 368 | | |
370 | 369 | | |
| 370 | + | |
371 | 371 | | |
372 | 372 | | |
373 | 373 | | |
374 | | - | |
| 374 | + | |
375 | 375 | | |
376 | 376 | | |
377 | 377 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
48 | 48 | | |
49 | 49 | | |
50 | 50 | | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
51 | 67 | | |
52 | 68 | | |
53 | 69 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
60 | | - | |
| 60 | + | |
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
| |||
91 | 91 | | |
92 | 92 | | |
93 | 93 | | |
94 | | - | |
95 | | - | |
96 | | - | |
97 | | - | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
98 | 98 | | |
99 | 99 | | |
100 | 100 | | |
| |||
462 | 462 | | |
463 | 463 | | |
464 | 464 | | |
465 | | - | |
| 465 | + | |
466 | 466 | | |
467 | 467 | | |
468 | 468 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
25 | | - | |
26 | | - | |
27 | | - | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
| |||
Lines changed: 2 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
211 | 211 | | |
212 | 212 | | |
213 | 213 | | |
| 214 | + | |
| 215 | + | |
214 | 216 | | |
215 | 217 | | |
216 | 218 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
874 | 874 | | |
875 | 875 | | |
876 | 876 | | |
877 | | - | |
| 877 | + | |
| 878 | + | |
| 879 | + | |
| 880 | + | |
| 881 | + | |
| 882 | + | |
| 883 | + | |
| 884 | + | |
| 885 | + | |
| 886 | + | |
| 887 | + | |
| 888 | + | |
| 889 | + | |
| 890 | + | |
| 891 | + | |
878 | 892 | | |
879 | 893 | | |
880 | 894 | | |
| |||
1495 | 1509 | | |
1496 | 1510 | | |
1497 | 1511 | | |
| 1512 | + | |
| 1513 | + | |
| 1514 | + | |
| 1515 | + | |
| 1516 | + | |
| 1517 | + | |
| 1518 | + | |
| 1519 | + | |
| 1520 | + | |
| 1521 | + | |
| 1522 | + | |
| 1523 | + | |
| 1524 | + | |
| 1525 | + | |
| 1526 | + | |
| 1527 | + | |
| 1528 | + | |
1498 | 1529 | | |
1499 | 1530 | | |
1500 | 1531 | | |
| |||
0 commit comments