Skip to content

Commit edba9d2

Browse files
pm-dispatch: a project seat creates its own hourly patrol routine, bound to its session (#26067)
Fixes #25991 Clause-②: no Metadata-protocol: none ## What this changes The pm-dispatch skill said a project seat's patrol routine runs every 2–4 hours and is created by the maintainer in the claude.ai Routines UI. The maintainer's word on the ui-lane project (2026-10-26, verbatim and untranslated): > 你应该自己创建定时啊 > 为什么不是每小时 > 那需要立卡改 skills吗 > 立卡 Two points, the project-seat form only (Routine seats are untouched): 1. **Interval.** The project seat's patrol runs **hourly by default**; a lane may relax it with a reason, stated on its seat post. 2. **Who creates it.** The project seat creates its own patrol routine from inside its session, bound to that session (`create_trigger` in its default same-session mode — no `create_new_session_on_fire`, no `persistent_session_id`). The "maintainer creates it in the Routines UI" step is removed for project seats. Kept, as the triage audit on the card fixes the boundary: the zero-output warning (now scoped to the new-session `create_trigger` form) and the `send_later`-chain ban. ## The four files, line by line All four sit at their `check-skill-line-ratchet` ceiling with headroom 0. The change is **line-neutral in every file** — rewrite in place, no ceiling moved, no re-wrap, no joined lines — and every rewritten line is within the ratchet's 120-byte line cap. | File | Lines before → after | Edited line(s) | Bytes | |:--|:--|:--|:--| | `.claude/skills/pm-dispatch/SKILL.md` | 319 → 319 | 71: the 项目席唤醒 rule — one self-created, self-bound (自绑, the term `platform-readings.md` already uses) patrol routine per project, hourly by default; the old `⛔ 无自绑 cron` clause is replaced by that scoped rule; the `send_later`-chain ban stays | 120 | | `references/seat-post-protocol.md` | 91 → 91 | 58: Routine seat = maintainer in the Routines UI; project seat = self-created, self-bound. 60: zero-output warning scoped to the new-session `create_trigger` form. 65: tier and cron as UI tunables scoped to Routine seats. 66: project-seat patrol hourly by default, relaxing needs a reason and goes on the seat post — folded into the existing "the protocol does not copy the current value; the seat post is the current state" rule | 119 / 119 / 110 / 118 | | `references/seat-lifecycle.md` | 96 → 96 | 96: 每 2–4 小时 → 默认每小时 | 118 | | `references/project-forms.md` | 54 → 54 | 31: the seating step builds its own routine (自建), patrol hourly by default | 117 | Wording choices worth a reviewer's eye: - `SKILL.md:71` drops the word 事件 from `PR 订阅事件` to land at exactly 120 bytes while keeping `每项目一个` — the one-per-project guard matters more now that seats create the routine themselves. - The mechanism is spelled by contrast, not by parameter name: the project seat's routine is 自绑 (bound to its own session, the tool's default mode), and the warned-against form is the one that 开新会话 (opens a new session per fire). `platform-readings.md` already records both facts (an agent-created new-session Routine carries no GitHub tools; a self-bound trigger wakes an existing session with its tools loaded, at the cost of an orphan if that session dies — delete and recreate from the new session). - The seat-post-protocol section keeps its smoke-test and rollback lines for both forms. ## Verification - `pnpm check:pm-skill-ratchet`, `pnpm check:pm-skill-id-lint`, `pnpm check:skill-frame-sync` green on the working tree before the commit, and the full derived union on the final head below. - Control-character scan of the four files: none. - Not run locally: the `Type Check` lanes and the workflow-event-only families `dispatch-gates` marks CI-measured; the PR's check-runs are the reading for those. ### Local gate union on the final head `c4503e6c` Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` (no paths; change set taken from git off the merge base): 20 commands, each run with its exit code captured before any pipe, reconciled with `--ran`: **20 derived, 20 run, 0 NOT-MEASURED, 0 UNRUN** — every one exit 0. `check-closing-keyword-parity` (+ `--self-test`) · `check-comment-mask-corpus` · `pm/check-governed-queue-guard --self-test` · `pm/check-harness-current --self-test` · `@objectstack/lint check:doc-formula-expressions` · `check:agent-test-spelling` · `check:cross-package-test-inputs` · `check:doc-authoring` · `check:driver-memory-census` · `check:gitlink-declared` · `check:nul-bytes` · `check:pm-expected-skips` · `check:pm-governed-merges` · `check:pm-governed-prose` · `check:pm-skill-id-lint` · `check:pm-skill-ratchet` · `check:refd-timer-probe` · `check:skill-frame-sync` · `check:watch-hint-literal` Readings worth quoting: `check:pm-skill-ratchet` holds each of the four files at its ceiling with headroom 0 (319, 91, 96, 54) and every line within the 120-byte budget; `check:pm-skill-id-lint`: 88 files clean; `check:skill-frame-sync`: the one declared copy of the decision frame is internally coherent (the frame lines were not touched). `check:doc-formula-expressions` first refused with exit 3 (unbuilt `@objectstack/formula` and `@objectstack/lint`); after building the two packages under the verify lock (VERDICT command-exit 0) it ran clean. Local-only reading, not a CI family: `check:skill-frame-freshness` — the decision frame in this tree is current with `origin/main`. ## 维护者速读(草稿) **改了什么**:项目席的巡查 routine 改为席位自己在会话内创建、绑定本会话(`create_trigger` 默认模式),默认每小时;车道有理由可放宽,间隔写在座位贴。「由维护者在 Routines UI 创建」只保留给 Routine 席;「开新会话的 `create_trigger` 拿不到 GitHub 工具、零产出」的警告保留并收窄到那一种形态;`send_later` 链禁令保留。四个文件各改一到四行,行数一行不增。 **为什么改**:你 2026-10-26 在 ui 车道项目的原话:「你应该自己创建定时啊」「为什么不是每小时」「立卡」。效果:新坐席的项目车道从第一分钟就有巡查,不用等你在 Routines UI 建一次;改判答复、半态巡查、补位这些非事件驱动的待命项最多晚一小时,不再是最多四小时。 **风险与代价(含回滚)**:自绑触发器随会话生死——所绑会话一死,触发器成孤儿(平台读数已记:先删旧的、再从新会话重建,不留孤儿)。每小时唤醒比 2–4 小时多耗用量,车道可按理由放宽。回滚 = revert 本 PR 的一个 commit;各席已建的触发器由各席自己 `delete_trigger`。 **席位意见**: **你要做的**:读完 diff 给一个字——批准则由你亲手落地(受管面 `.claude/**`,本 PR 保持 draft 等你),否决则关闭。 ## Acceptance notes Observed while measuring, outside the four named lines — noted here, not filed, for the seat to route: - `references/project-forms.md:32` says the director and triage seats in one project may share one routine. A session-bound patrol trigger wakes only the session that created it, so a shared routine now wakes one seat thread; the other needs its own trigger or a poke. Not changed here (outside the card's four lines). - `references/seat-post-protocol.md:61` (model pinned in the UI; a Routine inherits the environment default model) reads as Routine-seat text after line 58's split and is left as is; a self-bound trigger keeps the bound session's tier (`platform-readings.md`, the 自绑 facts). Not a contradiction of either point. - `references/execution-duties.md:158` and `references/dispatch-runbook.md:122`, named in the dispatch as unverified candidates, were measured and contradict neither point: 158 says the project seat is woken by events and the patrol routine (consistent); 122 is the poke-trigger spelling (`create_trigger` with `persistent_session_id` plus `fire_trigger`) for message delivery, a different mechanism. `references/lanes/director.md:7` (direct-connect director seat: no Routine or cron) is about the director seat and out of scope. - The card's evidence that a session-bound trigger runs with the seat session's own tools (the ui seat's hourly trigger) is a fleet colleague's statement. The wording here rests on `platform-readings.md` (self-bound triggers wake an existing session with its tools loaded) and the `create_trigger` tool contract (the default mode fires into the calling session), not on that trigger id. --- _Generated by [Claude Code](https://claude.ai/code/session_01LqKsGyMNFwwnbF5FTAqyPn)_ Co-authored-by: os-warren <noreply@anthropic.com>
1 parent 48e84a9 commit edba9d2

4 files changed

Lines changed: 7 additions & 7 deletions

File tree

‎.claude/skills/pm-dispatch/SKILL.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
6868
- 批 = 一个上下文里读完的 ≤5 张同族卡,是质量单位,⛔ 不是预算。
6969
- 班 = 一个会话的任期,只以交接或惰性回收结束。
7070
- 席位两形:Routine 席与项目席(会话是车队项目的线程);细则见 `references/seat-lifecycle.md`。
71-
- 项目席唤醒 = PR 订阅事件 + 每项目一个巡查 routine;⛔ 无自绑 cron、无 `send_later` 链。
71+
- 项目席唤醒 = PR 订阅 + 每项目一个自建自绑的巡查 routine,默认每小时;⛔ 无 `send_later` 链。
7272
- 探针先行:fire 的第一动作是一次最便宜的车道盘点查询,⛔ 在它之前不读任何长文本。
7373
- 队列空 + 无在飞 + 无待复核 + 决策箱无新答复 ⇒ 自退。
7474
- 分诊席跑直连会话、默认判断档;直连会话按召唤跑,⛔ 无自醒不常驻;裁决归总监席。

‎.claude/skills/pm-dispatch/references/project-forms.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
- 项目聊天里的长句(「本账户坐 X;Y 的 PR 由本账户复审」)是等价写法。
2929
- 协调者每次开场把指令行与座位贴对照:逐席按 `seat-post-protocol.md` 坐席或接管。
3030
- 坐席即把本账号写进 🟢 行、每席开一条席位线程;⛔ 无花名册文件。
31-
- 首次坐席建本项目的 routine:巡逻每 2–4 小时;总监席加每日摘要与每小时收件箱扫描。
31+
- 首次坐席自建本项目的 routine:巡逻默认每小时;总监席加每日摘要与每小时收件箱扫描。
3232
- 分诊席加每小时裸卡轮;总监与分诊同在一个项目时两者可共用一个 routine。
3333
- 并发上限是维护者在该项目定的姿态;⛔ 不是协议常量,本文不写数字。
3434

‎.claude/skills/pm-dispatch/references/seat-lifecycle.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,4 @@
9393

9494
- 权威的墙信号是失败本身:撞墙报文里的重置时刻在那一刻可得、事前查不到,记下来。
9595
- 恢复 playbook 链既有规则:逐个探在飞云卡 → 直接验收兜底或 transcript 复活 → 照常跑轮。
96-
- 项目席巡查 routine 每 2–4 小时跑各车道待命项(含前提过时);撞墙记入存根,⛔ 无 cron 链。
96+
- 项目席巡查 routine 默认每小时跑各车道待命项(含前提过时);撞墙记入存根,⛔ 无 cron 链。

‎.claude/skills/pm-dispatch/references/seat-post-protocol.md‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,15 @@
5555

5656
## 座位 Routine 创建
5757

58-
- 由维护者在 claude.ai 的 Routines UI 创建,凭据随 Routine 所挂 repo sources 走。
58+
- Routine 席由维护者在 claude.ai 的 Routines UI 创建,凭据随所挂 repo sources 走;项目席自建自绑。
5959
- Routines UI 并无 GitHub 连接器入口。
60-
- 会话内 `create_trigger` 的 Routine 拿不到 GitHub 工具、零产出;⛔ 不把它当座位 Routine 在跑。
60+
- `create_trigger` 开新会话的 Routine 拿不到 GitHub 工具、零产出;⛔ 不把它当座位 Routine 在跑。
6161
- 模型不能经 API 钉住,同样在 UI 钉;Routine 继承环境默认模型,环境默认变了它跟着变。
6262
- 创建后先手动 fire 一轮烟测,判据取 GitHub 上的产出:标签写入、审计评论、座位贴编辑。
6363
- ⛔ 不取会话看起来起来了;零产出即技术性失败。
6464
- 回滚 = `delete_trigger` + 清空座位登记 + 失败注记。
65-
- 档位按职责挑,⛔ 不按重要性挑;档位与 cron 是维护者在 UI 上的可调项。
66-
- 协议文本 ⛔ 不复制其当前值,座位贴才是现状。
65+
- 档位按职责挑,⛔ 不按重要性挑;Routine 席的档位与 cron 是维护者在 UI 上的可调项。
66+
- 项目席巡查默认每小时,放宽须有理由并写座位贴;协议 ⛔ 不复制当前值,座位贴即现状。
6767

6868
## Epic 车道收尾与僵尸回收
6969

0 commit comments

Comments
 (0)