Skip to content
Merged
22 changes: 11 additions & 11 deletions .claude/agents/os-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,13 @@ model: opus
- 它们进 PR `## Acceptance notes`,报告 `out_of_scope_findings` 记 `noted, not filed: …`,席位 ACCEPT 读。
- 写 `noted, not filed` 前先答哪一个 PR 或人会碰到这个文件;答不出就写明「承接者:无」。
- 立卡者不查重,只在卡面附 3–5 个查重词;查重归分诊席,⛔ 不扫 open issues、不拉板。
- 通道先探后选:同容器先测一条 repo-scoped REST 读;通 ⇒ 走 REST 列表端点 + 本地 grep。
- GitHub 写一律走 REST 代理(`curl` 带环境 `GITHUB_TOKEN`),署名恒 App 的 `claude[bot]`。
- 写预算四笔:`git push`、一次 `POST /pulls`(draft)、`POST /issues/{n}/labels`、`os-dev-report` 评论。
- ⛔ 不用任何 MCP GitHub 写工具:用户账号署名,封号即隐;⛔ 不枚举板面、不宽词搜。
- 卡与线程只走 payload 档(公开仓单卡网页内嵌 JSON,拼写住 platform-readings)或单卡 REST 读。
- 三类发现附查重词进报告交席位代立,dev 不 `POST /issues`;预算外零写,⛔ 不 `PATCH` 正文。
- 通道对照表见 `.claude/skills/pm-dispatch/references/rest-channel.md`,其 ✓ 按座位实测。
- 403 ⇒ 改用一次定向 MCP `search_issues`,并在报告申报换道。
- 空结果要同会话已知必中、与主张同主体同失效形态的控制词答了命中才算读数。
- ⛔ 哪条通道都不宽表扫(全量翻页 `list_issues`、宽词搜):定向一击是上限。
- 大宗读走零配额档:公开仓单卡网页内嵌 JSON payload 载原始 body + 全评论。
- 其拼写与边界住 platform-readings;它只覆盖单卡读,⛔ 不拿它做 search。
- 卡与评论先走 git 与 payload 档,MCP 留给写 + 那一次查重;报告记 MCP 调用计数(`mcp_calls`)。
- 报告记 `api_writes`(次数 + 端点清单)与 `mcp_calls`(MCP GitHub 调用计数),席位对照预算核验。
- 立不成 ⇒ 发现连同缘由写进报告交 PM 代立;⛔ 不查重硬立与静默弃报同为禁形。
- PM 的去重读数随派发词下发,当既有事实用,只复核其后增量,⛔ 不重跑。
- 归挂不散落:落在已排队 issue 完成范围内的发现,立成它的 sub-issue(自动进派发池)。
Expand All @@ -70,7 +69,7 @@ model: opus
5. **Contract-first。** 修复若诱使你在消费端加宽容回退(`??` 别名、宽松解析),缺陷在上游。
- 去生产者或 spec 修,或返回 `needs_decision`。
6. **issue 正文是线索,不是规格。** 动手前对 `origin/main` 核验其前提。
- 点名的文件可能移走、归因可能错、能力可能已存在。
- 文件可能移走、归因可能错、能力可能已存在;零命中配同主体同失效形态的控制词
- 带 `premise_still_valid: false`、附证据、无 PR 的报告是一等交付物;证伪 issue 是好运行。
- 把 PR 硬压在死前提上才是失败形态。

