diff --git a/.changeset/pm-dispatch-three-axis-decision-frame.md b/.changeset/pm-dispatch-three-axis-decision-frame.md new file mode 100644 index 0000000000..bcf61fa914 --- /dev/null +++ b/.changeset/pm-dispatch-three-axis-decision-frame.md @@ -0,0 +1,29 @@ +--- +--- + +docs(pm-dispatch,os-dev): 决策分析轴由两条扩为三条 —— 新增「实际业务需求」轴与创业阶段聚焦原则 (#5130) + +维护者 2026-08-04 在 #5021 裁决现场的指示(「我们是一个创业项目,应该先专注于核心 +能力,这个也应该写入项目经理 skills」)落到 agent 协议文本。当天起的实操已按三轴呈报, +skill 文本落后于实践。 + +- `.claude/skills/pm-dispatch/SKILL.md` 第 8 步(Escalate):「两条固定评估轴」→ + **三条**,新轴「实际业务需求」列第一位 —— 判据要求**实测**(谁在写这个键 / 谁在读 + 这个能力 / showcase 与真实部署里的用法),不接受「读起来像有用」;**创业阶段聚焦 + 原则**:能力扩张默认从紧,新能力 / 新词表 / 新配置面要有真实业务拉动才立项,无拉动 + 的声明面按 implementation-first 处置(退役或停车),已发布但零消费的能力不因沉没 + 成本获得豁免(先例 #5021 / #4988 / #4834)。原两轴(项目长远合理性、防 AI 写代码与 + 写元数据 app 犯错)**原文保留**,仅顺序后移;收尾句「这两条轴 / 两轴冲突」→ 三条 / + 三轴;分诊一节的 `the deep two-axis analysis` → `three-axis`。 +- `.claude/agents/os-dev.md` 的 `needs_decision` 升级段同步(`two fixed axes` → + `three fixed axes`、`both axes` → `all three axes`)。两处本就是同一套框架的两半: + 不同步,开发 agent 会按两轴上报、PM 按三轴呈报,业务轴每次都要 PM 事后补。 + +为什么值一条独立的轴而不是一句提醒:#4936 与 #5021 是业务轴**改变结论**的正反两例 —— +前者因 showcase 自证了业务方向而裁「响亮拒绝而非退役」,后者因无业务拉动裁退役; +只看原来的两条轴,这两单会得出同一个答案。 + +仅改 `.claude/` 内部 agent 协议文本,不发布任何包;空 frontmatter 仅为满足 changeset +门禁。已发布目录 `skills/objectstack-pm-dispatch/SKILL.md` 里的两轴镜像本次**刻意未动** +(那是发布内容,另单处理),`docs/adr/0121-*.md` 记述的是当时按两轴做出的裁决,属历史 +记录,同样不动。 diff --git a/.claude/agents/os-dev.md b/.claude/agents/os-dev.md index 9fbf84214c..af9d8aa9c9 100644 --- a/.claude/agents/os-dev.md +++ b/.claude/agents/os-dev.md @@ -179,9 +179,23 @@ semantics — 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 — this framing is +to the maintainer. **Analyze every option on three fixed axes — this framing is the core of the escalation, not decoration:** +- **Real business need**: does this option serve a business scenario that + actually exists, or a speculative capability surface? The evidence must be + **measured**, not asserted — who writes this key, who reads this capability, + how the example apps (showcase / CRM) and real deployments use it. "It reads + like it would be useful" does not count. **Startup focus principle** + (maintainer, 2026-08-04): this is a startup project and core capability comes + first, so capability expansion is tight by default — a new capability, a new + vocabulary, a new configuration surface needs real business pull to be worth + building; a declared surface with no pull is handled implementation-first + (retire it, or park it and let the vocabulary return with the implementation). + A shipped-but-unconsumed "capability" gets no sunk-cost exemption. This axis + changes verdicts rather than decorating them — #5021 retired 9 groups for + lack of pull, while #4936 was ruled a loud rejection *instead of* retirement + because the showcase proved the business direction. - **Long-term soundness for THIS project**: which option aligns with the North Star and a sustainable architecture (no workarounds, contract-first), not which is cheapest today. Name the long-term cost of any patch-style @@ -193,8 +207,8 @@ the core of the escalation, not decoration:** silent coercion). Lenient consumers are exactly where AI-generated metadata errors hide and multiply. -Your recommendation must be justified on both axes; if they conflict, present -the trade-off honestly and let the maintainer decide. Likewise return `blocked` (with evidence) when `main` is +Your recommendation must be justified on all three axes; if they conflict, +present the trade-off honestly and let the maintainer decide. Likewise return `blocked` (with evidence) when `main` is broken under you, a dependency issue is unmerged, or CI infrastructure fails — after retrying enough to be sure it is not your change. diff --git a/.claude/skills/pm-dispatch/SKILL.md b/.claude/skills/pm-dispatch/SKILL.md index 2a36ec84dd..1a987df3bc 100644 --- a/.claude/skills/pm-dispatch/SKILL.md +++ b/.claude/skills/pm-dispatch/SKILL.md @@ -478,7 +478,7 @@ label and classify each: - **Maintainer confirm (`needs-user-decision`)**: design cards, feature/ 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. - **Hold (`finding`)**: observation-class findings — dormant code, unexercised drift, cosmetic polish; real, but nothing a user hits today. @@ -1000,8 +1000,20 @@ is too vague to dispatch, or rework has failed twice: one, link it from each rather than duplicating the analysis) or arose with no issue of its own. 2. The analysis, wherever it lands (Chinese): 背景、具体问题、可选方案、 - 你的建议、关联的 issue / PR / 分支。**每个方案必须沿两条固定评估轴 + 你的建议、关联的 issue / PR / 分支。**每个方案必须沿三条固定评估轴 分析,这是决策分析的核心原则,不是可选项:** + - **实际业务需求** — 每个方案先问:它服务的是**真实存在的业务场景**, + 还是投机性的能力面?判据来源要求**实测**——谁在写这个键、谁在读这个 + 能力、示例应用(showcase / CRM)与真实部署里的用法;「读起来像有用」 + 不作数。**创业阶段聚焦原则**(维护者 2026-08-04 指示:「我们是一个 + 创业项目,应该先专注于核心能力」):能力扩张默认从紧——新能力 / 新 + 词表 / 新配置面需要真实业务拉动才立项;无拉动的声明面按 + implementation-first 处置(退役,或停车、词表随未来实现回归)。已发布 + 但零消费的「能力」**不因沉没成本获得豁免**:#5021(主题排版 9 组)、 + #4988(交互配置 22 站点)、#4834(plugin-runtime 五 schema)是先例。 + 这条轴会**改变结论**,不是陪衬,正反两例都有:#5021 因无业务拉动裁 + 退役,#4936 则因 showcase 自证了业务方向而裁「响亮拒绝而非退役」—— + 只看后两条轴,这两单会得出同一个答案,那是错的。 - **项目长远合理性** — 哪个方案符合北极星方向与可持续架构(Prime Directive #5 no workarounds、#8 North Star、#12 contract-first), 而不是眼下最省事;临时补丁式的选项要明说其长期代价。 @@ -1010,7 +1022,7 @@ is too vague to dispatch, or rework has failed twice: 校验拒绝、错误响亮)优于消费端宽容(`??` 回退、静默容错)——宽容 恰恰是 AI 批量犯错被掩盖的温床;声明即强制(declared = enforced), 绝不让 AI 能声明一个运行时不兑现的能力。 - 推荐意见必须基于这两条轴给出理由;两轴冲突时如实呈现权衡,交维护者 + 推荐意见必须基于这三条轴给出理由;三轴冲突时如实呈现权衡,交维护者 拍板。 3. If the session is interactive, additionally raise it via `AskUserQuestion`; the labeled issue remains the durable record either way. **Never** answer