@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.
- package/CHANGELOG.md +15 -0
- package/docs/architecture/architecture.md +165 -203
- package/docs/architecture/history/phase-19-implement-ui-decisions.md +282 -0
- package/package.json +6 -7
- package/src/config/default-agents.ts +3 -0
- package/src/lifecycle/subagent.ts +25 -14
- package/src/observation/notification.ts +23 -10
- package/src/observation/subagent-events-observer.ts +1 -3
- package/src/runtime.ts +2 -1
- package/src/service/service-adapter.ts +20 -17
- package/src/session/model-resolver.ts +31 -30
- package/src/tools/agent-tool.ts +17 -13
- package/src/tools/get-result-report.ts +60 -0
- package/src/tools/get-result-tool.ts +25 -40
- package/src/tools/helpers.ts +21 -5
- package/src/tools/spawn-config.ts +5 -5
- package/src/tools/steer-tool.ts +37 -27
- package/src/types.ts +4 -1
- package/src/ui/session-navigator.ts +0 -2
- package/.prettierignore +0 -5
- package/AGENTS.md +0 -7
- package/docs/plans/0048-implement-subagents-api.md +0 -304
- package/docs/plans/0049-remove-group-join-output-file-rpc.md +0 -180
- package/docs/plans/0051-update-adr-0001-hard-fork.md +0 -77
- package/docs/plans/0052-remove-scheduled-subagents.md +0 -133
- package/docs/plans/0053-extract-model-resolution-from-execute.md +0 -181
- package/docs/plans/0054-decompose-index-into-modules.md +0 -302
- package/docs/plans/0057-structured-debug-logging.md +0 -154
- package/docs/plans/0061-session-format-transcript.md +0 -284
- package/docs/plans/0066-replace-as-any-with-sdk-types.md +0 -215
- package/docs/plans/0069-create-subagent-runtime.md +0 -345
- package/docs/plans/0070-extract-event-handlers.md +0 -306
- package/docs/plans/0071-extract-session-config-assembler.md +0 -362
- package/docs/plans/0072-inject-agent-manager-collaborators.md +0 -329
- package/docs/plans/0076-inject-cwd-into-agent-manager.md +0 -102
- package/docs/plans/0077-inject-project-agents-dir.md +0 -115
- package/docs/plans/0080-consolidate-agent-config-lookup.md +0 -247
- package/docs/plans/0084-extract-git-worktree-manager.md +0 -142
- package/docs/plans/0087-evolve-subagent-runtime-methods.md +0 -240
- package/docs/plans/0098-extract-agent-record-state-machine.md +0 -435
- package/docs/plans/0099-replace-ctx-with-parent-snapshot.md +0 -488
- package/docs/plans/0100-replace-callback-threading-with-session-subscription.md +0 -454
- package/docs/plans/0102-consolidate-test-record-factory.md +0 -176
- package/docs/plans/0108-extract-agent-type-registry.md +0 -322
- package/docs/plans/0109-extract-settings-manager.md +0 -276
- package/docs/plans/0110-agent-activity-tracker.md +0 -297
- package/docs/plans/0111-split-agent-record-lifecycle.md +0 -582
- package/docs/plans/0112-replace-agent-manager-callbacks.md +0 -241
- package/docs/plans/0113-disambiguate-spawn-options.md +0 -155
- package/docs/plans/0114-narrow-agent-tool-menu-deps.md +0 -279
- package/docs/plans/0115-decompose-agent-tool.md +0 -337
- package/docs/plans/0116-type-housekeeping.md +0 -351
- package/docs/plans/0118-settings-manager-apply-methods.md +0 -271
- package/docs/plans/0123-remove-vi-fn-cast-smell.md +0 -179
- package/docs/plans/0131-consolidate-shared-test-fixtures.md +0 -207
- package/docs/plans/0132-inject-io-into-session-config.md +0 -219
- package/docs/plans/0133-inject-sdk-boundary-into-agent-runner.md +0 -373
- package/docs/plans/0134-reduce-as-any-casts.md +0 -366
- package/docs/plans/0135-extract-display-helpers.md +0 -182
- package/docs/plans/0136-decompose-agent-menu.md +0 -300
- package/docs/plans/0144-consolidate-observation-model.md +0 -263
- package/docs/plans/0145-decompose-execute-push-ctx-to-boundary.md +0 -290
- package/docs/plans/0146-narrow-ui-context.md +0 -319
- package/docs/plans/0147-inject-wrap-text-into-conversation-viewer.md +0 -166
- package/docs/plans/0148-split-agent-widget-rendering.md +0 -255
- package/docs/plans/0152-add-prompt-snippet.md +0 -91
- package/docs/plans/0164-reorganize-into-domain-directories.md +0 -409
- package/docs/plans/0165-decompose-resolved-spawn-config.md +0 -157
- package/docs/plans/0166-extract-parent-session-info.md +0 -231
- package/docs/plans/0167-narrow-runner-io.md +0 -150
- package/docs/plans/0168-extract-tool-filter-config.md +0 -173
- package/docs/plans/0169-extract-run-context-from-run-options.md +0 -194
- package/docs/plans/0170-reduce-build-content-lines-complexity.md +0 -225
- package/docs/plans/0171-reduce-render-result-complexity.md +0 -200
- package/docs/plans/0172-extract-turn-formatting.md +0 -206
- package/docs/plans/0180-reorder-append-prompt-for-kv-cache.md +0 -100
- package/docs/plans/0185-remove-persistent-agent-memory.md +0 -161
- package/docs/plans/0188-replace-any-casts-with-sdk-types.md +0 -162
- package/docs/plans/0192-define-session-context-interface.md +0 -107
- package/docs/plans/0193-runtime-owns-context-queries.md +0 -245
- package/docs/plans/0194-align-tool-interfaces-for-structural-typing.md +0 -139
- package/docs/plans/0195-convert-tool-factories-to-classes.md +0 -264
- package/docs/plans/0196-convert-runner-menu-to-classes.md +0 -268
- package/docs/plans/0205-decompose-render-widget-lines.md +0 -140
- package/docs/plans/0206-decompose-show-agent-detail.md +0 -211
- package/docs/plans/0207-decompose-agent-widget-update.md +0 -242
- package/docs/plans/0208-extract-shared-test-fixtures.md +0 -298
- package/docs/plans/0214-convert-remaining-closure-factories-to-classes.md +0 -261
- package/docs/plans/0215-decompose-build-parent-context.md +0 -166
- package/docs/plans/0216-decompose-start-agent.md +0 -255
- package/docs/plans/0217-extract-overwrite-guard.md +0 -176
- package/docs/plans/0218-push-sdk-boundary-in-settings.md +0 -172
- package/docs/plans/0219-reduce-test-duplication-top-3-clone-families.md +0 -162
- package/docs/plans/0227-evolve-agent-record-into-agent.md +0 -322
- package/docs/plans/0228-async-start-agent-dissolve-run-handle.md +0 -288
- package/docs/plans/0229-agent-born-complete.md +0 -564
- package/docs/plans/0230-extract-concurrency-queue.md +0 -265
- package/docs/plans/0231-push-exec-registry-to-runner.md +0 -245
- package/docs/plans/0232-agent-resume-internal-observer-lifecycle.md +0 -180
- package/docs/plans/0237-remove-disallowed-tools.md +0 -180
- package/docs/plans/0238-remove-extensions-filtering.md +0 -191
- package/docs/plans/0239-collapse-filter-active-tools.md +0 -217
- package/docs/plans/0242-rename-agent-tool-to-subagent.md +0 -165
- package/docs/plans/0256-extract-worktree-isolation.md +0 -256
- package/docs/plans/0257-extract-child-session-factory.md +0 -285
- package/docs/plans/0262-add-workspace-provider-seam.md +0 -264
- package/docs/plans/0264-remove-extension-lifecycle-control.md +0 -277
- package/docs/plans/0265-born-complete-subagent-session.md +0 -333
- package/docs/plans/0270-type-consumable-public-surface.md +0 -204
- package/docs/plans/0272-export-workspace-collaborator-types.md +0 -147
- package/docs/plans/0277-encapsulate-agent-session.md +0 -304
- package/docs/plans/0280-rename-agent-to-subagent.md +0 -197
- package/docs/plans/0360-custom-agents-default-append.md +0 -132
- package/docs/plans/0373-extract-subagent-state.md +0 -250
- package/docs/plans/0374-encapsulate-subagent-start-notification.md +0 -268
- package/docs/plans/0375-extract-run-listener-workspace-bracket.md +0 -300
- package/docs/plans/0376-extract-manager-observer.md +0 -232
- package/docs/plans/0377-split-widget-delegation-from-runtime.md +0 -254
- package/docs/plans/0378-consolidate-lifecycle-test-fixtures.md +0 -243
- package/docs/plans/0379-consolidate-ui-tools-test-fixtures.md +0 -335
- package/docs/plans/0380-extract-layered-settings-loader.md +0 -223
- package/docs/plans/0381-replace-concurrency-queue-with-limiter.md +0 -267
- package/docs/plans/0400-include-parent-prompt-in-replace-mode.md +0 -199
- package/docs/plans/0403-abort-subagents-on-interrupt.md +0 -180
- package/docs/plans/0412-unify-session-mock-builders.md +0 -146
- package/docs/plans/0420-fold-run-metrics-live-activity-onto-record.md +0 -228
- package/docs/plans/0421-migrate-activity-readers-to-record-getters.md +0 -309
- package/docs/plans/0422-delete-activity-tracker-ui-observer.md +0 -204
- package/docs/plans/0423-widget-self-drive-from-lifecycle.md +0 -264
- package/docs/plans/0424-drop-widget-dep-from-subagent-tool.md +0 -166
- package/docs/plans/0425-reconcile-subagent-events-contract.md +0 -144
- package/docs/plans/0426-consolidate-residual-test-clone-families.md +0 -235
- package/docs/plans/0427-reconsider-ui-direction.md +0 -212
- package/docs/plans/0441-remove-agent-definition-management-subtree.md +0 -180
- package/docs/plans/0442-dissolve-agents-conversation-viewer.md +0 -195
- package/docs/plans/0443-consolidate-remaining-test-clone-families.md +0 -268
- package/docs/plans/0444-shrink-widget-to-background-agents.md +0 -156
- package/docs/plans/0445-native-session-navigation.md +0 -365
- package/docs/plans/0446-spike-session-navigation-entry-criteria.md +0 -171
- package/docs/plans/0447-extract-subagents-settings-command.md +0 -220
- package/docs/plans/0448-block-disabled-agent-spawn.md +0 -207
- package/docs/plans/0462-navigation-renderer-tui-components.md +0 -338
- package/docs/plans/0463-file-snapshot-source-evicted-agents.md +0 -306
- package/docs/plans/0470-refresh-readme-command-surface.md +0 -159
- package/docs/retro/0048-implement-subagents-api.md +0 -44
- package/docs/retro/0049-remove-group-join-output-file-rpc.md +0 -49
- package/docs/retro/0051-update-adr-0001-hard-fork.md +0 -39
- package/docs/retro/0053-extract-model-resolution-from-execute.md +0 -40
- package/docs/retro/0054-decompose-index-into-modules.md +0 -53
- package/docs/retro/0057-structured-debug-logging.md +0 -77
- package/docs/retro/0061-session-format-transcript.md +0 -41
- package/docs/retro/0066-replace-as-any-with-sdk-types.md +0 -44
- package/docs/retro/0069-create-subagent-runtime.md +0 -43
- package/docs/retro/0070-extract-event-handlers.md +0 -49
- package/docs/retro/0071-extract-session-config-assembler.md +0 -60
- package/docs/retro/0072-inject-agent-manager-collaborators.md +0 -46
- package/docs/retro/0076-inject-cwd-into-agent-manager.md +0 -35
- package/docs/retro/0077-inject-project-agents-dir.md +0 -33
- package/docs/retro/0080-consolidate-agent-config-lookup.md +0 -35
- package/docs/retro/0084-extract-git-worktree-manager.md +0 -37
- package/docs/retro/0087-evolve-subagent-runtime-methods.md +0 -42
- package/docs/retro/0098-extract-agent-record-state-machine.md +0 -46
- package/docs/retro/0099-replace-ctx-with-parent-snapshot.md +0 -37
- package/docs/retro/0100-replace-callback-threading-with-session-subscription.md +0 -36
- package/docs/retro/0102-consolidate-test-record-factory.md +0 -30
- package/docs/retro/0108-extract-agent-type-registry.md +0 -41
- package/docs/retro/0109-extract-settings-manager.md +0 -55
- package/docs/retro/0110-agent-activity-tracker.md +0 -44
- package/docs/retro/0111-split-agent-record-lifecycle.md +0 -61
- package/docs/retro/0112-replace-agent-manager-callbacks.md +0 -35
- package/docs/retro/0113-disambiguate-spawn-options.md +0 -29
- package/docs/retro/0114-narrow-agent-tool-menu-deps.md +0 -38
- package/docs/retro/0115-decompose-agent-tool.md +0 -51
- package/docs/retro/0116-type-housekeeping.md +0 -42
- package/docs/retro/0118-settings-manager-apply-methods.md +0 -40
- package/docs/retro/0123-remove-vi-fn-cast-smell.md +0 -49
- package/docs/retro/0131-consolidate-shared-test-fixtures.md +0 -46
- package/docs/retro/0132-inject-io-into-session-config.md +0 -33
- package/docs/retro/0133-inject-sdk-boundary-into-agent-runner.md +0 -45
- package/docs/retro/0134-reduce-as-any-casts.md +0 -56
- package/docs/retro/0135-extract-display-helpers.md +0 -38
- package/docs/retro/0136-decompose-agent-menu.md +0 -43
- package/docs/retro/0144-consolidate-observation-model.md +0 -39
- package/docs/retro/0145-decompose-execute-push-ctx-to-boundary.md +0 -56
- package/docs/retro/0146-narrow-ui-context.md +0 -70
- package/docs/retro/0147-inject-wrap-text-into-conversation-viewer.md +0 -90
- package/docs/retro/0148-split-agent-widget-rendering.md +0 -39
- package/docs/retro/0152-add-prompt-snippet.md +0 -34
- package/docs/retro/0164-reorganize-into-domain-directories.md +0 -82
- package/docs/retro/0165-decompose-resolved-spawn-config.md +0 -78
- package/docs/retro/0166-extract-parent-session-info.md +0 -66
- package/docs/retro/0167-narrow-runner-io.md +0 -63
- package/docs/retro/0168-extract-tool-filter-config.md +0 -76
- package/docs/retro/0169-extract-run-context-from-run-options.md +0 -68
- package/docs/retro/0170-reduce-build-content-lines-complexity.md +0 -72
- package/docs/retro/0171-reduce-render-result-complexity.md +0 -77
- package/docs/retro/0172-extract-turn-formatting.md +0 -80
- package/docs/retro/0180-reorder-append-prompt-for-kv-cache.md +0 -62
- package/docs/retro/0185-remove-persistent-agent-memory.md +0 -73
- package/docs/retro/0188-replace-any-casts-with-sdk-types.md +0 -69
- package/docs/retro/0192-define-session-context-interface.md +0 -59
- package/docs/retro/0193-runtime-owns-context-queries.md +0 -75
- package/docs/retro/0194-align-tool-interfaces-for-structural-typing.md +0 -62
- package/docs/retro/0195-convert-tool-factories-to-classes.md +0 -84
- package/docs/retro/0196-convert-runner-menu-to-classes.md +0 -73
- package/docs/retro/0205-decompose-render-widget-lines.md +0 -64
- package/docs/retro/0206-decompose-show-agent-detail.md +0 -67
- package/docs/retro/0207-decompose-agent-widget-update.md +0 -92
- package/docs/retro/0208-extract-shared-test-fixtures.md +0 -102
- package/docs/retro/0214-convert-remaining-closure-factories-to-classes.md +0 -66
- package/docs/retro/0215-decompose-build-parent-context.md +0 -61
- package/docs/retro/0216-decompose-start-agent.md +0 -80
- package/docs/retro/0217-extract-overwrite-guard.md +0 -63
- package/docs/retro/0218-push-sdk-boundary-in-settings.md +0 -72
- package/docs/retro/0219-reduce-test-duplication-top-3-clone-families.md +0 -64
- package/docs/retro/0227-evolve-agent-record-into-agent.md +0 -80
- package/docs/retro/0228-async-start-agent-dissolve-run-handle.md +0 -80
- package/docs/retro/0229-agent-born-complete.md +0 -89
- package/docs/retro/0230-extract-concurrency-queue.md +0 -38
- package/docs/retro/0231-push-exec-registry-to-runner.md +0 -71
- package/docs/retro/0232-agent-resume-internal-observer-lifecycle.md +0 -109
- package/docs/retro/0237-remove-disallowed-tools.md +0 -78
- package/docs/retro/0238-remove-extensions-filtering.md +0 -72
- package/docs/retro/0239-collapse-filter-active-tools.md +0 -70
- package/docs/retro/0242-rename-agent-tool-to-subagent.md +0 -82
- package/docs/retro/0256-extract-worktree-isolation.md +0 -89
- package/docs/retro/0257-extract-child-session-factory.md +0 -33
- package/docs/retro/0262-add-workspace-provider-seam.md +0 -89
- package/docs/retro/0264-remove-extension-lifecycle-control.md +0 -91
- package/docs/retro/0265-born-complete-subagent-session.md +0 -97
- package/docs/retro/0270-type-consumable-public-surface.md +0 -108
- package/docs/retro/0272-export-workspace-collaborator-types.md +0 -38
- package/docs/retro/0277-encapsulate-agent-session.md +0 -80
- package/docs/retro/0280-rename-agent-to-subagent.md +0 -96
- package/docs/retro/0360-custom-agents-default-append.md +0 -81
- package/docs/retro/0373-extract-subagent-state.md +0 -94
- package/docs/retro/0374-encapsulate-subagent-start-notification.md +0 -171
- package/docs/retro/0375-extract-run-listener-workspace-bracket.md +0 -104
- package/docs/retro/0376-extract-manager-observer.md +0 -81
- package/docs/retro/0377-split-widget-delegation-from-runtime.md +0 -105
- package/docs/retro/0378-consolidate-lifecycle-test-fixtures.md +0 -100
- package/docs/retro/0379-consolidate-ui-tools-test-fixtures.md +0 -52
- package/docs/retro/0380-extract-layered-settings-loader.md +0 -97
- package/docs/retro/0381-replace-concurrency-queue-with-limiter.md +0 -95
- package/docs/retro/0400-include-parent-prompt-in-replace-mode.md +0 -84
- package/docs/retro/0403-abort-subagents-on-interrupt.md +0 -90
- package/docs/retro/0412-unify-session-mock-builders.md +0 -80
- package/docs/retro/0420-fold-run-metrics-live-activity-onto-record.md +0 -90
- package/docs/retro/0421-migrate-activity-readers-to-record-getters.md +0 -105
- package/docs/retro/0422-delete-activity-tracker-ui-observer.md +0 -97
- package/docs/retro/0423-widget-self-drive-from-lifecycle.md +0 -112
- package/docs/retro/0424-drop-widget-dep-from-subagent-tool.md +0 -89
- package/docs/retro/0425-reconcile-subagent-events-contract.md +0 -101
- package/docs/retro/0426-consolidate-residual-test-clone-families.md +0 -100
- package/docs/retro/0427-reconsider-ui-direction.md +0 -102
- package/docs/retro/0441-remove-agent-definition-management-subtree.md +0 -97
- package/docs/retro/0442-dissolve-agents-conversation-viewer.md +0 -108
- package/docs/retro/0443-consolidate-remaining-test-clone-families.md +0 -28
- package/docs/retro/0444-shrink-widget-to-background-agents.md +0 -81
- package/docs/retro/0445-native-session-navigation.md +0 -122
- package/docs/retro/0446-spike-session-navigation-entry-criteria.md +0 -99
- package/docs/retro/0447-extract-subagents-settings-command.md +0 -91
- package/docs/retro/0448-block-disabled-agent-spawn.md +0 -75
- package/docs/retro/0462-navigation-renderer-tui-components.md +0 -105
- package/docs/retro/0463-file-snapshot-source-evicted-agents.md +0 -103
- package/docs/retro/0470-refresh-readme-command-surface.md +0 -40
- package/src/observation/notification-state.ts +0 -27
- package/vitest.config.ts +0 -14
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 445
|
|
3
|
-
issue_title: "pi-subagents: implement native session navigation for any subagent (live or completed)"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #445 — pi-subagents: implement native session navigation for any subagent (live or completed)
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-06-22T00:00:00Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Produced `docs/plans/0445-native-session-navigation.md`, a sliced plan for Phase 19 Step 4.
|
|
13
|
-
The operator (issue author) chose Pi's per-entry TUI-component renderer as the eventual target but explicitly invited a Kent Beck "make the change easy, then make the easy change" breakdown into incremental, releasable additions, and chose `manager.listAgents()`-only as the candidate set.
|
|
14
|
-
The plan scopes #445 to the first releasable vertical slice — full list → pick → read-only live transcript using `serializeConversation` text rendering behind a renderer-agnostic `TranscriptSource` seam — and names two follow-ups (TUI-component renderer; evicted-agent file source).
|
|
15
|
-
|
|
16
|
-
### Observations
|
|
17
|
-
|
|
18
|
-
- **Two `ask_user` rounds drove scope.**
|
|
19
|
-
Round 1: renderer choice (text vs TUI components) and candidate-set scope.
|
|
20
|
-
Round 2: decomposition strategy.
|
|
21
|
-
The operator's note on round 1 ("If this sounds large, it's probably because it is... what would Kent Beck do") reframed the whole plan from one big issue into a sliced first release.
|
|
22
|
-
- **Key architectural finding — the file-snapshot branch is unreachable in #445.**
|
|
23
|
-
`SubagentManager.removeRecord` calls `record.disposeSession()` then `agents.delete(id)` atomically, and `disposeSession()` does not null `subagentSession`.
|
|
24
|
-
So no record in `listAgents()` is ever session-disposed; with the `listAgents()`-only candidate set, every listed session-ready record has a live session, and the dual-source "evicted/untracked → file" branch has no caller.
|
|
25
|
-
Implementing it now would be dead code that fails the `fallow dead-code` gate.
|
|
26
|
-
This sharpened the slice: #445 ships the **live source only** behind the seam.
|
|
27
|
-
- **Type-boundary plan.** `AgentMessage` is not in the `@earendil-works/pi-coding-agent` barrel and `@earendil-works/pi-agent-core` is not a dependency, so the plan derives `SessionMessage = SessionContext["messages"][number]` from the barrel-exported `SessionContext` rather than adding a dep. `serializeConversation` takes a mutable `Message[]`, so the renderer spreads (`serializeConversation([...messages])`); `AgentMessage`→`Message` assignability is flagged as a TDD step-2 `pnpm run check` verification with a typed-adapter fallback.
|
|
28
|
-
- **Seam justifies its weight via testability, not just the follow-up.** `TranscriptSource` + narrow `NavigableSubagent` interfaces let the pure module be unit-tested with light stubs (no full `Subagent`/`TUI`/`AgentSession`), and decouple the renderer (text→components) from sourcing (live→file) for the two named follow-ups.
|
|
29
|
-
- **Doomed-code avoidance.**
|
|
30
|
-
The navigator must not import `message-formatters.ts` or `conversation-viewer.ts` (both deleted in Step 5, [#442]); the streaming indicator is a small local helper and the transcript text is Pi's `serializeConversation`.
|
|
31
|
-
- **Open item for ship time:** the architecture roadmap's Step 4 description currently scopes full dual-source + components as one step and will need rescoping to match the slice, plus filing the two follow-up issues.
|
|
32
|
-
Command name `subagent-sessions` is proposed but flagged confirmable.
|
|
33
|
-
- Release: ship independently (roadmap Step 4 is `Release: independent`, spike-gated; not part of the "dissolve-agents" batch).
|
|
34
|
-
|
|
35
|
-
## Stage: Implementation — TDD (2026-06-22T18:03:26Z)
|
|
36
|
-
|
|
37
|
-
### Session summary
|
|
38
|
-
|
|
39
|
-
Implemented the sliced #445 in three TDD cycles: (1) the typed `agentMessages` accessor (`SessionMessage` on `SubagentSession`/`Subagent`); (2) the pure `session-navigation.ts` (selection, `liveSource`, `renderTranscriptLines`); (3) the `session-navigator.ts` overlay + `/subagent-sessions` command + `index.ts` wiring.
|
|
40
|
-
Test count went 1064 → 1084 (+20).
|
|
41
|
-
Pre-completion reviewer returned PASS.
|
|
42
|
-
|
|
43
|
-
### Observations
|
|
44
|
-
|
|
45
|
-
- **`AgentMessage` is NOT assignable to `serializeConversation`'s `Message[]`** (the plan's flagged risk materialized): `AgentMessage` is a superset adding session-display variants like `BashExecutionMessage`.
|
|
46
|
-
Applied the planned mitigation — a private `toMessages` adapter casting via `as unknown as Parameters<typeof serializeConversation>[0]` (`Message` is not re-exported from the `@earendil-works/pi-ai` barrel, so the type is referenced through the function signature rather than imported by name).
|
|
47
|
-
- **`SessionContext` name collision:** `types.ts` already declares a local `SessionContext` interface, so the SDK import is aliased — `import type { SessionContext as SdkSessionContext }` — and `SessionMessage = SdkSessionContext["messages"][number]`.
|
|
48
|
-
- **`describeActivity` survives in `display.ts`** (not the doomed `message-formatters.ts`), so the streaming indicator reuses it — the navigator imports neither doomed module, as planned.
|
|
49
|
-
- **File-snapshot branch confirmed unreachable and omitted:** with the `listAgents()`-only candidate set, no listed record is ever session-disposed (dispose-and-delete are atomic), so the live source is always valid; implementing the file branch would have been dead code.
|
|
50
|
-
`fallow dead-code` is clean.
|
|
51
|
-
- **Minor deviation:** `test/helpers/mock-session.ts` gained an `agentMessages` getter on the session stub (needed for the `Subagent.agentMessages` delegation test) — a small fixture addition not itemized in the plan's Module-Level Changes.
|
|
52
|
-
- **Two lint nits caught by the pre-commit hook** (both per the testing skill): an unnecessary optional chain on a destructured array element, and an unnecessary `!` on `mock.calls[0][0]` — both fixed inline.
|
|
53
|
-
- **Architecture doc:** added a "Landed ([#445], sliced)" note to Step 4; did **not** mark the step `✅` because the component renderer and evicted-agent file source are deferred follow-ups.
|
|
54
|
-
`SKILL.md` `ui/` module count (10 → 12) left for a later Phase 19 doc-sync, per the plan.
|
|
55
|
-
- **Reviewer verdict: PASS.**
|
|
56
|
-
Two WARN notes, both intentional and plan-sanctioned: Step 4 heading unchecked (correct for a partial slice) and the deferred `SKILL.md` count.
|
|
57
|
-
- **Open at ship time:** confirm command name `subagent-sessions`; file the two follow-up issues (component renderer; evicted-agent file source).
|
|
58
|
-
|
|
59
|
-
## Stage: User Note (2026-06-22T18:26:37Z)
|
|
60
|
-
|
|
61
|
-
When new issues are identified during planning, file them before leaving the planning stage rather than deferring to ship time.
|
|
62
|
-
Two motivations: the planning session uses a very capable model, and it already has all the context needed to write the issues well.
|
|
63
|
-
Applied here: the two follow-up issues (#462 renderer upgrade, #463 file-snapshot source) were identified during planning but filed only at ship time — they should have been created at the end of the planning commit instead.
|
|
64
|
-
|
|
65
|
-
## Stage: Final Retrospective (2026-06-22T18:28:31Z)
|
|
66
|
-
|
|
67
|
-
### Session summary
|
|
68
|
-
|
|
69
|
-
One continuous session carried #445 from planning through TDD, ship, and a mid-session retro note.
|
|
70
|
-
It delivered the sliced Phase 19 Step 4 — the `/subagent-sessions` command, the live `TranscriptSource`, and the typed `agentMessages` accessor — across three `feat:` commits plus docs, released as `pi-subagents` v17.3.0, with two follow-ups (#462, #463) filed at ship.
|
|
71
|
-
Execution was notably clean: the plan anticipated both hard risks, and every implementation slip was absorbed by the feedback loops within its active TDD cycle.
|
|
72
|
-
|
|
73
|
-
### Observations
|
|
74
|
-
|
|
75
|
-
#### What went well
|
|
76
|
-
|
|
77
|
-
1. **The plan pre-empted the two hardest risks.**
|
|
78
|
-
`AgentMessage`→`Message` non-assignability and the unreachable file-snapshot branch were both called out in planning and both materialized exactly as predicted; the planned mitigations (the `toMessages` adapter; shipping the live source only) applied with zero rework.
|
|
79
|
-
2. **The `TranscriptSource` seam earned its keep.**
|
|
80
|
-
The pure `session-navigation.ts` was unit-tested with light stubs (no full `Subagent`/`TUI`/`AgentSession`), and the seam cleanly hosts both deferred follow-ups — testability justified it independent of the follow-ups.
|
|
81
|
-
3. **Tight, incremental feedback loops.**
|
|
82
|
-
Per-cycle affected-file test runs, `pnpm run check` after every type-touching step, and full suite + lint + `fallow dead-code` after the last step caught every slip within seconds.
|
|
83
|
-
4. **Two `ask_user` rounds during planning converted a large issue into a releasable slice** (the operator's Kent Beck nudge) — the central design win of the issue.
|
|
84
|
-
|
|
85
|
-
#### What caused friction (agent side)
|
|
86
|
-
|
|
87
|
-
1. `missing-context` — wrote test assertions before checking helper behavior: `formatMs` yields `3.0s` not `3s`, `getDisplayName` falls back to `Agent`, `TOOL_DISPLAY` keys are lowercase, and `AgentTypeRegistry` takes `() => new Map()` not `() => []`.
|
|
88
|
-
Impact: ~4 assertion fixes within one Green iteration; no rework beyond the cycle.
|
|
89
|
-
2. `missing-context` — `SessionContext` name collision: imported the SDK type into `types.ts` without noticing a local `SessionContext` interface already existed.
|
|
90
|
-
Impact: one aliasing edit (`SdkSessionContext`), caught immediately by biome `noRedeclare`.
|
|
91
|
-
3. `other` (mechanical) — a stray `}` when wrapping a new `describe` block (AGENTS.md already warns about brace-pair edits), and `SessionMessage` imported from the wrong module in the navigator test.
|
|
92
|
-
Impact: one fix each, caught by autoformat and `tsc`.
|
|
93
|
-
4. `instruction-violation` (self-identified, hook-caught) — two lint nits the `testing` skill already documents: an unnecessary optional chain and an unnecessary `!` on `mock.calls[0][0]`.
|
|
94
|
-
Impact: two inline fixes; no rework.
|
|
95
|
-
|
|
96
|
-
None of the agent-side slips caused rework beyond their active TDD cycle — the autoformat/biome/`tsc`/vitest/pre-commit loops absorbed all of them.
|
|
97
|
-
|
|
98
|
-
#### What caused friction (user side)
|
|
99
|
-
|
|
100
|
-
1. The dominant cross-session finding (recorded separately as the User Note stage): follow-up issues identified during planning (#462, #463) were filed only at ship time.
|
|
101
|
-
The workflow itself encodes the deferral — the plan said "file at ship time" and `/ship-issue` step 4c creates them.
|
|
102
|
-
The operator wants them filed during planning, while the capable planning model still holds full context.
|
|
103
|
-
Opportunity: move follow-up creation into `/plan-issue`.
|
|
104
|
-
|
|
105
|
-
### Diagnostic details
|
|
106
|
-
|
|
107
|
-
- **Model-performance correlation** — the only subagent dispatch was the `pre-completion-reviewer` on `anthropic/claude-sonnet-4-6`, a judgment-heavy review task; appropriate match.
|
|
108
|
-
Planning ran on a capable model, which the operator explicitly values.
|
|
109
|
-
No mismatch.
|
|
110
|
-
- **Escalation-delay tracking** — no rabbit-holes; the longest same-area sequence was 4 assertion fixes inside one Green iteration (under the 5-call flag).
|
|
111
|
-
- **Unused-tool detection** — the `missing-context` slips were caught trivially by running tests; reading `display.ts` helpers first would have pre-empted them, but the cost was negligible and no Explore/`colgrep` dispatch was warranted.
|
|
112
|
-
- **Feedback-loop gap analysis** — verification ran incrementally and completely (per-cycle tests, `check` after type changes, full gate after the last step); no gap.
|
|
113
|
-
This is a win, not a gap.
|
|
114
|
-
|
|
115
|
-
### Changes made
|
|
116
|
-
|
|
117
|
-
Moved follow-up issue creation from ship time to planning time, with the backstop relocated to pre-completion (operator-directed):
|
|
118
|
-
|
|
119
|
-
1. `.pi/prompts/plan-issue.md` — added a `## File follow-up issues` section before `## Commit`: file plan-named follow-ups during planning with `gh issue create` and record each number in the plan; nothing speculative.
|
|
120
|
-
2. `.pi/agents/pre-completion-reviewer.md` — added checklist section `2i. Planned follow-up issues` and its report stanza: WARN when the plan names a follow-up but records no issue number; also added the case to the severity model's WARN list.
|
|
121
|
-
3. `.pi/prompts/ship-issue.md` — removed step `4c. Create planned follow-up issues` (follow-ups are now filed during planning; the close comment in step 5 references the recorded numbers).
|
|
122
|
-
4. `AGENTS.md` — extended the pre-completion-reviewer coverage enumeration to include planned follow-up filing.
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 446
|
|
3
|
-
issue_title: "pi-subagents: spike — resolve ADR-0004 session-navigation entry criteria"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #446 — pi-subagents: spike — resolve ADR-0004 session-navigation entry criteria
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-06-20T00:00:00Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Planned the Phase 19 Step 1 spike that answers the four ADR-0004 session-navigation entry criteria and records them as an ADR-0004 addendum.
|
|
13
|
-
Confirmed the release is independent and that the only committed artifact is the addendum.
|
|
14
|
-
The plan lives at `packages/pi-subagents/docs/plans/0446-spike-session-navigation-entry-criteria.md`; next stage is `/build-plan` (docs/spike deliverable, no committed TDD cycles).
|
|
15
|
-
|
|
16
|
-
### Observations
|
|
17
|
-
|
|
18
|
-
- Operator owns the issue (`gotgenes` == gh user), so the "Proposed change" is the working hypothesis.
|
|
19
|
-
Used `ask_user` once to resolve two method ambiguities: spike method = **automated observed test (vitest)**, committed artifact = **ADR addendum only** (the vitest harness is throwaway, discarded).
|
|
20
|
-
- Gathered the SDK evidence up front so the addendum's expected answers are grounded: `switchSession` is a full active-session takeover that tears down the current runtime via `session_shutdown` (so it threatens the root's in-flight turn); `ReplacedSessionContext` exposes `sendUserMessage` (switch makes the child interactive); `loadEntriesFromFile`/`parseSessionEntries` read entries without switching; `Subagent.outputFile` already exposes the child JSONL path; sibling commands use flat hyphenated names (`agents`, `colgrep-reindex`, `permission-system`).
|
|
21
|
-
- Expected recommendations the spike will confirm: read-only `loadEntriesFromFile` transcript (resolves root-continuity by construction), command-first parallel-agent selection (widget gesture deferred), and `/subagents-settings` (reject the ADR's tentative `/subagents:settings`).
|
|
22
|
-
- `setBeforeSessionInvalidate` is a **host** runtime seam (`agent-session-runtime`/`interactive-mode`), not on the extension command context — noted in Background so Step 4 does not assume the extension can call it.
|
|
23
|
-
- No production code changes and no invariants at risk; the read-only path was chosen partly to keep transcript rendering out of core (preserving the Phase 18 spine invariants from issues #422–#425).
|
|
24
|
-
|
|
25
|
-
## Stage: Implementation — Build (2026-06-20T10:00:00Z)
|
|
26
|
-
|
|
27
|
-
### Session summary
|
|
28
|
-
|
|
29
|
-
Executed the spike: ran a throwaway vitest harness against a real 43-entry child session JSONL, confirmed the read-only transcript path, then wrote the ADR-0004 addendum answering all four entry criteria.
|
|
30
|
-
Discarded the harness (operator decision: addendum only) and folded the architecture.md doc-sync into this build rather than deferring it.
|
|
31
|
-
Four `docs:` commits; pre-completion reviewer returned WARN, whose findings were then resolved.
|
|
32
|
-
|
|
33
|
-
### Observations
|
|
34
|
-
|
|
35
|
-
- **Key divergence from the plan (Finding 0):** the plan's Design Overview assumed `loadEntriesFromFile(path)` would be the read mechanism, but it is **not part of the package's public surface** — it lives in the deep `core/session-manager` module (marked `/** Exported for testing */`) and the public barrel (`src/index.ts` → `dist/index.{d.ts,js}`) re-exports only a curated subset that includes `parseSessionEntries` but not `loadEntriesFromFile`; the `exports` map exposes only `"."`, so the deep import is unsupported too.
|
|
36
|
-
This is **not** a types/runtime mismatch — both barrels agree, and `tsc` rejects the import with `TS2305`.
|
|
37
|
-
My first harness reached a runtime `is not a function` only because Vitest/esbuild strips types without type-checking; `pnpm run check` (`tsc`) would have caught it at compile time.
|
|
38
|
-
My earlier "types/runtime mismatch" framing in the addendum/architecture was wrong and was corrected in a follow-up `docs:` commit.
|
|
39
|
-
Viable path: `parseSessionEntries(readFileSync(outputFile, "utf8"))` (`parseSessionEntries` is public).
|
|
40
|
-
- **Upgrade check (operator question):** verified the omission is **not** version-specific — the latest `0.79.8` barrel omits it identically to the pinned `0.79.1`, so an SDK bump does not surface `loadEntriesFromFile`.
|
|
41
|
-
No upgrade pursued (out of scope for a docs-only spike); noted the routine `0.79.1` → `0.79.8` freshness gap as a separate, unrelated item.
|
|
42
|
-
- **Doc-sync landed now, not deferred:** the reviewer flagged architecture.md line 997 ("Mechanism (confirmed by Step 1): `switchSession` … or `loadEntriesFromFile`") as actively contradicting the spike.
|
|
43
|
-
Since the spike now exists, I marked Step 1 ✅ (heading + Mermaid node `S1`), corrected the Phase 18 summary line, and rewrote the Step 4 mechanism line to `parseSessionEntries(readFileSync(...))` — closing the WARN.
|
|
44
|
-
- **Pre-completion reviewer: WARN** (no FAILs) — three architecture.md staleness findings, all addressed in the final `docs:` commit (`74e2374f`).
|
|
45
|
-
No `src/`/`test/` changes; `pnpm run check` + `pnpm run lint` + `pnpm fallow dead-code` all green at baseline and after.
|
|
46
|
-
- Release recommendation unchanged: **ship independently** (`Release: independent`).
|
|
47
|
-
|
|
48
|
-
## Stage: Final Retrospective (2026-06-20T18:00:00Z)
|
|
49
|
-
|
|
50
|
-
### Session summary
|
|
51
|
-
|
|
52
|
-
Planned, built, and shipped the Phase 19 Step 1 spike across three workflow stages, producing the ADR-0004 addendum that answers all four session-navigation entry criteria and unblocks #445.
|
|
53
|
-
The spike did its job — it rejected ADR-0004's literally-named `loadEntriesFromFile` mechanism before Step 4 coded against it — but the build stage committed an incorrect "types/runtime mismatch" characterization that took two user questions and a correction commit to fix.
|
|
54
|
-
Eight `docs:` commits landed; no release (all `docs:`, auto-batched).
|
|
55
|
-
|
|
56
|
-
### Observations
|
|
57
|
-
|
|
58
|
-
#### What went well
|
|
59
|
-
|
|
60
|
-
- **The spike paid for itself, then over-delivered.**
|
|
61
|
-
It caught that ADR-0004's named candidate (`loadEntriesFromFile`) is not in the SDK's public surface — a finding about the *implementation*, not the harness — before Step 4 started.
|
|
62
|
-
The operator's three follow-up questions (upgrade?
|
|
63
|
-
describe-the-mismatch?
|
|
64
|
-
spike-vs-implementation impact?) then drove the addendum from a thin "use `parseSessionEntries`" note into a complete, link-backed render pipeline (Finding 1: `parseSessionEntries` → `buildSessionContext` → Pi's public entry components / `serializeConversation`).
|
|
65
|
-
Step 4 now starts from a verified, public-API-only design.
|
|
66
|
-
- **Clean, non-defensive self-correction.**
|
|
67
|
-
When the operator asked me to substantiate the claim with links (turn 74), running the actual `tsc` probe surfaced my own error; I corrected all three artifacts (addendum, `architecture.md`, retro) in commit `112c4254` without hedging.
|
|
68
|
-
"Ask the agent to cite/substantiate a claim" proved a high-leverage verification gesture.
|
|
69
|
-
|
|
70
|
-
#### What caused friction (agent side)
|
|
71
|
-
|
|
72
|
-
- `wrong-abstraction` (compounded by `missing-context`) — I diagnosed a question about the SDK's *export surface* from a *runtime* symptom.
|
|
73
|
-
The throwaway vitest harness threw `loadEntriesFromFile is not a function`, and I leapt to the dramatic reading ("declared in `.d.ts` but absent at runtime — a types/runtime mismatch") instead of running `tsc`, which disambiguates instantly (`TS2305: has no exported member`).
|
|
74
|
-
The symbol is simply not in the public barrel — types and runtime agree.
|
|
75
|
-
Impact: an incorrect technical claim shipped into three committed artifacts (addendum `7c505b78`, `architecture.md`, the build retro note) and required a 3-file correction commit (`112c4254`) plus two operator questions to surface and fix.
|
|
76
|
-
- `instruction-violation` (user-caught) — the `testing` skill already states "Vitest uses esbuild and does not typecheck; run `pnpm run check`."
|
|
77
|
-
I never ran `tsc` against the harness or the export claim during the build.
|
|
78
|
-
Two reasons it slipped: (1) the skill was not loaded — `/build-plan` only loads `testing` "if the plan involves test changes or TDD steps," and a docs-only spike using a throwaway harness does not obviously match; (2) the existing rule is framed for "type-only changes," not for *claims/findings about what a module exports*, so it would not clearly have fired even if loaded.
|
|
79
|
-
- `other` (tooling friction, minor) — getting the `tsc` probe to resolve the package took four attempts (turns 77–80: `npx` blocked → `pnpm exec` → files-on-cmdline tsconfig error → probe-inside-package).
|
|
80
|
-
Impact: added friction, no rework; not a conceptual rabbit-hole.
|
|
81
|
-
|
|
82
|
-
#### What caused friction (user side)
|
|
83
|
-
|
|
84
|
-
- None material — the operator's three interventions were strategic probes (dependency-freshness, claim substantiation, spike-vs-implementation scope) that each improved the artifact.
|
|
85
|
-
The only "earlier" opportunity is an agent-side gap: I should have self-applied the `tsc` check so the operator did not need to ask "describe the mismatch" to trigger verification.
|
|
86
|
-
|
|
87
|
-
### Diagnostic details
|
|
88
|
-
|
|
89
|
-
- **Model-performance correlation** — Planning + Build + the correction work all ran on `anthropic/claude-opus-4-8` (turns 2–104); the mischaracterization therefore occurred on the *strong* model, so the fix is process (run `tsc` on export claims), not model selection.
|
|
90
|
-
The Ship stage (turns 106–122) ran on `opencode-go/deepseek-v4-flash` — appropriate cost-matching for a mechanical git/CI/close procedure, which it executed cleanly.
|
|
91
|
-
A transient `anthropic/claude-sonnet-4-6` `model_change` carried no assistant turn (never ran).
|
|
92
|
-
- **Escalation-delay tracking** — no rabbit-hole exceeded five consecutive tool calls on one error; the runtime `is not a function` was resolved in ~2 calls (the issue was the *interpretation*, not a stuck loop).
|
|
93
|
-
- **Unused-tool detection** — for the mischaracterization, `tsc` / `pnpm run check` was available and routine but applied only at baseline (turn 29) and not again until the operator forced it (turns 77–80); it was never run against the harness or the claim.
|
|
94
|
-
- **Feedback-loop gap analysis** — `pnpm run lint` ran after every doc edit (good incremental hygiene), but the *type-check* loop was skipped for precisely the finding that needed it — the harness ran under vitest (no typecheck) and `tsc` was not run on the export claim before committing it.
|
|
95
|
-
|
|
96
|
-
### Changes made
|
|
97
|
-
|
|
98
|
-
1. Extended the `testing` skill's `## Type checking` section to cover verifying claims about module exports with `tsc`, not runtime symptoms — `Refs #446`.
|
|
99
|
-
File: `.pi/skills/testing/SKILL.md`.
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 447
|
|
3
|
-
issue_title: "pi-subagents: extract subagent settings to a focused /subagents-settings command"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #447 — pi-subagents: extract subagent settings to a focused /subagents-settings command
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-06-20T00:00:00Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Produced a numbered TDD plan for Phase 19 Step 2: a purely additive extraction of `AgentsMenuHandler.showSettings` into a standalone `SubagentsSettingsHandler` registered as the `/subagents-settings` command.
|
|
13
|
-
Confirmed the command name against the closed spike (#446) and its ADR-0004 addendum (Criterion 4), and verified `SettingsManager` already structurally satisfies the new narrow manager interface so it can be passed directly.
|
|
14
|
-
The plan ships independently (roadmap `Release: independent`).
|
|
15
|
-
|
|
16
|
-
### Observations
|
|
17
|
-
|
|
18
|
-
- The extraction is a faithful verbatim lift — `showSettings` already had zero coupling beyond `this.settings` and `ui`, so the design-review checklist came back clean (100% field usage on both new narrow interfaces, no LoD/output-arg smells).
|
|
19
|
-
Classified as a genuine collaborator extraction, not procedure-splitting.
|
|
20
|
-
- Declared two narrow interfaces owned by the new module: `SubagentsSettingsManager` (shape-identical to the doomed `AgentMenuSettings` but with no import from `agent-menu.ts`) and `SubagentsSettingsUI` (drops `confirm`/`editor`/`custom` from `MenuUI` — ISP).
|
|
21
|
-
- Strictly additive: `agent-menu.ts` is untouched, and its settings tests stay as-is because the in-menu path keeps shipping until Step 5 (#442) deletes the file.
|
|
22
|
-
Removing them now would drop coverage of a live surface.
|
|
23
|
-
- Preserved the single-selection-then-return semantics of `showSettings` verbatim (no re-show loop) — flagged a settings re-show loop as a deferred UX open question.
|
|
24
|
-
- Two small TDD steps (handler+tests, then `index.ts` registration); noted they may fold into one commit since the export and its sole call site are tiny, with `pnpm run check` required right after the wiring step.
|
|
25
|
-
- No third-party `ask_user` gate needed — issue filed by the operator (`gotgenes`), direction fixed by ADR-0004, design unambiguous.
|
|
26
|
-
|
|
27
|
-
## Stage: Implementation — TDD (2026-06-20T14:30:00Z)
|
|
28
|
-
|
|
29
|
-
### Session summary
|
|
30
|
-
|
|
31
|
-
Implemented Phase 19 Step 2 in two TDD cycles plus a doc-sync commit: added `SubagentsSettingsHandler` (with narrow `SubagentsSettingsManager` and `SubagentsSettingsUI` interfaces) lifted verbatim from `AgentsMenuHandler.showSettings`, then registered the `/subagents-settings` command in `index.ts`.
|
|
32
|
-
Test count went 1051 → 1062 (+11, one new file `test/ui/subagents-settings.test.ts`).
|
|
33
|
-
Full suite, `tsc`, root lint, and `fallow dead-code` all green.
|
|
34
|
-
|
|
35
|
-
### Observations
|
|
36
|
-
|
|
37
|
-
- The lift was clean: `SettingsManager` already exposed all six members of the new narrow manager interface, so the `index.ts` wiring passed `settings` directly with zero adapter — `pnpm run check` confirmed structural satisfaction.
|
|
38
|
-
- `makeMenuUI` from `ui-stubs.ts` was reused as the UI stub without modification — its wider shape (`confirm`/`editor`/`custom`) structurally satisfies the narrower `SubagentsSettingsUI`, so no new helper was needed.
|
|
39
|
-
- Kept the two cycles as separate commits rather than folding them; the export and its sole call site were small enough that either would have been valid.
|
|
40
|
-
- Deviation from plan: flipped `✅` on the architecture Step 2 heading and its Mermaid node now (the plan had flagged this as a ship-time open question).
|
|
41
|
-
Applied per the `/tdd-plan` template's roadmap-completion rule; verified the diagram still renders via `mmdc`.
|
|
42
|
-
The phase status row was left unchanged (only 1 of 7 steps done).
|
|
43
|
-
- `agent-menu.ts` was not touched (verified by the reviewer via `git log`), preserving the additive-only constraint.
|
|
44
|
-
- Pre-completion reviewer: WARN.
|
|
45
|
-
Reviewer warnings: one non-blocking finding — `.pi/skills/package-pi-subagents/SKILL.md` records `ui/` as 10 modules (now 11); the plan intentionally deferred this coarse-summary update to a later Phase 19 doc-sync.
|
|
46
|
-
No FAILs; all deterministic checks PASS, verbatim-lift fidelity and ISP of both narrow interfaces confirmed.
|
|
47
|
-
|
|
48
|
-
## Stage: Final Retrospective (2026-06-20T18:36:58Z)
|
|
49
|
-
|
|
50
|
-
### Session summary
|
|
51
|
-
|
|
52
|
-
Shipped Phase 19 Step 2 (#447) end to end across planning, TDD, and ship stages, releasing `pi-subagents` `17.1.0`.
|
|
53
|
-
The one off-script event was a user-reported Mermaid syntax error in `architecture.md`, which I localized by extracting all six diagram blocks and running `mmdc` on each, then fixed by quoting the offending flowchart node labels.
|
|
54
|
-
Execution was otherwise clean: two green TDD cycles (+11 tests), a WARN pre-completion review (one intentionally-deferred doc finding), and a correct `UNSTABLE`/`GITHUB_TOKEN` release-merge fallback.
|
|
55
|
-
|
|
56
|
-
### Observations
|
|
57
|
-
|
|
58
|
-
#### What went well
|
|
59
|
-
|
|
60
|
-
- Localizing the Mermaid error with the diagram name wrong: the user called it the "State dependency diagram" but the broken block was the "Step dependency diagram" flowchart.
|
|
61
|
-
Rather than guess from the ambiguous name (I had glanced at the `stateDiagram-v2` lifecycle and the `classDiagram` first), I scripted extraction of all six `mermaid` fences and ran `mmdc` on each — block 6 failed with `got 'PS'`, pinpointing the exact line.
|
|
62
|
-
Brute-force validation beat name-matching.
|
|
63
|
-
- The release-merge fallback worked exactly as the ship prompt describes: `release_pr_merge` refused on `merge_state: UNSTABLE`, the status-check rollup was empty (the `GITHUB_TOKEN` no-checks case), and `gh pr merge 450 --rebase` + `git pull --ff-only` landed `17.1.0` linearly.
|
|
64
|
-
|
|
65
|
-
#### What caused friction (agent side)
|
|
66
|
-
|
|
67
|
-
- `missing-context` (prior session) — the broken diagram was authored in `74e2374f docs: mark Phase 19 Step 1 spike complete (#446)`: a flowchart node label `S1[✅ Step 1 - Spike (#446)]` with unquoted parentheses, which Mermaid parses as a nested round-node shape (`Expecting ... got 'PS'`).
|
|
68
|
-
It was committed without an `mmdc` pass and slipped through `pnpm run lint` (rumdl validates markdown, not Mermaid semantics) and CI.
|
|
69
|
-
Impact: surfaced two sessions later as a user-caught defect; one extra `docs:` fix commit (`90ca6e2d`) this session.
|
|
70
|
-
Root cause is a coverage gap: the `mermaid` skill's pitfall list does not mention parentheses/shape-delimiter characters in node labels, so the exact failure mode was undocumented.
|
|
71
|
-
|
|
72
|
-
#### What caused friction (user side)
|
|
73
|
-
|
|
74
|
-
- None material.
|
|
75
|
-
The diagram-name mismatch ("State" vs "Step" dependency diagram) added one or two orienting reads but did not cause rework — the all-blocks `mmdc` sweep absorbed the ambiguity.
|
|
76
|
-
|
|
77
|
-
### Diagnostic details
|
|
78
|
-
|
|
79
|
-
- **Model-performance correlation** — the only subagent dispatch was the `pre-completion-reviewer` on `anthropic/claude-sonnet-4-6` (judgment-heavy review work); appropriate match, no over/under-powered mismatch.
|
|
80
|
-
- **Escalation-delay tracking** — the Mermaid detour resolved in ~5 progress-making tool calls (extract blocks → `mmdc` each → read error → quote labels → re-validate); not a rabbit-hole, no subagent escalation warranted.
|
|
81
|
-
- **Unused-tool detection** — none; `mmdc` (the correct validator) was used directly.
|
|
82
|
-
- **Feedback-loop gap analysis** — verification ran incrementally throughout TDD (per-file `vitest` in each red/green, `pnpm run check` right after the interface-bearing wiring step, full suite + root lint + `fallow dead-code` at the end), not just terminally.
|
|
83
|
-
|
|
84
|
-
### Changes made
|
|
85
|
-
|
|
86
|
-
1. `.pi/skills/mermaid/SKILL.md` — added a "Parentheses and special characters in node labels" pitfall (with the `S1[✅ Step 1 - Spike (#446)]` WRONG/RIGHT example from this session) covering the `(`/`[`/`{`/`:` shape-delimiter trap that produced the `got 'PS'` parse error.
|
|
87
|
-
|
|
88
|
-
### Follow-up (not implemented — suggest a GitHub issue + `/plan-issue`)
|
|
89
|
-
|
|
90
|
-
1. **CI Mermaid-validation gate** — run `mmdc` over every `mermaid` fence as part of `pnpm run lint` or a pre-commit hook, so a broken diagram (like `74e2374f`'s unquoted-parens node) fails at author time instead of surviving to a user-caught defect.
|
|
91
|
-
Out of retro scope (infra, touches `package.json`/lint config/hooks); record as its own issue.
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 448
|
|
3
|
-
issue_title: "`enabled: false` does not prevent explicitly spawning disabled agents"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #448 — `enabled: false` does not prevent explicitly spawning disabled agents
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-06-20T00:00:00Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Planned the fix for a third-party bug report: `enabled: false` agent overrides are hidden from the available-types list but still spawnable when named explicitly via `subagent_type`.
|
|
13
|
-
The plan adds a disabled-type gate in `resolveSpawnConfig` (returning an explicit error) and a `enabled` filter in `buildTypeListText`, both localized changes with no new collaborators or interface changes.
|
|
14
|
-
|
|
15
|
-
### Observations
|
|
16
|
-
|
|
17
|
-
- Issue author (`nickadminroot`) is not the operator (`gotgenes`), so I ran the `ask-user` direction gate.
|
|
18
|
-
Operator confirmed: fix it, **return an explicit error** (`Agent type "<Name>" is disabled`) rather than the lenient fall-back-to-`general-purpose` alternative, and **include both fixes** (spawn path + tool-description list).
|
|
19
|
-
- Root cause is `resolveType` → `resolveKey` ignoring `enabled`; the registry already has `isValidType` (checks `enabled`) but it was unused on the spawn path.
|
|
20
|
-
The gate reuses `isValidType`, leaving `resolveType` / `resolveAgentConfig` untouched so UI consumers that intentionally resolve disabled configs keep working.
|
|
21
|
-
- Rejected changing `resolveType` or `resolveAgentConfig` directly — `agent-config-editor.ts` and `agent-menu.ts` rely on resolving disabled agents to display/edit/re-enable them.
|
|
22
|
-
- For the tool-description fix, chose to filter inside `buildTypeListText` rather than re-define `getDefaultAgentNames` / `getUserAgentNames` semantics; those two methods have `buildTypeListText` as their sole consumer (verified by grep), but keeping their meaning intact is cleaner.
|
|
23
|
-
- Classified as non-breaking `fix:` — the change aligns code with the documented README/registry contract; explicit spawning of a disabled agent was undocumented buggy behavior.
|
|
24
|
-
- Not in any architecture roadmap step (no `#448` reference in `docs/`), so **ship independently**.
|
|
25
|
-
|
|
26
|
-
## Stage: Implementation — TDD (2026-06-20T12:40:00Z)
|
|
27
|
-
|
|
28
|
-
### Session summary
|
|
29
|
-
|
|
30
|
-
Completed 2 TDD cycles and all post-step verification gates.
|
|
31
|
-
Step 1 added a 3-line enabled-type gate in `resolveSpawnConfig` (reusing `isValidType`) and 2 new test cases in `test/tools/spawn-config.test.ts`.
|
|
32
|
-
Step 2 added an `isEnabled` predicate filter in `buildTypeListText` and 2 new test cases in `test/tools/helpers.test.ts`.
|
|
33
|
-
Test count delta: 1047 → 1051 (+4).
|
|
34
|
-
|
|
35
|
-
### Observations
|
|
36
|
-
|
|
37
|
-
- No deviations from the plan.
|
|
38
|
-
Both changes were as small as designed: 3 lines in `spawn-config.ts`, 2 lines in `helpers.ts`.
|
|
39
|
-
- Extended the `makeRegistry` stub's `resolve` type in `test/tools/helpers.test.ts` to include an optional `enabled` field, so the `isEnabled` predicate could be exercised without touching production code.
|
|
40
|
-
- The `makeAgentConfig` helper was added to `test/tools/spawn-config.test.ts` (mirroring the pattern in `test/config/agent-types.test.ts`) rather than importing from a shared fixture, since the existing spawn-config test fixture infrastructure didn't need modification.
|
|
41
|
-
- All three plan-enumerated cross-step invariants held green throughout: `resolveAgentConfig` disabled-config behavior, unknown-type fallback, and `getAllTypes` disabled-agent listing.
|
|
42
|
-
- Pre-completion reviewer: **PASS** — all deterministic checks, code design, test artifacts, and cross-step invariants clean.
|
|
43
|
-
|
|
44
|
-
## Stage: Land — worktree (2026-06-20T17:57:54Z)
|
|
45
|
-
|
|
46
|
-
### Session summary
|
|
47
|
-
|
|
48
|
-
Ran `/land-worktree 448` from the root checkout: fast-forward merged the peer branch `issue-448-enabled-false-does-not-prevent-explicitl` onto linear `main`, pushed, verified CI green, closed issue #448, merged the release-please PR, and tore down the worktree.
|
|
49
|
-
Released `pi-subagents-v17.0.1` (the plan marked `Release: ship independently`).
|
|
50
|
-
|
|
51
|
-
### Observations
|
|
52
|
-
|
|
53
|
-
#### What went well
|
|
54
|
-
|
|
55
|
-
- The new `/land-worktree` flow (added in `7cbfea46`) ran cleanly end-to-end on a real issue: ff-merge → push → CI → `issue_close` → release → teardown, with no blockers or rework.
|
|
56
|
-
- The release-please PR returned `MERGEABLE` / `UNSTABLE` with an empty `statusCheckRollup` — the documented `GITHUB_TOKEN` no-checks case.
|
|
57
|
-
Falling back from `release_pr_merge` to `gh pr merge 449 --rebase` followed by `git pull --ff-only` worked exactly as the prompt anticipates.
|
|
58
|
-
|
|
59
|
-
#### What caused friction (agent side)
|
|
60
|
-
|
|
61
|
-
- `instruction-violation` (self-identified, in retro) — the prompt's step 6.2 says to check the **full** release-PR body for which packages it bumps **before** merging.
|
|
62
|
-
I requested `body` in `gh pr view 449 --json body,...` but the `--jq` filter only printed `title`/`state`/`mergeStateStatus`/`statusCheckRollup`, so the body was never actually inspected.
|
|
63
|
-
I learned the bumped package (`pi-subagents`) only **after** merging, from the `git pull` output.
|
|
64
|
-
Impact: none this time (a single expected package bumped), but skipping the pre-merge body check means an unexpected sibling-package bump would slip through unnoticed.
|
|
65
|
-
|
|
66
|
-
### Diagnostic details
|
|
67
|
-
|
|
68
|
-
- **Model-performance correlation** — no subagents dispatched; the land flow ran entirely on the parent session model.
|
|
69
|
-
No mismatch.
|
|
70
|
-
- **Escalation-delay tracking** — no rabbit-holes; no error retried more than once.
|
|
71
|
-
- **Feedback-loop gap analysis** — no code changes in the land session, so CI (run on the pushed SHA, conclusion `success`) was the appropriate and only verification gate.
|
|
72
|
-
|
|
73
|
-
### Changes made
|
|
74
|
-
|
|
75
|
-
1. `.pi/prompts/land-worktree.md` — added a one-line nudge to step 6.2 to print the release-PR body explicitly with `gh pr view <N> --json body -q .body`, since a `--jq` that drops `body` skips the package-bump check silently.
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 462
|
|
3
|
-
issue_title: "pi-subagents: upgrade /subagent-sessions renderer to Pi per-entry TUI components"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #462 — pi-subagents: upgrade /subagent-sessions renderer to Pi per-entry TUI components
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-06-22T00:00:00Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Planned Phase 19 Step 4a: swap the `/subagent-sessions` renderer from `serializeConversation` plain text to Pi's per-entry TUI components behind the existing `TranscriptSource` seam.
|
|
13
|
-
Verified the SDK surface (per-entry components, `parseSkillBlock`, `getMarkdownTheme`, `ToolDefinition`, `AgentSession.getToolDefinition`) and mirrored Pi's own `renderSessionContext`/`rebuildChatFromMessages` mapping.
|
|
14
|
-
Wrote a four-step TDD plan at `packages/pi-subagents/docs/plans/0462-navigation-renderer-tui-components.md` and committed it.
|
|
15
|
-
|
|
16
|
-
### Observations
|
|
17
|
-
|
|
18
|
-
- Three design decisions were surfaced via `ask_user` and locked by the operator:
|
|
19
|
-
1. **Rebuild-on-change** (mirror Pi's `rebuildChatFromMessages`) over incremental `updateContent`/`updateResult` — the seam exposes only a full `getMessages()` snapshot plus a coarse `onChange`, so incremental would still diff snapshots while replicating Pi's `pendingTools` streaming state machine for marginal benefit.
|
|
20
|
-
2. **Keep the lightweight `◍ describeActivity` text indicator** — this absorbs the high-frequency streaming text, so the persisted component tree only changes at message granularity, which is what keeps rebuild-on-change cheap.
|
|
21
|
-
3. **Wire real tool definitions** — the operator flagged a dependency-inversion risk ("can't `SubagentManager` track this?").
|
|
22
|
-
Resolved dependency-safely: the SDK `AgentSession` already exposes `getToolDefinition(name)`, so a new read accessor on `SubagentSession`/`Subagent` (mirroring the existing `agentMessages` accessor) surfaces it through the record and onto the `TranscriptSource` seam — arrows stay inward, no `SubagentManager` bookkeeping.
|
|
23
|
-
- Key structural move: the component renderer must leave the pure `session-navigation.ts` (per-entry components need `TUI`/`cwd`/`markdownTheme`) and live in the SDK/TUI `session-navigator.ts`.
|
|
24
|
-
The pure module sheds `renderTranscriptLines`/`serializeConversation` entirely, becoming selection + sourcing only.
|
|
25
|
-
- The `renderTranscriptLines` removal, overlay rewrite, `session-navigation.ts` edits, `index.ts` `cwd` wiring, and test updates must land in **one commit** (TDD step 3) — removing the export breaks the overlay and its tests at the type level.
|
|
26
|
-
- Non-breaking internal renderer swap; `Release: independent` per the roadmap.
|
|
27
|
-
Step 4a gates Step 5 ([#442]) for rendering parity but is not part of any release batch.
|
|
28
|
-
- Follow-up [#463] (Step 4b, file-snapshot source) already exists and is open — referenced as a Non-Goal, nothing new to file.
|
|
29
|
-
- Parity is defined as *using Pi's own components*, not byte-equality with the bespoke viewer; `custom`-role messages are skipped (the bespoke viewer never rendered them either), noted as an Open Question.
|
|
30
|
-
|
|
31
|
-
## Stage: Implementation — TDD (2026-06-22T21:30:00Z)
|
|
32
|
-
|
|
33
|
-
### Session summary
|
|
34
|
-
|
|
35
|
-
Executed all four planned TDD steps: the `getToolDefinition` read accessor on `SubagentSession`/`Subagent`, the seam method on `TranscriptSource`/`NavigableSubagent`, the per-entry component renderer + overlay rewrite + `cwd` wiring, and the architecture doc flip (Step 4a `✅`).
|
|
36
|
-
The renderer now mounts Pi's interactive components into a cached `Container` rebuilt on source change, mirroring Pi's `renderSessionContext`.
|
|
37
|
-
Test count went from 1084 to 1088 (+4 net: +4 accessor/seam tests, +3 new navigator tests, −3 removed `renderTranscriptLines` tests), all green; one post-review `test:` commit pins invariant #423.
|
|
38
|
-
|
|
39
|
-
### Observations
|
|
40
|
-
|
|
41
|
-
- The production code (`session-navigation.ts`, `session-navigator.ts`, `index.ts`) type-checked clean on the first `tsc` run — the SDK message-union narrowing (`switch (message.role)`), component construction, and `updateResult(toolResultMessage)` all resolved without casts.
|
|
42
|
-
`SessionMessage` (= the SDK `AgentMessage` union) narrows by `role` even though `@earendil-works/pi-agent-core` is not a direct dependency.
|
|
43
|
-
- Two deviations from the plan's Module-Level Changes, both intentional: (1) `src/types.ts` was *not* changed — `ToolDefinition` is imported directly from `@earendil-works/pi-coding-agent` in each consumer rather than re-exported through the barrel (avoids a speculative re-export `fallow` would flag); (2) `test/helpers/mock-session.ts` gained a `getToolDefinition` stub (needed for the step-1 accessor tests, not listed in the plan).
|
|
44
|
-
- Pi's per-entry components read a *global* interactive theme initialized by `initTheme()`; Pi does this at startup, but tests had to call `initTheme(undefined, false)` in `beforeAll`.
|
|
45
|
-
An early probe with `AssistantMessageComponent` passed without it, but `UserMessageComponent`/`ToolExecutionComponent` throw `"Theme not initialized"` — so the global-theme dependency is component-specific and only surfaced once the broader role set was exercised.
|
|
46
|
-
- `setComplete`'s `TruncationResult` param requires more fields than `BashExecutionMessage` carries, so the bash component is completed with `undefined` truncation info (command + output still render).
|
|
47
|
-
Pi's own JS passes `{ truncated: true }` but that path is untyped.
|
|
48
|
-
- Pre-completion reviewer verdict: **WARN** (no failures; 3 non-blocking findings).
|
|
49
|
-
Reviewer warnings: (1) `package-pi-subagents/SKILL.md` UI module count is stale (10 listed vs 13 actual) — predates this issue, plan left it deliberately; (2) `addMessageComponents` mutates the received `pendingTools` accumulator (output-argument pattern) — intentional, mirrors Pi's own `renderedPendingTools` local and was plan-reviewed; (3) invariant #423 held and is type-enforced but lacked an explicit spy pin — **addressed** by the follow-up `test:` commit asserting the handler never calls `record.getToolDefinition` directly.
|
|
50
|
-
|
|
51
|
-
## Stage: Final Retrospective (2026-06-23T00:00:00Z)
|
|
52
|
-
|
|
53
|
-
### Session summary
|
|
54
|
-
|
|
55
|
-
Shipped Phase 19 Step 4a end-to-end across plan → TDD → ship: `/subagent-sessions` now renders through Pi's own per-entry interactive components behind the unchanged `TranscriptSource` seam, released as `pi-subagents` v17.4.0.
|
|
56
|
-
Execution was notably clean — six commits, no rework of production code, CI green on the first push, and the only two friction points (a missing `initTheme()` in tests, a wrong post-review assertion) were each self-caught and resolved in a single iteration.
|
|
57
|
-
|
|
58
|
-
### Observations
|
|
59
|
-
|
|
60
|
-
#### What went well
|
|
61
|
-
|
|
62
|
-
1. **Upfront SDK verification in planning paid off at implementation.**
|
|
63
|
-
Planning inspected the actual component constructors, the `renderSessionContext` mapping, and `AgentSession.getToolDefinition` in `node_modules/**/*.d.ts` before committing to a design.
|
|
64
|
-
Result: the production code (`session-navigation.ts`, `session-navigator.ts`, `index.ts`) type-checked clean on the *first* `tsc` run during TDD — the SDK message-union narrowing and component construction needed no casts.
|
|
65
|
-
2. **Probe-driven de-risking.**
|
|
66
|
-
Before the renderer rewrite, a throwaway `_probe-theme.test.ts` confirmed `getMarkdownTheme()` + a Pi component render works outside interactive mode — validating the riskiest assumption cheaply, then deleted.
|
|
67
|
-
3. **The operator's planning interjections were strategic, not mechanical.**
|
|
68
|
-
Rather than picking an `ask_user` option, the operator asked "what update frequency are we anticipating?"
|
|
69
|
-
and flagged a dependency-inversion risk on tool definitions.
|
|
70
|
-
Both redirects improved the design: the frequency analysis justified rebuild-on-change, and the inversion concern led to the dependency-safe `getToolDefinition` read accessor (discovered on the SDK, not invented).
|
|
71
|
-
4. **Incremental verification throughout.**
|
|
72
|
-
Targeted `vitest` per Red→Green step, `pnpm run check` immediately after each shared-interface change, then full suite + root lint + `fallow dead-code` before each commit — no end-of-session verification pile-up.
|
|
73
|
-
5. **Pre-completion review caught a real gap and the fix's own bug was caught by the loop.**
|
|
74
|
-
The reviewer flagged the missing #423 spy pin; while adding it, an over-assertion (`getToolDefinition` called on a no-toolCall fixture) failed the test run and was removed before committing.
|
|
75
|
-
|
|
76
|
-
#### What caused friction (agent side)
|
|
77
|
-
|
|
78
|
-
1. `missing-context` (self-identified) — the `initTheme()` requirement for Pi's interactive components.
|
|
79
|
-
The de-risking probe exercised only `AssistantMessageComponent`, which happens *not* to read the global theme, so the probe passed and gave false confidence.
|
|
80
|
-
The real tests then threw `"Theme not initialized"` from `UserMessageComponent`/`ToolExecutionComponent`.
|
|
81
|
-
Impact: one extra Red cycle (4 failing tests) → added `beforeAll(() => initTheme(undefined, false))`; no production rework.
|
|
82
|
-
2. `other` (self-identified) — a wrong second assertion in the post-review #423 pin (`expect(record.getToolDefinition).toHaveBeenCalled()` on a fixture whose assistant message had no `toolCall`, so the lookup never fires).
|
|
83
|
-
Impact: one failed test run, immediately diagnosed and the bad assertion removed; ~1 iteration.
|
|
84
|
-
|
|
85
|
-
#### What caused friction (user side)
|
|
86
|
-
|
|
87
|
-
- None.
|
|
88
|
-
The operator's interventions were timely and strategic (see What went well #3); no context was withheld and no correction was reactive.
|
|
89
|
-
|
|
90
|
-
### Diagnostic details
|
|
91
|
-
|
|
92
|
-
- **Feedback-loop gap analysis** — no gap.
|
|
93
|
-
Verification ran incrementally: per-step targeted `vitest`, `pnpm run check` after each interface change, full suite + lint + `fallow` before commits.
|
|
94
|
-
Both friction points were caught by running tests *before* committing, not after.
|
|
95
|
-
- **Escalation-delay tracking** — no rabbit holes; each friction point resolved in a single iteration (well under the 5-tool-call threshold).
|
|
96
|
-
- **Probe-coverage note** — the `initTheme()` miss is a probe *coverage* gap, not a tool-availability gap: a one-variant probe (`AssistantMessageComponent`) did not validate the environment dependency of the broader component set actually used.
|
|
97
|
-
- **Model-performance / unused-tool** — nothing notable.
|
|
98
|
-
The only subagent dispatch (`pre-completion-reviewer`) is purpose-built for judgment-heavy review; SDK inspection used direct `grep`/`bash` over `.d.ts` files, which was appropriate.
|
|
99
|
-
|
|
100
|
-
### Changes made
|
|
101
|
-
|
|
102
|
-
1. `.pi/skills/package-pi-subagents/SKILL.md` — added a `## Testing` note: tests mounting Pi's per-entry interactive components must call `initTheme(undefined, false)` in `beforeAll`, with the component-specific / false-confidence caveat.
|
|
103
|
-
2. `.pi/skills/package-pi-subagents/SKILL.md` — corrected the stale UI domain module count (10 → 13) and extended its responsibility blurb to include session navigation.
|
|
104
|
-
3. `.pi/skills/testing/SKILL.md` — extended the existing "Exploration before planning" disposable-probe bullet to require exercising the full input variety (variant-specific environment dependencies defeat a one-representative probe).
|
|
105
|
-
Placement confirmed with the operator: kept in the `testing` skill (loaded by both `/plan-issue` and `/tdd-plan`) next to the sibling rule, rather than duplicated into the plan prompt.
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 463
|
|
3
|
-
issue_title: "pi-subagents: add file-snapshot source to /subagent-sessions for evicted agents"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #463 — pi-subagents: add file-snapshot source to /subagent-sessions for evicted agents
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-06-23T00:00:00Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Produced a 4-step plan for the Phase 19 Step 4b file-snapshot source: implement `fileSnapshotSource(outputFile, readFile)` in the pure `session-navigation.ts`, broaden the `/subagent-sessions` candidate set to evicted agents, and dual-source the handler by `NavigationEntry.kind`.
|
|
13
|
-
The central design fork — how evicted agents enter the picker — was resolved with the operator via `ask_user`.
|
|
14
|
-
|
|
15
|
-
### Observations
|
|
16
|
-
|
|
17
|
-
- **Eviction is memory management.**
|
|
18
|
-
The cleanup sweep's `disposeSession()` frees the in-memory message history; the transcript survives only on disk.
|
|
19
|
-
So rendering an evicted agent *always* reads the file (`fileSnapshotSource`) regardless of candidate-set strategy — the strategy only affects the picker *label*.
|
|
20
|
-
- **Persisted child sessions carry no `type`/`description`.**
|
|
21
|
-
The JSONL has only the conversation plus a header (`id`, `timestamp`, `cwd`, `parentSession`).
|
|
22
|
-
A directory scan (the issue's literal wording) would therefore produce degraded labels and parse every file per open.
|
|
23
|
-
- **Decision: manager-retained descriptors over directory scan.**
|
|
24
|
-
The manager stashes a tiny no-messages `EvictedSubagent` descriptor in `cleanup()` before `removeRecord`, cleared in `clearCompleted()`/`dispose()`.
|
|
25
|
-
Rich labels identical to live entries, bounded memory, no per-open parse.
|
|
26
|
-
Coverage is limited to in-session evictions — which are the sweep's only targets, since a fresh manager per session never reloads prior-process subagents.
|
|
27
|
-
Operator confirmed; an `(evicted)` snapshot marker was also chosen for the label.
|
|
28
|
-
- **`NavigationEntry` becomes a discriminated union** (`live` | `evicted`); this breaks the handler, the `index.ts` call site, and both UI test files, so step 3 folds all of them into one commit.
|
|
29
|
-
- **SDK-runtime call kept direct.** `fileSnapshotSource` calls `parseSessionEntries` / `buildSessionContext` directly rather than injecting them — the injected `readFile` already provides the unit-test seam, and there is no `no-restricted-imports` rule.
|
|
30
|
-
- **Transient dead-code risk noted:** `fileSnapshotSource` and `listEvicted()` have no caller until step 3; flagged not to ship before step 3 lands (CI/`fallow` gate the pushed tip).
|
|
31
|
-
- Release: independent (Phase 19 Step 4b roadmap tag).
|
|
32
|
-
|
|
33
|
-
## Stage: Implementation — TDD (2026-06-23T13:00:00Z)
|
|
34
|
-
|
|
35
|
-
### Session summary
|
|
36
|
-
|
|
37
|
-
Executed all 4 plan steps in order: (1) `fileSnapshotSource` in the pure `session-navigation.ts`, (2) manager-retained `EvictedSubagent` descriptors (`cleanup` capture, `listEvicted`, `clearCompleted`/`dispose` clear), (3) the breaking `NavigationEntry` discriminated union + handler dual-source + `index.ts` wiring + all test updates in one commit, (4) architecture/ADR doc updates.
|
|
38
|
-
Test count went from 1088 to 1099 (+11); full suite, `check`, root `lint`, and `fallow dead-code` all green.
|
|
39
|
-
|
|
40
|
-
### Observations
|
|
41
|
-
|
|
42
|
-
- **No deviations from the plan.**
|
|
43
|
-
All steps landed as written; Module-Level Changes matched the touched files exactly.
|
|
44
|
-
- **Exploratory probe paid off.**
|
|
45
|
-
A disposable script confirmed `buildSessionContext` auto-detects the leaf with no `leafId`, the `type !== "session"` filter drops the header, and empty entries yield `[]` — validating the `fileSnapshotSource` shape before writing the test.
|
|
46
|
-
- **Two ESLint auto-fixes during commit hooks:** a stray `!` non-null assertion in the manager test (step 2) and four `entry?.kind` optional chains on a non-nullish destructured `entry` (`@typescript-eslint/no-unnecessary-condition`, step 3).
|
|
47
|
-
Both fixed and re-committed; `check` + tests confirmed green after.
|
|
48
|
-
- **Transient dead code** between steps 1–2 and 3 (predicted in the plan) cleared at the step-3 tip; final `fallow dead-code` is clean.
|
|
49
|
-
- **Pre-completion reviewer: PASS** — deterministic checks, code design, test artifacts, Mermaid render, and all three cross-step invariants (no inbound core call, read-only overlay, renderer parity) verified; no follow-ups deferred.
|
|
50
|
-
|
|
51
|
-
## Stage: Final Retrospective (2026-06-23T17:43:05Z)
|
|
52
|
-
|
|
53
|
-
### Session summary
|
|
54
|
-
|
|
55
|
-
Single continuous session carried #463 from planning through ship: a 4-step plan, TDD implementation (+11 tests, 1088→1099), pre-completion PASS, and release of `pi-subagents` v17.5.0.
|
|
56
|
-
The defining moment was planning: an `ask_user` design gate plus operator Socratic pushback diverged the candidate-set design from the issue's literal "directory scan" wording to manager-retained descriptors.
|
|
57
|
-
Execution was notably clean — no rework, no plan deviations, two auto-fixed lint nits.
|
|
58
|
-
|
|
59
|
-
### Observations
|
|
60
|
-
|
|
61
|
-
#### What went well
|
|
62
|
-
|
|
63
|
-
- **The `ask_user` gate caught a real design fork the issue body got wrong.**
|
|
64
|
-
The issue's "Proposed change" said "enumerate persisted child-session JSONL files" (a directory scan).
|
|
65
|
-
Exploration revealed the persisted session carries no subagent `type`/`description`, so a scan yields degraded labels.
|
|
66
|
-
The gate surfaced descriptors-vs-scan-vs-hybrid; the operator's "why are we evicting at all?"
|
|
67
|
-
and "tell me more about how the labels degrade" drove a better-grounded decision (descriptors).
|
|
68
|
-
This is the `/plan-issue` "treat Proposed change as a hypothesis" contract working as intended — novel because the divergence was the *enumeration mechanism*, not a surface ambiguity.
|
|
69
|
-
- **Exploratory probe before the first TDD test.**
|
|
70
|
-
A disposable script (`explore-session.mjs`, deleted after) confirmed `buildSessionContext` auto-detects the leaf with no `leafId` and the `type !== "session"` filter drops the header — validating the `fileSnapshotSource` shape before any test was written (the `testing` skill's "inspect the actual runtime shape first" rule).
|
|
71
|
-
- **The plan predicted transient dead code and sequenced to clear it.**
|
|
72
|
-
`fileSnapshotSource` and `listEvicted()` had no caller until step 3; the plan flagged this and ordered the integration step to close it, so the final `fallow dead-code` gate passed with no surprise suppressions.
|
|
73
|
-
- **Pre-completion reviewer ran on `claude-sonnet-4-6`** — model appropriate for the judgment-heavy invariant/design checklist; returned PASS.
|
|
74
|
-
|
|
75
|
-
#### What caused friction (agent side)
|
|
76
|
-
|
|
77
|
-
- `other` — the first `ask_user` led with the enumeration mechanism (descriptors/scan/hybrid) before establishing *why eviction creates the problem*.
|
|
78
|
-
The operator's first reply was "Why are we 'evicting' subagents in the first place?", i.e. asking for the framing I already held but had not front-loaded.
|
|
79
|
-
Impact: two extra `ask_user` round-trips before the decision — but they produced a better-understood outcome, so net-positive; no rework.
|
|
80
|
-
- `other` (lint nit) — four `entry?.kind` optional chains on a destructured array element tripped `@typescript-eslint/no-unnecessary-condition`, and a stray `!` tripped `no-unnecessary-type-assertion`; both surfaced via the pre-commit hook.
|
|
81
|
-
Impact: two re-commits during steps 2–3, auto-fixed, zero rework.
|
|
82
|
-
|
|
83
|
-
#### What caused friction (user side)
|
|
84
|
-
|
|
85
|
-
- None.
|
|
86
|
-
The operator's Socratic questions mid-`ask_user` were the session's highest-value input — they converted a plausible-but-degraded design (scan) into the right one (descriptors).
|
|
87
|
-
If anything, this is a model for how the gate should be used.
|
|
88
|
-
|
|
89
|
-
### Diagnostic details
|
|
90
|
-
|
|
91
|
-
- **Model-performance correlation** — the `pre-completion-reviewer` subagent ran on `anthropic/claude-sonnet-4-6` (judgment-heavy review): appropriate, no mismatch.
|
|
92
|
-
Main-thread `model_change` events included a `deepseek-v4-flash` variant; no quality degradation was observed in any artifact (plan, code, tests all clean), so no actionable correlation.
|
|
93
|
-
- **Escalation-delay tracking** — no `rabbit-hole` points; longest same-error streak was the two lint auto-fixes, each resolved in one re-commit.
|
|
94
|
-
- **Unused-tool detection** — exploration used `colgrep`, `grep`, and a disposable runtime probe; no missed-tool opportunities.
|
|
95
|
-
- **Feedback-loop gap analysis** — verification ran incrementally: `pnpm run check` after the shared-interface steps (2 and 3), per-file `vitest` on each red/green cycle, and the full suite + lint + `fallow` before the docs commit.
|
|
96
|
-
No end-only verification.
|
|
97
|
-
|
|
98
|
-
### Changes made
|
|
99
|
-
|
|
100
|
-
1. Appended this Final Retrospective stage entry to `packages/pi-subagents/docs/retro/0463-file-snapshot-source-evicted-agents.md`.
|
|
101
|
-
|
|
102
|
-
No `AGENTS.md` or prompt changes — the session's friction was net-positive (the `ask_user` round-trips) or auto-fixed with zero rework (the lint nits).
|
|
103
|
-
Two candidate changes were considered and rejected as noise (a `code-design` note on `entry?.kind` optional chaining; an `ask-user` "why-before-mechanism" guidance already covered by the skill).
|