@gotgenes/pi-subagents 18.0.1 → 18.0.3

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.
Files changed (268) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/docs/architecture/architecture.md +165 -203
  3. package/docs/architecture/history/phase-19-implement-ui-decisions.md +282 -0
  4. package/package.json +6 -7
  5. package/src/config/default-agents.ts +3 -0
  6. package/src/lifecycle/subagent.ts +25 -14
  7. package/src/observation/notification.ts +23 -10
  8. package/src/observation/subagent-events-observer.ts +1 -3
  9. package/src/runtime.ts +2 -1
  10. package/src/service/service-adapter.ts +20 -17
  11. package/src/session/model-resolver.ts +31 -30
  12. package/src/tools/agent-tool.ts +17 -13
  13. package/src/tools/get-result-report.ts +60 -0
  14. package/src/tools/get-result-tool.ts +25 -40
  15. package/src/tools/helpers.ts +21 -5
  16. package/src/tools/spawn-config.ts +5 -5
  17. package/src/tools/steer-tool.ts +37 -27
  18. package/src/types.ts +4 -1
  19. package/src/ui/session-navigator.ts +0 -2
  20. package/.prettierignore +0 -5
  21. package/AGENTS.md +0 -7
  22. package/docs/plans/0048-implement-subagents-api.md +0 -304
  23. package/docs/plans/0049-remove-group-join-output-file-rpc.md +0 -180
  24. package/docs/plans/0051-update-adr-0001-hard-fork.md +0 -77
  25. package/docs/plans/0052-remove-scheduled-subagents.md +0 -133
  26. package/docs/plans/0053-extract-model-resolution-from-execute.md +0 -181
  27. package/docs/plans/0054-decompose-index-into-modules.md +0 -302
  28. package/docs/plans/0057-structured-debug-logging.md +0 -154
  29. package/docs/plans/0061-session-format-transcript.md +0 -284
  30. package/docs/plans/0066-replace-as-any-with-sdk-types.md +0 -215
  31. package/docs/plans/0069-create-subagent-runtime.md +0 -345
  32. package/docs/plans/0070-extract-event-handlers.md +0 -306
  33. package/docs/plans/0071-extract-session-config-assembler.md +0 -362
  34. package/docs/plans/0072-inject-agent-manager-collaborators.md +0 -329
  35. package/docs/plans/0076-inject-cwd-into-agent-manager.md +0 -102
  36. package/docs/plans/0077-inject-project-agents-dir.md +0 -115
  37. package/docs/plans/0080-consolidate-agent-config-lookup.md +0 -247
  38. package/docs/plans/0084-extract-git-worktree-manager.md +0 -142
  39. package/docs/plans/0087-evolve-subagent-runtime-methods.md +0 -240
  40. package/docs/plans/0098-extract-agent-record-state-machine.md +0 -435
  41. package/docs/plans/0099-replace-ctx-with-parent-snapshot.md +0 -488
  42. package/docs/plans/0100-replace-callback-threading-with-session-subscription.md +0 -454
  43. package/docs/plans/0102-consolidate-test-record-factory.md +0 -176
  44. package/docs/plans/0108-extract-agent-type-registry.md +0 -322
  45. package/docs/plans/0109-extract-settings-manager.md +0 -276
  46. package/docs/plans/0110-agent-activity-tracker.md +0 -297
  47. package/docs/plans/0111-split-agent-record-lifecycle.md +0 -582
  48. package/docs/plans/0112-replace-agent-manager-callbacks.md +0 -241
  49. package/docs/plans/0113-disambiguate-spawn-options.md +0 -155
  50. package/docs/plans/0114-narrow-agent-tool-menu-deps.md +0 -279
  51. package/docs/plans/0115-decompose-agent-tool.md +0 -337
  52. package/docs/plans/0116-type-housekeeping.md +0 -351
  53. package/docs/plans/0118-settings-manager-apply-methods.md +0 -271
  54. package/docs/plans/0123-remove-vi-fn-cast-smell.md +0 -179
  55. package/docs/plans/0131-consolidate-shared-test-fixtures.md +0 -207
  56. package/docs/plans/0132-inject-io-into-session-config.md +0 -219
  57. package/docs/plans/0133-inject-sdk-boundary-into-agent-runner.md +0 -373
  58. package/docs/plans/0134-reduce-as-any-casts.md +0 -366
  59. package/docs/plans/0135-extract-display-helpers.md +0 -182
  60. package/docs/plans/0136-decompose-agent-menu.md +0 -300
  61. package/docs/plans/0144-consolidate-observation-model.md +0 -263
  62. package/docs/plans/0145-decompose-execute-push-ctx-to-boundary.md +0 -290
  63. package/docs/plans/0146-narrow-ui-context.md +0 -319
  64. package/docs/plans/0147-inject-wrap-text-into-conversation-viewer.md +0 -166
  65. package/docs/plans/0148-split-agent-widget-rendering.md +0 -255
  66. package/docs/plans/0152-add-prompt-snippet.md +0 -91
  67. package/docs/plans/0164-reorganize-into-domain-directories.md +0 -409
  68. package/docs/plans/0165-decompose-resolved-spawn-config.md +0 -157
  69. package/docs/plans/0166-extract-parent-session-info.md +0 -231
  70. package/docs/plans/0167-narrow-runner-io.md +0 -150
  71. package/docs/plans/0168-extract-tool-filter-config.md +0 -173
  72. package/docs/plans/0169-extract-run-context-from-run-options.md +0 -194
  73. package/docs/plans/0170-reduce-build-content-lines-complexity.md +0 -225
  74. package/docs/plans/0171-reduce-render-result-complexity.md +0 -200
  75. package/docs/plans/0172-extract-turn-formatting.md +0 -206
  76. package/docs/plans/0180-reorder-append-prompt-for-kv-cache.md +0 -100
  77. package/docs/plans/0185-remove-persistent-agent-memory.md +0 -161
  78. package/docs/plans/0188-replace-any-casts-with-sdk-types.md +0 -162
  79. package/docs/plans/0192-define-session-context-interface.md +0 -107
  80. package/docs/plans/0193-runtime-owns-context-queries.md +0 -245
  81. package/docs/plans/0194-align-tool-interfaces-for-structural-typing.md +0 -139
  82. package/docs/plans/0195-convert-tool-factories-to-classes.md +0 -264
  83. package/docs/plans/0196-convert-runner-menu-to-classes.md +0 -268
  84. package/docs/plans/0205-decompose-render-widget-lines.md +0 -140
  85. package/docs/plans/0206-decompose-show-agent-detail.md +0 -211
  86. package/docs/plans/0207-decompose-agent-widget-update.md +0 -242
  87. package/docs/plans/0208-extract-shared-test-fixtures.md +0 -298
  88. package/docs/plans/0214-convert-remaining-closure-factories-to-classes.md +0 -261
  89. package/docs/plans/0215-decompose-build-parent-context.md +0 -166
  90. package/docs/plans/0216-decompose-start-agent.md +0 -255
  91. package/docs/plans/0217-extract-overwrite-guard.md +0 -176
  92. package/docs/plans/0218-push-sdk-boundary-in-settings.md +0 -172
  93. package/docs/plans/0219-reduce-test-duplication-top-3-clone-families.md +0 -162
  94. package/docs/plans/0227-evolve-agent-record-into-agent.md +0 -322
  95. package/docs/plans/0228-async-start-agent-dissolve-run-handle.md +0 -288
  96. package/docs/plans/0229-agent-born-complete.md +0 -564
  97. package/docs/plans/0230-extract-concurrency-queue.md +0 -265
  98. package/docs/plans/0231-push-exec-registry-to-runner.md +0 -245
  99. package/docs/plans/0232-agent-resume-internal-observer-lifecycle.md +0 -180
  100. package/docs/plans/0237-remove-disallowed-tools.md +0 -180
  101. package/docs/plans/0238-remove-extensions-filtering.md +0 -191
  102. package/docs/plans/0239-collapse-filter-active-tools.md +0 -217
  103. package/docs/plans/0242-rename-agent-tool-to-subagent.md +0 -165
  104. package/docs/plans/0256-extract-worktree-isolation.md +0 -256
  105. package/docs/plans/0257-extract-child-session-factory.md +0 -285
  106. package/docs/plans/0262-add-workspace-provider-seam.md +0 -264
  107. package/docs/plans/0264-remove-extension-lifecycle-control.md +0 -277
  108. package/docs/plans/0265-born-complete-subagent-session.md +0 -333
  109. package/docs/plans/0270-type-consumable-public-surface.md +0 -204
  110. package/docs/plans/0272-export-workspace-collaborator-types.md +0 -147
  111. package/docs/plans/0277-encapsulate-agent-session.md +0 -304
  112. package/docs/plans/0280-rename-agent-to-subagent.md +0 -197
  113. package/docs/plans/0360-custom-agents-default-append.md +0 -132
  114. package/docs/plans/0373-extract-subagent-state.md +0 -250
  115. package/docs/plans/0374-encapsulate-subagent-start-notification.md +0 -268
  116. package/docs/plans/0375-extract-run-listener-workspace-bracket.md +0 -300
  117. package/docs/plans/0376-extract-manager-observer.md +0 -232
  118. package/docs/plans/0377-split-widget-delegation-from-runtime.md +0 -254
  119. package/docs/plans/0378-consolidate-lifecycle-test-fixtures.md +0 -243
  120. package/docs/plans/0379-consolidate-ui-tools-test-fixtures.md +0 -335
  121. package/docs/plans/0380-extract-layered-settings-loader.md +0 -223
  122. package/docs/plans/0381-replace-concurrency-queue-with-limiter.md +0 -267
  123. package/docs/plans/0400-include-parent-prompt-in-replace-mode.md +0 -199
  124. package/docs/plans/0403-abort-subagents-on-interrupt.md +0 -180
  125. package/docs/plans/0412-unify-session-mock-builders.md +0 -146
  126. package/docs/plans/0420-fold-run-metrics-live-activity-onto-record.md +0 -228
  127. package/docs/plans/0421-migrate-activity-readers-to-record-getters.md +0 -309
  128. package/docs/plans/0422-delete-activity-tracker-ui-observer.md +0 -204
  129. package/docs/plans/0423-widget-self-drive-from-lifecycle.md +0 -264
  130. package/docs/plans/0424-drop-widget-dep-from-subagent-tool.md +0 -166
  131. package/docs/plans/0425-reconcile-subagent-events-contract.md +0 -144
  132. package/docs/plans/0426-consolidate-residual-test-clone-families.md +0 -235
  133. package/docs/plans/0427-reconsider-ui-direction.md +0 -212
  134. package/docs/plans/0441-remove-agent-definition-management-subtree.md +0 -180
  135. package/docs/plans/0442-dissolve-agents-conversation-viewer.md +0 -195
  136. package/docs/plans/0443-consolidate-remaining-test-clone-families.md +0 -268
  137. package/docs/plans/0444-shrink-widget-to-background-agents.md +0 -156
  138. package/docs/plans/0445-native-session-navigation.md +0 -365
  139. package/docs/plans/0446-spike-session-navigation-entry-criteria.md +0 -171
  140. package/docs/plans/0447-extract-subagents-settings-command.md +0 -220
  141. package/docs/plans/0448-block-disabled-agent-spawn.md +0 -207
  142. package/docs/plans/0462-navigation-renderer-tui-components.md +0 -338
  143. package/docs/plans/0463-file-snapshot-source-evicted-agents.md +0 -306
  144. package/docs/plans/0470-refresh-readme-command-surface.md +0 -159
  145. package/docs/retro/0048-implement-subagents-api.md +0 -44
  146. package/docs/retro/0049-remove-group-join-output-file-rpc.md +0 -49
  147. package/docs/retro/0051-update-adr-0001-hard-fork.md +0 -39
  148. package/docs/retro/0053-extract-model-resolution-from-execute.md +0 -40
  149. package/docs/retro/0054-decompose-index-into-modules.md +0 -53
  150. package/docs/retro/0057-structured-debug-logging.md +0 -77
  151. package/docs/retro/0061-session-format-transcript.md +0 -41
  152. package/docs/retro/0066-replace-as-any-with-sdk-types.md +0 -44
  153. package/docs/retro/0069-create-subagent-runtime.md +0 -43
  154. package/docs/retro/0070-extract-event-handlers.md +0 -49
  155. package/docs/retro/0071-extract-session-config-assembler.md +0 -60
  156. package/docs/retro/0072-inject-agent-manager-collaborators.md +0 -46
  157. package/docs/retro/0076-inject-cwd-into-agent-manager.md +0 -35
  158. package/docs/retro/0077-inject-project-agents-dir.md +0 -33
  159. package/docs/retro/0080-consolidate-agent-config-lookup.md +0 -35
  160. package/docs/retro/0084-extract-git-worktree-manager.md +0 -37
  161. package/docs/retro/0087-evolve-subagent-runtime-methods.md +0 -42
  162. package/docs/retro/0098-extract-agent-record-state-machine.md +0 -46
  163. package/docs/retro/0099-replace-ctx-with-parent-snapshot.md +0 -37
  164. package/docs/retro/0100-replace-callback-threading-with-session-subscription.md +0 -36
  165. package/docs/retro/0102-consolidate-test-record-factory.md +0 -30
  166. package/docs/retro/0108-extract-agent-type-registry.md +0 -41
  167. package/docs/retro/0109-extract-settings-manager.md +0 -55
  168. package/docs/retro/0110-agent-activity-tracker.md +0 -44
  169. package/docs/retro/0111-split-agent-record-lifecycle.md +0 -61
  170. package/docs/retro/0112-replace-agent-manager-callbacks.md +0 -35
  171. package/docs/retro/0113-disambiguate-spawn-options.md +0 -29
  172. package/docs/retro/0114-narrow-agent-tool-menu-deps.md +0 -38
  173. package/docs/retro/0115-decompose-agent-tool.md +0 -51
  174. package/docs/retro/0116-type-housekeeping.md +0 -42
  175. package/docs/retro/0118-settings-manager-apply-methods.md +0 -40
  176. package/docs/retro/0123-remove-vi-fn-cast-smell.md +0 -49
  177. package/docs/retro/0131-consolidate-shared-test-fixtures.md +0 -46
  178. package/docs/retro/0132-inject-io-into-session-config.md +0 -33
  179. package/docs/retro/0133-inject-sdk-boundary-into-agent-runner.md +0 -45
  180. package/docs/retro/0134-reduce-as-any-casts.md +0 -56
  181. package/docs/retro/0135-extract-display-helpers.md +0 -38
  182. package/docs/retro/0136-decompose-agent-menu.md +0 -43
  183. package/docs/retro/0144-consolidate-observation-model.md +0 -39
  184. package/docs/retro/0145-decompose-execute-push-ctx-to-boundary.md +0 -56
  185. package/docs/retro/0146-narrow-ui-context.md +0 -70
  186. package/docs/retro/0147-inject-wrap-text-into-conversation-viewer.md +0 -90
  187. package/docs/retro/0148-split-agent-widget-rendering.md +0 -39
  188. package/docs/retro/0152-add-prompt-snippet.md +0 -34
  189. package/docs/retro/0164-reorganize-into-domain-directories.md +0 -82
  190. package/docs/retro/0165-decompose-resolved-spawn-config.md +0 -78
  191. package/docs/retro/0166-extract-parent-session-info.md +0 -66
  192. package/docs/retro/0167-narrow-runner-io.md +0 -63
  193. package/docs/retro/0168-extract-tool-filter-config.md +0 -76
  194. package/docs/retro/0169-extract-run-context-from-run-options.md +0 -68
  195. package/docs/retro/0170-reduce-build-content-lines-complexity.md +0 -72
  196. package/docs/retro/0171-reduce-render-result-complexity.md +0 -77
  197. package/docs/retro/0172-extract-turn-formatting.md +0 -80
  198. package/docs/retro/0180-reorder-append-prompt-for-kv-cache.md +0 -62
  199. package/docs/retro/0185-remove-persistent-agent-memory.md +0 -73
  200. package/docs/retro/0188-replace-any-casts-with-sdk-types.md +0 -69
  201. package/docs/retro/0192-define-session-context-interface.md +0 -59
  202. package/docs/retro/0193-runtime-owns-context-queries.md +0 -75
  203. package/docs/retro/0194-align-tool-interfaces-for-structural-typing.md +0 -62
  204. package/docs/retro/0195-convert-tool-factories-to-classes.md +0 -84
  205. package/docs/retro/0196-convert-runner-menu-to-classes.md +0 -73
  206. package/docs/retro/0205-decompose-render-widget-lines.md +0 -64
  207. package/docs/retro/0206-decompose-show-agent-detail.md +0 -67
  208. package/docs/retro/0207-decompose-agent-widget-update.md +0 -92
  209. package/docs/retro/0208-extract-shared-test-fixtures.md +0 -102
  210. package/docs/retro/0214-convert-remaining-closure-factories-to-classes.md +0 -66
  211. package/docs/retro/0215-decompose-build-parent-context.md +0 -61
  212. package/docs/retro/0216-decompose-start-agent.md +0 -80
  213. package/docs/retro/0217-extract-overwrite-guard.md +0 -63
  214. package/docs/retro/0218-push-sdk-boundary-in-settings.md +0 -72
  215. package/docs/retro/0219-reduce-test-duplication-top-3-clone-families.md +0 -64
  216. package/docs/retro/0227-evolve-agent-record-into-agent.md +0 -80
  217. package/docs/retro/0228-async-start-agent-dissolve-run-handle.md +0 -80
  218. package/docs/retro/0229-agent-born-complete.md +0 -89
  219. package/docs/retro/0230-extract-concurrency-queue.md +0 -38
  220. package/docs/retro/0231-push-exec-registry-to-runner.md +0 -71
  221. package/docs/retro/0232-agent-resume-internal-observer-lifecycle.md +0 -109
  222. package/docs/retro/0237-remove-disallowed-tools.md +0 -78
  223. package/docs/retro/0238-remove-extensions-filtering.md +0 -72
  224. package/docs/retro/0239-collapse-filter-active-tools.md +0 -70
  225. package/docs/retro/0242-rename-agent-tool-to-subagent.md +0 -82
  226. package/docs/retro/0256-extract-worktree-isolation.md +0 -89
  227. package/docs/retro/0257-extract-child-session-factory.md +0 -33
  228. package/docs/retro/0262-add-workspace-provider-seam.md +0 -89
  229. package/docs/retro/0264-remove-extension-lifecycle-control.md +0 -91
  230. package/docs/retro/0265-born-complete-subagent-session.md +0 -97
  231. package/docs/retro/0270-type-consumable-public-surface.md +0 -108
  232. package/docs/retro/0272-export-workspace-collaborator-types.md +0 -38
  233. package/docs/retro/0277-encapsulate-agent-session.md +0 -80
  234. package/docs/retro/0280-rename-agent-to-subagent.md +0 -96
  235. package/docs/retro/0360-custom-agents-default-append.md +0 -81
  236. package/docs/retro/0373-extract-subagent-state.md +0 -94
  237. package/docs/retro/0374-encapsulate-subagent-start-notification.md +0 -171
  238. package/docs/retro/0375-extract-run-listener-workspace-bracket.md +0 -104
  239. package/docs/retro/0376-extract-manager-observer.md +0 -81
  240. package/docs/retro/0377-split-widget-delegation-from-runtime.md +0 -105
  241. package/docs/retro/0378-consolidate-lifecycle-test-fixtures.md +0 -100
  242. package/docs/retro/0379-consolidate-ui-tools-test-fixtures.md +0 -52
  243. package/docs/retro/0380-extract-layered-settings-loader.md +0 -97
  244. package/docs/retro/0381-replace-concurrency-queue-with-limiter.md +0 -95
  245. package/docs/retro/0400-include-parent-prompt-in-replace-mode.md +0 -84
  246. package/docs/retro/0403-abort-subagents-on-interrupt.md +0 -90
  247. package/docs/retro/0412-unify-session-mock-builders.md +0 -80
  248. package/docs/retro/0420-fold-run-metrics-live-activity-onto-record.md +0 -90
  249. package/docs/retro/0421-migrate-activity-readers-to-record-getters.md +0 -105
  250. package/docs/retro/0422-delete-activity-tracker-ui-observer.md +0 -97
  251. package/docs/retro/0423-widget-self-drive-from-lifecycle.md +0 -112
  252. package/docs/retro/0424-drop-widget-dep-from-subagent-tool.md +0 -89
  253. package/docs/retro/0425-reconcile-subagent-events-contract.md +0 -101
  254. package/docs/retro/0426-consolidate-residual-test-clone-families.md +0 -100
  255. package/docs/retro/0427-reconsider-ui-direction.md +0 -102
  256. package/docs/retro/0441-remove-agent-definition-management-subtree.md +0 -97
  257. package/docs/retro/0442-dissolve-agents-conversation-viewer.md +0 -108
  258. package/docs/retro/0443-consolidate-remaining-test-clone-families.md +0 -28
  259. package/docs/retro/0444-shrink-widget-to-background-agents.md +0 -81
  260. package/docs/retro/0445-native-session-navigation.md +0 -122
  261. package/docs/retro/0446-spike-session-navigation-entry-criteria.md +0 -99
  262. package/docs/retro/0447-extract-subagents-settings-command.md +0 -91
  263. package/docs/retro/0448-block-disabled-agent-spawn.md +0 -75
  264. package/docs/retro/0462-navigation-renderer-tui-components.md +0 -105
  265. package/docs/retro/0463-file-snapshot-source-evicted-agents.md +0 -103
  266. package/docs/retro/0470-refresh-readme-command-surface.md +0 -40
  267. package/src/observation/notification-state.ts +0 -27
  268. package/vitest.config.ts +0 -14
