@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,97 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 265
|
|
3
|
-
issue_title: "Born-complete child execution; dissolve the runner"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #265 — Born-complete child execution; dissolve the runner
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-05-30T02:30:00Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Produced the implementation plan for dissolving the `agent-runner` and introducing a born-complete `SubagentSession`.
|
|
13
|
-
Most of the session was a design dialogue that resolved naming, the turn-loop home, a discovered Law-of-Demeter cluster, and the workspace-ownership fork before any plan text was written.
|
|
14
|
-
Plan committed as `0265-born-complete-subagent-session.md`; a side-quest filed #277 and added an architecture-doc breadcrumb for discovered debt.
|
|
15
|
-
|
|
16
|
-
### Observations
|
|
17
|
-
|
|
18
|
-
- Vocabulary was pinned down explicitly because "execution" is overloaded: granular execution = one turn loop (one `session.prompt()`, run or resume); the born-complete object spans the whole session lifetime (run + resumes).
|
|
19
|
-
The object is named `SubagentSession` (matches the existing `SubagentType` / `SubagentSessionDir` / `SubagentSessionRegistry` family; cohesive with the deferred `Agent` → `Subagent` rename).
|
|
20
|
-
Turn driving is `runTurnLoop` / `resumeTurnLoop`; resume is *not* an SDK `session.resume()` — it is `session.prompt()` again on the retained session.
|
|
21
|
-
- The turn-loop home is **on `SubagentSession`** (methods), not inline on `Agent` and not a free function.
|
|
22
|
-
The user caught that `subagent.driveTurnLoop(subagentSession.session, …)` is a Law-of-Demeter reach-through; putting the behavior on the object that owns the `AgentSession` is both LoD-correct and more testable (satisfying the user's conditional "inline only if straightforward to test").
|
|
23
|
-
- Workspace ownership locked to **Option A** (session-only `SubagentSession`; `Agent` keeps workspace prepare/dispose).
|
|
24
|
-
Decisive reasoning: the workspace and the session have genuinely different lifetimes (workspace dies at run-completion to fold its `resultAddendum` into the result; session survives to cleanup for resume + the new registry boundary), so they are different resources.
|
|
25
|
-
Option B would fuse them into one object needing two teardown methods, and would thread the `WorkspaceProvider` + prepare-context through the factory just to call `prepare()` — a parameter-relay smell the user flagged.
|
|
26
|
-
The factory takes a resolved `cwd` value (used directly), never the provider.
|
|
27
|
-
- Worktrees are already out of the core (#263) — confirmed zero git code in `pi-subagents/src/` (only doc comments).
|
|
28
|
-
The A/B fork is purely about how the core sequences its abstract `WorkspaceProvider` seam; `@gotgenes/pi-subagents-worktrees` is untouched.
|
|
29
|
-
- Registry semantics: moving `disposed` from run-completion to true session disposal makes resume executions registry-detected (closes the gap deferred from #261).
|
|
30
|
-
The permission system's subscription code does not change; only *when* `disposed` fires moves.
|
|
31
|
-
Edge case planned: `createSubagentSession` must dispose on a post-`session-created` failure to avoid a registry leak.
|
|
32
|
-
- Discovered debt captured (the user's "it is in doing the work that we discover the work to be done"): filed #277 for the remaining `agent.session` reach-throughs (steer buffer-or-deliver duplicated across `steer-tool` + `service-adapter`, conversation viewing, resume-readiness guards) and added a "Session encapsulation debt (Law of Demeter)" subsection to `architecture.md` (commit `038a1283`).
|
|
33
|
-
`SubagentSession` exposes a `.session` accessor in #265 so observer wiring + consumers keep working; #277 retires those.
|
|
34
|
-
- Two follow-ups deliberately deferred and noted in the plan's Non-Goals / Open Questions: the `Agent` → `Subagent` class rename (mechanical, ~19 files — separate issue) and resume-aware workspaces (a worktree's lifetime is one turn loop; worktree + resume is degenerate today).
|
|
35
|
-
- The change is non-breaking (no `feat!:`): the dissolved types (`RunOptions`, `RunResult`, `AgentRunner`) are internal, so `public.d.ts` is unaffected.
|
|
36
|
-
TDD order uses lift-and-shift across 7 steps to keep each commit compiling; transient duplication of the turn-loop helpers/assembly exists between steps 3–5 and is deleted in step 6.
|
|
37
|
-
|
|
38
|
-
## Stage: Implementation — TDD (2026-05-29T22:18:00Z)
|
|
39
|
-
|
|
40
|
-
### Session summary
|
|
41
|
-
|
|
42
|
-
Executed all 7 TDD steps from the plan via lift-and-shift, one commit per step, each leaving the suite green.
|
|
43
|
-
Introduced `SubagentSession` (`runTurnLoop`/`resumeTurnLoop`/`steer`/`dispose`) and the `createSubagentSession()` assembly factory, swapped `Agent`/`AgentManager`/`index.ts` onto them, then deleted `agent-runner.ts` + `execution-state.ts` and the three runner test files.
|
|
44
|
-
Package test count went 951 → 960 (net +9: new `subagent-session`/`create-subagent-session`/`turn-limits` suites added, the redundant runner suites deleted).
|
|
45
|
-
Pre-completion reviewer: initial FAIL (MD060 table alignment in SKILL.md, auto-fixed by `rumdl fmt`), PASS on re-check after fix + stale doc cleanup.
|
|
46
|
-
|
|
47
|
-
### Observations
|
|
48
|
-
|
|
49
|
-
- The plan sketch's `TurnLoopOptions` listed only `maxTurns`/`graceTurns`/`signal`, but preserving the old `runAgent` precedence `per-call ?? agentMaxTurns ?? defaultMaxTurns` required threading `defaultMaxTurns` through `TurnLoopOptions` and storing `agentMaxTurns` + `parentContext` in `SubagentSession` meta (both are session-level facts known at creation).
|
|
50
|
-
This is a correctness-preserving deviation, well covered by three precedence tests plus a parent-context-prepend test in `subagent-session.test.ts`.
|
|
51
|
-
- The atomic call-site swap (step 5) touched more test files than the plan's step-5 list anticipated: every tool/service test that set `record.execution = { session, outputFile }` (`steer-tool`, `agent-tool`, `background-spawner`, `foreground-runner`, `get-result-tool`, `service-adapter`) had to migrate to `record.subagentSession = toSubagentSession(createSubagentSessionStub(...))`.
|
|
52
|
-
Added `createSubagentSessionStub`/`toSubagentSession` to `mock-session.ts` so the migration was a one-line change per call site; the stub's `steer`/`dispose` delegate to the underlying `MockSession` so existing session-spy assertions kept working unchanged.
|
|
53
|
-
- `disposed` moved from `runAgent`'s `finally` (run-completion) to `SubagentSession.dispose()`, invoked by `AgentManager` via the new `Agent.disposeSession()` (routing both `record.session?.dispose?.()` call sites at `agent-manager.ts:235,309`).
|
|
54
|
-
The full cross-package suite confirms the permission system (1504 tests) is unaffected — its subscription code did not change, only *when* `disposed` fires.
|
|
55
|
-
- Test-helper gotcha: `makeSubagentSession`'s `outputFile` default initially swallowed an explicit `undefined` via `?? default`; fixed with an `"outputFile" in metaOverrides` presence check (the testing-skill "Partial spread erases explicit undefined" family).
|
|
56
|
-
- `print-mode.test.ts` now mocks `#src/lifecycle/create-subagent-session` (was `#src/lifecycle/agent-runner`); `index.ts` wraps the factory as `(params) => createSubagentSession(params, deps)`, so the module mock still intercepts it.
|
|
57
|
-
- fallow stayed clean throughout — the transient duplication of IO interfaces + turn-loop helpers between `agent-runner.ts` and the new modules (steps 3–5) was removed in step 6 before the pre-completion gate ran.
|
|
58
|
-
- Reviewer's two minor non-blocking notes: SKILL.md Session-domain count now lists `conversation.ts` but still omits the pre-existing `content-items.ts` (drift predates this issue); `create-subagent-session.ts` keeps an accurate "old runner's runAgent()" provenance comment.
|
|
59
|
-
|
|
60
|
-
## Stage: Final Retrospective (2026-05-30T13:37:00Z)
|
|
61
|
-
|
|
62
|
-
### Session summary
|
|
63
|
-
|
|
64
|
-
Shipped issue #265 (`pi-subagents-v13.1.0`) and ran the retrospective across all three stages (planning, TDD implementation, ship).
|
|
65
|
-
The implementation landed cleanly in 7 TDD commits + 1 docs commit; test count 951 → 960.
|
|
66
|
-
|
|
67
|
-
### Observations
|
|
68
|
-
|
|
69
|
-
#### What went well
|
|
70
|
-
|
|
71
|
-
- The lift-and-shift strategy (new modules alongside old, swap consumers, delete old) kept every intermediate commit compiling and the suite green — zero broken-baseline moments across 7 steps.
|
|
72
|
-
- The `createSubagentSessionStub` pattern (steer/dispose delegate to the wrapped `MockSession`) let 6 tool/service test files migrate with a one-line change each, preserving all existing session-spy assertions.
|
|
73
|
-
- Verification ran incrementally: `pnpm vitest run <file>` after every Red/Green, `pnpm run check` after every interface change, and `pnpm -r run test` (full cross-package) after step 6's deletion to confirm the permission system (1504 tests) was unaffected.
|
|
74
|
-
|
|
75
|
-
#### What caused friction (agent side)
|
|
76
|
-
|
|
77
|
-
1. `missing-context` — The plan's step-5 file list omitted 6 tool/service test files (`steer-tool`, `agent-tool`, `background-spawner`, `foreground-runner`, `get-result-tool`, `service-adapter`) that directly set `record.execution = { session, outputFile }`.
|
|
78
|
-
The existing planning rule ("grep all test files for every removed symbol") was present but was not applied to the renamed `.execution` property — only to removed type imports.
|
|
79
|
-
Impact: step 5 took ~2× expected time; each file was discovered reactively via `tsc --noEmit` errors.
|
|
80
|
-
2. `rabbit-hole` — Step 6's `sed` invocation for import-path renames failed silently on macOS BSD `sed` because the `#` delimiter clashed with `#test/helpers/...` paths. 3 consecutive tool calls were spent diagnosing and retrying before switching to per-file `sed` with `@` delimiters.
|
|
81
|
-
Impact: added ~3 minutes of friction; the `edit` tool would have been safer for targeted, known-file replacements.
|
|
82
|
-
3. `other` (autoformat race) — The `pi-autoformat` extension ran concurrently with `git commit` twice during the docs phase, causing `.git/index.lock` conflicts.
|
|
83
|
-
Recovery was mechanical (remove lock, retry) but required user intervention once.
|
|
84
|
-
Impact: one user prompt to retry; no rework.
|
|
85
|
-
4. `other` (markdown table alignment) — Replacing short table cells with long module lists in SKILL.md broke MD060's compact-table rule.
|
|
86
|
-
The pre-completion reviewer caught it (initial FAIL); `rumdl fmt` auto-fixed it.
|
|
87
|
-
Impact: one amend + re-lint cycle; self-identified after reviewer report.
|
|
88
|
-
|
|
89
|
-
#### What caused friction (user side)
|
|
90
|
-
|
|
91
|
-
- No user-side friction observed.
|
|
92
|
-
The user's only intervention was a retry prompt after the autoformat/git-lock race — a timing issue, not a judgment or context gap.
|
|
93
|
-
|
|
94
|
-
### Changes made
|
|
95
|
-
|
|
96
|
-
1. `.pi/skills/testing/SKILL.md` — added rule about `??` swallowing explicit `undefined` in factory overrides (under "Vitest mock patterns").
|
|
97
|
-
2. `packages/pi-subagents/docs/retro/0265-born-complete-subagent-session.md` — appended Final Retrospective stage entry.
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 270
|
|
3
|
-
issue_title: "Make @gotgenes/pi-subagents type-consumable by sibling workspace packages"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #270 — Make @gotgenes/pi-subagents type-consumable by sibling workspace packages
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-05-29T00:00:00Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Diagnosed the consumability failure empirically with `tsc --traceResolution` and planned a `.d.ts`-emit fix.
|
|
13
|
-
The plan adds a `rollup-plugin-dts` build that bundles `src/service/service.ts` into a self-contained `dist/public.d.ts`, wires conditional `exports` (`types` → the bundle, `default` → the real source), generates the artifact at `prepack` time, ships it via a `files` allowlist, and proves external consumability with a `pnpm pack` → throwaway-consumer → `tsc` harness.
|
|
14
|
-
|
|
15
|
-
### Observations
|
|
16
|
-
|
|
17
|
-
- Root cause is two compounding failures: the stale `exports["."]` path (`./src/service.ts` does not exist) and, once fixed, an unresolvable `#src/*` cascade.
|
|
18
|
-
The trace showed the consumer's own `paths` (`#src/*` → `./src/*`) intercept first (both packages define `#src/*`), and the publisher's `imports`-field fallback cannot resolve the extensionless `.ts` target.
|
|
19
|
-
- The public type closure is entangled: `WorkspaceProvider` → `AgentStatus` (in the 510-LOC `agent.ts`) → `types.ts` (which re-exports the `Agent` class).
|
|
20
|
-
This made the alias-free-entry alternative (Option 2) a substantial source restructure, so it was rejected.
|
|
21
|
-
- Decisions taken via `ask_user`:
|
|
22
|
-
1. Approach — emit a bundled `.d.ts` (the repo's first build step), over alias-free restructure or type re-declaration.
|
|
23
|
-
2. Bundler — `rollup-plugin-dts` (purpose-built for flattening declarations; no JS bundle, which suits ship-source), over `tsdown`/`api-extractor`.
|
|
24
|
-
3. Artifact — not committed; generated at `prepack` and shipped in the tarball, consumed via the package interface.
|
|
25
|
-
4. Scope — tight: packaging + a `pnpm pack`-based verification harness in #270; defer the `pi-subagents-worktrees` registry-consumption flip (drop `workspace:*`, `link-workspace-packages: false`, wire the real import) to #263.
|
|
26
|
-
- Scope was deliberately narrowed after a chicken-and-egg surfaced: the registry version carrying the fix does not exist until #270 publishes, so the meaningful consumer flip belongs to #263.
|
|
27
|
-
- Sequencing constraint for #263 (captured in the plan): publish #270 first — merge its release-please PR so `pi-subagents` publishes — *before* resuming #263, otherwise #263's `pi-subagents` core edits batch into the same release.
|
|
28
|
-
The current `#263` scaffold commits on `main` touch only the unregistered `pi-subagents-worktrees` component, so they do not batch into `pi-subagents` and #270 ships cleanly.
|
|
29
|
-
- Primary feasibility risk flagged: whether `rollup-plugin-dts` resolves `#src/*` while rolling up the type graph.
|
|
30
|
-
Build Step 1 is the explicit checkpoint (emit + assert the output is alias-free and exports the expected symbols).
|
|
31
|
-
- `dist/` is gitignored and already excluded by eslint/biome; the new wrinkle is that a `files` allowlist is required so the gitignored `dist/public.d.ts` is included in the npm tarball — validate `pnpm pack --dry-run` parity so no currently-shipped file is dropped.
|
|
32
|
-
|
|
33
|
-
## Stage: Implementation — Build (2026-05-29T00:00:00Z)
|
|
34
|
-
|
|
35
|
-
### Session summary
|
|
36
|
-
|
|
37
|
-
Executed all four build-order steps: added `rollup` + `rollup-plugin-dts` and a `build:types` script that bundles `src/service/service.ts` into a self-contained `dist/public.d.ts`; wired conditional `exports` (`types` + `default`, fixing the stale path) with a `prepack` hook and a `files` allowlist; added a `pnpm pack` → throwaway-consumer → `tsc` verification harness (`scripts/verify-public-types.sh`) plus a CI step; and recorded [ADR-0003].
|
|
38
|
-
A fifth commit documented the new build step in the `package-pi-subagents` skill (reviewer WARN).
|
|
39
|
-
Root `pnpm run check`, root `pnpm run lint`, and `verify:public-types` all pass.
|
|
40
|
-
|
|
41
|
-
### Observations
|
|
42
|
-
|
|
43
|
-
- The primary feasibility risk (`rollup-plugin-dts` resolving `#src/*`) resolved cleanly out of the box: driving it with the package `tsconfig` (which carries the `#src/*` paths) produced a 178-line `dist/public.d.ts` with zero `#src/` residue and only `ThinkingLevel` kept external from `@earendil-works/pi-ai`.
|
|
44
|
-
No alias/path resolver plugin was needed.
|
|
45
|
-
- Harness deviation (fixed in the same step): `pnpm add` in the isolated (`--ignore-workspace`) throwaway consumer exited non-zero with `ERR_PNPM_IGNORED_BUILDS` because it does not inherit the workspace `allowBuilds` approvals (`@google/genai`, `protobufjs`).
|
|
46
|
-
Fixed by adding `--ignore-scripts` — a type-check needs no dependency build scripts.
|
|
47
|
-
Worth remembering for any future packaged-consumer harness.
|
|
48
|
-
- A subtle gotcha while debugging: `pnpm ... | tail; echo $?` reports `tail`'s exit, not pnpm's, which masked the real failure.
|
|
49
|
-
Use `set -o pipefail` or check the command directly.
|
|
50
|
-
- `files` allowlist parity was validated with a before/after `pnpm pack --dry-run` diff: nothing dropped, only `dist/public.d.ts` added.
|
|
51
|
-
The allowlist reproduces the current contents (`src`, `docs`, `vitest.config.ts`, `AGENTS.md`, `CHANGELOG.md`, `.prettierignore`) plus `dist`.
|
|
52
|
-
Did not take the opportunity to slim the tarball (docs/test-config still ship) — that would be a separate deliberate change.
|
|
53
|
-
- Runtime `default` → `./src/service/service.ts` is safe because that module's only internal imports are `import type`, which erase; no runtime `#src/*` resolution occurs.
|
|
54
|
-
- No `src/`/`test/` `.ts` files were touched, so the vitest suite and `tsc` were unaffected (confirmed via root check).
|
|
55
|
-
- Pre-completion reviewer: WARN — no findings attributable to this session.
|
|
56
|
-
Reviewer warnings: (1) the `package-pi-subagents` skill lacked a build-step note — addressed in commit `2ff5a375`; (2) `pnpm fallow dead-code` exits non-zero on a pre-existing finding in `packages/pi-subagents-worktrees/package.json` from the #263 scaffold (commit `9a7dcfc5`), out of scope for #270 and left for #263.
|
|
57
|
-
|
|
58
|
-
## Stage: Final Retrospective (2026-05-29T21:00:00Z)
|
|
59
|
-
|
|
60
|
-
### Session summary
|
|
61
|
-
|
|
62
|
-
Shipped #270 end-to-end across planning, build, and ship stages: diagnosed the cross-package type-resolution failure empirically, built a `rollup-plugin-dts` declaration bundle plus a pack-based verification harness, and published `@gotgenes/pi-subagents@11.6.0` (tag `pi-subagents-v11.6.0`).
|
|
63
|
-
Two CI failures during the ship stage — a pre-existing `pnpm fallow dead-code` gate and lockfile drift — required two extra fix commits before CI went green.
|
|
64
|
-
|
|
65
|
-
### Observations
|
|
66
|
-
|
|
67
|
-
#### What went well
|
|
68
|
-
|
|
69
|
-
- Empirical-first diagnosis: `tsc --traceResolution` in planning pinned the exact two-part failure (consumer `paths` collision + the publisher's `imports`-field extensionless-`.ts` miss) and directly justified the chosen `.d.ts`-emit approach over the alias-free restructure.
|
|
70
|
-
- The flagged primary risk evaporated: `rollup-plugin-dts` resolved `#src/*` out of the box via the package `tsconfig` paths, producing a clean 178-line `dist/public.d.ts` with no resolver plugin.
|
|
71
|
-
- Novel, reusable pattern: `scripts/verify-public-types.sh` proves a ship-source package is externally type-consumable via `pnpm pack` → throwaway-consumer → `tsc`, with no publish round-trip.
|
|
72
|
-
Worth promoting if other packages grow public surfaces.
|
|
73
|
-
- Disciplined `ask_user` use on the genuinely ambiguous decisions (approach, bundler, artifact handling, scope), with strong user steering — the `tsup`-is-unmaintained redirect to `rollup-plugin-dts`, the "no workspace trickery / use released versions" directive, and the #263 chicken-and-egg catch that correctly narrowed scope.
|
|
74
|
-
|
|
75
|
-
#### What caused friction (agent side)
|
|
76
|
-
|
|
77
|
-
- `missing-context` — Pushed to `main` with a pre-existing `pnpm fallow dead-code` failure (unused `@earendil-works/pi-coding-agent` devDependency in `packages/pi-subagents-worktrees/package.json`, from the #263 scaffold).
|
|
78
|
-
The pre-completion reviewer reported it as `FAIL` but labelled it out-of-scope, and I accepted that framing and pushed.
|
|
79
|
-
The CI `Fallow dead-code gate` runs `if: github.ref == 'refs/heads/main'` — a hard gate that fires on every `main` push regardless of who introduced the failure — so CI failed (run `26659647270`).
|
|
80
|
-
Impact: 2 fix commits (`7e7afadd`, `10e74f2f`) and 2 extra CI cycles (~10 min).
|
|
81
|
-
The ship pre-push step runs only `pnpm run lint`, never `pnpm fallow dead-code`.
|
|
82
|
-
- `missing-context` — Removed the devDependency and committed/pushed `package.json` (`7e7afadd`) without the updated `pnpm-lock.yaml`.
|
|
83
|
-
CI's `pnpm install --frozen-lockfile` failed with `ERR_PNPM_OUTDATED_LOCKFILE` (run `26659851716`).
|
|
84
|
-
Impact: 1 extra commit (`10e74f2f`) and 1 extra CI cycle.
|
|
85
|
-
Self-identified from the CI log.
|
|
86
|
-
- `rabbit-hole` (minor) — While debugging the harness's `ERR_PNPM_IGNORED_BUILDS`, the `pnpm ... | tail; echo $?` idiom reported `tail`'s exit code, masking pnpm's real failure; took ~4 tool calls before tracing with `bash -x`.
|
|
87
|
-
Impact: added friction, no rework.
|
|
88
|
-
|
|
89
|
-
#### What caused friction (user side)
|
|
90
|
-
|
|
91
|
-
- The "pi-subagents-* extensions should use the released, npm-installed version, no workspace trickery" directive arrived mid-planning, after initial exploration.
|
|
92
|
-
Surfacing the consumption-model constraint at kickoff would have framed the scope question earlier.
|
|
93
|
-
Opportunity, not criticism — the same exchange produced the high-value chicken-and-egg catch (the registry version with the fix cannot exist until #270 publishes) that correctly deferred the worktrees flip to #263.
|
|
94
|
-
- A brief "there is no [ADR-0003]" → "My mistake" exchange; no rework.
|
|
95
|
-
|
|
96
|
-
### Diagnostic details
|
|
97
|
-
|
|
98
|
-
- Model-performance correlation — the lone subagent dispatch (`pre-completion-reviewer`) ran on `anthropic/claude-sonnet-4-6`, appropriate for judgment-heavy review.
|
|
99
|
-
The dead-code-gate framing miss was a protocol-scope issue (pre-existing vs blocking), not a model-capability mismatch.
|
|
100
|
-
- Escalation-delay — no error sequence exceeded 5 consecutive tool calls; the harness `ERR_PNPM_IGNORED_BUILDS` resolved in ~4.
|
|
101
|
-
- Feedback-loop gap — build-stage verification ran incrementally after each step (good); the gap was at ship: the pre-push check omits the `main`-only gates (`pnpm fallow dead-code`) and lockfile validation that CI enforces, so a locally-clean `pnpm run lint` still failed CI twice.
|
|
102
|
-
|
|
103
|
-
### Changes made
|
|
104
|
-
|
|
105
|
-
1. `.pi/prompts/ship-issue.md` — renamed Step 2 to "Pre-push checks" and added `pnpm fallow dead-code` alongside `pnpm run lint`, with a one-line note that the gate is `main`-only and blocks pushes regardless of who introduced the failure.
|
|
106
|
-
2. `AGENTS.md` (§ Code Style pnpm rules) — added a rule to run `pnpm install` and commit the updated `pnpm-lock.yaml` in the same commit when a `package.json` dependency changes, since CI installs with `--frozen-lockfile`.
|
|
107
|
-
|
|
108
|
-
[ADR-0003]: ../decisions/0003-publish-bundled-type-declarations.md
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 272
|
|
3
|
-
issue_title: "Export WorkspaceProvider collaborator types by name from the public surface"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #272 — Export `WorkspaceProvider` collaborator types by name from the public surface
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-05-29T23:23:37Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Planned a purely additive, type-only change to `@gotgenes/pi-subagents`'s public surface: re-export `Workspace`, `WorkspacePrepareContext`, `WorkspaceDisposeOutcome`, and `WorkspaceDisposeResult` by name from `src/service/service.ts`, alongside the already-exported `WorkspaceProvider`.
|
|
13
|
-
The plan bundles the source change with extending the `verify:public-types` harness (symbol guard + probe consumer) into a single `feat:` commit, since a packaged-tarball probe cannot import names the entry does not yet export.
|
|
14
|
-
|
|
15
|
-
### Observations
|
|
16
|
-
|
|
17
|
-
- The issue's "Proposed change" was unambiguous, so the `ask-user` design gate was skipped.
|
|
18
|
-
|
|
19
|
-
## Stage: Implementation — Build (2026-05-29T23:30:13Z)
|
|
20
|
-
|
|
21
|
-
### Session summary
|
|
22
|
-
|
|
23
|
-
Implemented the single plan step: widened the `#src/lifecycle/workspace` import in `src/service/service.ts` to include all four collaborator types and added them to the `export type { … }` block, updating the standing comment from a future-tracking reference to a present-tense description.
|
|
24
|
-
Extended `scripts/verify-public-types.sh` — the symbol guard loop and inline `probe.ts` — to assert all four new names, confirmed the harness fails (red) before the source change and passes (green) after.
|
|
25
|
-
Also updated two stale forward-references to #272 in `docs/architecture/architecture.md` (flagged by the pre-completion reviewer).
|
|
26
|
-
|
|
27
|
-
### Observations
|
|
28
|
-
|
|
29
|
-
- Red→green cycle through the type-level harness (`verify:public-types`) rather than vitest, exactly as planned.
|
|
30
|
-
- No rollup config change was needed — `rollup-plugin-dts` carries through whatever the entry exports; the symbol guard and `#src` self-containment guard both stayed green.
|
|
31
|
-
- The symbol guard already found the names present in the bundle (declared but not exported); the probe's type-check was the real red signal.
|
|
32
|
-
- Pre-completion reviewer: WARN — two stale forward-references to #272 in `docs/architecture/architecture.md`; both fixed in a follow-up `docs:` commit before shipping.
|
|
33
|
-
- No new vitest cycle: the re-exports are type-only and erase at runtime.
|
|
34
|
-
The red→green loop lives in the type-level `verify:public-types` harness, not the runtime suite — this is closer to a `/build-plan` shape than a code TDD cycle, but it still has a clean red→green via the probe consumer.
|
|
35
|
-
- The four interfaces already exist in `src/lifecycle/workspace.ts` with correct shapes; only re-exporting is in scope.
|
|
36
|
-
- `rollup.dts.config.mjs` needs no change — `WorkspaceProvider` already pulls the four collaborator declarations into the bundle by reference, so adding named exports keeps the `grep '#src'` self-containment guard green.
|
|
37
|
-
- A standing comment in `service.ts` ("Named re-exports … tracked in #272") goes stale on landing — the plan updates it in the same step.
|
|
38
|
-
- The downstream simplification in `@gotgenes/pi-subagents-worktrees` (swap indexed-access aliases for named imports, bump the dependency) is deferred until a `pi-subagents` release carries these exports — consistent with the registry-consumption model settled in #270.
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 277
|
|
3
|
-
issue_title: "Encapsulate AgentSession behind SubagentSession; retire the remaining agent.session reach-throughs"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #277 — Encapsulate AgentSession behind SubagentSession
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-05-30T12:00:00Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Produced an 8-step TDD plan covering delegate methods on `SubagentSession`, intent-revealing methods on `Agent`, caller migration across tools/service/UI/observation, observer callback narrowing, and `Agent.session` getter removal.
|
|
13
|
-
The plan extends the issue's three proposed methods with `getContextPercent()`, `subscribeToUpdates()`, and `messages` to fully satisfy the acceptance criterion that no production module outside `lifecycle/` references the raw `AgentSession`.
|
|
14
|
-
|
|
15
|
-
### Observations
|
|
16
|
-
|
|
17
|
-
- `subscribeAgentObserver` already accepts `SubscribableSession` (not `AgentSession`), so adding `subscribe()` to `SubagentSession` enables passing it directly — no `session` getter needed for observer wiring.
|
|
18
|
-
- The `onSessionCreated` observer callback delivers raw `AgentSession` to spawners in `tools/`.
|
|
19
|
-
The plan narrows it to `(agent: Agent)` and has spawners use `agent.subagentSession!` which structurally satisfies both `SubscribableSession` and `SessionLike` via the new delegate methods.
|
|
20
|
-
- The conversation viewer uses `session.messages` for rendering and `session.subscribe()` for live updates — both require delegate methods beyond the issue's three proposed methods.
|
|
21
|
-
- `queueSteer()` and `flushPendingSteers()` become private after migration, which requires migrating existing tests that call them directly.
|
|
22
|
-
- The public API surface (`SubagentsService` + `SubagentRecord`) is unaffected — `Agent` is internal.
|
|
23
|
-
|
|
24
|
-
## Stage: Implementation — TDD (2026-05-30T15:10:00Z)
|
|
25
|
-
|
|
26
|
-
### Session summary
|
|
27
|
-
|
|
28
|
-
All 8 TDD steps completed in one session. 13 commits landed: 2 `feat:`, 5 `refactor:`, 2 `docs:`, 1 `style:`, plus the earlier plan and retro commits.
|
|
29
|
-
Test count went from 960 → 973 (+13 net: +18 new tests, −5 removed tests for the retired `session` getter and `queueSteer`/`flushPendingSteers` private methods).
|
|
30
|
-
|
|
31
|
-
### Observations
|
|
32
|
-
|
|
33
|
-
- `subscribeAgentObserver` already accepted `SubscribableSession`, so `SubagentSession` (once it grew a `subscribe()` delegate) could be passed directly in `Agent.run()` and `Agent.resume()` — no cast needed.
|
|
34
|
-
- Adding `messages` to `MockSession` interface was a minor unplanned step: the field existed at runtime (via `createMockSession`'s spread) but the interface didn't declare it, causing a type error when `createSubagentSessionStub` tried to forward it.
|
|
35
|
-
- `onSessionCreated` tests in `foreground-runner.test.ts` called the callback with 2 args `(record, mockSess)`.
|
|
36
|
-
After narrowing, the first test case was missing a `subagentSession` setup; fixed by setting `record.subagentSession` before invoking the callback.
|
|
37
|
-
- The `get-result-tool.test.ts` verbose conversation test needed updating: previously built a mock session with messages and passed it directly; now the stub's `getConversation` must return the expected text via `mockReturnValue`.
|
|
38
|
-
- Pre-completion reviewer returned **WARN** for two stale `architecture.md` passages: (1) conversation-viewer description still said "subscribes directly to `AgentSession`"; (2) `Agent` classDiagram still listed `queueSteer`/`flushPendingSteers` as public and omitted the 6 new public members.
|
|
39
|
-
Both fixed in a `docs:` commit before closing.
|
|
40
|
-
|
|
41
|
-
## Stage: Final Retrospective (2026-05-30T16:00:00Z)
|
|
42
|
-
|
|
43
|
-
### Session summary
|
|
44
|
-
|
|
45
|
-
Issue #277 shipped across three sessions (planning, TDD, ship) in a single day.
|
|
46
|
-
All 8 TDD steps completed cleanly, 13 implementation commits landed, and `pi-subagents-v13.2.0` released.
|
|
47
|
-
|
|
48
|
-
### Observations
|
|
49
|
-
|
|
50
|
-
#### What went well
|
|
51
|
-
|
|
52
|
-
- Planning correctly identified scope beyond the issue's three proposed methods: `getContextPercent()`, `subscribeToUpdates()`, and `messages` were needed to satisfy the "no production module outside `lifecycle/` references `AgentSession`" acceptance criterion.
|
|
53
|
-
This prevented mid-TDD design revisions.
|
|
54
|
-
- The discovery that `subscribeAgentObserver` already accepted `SubscribableSession` meant adding `subscribe()` to `SubagentSession` was sufficient for observer wiring — no type cast or adapter needed.
|
|
55
|
-
- Lift-and-shift execution was precise: new methods added first (steps 1-2), callers migrated by concern (steps 3-6), old getter removed last (step 7).
|
|
56
|
-
No step broke any other step's tests.
|
|
57
|
-
- Pre-completion reviewer caught two stale `architecture.md` passages (classDiagram with removed public methods, conversation-viewer description) that the implementation steps missed.
|
|
58
|
-
Both fixed in a `docs:` commit before closing.
|
|
59
|
-
|
|
60
|
-
#### What caused friction (agent side)
|
|
61
|
-
|
|
62
|
-
1. `missing-context` — `MockSession` interface lacked `messages`.
|
|
63
|
-
The field existed at runtime (via `createMockSession`'s spread + `Record<string, unknown>` return type) but the `MockSession` interface didn't declare it.
|
|
64
|
-
Adding `messages` to `createSubagentSessionStub` triggered a type error.
|
|
65
|
-
Impact: 2 extra edits to `mock-session.ts` (add field to interface, add to `base` object), no rework.
|
|
66
|
-
2. `missing-context` — `get-result-tool.test.ts` conversation test relied on raw mock session messages.
|
|
67
|
-
After migrating to `record.getConversation()`, the stub's `getConversation` returned `""` by default.
|
|
68
|
-
The test needed `stub.getConversation.mockReturnValue("...")` instead.
|
|
69
|
-
Impact: 1 test update, caught immediately by `pnpm vitest run`.
|
|
70
|
-
3. `missing-context` — `foreground-runner.test.ts` called `onSessionCreated(record, mockSess)` with 2 args.
|
|
71
|
-
After narrowing the callback to `(agent: Agent)`, the first test lacked `record.subagentSession` setup.
|
|
72
|
-
Impact: 2 test blocks updated, caught by `pnpm vitest run`.
|
|
73
|
-
4. `missing-context` — First `get-result-tool.ts` edit left a double-nested `if (conversation)` block.
|
|
74
|
-
The multi-edit replaced the outer `if (params.verbose && record.session)` but preserved the inner guard, creating `if (conversation) { if (conversation) { ... } }`.
|
|
75
|
-
Impact: Self-caught on immediate read-back; fixed in the same commit, no rework.
|
|
76
|
-
|
|
77
|
-
#### What caused friction (user side)
|
|
78
|
-
|
|
79
|
-
- None observed.
|
|
80
|
-
The user's involvement was limited to the `/plan-issue`, `/tdd-plan`, `/ship-issue`, and `/retro` prompts — no mid-session corrections or redirections were needed.
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 280
|
|
3
|
-
issue_title: "Rename the internal Agent class to Subagent"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #280 — Rename the internal `Agent` class to `Subagent`
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-05-31T00:09:51Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Produced a numbered implementation plan to rename the subagent-instance cluster in `src/lifecycle/` from the bare `Agent*` family to `Subagent*`, consolidate the duplicate `AgentStatus` union into the public `SubagentStatus`, and update the architecture doc.
|
|
13
|
-
The plan is a 7-step refactor (no behavior change), each step an atomic language-service rename that leaves the tree green.
|
|
14
|
-
|
|
15
|
-
### Observations
|
|
16
|
-
|
|
17
|
-
- Scope decisions confirmed with the user via `ask_user`: (1) rename the module files too (`agent.ts` → `subagent.ts`, `agent-manager.ts` → `subagent-manager.ts`, plus test/helper files), and (2) full-consistency rename of adjacent identifiers — `subscribeAgentObserver`, the `SubagentManagerObserver` `onAgent*` methods, and the `createTestAgent` helper.
|
|
18
|
-
- Layering catch: pointing `WorkspaceDisposeOutcome.status` directly at `service.ts`'s `SubagentStatus` would create a `lifecycle → service` cycle (`service.ts` already imports the workspace collaborator types).
|
|
19
|
-
Resolution: keep the union's single home in the lifecycle layer (`subagent.ts`) and have `service.ts` re-export it, mirroring the existing `LifetimeUsage` / workspace re-export pattern.
|
|
20
|
-
- Acceptance-grep catch: the issue's `grep src/lifecycle/` for bare `Agent` matches comments and string literals (e.g. the two `"Agent not configured …"` error messages), not just symbols.
|
|
21
|
-
The language-service rename does not touch those, so each step must sweep residual comment/string occurrences; step 7 has a final grep gate.
|
|
22
|
-
- Compound names (`AgentSession`, `AgentInvocation`, `AgentTypeRegistry`, `AgentTool`, `AgentSpawnConfig`) are not bare-word matches and are explicitly out of scope.
|
|
23
|
-
- Non-breaking — `refactor:` commits throughout; `verify:public-types` runs after the status consolidation and the final step since the public bundle (`dist/public.d.ts`) is rolled from `src/service/service.ts`.
|
|
24
|
-
- Also flagged the `package-pi-subagents` SKILL.md for an internals-naming update (it references `AgentManager`, `Agent`, `make-agent`).
|
|
25
|
-
|
|
26
|
-
## Stage: Implementation — TDD (2026-05-31T00:38:55Z)
|
|
27
|
-
|
|
28
|
-
### Session summary
|
|
29
|
-
|
|
30
|
-
Completed 6 refactor commits (steps 1–6 from the plan, with step 5 folded into step 3) plus a `test:` commit for the helper rename and a `docs:` commit for the architecture doc update.
|
|
31
|
-
All 973 tests pass across 59 test files with no test count delta.
|
|
32
|
-
Pre-completion reviewer returned PASS with all 5 acceptance criteria verified.
|
|
33
|
-
|
|
34
|
-
### Observations
|
|
35
|
-
|
|
36
|
-
- Step 5 (`AgentManagerLike` → `SubagentManagerLike`) was automatically folded into step 3 because the bulk-rename Python script replaced all `AgentManager*` compounds at once — no separate commit was needed or appropriate.
|
|
37
|
-
- The acceptance grep (`grep -rnE '\bAgent(Manager|Init)?\b' src/lifecycle/`) also flags bare `Agent` in comments and error strings; each rename step swept those manually since the language-service rename does not touch non-symbol text.
|
|
38
|
-
- `sed` with negative lookaheads failed on macOS for the `notification.ts` file; fell back to a two-pass approach (sed for the import, then `perl -i -0pe` with negative lookahead for the body).
|
|
39
|
-
- `describe("Agent — ...)` test block names used em-dashes (Unicode U+2014); `sed` with `\u2014` escape did not match on macOS — required Python `re.sub` with the literal character.
|
|
40
|
-
- The `SubagentStatus` type definition was kept in `src/lifecycle/subagent.ts` (single home) and re-exported from `src/service/service.ts`, matching the existing `LifetimeUsage` / workspace re-export pattern and avoiding a `lifecycle → service` cycle.
|
|
41
|
-
- Docs: the architecture doc's session-encapsulation table had misaligned Markdown table columns after the rename (cell widths changed); `rumdl fmt` auto-fixed them.
|
|
42
|
-
- Pre-completion reviewer: PASS — all deterministic checks, all 5 acceptance criteria, conventional commits, docs, Mermaid diagrams, and dead-code gate confirmed clean.
|
|
43
|
-
|
|
44
|
-
## Stage: Final Retrospective (2026-05-31T01:05:57Z)
|
|
45
|
-
|
|
46
|
-
### Session summary
|
|
47
|
-
|
|
48
|
-
Shipped the full Planning → TDD → Ship lifecycle for the internal `Agent` → `Subagent` rename across `@gotgenes/pi-subagents`: 7 implementation commits (6 `refactor:`/`test:` + 1 `docs:`), 973 tests green throughout, CI passed on `27abb5aa`, and issue #280 closed.
|
|
49
|
-
No release was triggered (all `refactor:`/`test:`/`docs:` commits), so no release-please PR appeared — expected.
|
|
50
|
-
|
|
51
|
-
### Observations
|
|
52
|
-
|
|
53
|
-
#### What went well
|
|
54
|
-
|
|
55
|
-
- Two planning-stage catches prevented downstream rework: the `lifecycle → service` import cycle (resolved by keeping `SubagentStatus`'s single home in `subagent.ts` and re-exporting from `service.ts`) and the acceptance grep matching bare `Agent` in comments/strings (so each step swept non-symbol text).
|
|
56
|
-
Both were anticipated in the plan and held during execution.
|
|
57
|
-
- Incremental verification carried the rename safely: `pnpm run check` plus the affected test files ran after every step, so the text-based substitution mistakes were caught instantly and never reached a commit.
|
|
58
|
-
The pre-completion reviewer then returned a clean PASS with nothing to fix.
|
|
59
|
-
- The status re-export needed a follow-up `import type { SubagentStatus }` because `export type { … } from` does not create a local binding for `SubagentRecord` to reference — `pnpm run check` flagged it immediately, a one-edit fix.
|
|
60
|
-
|
|
61
|
-
#### What caused friction (agent side)
|
|
62
|
-
|
|
63
|
-
- `wrong-abstraction` — The plan specified each rename as a "scope-aware language-service pass" (`findRenameLocations`), but the execution toolkit has no LSP-rename tool — only `Edit`, `Bash` (`sed`/`perl`/`python`), and `grep`.
|
|
64
|
-
Execution fell back to text substitution, which is exactly why the comment/string sweep was needed and why the regex gymnastics below happened.
|
|
65
|
-
Impact: added friction but no rework — `tsc` + tests caught every gap; no incorrect commit landed.
|
|
66
|
-
- `other` (cross-platform tooling) — Repeated silent failures from BSD `sed` / `perl` one-liners: BSD `sed` lacks `\b` and lookahead; `perl -i ''` is malformed (the `-i ''` form is a `sed`-ism); neither interprets `\uXXXX` escapes, so em-dash `describe("Agent — …")` blocks and `notification.ts` body renames did not match.
|
|
67
|
-
Each failure forced a grep-verify-redo loop, ultimately resolved by switching to Python `re.sub`.
|
|
68
|
-
Impact: roughly 5–8 extra tool calls across the TDD stage; no rework beyond the redo cycles.
|
|
69
|
-
|
|
70
|
-
#### What caused friction (user side)
|
|
71
|
-
|
|
72
|
-
- None.
|
|
73
|
-
The user's two `ask_user` answers at planning time (file renames + full-consistency adjacent identifiers) front-loaded every scope decision, so the TDD and Ship stages ran without a single mid-course correction.
|
|
74
|
-
|
|
75
|
-
### Diagnostic details
|
|
76
|
-
|
|
77
|
-
- **Model-performance correlation** — One subagent dispatched (`pre-completion-reviewer`) on judgment-heavy review work (acceptance verification, Mermaid validation via `mmdc`, dead-code gate); appropriate match, no mismatch.
|
|
78
|
-
- **Escalation-delay tracking** — The `notification.ts` body rename cycled ~4–5 consecutive `sed`/`perl`/`grep` calls on the same substitution before switching to `perl -i -0pe`; under the 5-call threshold but the closest the session came.
|
|
79
|
-
The general lesson (prefer Python `re.sub`) generalizes the fix.
|
|
80
|
-
- **Unused-tool detection** — No Explore/`colgrep` gap: the codebase was already understood from planning, and an exact symbol rename is not a semantic-search task.
|
|
81
|
-
The only "missing capability" is a language-service rename tool, which is not in the toolkit — a genuine gap, not an unused option.
|
|
82
|
-
- **Feedback-loop gap analysis** — No gap: `pnpm run check` and affected tests ran after each step (incremental); `pnpm run lint`, `pnpm fallow dead-code`, and `verify:public-types` ran as the final batch.
|
|
83
|
-
Verification cadence was correct.
|
|
84
|
-
|
|
85
|
-
### Changes made
|
|
86
|
-
|
|
87
|
-
1. Appended this Final Retrospective stage entry to `packages/pi-subagents/docs/retro/0280-rename-agent-to-subagent.md`.
|
|
88
|
-
2. Strengthened the global `APPEND_SYSTEM.md` "Shell Commands" rule to name the literal absolute-path `cd` form (e.g. `cd /Users/you/project &&`), not just `cd $CWD &&` — the existing rule failed to catch the literal-path form that agents actually emit.
|
|
89
|
-
This file is global (`~/.pi/agent/APPEND_SYSTEM.md`), outside the repo, so it is not committed here.
|
|
90
|
-
3. Added a monorepo-specific line to `AGENTS.md` § Monorepo Structure: prefer `pnpm --filter @gotgenes/<pkg> run <script>` (or `pnpm -C packages/<pkg> run <script>`) from the root over `cd packages/<pkg> && pnpm run <script>`.
|
|
91
|
-
Prompted by excessive `cd` chaining observed across this session's Ship and Retro stages.
|
|
92
|
-
|
|
93
|
-
### Follow-ups considered (not applied)
|
|
94
|
-
|
|
95
|
-
1. Proposed adding a bulk-substitution tooling rule (prefer Python `re.sub` over `sed`/`perl` one-liners, since BSD `sed` lacks `\b`/lookahead and `\uXXXX` is uninterpreted) to the `code-design` skill's Tooling section.
|
|
96
|
-
The user opted to record the observation here only and skip the skill change.
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 360
|
|
3
|
-
issue_title: "fix(pi-subagents): custom agents default to replace mode instead of append"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #360 — fix(pi-subagents): custom agents default to replace mode instead of append
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-06-09T02:42:19Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Planned the one-line fix flipping the `promptMode` ternary in `custom-agents.ts` so custom agents without an explicit `prompt_mode` default to `append` (matching the built-in default) instead of `replace`.
|
|
13
|
-
Enumerated the full change surface: the source line, two existing tests in `test/config/custom-agents.test.ts`, the wizard frontmatter doc comment, and the `README.md` defaults table.
|
|
14
|
-
|
|
15
|
-
### Observations
|
|
16
|
-
|
|
17
|
-
- The issue's proposed fix is unambiguous, so no `ask_user` round was needed.
|
|
18
|
-
- `grep` confirmed the only default-asserting tests live in `test/config/custom-agents.test.ts`; the broader upstream regression suite uses explicit `promptMode` values and is unaffected.
|
|
19
|
-
- Unknown `prompt_mode` values (e.g. `merge`) now resolve to `append` rather than `replace` — flagged as the safer fallback (inheriting a superset of context rather than silently dropping project context).
|
|
20
|
-
- Source fix and test updates are coupled into one TDD cycle because the assertions and the changed line move together; docs split into a separate `docs:` commit.
|
|
21
|
-
- **Breaking change**: flipping the default alters the runtime behavior of existing `.pi/agents/*.md` files that omit `prompt_mode` (they switch from `replace` to `append` on upgrade with no config edit).
|
|
22
|
-
The plan was corrected mid-session to use `fix!:` with a `BREAKING CHANGE:` footer so release-please cuts a major — the initial draft incorrectly used a plain `fix:`.
|
|
23
|
-
- No `docs/architecture/` references to the default value exist; `CHANGELOG.md` is release-please-owned and untouched.
|
|
24
|
-
|
|
25
|
-
## Stage: Implementation — TDD (2026-06-09T02:48:38Z)
|
|
26
|
-
|
|
27
|
-
### Session summary
|
|
28
|
-
|
|
29
|
-
Completed both TDD cycles from the plan in a single session.
|
|
30
|
-
Step 1 flipped the ternary in `src/config/custom-agents.ts` and updated three assertions in `test/config/custom-agents.test.ts` (empty-frontmatter default, no-frontmatter assertion added, unknown-mode renamed and flipped).
|
|
31
|
-
Step 2 updated the inline doc comment in `src/ui/agent-creation-wizard.ts` and the `README.md` defaults table.
|
|
32
|
-
Test count: 973 (unchanged — no new tests added, three assertions updated in-place).
|
|
33
|
-
|
|
34
|
-
### Observations
|
|
35
|
-
|
|
36
|
-
- No deviations from the plan; all three test mutations landed exactly as specified.
|
|
37
|
-
- Full suite (59 test files, 973 tests) stayed green after the source change — the planning analysis that the broader upstream regression suite uses explicit `promptMode` values was confirmed correct.
|
|
38
|
-
- `pnpm fallow dead-code` and `pnpm run check` both passed with no findings.
|
|
39
|
-
- Pre-completion reviewer verdict: **PASS** — no warnings or findings raised.
|
|
40
|
-
|
|
41
|
-
## Stage: Final Retrospective (2026-06-09T03:04:21Z)
|
|
42
|
-
|
|
43
|
-
### Session summary
|
|
44
|
-
|
|
45
|
-
Shipped the breaking-default fix end to end across four staged sessions (plan → TDD → ship → retro), cutting `pi-subagents@15.0.0`.
|
|
46
|
-
The change flips the `promptMode` default for custom agents that omit `prompt_mode` from `replace` to `append`.
|
|
47
|
-
Execution was clean except for one significant miss in planning: the change was initially classified as a non-breaking `fix:` and corrected only after the user intervened.
|
|
48
|
-
|
|
49
|
-
### Observations
|
|
50
|
-
|
|
51
|
-
#### What went well
|
|
52
|
-
|
|
53
|
-
- The multi-model pipeline matched models to stage complexity: planning and retro on `claude-opus-4-8`, TDD on `claude-sonnet-4-6`, and the mechanical ship stage (push, CI watch, close, merge) on a cheaper `deepseek-v4-flash` — all stages completed their work correctly.
|
|
54
|
-
- The breaking-change correction propagated cleanly across the stage boundary: once the plan was fixed to `fix!:` with a `BREAKING CHANGE:` footer, the TDD stage (different model, different session) picked it up from the plan and committed the footer verbatim without re-deciding.
|
|
55
|
-
- TDD verification was incremental, not end-loaded: green baseline (`check`/`lint`/test) before any edit, red confirmation after the test edit, green after the source edit, then full suite + `check` + `lint` + `fallow` before the reviewer dispatch.
|
|
56
|
-
|
|
57
|
-
#### What caused friction (agent side)
|
|
58
|
-
|
|
59
|
-
- `instruction-violation` (user-caught) — the planning stage classified a changed-default bug fix as a non-breaking `fix:`, producing a plan with `fix:` commit messages.
|
|
60
|
-
The plan template line "If the change is breaking, say so explicitly in Goals and use `feat!:`" was available but never triggered, because the agent conflated "the fix is unambiguous" (turn 8) with "the change is non-breaking" and skipped the breaking determination entirely.
|
|
61
|
-
Impact: the user had to intervene ("This is a breaking change, right?"); three corrective edits (plan Goals, plan TDD commit block, retro Planning notes) plus one extra commit (`docs: mark issue #360 change as breaking`).
|
|
62
|
-
Caught before TDD, so no code rework — but a wrong `fix:` that reached `/ship-issue` would have cut a patch release for a breaking change.
|
|
63
|
-
|
|
64
|
-
#### What caused friction (user side)
|
|
65
|
-
|
|
66
|
-
- None on the #360 work.
|
|
67
|
-
The single redirecting question ("This is a breaking change, right?") was a near-optimal intervention: minimal, Socratic, and it let the agent reason to the correct classification itself rather than dictating the fix.
|
|
68
|
-
- Environment note (not #360-specific): the retro session opened with local `main` detached onto a stale `#332` side-branch after an aborted rebase (2 duplicate commits, 36 behind `origin/main`).
|
|
69
|
-
`origin/main` was intact; recovery was a verified `git reset --hard origin/main` after confirming the 2 local commits were byte-identical duplicates of work already on origin.
|
|
70
|
-
|
|
71
|
-
### Diagnostic details
|
|
72
|
-
|
|
73
|
-
- **Model-performance correlation** — the breaking-change miss happened on the *strongest* model in the pipeline (`claude-opus-4-8`) during the judgment-heaviest stage (planning).
|
|
74
|
-
This rules out model capability as the cause and points to a salience gap in the plan-issue prompt: the breaking determination is framed only as an `ask-user` ambiguity, conditional on the change being "ambiguous," with no unconditional classification step.
|
|
75
|
-
- **Feedback-loop gap analysis** — no gap; the TDD stage ran `check`/`lint`/test/`fallow` incrementally rather than only at the end.
|
|
76
|
-
- Escalation-delay and unused-tool lenses found nothing notable (no rabbit-holes or tool-availability misses).
|
|
77
|
-
|
|
78
|
-
### Changes made
|
|
79
|
-
|
|
80
|
-
1. `.pi/prompts/plan-issue.md` — added an unconditional breaking-change classification step to the `## Decide` section (before the ambiguity paragraph), so the breaking determination no longer hides behind the `ask-user` ambiguity gate.
|
|
81
|
-
Names the non-obvious case explicitly: a bug fix that changes a default is breaking.
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 373
|
|
3
|
-
issue_title: "Extract SubagentState; make Subagent execution deps mandatory"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #373 — Extract SubagentState; make Subagent execution deps mandatory
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-06-14T03:34:51Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Produced the implementation plan at `packages/pi-subagents/docs/plans/0373-extract-subagent-state.md`.
|
|
13
|
-
The architecture doc (Phase 17 Step 2 + "First-principles refinement") already specified the design precisely and the issue body matched it, so planning was confirmation-and-detailing rather than discovery.
|
|
14
|
-
Issue is first-party (`gotgenes`) and unambiguous — skipped the `ask_user` gate.
|
|
15
|
-
|
|
16
|
-
### Observations
|
|
17
|
-
|
|
18
|
-
- **Not breaking** for the published surface: `src/service/service.ts` exposes `SubagentRecord`/`SubagentStatus`/spawn-config, never `SubagentInit` or the `Subagent` constructor.
|
|
19
|
-
Only the internal constructor signature changes.
|
|
20
|
-
- **Single production construction site** confirmed: `SubagentManager.spawn` (~line 139) is the only `new Subagent(...)` outside tests — this is what makes mandatory execution deps viable.
|
|
21
|
-
- **Observer retarget is required**, not optional: making execution mandatory would otherwise force `record-observer.test.ts` to stub execution.
|
|
22
|
-
Pointing `subscribeSubagentObserver` at `SubagentState` (and dropping the record from `onCompact`, closing over `this` in `subagent.ts`) is the move that lets observer tests target `SubagentState` directly.
|
|
23
|
-
- **`resume()`'s missing-session throw stays** — it guards a genuine runtime state, not a construction concern.
|
|
24
|
-
Only the two `run()` "not configured for execution" throws are deleted.
|
|
25
|
-
- **`SubagentStatus` home**: moved to `subagent-state.ts` but re-exported from `subagent.ts` to keep `service.ts`'s import path (and the public type bundle path) unchanged, and to avoid a circular import.
|
|
26
|
-
- **Lift-and-shift for the large test file**: `test/lifecycle/subagent.test.ts` (~700 LOC).
|
|
27
|
-
Step 1 funnels constructions through a local helper and moves the state-machine `describe` blocks to the new `subagent-state.test.ts`, so Step 3's mandatory-execution flip is bounded to the helper + two run/resume factories.
|
|
28
|
-
Step 3 is unavoidably one atomic commit (removing optional fields breaks every construction at the type level at once).
|
|
29
|
-
- **Doc updates identified**: `architecture.md` (lifecycle file listing, `Subagent` class diagram, mark Step 2 ✅ Complete, Phase 17 prose ~line 879, type-complexity table ~line 649) and `SKILL.md` (Lifecycle 10→11 modules, total 56→57 files).
|
|
30
|
-
- Deferred per scope boundary: metrics-as-projection and result-delivery domain extraction (the other two of the four conflated domains).
|
|
31
|
-
|
|
32
|
-
## Stage: Implementation — TDD (2026-06-14T09:23:00Z)
|
|
33
|
-
|
|
34
|
-
### Session summary
|
|
35
|
-
|
|
36
|
-
Executed all four planned steps as separate commits: (1) extract `SubagentState` value object + new `subagent-state.test.ts`, (2) retarget `subscribeSubagentObserver` at `SubagentState`, (3) the atomic flip making `SubagentExecution` a mandatory collaborator and deleting the two `run()` throws, (4) docs.
|
|
37
|
-
Test count moved 966 → 967 (net): +26 new `SubagentState` tests, minus the migrated state-machine duplicates and the obsolete missing-factory test.
|
|
38
|
-
Pre-completion reviewer returned **PASS**; `check`/`lint`/`test`/`fallow` all clean.
|
|
39
|
-
|
|
40
|
-
### Observations
|
|
41
|
-
|
|
42
|
-
- The plan held exactly — every file in Module-Level Changes was touched and nothing else.
|
|
43
|
-
The `createTestSubagent` consumers (`conversation-viewer`, `notification`, `get-result-tool`, `make-subagent.test`) stayed untouched as predicted; the helper absorbed the construction change via a `TestSubagentOptions` shape that splits passive-state shorthands from identity/execution.
|
|
44
|
-
- **Explicit-`undefined` preservation** (testing-skill warning) mattered: `createTestSubagent` and the local `makeSubagent` build their `SubagentState` via spread of the rest-captured state overrides (`{ defaults, ...stateOverrides }`) so callers passing `completedAt: undefined` (running-status records in `get-result-tool.test`) still get `undefined`, not the `2000` default.
|
|
45
|
-
- The lift-and-shift prep in Step 1 (local `makeSubagent` helper + perl-routing the single-line constructions) paid off: Step 3's breaking flip only had to edit the helper, `createRunnableAgent`, `createResumableAgent`, `createCompletionAgent`, and the constructor describe — not the whole file.
|
|
46
|
-
- Removed the obsolete "throws when the session factory is missing" test (the guard is gone by construction); the construct-complete invariant is now type-level, not runtime-testable.
|
|
47
|
-
An initial replacement comment was dropped per reviewer/operator feedback as unhelpful.
|
|
48
|
-
- `SubagentExecution` carries 12 fields (4 mandatory).
|
|
49
|
-
Reviewer flagged it as wide but accepted per the plan's recorded decision to keep it concrete rather than split further.
|
|
50
|
-
- Pre-completion reviewer: **PASS** (no WARN findings).
|
|
51
|
-
|
|
52
|
-
## Stage: Final Retrospective (2026-06-14T17:20:00Z)
|
|
53
|
-
|
|
54
|
-
### Session summary
|
|
55
|
-
|
|
56
|
-
Shipped #373 end-to-end across one conversation spanning Planning → TDD → Ship → Retro: four implementation commits, CI green, issue closed, no release-please PR (a `refactor:`-only change does not trigger a release).
|
|
57
|
-
The plan held exactly — zero rework, and the pre-completion reviewer returned PASS with nothing to fix.
|
|
58
|
-
The single user intervention was a one-line comment removal during TDD Step 3.
|
|
59
|
-
|
|
60
|
-
### Observations
|
|
61
|
-
|
|
62
|
-
#### What went well
|
|
63
|
-
|
|
64
|
-
- **Plan-to-ship with zero rework.**
|
|
65
|
-
Every file in the plan's Module-Level Changes was touched and nothing else; the `createTestSubagent` consumers stayed untouched exactly as predicted.
|
|
66
|
-
The lift-and-shift prep (Step 1 funneling constructions through a local `makeSubagent` helper) bounded the breaking Step 3 flip to the helper plus three factories — the atomic-construction-change concern from the plan never materialized as churn.
|
|
67
|
-
- **Clean model allocation across stages.**
|
|
68
|
-
Planning ran on `claude-opus-4-8`, TDD on `claude-sonnet-4-6`, Ship on `opencode-go/deepseek-v4-flash` (mechanical git/CI/close work), the pre-completion reviewer subagent on `claude-sonnet-4-6`, and Retro on `claude-opus-4-8`.
|
|
69
|
-
Judgment-heavy work landed on reasoning-strong models; the cheap model handled only the mechanical ship sequence.
|
|
70
|
-
- **Incremental verification.** `pnpm run check` ran after every TDD step (not just at the end), catching the shared-type breakage at the right boundary; the affected test files were run per-step before the full suite.
|
|
71
|
-
|
|
72
|
-
#### What caused friction (agent side)
|
|
73
|
-
|
|
74
|
-
- `other` (tombstone comment) — after removing the obsolete "throws when the session factory is missing" test in TDD Step 3, left a comment narrating the *absence* of the guard (`// No "missing session factory" guard: execution is a mandatory constructor collaborator …`).
|
|
75
|
-
The user flagged it as unhelpful and asked for removal.
|
|
76
|
-
Impact: one extra `Edit` + a blank-line cleanup + a `--amend` of the Step 3 commit.
|
|
77
|
-
No behavioral rework; user-caught.
|
|
78
|
-
|
|
79
|
-
#### What caused friction (user side)
|
|
80
|
-
|
|
81
|
-
- None of consequence.
|
|
82
|
-
The single intervention (comment removal) was light mechanical oversight on an otherwise self-driving session; no earlier context would have changed the outcome.
|
|
83
|
-
|
|
84
|
-
### Diagnostic details
|
|
85
|
-
|
|
86
|
-
- **Model-performance correlation** — no mismatch.
|
|
87
|
-
The only subagent dispatch (pre-completion-reviewer) ran on `claude-sonnet-4-6`, appropriate for judgment-heavy review; it returned PASS.
|
|
88
|
-
The Ship stage on `deepseek-v4-flash` was purely mechanical (git push, `ci_find`/`ci_watch`, `issue_close`, `release_pr_find`) and the one judgment point (the batch-vs-release `ask_user`) was handled correctly.
|
|
89
|
-
- **Escalation-delay / unused-tool / feedback-loop** — nothing notable: no rabbit-holes, no error-chasing sequences, and verification ran incrementally throughout.
|
|
90
|
-
Lenses skipped.
|
|
91
|
-
|
|
92
|
-
### Changes made
|
|
93
|
-
|
|
94
|
-
1. `.pi/skills/code-design/SKILL.md` (§ Names over comments) — added a line forbidding tombstone comments that narrate removed code or the absence of a guard/test/branch, prompted by the user-caught over-comment in TDD Step 3.
|