Skip to content

Commit 77adf29

Browse files
os-zhuangclaude
andauthored
docs(skills): 已发布 skill objectstack-pm-dispatch 的决策框架由两轴升为三轴(#5451) (#5799)
#5130 把内部 agent 协议的决策评估轴由两条扩为三条,但同一套框架在已发布目录里还有 一份镜像 —— `skills/objectstack-pm-dispatch/SKILL.md`(#4607 发布,第三方可 `npx skills add` 安装),它仍是两轴。#5130 刻意把范围钉在 `.claude/`(改发布内容是 用户可见变更),本单补齐,两份文本重新同构。 维护者 2026-08-06 裁决 B(泛化内核后搬): - 新增 Axis ①「real business need」,排在两条原有轴之前 —— 每个方案先问它服务的是 真实存在的业务场景还是投机性能力面;判据要求实测而非推断;无拉动的声明面按 implementation-first 处置(收窄声明使 `declared = enforced`,而不是为声明补实现); 已发布但零消费的能力不因沉没成本获得豁免。并写明这条轴会改变结论。原两轴原文保留, 仅编号后移为 Axis ② / ③。 - 泛化纪律:去掉内部版的「我们是一个创业项目」自我描述,不带入本仓专属先例单号; 扩张姿态改由安装方项目自己的 conventions 文件声明,接进该 skill 既有的 config-over-hardcoding 机制(`conventionsFile` 说明 + Adapting 表格各一处)。 - 全文 7 处两轴措辞逐处升三轴,含嵌入的 dev-agent 模板两处;仅保留一处 `the other two axes`(指 Axis ② / ③ 这「另外两条」,三轴语境下的正确表述)。 - `metadata.version` 1.0 → 1.1。 空 frontmatter changeset 沿 #4607 与 #5130 同一先例:`skills/` 不随任何 npm 包发布, 没有包可署名。 Fixes #5451 Co-authored-by: Claude <noreply@anthropic.com>
1 parent fb3d99b commit 77adf29

2 files changed

Lines changed: 88 additions & 14 deletions

File tree

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
---
2+
---
3+
4+
docs(skills): 已发布 skill `objectstack-pm-dispatch` 的决策框架由两轴升为三轴 —— 新增「实际业务需求」轴,内核泛化后搬 (#5451)
5+
6+
#5130 把内部 agent 协议的决策评估轴由两条扩为三条,但同一套框架在**已发布目录**里还有
7+
一份镜像 —— `skills/objectstack-pm-dispatch/SKILL.md`(#4607 发布,`metadata.domain:
8+
process`,无 `metadata.internal`,第三方 ObjectStack 项目可 `npx skills add` 安装),
9+
它仍是两轴。#5130 刻意把范围钉在 `.claude/`(改发布内容是用户可见变更),本单补齐,
10+
两份文本重新同构。
11+
12+
维护者 2026-08-06 在 #5451 裁决 **B(泛化内核后搬)**,而不是原样搬或不搬:
13+
14+
- **新增 Axis ①「real business need」,排在两条原有轴之前**——每个方案先问它服务的是
15+
真实存在的业务场景还是投机性能力面;判据要求**实测而非推断**(谁在写这个键、谁在读
16+
这个能力、示例应用与真实部署里的用法),「读起来像有用」不作数;无拉动的声明面按
17+
**implementation-first** 处置(收窄声明使 `declared = enforced`,或让词表随未来实现
18+
回归),而不是为声明补实现;**已发布但零消费的能力不因沉没成本获得豁免**。并写明这条
19+
轴会**改变结论**:技术形状相同的两个发现可以仅凭这条轴得出相反裁决(一个因无业务拉动
20+
退役,另一个因真实应用自证方向而裁「响亮拒绝而非退役」),只看后两条轴会得出同一个
21+
答案。原两轴(项目长远合理性、防 AI 写代码/写元数据 app 犯错)**原文保留**,仅编号后
22+
移为 Axis ② / ③。
23+
- **泛化纪律**:去掉内部版绑定的「我们是一个创业项目」自我描述,也不带入本仓专属先例
24+
单号 —— 发布版是 project-agnostic 的,把我们的处境写进别人的决策机器,会让安装方的
25+
PM agent 按错误前提做决策。**扩张姿态改由安装方项目自己的 conventions 文件声明**
26+
(核心面尚在成形时从紧、平台面稳定后放宽),接进该 skill 既有的 config-over-hardcoding
27+
机制:`conventionsFile` 配置项说明与「Adapting this loop to your project」表格各加
28+
一处,与分支命名、release-note 产物、测试命令走同一条覆写路径。
29+
- 全文 7 处两轴措辞逐处升三轴:分诊一节的 `the deep two-axis`、升级流程的
30+
`the two fixed axes below`、`#### The two-axis decision frame (binding)` 标题、
31+
框架首句与收尾句的 `**both** axes`,以及**嵌入的 dev-agent 模板**里的
32+
`Analyze every option on two fixed axes:` 与 `Justify your recommendation on both
33+
axes`。模板那两处是关键:PM 按三轴呈报而开发 agent 按两轴上报,业务轴每次都要 PM 事后
34+
补。文中仅保留一处 `the other two axes`,指的是 Axis ② / ③ 这「另外两条」,是三轴语境
35+
下的正确表述。
36+
- `metadata.version` 1.0 → 1.1:已安装 1.0 的第三方据此看到这是一次内容修订。
37+
38+
**空 frontmatter 是刻意的,不是遗漏**,沿 #4607 发布 PR 与 #5130 的同一先例:`skills/`
39+
不随任何 npm 包发布(没有 package 的 `files` 含它,分发路径是 `npx skills add` 直读
40+
仓库),因此没有包可署名 —— 署一个包会凭空造出一条其发布物未变更的 release 记录,并把
41+
PM skill 的说明塞进那个包的 CHANGELOG。本次变更对**装这份 skill 的人**可见,但不发布
42+
任何包。

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

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ compatibility: >
2222
(MCP server) with issue/label/PR write access.
2323
metadata:
2424
author: objectstack-ai
25-
version: "1.0"
25+
version: "1.1"
2626
domain: process
2727
tags: pm, dispatch, backlog, triage, multi-agent, delivery, github, escalation, upstream
2828
---
@@ -99,7 +99,7 @@ single-repository project work with no configuration at all.
9999
| `repos` | `string[]` | `[backlogRepo]` | Every repository work may land in. Used for label setup and for validating routing labels. |
100100
| `batch` | `number` | `3` | Maximum developer agents in flight at once. |
101101
| `mode` | `"subagent" \| "cloud"` | `"subagent"` | Dispatch backend — see [Dispatch backends](#dispatch-backends). |
102-
| `conventionsFile` | `string` | first existing of `AGENTS.md`, `CLAUDE.md`, `CONTRIBUTING.md` | Repository-relative path to the file that defines gates, branch rules, release-note artifacts and review policy. Injected by path into every dispatch. |
102+
| `conventionsFile` | `string` | first existing of `AGENTS.md`, `CLAUDE.md`, `CONTRIBUTING.md` | Repository-relative path to the file that defines gates, branch rules, release-note artifacts, review policy and the capability-expansion stance. Injected by path into every dispatch. |
103103
| `routingLabelPrefix` | `string` | `"repo:"` | Prefix of the labels that route an issue to a non-default repository, e.g. `repo:hotcrm-web`. Inert when `repos` has one entry. |
104104

105105
**Unknown keys are an error, not a hint.** If the file contains a key not in
@@ -182,7 +182,7 @@ classify each:
182182
- **Maintainer confirm (`needs-user-decision`)** — design cards, feature or
183183
contract-shape proposals, multi-week programs needing appetite and
184184
sequencing, anything touching stored-data migration shape or removing a
185-
shipped capability. The label alone is the inbox entry; the deep two-axis
185+
shipped capability. The label alone is the inbox entry; the deep three-axis
186186
analysis is written when the card is actually taken up.
187187
- **Repair first** — a body truncated by GitHub's sanitizer cannot be
188188
dispatched. Comment the repair instruction and move on.
@@ -449,23 +449,44 @@ When something *does* pass the bar:
449449
no issue of its own.
450450
2. Write the analysis with: background, the precise question, the options, your
451451
recommendation, and the related issues / PRs / branches — **and analyze
452-
every option on the two fixed axes below.**
452+
every option on the three fixed axes below.**
453453
3. If the session is interactive, additionally ask the maintainer directly; the
454454
labeled issue remains the durable record either way. **Never** answer a
455455
product or architecture question on the maintainer's behalf.
456456

457-
#### The two-axis decision frame (binding)
458-
459-
Every option in an escalation is analyzed on **both** axes. This framing is the
460-
core of the escalation, not decoration.
461-
462-
**Axis ① — long-term architectural soundness for *this* project.** Which option
457+
#### The three-axis decision frame (binding)
458+
459+
Every option in an escalation is analyzed on **all three** axes. This framing is
460+
the core of the escalation, not decoration.
461+
462+
**Axis ① — real business need.** Does this option serve a business scenario that
463+
**actually exists**, or a speculative capability surface? Ask it of every option
464+
*first*, before the architecture argument, because it can retire the question
465+
instead of answering it. The evidence must be **measured, not inferred**: who
466+
writes this key, who reads this capability, how the project's example apps and
467+
real deployments use it today. "It reads like it would be useful" does not
468+
count — and neither does "we already shipped it": a **shipped-but-unconsumed
469+
capability gets no sunk-cost exemption**. A declared surface with no pull is
470+
handled **implementation-first** — narrow the declaration until
471+
`declared = enforced` (retire it, or park the vocabulary and let it return with
472+
the implementation) rather than building implementation to justify a declaration
473+
nobody asked for. **How tight that default should be is your project's call, not
474+
this skill's:** declare the capability-expansion stance in your conventions file —
475+
tight while the core surface is still forming, more permissive once it is
476+
stable — and this axis reads it from there, like every other project-specific
477+
rule. This axis **changes verdicts** rather than decorating them: two findings
478+
of identical technical shape can be ruled opposite ways on it alone — one
479+
declared surface retired for lack of pull, another kept and made to *reject
480+
loudly* because a real app proved the direction. On the other two axes they
481+
would read the same, and that would be the wrong answer.
482+
483+
**Axis ② — long-term architectural soundness for *this* project.** Which option
463484
matches where the project is going and a sustainable architecture — no
464485
workarounds, contract-first — rather than which is cheapest today. **Name the
465486
long-term cost of any patch-style option explicitly.** "We can special-case it
466487
here" is a valid option only when its future removal cost is stated.
467488

468-
**Axis ② — making AI-authored code structurally hard to get wrong**, and
489+
**Axis ③ — making AI-authored code structurally hard to get wrong**, and
469490
especially AI-authored ObjectStack **metadata**. Prefer the option that
470491
prevents the mistake at authoring time — a strict schema, publish-time
471492
validation that rejects loudly, declared = enforced — over consumer-side
@@ -475,7 +496,7 @@ reader turns a whole generation of wrong metadata into something that "works"
475496
until it does not. Never let an agent declare a capability the runtime does not
476497
honour.
477498

478-
Your recommendation must be justified on **both** axes. If they conflict,
499+
Your recommendation must be justified on **all three** axes. If they conflict,
479500
present the trade-off honestly and let the maintainer decide.
480501

481502
### 9. Round report, then next round
@@ -571,7 +592,17 @@ or two readings of the issue lead to different architectures: make no guess,
571592
write no speculative code. Return status "needs_decision" with each question,
572593
the options, their costs, and your recommendation in open_questions. A wrong
573594
guess shipped is far more expensive than a round-trip to the maintainer.
574-
Analyze every option on two fixed axes:
595+
Analyze every option on three fixed axes:
596+
- Real business need — does the option serve a business scenario that ACTUALLY
597+
EXISTS, or a speculative capability surface? Ask this first. The evidence must
598+
be MEASURED, not inferred: who writes this key, who reads this capability, how
599+
the project's example apps and real deployments use it today. "It reads like it
600+
would be useful" does not count, and a shipped-but-unconsumed capability gets
601+
no sunk-cost exemption. A declared surface with no pull is handled
602+
implementation-first — narrow the declaration until declared = enforced
603+
(retire it, or park the vocabulary until the implementation arrives) rather
604+
than building implementation to justify the declaration. How tight the default
605+
is comes from the project's conventions file, not from this template.
575606
- Long-term architectural soundness for THIS project — which option matches a
576607
sustainable architecture (no workarounds, contract-first), not which is
577608
cheapest today. Name the long-term cost of any patch-style option.
@@ -580,7 +611,7 @@ Analyze every option on two fixed axes:
580611
publish-time validation that rejects loudly, declared = enforced) over
581612
consumer-side tolerance. Lenient consumers are where AI-generated errors hide
582613
and multiply.
583-
Justify your recommendation on both axes; if they conflict, present the
614+
Justify your recommendation on all three axes; if they conflict, present the
584615
trade-off and let the maintainer decide.
585616
586617
Return "blocked" (with evidence) when the default branch is broken under you, a
@@ -799,6 +830,7 @@ them into every dispatch:
799830
| Files owned by a release process that a code PR must never touch | conventions file |
800831
| Test / typecheck / lint commands per package | conventions file |
801832
| Merge policy (merge queue, serial merge, maintainer-only) | conventions file |
833+
| Capability-expansion stance the business-need axis reads (tight by default, or permissive) | conventions file |
802834
| Which repositories exist and which is the backlog | `.claude/pm-dispatch.json` |
803835
| Recorded architecture decisions the escalation bar defers to | the project's ADR directory |
804836

0 commit comments

Comments
 (0)