@@ -1,52 +0,0 @@
1
- ---
2
- issue: 379
3
- issue_title: "Consolidate UI and tools test fixtures"
4
- ---
5
-
6
- # Retro: #379 — Consolidate UI and tools test fixtures
7
-
8
- ## Stage: Planning (2026-06-16T00:00:00Z)
9
-
10
- ### Session summary
11
-
12
- Produced a 9-step lift-and-shift plan for Phase 17 Step 8 — consolidating the non-lifecycle test clone families.
13
- Measured the live baseline (`fallow dupes -r packages/pi-subagents`: 32 clone groups / 512 lines / 2.49%, seven families) and characterized each family by reading all seven test files, classifying each as genuine cross-file duplication (one) versus intra-file (six).
14
-
15
- ### Observations
16
-
17
- - The only genuine cross-file duplication is the `ResolvedSpawnConfig` builder shared by `foreground-runner.test.ts` and `background-spawner.test.ts` (`dup:80ee2004`) — the one promotion to `test/helpers/` (`make-spawn-config.ts`).
18
- Everything else fallow scores same-file, so it stays file-local or moves into a describe-scoped `beforeEach`, per Step 7's ([#378]) discipline.
19
- - The plan's central constraint is Step 7's hard-won lesson: never wrap the system-under-test **act** in a helper to chase a duplication metric.
20
- Every extracted helper returns a value (`createResolvedSpawnConfig`, `disabledConfig`, `exploreConfig`, `createManagerStub`, `spawnAndWaitRegistering`) or seeds `beforeEach`; the acts stay inline.
21
- Added an "Invariants at risk" grep check to enforce this at review.
22
- - Scope was genuinely ambiguous and resolved via `ask_user`: the issue body names six files, but fallow reports a seventh non-lifecycle family in `test/service/service-adapter.test.ts` (four near-identical `SubagentManagerLike` stubs).
23
- Operator chose to include service-adapter (seven files total) and to **not** bind a numeric group target — acceptance is "each named family consolidated, resulting fallow numbers reported."
24
- My `ask_user` prompt incorrectly claimed the architecture roadmap's Step 8 `Targets` lists service-adapter; it does not (it lists the six issue-body files).
25
- The plan corrects this and notes service-adapter was added in planning.
26
- - The roadmap's stated Step 8 outcome ("clone groups 44 → ≤ 25; overall duplication ≤ 0.6%") predates Steps 1–7 and does not match the current fallow metric (2.49%); flagged as an Open Question rather than treated as binding.
27
- - Non-Goals call out the two residual lifecycle families (Step 7 left them as the visible act), the 11-line production clone inside `src/ui/agent-config-editor.ts` (test-only issue), and the three overlapping session-mock builders ([#412]).
28
- - `ResolvedSpawnConfig` is deeply nested (`identity`/`execution`/`presentation` with mirrored scalars).
29
- Designed the shared builder to take **flat** options and assemble the nested structure internally — sidesteps the `Partial<T>` deep-merge trap and encapsulates the mirroring (`agentInvocation.runInBackground`, `presentation.detailBase`) the hand-built copies duplicate.
30
-
31
- ## Stage: Implementation — TDD (2026-06-16T13:10:00Z)
32
-
33
- ### Session summary
34
-
35
- Executed all 9 plan steps as green-to-green lift-and-shift refactors (no red phase — the existing assertions were the spec), one commit per step plus the docs commit.
36
- Promoted the shared `createResolvedSpawnConfig` builder to `test/helpers/` (+5 self-tests) and consolidated the six remaining families with file-local value-returning builders / `beforeEach` setup.
37
- Test count 1010 → 1015; test files 63 → 64; clone groups 32 → 24; package test duplication 512 → 355 lines (2.49% → 1.73%).
38
-
39
- ### Observations
40
-
41
- - The `agent-config-editor.test.ts` family did not collapse as the plan loosely estimated ("4 → ideally 2"): it stayed at 4 groups / 28 lines.
42
- The `disabledConfig` helper removed only the small `enabled: false` arrange; the residual clones are the repeated `await editor.showAgentDetail(...)` **act** plus its `setupDetail` arrange and `ui.select.mock.calls` menu assertion — left inline because wrapping the system-under-test is the wrong abstraction (Step 7 lesson).
43
- No `ask_user` was needed: acceptance was "consolidate and measure" (no binding numeric target), and the only way to force the number would violate the plan's stated discipline.
44
- - `service-adapter.test.ts` had four near-identical `SubagentManagerLike` stub factories with diverging defaults (`hasRunning` true vs false, varying `spawn` returns).
45
- Consolidated into one file-local `createManagerStub()` with **unannotated** return (typed `vi.fn<SubagentManagerLike[...]>()` stubs) so callers retain `Mock<...>` methods — per the testing-skill rule that annotating the return with the production interface, or spreading `Partial<Interface>` overrides, erases mock methods.
46
- Dropped the overrides parameter entirely; per-test behavior is configured on the returned object (`mgr.getRecord.mockImplementation(...)`, `mgr.hasRunning.mockReturnValue(true)`).
47
- Used `sed` to swap the `defaultManager()` / `createTestManager()` call sites after deleting the factory definitions.
48
- - `ui-observer` update-counting tests moved from closure `let updateCount` counters to `vi.fn()` onUpdate with `toHaveBeenCalledTimes` — removes the repeated scaffolding without hiding the `session.emit` act.
49
- - Pre-completion reviewer: WARN — sole finding was this missing TDD retro entry (now written); all deterministic checks PASS, cross-step invariant ("don't wrap the act") verified upheld, 6 Mermaid blocks validated, dead-code clean.
50
-
51
- [#378]: https://github.com/gotgenes/pi-packages/issues/378
52
- [#412]: https://github.com/gotgenes/pi-packages/issues/412
@@ -1,97 +0,0 @@
1
- ---
2
- issue: 380
3
- issue_title: "Resolve the cross-package settings-loader duplication"
4
- ---
5
-
6
- # Retro: #380 — Resolve the cross-package settings-loader duplication
7
-
8
- ## Stage: Planning (2026-06-16T00:00:00Z)
9
-
10
- ### Session summary
11
-
12
- Planned the resolution of the 23-line cross-package production clone between `src/settings.ts` and `@gotgenes/pi-subagents-worktrees`'s `src/config.ts`.
13
- Issue #380 posed a binary: extract a shared loader vs. document-and-suppress.
14
- The operator chose extraction, delivered as a dedicated subpath export `@gotgenes/pi-subagents/settings`, sequenced as two stages (this plan lands the helper in pi-subagents; a follow-up migrates worktrees).
15
- The plan is a single-package TDD plan in `packages/pi-subagents/docs/plans/0380-extract-layered-settings-loader.md`.
16
-
17
- ### Observations
18
-
19
- - The issue is the operator's own (author `gotgenes` == gh user), so the "Proposed change" was a hypothesis.
20
- Used `ask_user` twice: first to confirm Option 1 vs Option 2 (operator picked extract, then asked for explicit for/against), then to pin API placement (`./settings` subpath, recommended) and release sequencing (two-stage, follow-up for worktrees).
21
- - Key mechanism finding that shaped the framing: fallow's `code-duplication` suppression is **file-scoped only** (`// fallow-ignore-file code-duplication`) — there is no line-level next-line directive, contrary to the issue's "rationale on the line above" phrasing for Option 2.
22
- This would have mattered had Option 2 been chosen.
23
- - The shared idiom is the read-sanitize-warn-merge mechanism; the per-package `sanitize` (numeric ceilings vs `string[]`) is the genuinely-different part.
24
- A generic `loadLayeredSettings<T>({ sanitize, warnLabel, filename, agentDir, cwd })` is a clean extraction with no discriminator parameter.
25
- - Honest Outcome caveat captured in the plan: because worktrees keeps its copy until the follow-up, `fallow:dupes` may still report a residual (or dissolve below `min-lines: 5`, since the generic helper's tokens diverge).
26
- Definitive elimination is the follow-up's outcome, not a hard gate on this plan.
27
- - Followed the `0270-type-consumable-public-surface.md` plan as the template for the `.d.ts`-bundle + `verify:public-types` machinery; the new subpath extends that rather than introducing a new mechanism.
28
- - `loadSettings`'s `process.cwd()` default is dropped per the code-design "no `process.*` in library functions" rule; the sole caller (`SettingsManager.load`) already passes `this.cwd` (verified by grep).
29
- - The worktrees-migration follow-up issue should be created at ship time and back-referenced from the architecture Step 9 roadmap entry.
30
-
31
- ## Stage: Implementation — TDD (2026-06-16T16:00:00Z)
32
-
33
- ### Session summary
34
-
35
- Completed all 4 TDD steps from the plan: added `src/layered-settings.ts` with 15 unit tests, refactored `settings.ts` to delegate through the helper (removing `readSettingsFile` and `globalPath`), published the `@gotgenes/pi-subagents/settings` subpath export with a rolled `dist/settings.d.ts` and extended `verify:public-types` harness, and recorded the decision in the architecture doc.
36
- Test count grew from 1015 to 1030 (+15).
37
- Pre-completion reviewer returned **PASS**.
38
- Follow-up issue [#415] created for the worktrees migration.
39
-
40
- ### Observations
41
-
42
- - The plan's "Outcome caveat" resolved favourably: `pnpm fallow:dupes --skip-local` no longer reports the `settings.ts` ↔ `config.ts` pair after the extraction.
43
- The parametrised helper's token sequence diverged enough that the contiguous identical run dropped below the reporting threshold — a better outcome than the plan's hedged prediction.
44
- - ESLint's pre-commit hook removed `!` non-null assertions from `spy.mock.calls[0]![0]` in the test file (typed `vi.spyOn` mock calls are non-optional tuples; the assertions were redundant).
45
- Staged the auto-fix into the same commit without issue.
46
- - The `rollup.dts.config.mjs` array-of-configs approach worked without incident: both bundles (`dist/public.d.ts` and `dist/settings.d.ts`) are self-contained and `verify:public-types` confirmed both probes type-check against the packaged tarball.
47
- - The `satisfies LayeredSettingsSource<SubagentsSettings>` annotation at the `loadSettings` call site serves double duty: validates the object literal and keeps `LayeredSettingsSource` referenced for fallow dead-code (fallow confirmed: 0 issues).
48
- - Follow-up issue [#415] created before the TDD stage notes were written (operator requested it during the session); architecture doc updated with the `[#415]` reference and link definition.
49
-
50
- ## Stage: Final Retrospective (2026-06-16T18:00:00Z)
51
-
52
- ### Session summary
53
-
54
- Shipped issue #380 end-to-end across four stages (plan → TDD → ship) in one session: extracted `loadLayeredSettings<T>` into `src/layered-settings.ts`, published it at the `@gotgenes/pi-subagents/settings` subpath, and adopted it internally in `settings.ts`.
55
- Released as `pi-subagents-v16.4.0`; CI passed first try; pre-completion reviewer returned PASS.
56
- Notably clean run — no rework, no failed commits, no rabbit-holes.
57
-
58
- ### Observations
59
-
60
- #### What went well
61
-
62
- - The two-stage `ask_user` planning gate worked as designed: it surfaced the binary (extract vs. suppress) neutrally, the operator engaged deeply (asked for explicit for/against before committing), and the answers drove the plan's Goals rather than the issue body.
63
- This is the intended use of `ask_user` for an operator-authored issue framed as "weigh two options."
64
- - Proactive tool-mechanism research paid off: `web_search` + `fetch_content` on the fallow docs during planning revealed that `code-duplication` suppression is **file-scoped only** (no line-level directive), which would have changed Option 2's shape had it been chosen.
65
- Checking the tool's real surface before planning around it caught a latent wrong assumption.
66
- - The plan's honestly-hedged "Outcome caveat" (clone might persist until the worktrees follow-up) resolved favourably — the parametrised helper diverged below fallow's threshold immediately.
67
- Hedging a quantitative prediction rather than over-promising left no credibility gap when the better outcome landed.
68
- - Incremental verification cadence: `pnpm run check` ran right after the interface-adjacent Step 2, vitest ran per-file in each Red/Green, and `build:types` + `verify:public-types` ran inside Step 3 — not deferred to the end.
69
- No feedback-loop gaps.
70
-
71
- #### What caused friction (agent side)
72
-
73
- - `missing-context` (process gap) — the plan's Open Questions flagged the worktrees follow-up issue as "created at ship time," but the `ship-issue` prompt has no step for creating a deferred follow-up.
74
- During shipping I went straight to close + release; the operator had to prompt ("What about the follow up issue…") to trigger #415's creation.
75
- Impact: one extra user turn, no rework — but the #380 close comment references #415, so the follow-up had to exist before close, making the ordering load-bearing.
76
- - `instruction-violation` (self-identified, no rework) — the new test used `String(spy.mock.calls[0]![0])`, which the `testing` skill explicitly warns against ("Assert mock calls with `expect(fn).toHaveBeenCalledWith(...)`, not `fn.mock.calls[0]![0]`").
77
- ESLint's pre-commit hook auto-stripped the redundant `!`, leaving `spy.mock.calls[0][0]`; tests stayed green.
78
- I mirrored the pre-existing pattern in `settings.test.ts` rather than the skill's recommended `toHaveBeenCalledWith(expect.stringMatching(...))`.
79
- Impact: none (auto-fixed, matches existing file style); the rule already exists in the skill, so this is a salience note, not a gap.
80
-
81
- #### What caused friction (user side)
82
-
83
- - None material.
84
- The operator's one mid-ship intervention (asking about the follow-up issue) was a good catch that compensated for the prompt gap above, not a correction of a mistake.
85
-
86
- ### Diagnostic details
87
-
88
- - **Model-performance correlation** — the single subagent dispatch (`pre-completion-reviewer`) ran on `anthropic/claude-sonnet-4-6`, appropriate for judgment-heavy review; no mismatch.
89
- Parent-session `model_change` entries toggled among `sonnet-4-6`, `deepseek-v4-flash`, and `opus-4-8`, but these are operator model selections, not quality-relevant task assignments.
90
- - **Escalation-delay tracking** — no `rabbit-hole` friction; no error sequence exceeded one or two tool calls before resolution.
91
- - **Unused-tool detection** — nothing missed; `web_search`/`fetch_content` were dispatched proactively during planning for the fallow-mechanism question.
92
- - **Feedback-loop gap analysis** — verification ran incrementally (per-step `check`/vitest, in-step `verify:public-types`), not just at the end.
93
- No gap.
94
-
95
- ### Changes made
96
-
97
- 1. `.pi/prompts/ship-issue.md` — added `## 4c. Create planned follow-up issues` between the stacked-release check (§4b) and the close step (§5): if the plan or retro defers work to a follow-up issue, create it with `gh issue create` before closing so the close comment can reference its number.
@@ -1,95 +0,0 @@
1
- ---
2
- issue: 381
3
- issue_title: "Replace ConcurrencyQueue with a thunk-based ConcurrencyLimiter"
4
- ---
5
-
6
- # Retro: #381 — Replace ConcurrencyQueue with a thunk-based ConcurrencyLimiter
7
-
8
- ## Stage: Planning (2026-06-13T00:00:00Z)
9
-
10
- ### Session summary
11
-
12
- Produced a 3-step TDD plan to replace the ID-registry `ConcurrencyQueue` (with its `startAgent` back-edge and `markStarted`/`markFinished` relays) with a pure `ConcurrencyLimiter` that schedules thunks FIFO against a dynamic limit.
13
- The design follows the architecture doc's Phase 17 Step 1 entry and the issue's revised framing closely; the plan adds concrete code sketches for `schedule`/`recheck`/`clear`, the manager call site, the simplified `waitForAll`, and `index.ts` wiring.
14
-
15
- ### Observations
16
-
17
- - Author is `gotgenes` (matches the gh CLI user), so the well-specified proposal was treated as the working hypothesis; the design is unambiguous (down to the architecture-doc Step 1), so the `ask_user` gate was skipped.
18
- - Classified non-breaking: `ConcurrencyQueue`/`ConcurrencyLimiter` are internal — no public API, config, or observable behavior change.
19
- The FIFO admission gate against `maxConcurrent` is preserved.
20
- - Key design decision beyond the issue sketch: `clear()` must *settle* dropped pending promises (resolve them), not just drop the thunks.
21
- Every `schedule()` promise becomes `record.promise`, and the post-spawn contract is that it always settles — dropping without resolving would strand a promise.
22
- This costs a small `settle` handle per pending entry (a few lines beyond the issue's "~40 lines").
23
- - Verified no production caller awaits a *queued* agent's promise in a blocking way (`get-result-tool.ts` guards on `status === "running"`; `spawnAndWait` is foreground/direct; `waitForAll` filters by status), confirming it is safe to give queued agents a real promise.
24
- - Sequencing decision: the `SubagentManagerOptions.queue` → `limiter` swap breaks both call sites (`index.ts` + the manager test helper) and the old test file imports the deleted source, so step 2 is one atomic commit (migrate consumers + delete queue + delete old test).
25
- - `bypassQueue` is kept as-is — it is in the published `SubagentsService` type bundle, so renaming would be breaking; deferred to Open Questions.
26
- - Doc inventory: grep confirmed current-state references to update are the Mermaid lifecycle node, the layout listing, the "What the core owns" bullet, the Step 7 ([#378]) target filename, and the `package-pi-subagents` SKILL lifecycle-domain table.
27
- `SKILL.md` line 80 (Phase 15 history) keeps `ConcurrencyQueue` as a historical record.
28
-
29
- ## Stage: Implementation — TDD (2026-06-13T22:15:00Z)
30
-
31
- ### Session summary
32
-
33
- Executed all 3 planned TDD cycles: (1) added `ConcurrencyLimiter` + 13 unit tests, (2) migrated `SubagentManager`, `index.ts`, `subagent.ts` docstring, and the manager test helper to the limiter while deleting `concurrency-queue.ts` + its test in the same atomic commit, (3) updated `architecture.md` and the package SKILL.
34
- Test count went 975 → 966 (−22 deleted queue tests, +13 new limiter tests); the full suite, `check`, `lint`, and `pnpm fallow dead-code` are all green.
35
-
36
- ### Observations
37
-
38
- - The plan held up cleanly — no surprises in the manager integration tests.
39
- The `queueing and concurrency` describe block passed unchanged after only the `createManager` helper swap (real `ConcurrencyLimiter` instead of `ConcurrencyQueue` + forward-ref start callback), confirming those tests exercise behavior, not queue internals.
40
- - One deviation: a 4th commit (`90135005`, `refactor:`) fixes a stale `// before startAgent / queue drain` comment at `src/index.ts:125` that the plan's grep inventory missed (it named no removed symbol, just deleted concepts).
41
- The pre-completion reviewer caught it.
42
- Committed separately rather than amending the non-HEAD refactor commit, since AGENTS.md discourages interactive rebase in this environment.
43
- - ESLint `@typescript-eslint/no-floating-promises` fired on every bare `limiter.schedule(...)` in the limiter test (the queue's `enqueue` returned `void`; `schedule` returns a promise).
44
- Resolved by prefixing unawaited calls with `void` — all such tasks either stay pending or resolve, so no unhandled rejection.
45
- - The `clear()`-settles-pending-promises decision (made at planning) proved correct and is covered by a dedicated test ("resolves the promises of dropped pending tasks").
46
- - Pre-completion reviewer: WARN (no FAILs).
47
- Reviewer warnings: the single stale-comment finding at `index.ts:125` — now fixed in commit `90135005`.
48
-
49
- ## Stage: Final Retrospective (2026-06-14T00:30:00Z)
50
-
51
- ### Session summary
52
-
53
- Shipped #381 across planning, TDD, and release: `pi-subagents` `16.0.0` → `16.1.0`, tag `pi-subagents-v16.1.0`.
54
- Four commits landed (one `feat`, two `refactor`, one `docs`) plus two `docs(retro)` notes; CI passed first try, the issue was closed with an implemented-in summary, and the release-please PR was merged.
55
- The plan — written down to code sketches — held up across all three TDD cycles with no design rework.
56
-
57
- ### Observations
58
-
59
- #### What went well
60
-
61
- - The plan's fidelity paid off: the `clear()`-settles-pending-promises decision, the atomic step-2 sequencing (migrate consumers + delete queue + delete old test in one commit), and the `void`-prefix prediction for floating promises were all made at planning time and executed without surprise.
62
- The `queueing and concurrency` manager tests passed unchanged after only the `createManager` helper swap, validating the planning claim that they exercise behavior, not queue internals.
63
- - The pre-completion-reviewer (on `anthropic/claude-sonnet-4-6`, 161s, 21 tool uses) caught a stale comment at `src/index.ts:125` that all four deterministic gates (`check`, `lint`, `test`, `fallow dead-code`) passed over.
64
- This is the backstop working exactly as intended — a judgment-model review surfacing residue that pattern-matchers cannot.
65
- - Verification cadence was incremental, not end-loaded: file-scoped `vitest` + `biome` + `eslint` after step 1, `pnpm run check` immediately after the shared-interface change mid-step-2 (per the plan's own instruction), then lifecycle suite → full suite → full lint, then `rumdl` for the docs step, then the full gates + `fallow` before push.
66
-
67
- #### What caused friction (agent side)
68
-
69
- - `missing-context` (self/reviewer-caught) — the stale comment `// before startAgent / queue drain` at `src/index.ts:125` referenced two deleted concepts but was not cataloged in the plan's Module-Level Changes, despite the planning grep output having surfaced that exact line.
70
- The grep hit was visible but never converted into a plan action or an explicit leave-as-is.
71
- Impact: one small follow-up commit (`90135005`, `refactor:`); no rework, no design impact — the reviewer backstop absorbed it before ship.
72
-
73
- #### What caused friction (user side)
74
-
75
- - None.
76
- The single user touchpoint — the release-timing gate in `/ship-issue` (release now vs. batch the Phase 17 sequence) — was strategic judgment the agent correctly deferred, not mechanical oversight.
77
-
78
- ### Diagnostic details
79
-
80
- - **Model-performance correlation** — one subagent dispatch (`pre-completion-reviewer`) on `anthropic/claude-sonnet-4-6`; appropriate match for judgment-heavy review, and it returned the session's only actionable finding.
81
- - **Escalation-delay tracking** — no rabbit-holes; the lone lint error (`@typescript-eslint/no-floating-promises`, 18 sites) was resolved in a single test-file rewrite, far under the 5-call escalation threshold.
82
- - **Unused-tool detection** — nothing under-tooled; `colgrep`/`grep` were used during planning exploration and the reviewer subagent was dispatched as designed.
83
- - **Feedback-loop gap analysis** — no gap; verification ran after every cycle, with `pnpm run check` correctly invoked right after the shared-interface change rather than at end-of-session.
84
-
85
- #### Process note (no inline change)
86
-
87
- - The release-please PR merge required the documented `UNSTABLE` → `gh pr merge` fallback (step 6.4 of `/ship-issue`) because default-`GITHUB_TOKEN` release PRs never get checks.
88
- This recurs every release; the prompt already handles it, so it is recorded here only as a standing pattern, not a friction point.
89
-
90
- ### Changes made
91
-
92
- 1. Added this Final Retrospective stage entry to `packages/pi-subagents/docs/retro/0381-replace-concurrency-queue-with-limiter.md`.
93
- 2. No prompt or `AGENTS.md` changes — the operator chose retro-file-only, since the single friction (the stale `src/index.ts:125` comment) was a one-off execution slip already caught by the pre-completion-reviewer backstop, and the candidate grep-hit rule was judged not worth the prompt verbosity.
94
-
95
- [#378]: https://github.com/gotgenes/pi-packages/issues/378
@@ -1,84 +0,0 @@
1
- ---
2
- issue: 400
3
- issue_title: "perf(pi-subagents): include parent system prompt in replace mode for KV cache reuse"
4
- ---
5
-
6
- # Retro: #400 — Include parent system prompt in replace mode for KV cache reuse
7
-
8
- ## Stage: Planning (2026-06-14T00:42:49Z)
9
-
10
- ### Session summary
11
-
12
- Produced a numbered plan for including the parent system prompt as a cacheable prefix in `buildAgentPrompt()`'s replace branch, mirroring the [#180] append-mode reorder.
13
- The change is a single-function edit plus test and README updates, planned across three TDD/docs commits.
14
-
15
- ### Observations
16
-
17
- - Three design decisions were confirmed with the operator (issue author = gh user) before planning:
18
- 1. Ship as breaking `perf!:` with a `BREAKING CHANGE:` footer — replace-mode agents inherit the parent prompt on upgrade with no user edit, and the thin two-line header is removed.
19
- 2. Use `genericBase` as the no-parent fallback, consistent with append mode.
20
- 3. Apply uniformly to all replace agents, including built-in `Explore` and `Plan` (one code path, no special-casing).
21
- - The operator raised a cross-extension concern about the `genericBase` fallback interacting with `@gotgenes/pi-anthropic-auth`.
22
- Investigation of that package's `system-prompt-shaping.ts` / `request-shaping.ts` showed no new interaction: the `x-anthropic-billing-header` block is prepended unconditionally for OAuth, and de-fingerprinting keys off `PI_DEFAULT_PROMPT_PREFIX` (absent from `genericBase`, which is already neutral).
23
- Captured this in the plan's Background and Risks.
24
- - `parentSystemPrompt` is a required `string` at the `session-config` layer (sourced from `snapshot.systemPrompt`), so the `genericBase` fallback is effectively a defensive/test-only path in real sessions.
25
- - The thin replace header string (`You are a pi coding agent sub-agent`) appears only in `prompts.ts` and its test — no skill or live doc pins it; README needs three edits (Explore/Plan rows, `prompt_mode` table, Patch 3 `<active_agent>` wording, the last already slightly stale post-#180).
26
- - Notable emergent scope point: `Explore`/`Plan` are built-in replace-mode agents, so this change affects them visibly — surfaced and confirmed rather than assumed.
27
-
28
- ## Stage: Implementation — TDD (2026-06-14T00:54:46Z)
29
-
30
- ### Session summary
31
-
32
- Completed all 3 TDD cycles in `packages/pi-subagents`.
33
- The change is a single-function edit to `src/session/prompts.ts` (hoist `identity`, rewrite replace branch) plus test updates and README/skill-doc corrections.
34
- Test count went from 973 to 975 (+2 net new tests) across 59 test files.
35
-
36
- ### Observations
37
-
38
- - Step 1 (Red): rewrote 2 existing replace-mode tests and added 2 new ones (4 failures confirmed against old code); the old "ignores parent prompt" test premise inverted cleanly into "includes parent prompt as base."
39
- - Step 2 (Green): hoisting `const identity = parentSystemPrompt ?? genericBase;` above the `if` block and replacing the `replaceHeader` template were the only `src/` changes; also updated two positional `<active_agent>` tests in the same commit since they broke the moment the branch changed (`tagIdx === 0` → `toBeGreaterThan(0)`).
40
- - The `BREAKING CHANGE:` footer wording was taken verbatim from the plan and landed in the `perf!:` commit.
41
- - Pre-completion reviewer: WARN — one finding: `.pi/skills/package-pi-subagents/SKILL.md` still said "prepends" for the `<active_agent>` tag; fixed in a follow-up `docs:` commit before shipping.
42
- - No deviations from the plan's Module-Level Changes list; no lockfile changes; fallow dead-code exited zero.
43
-
44
- ## Stage: Final Retrospective (2026-06-14T01:11:10Z)
45
-
46
- ### Session summary
47
-
48
- Shipped #400 across three stages (Planning on `claude-opus-4-8`, TDD + Ship on `claude-sonnet-4-6`) as a single-function edit to `buildAgentPrompt()`'s replace branch plus tests and doc updates, released as `pi-subagents` v16.0.0 (major, breaking `perf!:`).
49
- The run was clean end-to-end: two `ask_user` gates during planning, a 3-cycle TDD pass, one pre-completion WARN resolved before push, and a no-friction release-please merge.
50
-
51
- ### Observations
52
-
53
- #### What went well
54
-
55
- - Cross-extension investigation on demand — when the operator asked mid-`ask_user` how the `genericBase` fallback interacts with `@gotgenes/pi-anthropic-auth`, the agent read that sibling repo's `system-prompt-shaping.ts` and `request-shaping.ts` and proved no new interaction (billing header prepended unconditionally; de-fingerprinting keys off `PI_DEFAULT_PROMPT_PREFIX`, absent from the neutral `genericBase`) before answering.
56
- This converted an open worry into a documented Risk row rather than a deferred unknown.
57
- - Emergent-scope surfacing — planning noticed that built-in `Explore`/`Plan` are replace-mode agents and so are visibly affected, then confirmed uniform application via a second `ask_user` instead of assuming.
58
- - Autoformat discipline — after `pi-autoformat` touched `README.md` mid-edit, the agent re-read the region before the next edit (turns 49–50) rather than matching against stale layout, avoiding a failed `oldText`.
59
-
60
- #### What caused friction (agent side)
61
-
62
- - `missing-context` (planning) — the plan listed the README's Patch 3 `<active_agent>` "prepends" wording as a doc update but missed the identical Patch 3 description in `.pi/skills/package-pi-subagents/SKILL.md`.
63
- Exact-grep during planning keyed on removed strings (`You are a pi coding agent sub-agent`, `prompt_mode`); the stale prose carried none of them, so the skill file's "prepends `<active_agent>`" line was not found.
64
- Impact: the pre-completion reviewer caught it as a WARN, requiring one follow-up `docs:` commit (8e93d2a4) during TDD before push — no rework beyond that, and the safety net worked as designed.
65
-
66
- #### What caused friction (user side)
67
-
68
- - None — the operator's mid-planning OAuth question was a high-value redirect that strengthened the plan, not friction.
69
-
70
- ### Diagnostic details
71
-
72
- - **Model-performance correlation** — judgment-heavy planning ran on `claude-opus-4-8`; mechanical TDD execution and the deterministic ship steps ran on `claude-sonnet-4-6`.
73
- Appropriate assignment in both directions; no mismatch.
74
- - **Unused-tool detection** — the `colgrep` skill was loaded in planning but never used; exploration was all exact-symbol grep, which was correct for known symbols.
75
- The one place it would have helped is the `missing-context` friction: a semantic search like "docs describing how the active_agent tag is added to the system prompt" would likely have surfaced both the README and the SKILL.md descriptions that symbol-grep missed.
76
- - **Feedback-loop gap analysis** — verification ran incrementally throughout (green baseline before cycle 1, per-file `vitest` each cycle, full suite + `check` + `lint` + `fallow` after the last step).
77
- No end-loaded verification.
78
- - **Escalation-delay tracking** — no rabbit-holes; no error sequence exceeded one tool call.
79
-
80
- ### Changes made
81
-
82
- 1. `.pi/prompts/plan-issue.md` — extended the Module-Level Changes grep bullet: when a step reworks a documented mechanism's behavior (rather than removing a symbol), grep `.pi/skills/package-*/SKILL.md` for the mechanism name, since reworded prose carries no removed symbol to match.
83
-
84
- [#180]: https://github.com/gotgenes/pi-packages/issues/180
@@ -1,90 +0,0 @@
1
- ---
2
- issue: 403
3
- issue_title: "Pressing Escape does not stop subagent/background agent"
4
- ---
5
-
6
- # Retro: #403 — Pressing Escape does not stop subagent/background agent
7
-
8
- ## Stage: Planning (2026-06-14T00:00:00Z)
9
-
10
- ### Session summary
11
-
12
- Investigated the third-party bug report that ESC does not stop subagents and traced the abort path through both the package and the pinned Pi SDK peer deps.
13
- Found that foreground subagents already receive the parent abort signal end-to-end, while background subagents are detached with no interrupt wiring — the reproducible bug.
14
- Confirmed direction with the operator via `ask_user` (third-party gate): implement ESC-to-abort for both modes, with a foreground guard test, aborting all running and queued background agents.
15
- Wrote and committed plan `0403-abort-subagents-on-interrupt.md`.
16
-
17
- ### Observations
18
-
19
- - Key SDK fact that de-risks the design: in `pi-agent-core` `agent.js`, each run creates a fresh `AbortController` and `finishRun()` discards it **without** aborting on normal completion.
20
- So the parent signal's `abort` event fires only on a real ESC interrupt — latching `abortAll()` to it will not spuriously kill background agents at turn end.
21
- - Chosen mechanism: a small `InterruptHandler` driven by `pi.on("turn_start", ...)`, re-latching `ctx.signal` each turn so the latch tracks the live per-run signal even across runs and tool-less turns.
22
- `turn_start` was preferred over `tool_execution_start` because a background agent can outlive the run that spawned it; a turn-level latch still holds the current run's signal when the user interrupts a later tool-less turn.
23
- - Reused the existing `manager.abortAll()` rather than adding `abortBackground()`.
24
- Foreground agents are already aborted via their own `wireSignal`, so `abortAll()`'s overlap is redundant-but-harmless (status-guarded `abort()`, idempotent `markStopped`).
25
- The manager does not store `isBackground` on the record, so distinguishing modes would need extra state — deferred as an Open Question.
26
- - Classified as a non-breaking `fix:` (not `fix!:`): no config key, default, or output shape changes; detached-survives-ESC was a limitation, not a contract.
27
- Noted the behavior change explicitly in Goals.
28
- - Foreground path is believed already-correct from the code trace; the plan adds a regression guard in `subagent-session.test.ts` (`forwardAbortSignal` is currently untested for the parent-signal path) and will fix only if the guard fails.
29
-
30
- ## Stage: Implementation — TDD (2026-06-14T18:00:00Z)
31
-
32
- ### Session summary
33
-
34
- Completed all three TDD cycles against a green baseline (967 tests).
35
- Added the foreground-abort guard, implemented `InterruptHandler` + `turn_start` wiring, and updated the architecture doc.
36
- Test count went from 967 to 975 (+8: 6 `InterruptHandler` unit tests, 2 foreground guard tests); `check`, `lint`, `test`, and `fallow dead-code` all pass.
37
-
38
- ### Observations
39
-
40
- - The foreground guard (Step 1) passed on the first run, confirming the planning-stage code trace: the parent signal already reaches the child `session.abort()` via `forwardAbortSignal`.
41
- No code fix was needed, so it landed as `test:` exactly as the plan anticipated.
42
- - `InterruptHandler` came out clean against the `code-design` heuristics — one field read from `ctx`, one method on a one-method `InterruptManager` interface, latch state owned internally, `{ once: true }` listener.
43
- The reviewer's code-design check was PASS with no structural concerns.
44
- - `abortAll()` gained a second narrow-interface consumer (the new handler) on top of the shutdown path; `fallow dead-code` stayed green, so its existing `fallow-ignore-next-line unused-class-member` comment was left untouched.
45
- - Pre-completion reviewer: **WARN**.
46
- - Reviewer warnings: stale source-file counts in `architecture.md`.
47
- Fixed the current-state prose claim (`56` → `58` source files).
48
- Left the fallow health-metrics snapshot rows (line ~650, `7,778 (57 files)`) intact — those are point-in-time analysis tables where the file count was computed alongside LOC and other metrics, so bumping one cell in isolation would desync the snapshot.
49
- Amended the fix into the docs commit (not yet pushed).
50
-
51
- ## Stage: Final Retrospective (2026-06-14T20:00:00Z)
52
-
53
- ### Session summary
54
-
55
- Shipped issue #403 end-to-end across four stages (plan → TDD → ship → live verification): root-caused the bug, implemented the `InterruptHandler` (single `fix:` commit), guarded the already-working foreground path, and released `pi-subagents-v16.1.1`.
56
- The operator then live-tested all three abort paths (background subagent, foreground subagent, main agent) and confirmed a single Escape aborts each immediately.
57
- Near-zero rework: one reviewer WARN (stale doc file count) fixed by amend, no follow-up commits, no failed CI.
58
-
59
- ### Observations
60
-
61
- #### What went well
62
-
63
- 1. The planning-stage SDK trace paid dividends two stages later.
64
- When the operator asked during live testing "is it supposed to take two Escapes or just one?", the answer came straight from the `restoreQueuedMessagesToEditor → agent.abort()` trace captured at planning time — no re-investigation.
65
- The same trace explained the main-agent and foreground-subagent abort paths immediately.
66
- 2. The keystone de-risking finding (`finishRun()` discards the per-run `AbortController` without aborting it, so the `abort` event fires only on a real interrupt) held up in practice — no spurious turn-end aborts were observed in live testing.
67
- 3. The foreground guard test passed on its first run, confirming the planning trace, so the plan's pre-typed `test:` commit type was correct and the whole implementation landed with zero rework.
68
- 4. Verification was incremental throughout TDD: green baseline first, per-step affected-file runs, `pnpm run check` after the interface-touching step, and full `test`/`check`/`lint`/`fallow` at the end.
69
-
70
- #### What caused friction (agent side)
71
-
72
- 1. `missing-context` — when adding the new source file `interrupt.ts`, I updated the `handlers/` directory listing in `architecture.md` but not the prose total-file count at line 277 (which was already stale: `56` vs the pre-change actual of `57`).
73
- Impact: one pre-completion reviewer WARN, fixed by amending the docs commit before push — no rework, no extra commit, no CI cost.
74
-
75
- #### What caused friction (user side)
76
-
77
- 1. None.
78
- The operator's involvement was high-value: the third-party-issue direction gate (planning) and the live three-path abort verification (post-ship) validated behavior that unit tests cannot reach (real ESC keypress through the interactive TUI).
79
-
80
- ### Diagnostic details
81
-
82
- 1. Model-performance correlation — ship stage and the `pre-completion-reviewer` subagent both ran on `claude-sonnet-4-6` (mechanical orchestration and checklist review — appropriate); retro synthesis on `claude-opus-4-8` (judgment — appropriate).
83
- No mismatch.
84
- 2. Escalation-delay tracking — no `rabbit-hole` friction points; the planning SDK dig was productive forward exploration, not repeated calls against one error.
85
- 3. Unused-tool detection — the planning SDK trace navigated minified `node_modules/.pnpm` dist files by hand; `colgrep` (project-code semantic search) and an Explore subagent (project-code understanding) were not suited to reverse-engineering pinned third-party `dist` JS, so no tool was wrongly skipped.
86
- 4. Feedback-loop gap analysis — no gap; verification ran incrementally per TDD step, not only at the end.
87
-
88
- ### Changes made
89
-
90
- 1. Added an "Abort / interrupt signal lifecycle" section to `.pi/skills/pi-extension-lifecycle/SKILL.md` documenting the per-run `AbortController`, the ESC → `agent.abort()` path, the `finishRun()` discard-without-abort behavior, and the `ctx.signal` / `tool.execute(signal)` exposure — so future interrupt-timing work need not re-derive it from the pinned SDK `dist` files.
@@ -1,80 +0,0 @@
1
- ---
2
- issue: 412
3
- issue_title: "Unify the three overlapping session-mock builders in pi-subagents tests"
4
- ---
5
-
6
- # Retro: #412 — Unify the three overlapping session-mock builders in pi-subagents tests
7
-
8
- ## Stage: Planning (2026-06-16T00:00:00Z)
9
-
10
- ### Session summary
11
-
12
- Planned the unification of the three `test/helpers/` session-mock builders.
13
- A structural read showed the three sit on two axes (AgentSession-vs-`SubagentSession`, event-bus-vs-factory), that `createSubagentSessionStub` already composes `createMockSession` (intrinsic delegation, not duplication), and that the only genuine independent redeclaration of the four shared base fields lives in `createFactorySession`.
14
- The operator chose targeted reuse with a working-bus core default; the plan folds `createFactorySession` onto the `createMockSession` core and leaves the other two builders untouched.
15
-
16
- ### Observations
17
-
18
- - The issue is the operator's own and explicitly flags the wrong-abstraction risk (Sandi Metz quote), so the `Decide` gate used `ask_user` to choose between full composable factory (A), targeted reuse (B), and decline-and-document (C).
19
- Operator picked **B** with the **working event bus as the core default**.
20
- - Rejected option A (the issue's literal "Proposed change") because a multi-facet `createSessionMock()` with opt-in `withTurnLoop()`/`withBindFacet()` is the over-parameterized factory the issue itself warns against; the honest target is only `createFactorySession`'s independently-redeclared base.
21
- - De-risked the key feasibility assumption with a throwaway `tsc --noEmit` probe: spreading `...createMockSession()` (which returns `MockSession & Record<string, unknown>`) preserves `Mock<...>` typing on the facet methods because `unknown & Mock<...>` narrows to `Mock<...>`.
22
- - Behavioral delta is the inert→working `subscribe` plus new `emit`/`sessionManager` fields on the factory session; confirmed no factory/lifecycle test emits or asserts on the inert subscribe, and `session.dispose` stays a spy (`create-subagent-session.test.ts:194`).
23
- - Plan is two commits: a `refactor(test):` cycle (one new event-bus self-test + the rewrite) and a `docs:` cycle updating the Phase 17 Step 7 note in `architecture.md` to record the resolution.
24
-
25
- ## Stage: Implementation — TDD (2026-06-16T21:20:00Z)
26
-
27
- ### Session summary
28
-
29
- Executed the plan in two TDD cycles exactly as written: a `refactor(test):` cycle (added the working-event-bus self-test as the red, rewrote `createFactorySession` to spread `...createMockSession()` + the factory facet as the green) and a `docs:` cycle recording the targeted-reuse outcome in the `architecture.md` Phase 17 Step 7 note.
30
- Test count went 1030 → 1031 (the one new `createFactorySession` event-bus self-test); full suite 1031 pass across 65 files.
31
- All deterministic gates green from repo root: `check`, `lint`, `test`, and `pnpm fallow dead-code`.
32
-
33
- ### Observations
34
-
35
- - The plan's feasibility probe held: spreading `...createMockSession()` (typed `MockSession & Record<string, unknown>`) preserved `Mock<...>` typing on the facet methods, so `setActiveToolsByName.mock.calls[0][0]` still type-checks — no annotation gymnastics needed.
36
- - The inert→working `subscribe` change was inert in practice as predicted: no factory or lifecycle test emits, and `create-subagent-session.test.ts:194`'s `session.dispose` spy assertion held (the core supplies `dispose` as a `vi.fn()`).
37
- - Pre-completion reviewer: **WARN** (no FAILs).
38
- Reviewer warnings: (1) the `createMockSession` core docstring I added landed orphaned above `toAgentSession` rather than attached to `createMockSession` — fixed in a follow-up `refactor(test):` commit (`5999dcad`) by moving it directly above the declaration; (2) the TDD retro stage was not yet written when the reviewer ran — this entry resolves it.
39
- - Deviation: one extra cleanup commit beyond the planned two (the docstring-placement fix), landed as `refactor(test):` rather than amended because the `docs:` commit already sat on top of the refactor commit and neither was pushed.
40
-
41
- ## Stage: Final Retrospective (2026-06-17T00:00:00Z)
42
-
43
- ### Session summary
44
-
45
- Shipped issue #412 across three stages (planning, TDD, ship) in one continuous session with a single deviation: one extra `refactor(test):` cleanup commit for an orphaned docstring the pre-completion reviewer flagged.
46
- The whole arc was low-friction — the `ask_user` wrong-abstraction gate in planning, the `tsc --noEmit` feasibility probe, and incremental verification all paid off, and CI/release/close ran clean.
47
- No `pi-subagents` release bumped (a `refactor(test):` change), so only the unrelated `pi-github-tools-v4.1.5` doc release rode along in the release-please PR.
48
-
49
- ### Observations
50
-
51
- #### What went well
52
-
53
- - The planning-stage `ask_user` gate did real work: it surfaced the wrong-abstraction risk the issue itself flagged and let the operator pick targeted reuse (B) over the issue's literal composable-factory proposal (A).
54
- This is the `ask_user` skill behaving exactly as the `Decide` gate intends for an operator-authored issue.
55
- - The `tsc --noEmit` throwaway probe in planning (does spreading `...createMockSession()` preserve `Mock<...>` typing?) de-risked the one feasibility unknown before any commit, so the TDD green step landed on the first try with no annotation gymnastics.
56
- - Verification cadence was incremental, not end-loaded: `pnpm run check` ran right after the TDD green step, the full suite after both steps, then `lint`/`fallow` before push.
57
- No feedback-loop gap.
58
-
59
- #### What caused friction (agent side)
60
-
61
- - `missing-context` — the plan called for a docstring touch-up on `createMockSession`, but the existing `createMockSession` docstring block in `mock-session.ts` was *already orphaned* (sitting above `toAgentSession`, not its own declaration).
62
- I enriched the orphaned block instead of noticing it wasn't attached to the symbol it documents.
63
- Impact: one extra `refactor(test):` commit (`5999dcad`) to move the block; caught by the pre-completion reviewer, so no escaped defect — reviewer-caught, not user-caught.
64
-
65
- #### What caused friction (user side)
66
-
67
- - None.
68
- The operator's only mid-session input was the planning `ask_user` answer (direction B, working-bus core default), which was strategic judgment, not mechanical oversight.
69
-
70
- ### Diagnostic details
71
-
72
- - **Model-performance correlation** — the one subagent dispatch (`pre-completion-reviewer`) ran on `anthropic/claude-sonnet-4-6`, appropriate for judgment-heavy review; it found a genuine issue (the orphaned docstring), so no quality mismatch.
73
- - **Escalation-delay tracking** — no `rabbit-hole` friction; no error sequence exceeded one tool call.
74
- - **Unused-tool detection** — no missing-context gap that an Explore/`colgrep` dispatch would have closed; planning already used `grep`/`colgrep` and a `tsc` probe.
75
- - **Feedback-loop gap analysis** — verification ran incrementally (see "What went well"); no end-loaded check.
76
-
77
- ### Changes made
78
-
79
- 1. Appended this Final Retrospective stage entry to `packages/pi-subagents/docs/retro/0412-unify-session-mock-builders.md`.
80
- No `AGENTS.md` or `.pi/prompts/` changes — the single friction point was a one-off slip the pre-completion reviewer already caught (weak evidence for a new rule).
@@ -1,90 +0,0 @@
1
- ---
2
- issue: 420
3
- issue_title: "pi-subagents: fold subagent run metrics and live activity onto the core record"
4
- ---
5
-
6
- # Retro: #420 — pi-subagents: fold subagent run metrics and live activity onto the core record
7
-
8
- ## Stage: Planning (2026-06-17T00:00:00Z)
9
-
10
- ### Session summary
11
-
12
- Produced a 3-step TDD plan (`docs/plans/0420-fold-run-metrics-live-activity-onto-record.md`) for Phase 18 Step 1: fold `turnCount`, active tools, and response text onto `SubagentState`, have `record-observer` populate them, and expose read-only getters on `Subagent`.
13
- The change is a pure addition / tidy-first — both observers keep running and no consumer reads the new getters until Step 2 ([#421]).
14
- Operator-authored, unambiguous proposal matching the architecture roadmap, so the `ask-user` gate was skipped.
15
-
16
- ### Observations
17
-
18
- - The `maxTurns` getter is the one getter that does **not** delegate to `SubagentState` — it delegates to `this.execution.maxTurns`.
19
- Verified both spawners pass `execution.effectiveMaxTurns` as `options.maxTurns` (threaded into `SubagentExecution.maxTurns` by `SubagentManager.spawn`), so the record getter returns the same value `AgentActivityTracker` was constructed with.
20
- - Semantics must be copied field-for-field from `AgentActivityTracker` so Step 2's reader swap is behavior-preserving: `turnCount` starts at **1** (readers assume the at-least-1 invariant — `notification.ts` uses `?? 0`, `result-renderer.ts` gates on `> 0`); `activeTools` uses `name_seq` keying for concurrent same-name tools; `removeActiveTool` deletes the first match; `responseText` resets at `message_start` and appends each text delta.
21
- - Decided to leave `resetForResume` **unchanged** (the new fields are not reset on resume).
22
- Rationale: the tracker is not reconstructed/reset on resume today, so the surviving `SubagentState` accumulating across a resume preserves parity.
23
- Touching it would violate the pure-addition contract; flagged in Open Questions for Step 2 to revisit against observable reader behavior.
24
- - The tracker's `_session`/`setSession` is deliberately **not** folded — it exists only for UI polling reads and is migrated/removed in Steps 2–3.
25
- - No symbol is removed or renamed, so no `package-pi-subagents` SKILL or architecture-doc prose update is needed; the Phase 18 Step 1 roadmap entry already describes this work.
26
-
27
- [#421]: https://github.com/gotgenes/pi-packages/issues/421
28
-
29
- ## Stage: Implementation — TDD (2026-06-17T13:10:00Z)
30
-
31
- ### Session summary
32
-
33
- Executed all 3 TDD steps from the plan: (1) added `turnCount`/`activeTools`/`responseText` fields plus 5 transition methods to `SubagentState`; (2) extended `record-observer` with 4 new event branches (`tool_execution_start`, `turn_end`, `message_start`, `message_update` text_delta) plus paired `removeActiveTool` on `tool_execution_end`; (3) added 4 read-only getters to `Subagent` (`turnCount`, `activeTools`, `responseText`, `maxTurns`).
34
- Test count: 1031 → 1058 (+27 across 3 test files).
35
- Full suite green; type check and lint clean; zero dead code.
36
-
37
- ### Observations
38
-
39
- - The first pre-completion reviewer run returned **FAIL** due to 3 pre-existing `MD051` broken-fragment links in `docs/architecture/history/phase-17-core-consolidation.md` (fragment `#first-principles-refinement-the-deeper-target` was missing `-and-`; correct anchor is `#first-principles-refinement-and-the-deeper-target`).
40
- Fixed in a separate `docs:` commit; re-run returned **WARN**.
41
- - 3 Biome `useTemplate` infos in `packages/pi-permission-system/` are informational only (marked unsafe fix, `biome check --write` skips them) and do not cause a non-zero lint exit.
42
- - The 3 "vacuously-passing" new observer tests (paired `tool_execution_end` removal, `message_start` reset, non-text_delta ignore) pass before the observer handles the events because the state starts in the default/empty state — they correctly verify absence-of-mutation and fully exercise the code path after the observer is implemented.
43
- - WARN finding: `package-pi-subagents` SKILL.md `Observation` domain row description ("Session-event stats") is now slightly incomplete for `record-observer` (it also accumulates live-activity fields).
44
- Intentionally deferred per the planning-stage decision — no symbol removed, and the description will be updated in Step 2 ([#421]) when the observer's role is fully defined after the reader migration.
45
- - Pre-completion reviewer verdict: **WARN** (one non-blocking finding, deferred per retro).
46
-
47
- ## Stage: Final Retrospective (2026-06-17T17:40:39Z)
48
-
49
- ### Session summary
50
-
51
- Shipped Phase 18 Step 1 across planning, TDD (3 red→green→commit cycles, +27 tests), and release (`pi-subagents` v16.5.0).
52
- The code work was clean and rework-free; all friction was in markdown-lint surfacing late — two separate doc-lint failures (one pre-existing, one introduced) escaped the baseline and post-TDD gates and were caught only by the pre-completion reviewer and the ship-stage lint, each requiring a fix commit.
53
-
54
- ### Observations
55
-
56
- #### What went well
57
-
58
- - The `pre-completion-reviewer` safety net earned its keep: it caught the pre-existing `MD051` broken-fragment links in `phase-17-core-consolidation.md` (introduced earlier by `e4d92535`, unrelated to this issue) before the push, returning FAIL on the first run.
59
- Without it the broken links would have shipped.
60
- - TDD execution was textbook: each of the 3 steps followed red→green→commit with no rework to production code, the `maxTurns`-via-`execution` delegation decision from planning held, and the "vacuously-passing" observer tests (verified in the retro) correctly converted to real assertions once the observer was implemented.
61
-
62
- #### What caused friction (agent side)
63
-
64
- - `instruction-violation` (gate-caught, at ship) — wrote a second `[#421]:` link-reference definition into the retro file when appending the TDD stage entry via `Write` full-content, tripping `MD053` (duplicate definition).
65
- The `markdown-conventions` skill states this rule verbatim ("Link reference definitions are file-scoped … a duplicate trips MD053").
66
- Impact: one fix commit at ship time (`80d4d050`), caught by the root `pnpm run lint` pre-push gate rather than during TDD (no lint runs after stage-notes writing).
67
- - `missing-context` (self-identified during ship investigation) — the TDD green-baseline lint was run package-scoped (`pnpm --filter @gotgenes/pi-subagents run lint`), which **silently passes** on `MD051` cross-file fragment failures.
68
- Verified empirically: package `lint:md` (`rumdl check *.md docs/**/*.md`) returns "No issues" on the broken fragment, while root `rumdl check .` exits 1 on it — the cross-file fragment target (`../architecture.md`) is only resolved on a repo-root tree walk.
69
- Impact: the pre-existing `MD051` failure slipped past the baseline gate (whose job is to catch exactly that) and surfaced mid-TDD via the reviewer, costing a fix commit (`86ed0c81`) and a reviewer FAIL/re-dispatch cycle.
70
-
71
- #### What caused friction (user side)
72
-
73
- - None.
74
- The session ran end-to-end without user correction; the operator-authored, roadmap-aligned issue meant no clarification was needed.
75
-
76
- ### Diagnostic details
77
-
78
- - **Model-performance correlation** — two `pre-completion-reviewer` subagent dispatches ran on the agent's configured reviewer model and performed judgment-heavy review work (acceptance criteria, design review, cross-step invariants); appropriate match.
79
- No high-cost model was spent on mechanical work and no reasoning-weak model on judgment work.
80
- - **Feedback-loop gap analysis** — the lint feedback loop fired at the wrong scope and the wrong time: package-scoped at baseline (missed `MD051`), and absent after retro stage-notes writing (missed `MD053` until ship).
81
- `pnpm run check` and `pnpm run test` were run incrementally per step and caught everything they should; only the markdown-lint loop was misconfigured.
82
- - **Escalation-delay / unused-tool** — no `rabbit-hole` friction; no lens-2 or lens-3 findings.
83
-
84
- ### Changes made
85
-
86
- 1. `.pi/prompts/tdd-plan.md` — "Verify green baseline" step 2 and "After the last TDD step" step 3 now specify `pnpm run lint` runs **from the repo root**, with a one-clause rationale that package-scoped lint silently passes on `MD051` cross-file fragments and cross-package issues (Proposal 1).
87
- 2. Proposal 2 (an `MD053` duplicate-link-definition reminder in the retro-writing prompts) was declined — the rule already exists verbatim in the `markdown-conventions` skill, so a prompt clause would duplicate it.
88
- 3. Follow-up (post-retro): `#420` completed Phase 18 Step 1 but the roadmap Steps section was not marked done until the operator noticed.
89
- Added a roadmap-step-status check so this is caught going forward: a WARN bullet in `pre-completion-reviewer.md` §2c (backstop), and a proactive step in `.pi/prompts/tdd-plan.md` step 7 and `.pi/prompts/build-plan.md` "After the last step" — mark the completed roadmap step done (`✅`/`Landed:`) and update the phase status row.
90
- Also marked Step 1 complete in `architecture.md` (Steps list, dependency diagram node, phase table row → "In progress").