Expand All @@ -92,7 +91,7 @@ model: opus
5. ⛔ 永不按进程名杀(`pkill -f` 会带走并行 agent 的运行);记下你启动的 PID,只对它操作。
6. **整条流水线在前台跑。** build 与 test 都是本任务的步骤:阻塞运行、读真实输出、继续。
- 宿主事实:你启动的后台作业、watcher、你请求的通知都不会唤醒你;结束一轮就是结束。
- 有可展示内容即 commit、push 并开 draft PR,不等验证结束;验证结果到达即补进正文
- 有可展示内容即 commit、push 并开 draft PR,不等验证结束;验证结果到达即写进报告
- 带具名缺口的 PR 是交付进行中的常态,未读到的判决写 `NOT MEASURED: <family>, reason: …`。
- 平台事实:容器把前台命令钉在约 10 分钟上限,超时 SIGTERM 杀掉(`exit 143`)。
- 上限划定前台里放什么:重活走规则 1 的锁;仓级扫描归 CI(见本地验证范围节)。
Expand Down Expand Up @@ -299,7 +298,7 @@ model: opus
- 其余实测:构建后 grep `files[]` 所列路径找符号,带正控;符号零命中、正控命中 ⇒ 不发布。
- 本仓库:标签是真实机制,打标签是你的步骤、不是 CI 的,PR 一开出就打。
- 写入首选加法端点(REST `POST .../issues/<n>/labels`,不碰已有标签);可达性按会话探,先探后用。
- 被拒 ⇒ 走回退:MCP 读现值→并集→整组写→必做对比式读回,并申报换道
- 被拒 ⇒ 停下报 `blocked` 点名端点与状态码,⛔ 不换 MCP 写道;写后必做对比式读回
- 读回 diff 现集对 union(读集, 目标):union 有而回读缺 = 被剥的并发标签,重挂并写进报告。
- 读回只检测剥除防不了,门语义标签被剥恰成绿灯;加法写同样必要不充分。
- size-labeler 的整组 PUT 会抹掉正确的加法写;收尾一律读回、清单进报告;标签没了就重挂。
Expand Down Expand Up @@ -368,10 +367,11 @@ model: opus
"summary": "what was implemented, 2-4 sentences",
"tests": "commands run + pass/fail evidence (real output excerpts); ablation: rebuild + on-disk mutation proof",
"mcp_calls": "<n> — your MCP GitHub call count for the whole run",
"api_writes": "<n> — REST proxy writes, each endpoint listed",
"open_questions": [
{ "question": "…", "options": ["A …", "B …"], "recommendation": "A, because …" }
],
"out_of_scope_findings": ["filed as #<n>: one-line description", "noted, not filed: one-line observation"]
"out_of_scope_findings": ["to file (3 classes, dedupe words): one-liner", "noted, not filed: one-liner"]
}
```

Expand Down
16 changes: 16 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,22 @@
"Bash(curl -sS -X GET https://api.github.com/repos/objectstack-ai/objectui/commits/*/check-runs* *)",
"Bash(curl -sS -X PATCH https://api.github.com/repos/objectstack-ai/objectstack/pulls/* *)",
"Bash(curl -sS -X PATCH https://api.github.com/repos/objectstack-ai/objectui/pulls/* *)"
],
"deny": [
"mcp__github__issue_write",
"mcp__github__create_pull_request",
"mcp__github__add_issue_comment",
"mcp__github__add_comment_to_pending_review",
"mcp__github__add_reply_to_pull_request_comment",
"mcp__github__pull_request_review_write",
"mcp__github__push_files",
"mcp__github__create_or_update_file",
"mcp__github__delete_file",
"mcp__github__create_branch",
"mcp__github__sub_issue_write",
"mcp__github__merge_pull_request",
"mcp__github__create_repository",
"mcp__github__fork_repository"
]
},
"hooks": {
Expand Down
12 changes: 6 additions & 6 deletions .claude/skills/pm-dispatch/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
| `director` | 以项目总监席身份运行(人工召唤;四职见 升级与决策 节与 `references/lanes/director.md`) | — |
| `label:<name>` | backlog 过滤标签;`label:all` = 全部 open 未认领 | `pm:queue` |
| `repo:<owner/name>` | 扫哪个仓的 backlog(单 issue 的落地仓看它自己的 `repo:*` 标签) | `objectstack-ai/objectstack` |
| `batch:<n>` | 同时在飞的 dev 上限 | 默认 `3`;`n` 的维护者天花板 `5` |
| `batch:<n>` | 同时在飞的 dev 上限 | 默认 `2`;`n` 的维护者天花板 `5` |
| `rounds:<n>` | 跑 N 轮后停 | 队列清空为止 |
| `mode:subagent` \| `mode:cloud` | 派发后端 | 按卡分流:S+M ⇒ `subagent`,`cloud` 只留 L/XL 等保留面 |
| `#12 #34 …` | 显式 issue 清单,整体覆盖标签查询 | — |
Expand Down Expand Up @@ -91,10 +91,10 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报

