pi-matt-pocock 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.zh-CN.md +37 -19
- package/README.md +80 -13
- package/package.json +12 -7
- package/procedures/code-review.md +25 -17
- package/procedures/codebase-design.md +11 -10
- package/procedures/deslop.md +4 -2
- package/procedures/diagnosing-bugs.md +25 -25
- package/procedures/domain-modeling.md +18 -20
- package/procedures/grill-me.md +1 -1
- package/procedures/grill-with-docs.md +1 -1
- package/procedures/grilling.md +29 -5
- package/procedures/handoff.md +1 -1
- package/procedures/implement.md +7 -1
- package/procedures/improve-codebase-architecture.md +22 -22
- package/procedures/pr.md +169 -0
- package/procedures/prototype.md +7 -6
- package/procedures/research.md +2 -2
- package/procedures/retro.md +42 -0
- package/procedures/setup-matt-pocock-skills.md +26 -22
- package/procedures/tdd.md +17 -15
- package/procedures/teach.md +11 -7
- package/procedures/to-questionnaire.md +7 -5
- package/procedures/to-spec.md +2 -2
- package/procedures/to-tickets.md +12 -12
- package/procedures/triage.md +22 -22
- package/procedures/wait-what.md +1 -1
- package/procedures/wayfinder.md +24 -24
- package/procedures/wizard.md +7 -7
- package/procedures/writing-for-agents.md +14 -14
- package/{procedures → references}/ADR-FORMAT.md +11 -11
- package/{procedures → references}/AGENT-BRIEF.md +4 -4
- package/{procedures → references}/DEEPENING.md +3 -3
- package/{procedures → references}/DESIGN-IT-TWICE.md +7 -7
- package/{procedures → references}/GLOSSARY-FORMAT.md +9 -2
- package/{procedures → references}/HTML-REPORT.md +15 -15
- package/{procedures → references}/LEARNING-RECORD-FORMAT.md +10 -10
- package/{procedures → references}/LOGIC.md +5 -5
- package/{procedures → references}/MISSION-FORMAT.md +2 -2
- package/{procedures → references}/OUT-OF-SCOPE.md +11 -11
- package/{procedures → references}/RESOURCES-FORMAT.md +1 -1
- package/{procedures → references}/SKILL-MECHANICS.md +3 -3
- package/{procedures → references}/UI.md +14 -14
- package/{procedures → references}/bdd-best-practices.md +3 -3
- package/{procedures → references}/bdd.md +9 -9
- package/{procedures → references}/domain.md +12 -12
- package/references/issue-tracker-github.md +50 -0
- package/{procedures → references}/issue-tracker-gitlab.md +9 -9
- package/{procedures → references}/issue-tracker-local.md +3 -3
- package/{procedures → references}/phase-boundaries.md +8 -8
- package/src/catalog.json +49 -28
- package/src/catalog.ts +58 -2
- package/src/index.ts +539 -363
- package/src/native-dialog.ts +149 -213
- package/src/resolver.ts +57 -11
- package/src/workflow.ts +76 -18
- package/upstream/UPSTREAM.md +116 -0
- package/{scripts → upstream}/check-upstream-sync.mjs +12 -12
- package/{upstream-selection.json → upstream/upstream-selection.json} +9 -7
- package/UPSTREAM.md +0 -63
- package/procedures/CONTEXT-FORMAT.md +0 -60
- package/procedures/issue-tracker-github.md +0 -45
- /package/{procedures → assets}/hitl-loop.template.sh +0 -0
- /package/{procedures → assets}/template.sh +0 -0
- /package/{procedures → references}/GLOSSARY.md +0 -0
- /package/{procedures → references}/gherkin-guide.md +0 -0
- /package/{procedures → references}/mocking.md +0 -0
- /package/{procedures → references}/testing-anti-patterns.md +0 -0
- /package/{procedures → references}/tests.md +0 -0
- /package/{procedures → references}/triage-labels.md +0 -0
- /package/{procedures → references}/writing-great-skills.md +0 -0
package/ARCHITECTURE.zh-CN.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
`pi-matt-pocock` 将 [mattpocock/skills](https://github.com/mattpocock/skills) 中选定的工程方法适配为 Pi 的**目录驱动能力网关**。它不是上游仓库的完整镜像,也不把每份上游 `SKILL.md` 注册为 Pi skill。
|
|
4
4
|
|
|
5
|
+
上游检查已更新至 `d81f3a1`。新增 `pr`(模型与命令可用)和 `retro`(用户命令)能力;词汇表采用 `GLOSSARY.md`,旧 reference id `CONTEXT-FORMAT` 通过别名继续可恢复。上游移除的 `resolving-merge-conflicts` 保留为本地兼容能力。开发依赖与可执行运行 fixture 都按包内实际解析结果验证 Pi v1.0。
|
|
6
|
+
|
|
5
7
|
## 核心模型:procedureCatalog manifest
|
|
6
8
|
|
|
7
9
|
`src/catalog.json` 中的 `procedureCatalog` manifest 是能力与资源关系的单一事实来源,`src/catalog.ts` 提供类型化查询与校验。命令菜单、模型可见能力、工作流入口、route 标题与说明、阶段、别名、依赖、引用披露、合法迁移和完整性检查都从目录派生,而不是分别维护 route/procedure 巨型枚举。
|
|
@@ -42,16 +44,16 @@
|
|
|
42
44
|
启动 route 时,`src/workflow.ts` 从目录查找唯一入口,并创建如下持久化状态:
|
|
43
45
|
|
|
44
46
|
```text
|
|
45
|
-
version / workItemId / route / procedure / phase / status / loadedReferences
|
|
47
|
+
version / workItemId / route / procedure / phase / status / loadedReferences / deliveredProcedures
|
|
46
48
|
```
|
|
47
49
|
|
|
48
50
|
- `workItemId` 是每次工作流启动时生成的稳定 UUID,用于区分独立工作项。
|
|
49
51
|
- 活动记录的 `status` 为 `active`。
|
|
50
52
|
- 结束记录保留同一 `workItemId`,`status` 为 `completed` 或 `cancelled`;取消记录可包含原因。
|
|
51
|
-
- 状态通过 `pi.appendEntry` 写入 session branch
|
|
53
|
+
- 状态通过 `pi.appendEntry` 写入 session branch。Pi v1.0 的 session start、tree navigation 和 context compaction 都以当前分支最新记录为准;记录已结束、损坏或版本不兼容时,不会回退恢复旧活动状态。
|
|
52
54
|
- 恢复前会重新验证 route、procedure 与资源 bundle。无效的陈旧状态会被明确记录为 `cancelled`,而不是静默回退到 route 默认入口。
|
|
53
55
|
|
|
54
|
-
|
|
56
|
+
扩展实例独立持有运行状态,避免同一进程中多个会话串扰。工作流启动或恢复时会返回完整的当前 procedure bundle;迁移只交付本次连续上下文中尚未交付的正文。压缩上下文后重置交付集合并静默注入当前完整 bundle。之后每个 agent turn 只追加紧凑 guidance,包含 `workItemId`、当前阶段、合法下一步、可加载 reference 与终止责任,不会把整个目录反复注入 system prompt。
|
|
55
57
|
|
|
56
58
|
模型可以通过 `matt_pocock_active` 明确完成工作流;完成不再依赖用户进入菜单。用户仍可从同一 `/matt-pocock` 菜单迁移、完成或取消,作为显式控制入口。
|
|
57
59
|
|
|
@@ -76,13 +78,13 @@ version / workItemId / route / procedure / phase / status / loadedReferences
|
|
|
76
78
|
| `hard-bug` | Reproducing & Diagnostics;Implementation;Code Review |
|
|
77
79
|
| `architecture` | Architecture Survey;Architecture Design;Implementation;Code Review |
|
|
78
80
|
|
|
79
|
-
route、procedure、phase、workItemId 和状态的持久化结构不变,模型 guidance、工具参数与结果 details
|
|
81
|
+
route、procedure、phase、workItemId 和状态的持久化结构不变,模型 guidance、工具参数与结果 details 仍使用原标识。启动提示行只显示可读的阶段标题,不再重复 route id 或 route 标题,也不会展示 procedure 正文。
|
|
80
82
|
|
|
81
|
-
|
|
83
|
+
所有 Matt Pocock 行都在折叠状态显示全部事实,不使用展开隐藏字段正文:
|
|
82
84
|
|
|
83
85
|
- 迁移、完成和参考资料加载不显示重复的 `action` 字段;独立能力和独立参考资料也不把标题再复制为字段。标题完整可见时,这些提示没有展开提示或额外正文。
|
|
84
|
-
-
|
|
85
|
-
-
|
|
86
|
+
- 取消提示在该结果保存的终止快照包含非空白原因时,直接在折叠行内联显示一次 `reason · <stored reason>`,不显示 `action · cancel`,也不读取当前工作流的原因。缺失、空字符串或纯空白原因不会新增正文。
|
|
87
|
+
- 窄终端中的标题或正文行被截断时,由 Pi-kit 共享渲染器提供展开,并使用 Pi 原生换行恢复完整文本;本包不自行计算宽度。仅供模型使用的正文不会触发展开提示。
|
|
86
88
|
|
|
87
89
|
`matt-pocock-procedure` 消息渲染器负责这条块状提示。用户从 `/matt-pocock` 启动 route/独立能力、用自由文本触发路由、或在菜单里选 “Start a task” 时,procedure 都通过这条可见消息交付,而不是把正文当 user message 贴出:
|
|
88
90
|
|
|
@@ -92,11 +94,15 @@ route、procedure、phase、workItemId 和状态的持久化结构不变,模
|
|
|
92
94
|
fix the login redirect
|
|
93
95
|
```
|
|
94
96
|
|
|
95
|
-
head
|
|
97
|
+
head 单独成行,一个空行分隔,随后是用户自己的任务原文(未提供任务时用可读的阶段标题或能力显示名称);整块使用 Pi 原生 user-message 底色(`userMessageBg`),逐行保留换行、过长自动换行,且不提供展开。模型侧仍收到完整正文和 `User target/request:` 段落。恢复会话时仅静默注入 guidance(`display: false`),不新增重复的启动行。旧工具结果即使保存了 route 风格的 subject,也根据该事件保存的 phase 和 action 重新渲染,不读取当前工作流的可变状态,无需迁移会话数据。
|
|
98
|
+
|
|
99
|
+
能力与引用统一使用目录中的可读显示名称;阶段切换菜单使用目标阶段标题,与进入阶段后的状态行一致。命令和持久化数据仍保留原有 id,用户任务原文不改写。
|
|
96
100
|
|
|
97
101
|
独立能力、参考资料和提问保留各自的展示对象:`started · <capability>`、`started · <capability> · <reference>`、`event · loaded <reference>` 和 `ask · <question>`,不替换成工作流阶段。提问的答案或待定状态保持可见,超时、无 UI 和自定义输入等有效 metadata 仍可展开查看,不重复答案。
|
|
98
102
|
|
|
99
|
-
从仓库根目录运行 `uv run --no-project packages/matt-pocock/tests/live_smoke.py`,可在真实 Pi CLI 中验证 print
|
|
103
|
+
从仓库根目录运行 `uv run --no-project packages/matt-pocock/tests/live/live_smoke.py`,可在真实 Pi CLI 中验证 print 模式、交互终端提示、真实选择超时与 Escape 取消、Ctrl+O 展开、缩至 48 列,以及 `/matt-pocock hard-bug fix the login redirect` 只产生一块 user-message 底色的块状提示。脚本使用临时 HOME 与离线脚本化 provider,不读取用户凭证或调用外部模型。
|
|
104
|
+
|
|
105
|
+
`tests/live/runtime_live.py` 从 catalog 派生全部 route、合法转移和独立能力,在真实 Pi agent loop 中运行,并验证持久化重启;`tests/live/decision_live.py` 通过 PTY 发送实际选择、文本输入与取消按键。运行方式同上。原生进程失败模拟与实际 macOS 对话框验证分别记录。这些验证覆盖 Pi 集成路径,不证明外部模型的决策质量,也不代表每份 procedure 的下游工程任务已执行。
|
|
100
106
|
|
|
101
107
|
## 协作验证与完成门槛
|
|
102
108
|
|
|
@@ -149,7 +155,7 @@ head 单独成行,一个空行分隔,随后是用户自己的任务原文(
|
|
|
149
155
|
|
|
150
156
|
上游以多份嵌套 `SKILL.md` 分发能力。Pi 会递归发现 skill root 下的这些文件,因此 `tdd`、`research`、`implement`、`code-review` 等通用名字可能与用户安装的其他集合冲突,也不天然表达工作项状态和合法阶段迁移。
|
|
151
157
|
|
|
152
|
-
|
|
158
|
+
本包把选定内容按 catalog 的 kind 分目录保存:可加载的 capability 放在 `procedures/`,按需加载的 reference 放在 `references/`,模板类 asset 放在 `assets/`,并由 extension 解析。包内不含子 `SKILL.md`:
|
|
153
159
|
|
|
154
160
|
- 名称不会进入全局 skill 命名空间;
|
|
155
161
|
- workflow 与 standalone capability 共用同一个目录和网关;
|
|
@@ -160,28 +166,34 @@ head 单独成行,一个空行分隔,随后是用户自己的任务原文(
|
|
|
160
166
|
|
|
161
167
|
## 上游选择与同步校验
|
|
162
168
|
|
|
163
|
-
[`upstream-selection.json`](upstream-selection.json) 是机器可读的上游选择记录。它把最新检查版本中的每个上游 skill 标为:
|
|
169
|
+
[`upstream/upstream-selection.json`](upstream/upstream-selection.json) 是机器可读的上游选择记录。它把最新检查版本中的每个上游 skill 标为:
|
|
164
170
|
|
|
165
171
|
- `selected`:映射到本地 catalog id、普通 Markdown resource 与上游调用模式;
|
|
166
172
|
- `excluded`:保留明确排除理由,包括依赖 Claude Code hook 或后台 agent 命令的宿主专属能力。
|
|
167
173
|
|
|
168
|
-
[`UPSTREAM.md`](UPSTREAM.md) 记录比较 commit、tag、tag commit、最新检查 commit 以及适配规则。[`
|
|
174
|
+
[`upstream/UPSTREAM.md`](upstream/UPSTREAM.md) 记录比较 commit、tag、tag commit、最新检查 commit 以及适配规则。[`upstream/check-upstream-sync.mjs`](upstream/check-upstream-sync.mjs) 是同步 checker:不带参数时验证本地元数据和资源;传入已克隆的上游路径时,还会检查完整 skill inventory、调用模式和正文差异。checker 不会自行 clone 或 fetch。
|
|
169
175
|
|
|
170
176
|
贡献者应运行:
|
|
171
177
|
|
|
172
178
|
```bash
|
|
173
|
-
node packages/matt-pocock/
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
179
|
+
node packages/matt-pocock/upstream/check-upstream-sync.mjs
|
|
180
|
+
uv run pytest packages/matt-pocock/tests/ -q
|
|
181
|
+
bun run typecheck
|
|
182
|
+
bun pm pack --destination /tmp --quiet --cwd packages/matt-pocock
|
|
177
183
|
```
|
|
178
184
|
|
|
179
185
|
需要核对上游 checkout 时再运行:
|
|
180
186
|
|
|
181
187
|
```bash
|
|
182
|
-
node packages/matt-pocock/
|
|
188
|
+
node packages/matt-pocock/upstream/check-upstream-sync.mjs --upstream /path/to/mattpocock-skills
|
|
183
189
|
```
|
|
184
190
|
|
|
191
|
+
实际 Pi v1.0 检查见 [`README.md`](README.md) 中的运行命令。目录矩阵从 manifest 派生所有 route、合法迁移和独立能力,通过真实 Pi agent loop 执行,并检查工具启停、持久化、重启、原生树切换与上下文压缩。压缩检查通过 `session_before_compact` 提供固定摘要;Pi 的压缩事件与会话写入仍实际执行,下一次模型上下文需包含恢复后的完整 procedure 来源。
|
|
192
|
+
|
|
193
|
+
决策、活动菜单和 AbortSignal 检查运行在真实 Pi 终端中。测试使用临时 HOME 和本地固定响应 provider,不读取用户认证,也不验证外部模型的决策质量或 procedure 指导的下游项目任务。故意失败的模拟原生子进程只证明 TUI fallback;独立 macOS smoke 使用实际 `osascript` 验证超时、中止和进程退出,不代替原生按钮选择或物理界面的人工验收。
|
|
194
|
+
|
|
195
|
+
真实模型检查单独使用 `tests/real_model_live.py`,用例清单位于 `tests/real-model-cases.json`,覆盖 21 个独立能力、5 个工作流入口、自然语言路由和“测试全绿但含需求外行为”的审查回归,共 28 项。`--list` 只列清单;显式 `--case` 或 `--all` 使用当前 Pi provider/model,thinking 为 off,并在每项独立的临时项目中加载生产扩展。认证副本只用于 provider 请求,项目文件工具无法读取;固定验收在 macOS sandbox 中执行,模型不能修改验收文件。产物检查、需要人回答的问题、失败和未运行项分别记录,不以进程正常退出作为成功证据。有待回答问题时,总体状态保持 `awaiting_user`,预期的 pending 验收仍以退出码 0 表示。外部 provider 不可用时停止,不自动更换模型。
|
|
196
|
+
|
|
185
197
|
## 与上游纯 skills方案的差异
|
|
186
198
|
|
|
187
199
|
| 维度 | `mattpocock/skills` | `pi-matt-pocock` |
|
|
@@ -199,7 +211,7 @@ node packages/matt-pocock/scripts/check-upstream-sync.mjs --upstream /path/to/ma
|
|
|
199
211
|
|
|
200
212
|
工作流进行决策访谈(如 `grilling`、`domain-modeling`)时,通过 `matt_pocock_ask` 工具向用户发起选项选择或自定义输入。默认情况下,使用 Pi 终端内置的 TUI 界面(`ctx.ui.select` / `ctx.ui.input`)。
|
|
201
213
|
|
|
202
|
-
用户可在
|
|
214
|
+
用户可在 Pi 的 agent 目录下的 `matt-pocock.json` 中配置是否在本地 macOS 环境下启用系统原生弹窗(默认 `~/.pi/agent/matt-pocock.json`;若设置了 `PI_CODING_AGENT_DIR`,则使用该目录):
|
|
203
215
|
|
|
204
216
|
```json
|
|
205
217
|
{
|
|
@@ -213,4 +225,10 @@ node packages/matt-pocock/scripts/check-upstream-sync.mjs --upstream /path/to/ma
|
|
|
213
225
|
- **原生交互体验**:
|
|
214
226
|
1. **列表单选**:调用系统原生 `choose from list` 弹窗展示选项,支持上下键移动、回车选择;
|
|
215
227
|
2. **自定义输入**:当用户选择“输入自定义回答...”时,自动唤起原生文本输入窗口(`display dialog` 带输入框),供用户直接打字;
|
|
216
|
-
3.
|
|
228
|
+
3. **推荐超时自动采纳**:`recommended` 为必填且必须属于候选项;每次提问都装填一个有界截止时间(默认 60 秒,上限 3600 秒),截止到达后同时关闭选择列表和自定义输入并采纳推荐选项,提问不会无限等待。仅实际达到截止时间后才采纳,取消、工具中断或流程切换均保持待定。需要授权的操作应把推荐设为不执行该操作的安全选项,因为截止时间会采纳它。
|
|
229
|
+
|
|
230
|
+
原生对话框仅在配置 `useNativeDialog: true`(布尔值)时启用。取消信号会关闭 TUI 或终止并回收 osascript 子进程;进程启动、退出或解析失败会回退到 TUI。Catalog 在注册工具前校验别名冲突、重复路由位置和 requires 环;加载 reference 前校验累计上下文的 64 KiB 限额,失败不写入部分状态。独立能力在内存中保存当前披露链,可继续加载 reference 披露的下级资料,不创建持久流程状态;重启能力或跨会话上下文时清空。
|
|
231
|
+
|
|
232
|
+
开发者完整任务另见 `tests/developer-journey-cases.json`:折扣需求到审查交接、异步缓存故障修复、配置解析的设计/清理/审查/交接,使用真实模型连续多轮调用。运行 `tests/real_model_live.py --cases packages/matt-pocock/tests/developer-journey-cases.json --all --deadline 420 --output /tmp/matt-developer-journeys.json`。独立验收验证公共行为;审查中的因果解释和清理结论另需阅读实际产物验证,不能把测试通过等同于报告正确。
|
|
233
|
+
|
|
234
|
+
完整任务以实际进入指定阶段及单一工作项身份为验收条件,跨轮次等待 `agent_settled` 后继续;缓存测试覆盖失败前成功缓存和独立的加载中键。这三个任务显式设置最多 80 次工具调用,普通矩阵默认仍为 40 次,预算耗尽后后续轮次也不能绕过。
|
package/README.md
CHANGED
|
@@ -38,7 +38,17 @@ Tools are progressively exposed based on active session state:
|
|
|
38
38
|
- `action: "cancel"`: Cancel the active workflow with an explicit reason.
|
|
39
39
|
3. **Active-only tool**: `matt_pocock_ask`
|
|
40
40
|
- Prompt the user for structured, genuinely user-owned decisions with selectable options.
|
|
41
|
-
-
|
|
41
|
+
- Requires a recommended choice and adopts it when the deadline elapses; supports custom text input. One deadline governs the ask and dismisses both the selector and the custom-answer input; elapsed clock readings alone never imply a timeout. Escape, cancellation, abort, no UI, and a blank custom answer leave the decision pending. Recommendations must match an offered option, so an approval-required action recommends the option that does not act.
|
|
42
|
+
|
|
43
|
+
## Pi v1.0 runtime boundaries
|
|
44
|
+
|
|
45
|
+
This extension targets Pi v1.0 (`@earendil-works/pi-*`). Each extension instance owns its workflow state. Session start, tree navigation, and context compaction silently restore the active branch's complete procedure context; subsequent transitions deliver only new bodies. Malformed or incompatible newest records disable workflow-only tools rather than resurrecting older work. Restored phases must match the catalog placement.
|
|
46
|
+
|
|
47
|
+
Workflow changes and session boundaries dismiss pending questions and menus. A late selection cannot act on a replacement work item. Invalid arguments to `status` or `complete` report usage without cancelling the active work.
|
|
48
|
+
|
|
49
|
+
Standalone reference loading remembers the current capability's disclosure chain in memory, so a reference can disclose further references without creating workflow state. This chain resets when the capability restarts or the session context changes. Standalone procedures ask decisions in conversation rather than relying on workflow-only tools.
|
|
50
|
+
|
|
51
|
+
The catalog is validated before tools are registered, including alias conflicts, duplicate route placements, and required dependency cycles. A cumulative reference bundle is validated against the 64 KiB limit before state is persisted. Dialog cancellation propagates to Pi UI and native subprocesses; native process failures fall back to Pi UI.
|
|
42
52
|
|
|
43
53
|
## Workflow Routes & Graph Topology
|
|
44
54
|
|
|
@@ -106,8 +116,11 @@ The following curated capabilities are reachable via `matt_pocock_workflow` (`mo
|
|
|
106
116
|
- **`deslop`**: Eliminating AI code smell patterns while keeping interfaces and tests green.
|
|
107
117
|
- **`wizard`**: Generating interactive human-in-the-loop shell wizards.
|
|
108
118
|
- **`grilling`**: Relentlessly interviewing requirements one question at a time.
|
|
109
|
-
- **`domain-modeling`**: Clarifying ubiquitous domain language and
|
|
119
|
+
- **`domain-modeling`**: Clarifying ubiquitous domain language and GLOSSARY.md.
|
|
110
120
|
- **`tdd`**: Running the BDD-driven red-green automation loop.
|
|
121
|
+
- **`pr`**: Writing a concise PR body with evidence and merge risk.
|
|
122
|
+
|
|
123
|
+
User-invoked capabilities also appear in the command menu. `/matt-pocock retro` reviews a session and proposes improvements to the agent environment. The upstream glossary rename retains `CONTEXT-FORMAT` as an alias of `GLOSSARY-FORMAT`, so existing workflow records can still restore. `resolving-merge-conflicts` remains a local compatibility capability after its removal upstream.
|
|
111
124
|
|
|
112
125
|
## Lifecycle Display Lines
|
|
113
126
|
|
|
@@ -156,13 +169,13 @@ Supported titles by route (not a mandatory execution order):
|
|
|
156
169
|
| `hard-bug` | Reproducing & Diagnostics; Implementation; Code Review |
|
|
157
170
|
| `architecture` | Architecture Survey; Architecture Design; Implementation; Code Review |
|
|
158
171
|
|
|
159
|
-
Route and phase ids remain unchanged in tool arguments, model guidance, result details, and persisted state.
|
|
172
|
+
Route and phase ids remain unchanged in tool arguments, model guidance, result details, and persisted state. A workflow-start row shows the readable phase title only. The row does not repeat the route id or its title, and it does not expose procedure bodies.
|
|
160
173
|
|
|
161
|
-
|
|
174
|
+
No Matt Pocock row hides a field body behind expansion. Every row shows its facts in the collapsed transcript:
|
|
162
175
|
|
|
163
176
|
- Transitions, completion, and reference loads omit repetitive `action` fields; standalone capability and reference rows do not repeat their subjects as fields. When the title fits, these rows have no expand hint or extra detail body.
|
|
164
|
-
-
|
|
165
|
-
- At narrower widths, Pi-kit's shared renderer can offer expansion to wrap a clipped title or
|
|
177
|
+
- A cancellation row carries `reason · <stored reason>` inline when that result's terminal snapshot has a nonblank reason. The reason appears once, never as `action · cancel`, and it does not come from the current workflow. A missing, empty, or whitespace-only reason adds no body line.
|
|
178
|
+
- At narrower widths, Pi-kit's shared renderer can offer expansion to wrap a clipped title or body line with Pi's native wrapping. Model-only content does not itself create an expand hint.
|
|
166
179
|
|
|
167
180
|
The `matt-pocock-procedure` message renderer owns that block layout. A `/matt-pocock` route or capability start (including a freeform routing request and the menu's "Start a task") delivers the procedure through this displayed message instead of posting the procedure text as a user message, while the model still receives the complete body plus any `User target/request:` section. Session restoration reinjects guidance silently (`display: false`), without a duplicate lifecycle event. Saved active-tool results with old route-based subjects are rendered from their recorded phase and action, not the session's current workflow; no session-data migration is needed.
|
|
168
181
|
|
|
@@ -170,17 +183,61 @@ The `matt-pocock-procedure` message renderer owns that block layout. A `/matt-po
|
|
|
170
183
|
|
|
171
184
|
These operations keep their own subjects rather than substituting a workflow phase:
|
|
172
185
|
|
|
173
|
-
- **Reference loading (`load`)**: `[matt pocock] event · loaded <reference>` (e.g. `[matt pocock] event · loaded HTML
|
|
174
|
-
- **Standalone capability**: `[matt pocock] started · <capability>` (e.g. `[matt pocock] started ·
|
|
186
|
+
- **Reference loading (`load`)**: `[matt pocock] event · loaded <reference>` (e.g. `[matt pocock] event · loaded HTML Report`).
|
|
187
|
+
- **Standalone capability**: `[matt pocock] started · <capability>` (e.g. `[matt pocock] started · Diagnosing Bugs`).
|
|
175
188
|
- **Standalone reference**: `[matt pocock] started · <capability> · <reference>`.
|
|
176
|
-
- **`matt_pocock_ask`**: `[matt pocock] ask · <question>`, with the answer or pending status below. Timeout, no-UI, and custom-input metadata
|
|
189
|
+
- **`matt_pocock_ask`**: `[matt pocock] ask · <question>`, with the answer or pending status below. The model-facing result includes the full question followed by the chosen answer as a block quote (`> <answer>`); `(Recommended)` is only a choice label and is omitted from the answer. Timeout, no-UI, and custom-input metadata appear as inline body lines below the answer, which is never repeated.
|
|
177
190
|
- **Fallback**: `[matt pocock] event · workflow updated` when no action or subject is available.
|
|
178
191
|
|
|
179
|
-
|
|
192
|
+
Capability and reference names use readable catalog labels consistently. Transition-menu choices use their destination phase titles, matching lifecycle rows. Command identifiers and saved resource ids remain unchanged; user-supplied tasks are displayed verbatim.
|
|
193
|
+
|
|
194
|
+
Run the actual Pi checks from the repository root:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
uv run --no-project packages/matt-pocock/tests/live/live_smoke.py
|
|
198
|
+
uv run --no-project packages/matt-pocock/tests/live/runtime_live.py
|
|
199
|
+
uv run --no-project packages/matt-pocock/tests/live/restore_live.py
|
|
200
|
+
uv run --no-project packages/matt-pocock/tests/live/decision_live.py
|
|
201
|
+
uv run --no-project packages/matt-pocock/tests/live/active_menu_live.py
|
|
202
|
+
uv run --no-project packages/matt-pocock/tests/live/abort_live.py
|
|
203
|
+
uv run --no-project packages/matt-pocock/tests/live/adversarial_live.py
|
|
204
|
+
node --import tsx/esm packages/matt-pocock/tests/live/native_real_smoke.ts
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
The lifecycle check covers print mode, terminal rows, timeout and Escape, Ctrl+O, 48-column resizing, and the user-message band. The catalog matrix derives routes, legal transitions and standalone capabilities from the manifest and exercises them through Pi's agent loop, including persistence, restart, native tree navigation and native compaction. The compaction probe supplies a deterministic summary through `session_before_compact`; Pi still performs compaction and session persistence. Restored procedure sources are checked in the next model context.
|
|
208
|
+
|
|
209
|
+
The restart boundary check also covers completed/cancelled latest records, incompatible versions, and invalid phase/reference/procedure records, with older active records still present. It verifies inactive tools and guidance, and cancellation records for invalid active state.
|
|
210
|
+
|
|
211
|
+
The adversarial check opens real Pi selectors and menus, then injects deterministic state changes through the registered handlers. It verifies immediate dismissal, replacement work-item identity, and reference-only loading before and after a user command. Package tests additionally derive resource/alias/disclosure/transition cases from the catalog and test exact UTF-8 size boundaries in disposable package copies.
|
|
212
|
+
|
|
213
|
+
Repository verification details and reproduced failures are recorded in [the adversarial verification report](tests/reports/ADVERSARIAL-VERIFICATION.md).
|
|
214
|
+
|
|
215
|
+
The decision and active-menu checks send actual keyboard input through Pi's terminal UI. They cover option/custom input, cancellation, timeout, View, Transition, Cancel and Complete. The abort check interrupts a live selector with an AbortSignal. These Pi checks use an isolated home, allowlisted process settings and a deterministic local provider; they do not inherit provider credentials or validate external-model decisions or downstream project work performed by a procedure.
|
|
216
|
+
|
|
217
|
+
The decision check deliberately fails a simulated native subprocess to exercise TUI fallback. On macOS, the separate native smoke uses the real `osascript` to verify list/input/prompt timeout and list abort, including process exit. It does not automate native button selection or verify physical rendering. Package tests also typecheck every TypeScript test fixture and verify package-local Pi v1.0 dependency resolution.
|
|
218
|
+
|
|
219
|
+
The separate real-model matrix covers all 21 standalone capabilities, five workflow entries, natural-language routing, and a review regression where passing tests coexist with unrequested behavior (28 cases). Listing it does not read credentials or start Pi:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
uv run --no-project packages/matt-pocock/tests/real_model_live.py --list
|
|
223
|
+
uv run --no-project packages/matt-pocock/tests/real_model_live.py --case cap-pr --output /tmp/matt-real-pr.json
|
|
224
|
+
uv run --no-project packages/matt-pocock/tests/real_model_live.py --all --output /tmp/matt-real-matrix.json
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
`--case` and `--all` call the configured real provider and model, with thinking off. Each case uses a disposable project and agent directory; authentication files are copied with private permissions and deleted afterward. The production extension runs through native Pi RPC. File tools stay inside the project, fixed tests run in a macOS sandbox, and the verifier cannot be modified. Results distinguish verified artifacts, questions awaiting an answer, failures, and skipped cases. If any question is pending, the aggregate remains `awaiting_user`; an expected pending result has exit code 0. A provider failure stops the matrix instead of switching models. These runs are deliberately separate from the credential-free package test suite.
|
|
228
|
+
|
|
229
|
+
Three multi-turn developer journeys additionally cover an agreed discount feature through review and handoff, async cache incident repair, and configuration cleanup through design, de-slop, review and handoff. Their fixed acceptance tests verify public behavior and independent cache keys; review notes are also inspected for unsupported causal claims and misleading verdicts. Workflow journeys require the actual requested stages and one work item. The harness waits for Pi agent settlement between turns. These longer journeys explicitly allow up to 80 tool calls; the ordinary matrix retains its default 40-call budget, and exhaustion blocks later turns too.
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
uv run --no-project packages/matt-pocock/tests/real_model_live.py --cases packages/matt-pocock/tests/developer-journey-cases.json --list
|
|
233
|
+
uv run --no-project packages/matt-pocock/tests/real_model_live.py --cases packages/matt-pocock/tests/developer-journey-cases.json --all --deadline 420 --output /tmp/matt-developer-journeys.json
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
The developer journey evidence and observed limitations are documented in [DEVELOPER-JOURNEYS.md](tests/reports/DEVELOPER-JOURNEYS.md).
|
|
180
237
|
|
|
181
238
|
## Configuration
|
|
182
239
|
|
|
183
|
-
You can optionally configure native macOS dialog prompts for `matt_pocock_ask` via `~/.pi/agent/
|
|
240
|
+
You can optionally configure native macOS dialog prompts for `matt_pocock_ask` via `matt-pocock.json` in Pi's agent directory (`~/.pi/agent/matt-pocock.json`, or `$PI_CODING_AGENT_DIR/matt-pocock.json` when that variable is set):
|
|
184
241
|
|
|
185
242
|
```json
|
|
186
243
|
{
|
|
@@ -188,10 +245,20 @@ You can optionally configure native macOS dialog prompts for `matt_pocock_ask` v
|
|
|
188
245
|
}
|
|
189
246
|
```
|
|
190
247
|
|
|
191
|
-
By default (`useNativeDialog: false` or missing file), Pi uses its built-in TUI selection dialog. Native dialogs are automatically guarded to only trigger on local macOS GUI sessions (SSH sessions, non-macOS platforms, and CI environments always fall back cleanly to terminal TUI).
|
|
248
|
+
Only the boolean `true` enables native dialogs; strings and numbers keep them disabled. By default (`useNativeDialog: false` or missing file), Pi uses its built-in TUI selection dialog. Native dialogs are automatically guarded to only trigger on local macOS GUI sessions (SSH sessions, non-macOS platforms, and CI environments always fall back cleanly to terminal TUI).
|
|
192
249
|
|
|
193
|
-
See the detailed [中文架构说明](ARCHITECTURE.zh-CN.md), the upstream [selection metadata](upstream-selection.json) and [sync rules](UPSTREAM.md), and the deliberately deferred items in [TODO.md](TODO.md).
|
|
250
|
+
See the detailed [中文架构说明](ARCHITECTURE.zh-CN.md), the upstream [selection metadata](upstream/upstream-selection.json) and [sync rules](upstream/UPSTREAM.md), and the deliberately deferred items in [TODO.md](TODO.md).
|
|
194
251
|
|
|
195
252
|
## License
|
|
196
253
|
|
|
197
254
|
MIT
|
|
255
|
+
|
|
256
|
+
Eight additional developer fixtures cover generated frontend HTML, API request boundaries, authorization, versioned migration, operation-count performance, localization, lexical paths and behavioral test design. Together with the earlier journeys, these cover eleven developer task categories. The catalog-derived inventory checks every supported standalone capability and route; JSON boundary checks cover all JSON value classes.
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
uv run --no-project packages/matt-pocock/tests/type_inventory.py
|
|
260
|
+
uv run --no-project packages/matt-pocock/tests/real_model_live.py --cases packages/matt-pocock/tests/expanded-type-cases.json --list
|
|
261
|
+
uv run --no-project packages/matt-pocock/tests/real_model_live.py --cases packages/matt-pocock/tests/expanded-type-cases.json --all --deadline 300 --output /tmp/matt-expanded-types.json
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
The real-model verifier returns bounded redacted diagnostics and requires an immutable acceptance completion marker, so an early successful process exit cannot silently skip acceptance. See [TEST-TYPES.md](tests/reports/TEST-TYPES.md) for the coverage inventory, actual attempts and limitations. These checks do not establish browser assistive-technology behavior, deployed services, physical input or every possible software task.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-matt-pocock",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "BDD-first engineering and productivity skills adapted from Matt Pocock's skills",
|
|
6
6
|
"keywords": [
|
|
@@ -25,13 +25,13 @@
|
|
|
25
25
|
"index.ts",
|
|
26
26
|
"src",
|
|
27
27
|
"procedures",
|
|
28
|
+
"references",
|
|
29
|
+
"assets",
|
|
30
|
+
"upstream",
|
|
28
31
|
"TODO.md",
|
|
29
32
|
"LICENSE",
|
|
30
33
|
"README.md",
|
|
31
|
-
"ARCHITECTURE.zh-CN.md"
|
|
32
|
-
"UPSTREAM.md",
|
|
33
|
-
"upstream-selection.json",
|
|
34
|
-
"scripts"
|
|
34
|
+
"ARCHITECTURE.zh-CN.md"
|
|
35
35
|
],
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"@earendil-works/pi-coding-agent": "*",
|
|
@@ -39,11 +39,16 @@
|
|
|
39
39
|
"typebox": "*"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@fradser/pi-kit": "0.
|
|
42
|
+
"@fradser/pi-kit": "0.6.0"
|
|
43
43
|
},
|
|
44
44
|
"pi": {
|
|
45
45
|
"extensions": [
|
|
46
46
|
"./index.ts"
|
|
47
47
|
]
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@earendil-works/pi-ai": "^1.2.0",
|
|
51
|
+
"@earendil-works/pi-coding-agent": "^1.2.0",
|
|
52
|
+
"@earendil-works/pi-tui": "^1.2.0"
|
|
48
53
|
}
|
|
49
|
-
}
|
|
54
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Two-axis review of a task-scoped candidate against an explicit baseline:
|
|
2
2
|
|
|
3
|
-
- **Standards
|
|
4
|
-
- **Spec** — does the code faithfully implement the originating issue / PRD / spec? If the spec contains Gherkin scenarios (from [bdd](bdd.md)), those are the authoritative acceptance criteria.
|
|
3
|
+
- **Standards**: does the code conform to this repo's documented coding standards?
|
|
4
|
+
- **Spec** — does the code faithfully implement the originating issue / PRD / spec? If the spec contains Gherkin scenarios (from [bdd](../references/bdd.md)), those are the authoritative acceptance criteria.
|
|
5
5
|
|
|
6
|
-
For a bounded change, one fresh reviewer can assess both axes and return separate verdicts. Use separate reviewers only when scale, distinct expertise, or repository policy justifies them. Without delegation, assess Standards then Spec and preserve the reports separately. Agent count is not evidence of independence or quality.
|
|
6
|
+
For a bounded change, one fresh reviewer can assess both axes and return separate verdicts. Use separate reviewers only when scale, distinct expertise, or repository policy justifies them. Start each delegated reviewer with a fresh context window, not inherited parent history. Without delegation, assess Standards then Spec and preserve the reports separately. Agent count is not evidence of independence or quality.
|
|
7
7
|
|
|
8
8
|
Use the confirmed requirements already available; an issue tracker is optional. Read repository issue-tracker guidance only when the spec actually lives there. Missing tracker setup is not a reason to start setup work for a local review.
|
|
9
9
|
|
|
@@ -35,18 +35,18 @@ On top of whatever the repo documents, the Standards axis always carries the **s
|
|
|
35
35
|
|
|
36
36
|
Each smell reads *what it is* → *how to fix*; match it against the diff:
|
|
37
37
|
|
|
38
|
-
- **Mysterious Name
|
|
39
|
-
- **Duplicated Code
|
|
40
|
-
- **Feature Envy
|
|
41
|
-
- **Data Clumps
|
|
42
|
-
- **Primitive Obsession
|
|
43
|
-
- **Repeated Switches
|
|
44
|
-
- **Shotgun Surgery
|
|
45
|
-
- **Divergent Change
|
|
46
|
-
- **Speculative Generality
|
|
47
|
-
- **Message Chains
|
|
48
|
-
- **Middle Man
|
|
49
|
-
- **Refused Bequest
|
|
38
|
+
- **Mysterious Name**: a function, variable, or type whose name doesn't reveal what it does or holds. → rename it; if no honest name comes, the design's murky.
|
|
39
|
+
- **Duplicated Code**: the same logic shape appears in more than one hunk or file in the change. → extract the shared shape, call it from both.
|
|
40
|
+
- **Feature Envy**: a method that reaches into another object's data more than its own. → move the method onto the data it envies.
|
|
41
|
+
- **Data Clumps**: the same few fields or params keep travelling together (a type wanting to be born). → bundle them into one type, pass that.
|
|
42
|
+
- **Primitive Obsession**: a primitive or string standing in for a domain concept that deserves its own type. → give the concept its own small type.
|
|
43
|
+
- **Repeated Switches**: the same `switch`/`if`-cascade on the same type recurs across the change. → replace with polymorphism, or one map both sites share.
|
|
44
|
+
- **Shotgun Surgery**: one logical change forces scattered edits across many files in the diff. → gather what changes together into one module.
|
|
45
|
+
- **Divergent Change**: one file or module is edited for several unrelated reasons. → split so each module changes for one reason.
|
|
46
|
+
- **Speculative Generality**: abstraction, parameters, or hooks added for needs the spec doesn't have. → delete it; inline back until a real need shows.
|
|
47
|
+
- **Message Chains**: long `a.b().c().d()` navigation the caller shouldn't depend on. → hide the walk behind one method on the first object.
|
|
48
|
+
- **Middle Man**: a class or function that mostly just delegates onward. → cut it, call the real target direct.
|
|
49
|
+
- **Refused Bequest**: a subclass or implementer that ignores or overrides most of what it inherits. → drop the inheritance, use composition.
|
|
50
50
|
|
|
51
51
|
### AI slop baseline
|
|
52
52
|
|
|
@@ -76,13 +76,21 @@ Give the reviewer both briefs for bounded work, or one brief per reviewer when s
|
|
|
76
76
|
- The spec or confirmed conversation requirements and scenarios.
|
|
77
77
|
- The brief: "Report: (a) Gherkin scenarios (Given/When/Then) in the spec that are missing or partial; (b) behaviour in the diff that wasn't asked for (scope creep); (c) requirements that look implemented but where the implementation looks wrong. If the spec contains Gherkin scenarios, those are the authoritative acceptance criteria. Quote the spec line for each finding. Under 400 words."
|
|
78
78
|
|
|
79
|
+
Unconfirmed scope creep is a Spec finding; non-breaking behavior requires an explicit compatibility requirement before Spec PASS.
|
|
80
|
+
|
|
79
81
|
If the spec is missing, skip the Spec review and note this in the final report.
|
|
80
82
|
|
|
83
|
+
### Evidence for causal claims
|
|
84
|
+
|
|
85
|
+
Before calling a concurrency guard load-bearing, show a reachable interleaving using the actual public API: which operation replaces or deletes the entry, when each callback runs, and how the guard changes the observable result. A hypothetical future invalidation or replacement operation is not evidence about this candidate. If no such operation exists, describe the guard as redundant or a deliberate readability preference, not as a verified race fix. Apply the same standard to other causal claims: distinguish an observed failure, a source-supported possibility, and an untested hypothesis. Green tests alone do not prove the explanation.
|
|
86
|
+
|
|
87
|
+
A judgement call changes confidence, not the verdict: once the report identifies an unresolved smell, Standards is REWORK even if no lint rule prohibits it. If current evidence shows the candidate is not a smell, explain that refutation and remove it from the findings; naming it a deliberate preference or a safeguard for a hypothetical future API does not resolve it. Do not let a necessary rejection handler justify a separate redundant identity guard by association.
|
|
88
|
+
|
|
81
89
|
### 5. Aggregate
|
|
82
90
|
|
|
83
91
|
Present the two reports under `## Standards` and `## Spec` headings, verbatim or lightly cleaned. Do **not** merge or rerank findings — the two axes are deliberately separate (see _Why two axes_).
|
|
84
92
|
|
|
85
|
-
End with a one-line summary: total findings per axis, and the worst issue _within each axis_ (if any). Don't pick a single winner across axes
|
|
93
|
+
End with a one-line summary: total findings per axis, and the worst issue _within each axis_ (if any). Don't pick a single winner across axes: that's the reranking the separation exists to prevent.
|
|
86
94
|
|
|
87
95
|
### 5.3 Owner remediation and recheck handoff
|
|
88
96
|
|
|
@@ -107,7 +115,7 @@ In step 5.5's Standards scoring, treat a read memory file as a red flag: if the
|
|
|
107
115
|
After presenting the two reports, emit a binary verdict per axis:
|
|
108
116
|
|
|
109
117
|
- **Standards axis**: binary PASS (no unresolved standard violations or smells in the Standards report) / REWORK (any standard violation or listed smell).
|
|
110
|
-
- **Spec axis**:
|
|
118
|
+
- **Spec axis**: PASS requires every scenario, no unresolved scope creep, and no wrong implementation; otherwise REWORK. Non-breaking fallback requires an explicit compatibility requirement.
|
|
111
119
|
|
|
112
120
|
**Refute-before-PASS (red-team protocol):** Before assigning PASS to either axis, attempt to refute your own PASS:
|
|
113
121
|
|
|
@@ -4,19 +4,19 @@ Design **deep modules**: a lot of behaviour behind a small interface, placed at
|
|
|
4
4
|
|
|
5
5
|
## Glossary
|
|
6
6
|
|
|
7
|
-
Use these terms exactly
|
|
7
|
+
Use these terms exactly: don't substitute "component," "service," "API," or "boundary." Consistent language is the whole point.
|
|
8
8
|
|
|
9
|
-
**Module
|
|
9
|
+
**Module**: anything with an interface and an implementation. Deliberately scale-agnostic: a function, class, package, or tier-spanning slice. _Avoid_: unit, component, service.
|
|
10
10
|
|
|
11
|
-
**Interface
|
|
11
|
+
**Interface**: everything a caller must know to use the module correctly: the type signature, but also invariants, ordering constraints, error modes, required configuration, and performance characteristics. _Avoid_: API, signature (too narrow, they refer only to the type-level surface).
|
|
12
12
|
|
|
13
|
-
**Implementation
|
|
13
|
+
**Implementation**: what's inside a module, its body of code. Distinct from **Adapter**: a thing can be a small adapter with a large implementation (a Postgres repo) or a large adapter with a small implementation (an in-memory fake). Reach for "adapter" when the seam is the topic; "implementation" otherwise.
|
|
14
14
|
|
|
15
15
|
**Depth** — leverage at the interface: the amount of behaviour a caller (or test) can exercise per unit of interface they have to learn. A module is **deep** when a large amount of behaviour sits behind a small interface, **shallow** when the interface is nearly as complex as the implementation.
|
|
16
16
|
|
|
17
|
-
**Seam** _(Michael Feathers)_
|
|
17
|
+
**Seam** _(Michael Feathers)_: a place where you can alter behaviour without editing in that place; the *location* at which a module's interface lives. Where to put the seam is its own design decision, distinct from what goes behind it. _Avoid_: boundary (overloaded with DDD's bounded context).
|
|
18
18
|
|
|
19
|
-
**Adapter
|
|
19
|
+
**Adapter**: a concrete thing that satisfies an interface at a seam. Describes *role* (what slot it fills), not substance (what's inside).
|
|
20
20
|
|
|
21
21
|
**Leverage** — what callers get from depth: more capability per unit of interface they learn. One implementation pays back across N call sites and M tests.
|
|
22
22
|
|
|
@@ -58,7 +58,8 @@ When designing an interface, ask:
|
|
|
58
58
|
|
|
59
59
|
## Principles
|
|
60
60
|
|
|
61
|
-
- **
|
|
61
|
+
- **Separate sourced requirements from proposed invariants.** Attribute only verified requirements to a spec. Label unsupported constraints, error modes, and business policies as assumptions or unresolved decisions; a proposed interface does not turn them into existing requirements.
|
|
62
|
+
- **Depth is a property of the interface, not the implementation.** A deep module can be internally composed of small, mockable, swappable parts; they just aren't part of the interface. A module can have **internal seams** (private to its implementation, used by its own tests) as well as the **external seam** at its interface.
|
|
62
63
|
- **The deletion test.** Imagine deleting the module. If complexity vanishes, it was a pass-through. If complexity reappears across N callers, it was earning its keep.
|
|
63
64
|
- **The interface is the test surface.** Callers and tests cross the same seam. If you want to test *past* the interface, the module is probably the wrong shape.
|
|
64
65
|
- **One adapter means a hypothetical seam. Two adapters means a real one.** Don't introduce a seam unless something actually varies across it.
|
|
@@ -104,10 +105,10 @@ Good interfaces make testing natural:
|
|
|
104
105
|
## Rejected framings
|
|
105
106
|
|
|
106
107
|
- **Depth as ratio of implementation-lines to interface-lines** (Ousterhout): rewards padding the implementation. We use depth-as-leverage instead.
|
|
107
|
-
- **"Interface" as the TypeScript `interface` keyword or a class's public methods**: too narrow
|
|
108
|
+
- **"Interface" as the TypeScript `interface` keyword or a class's public methods**: too narrow: interface here includes every fact a caller must know.
|
|
108
109
|
- **"Boundary"**: overloaded with DDD's bounded context. Say **seam** or **interface**.
|
|
109
110
|
|
|
110
111
|
## Going deeper
|
|
111
112
|
|
|
112
|
-
- **Deepening a cluster given its dependencies
|
|
113
|
-
- **Exploring alternative interfaces** — see [DESIGN-IT-TWICE.md](DESIGN-IT-TWICE.md): use teammates when the teammate facility is available, otherwise develop several designs sequentially, then compare depth, locality, and seam placement.
|
|
113
|
+
- **Deepening a cluster given its dependencies**, see [DEEPENING.md](../references/DEEPENING.md): dependency categories, seam discipline, and replace-don't-layer testing.
|
|
114
|
+
- **Exploring alternative interfaces** — see [DESIGN-IT-TWICE.md](../references/DESIGN-IT-TWICE.md): use teammates when the teammate facility is available, otherwise develop several designs sequentially, then compare depth, locality, and seam placement.
|
package/procedures/deslop.md
CHANGED
|
@@ -31,6 +31,8 @@ Resolve the change set before touching anything:
|
|
|
31
31
|
|
|
32
32
|
### 2. Inventory findings
|
|
33
33
|
|
|
34
|
+
For a compound guard, justify each predicate separately by tracing the exact expression and conversion order on a concrete input. A failure rejected by another predicate does not prove this one necessary. If no distinguishing input is established, record the claimed necessity as unverified rather than converting a redundant check into a proven requirement. Removing a proven inert predicate preserves the accepted grammar and does not require changing the spec or obtaining a new product decision. Reconcile cleanup, review and handoff verdicts against the final candidate after remediation.
|
|
35
|
+
|
|
34
36
|
Scan the scope once per category. Produce a findings list: category, location (file plus hunk), the offending line quoted, and the replacement plan. A finding without a concrete replacement plan is not ready to fix — leave it as a reported finding.
|
|
35
37
|
|
|
36
38
|
### 3. Rewrite
|
|
@@ -43,7 +45,7 @@ Apply the plans in one pass, category by category. For each rewrite:
|
|
|
43
45
|
|
|
44
46
|
### 4. Verify
|
|
45
47
|
|
|
46
|
-
Run the verification the repository already uses — tests, typecheck, and lint. A de-slop pass ends green or it has not ended.
|
|
48
|
+
Run the verification the repository already uses — tests, typecheck, and lint. A de-slop pass ends green or it has not ended. Record each actually failed command and its observed result separately from reasoning about an unexecuted alternative. Do not describe a rejected design, source inspection or hypothetical regression as a test failure unless that candidate was executed and failed. Label untested conclusions and preserve the real verification sequence in cleanup and handoff notes. Reconcile the summary, findings, verdict and handoff against that sequence before finishing; remove contradictory counts or claims about failed attempts.
|
|
47
49
|
|
|
48
50
|
### 5. Verdict
|
|
49
51
|
|
|
@@ -53,4 +55,4 @@ Report under three headings:
|
|
|
53
55
|
- **Findings** — slop that could not be removed without a behavior change, test coverage, or a design decision, each with the reason.
|
|
54
56
|
- **Skipped** — categories skipped because repository tooling already enforces them.
|
|
55
57
|
|
|
56
|
-
End with a binary verdict: **CLEAN** only if every planned rewrite landed
|
|
58
|
+
End with a binary verdict: **CLEAN** only if every planned rewrite landed, verification is green, and no findings remain; **PARTIAL** when findings remain. A retained finding cannot be made CLEAN by excluding it from the rewrite plan. A readability preference is not a behavioral compatibility requirement: if a known redundant check is kept only to document intent, state that reason honestly and keep the finding in the PARTIAL verdict. Proven necessary guards are not clutter; explain their current requirement rather than listing them as unresolved findings. Never report CLEAN with unverified skips.
|