From 890f8156d4548ccafb23390d865e7c0392f1735d Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 6 Aug 2026 05:54:33 +0000 Subject: [PATCH] =?UTF-8?q?docs(skills):=20=E5=B7=B2=E5=8F=91=E5=B8=83=20s?= =?UTF-8?q?kill=20`objectstack-pm-dispatch`=20=E7=9A=84=E5=86=B3=E7=AD=96?= =?UTF-8?q?=E6=A1=86=E6=9E=B6=E7=94=B1=E4=B8=A4=E8=BD=B4=E5=8D=87=E4=B8=BA?= =?UTF-8?q?=E4=B8=89=E8=BD=B4(#5451)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #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 --- ...d-pm-dispatch-three-axis-decision-frame.md | 42 +++++++++++++ skills/objectstack-pm-dispatch/SKILL.md | 60 ++++++++++++++----- 2 files changed, 88 insertions(+), 14 deletions(-) create mode 100644 .changeset/published-pm-dispatch-three-axis-decision-frame.md diff --git a/.changeset/published-pm-dispatch-three-axis-decision-frame.md b/.changeset/published-pm-dispatch-three-axis-decision-frame.md new file mode 100644 index 0000000000..576903a019 --- /dev/null +++ b/.changeset/published-pm-dispatch-three-axis-decision-frame.md @@ -0,0 +1,42 @@ +--- +--- + +docs(skills): 已发布 skill `objectstack-pm-dispatch` 的决策框架由两轴升为三轴 —— 新增「实际业务需求」轴,内核泛化后搬 (#5451) + +#5130 把内部 agent 协议的决策评估轴由两条扩为三条,但同一套框架在**已发布目录**里还有 +一份镜像 —— `skills/objectstack-pm-dispatch/SKILL.md`(#4607 发布,`metadata.domain: +process`,无 `metadata.internal`,第三方 ObjectStack 项目可 `npx skills add` 安装), +它仍是两轴。#5130 刻意把范围钉在 `.claude/`(改发布内容是用户可见变更),本单补齐, +两份文本重新同构。 + +维护者 2026-08-06 在 #5451 裁决 **B(泛化内核后搬)**,而不是原样搬或不搬: + +- **新增 Axis ①「real business need」,排在两条原有轴之前**——每个方案先问它服务的是 + 真实存在的业务场景还是投机性能力面;判据要求**实测而非推断**(谁在写这个键、谁在读 + 这个能力、示例应用与真实部署里的用法),「读起来像有用」不作数;无拉动的声明面按 + **implementation-first** 处置(收窄声明使 `declared = enforced`,或让词表随未来实现 + 回归),而不是为声明补实现;**已发布但零消费的能力不因沉没成本获得豁免**。并写明这条 + 轴会**改变结论**:技术形状相同的两个发现可以仅凭这条轴得出相反裁决(一个因无业务拉动 + 退役,另一个因真实应用自证方向而裁「响亮拒绝而非退役」),只看后两条轴会得出同一个 + 答案。原两轴(项目长远合理性、防 AI 写代码/写元数据 app 犯错)**原文保留**,仅编号后 + 移为 Axis ② / ③。 +- **泛化纪律**:去掉内部版绑定的「我们是一个创业项目」自我描述,也不带入本仓专属先例 + 单号 —— 发布版是 project-agnostic 的,把我们的处境写进别人的决策机器,会让安装方的 + PM agent 按错误前提做决策。**扩张姿态改由安装方项目自己的 conventions 文件声明** + (核心面尚在成形时从紧、平台面稳定后放宽),接进该 skill 既有的 config-over-hardcoding + 机制:`conventionsFile` 配置项说明与「Adapting this loop to your project」表格各加 + 一处,与分支命名、release-note 产物、测试命令走同一条覆写路径。 +- 全文 7 处两轴措辞逐处升三轴:分诊一节的 `the deep two-axis`、升级流程的 + `the two fixed axes below`、`#### The two-axis decision frame (binding)` 标题、 + 框架首句与收尾句的 `**both** axes`,以及**嵌入的 dev-agent 模板**里的 + `Analyze every option on two fixed axes:` 与 `Justify your recommendation on both + axes`。模板那两处是关键:PM 按三轴呈报而开发 agent 按两轴上报,业务轴每次都要 PM 事后 + 补。文中仅保留一处 `the other two axes`,指的是 Axis ② / ③ 这「另外两条」,是三轴语境 + 下的正确表述。 +- `metadata.version` 1.0 → 1.1:已安装 1.0 的第三方据此看到这是一次内容修订。 + +**空 frontmatter 是刻意的,不是遗漏**,沿 #4607 发布 PR 与 #5130 的同一先例:`skills/` +不随任何 npm 包发布(没有 package 的 `files` 含它,分发路径是 `npx skills add` 直读 +仓库),因此没有包可署名 —— 署一个包会凭空造出一条其发布物未变更的 release 记录,并把 +PM skill 的说明塞进那个包的 CHANGELOG。本次变更对**装这份 skill 的人**可见,但不发布 +任何包。 diff --git a/skills/objectstack-pm-dispatch/SKILL.md b/skills/objectstack-pm-dispatch/SKILL.md index 3af57781c9..0cc704f1f6 100644 --- a/skills/objectstack-pm-dispatch/SKILL.md +++ b/skills/objectstack-pm-dispatch/SKILL.md @@ -22,7 +22,7 @@ compatibility: > (MCP server) with issue/label/PR write access. metadata: author: objectstack-ai - version: "1.0" + version: "1.1" domain: process tags: pm, dispatch, backlog, triage, multi-agent, delivery, github, escalation, upstream --- @@ -99,7 +99,7 @@ single-repository project work with no configuration at all. | `repos` | `string[]` | `[backlogRepo]` | Every repository work may land in. Used for label setup and for validating routing labels. | | `batch` | `number` | `3` | Maximum developer agents in flight at once. | | `mode` | `"subagent" \| "cloud"` | `"subagent"` | Dispatch backend — see [Dispatch backends](#dispatch-backends). | -| `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. | +| `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. | | `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. | **Unknown keys are an error, not a hint.** If the file contains a key not in @@ -182,7 +182,7 @@ classify each: - **Maintainer confirm (`needs-user-decision`)** — design cards, feature or contract-shape proposals, multi-week programs needing appetite and sequencing, anything touching stored-data migration shape or removing a - shipped capability. The label alone is the inbox entry; the deep two-axis + shipped capability. The label alone is the inbox entry; the deep three-axis analysis is written when the card is actually taken up. - **Repair first** — a body truncated by GitHub's sanitizer cannot be dispatched. Comment the repair instruction and move on. @@ -449,23 +449,44 @@ When something *does* pass the bar: no issue of its own. 2. Write the analysis with: background, the precise question, the options, your recommendation, and the related issues / PRs / branches — **and analyze - every option on the two fixed axes below.** + every option on the three fixed axes below.** 3. If the session is interactive, additionally ask the maintainer directly; the labeled issue remains the durable record either way. **Never** answer a product or architecture question on the maintainer's behalf. -#### The two-axis decision frame (binding) - -Every option in an escalation is analyzed on **both** axes. This framing is the -core of the escalation, not decoration. - -**Axis ① — long-term architectural soundness for *this* project.** Which option +#### The three-axis decision frame (binding) + +Every option in an escalation is analyzed on **all three** axes. This framing is +the core of the escalation, not decoration. + +**Axis ① — real business need.** Does this option serve a business scenario that +**actually exists**, or a speculative capability surface? Ask it of every option +*first*, before the architecture argument, because it can retire the question +instead of answering it. The evidence must be **measured, not inferred**: who +writes this key, who reads this capability, how the project's example apps and +real deployments use it today. "It reads like it would be useful" does not +count — and neither does "we already shipped it": a **shipped-but-unconsumed +capability gets no sunk-cost exemption**. A declared surface with no pull is +handled **implementation-first** — narrow the declaration until +`declared = enforced` (retire it, or park the vocabulary and let it return with +the implementation) rather than building implementation to justify a declaration +nobody asked for. **How tight that default should be is your project's call, not +this skill's:** declare the capability-expansion stance in your conventions file — +tight while the core surface is still forming, more permissive once it is +stable — and this axis reads it from there, like every other project-specific +rule. This axis **changes verdicts** rather than decorating them: two findings +of identical technical shape can be ruled opposite ways on it alone — one +declared surface retired for lack of pull, another kept and made to *reject +loudly* because a real app proved the direction. On the other two axes they +would read the same, and that would be the wrong answer. + +**Axis ② — long-term architectural soundness for *this* project.** Which option matches where the project is going and a sustainable architecture — no workarounds, contract-first — rather than which is cheapest today. **Name the long-term cost of any patch-style option explicitly.** "We can special-case it here" is a valid option only when its future removal cost is stated. -**Axis ② — making AI-authored code structurally hard to get wrong**, and +**Axis ③ — making AI-authored code structurally hard to get wrong**, and especially AI-authored ObjectStack **metadata**. Prefer the option that prevents the mistake at authoring time — a strict schema, publish-time 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" until it does not. Never let an agent declare a capability the runtime does not honour. -Your recommendation must be justified on **both** axes. If they conflict, +Your recommendation must be justified on **all three** axes. If they conflict, present the trade-off honestly and let the maintainer decide. ### 9. Round report, then next round @@ -571,7 +592,17 @@ or two readings of the issue lead to different architectures: make no guess, write no speculative code. Return status "needs_decision" with each question, the options, their costs, and your recommendation in open_questions. A wrong guess shipped is far more expensive than a round-trip to the maintainer. -Analyze every option on two fixed axes: +Analyze every option on three fixed axes: +- Real business need — does the option serve a business scenario that ACTUALLY + EXISTS, or a speculative capability surface? Ask this first. The evidence must + be MEASURED, not inferred: who writes this key, who reads this capability, how + the project's example apps and real deployments use it today. "It reads like it + would be useful" does not count, and a shipped-but-unconsumed capability gets + no sunk-cost exemption. A declared surface with no pull is handled + implementation-first — narrow the declaration until declared = enforced + (retire it, or park the vocabulary until the implementation arrives) rather + than building implementation to justify the declaration. How tight the default + is comes from the project's conventions file, not from this template. - Long-term architectural soundness for THIS project — which option matches a sustainable architecture (no workarounds, contract-first), not which is cheapest today. Name the long-term cost of any patch-style option. @@ -580,7 +611,7 @@ Analyze every option on two fixed axes: publish-time validation that rejects loudly, declared = enforced) over consumer-side tolerance. Lenient consumers are where AI-generated errors hide and multiply. -Justify your recommendation on both axes; if they conflict, present the +Justify your recommendation on all three axes; if they conflict, present the trade-off and let the maintainer decide. Return "blocked" (with evidence) when the default branch is broken under you, a @@ -799,6 +830,7 @@ them into every dispatch: | Files owned by a release process that a code PR must never touch | conventions file | | Test / typecheck / lint commands per package | conventions file | | Merge policy (merge queue, serial merge, maintainer-only) | conventions file | +| Capability-expansion stance the business-need axis reads (tight by default, or permissive) | conventions file | | Which repositories exist and which is the backlog | `.claude/pm-dispatch.json` | | Recorded architecture decisions the escalation bar defers to | the project's ADR directory |