Skip to content

Commit 9697865

Browse files
committed
Merge remote-tracking branch 'origin/main' into claude/project-thread-zhlg06
2 parents 6d07608 + ea33919 commit 9697865

27 files changed

Lines changed: 1423 additions & 105 deletions
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
'@objectstack/lint': minor
3+
'@objectstack/spec': minor
4+
---
5+
6+
feat(lint)!: `objectstack validate`, `compile` and the publish gate refuse a bulk action's `confirmText` hole over an unbound root, a single-brace token, a hole holding logic and a blank sentence (#25205)
7+
8+
Clause-②: no (narrowing: a bulk action's `confirmText` that names an unbound root, carries a single-brace token, holds logic in a hole or is blank is refused at `objectstack validate`, `compile` and the publish gate; it ships now under the amended 「甲」, #6015 `6303865025`)
9+
Metadata-protocol: narrowed
10+
11+
A list-view bulk action's `confirmText` is an ADR-0032 `template` slot over a closed scope, `count` and the def's params by name (#24798). `validateStackExpressions`, the rule all three doors run, judges each one through `closedScopeTemplateRefusal`, then compiles it as a template. Its findings were warnings. They are now errors, as the flow text slots' findings are. This supersedes the warning-only behaviour described for the same pass earlier in this release line; the finding no longer ends with "A warning, not a refusal".
12+
13+
**BREAKING — what moves for consumers.**
14+
15+
- FROM: a warning at `objectstack validate` and `compile`, and an entry on the publish gate's `advisories` channel while the view or object saved. TO: an error. Both commands fail, and an active `view` or `object` write answers `422 INVALID_METADATA` with an `expression-invalid` issue located at `bulkActionDefs[N] confirmText`. The item is not stored. This covers `saveMetaItem` in publish mode (Studio, REST `/meta`, MCP) and the promotion of a draft (`publishMetaItem`).
16+
- The four refused texts: a hole over a root the def does not bind (`{{ owner }}` when the def binds `count` and `tier`), a single-brace `{x}` token, a hole holding logic or naming an unknown formatter (`{{ count * 2 }}`, `{{ count | shout }}`), and a blank sentence (`''`).
17+
18+
**Fix (one line).** Write the hole over `count` or one of the def's params (`{{ count }}`, `{{ tier }}`), double a single-brace token as the finding prescribes, move logic out of the hole, or remove a blank `confirmText` so the default sentence shows.
19+
20+
**Unchanged.**
21+
22+
- The parse. `bulkActionDefs[].confirmText` accepts what it accepted, a blank string included (its second union arm stays). The boot load and the read path judge a stored view with this parse, so a stored view carrying such a sentence keeps loading and serving until it is next saved, and that save is judged. Saving as a draft is still allowed; publishing the draft is judged.
23+
- A sentence with no finding draws nothing at any door, in either form (the bare string or the `{ dialect: 'template', source }` envelope).
24+
- `OS_ALLOW_UNLINTED_METADATA_WRITES=1` still turns a refusal into a logged write.
25+
- No public export, signature or schema shape moves. The `confirmText` describe now says the texts are refused.
26+
- Measured before crossing, through the built `@objectstack/lint` at `925fd0772c`: 0 in-repo producers carry such a sentence. The 6 bulk defs with a `confirmText` in `examples/app-showcase` (`project.view.ts`) draw 0 findings, against 1 for a planted unbound hole. HotCRM at `1e71d5e` declares 3 bulk `confirmText` sentences on `account.view.ts` (`{{count}}`, and `{{tier}}` on the def whose param is `tier`), all over bound roots: 0 findings. Its other 9 of the 12 are translations of those 3 in its locale bundles, which this pass does not read.
27+
28+
<!-- adr-0087: not-required (no-migration-prescription) a refusal at `objectstack validate`, `compile` and the publish gate of a bulk action `confirmText` naming an unbound root, carrying a single-brace token, holding logic in a hole, or blank: no authorable key, spelling, export or stored shape moves, the parse is unchanged, and no stored row is read, rewritten or converted. A stored view whose sentence is refused keeps loading until it is next saved, and the repair is the author's rewrite of the sentence (which root a hole should name is the author's intent), which no ledger entry can derive. The other categories are closed on facts: the packages publish (not unpublished); no ADR-0087 id covers this verdict (not already-registered); and the change is a build and door verdict, not a declaration (not runtime-interface-only or type-surface-only). -->

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,14 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
4646

4747
## 入口与角色
4848

49-
`/pm-dispatch [args]`,自由组合,全部可选:
49+
`/pm-dispatch [args]` 或项目指令行 `pm-dispatch <席位…>`,自由组合,全部可选:
5050

5151
| arg | 含义 | 默认 |
5252
|---|---|---|
5353
| `triage` | 以分诊座位身份运行(只扫/分类/路由,永不认领) | — |
54-
| `<domain>`(如 `spec`、`skills`) | 以该 `domain:*` 车道的执行座位身份运行;承办该车道的项目即「车道项目」 | — |
54+
| `<domain>`(如 `spec`、`skills`) | 以该 `domain:*` 车道的执行座位身份运行;承办它的是坐该席的车队项目 | — |
5555
| `epic:#<n>` | 以父单 #n 的 epic PM 身份运行(见 `references/seat-lifecycle.md` 〈Epic 子树车道〉) | — |
56-
| `director` | 以总监席身份运行(人工召唤;所在项目即「总监项目」;三职与章程见 `references/lanes/director.md`) | — |
56+
| `director` | 以总监席身份运行(人工召唤,任一车队项目可召;三职与章程见 `references/lanes/director.md`) | — |
5757
| `coordinator` | 以协调者身份运行(项目会话:开席位线程与卡线程、跨车道调度;接口见 `references/coordinator.md`) | — |
5858
| `label:<name>` | backlog 过滤标签;`label:all` = 全部 open 未认领 | `pm:queue` |
5959
| `repo:<owner/name>` | 扫哪个仓的 backlog(单 issue 的落地仓看它自己的 `repo:*` 标签) | `objectstack-ai/objectstack` |
@@ -68,7 +68,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
6868
- fire = 一次唤醒;fire 到达时上一轮未清空的接续处理,⛔ 不重开、不重排。
6969
- 批 = 一个上下文里读完的 ≤5 张同族卡,是质量单位,⛔ 不是预算。
7070
- 班 = 一个会话的任期,只以交接或惰性回收结束。
71-
- 席位两形:Routine 席与项目席(会话是车道项目的线程);细则见 `references/seat-lifecycle.md`。
71+
- 席位两形:Routine 席与项目席(会话是车队项目的线程);细则见 `references/seat-lifecycle.md`。
7272
- 项目席唤醒 = PR 订阅事件 + 每项目一个巡查 routine;⛔ 无自绑 cron、无 `send_later` 链。
7373
- 探针先行:fire 的第一动作是一次最便宜的车道盘点查询,⛔ 在它之前不读任何长文本。
7474
- 队列空 + 无在飞 + 无待复核 + 决策箱无新答复 ⇒ 自退。
@@ -80,6 +80,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
8080
| 文件 | 谁在哪个 fire 读 | 承载的章节 |
8181
|:--|:--|:--|
8282
| `references/seat-lifecycle.md` | 每个座位每次 fire:开轮互斥读数前、收班前 | 开轮互斥 · 座位贴协议 · Epic 子树车道 · 轮次报告与节奏 · 停止条件与待命 · 断粮与跨墙恢复 |
83+
| `references/project-forms.md` | 协调者每次开场;席位坐席、接管、移交、开信箱 PR 前 | 一种项目形态 · 指令行即召唤 · 席位是读出来的 · 接管 · 信箱 PR · 总表 |
8384
| `references/reading-discipline.md` | 任一座位取读数、引读数或核验 main 的那一刻 | 平台读数纪律 |
8485
| `references/cross-repo-coordination.md` | 分诊席路由与查重前;执行席跨仓认领、派发或转移时 | 多仓协调 |
8586
| `references/triage-duties.md` | 分诊席每次 fire 开局 | 分诊座位职责 |
@@ -95,7 +96,6 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
9596
- 席位及其子代理 ⛔ 永不打印环境变量的值;判存在只用不印值的形式 `[ -n "${X+x}" ]`。
9697
- GitHub 上一切新内容用英文;中文只留四通道(维护者速读、轮报、裁决引文、四维分析)。
9798
- 裁决引文照抄不译;四维中文只管新记录,存量英文块 ⛔ 不迁移;存量中文 ⛔ 不追溯改写。
98-
- 一 PM 恰管一车道,一车道由一组座位管,一席一贴;PM Y 管什么恰一个答案。
9999

100100
## 状态模型
101101

‎.claude/skills/pm-dispatch/references/lanes/director.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
## 授权与形态
66

7-
- 授权面 = 人工定期召唤,处理 contract-review 与需决裁项;⛔ 无 Routine、无 cron、无舰队位。
7+
- 授权面 = 人工召唤,任一项目可召;处理 contract-review 与需决裁项;直连 ⛔ 无 Routine/cron。
88
- 只出裁决不持在飞状态:多场并行、无交班,新场不等不停不替,⛔ 无接管无在任者。
99
- 裁决只存在于本卡:聊天原话、台账行、他卡引述 ⛔ 都不是裁决;先记卡再动标签。
1010
- 同卡同笔只一场写,线程即顺序、后记者胜,裁前先读线程。
@@ -13,7 +13,7 @@
1313
- 裁决记录同笔写明所选字母的工作量,读数取自卡面工作量列。
1414
- 划掉原 ⛔ 不派断言,走 `post-stamped --body --ack-through`;漏此笔 ⇒ 接卡者先读正文退决策箱。
1515
- 入口:维护者说处理决裁或处理 contract-review,或 `/pm-dispatch director`。
16-
- 未回字 = 不在 = 停,⛔ 无巡检、审计、快照、聊天、卡评论;⛔ 无任何例外。
16+
- 未回字 = 不在 = 停,⛔ 无巡检、审计、快照、聊天、卡评论;例外 = `../project-forms.md` 例行。
1717
- 回来后先补跑审计与重挂复位一次,再只发一行「批 #N 待字;箱内另有 K 张新到未呈」。
1818
- 开场读一次服役档记入会话审计行,读法见 `../platform-readings.md`;⛔ 不因档位拒裁停三职。
1919
- 双射 carve-out:一张 `pm:seat` 座位贴,四段照旧;状态块逐场一行,各记己锚,⛔ 无占席人。
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# 车队项目(项目形态)
2+
3+
协调者每次开场读本文;坐席、接管、移交、开信箱 PR 前再读。本文是席位之上的项目层。
4+
5+
## 一种项目形态
6+
7+
- 车队项目 = 任一账号上、指令行指向 pm-dispatch 的 Claude Code 项目;⛔ 不分项目类型。
8+
- 项目做什么只由它坐的席位决定;车道席、总监席、分诊席都是席位,由维护者召唤。
9+
- 车道席:认领、派发、PR、跨账号复审;总监席:决策箱与决裁批、发版、日报、总表。
10+
- 分诊席:只写标签与审计评论;分诊与总监可召进任一项目,⛔ 不绑定项目。
11+
- 唯一不变量在账号不在项目:批准账号永不跑席位(SKILL.md 全体座位的不变量);本文不另加。
12+
- 规则与指派只写角色词(总监账户、车道账户);登录名只在裁决记录里作既往事件的证据。
13+
14+
## 指令行即召唤
15+
16+
- 项目指令只有一行:`pm-dispatch <席位> [<席位>…]`,如 `pm-dispatch 总监`、`pm-dispatch ui skills`。
17+
- 首词恒为技能目录名 `pm-dispatch`;⛔ 不用 `fleet`,它已是 bot 与中继的名字。
18+
- 席位词 = 中文名或车道文件名:总监 = `lanes/director.md`,分诊 = `lanes/triage.md`。
19+
- 其余席位词同 `lanes/<lane>.md` 文件名:ui、skills、devx、server、spec、hotcrm。
20+
- 一车道多席:协调者取 🟢 行写本账号的那一席;无则取空席;再无则问维护者一次。
21+
- 其余一切住本文:⛔ 不往项目里贴模板;⛔ 不在账号层复制技能。
22+
23+
## 席位是读出来的,不是配出来的
24+
25+
- 项目的席位 = 🟢 行写本账号的座位贴(车道、总监、分诊同此);派发前先读座位贴。
26+
- 一张也没有 ⇒ 项目闲置;每席恰一条席位线程、恰一车道,一席一贴。
27+
- 指令行就是指派:维护者在项目里写下或改写这一行,是唯一的指派动作。
28+
- 项目聊天里的长句(「本账户坐 X;Y 的 PR 由本账户复审」)是等价写法。
29+
- 协调者每次开场把指令行与座位贴对照:逐席按 `seat-post-protocol.md` 坐席或接管。
30+
- 坐席即把本账号写进 🟢 行、每席开一条席位线程;⛔ 无花名册文件。
31+
- 首次坐席建本项目的 routine:巡逻每 2–4 小时;总监席加每日摘要与每小时收件箱扫描。
32+
- 分诊席加每小时裸卡轮;总监与分诊同在一个项目时两者可共用一个 routine。
33+
- 并发上限是维护者在该项目定的姿态;⛔ 不是协议常量,本文不写数字。
34+
35+
## 接管不等撞墙账号
36+
37+
- 🟢 行写着别的账号 ⇒ 指令行即维护者强制接管令,含在飞卡。
38+
- 撞墙账号写不出任何东西,接管永不等它的注记或简报。
39+
- 跨账号 `Release:` 点名旧会话与出处三件;新 `Claim:` 带 `Resume-from: BRANCH@SHA`,新 dev 续旧分支。
40+
- 四件形状见 `execution-duties.md` 认领节;台账 = 标签 + assignee + `Claim:` + `head:claude/` PR。
41+
- 台账按 `assignee:<旧登录名>` 读;⛔ 项目记忆与共享目录永不是台账,只是本账号的缓存。
42+
43+
## 信箱 PR
44+
45+
- 绑 PR 的对话不需要新东西:卡线程订阅自己的 PR,评论即唤醒。
46+
- 非 PR 对话:每项目至多一个 draft PR,标签 `pm:mailbox`,分支 `mailbox/<login>`,由常驻线程订阅。
47+
- 永不合并,移交或换账号时关闭;正文首行 `To: <login>`。
48+
- `pm:mailbox` PR 不欠 CI,一切落地与台账查询排除它。
49+
50+
## 总表
51+
52+
- objectstack 置顶 issue「车队总表」,一席一行;正文由总监席日报与坐席/接管/移交重生成。
53+
- 行 = 仓 · 车道 · 席 · 账号 · 在飞 · 待裁 · 待落地 · 撞墙注记 · 最近动静 · 信箱 PR。
54+
- 读自座位贴、标签、assignee 与 PR 查询;生成视图 ⛔ 不手改(`cross-repo-coordination.md` 规则 5)。

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
- 存根外的姿态、台账与轮报住项目;标题、assignee、坐席审计评论与跨账号移交简报照旧。
2828
- 正文只由在任座位 PM 编辑且为权威;标题与 assignee 是派生视图,三者同笔更新。
2929
- 标题只放慢状态,快状态留在说明段。
30-
- 维护者强制接管令取席位、队列、未起工卡与待落地 PR;⛔ 不取在飞卡,由原认领者跟完。
30+
- 维护者强制接管令取席位、队列、在飞卡、未起工卡与待落地 PR;⛔ 不等原认领者注记。
3131
- 子代理 dev 的返回消息、探活与续派只在派发会话;落地或 `Release:` 后归新席位。
3232
- 范围与常设承诺是岗位说明不是状态,版本化在 `references/lanes/<lane>.md`。
3333
- 贴内只放指向车道文件的指针,升级走技能 PR,⛔ 不手抄接力。
@@ -67,7 +67,7 @@
6767
## 轮次报告与节奏
6868

6969
- 每轮向维护者打中文轮次报告(chat 通道):issue → 判决 → PR 链接 → 备注的表。
70-
- 项目席轮报 = 卡线程清单,⛔ 不逐轮发聊天表;五项健康指标进总监项目的每日摘要。
70+
- 项目席轮报 = 卡线程清单,⛔ 不逐轮发聊天表;五项健康指标进总监席的每日摘要。
7171
- 报告加升级项、呈裁清单、awaiting a human merge 项、逐 PR 熔断命中项(无则 none)。
7272
- 报告含 `UNRECOGNISED` 行:对本轮门禁日志 grep `UNRECOGNISED` 逐行照录,`NOT APPLICABLE` 行也在内。
7373
- 健康指标五个:可派发库存(open `pm:queue` 未认领及趋势);决策箱(待维护者数)。

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
- 状态词表:`🟢 <github-login>` 在任、`🟢 Routine`、`⏳ vacant`、`⏸️ paused`。
1111
- assignee = 在任 PM 的 GitHub 账号,退场或回收时摘除;无 assignee = 空缺,与标题互为校验。
1212
- 例外:Routine 座位的 bot 身份通常不可被 assign,以标题为准。
13-
- 多场席(总监):`🟢` 后写召唤账号,状态块逐场一行(会话 ID + 锚);无在任者、无接管。
13+
- 直连多场总监席:`🟢` 后写召唤账号,逐场一行;项目席 🟢 即指派,接管见 `project-forms.md`。
1414
- 当前 PM 段登记三元:GitHub 账号(`get_me` 自查)、会话 ID 或 Routine ID、上任时刻。
1515
- 审计与认领评论的作者字段是平台盖章的硬读数,接管仲裁与活性判定优先用它对账正文。
1616
- 班次叙事 ⛔ 不进贴正文:逐卡状态在卡与 PR 上必填,轮次合计走轮次报告。

0 commit comments

Comments
 (0)