## 全体座位的不变量

- 所有状态在 GitHub:只经 issue 标签、assignee、正文行与 `pm:seat` 座位贴读写。
- 循环必须能从全新会话恢复
- GitHub 上一切新内容用英文;中文只留四通道,含 `## 维护者速读`(受管 PR 与决策卡)
- 另三通道:轮次报告、派发令里的裁决引文、决策四维分析(评论与四棱块)。
- 状态只经 GitHub 标签、assignee、正文行与 `pm:seat` 座位贴读写;循环须能从全新会话恢复
- 用户账号仅三用:assignee、授权批准、维护者亲手;⛔ 席位与 dev 永不以用户账号写内容
- 内容恒经 REST 代理(`claude[bot]`);批准账号永不跑席位、不作席位 claude.ai 的关联用户
- GitHub 上一切新内容用英文;中文只留四通道(维护者速读、轮报、裁决引文、四维分析)。
- 裁决引文照抄不译;四维中文只管新记录,存量英文块 ⛔ 不迁移;存量中文 ⛔ 不追溯改写。
- 一座位一车道双射:域 X 谁管、PM Y 管什么,各恰好一个答案。

Expand Down Expand Up @@ -462,7 +462,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报

### 认领(先认领后动工)

- 同账号多会话共享 GitHub 身份:assignee 只回答有 agent 认领了,认领评论承载身份
- 共享身份下 assignee 只答有无认领;身份只认正文 session ID,⛔ 不认作者字段
- assignee 字段归 PM:原子对 step 1 设,dev 席恒不写它;跨账号 assignee 不是你 ⇒ 永不碰。
- 释放是显式动作:让卡离手者同笔清 assignee + `Release:` 行(会话/因/去向);下一任重新认领。
- 部分落地(PR 带 `Refs #N (item k)`,⛔ 不 `Fixes`)即释放:合入同笔回 `pm:queue` + 清 assignee。
Expand Down
6 changes: 3 additions & 3 deletions .claude/skills/pm-dispatch/references/core-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
- 状态住 GitHub 标签、assignee、正文行与座位贴;⛔ 本地零状态;循环须能从新会话恢复。
- PM ⛔ 不写文件也不写代码,唯一例外是维护者逐 PR 明示授权的 `.claude/` 内部工具 PR。
- 该例外须把授权原话引在 PR 正文并由另一座位或维护者复核,⛔ 不得自审自合。
- GitHub 上的新内容一律英文,中文只留轮次报告、派发令里的裁决引文与决策四维分析
- 裁决引文照抄不译;存量中文 ⛔ 不追溯改写
- 一座位一车道双射,每个域恰好一个 PM;与 AGENTS.md 冲突时以 AGENTS.md 为准
- 用户账号仅三用:assignee、授权批准、维护者亲手;写恒经 REST 代理;批准账号永不跑席位
- GitHub 新内容一律英文,中文只留轮次报告、派发令裁决引文与四维分析;引文照抄不译
- 存量中文 ⛔ 不追溯改写;一座位一车道双射,每域恰一 PM;与 AGENTS.md 冲突以之为准
## 状态模型
- 可派发等于 open 加队列标签加无 assignee 且不带 `pm:retriage`,已设 assignee 即 ⛔ 永不碰。
- `pm:on-hold` 仅当带机器可读 `Restart-when:` 行才合法,触发文件走 `Restart-touch:` 行。
Expand Down
2 changes: 2 additions & 0 deletions .claude/skills/pm-dispatch/references/platform-readings.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@
- ⇒ 一次调用里限定符半边算术正确、文本半边静默胡说;文本分层必跑补集与总体求和。
- 会话中途轮换凭据把 GitHub MCP 服务器杀到不可恢复:其后 `mcp__github__*` 全回 invalid session。
- 只有新会话重绑 ⇒ 轮换前提醒维护者:在飞席位丢整条 GitHub 通道。
- 文档载明未实测:`.claude/settings.json` 的 `permissions.deny` 云会话照读,deny 在任一层先于 allow。
- 被拒的 MCP 工具从工具表整个消失:工具缺席读作 deny 生效,⛔ 不读作 MCP 服务器坏。
- 配额池按身份计,换身份即清零燃烧,共享身份结构不变。
- 组织侧授权变更后仓库访问逐步传播,同一端点数分钟内 403 转 200。
- 该 403 体解析成净零 ⇒ 空车道先对 `open_issues_count` 反查再信,零命中纪律覆盖 list 读。
Expand Down
33 changes: 32 additions & 1 deletion scripts/pm/check-skill-line-ratchet.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -874,7 +874,21 @@ export const CEILINGS = new Map([
// line-neutral folds among this file's adjacent rule pairs, and re-wrap funding
// is refused per the 2026-08-17 rule in any case. Landed count, headroom 0,
// same convention.
['.claude/skills/pm-dispatch/references/platform-readings.md', 451],
// Raised 451 → 453 by the THIRTEENTH readings increment, again under the
// STANDING one-file exception quoted above rather than a fresh decision
// card, and again recorded as a `ruledRaises` record citing it. Spent at ONE
// line per deduplicated reading, each written in this file's voice, both
// from the Claude Code settings and permissions documentation and marked
// 文档载明未实测 in the file's own convention: the repository's shared
// `.claude/settings.json` `permissions.deny` is read in a cloud session
// and a deny at any scope is evaluated before every allow (+1); and its
// reading trap — a denied MCP tool is removed from the tool roster
// entirely, so a tool's absence reads as the deny working, never as a dead
// MCP server (+1) = +2 exactly. Candidates 2 / landed 2 / already present 0
// / refused 0. Nothing paid in place: the two lines sit beside the
// invalid-session pair they qualify. Landed count, headroom 0, same
// convention.
['.claude/skills/pm-dispatch/references/platform-readings.md', 453],
// Per-operation REST/GraphQL/git channel mapping — which fleet operation has
// a REST twin (each row executed in a real session, provenance date carried
// per row), the handful that are GraphQL-only, and the queue-routing
Expand Down Expand Up @@ -1495,6 +1509,23 @@ export const CROSS_FILE_MOVES = new Map([
date: '2026-09-13',
delta: 2,
},
{
// The THIRTEENTH increment, under the same STANDING exception — the
// same words again, for the same reason: a record that quotes no
// ruling is RED and each record stands alone. The +2 is accounted for
// line by line beside this entry's ceiling above; the exception's
// conditions (per-item verification and the candidate / landed /
// already-present / refused counts) are carried by the raising PR's
// body and the seat's ACCEPT.
ruling:
'the standing one-file exception for'
+ ' `.claude/skills/pm-dispatch/references/platform-readings.md` — pm-dispatch'
+ ' SKILL.md, verbatim and untranslated: 「唯一例外:`platform-readings.md`'
+ ' 增量抬上限到落地行数,免决策卡,记 `ruledRaises` 引常设裁决。条件:席位验收评论'
+ '逐条核实、去重计数(候选/落地/已有/拒收)、一事一行、不计重排」',
date: '2026-09-13',
delta: 2,
},
],
sources: [
['.claude/skills/pm-dispatch/references/lanes/cli.md', 35],
Expand Down
Loading