@gotgenes/pi-subagents 17.4.0 → 18.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,28 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [18.0.0](https://github.com/gotgenes/pi-packages/compare/pi-subagents-v17.5.0...pi-subagents-v18.0.0) (2026-06-23)
9
+
10
+
11
+ ### ⚠ BREAKING CHANGES
12
+
13
+ * **pi-subagents:** The /agents command is removed. Its responsibilities are now served by: /subagents:settings (configure concurrency and turn limits), /subagents:sessions (read-only session transcript viewing), and the always-on background widget (running-agent visibility).
14
+ * **pi-subagents:** the /subagents-settings and /subagent-sessions commands are renamed to /subagents:settings and /subagents:sessions.
15
+
16
+ ### Features
17
+
18
+ * **pi-subagents:** dissolve /agents and remove the conversation-viewer subtree ([cb813f2](https://github.com/gotgenes/pi-packages/commit/cb813f2c5fac7c0b5fa62eecf7f0665671382c1c))
19
+ * **pi-subagents:** namespace commands under subagents: ([23bf99e](https://github.com/gotgenes/pi-packages/commit/23bf99e8662a2b89b2816a14e5f2801fd6c74159))
20
+
21
+ ## [17.5.0](https://github.com/gotgenes/pi-packages/compare/pi-subagents-v17.4.0...pi-subagents-v17.5.0) (2026-06-23)
22
+
23
+
24
+ ### Features
25
+
26
+ * **pi-subagents:** add file-snapshot transcript source ([06a9ee3](https://github.com/gotgenes/pi-packages/commit/06a9ee39b5f529f770c39cf8d8bdcefd1511bb7d))
27
+ * **pi-subagents:** retain evicted-agent descriptors in the manager ([3128e2a](https://github.com/gotgenes/pi-packages/commit/3128e2a44b94be9b976b74d24cf5127ca0944074))
28
+ * **pi-subagents:** source evicted-agent transcripts from disk in /subagent-sessions ([b4da762](https://github.com/gotgenes/pi-packages/commit/b4da762b0574b49e028518c62e7b2f11acaf1ad4))
29
+
8
30
  ## [17.4.0](https://github.com/gotgenes/pi-packages/compare/pi-subagents-v17.3.0...pi-subagents-v17.4.0) (2026-06-23)
9
31
 
10
32
 
@@ -81,8 +81,8 @@ flowchart TB
81
81
  subgraph ui["UI domain"]
82
82
  direction TB
83
83
  Widget["agent-widget<br/>(live status)"]
84
- ConvViewer["conversation-viewer<br/>(session overlay)"]
85
- Menu["agent-menu<br/>(slash command)"]
84
+ Sessions["session-navigator<br/>(session view)"]
85
+ Settings["subagents-settings<br/>(settings command)"]
86
86
  end
87
87
 
88
88
  AgentTool --> SubagentManager
@@ -341,14 +341,10 @@ src/
341
341
  ├── ui/ user-facing presentation
342
342
  │ ├── agent-widget.ts above-editor live status widget
343
343
  │ ├── widget-renderer.ts pure rendering for widget
344
- │ ├── agent-menu.ts /agents slash command menu
345
- │ ├── agent-config-editor.ts agent detail/edit view (AgentConfigEditor class)
346
- │ ├── agent-creation-wizard.ts agent creation (AgentCreationWizard class)
347
- ├── conversation-viewer.ts scrollable session overlay
348
- │ ├── message-formatters.ts pure per-message-type formatters (extracted from conversation-viewer)
349
- │ ├── agent-file-ops.ts filesystem abstraction
350
- │ ├── agent-file-writer.ts overwrite-guard + write + reload + notify helper
351
- │ └── display.ts pure formatters and shared types
344
+ │ ├── display.ts pure formatters and shared types
345
+ │ ├── subagents-settings.ts /subagents:settings command handler
346
+ │ ├── session-navigation.ts pure session-selection and transcript-source logic
347
+ └── session-navigator.ts /subagents:sessions command handler
352
348
 
353
349
  └── handlers/ event handlers
354
350
  ├── index.ts barrel re-export
@@ -363,7 +359,7 @@ Record statistics (tool uses, token usage, compaction counts) and live activity
363
359
  This is the single per-child session subscription — all run state lives on the `Subagent` record.
364
360
 
365
361
  The widget reads agent state by polling the records exposed via `SubagentManager.listAgents()` every 80 ms; that poll loop is now started by the manager's lifecycle notifications (the widget subscribes as a `SubagentManagerObserver` fanned out through `CompositeSubagentObserver`), not by inbound calls from the spawn tools.
366
- The conversation viewer subscribes to session events via `Subagent.subscribeToUpdates()` and reads messages via `Subagent.messages` — no direct `AgentSession` reference (#277).
362
+ The `/subagents:sessions` navigator reads messages via `Subagent.agentMessages` and subscribes to updates via `Subagent.subscribeToUpdates()` — no direct `AgentSession` reference (#277).
367
363
 
368
364
  ## Cross-extension architecture
369
365
 
@@ -373,7 +369,7 @@ flowchart TD
373
369
  direction TB
374
370
  exports["SubagentsService API<br/>publish / getSubagentsService<br/>SubagentRecord, SubagentStatus"]
375
371
  engine["Tools: subagent, get_subagent_result,<br/>steer_subagent<br/>SubagentManager, createSubagentSession, SubagentSession"]
376
- ui_int["Internal UI: widget, viewer,<br/>/agents menu"]
372
+ ui_int["Internal UI: widget, session-navigator,<br/>subagents-settings"]
377
373
  end
378
374
 
379
375
  core -- "Symbol.for on globalThis" --> sched["scheduling extension<br/>(hypothetical)"]
@@ -406,7 +402,7 @@ They declare this package as an optional peer dependency and use dynamic import
406
402
  - Token usage tracking.
407
403
  - Session directory derivation and persisted `SessionManager` for subagent transcripts.
408
404
  - Settings persistence.
409
- - Internal UI (widget, conversation viewer, `/agents` menu) — these stay until the API boundary is proven, then move to a separate extension.
405
+ - Internal UI (widget, `/subagents:sessions` session navigator, `/subagents:settings` command) — the conversation viewer and `/agents` menu were removed in Phase 19 (Steps 5–6, [#442], [#441]) per [ADR-0004].
410
406
 
411
407
  ### What the core dropped
412
408
 
@@ -560,7 +556,7 @@ In the target state, pi-subagents publishes events and a provider seam; other pa
560
556
 
561
557
  - **pi-permission-system** (observational) subscribes to child-session lifecycle events, detects subagent execution context in the child, and gates tool calls at runtime.
562
558
  - **pi-subagents-worktrees** (generative) registers a `WorkspaceProvider` that prepares a git worktree at run-start and tears it down after, supplying the child's cwd.
563
- - **pi-subagents-ui** (future, under reconsideration — see the [first-principles refinement](#first-principles-refinement-and-the-deeper-target)) subscribes to the broadcast and the query/behavior interfaces; whether the inherited widget, conversation viewer, and `/agents` menu survive is judged on our principles, not preserved by default.
559
+ - **pi-subagents-ui** (future, under reconsideration — see the [first-principles refinement](#first-principles-refinement-and-the-deeper-target)) subscribes to the broadcast and the query/behavior interfaces; the conversation viewer and `/agents` menu were removed in Phase 19 per [ADR-0004]; the surviving UI (widget, session navigator, settings command) stays in-core.
564
560
  - **Any future extension** (OTel, auditing, cost tracking) subscribes to the same events without pi-subagents knowing.
565
561
 
566
562
  Composition test: install neither extension, only permissions, only workspaces, or both — the core is byte-for-byte identical in all four cases, and the two extensions never reference each other.
@@ -1036,19 +1032,26 @@ Selection and sourcing are untouched; native navigation now renders at parity, u
1036
1032
 
1037
1033
  `Release: independent`
1038
1034
 
1039
- ### Step 4b — File-snapshot source for evicted agents ([#463])
1035
+ ### Step 4b — File-snapshot source for evicted agents ([#463])
1040
1036
 
1041
1037
  Smell: Category C (coupling) — the #445 slice sources transcripts live from `manager.listAgents()` only; an agent evicted by the 10-minute cleanup sweep has a persisted session JSONL but no live record, so it is unreachable.
1042
- This step adds the file-snapshot `TranscriptSource` branch (`parseSessionEntries(readFile(outputFile))` → drop the `SessionHeader` → `buildSessionContext(...).messages`) and broadens the candidate set to enumerate evicted agents, behind the same seam; the renderer is untouched.
1038
+ This step adds the file-snapshot `TranscriptSource` branch (`parseSessionEntries(readFile(outputFile))` → drop the `SessionHeader` → `buildSessionContext(...).messages`) and broadens the candidate set to evicted agents, behind the same seam; the renderer is untouched.
1043
1039
 
1044
1040
  Independent: this is a new capability the bespoke viewer never had, so it gates nothing and is not a Step 5 prerequisite.
1045
1041
  Best sequenced after Step 4a (shared renderer), but carries no hard dependency.
1046
1042
 
1047
1043
  Outcome: the operator can view a fully-evicted agent's transcript from its persisted session file; the dual-source design recorded in [ADR-0004] Addendum 2 is fully realized.
1048
1044
 
1045
+ Landed ([#463]): `fileSnapshotSource(outputFile, readFile)` lands in the pure `session-navigation.ts` (`parseSessionEntries` → drop the `SessionHeader` → `buildSessionContext(...).messages`; a static no-subscribe, no-streaming source).
1046
+ The candidate set is broadened via **manager-retained descriptors**, not a directory scan: the persisted child session carries no subagent `type`/`description` (those live only on the in-memory record), so a scan would yield degraded labels and parse every file per open.
1047
+ Instead `SubagentManager.cleanup()` stashes a lightweight `EvictedSubagent` descriptor (label fields + `outputFile`, no messages) before disposing a record with a persisted file, exposed via `listEvicted()` and cleared by `clearCompleted()`/`dispose()`.
1048
+ `NavigationEntry` became a `live | evicted` discriminated union; the handler selects `liveSource` vs `fileSnapshotSource` by kind inside a `try/catch` (an unreadable file notifies and skips), and `index.ts` injects `readFileSync`.
1049
+ Evicted entries carry an `· evicted (snapshot)` label marker.
1050
+ Coverage is in-session evictions (the sweep's only targets); old-session orphan files — the ones a scan would surface with degraded labels — are out of scope.
1051
+
1049
1052
  `Release: independent`
1050
1053
 
1051
- ### Step 5 — Dissolve `/agents` and remove the conversation-viewer subtree ([#442])
1054
+ ### Step 5 — Dissolve `/agents` and remove the conversation-viewer subtree ([#442])
1052
1055
 
1053
1056
  Smell: Category A (dead subsystem) plus Category B (oversized) — once Steps 2–4 re-home all four menu responsibilities, the `/agents` command and everything reachable only from `agent-menu.ts` is an unreferenced subtree.
1054
1057
  This is the first of two deletion commits (split by subtree).
@@ -1063,11 +1066,16 @@ Target files:
1063
1066
  Running-agent visibility is now owned by the background widget (Step 3); session navigation replaces the bespoke overlay (Step 4); settings live in `/subagents-settings` (Step 2).
1064
1067
  Deleting the hub in one move avoids any surgical edit to the doomed file and leaves the definition-management leaves orphaned for Step 6.
1065
1068
 
1066
- Outcome: `/agents` dissolved; −767 LOC source (menu hub + viewer + formatters); −812 LOC test; largest test function eliminated; `index.ts` edited once (deregistration), never surgically narrowed.
1069
+ Actual approach (vs. original plan): a tidy-first preparatory commit first extracted `MenuUI` from `agent-menu.ts` into a new `src/ui/menu-ui.ts` module, breaking the bidirectional type cycle the hub imported the wizard/editor classes while the leaves imported back the `MenuUI` type.
1070
+ Without the prep commit, deleting either subtree first would have left the other half referencing a deleted module.
1071
+ `index.ts` also shed the now-dead `join` (node:path) and `buildParentSnapshot` imports in addition to the two module imports.
1072
+ The `menu-ui.ts` module is transient and is removed with the wizard/editor in Step 6.
1073
+
1074
+ Outcome: ✅ `/agents` dissolved; −767 LOC source (menu hub + viewer + formatters); −812 LOC test; largest test function eliminated; `index.ts` dewired.
1067
1075
 
1068
1076
  `Release: batch "dissolve-agents"`
1069
1077
 
1070
- ### Step 6 — Remove the orphaned agent-definition management subtree ([#441])
1078
+ ### Step 6 — Remove the orphaned agent-definition management subtree ([#441])
1071
1079
 
1072
1080
  Smell: Category A (dead subsystem) — the creation wizard and config editor are removed per ADR-0004 Decision C; after Step 5 deletes their only importer (`agent-menu.ts`), they and their file-ops helpers are pure orphans.
1073
1081
  This is the second deletion commit (split by subtree).
@@ -1084,6 +1092,10 @@ These files are orphaned by Step 5, so this is a pure `git rm` with no surviving
1084
1092
 
1085
1093
  Outcome: −546 LOC source (wizard + editor + file-ops + file-writer); −948 LOC test; production duplication → 0 lines; 1 production and 1 test clone group eliminated.
1086
1094
 
1095
+ Landed ([#441]): deleted `agent-creation-wizard.ts`, `agent-config-editor.ts`, `agent-file-ops.ts`, `agent-file-writer.ts`, and `menu-ui.ts` (orphaned transient) from `src/ui/`, plus their four test files.
1096
+ `test/helpers/ui-stubs.ts` pruned to `makeMenuUI` only (still consumed by `subagents-settings.test.ts`); `makeFileOps`, `makeMenuManager`, and `createTestSubagentConfig` removed with their `ui-stubs.test.ts` describe blocks.
1097
+ Production duplication: 0 lines (confirmed by `fallow dupes`); `fallow dead-code`: clean. 16 test clone groups remain — Step 7 consolidation target.
1098
+
1087
1099
  `Release: batch "dissolve-agents"`
1088
1100
 
1089
1101
  ### Step 7 — Consolidate remaining test clone families ([#443])
@@ -1111,9 +1123,9 @@ flowchart LR
1111
1123
  S3["✅ Step 3 - Background widget (#444)"]
1112
1124
  S4["✅ Step 4 - Native session nav slice (#445)"]
1113
1125
  S4a["✅ Step 4a - Renderer to TUI components (#462)"]
1114
- S4b["Step 4b - File-snapshot source (#463)"]
1115
- S5["Step 5 - Dissolve /agents + viewer (#442)"]
1116
- S6["Step 6 - Remove definition mgmt (#441)"]
1126
+ S4b["Step 4b - File-snapshot source (#463)"]
1127
+ S5["Step 5 - Dissolve /agents + viewer (#442)"]
1128
+ S6["Step 6 - Remove definition mgmt (#441)"]
1117
1129
  S7["Step 7 - Test clones (#443)"]
1118
1130
 
1119
1131
  S1 --> S4
@@ -248,7 +248,32 @@ This matches the bespoke viewer's current reach (gated on `record.isSessionReady
248
248
  A foreground agent is navigable only _after_ it completes — while it runs, the root turn is blocked on it — whereas a background agent is navigable live.
249
249
  The background widget ([#444]) remains the optional secondary selection gesture for background agents; the command is the primary, unit-testable surface.
250
250
 
251
+ **Evicted-agent candidate set ([#463]).**
252
+ Step 4b realizes the file-snapshot branch for fully-evicted agents.
253
+ The candidate set is broadened via **manager-retained descriptors**, not a directory scan of the tasks directory: the persisted child session carries no subagent `type`/`description` (those live only on the in-memory record), so a scan yields degraded labels and parses every file per picker open.
254
+ The cleanup sweep instead stashes a lightweight `EvictedSubagent` descriptor (label fields + `outputFile`, no messages) before disposing a record, preserving rich labels and bounded memory.
255
+ This covers in-session evictions — the sweep's only targets, since a fresh manager per session never reloads prior-process subagents.
256
+ The "render from the file snapshot" mechanism for an evicted agent (above) is unchanged; only the candidate-set _enumeration_ is pinned to descriptors.
257
+
258
+ ## Addendum 3 (2026-06-23): adopt the `subagents:` colon namespace, superseding Criterion 4
259
+
260
+ This addendum reverses **Criterion 4**, which confirmed flat, hyphenated command names (`/subagents-settings`) and rejected `/subagents:settings`.
261
+ The two registered commands are renamed: `/subagents-settings` → `/subagents:settings` and `/subagent-sessions` → `/subagents:sessions`.
262
+ This is a breaking change to the command surface.
263
+
264
+ **Why revise.**
265
+ Criterion 4 surveyed only in-repo siblings (`agents`, `colgrep-reindex`, `permission-system`) and concluded a `:` namespace would be inconsistent with every existing command.
266
+ That survey missed the broader Pi ecosystem: `@eko24ive/pi-ask` establishes the colon convention with `answer:again` and `ask:replay`, grouping a package's commands under a shared prefix.
267
+ The colon namespace reads as a deliberate grouping gesture (`subagents:settings`, `subagents:sessions` clearly belong to one package) where the hyphen form blurs into an ordinary command name.
268
+ The newer ecosystem signal outweighs the original in-repo-only consistency argument.
269
+
270
+ **Scope.**
271
+ This change is pi-subagents-only.
272
+ Whether the colon convention becomes repo-wide (renaming `colgrep-reindex`, `permission-system`, etc.) is deferred — not decided here.
273
+ `/agents` is intentionally left flat: it is slated for removal in the Phase 18 / Step 5 menu retirement, so namespacing it would be churn on a command being deleted.
274
+
251
275
  [#444]: https://github.com/gotgenes/pi-packages/issues/444
252
276
  [#445]: https://github.com/gotgenes/pi-packages/issues/445
253
277
  [#446]: https://github.com/gotgenes/pi-packages/issues/446
254
278
  [#447]: https://github.com/gotgenes/pi-packages/issues/447
279
+ [#463]: https://github.com/gotgenes/pi-packages/issues/463
@@ -0,0 +1,180 @@
1
+ ---
2
+ issue: 441
3
+ issue_title: "pi-subagents: remove the orphaned agent-definition management subtree"
4
+ ---
5
+
6
+ # Remove the orphaned agent-definition management subtree
7
+
8
+ ## Release Recommendation
9
+
10
+ **Release:** ship now — batch "dissolve-agents" tail (this issue completes the batch)
11
+
12
+ This issue is Phase 19 Step 6, the tail of release batch "dissolve-agents" (Steps 5–6) in `docs/architecture/architecture.md`.
13
+ Step 5 ([#442], commit `cb813f2c`) landed a breaking `feat(pi-subagents)!:` that is still **unreleased** — it sits after the latest tag `pi-subagents-v17.5.0`.
14
+ Landing this tail completes the batch and lets release-please cut the major bump that carries Step 5's `/agents` removal.
15
+
16
+ ## Problem Statement
17
+
18
+ ADR-0004 Decision C removes both agent-definition surfaces: creating a new agent is better done by asking a Pi session directly (more capable than a fixed wizard) or by writing the `.md` file in an editor, and viewing or editing definitions is better served by opening the `.md` files in an editor or IDE.
19
+ Phase 19 Step 5 ([#442]) deleted `agent-menu.ts` — the only importer of the creation wizard, config editor, and their file-ops helpers — so this subtree is now pure dead code.
20
+ This step is the second of two deletion commits in the Phase 19 terminal cut: a clean `git rm` of the orphaned modules, with no surviving references and no edit to any doomed file.
21
+
22
+ ## Goals
23
+
24
+ - Delete the orphaned creation wizard, config editor, and their two file-ops helper modules, plus their tests.
25
+ - Delete the transient `menu-ui.ts` module, orphaned once its only consumers (the wizard and editor) are gone.
26
+ - Prune the now-unused helpers from `test/helpers/ui-stubs.ts`, keeping only the helper a surviving test still uses.
27
+ - Drive the package's remaining production duplication to zero (the 11-line internal clone in `disableAgent`/`ejectAgent` dies with `agent-config-editor.ts`).
28
+ - This is **not** a breaking change at this step: the modules are already unreachable after Step 5, so deleting them changes no observable behavior — the user-facing removal already shipped (unreleased) in Step 5's `feat!:`.
29
+
30
+ ## Non-Goals
31
+
32
+ - No change to `index.ts` — it already references none of the deleted symbols (verified by grep); the dewiring happened in Step 5.
33
+ - No change to the surviving UI modules (`agent-widget.ts`, `display.ts`, `session-navigation.ts`, `session-navigator.ts`, `subagents-settings.ts`, `widget-renderer.ts`).
34
+ - No change to `subagents-settings.ts`, which carries its own `SubagentsSettingsUI` interface and never depended on `MenuUI`.
35
+ - Test clone consolidation (Phase 19 Step 7, [#443]) — runs after this cut so no surviving helper is extracted into a doomed file.
36
+
37
+ ## Background
38
+
39
+ Relevant modules and their current dependency facts (verified against `main`):
40
+
41
+ - `src/ui/agent-creation-wizard.ts` (235 LOC) — `AgentCreationWizard` class; imports `AgentFileOps`, `writeAgentFile`, and `MenuUI` from its siblings.
42
+ - `src/ui/agent-config-editor.ts` (201 LOC) — `AgentConfigEditor` class plus `buildMenuOptions`/`buildEjectContent`; imports `AgentFileOps`, `writeAgentFile`, and `MenuUI`.
43
+ Contains the package's only remaining production clone (the 11-line `disableAgent`/`ejectAgent` block).
44
+ - `src/ui/agent-file-ops.ts` (59 LOC) — `AgentFileOps` interface + `FsAgentFileOps`; only consumers were the wizard and editor.
45
+ - `src/ui/agent-file-writer.ts` (55 LOC) — `writeAgentFile` + narrow interfaces; only consumers were the wizard and editor.
46
+ - `src/ui/menu-ui.ts` (9 LOC) — the `MenuUI` interface, extracted in Step 5's tidy-first prep commit (`bb03efd7`) to break a bidirectional type cycle.
47
+ After this step deletes the wizard and editor, `menu-ui.ts` has zero importers.
48
+ The architecture doc marks it for removal here: its current-state directory listing reads `menu-ui.ts transient: MenuUI interface (removed with wizard/editor in #441)` (line 346), and the Step 5 entry states "The `menu-ui.ts` module is transient and is removed with the wizard/editor in Step 6" (line 1076).
49
+
50
+ Orphan verification (grep across `src/`, excluding the doomed files themselves): **no** surviving importer of any of the five modules or their exported symbols (`AgentCreationWizard`, `AgentConfigEditor`, `FsAgentFileOps`, `writeAgentFile`, `MenuUI`).
51
+ `src/index.ts` references none of them.
52
+
53
+ Test-helper facts (`test/helpers/ui-stubs.ts`), evaluated **after** the four doomed test files are deleted:
54
+
55
+ - `makeMenuUI` — still imported by `test/ui/subagents-settings.test.ts` → **survives**.
56
+ - `makeFileOps` — only remaining importer is its own self-test `ui-stubs.test.ts` → orphan.
57
+ - `makeMenuManager` (including the wizard `spawnAndWait` relay) — only remaining importer is `ui-stubs.test.ts` → orphan.
58
+ - `createTestSubagentConfig` (and its private `DEFAULT_TEST_AGENT_CONFIG`) — only remaining importer is `ui-stubs.test.ts` → orphan.
59
+
60
+ AGENTS.md constraints that apply:
61
+
62
+ - Run `pnpm fallow dead-code` locally before pushing — CI gates on it.
63
+ - Conventional Commits; reference the issue as `(#441)` in the subject, never `Closes #441`.
64
+ - `pnpm` only; package-scoped scripts via `pnpm --filter @gotgenes/pi-subagents`.
65
+
66
+ ## Design Overview
67
+
68
+ This is a deletion-only change — no new collaborators, no shared-interface edits, no behavior moved.
69
+ There is nothing to extract and no decision model beyond "delete the orphans, leave `fallow` clean."
70
+
71
+ Two clarifications where the issue body is less precise than the authoritative architecture doc:
72
+
73
+ 1. **`menu-ui.ts` is in scope.**
74
+ The issue body's "Proposed change" lists only the four modules, but `menu-ui.ts` is orphaned by the same cut and the architecture doc (lines 346, 1076) explicitly schedules its removal here.
75
+ Deleting it in the same commit as the wizard/editor avoids a dangling `import type { MenuUI }` and a `fallow dead-code` flag.
76
+
77
+ 2. **`makeMenuManager` is removed whole, not just its `spawnAndWait` field.**
78
+ The issue body says to prune the "wizard `spawnAndWait` relay," but after the four test files are deleted, `makeMenuManager`'s only remaining caller is its own self-test.
79
+ A test helper whose sole consumer is its own unit test is exactly the residual clutter the Phase 19 cut eliminates, so the whole helper (and its `describe` block) goes.
80
+ The architecture doc's Step 6 phrasing — "delete … `spawnAndWait` from `makeMenuManager` **if no surviving consumer remains**; delete the file outright once all consumers are gone" — licenses this: no real consumer remains.
81
+ `ui-stubs.ts` itself survives because `makeMenuUI` still has a real consumer.
82
+
83
+ End state of `test/helpers/ui-stubs.ts`: a single `makeMenuUI` export plus its file header.
84
+ End state of `test/helpers/ui-stubs.test.ts`: the `makeMenuUI` `describe` block only.
85
+
86
+ Commit-type rationale: deleting already-unreachable code is `refactor(pi-subagents):` — it neither adds a feature nor fixes a bug, and it changes no observable behavior at this step.
87
+ The release is driven by Step 5's unreleased `feat!:` already in the queue, not by this commit's type.
88
+
89
+ ## Module-Level Changes
90
+
91
+ Source (deleted):
92
+
93
+ - `src/ui/agent-creation-wizard.ts` — deleted (235 LOC).
94
+ - `src/ui/agent-config-editor.ts` — deleted (201 LOC); removes the 11-line internal production clone.
95
+ - `src/ui/agent-file-ops.ts` — deleted (59 LOC).
96
+ - `src/ui/agent-file-writer.ts` — deleted (55 LOC).
97
+ - `src/ui/menu-ui.ts` — deleted (9 LOC); orphaned once the wizard and editor are gone.
98
+
99
+ Tests (deleted):
100
+
101
+ - `test/ui/agent-creation-wizard.test.ts` — deleted (296 LOC).
102
+ - `test/ui/agent-config-editor.test.ts` — deleted (392 LOC).
103
+ - `test/ui/agent-file-ops.test.ts` — deleted (112 LOC).
104
+ - `test/ui/agent-file-writer.test.ts` — deleted (148 LOC).
105
+
106
+ Tests (pruned, not deleted):
107
+
108
+ - `test/helpers/ui-stubs.ts` — remove `makeFileOps`, `makeMenuManager`, `createTestSubagentConfig`, and the private `DEFAULT_TEST_AGENT_CONFIG`; keep `makeMenuUI`.
109
+ Also drop the file's `import type { AgentConfig }` — it serves only the removed helpers, and `makeMenuUI` references no package-local type.
110
+ - `test/helpers/ui-stubs.test.ts` — remove the `makeFileOps`, `makeMenuManager`, and `createTestSubagentConfig` `describe` blocks and the now-unused imports; keep the `makeMenuUI` `describe` block.
111
+
112
+ Docs (updated):
113
+
114
+ - `docs/architecture/architecture.md` — in the current-state directory tree (lines ~341–346), remove the five deleted `ui/` entries including the `menu-ui.ts` transient line; add a `Landed` note to the Step 6 entry and mark it ✅, mirroring the Step 5 entry's format.
115
+ - `.pi/skills/package-pi-subagents/SKILL.md` — update the UI domain-table row: module count `11` → `6`, and drop "creation wizard, config editor" from the responsibility summary.
116
+
117
+ Doc-reference grep results (the removed symbols / mechanism):
118
+
119
+ - `docs/plans/*` and `docs/retro/*` and `docs/architecture/history/*` mention the deleted modules only as **historical record** of prior phases (extraction, narrowing, clone removal).
120
+ Per markdown conventions these are immutable records of completed work — do not rewrite them.
121
+ - The only **current-state** docs that describe the live layout are `architecture.md` (directory tree + Step 6 entry) and `SKILL.md` (UI domain row), both listed above.
122
+
123
+ ## Test Impact Analysis
124
+
125
+ This is a deletion, not an extraction, so the standard extraction lenses invert:
126
+
127
+ 1. **New tests enabled:** none — nothing new is created.
128
+ 2. **Tests that become redundant:** all four deleted test files exercised only the deleted modules; they go with their subjects.
129
+ The three pruned `ui-stubs.test.ts` `describe` blocks tested helpers that no longer exist.
130
+ 3. **Tests that must stay as-is:** `test/ui/subagents-settings.test.ts` (the surviving real consumer of `makeMenuUI`) and the `makeMenuUI` `describe` block in `ui-stubs.test.ts` — both genuinely exercise the surviving helper.
131
+
132
+ After the cut, `pnpm --filter @gotgenes/pi-subagents run test` must stay green with the reduced suite.
133
+
134
+ ## Invariants at risk
135
+
136
+ This step touches surfaces that Phase 19 Step 5 ([#442]) and earlier phases refactored, but only by deleting them, so no earlier `Outcome:` is regressed — it is fulfilled:
137
+
138
+ - Step 5's outcome ("`/agents` dissolved; the definition-management leaves orphaned for Step 6") is the precondition this step consumes.
139
+ Verification that the leaves are still orphaned is the grep in Background (no surviving importer) — the standing guarantee that nothing re-wired them between Step 5 landing and this step.
140
+ - The "production duplication → 0 lines" target in the Phase 19 health-metrics table is met when `agent-config-editor.ts` is deleted.
141
+ Pin: `pnpm fallow dupes` after the cut shows no production clone group.
142
+
143
+ No green-suite regression risk exists because no surviving code path is modified; the type checker and `fallow dead-code` are the guards that the deletion is complete and clean.
144
+
145
+ ## Step Order
146
+
147
+ This is a pure-deletion plan with no red→green cycles, so it routes to `/build-plan`, not `/tdd-plan`.
148
+ Two commits, ordered for reviewability.
149
+
150
+ 1. **Remove the orphaned subtree and prune the test helpers.**
151
+ `git rm` the five source modules and four test files; prune `test/helpers/ui-stubs.ts` and `test/helpers/ui-stubs.test.ts` to `makeMenuUI` only.
152
+ The `menu-ui.ts` deletion and the four-module deletion go together — deleting them in one commit means no dangling `import type { MenuUI }` ever exists at the type-check boundary.
153
+ The helper prune rides in the same commit as the test-file deletion that orphans the helpers, so `fallow dead-code` sees a consistent state.
154
+ Verify: `pnpm --filter @gotgenes/pi-subagents run check`, `… run test`, `pnpm fallow dead-code`, and `pnpm fallow dupes` (expect no production clone group) all green.
155
+ Commit: `refactor(pi-subagents): remove orphaned agent-definition management subtree (#441)`.
156
+
157
+ 2. **Update the current-state docs.**
158
+ Edit `docs/architecture/architecture.md` (directory tree + Step 6 `Landed`/✅ note) and `.pi/skills/package-pi-subagents/SKILL.md` (UI domain row count + summary).
159
+ Verify: `pnpm run lint` (rumdl) green.
160
+ Commit: `docs(pi-subagents): record agent-definition subtree removal (#441)`.
161
+
162
+ ## Risks and Mitigations
163
+
164
+ - **Risk:** a non-obvious importer of one of the five modules exists and the deletion breaks the type check.
165
+ **Mitigation:** the Background grep already confirms zero `src/` importers and `index.ts` is clean; the Step 1 `check` is the backstop.
166
+ - **Risk:** pruning `ui-stubs.ts` removes a helper a surviving test still imports.
167
+ **Mitigation:** verified `makeMenuUI` is the only helper imported outside the doomed test files (by `subagents-settings.test.ts`); it is explicitly kept.
168
+ - **Risk:** deleting `menu-ui.ts` was not anticipated by the issue body and could be seen as scope creep.
169
+ **Mitigation:** it is mandated by the architecture doc (lines 346, 1076) and is a forced consequence of the orphan analysis; documented in Design Overview.
170
+ - **Risk:** `refactor:` commit type fails to trigger the batch release.
171
+ **Mitigation:** Step 5's unreleased `feat(pi-subagents)!:` (`cb813f2c`, after `v17.5.0`) is already queued; release-please cuts the major bump on the next release regardless of this commit's type.
172
+ `/ship-issue` reads the `**Release:** ship now — batch tail` marker and releases.
173
+
174
+ ## Open Questions
175
+
176
+ None.
177
+ The two interpretation points (deleting `menu-ui.ts`; removing `makeMenuManager` whole) are resolved in Design Overview against the authoritative architecture doc and orphan analysis, not deferred.
178
+
179
+ [#442]: https://github.com/gotgenes/pi-packages/issues/442
180
+ [#443]: https://github.com/gotgenes/pi-packages/issues/443
@@ -0,0 +1,195 @@
1
+ ---
2
+ issue: 442
3
+ issue_title: "pi-subagents: dissolve /agents and remove the conversation-viewer subtree"
4
+ ---
5
+
6
+ # Dissolve `/agents` and remove the conversation-viewer subtree
7
+
8
+ ## Release Recommendation
9
+
10
+ **Release:** mid-batch — defer (batch "dissolve-agents"); confirm at ship time
11
+
12
+ This is Phase 19 Step 5, the first of the two deletion commits in release batch "dissolve-agents" (Steps 5–6).
13
+ The batch tail is Step 6 ([#441]); per the architecture roadmap's `Release batches` subsection the two ship together, and the operator has confirmed: do not release until both [#442] and [#441] have landed on `main`.
14
+ Hold the release-please PR open after this issue merges; the release is cut when [#441] (the tail) lands.
15
+
16
+ ## Problem Statement
17
+
18
+ Phase 19 Steps 2–4 re-homed all four `/agents` menu responsibilities: settings moved to the `/subagents:settings` command, running-agent visibility moved to the background widget, and session viewing moved to native session navigation (`/subagents:sessions`).
19
+ With those replacements live, the `/agents` command and everything reachable only from `agent-menu.ts` is an orphaned subtree.
20
+ This issue performs the first of two terminal-cut deletions: dissolve the `/agents` command and delete the conversation-viewer subtree (`agent-menu.ts`, `conversation-viewer.ts`, `message-formatters.ts`, and their tests).
21
+ Deleting the hub `agent-menu.ts` wholesale — rather than surgically narrowing it once per option — is what orphans the definition-management leaves, so the hub must go first (it statically imports the wizard, editor, and file-ops, and dynamically imports the viewer).
22
+
23
+ ## Goals
24
+
25
+ - Remove the `/agents` slash command and its menu hub (`agent-menu.ts`).
26
+ - Delete the conversation-viewer subtree: `conversation-viewer.ts` (the bespoke session overlay) and `message-formatters.ts` (its only consumer), plus all three tests.
27
+ - Dewire `index.ts`: drop the `registerCommand("agents", …)` block, the `AgentsMenuHandler` and `FsAgentFileOps` imports/construction, and the now-dead `join` and `buildParentSnapshot` imports.
28
+ - Keep `pnpm run check`, `pnpm run lint`, `pnpm run test`, and `pnpm fallow dead-code` green at every commit by breaking the hub↔leaf type cycle first (see Design Overview).
29
+ - Leave the agent-definition-management leaves (`agent-creation-wizard.ts`, `agent-config-editor.ts`, `agent-file-ops.ts`, `agent-file-writer.ts`) orphaned but compiling, for [#441] to `git rm`.
30
+
31
+ This change is **breaking**: removing the `/agents` command alters observable behavior on upgrade with no user edit.
32
+ The deletion commit uses `feat(pi-subagents)!:` with a `BREAKING CHANGE:` footer naming the replacements (`/subagents:settings`, `/subagents:sessions`, the background widget).
33
+
34
+ ## Non-Goals
35
+
36
+ - Deleting the agent-definition-management subtree (`agent-creation-wizard.ts`, `agent-config-editor.ts`, `agent-file-ops.ts`, `agent-file-writer.ts`) and the transient `menu-ui.ts` — that is [#441] (Step 6), the batch tail.
37
+ - Consolidating residual test clone families — that is [#443] (Step 7), which runs after the cut.
38
+ - Cleaning up `test/helpers/ui-stubs.ts` (`makeFileOps`, `makeMenuManager`, `createTestSubagentConfig`) — its helpers still have surviving consumers (the wizard/editor tests) until [#441].
39
+ - The holistic architecture-doc refresh (health-metrics final numbers, the domain Mermaid diagram, the complexity tables, migrating Phase 19 to `docs/architecture/history/`) — deferred to the batch tail [#441] to avoid editing the same analytical tables twice, since they also reference files [#441] deletes.
40
+
41
+ ## Background
42
+
43
+ Relevant modules and their current coupling:
44
+
45
+ - `src/ui/agent-menu.ts` (331 LOC) — the `AgentsMenuHandler` god-command; statically imports `AgentConfigEditor` and `AgentCreationWizard` (constructs them), and dynamically imports `ConversationViewer` in `viewAgentConversation`.
46
+ Defines three exported interfaces: `AgentMenuManager`, `AgentMenuSettings`, and `MenuUI`.
47
+ - `src/ui/conversation-viewer.ts` (241 LOC) — the bespoke scrollable session overlay; its only consumer is `agent-menu.ts`'s dynamic `import("./conversation-viewer")`.
48
+ - `src/ui/message-formatters.ts` (195 LOC) — pure per-message-type formatters; its only consumer is `ConversationViewer`.
49
+ - `src/index.ts` — registers the `/agents` command, constructs `AgentsMenuHandler` (wiring in `FsAgentFileOps` and the two agents dirs), and uses `join` + `buildParentSnapshot` only inside that block.
50
+
51
+ The hub↔leaf type cycle (the key constraint):
52
+
53
+ - `agent-menu.ts` value-imports the wizard and editor classes.
54
+ - `agent-creation-wizard.ts` and `agent-config-editor.ts` each `import type { MenuUI } from "#src/ui/agent-menu"` and use `MenuUI` as a parameter type throughout.
55
+
56
+ This is a bidirectional cycle: the hub imports the leaf classes; the leaves import the hub's `MenuUI` type.
57
+ Deleting either subtree first leaves the other half referencing a deleted module, so `tsc --noEmit` (which type-checks all of `src` + `test`) fails.
58
+ The issue's premise that the leaves become "pure orphans" once the hub is gone holds for *runtime* reachability but not at the *type* level — the `MenuUI` back-import keeps them coupled.
59
+
60
+ Constraints from AGENTS.md / package skill:
61
+
62
+ - Each commit must leave the repo in a valid state (`pnpm run check` green).
63
+ - This package builds public `.d.ts` bundles; none of the deleted modules are part of the public surface (`service.ts`, `layered-settings.ts`), so no `verify:public-types` impact.
64
+ - `MenuUI`, `AgentMenuManager`, `AgentMenuSettings` are internal — not exported from any package subpath.
65
+
66
+ ## Design Overview
67
+
68
+ Resolve the cycle with a **tidy-first** preparatory move (per the operator's decision and the `code-design` skill's "preparatory refactoring"): relocate the `MenuUI` interface to its own surviving module before deleting the hub.
69
+
70
+ Only `MenuUI` needs to survive the cut — `AgentMenuManager` and `AgentMenuSettings` have no consumers outside the hub (verified) and die with it.
71
+ `MenuUI` is self-contained (its members reference only SDK-shaped primitives), so the extracted module carries no upstream-dependency baggage and introduces no Tell-Don't-Ask or output-argument smell.
72
+
73
+ New module `src/ui/menu-ui.ts`:
74
+
75
+ ```typescript
76
+ /** Narrow UI interface — only the ctx.ui methods menu handlers actually call. */
77
+ export interface MenuUI {
78
+ select(title: string, options: string[]): Promise<string | undefined>;
79
+ confirm(title: string, message: string): Promise<boolean>;
80
+ input(title: string, defaultValue?: string): Promise<string | undefined>;
81
+ notify(message: string, level: "info" | "warning" | "error"): void;
82
+ editor(title: string, content: string): Promise<string | undefined>;
83
+ custom<R>(component: any, options?: any): Promise<R>;
84
+ }
85
+ ```
86
+
87
+ Consumer call sites after the move (the leaves import the relocated type unchanged):
88
+
89
+ ```typescript
90
+ // agent-creation-wizard.ts / agent-config-editor.ts
91
+ import type { MenuUI } from "#src/ui/menu-ui";
92
+ async showCreateWizard(ui: MenuUI, parentSnapshot: ParentSnapshot): Promise<void> { … }
93
+ ```
94
+
95
+ `menu-ui.ts` is **transient**: after this issue it is imported only by the wizard and editor (both alive until [#441]), so it has live consumers and stays off the fallow dead-code list.
96
+ [#441] deletes the wizard, editor, and `menu-ui.ts` together, so the transient module never outlives its consumers.
97
+
98
+ Two-commit sequence within this issue:
99
+
100
+ 1. `refactor(pi-subagents): extract MenuUI to its own module` — pure move; repoints the hub, wizard, and editor imports.
101
+ Green.
102
+ 2. `feat(pi-subagents)!: dissolve /agents and remove the conversation-viewer subtree` — delete the three source files + three tests, dewire `index.ts`, update docs.
103
+ Green (wizard/editor now import `MenuUI` from the surviving `menu-ui.ts`; the hub is gone).
104
+
105
+ Edge cases / verifications already confirmed:
106
+
107
+ - `subagents-settings.ts` defines its own `SubagentsSettingsUI` interface — it does **not** import `MenuUI`, so the relocation does not touch the surviving settings command.
108
+ - `test/helpers/ui-stubs.ts`'s `makeMenuUI` is structurally typed and does **not** import the `MenuUI` type, so no test-helper repointing is needed.
109
+ - After dewiring, `join` (node:path) and `buildParentSnapshot` are used nowhere else in `index.ts` (verified) and their imports are removed; `getAgentDir`, `process.cwd`, `registry`, `settings`, and `manager` retain other live uses and stay.
110
+ - `FsAgentFileOps` becomes production-unused after the `index.ts` construction is removed, but `test/ui/agent-file-ops.test.ts` still imports it, so fallow (syntactic import analysis) keeps it off the dead-code list until [#441].
111
+ - Deleting the consumers does not orphan any local export: `formatDuration`/`getDisplayName`/`getModelLabelFromConfig` retain other consumers, and `wrapTextWithAnsi` is an external `@earendil-works/pi-tui` import.
112
+
113
+ ## Module-Level Changes
114
+
115
+ Commit 1 — extract `MenuUI` (refactor):
116
+
117
+ - Add `src/ui/menu-ui.ts` — the `MenuUI` interface (moved verbatim from `agent-menu.ts`).
118
+ - `src/ui/agent-menu.ts` — remove the `MenuUI` interface definition; import `MenuUI` from `#src/ui/menu-ui`.
119
+ - `src/ui/agent-creation-wizard.ts` — change `import type { MenuUI } from "#src/ui/agent-menu"` to `from "#src/ui/menu-ui"`.
120
+ - `src/ui/agent-config-editor.ts` — same import repoint.
121
+
122
+ Commit 2 — dissolve `/agents` and delete the viewer subtree (feat!):
123
+
124
+ - Delete `src/ui/agent-menu.ts`, `src/ui/conversation-viewer.ts`, `src/ui/message-formatters.ts`.
125
+ - Delete `test/ui/agent-menu.test.ts`, `test/conversation-viewer.test.ts`, `test/message-formatters.test.ts`.
126
+ - `src/index.ts`:
127
+ - Remove the `import { FsAgentFileOps } from "#src/ui/agent-file-ops"` and `import { AgentsMenuHandler } from "#src/ui/agent-menu"` lines.
128
+ - Remove the now-dead `import { join } from "node:path"` and `import { buildParentSnapshot } from "#src/lifecycle/parent-snapshot"` lines.
129
+ - Remove the `// ---- /agents interactive menu ----` comment, the `agentsMenu` construction, and the `registerCommand("agents", …)` block.
130
+ - Remove the `/agents — Interactive agent management menu` line from the top-of-file `Commands:` doc comment.
131
+ - `packages/pi-subagents/docs/architecture/architecture.md` — update the current-state `ui/` file tree (remove the `agent-menu.ts`, `conversation-viewer.ts`, `message-formatters.ts` entries; add a `menu-ui.ts` entry), and annotate the Step 5 roadmap entry's `Outcome:` to record the actual approach (the `MenuUI` relocation prep; `index.ts` import-removal also drops `join`/`buildParentSnapshot`).
132
+ The structural-analysis tables, domain Mermaid diagram, and health-metrics numbers are deferred to the batch tail [#441] (see Non-Goals).
133
+ - `.pi/skills/package-pi-subagents/SKILL.md` — update the UI domain row: count `13` → `11`, and drop "conversation viewer, /agents menu" from the responsibility description (keep "creation wizard, config editor" — those survive until [#441]).
134
+
135
+ The Step 5 `Outcome:` line in `architecture.md` currently asserts "no edit to doomed files" and "`index.ts` edited once."
136
+ Both are now slightly inaccurate: the tidy-first prep repoints the doomed wizard/editor `MenuUI` import (one line each), and `index.ts` also sheds two now-dead imports.
137
+ The annotation should reflect this, not leave the stale claim.
138
+
139
+ ## Test Impact Analysis
140
+
141
+ This is a deletion, not an extraction-for-testability, so no new unit tests are enabled.
142
+
143
+ 1. New tests enabled: none.
144
+ 2. Tests that become redundant / removed: `test/ui/agent-menu.test.ts`, `test/conversation-viewer.test.ts`, `test/message-formatters.test.ts` (the largest test function by LOC) — they exercise deleted production code and are deleted with it.
145
+ 3. Tests that must stay as-is: the wizard/editor tests (`test/ui/agent-creation-wizard.test.ts`, `test/ui/agent-config-editor.test.ts`) keep compiling against the relocated `MenuUI` and survive until [#441]; `test/ui/subagents-settings.test.ts`, the session-navigation tests, and `test/ui/agent-widget.test.ts` pin the replacement surfaces and must stay green (see Invariants at risk).
146
+
147
+ ## Invariants at risk
148
+
149
+ The cut removes surfaces whose responsibilities Steps 2–4 already re-homed.
150
+ Each replacement's invariant must remain green after this deletion:
151
+
152
+ - Settings management (Step 2, [#447]) → pinned by `test/ui/subagents-settings.test.ts`.
153
+ The `/subagents:settings` command and `SubagentsSettingsHandler` are untouched here.
154
+ - Running-agent visibility (Step 3, [#444]) → pinned by `test/ui/agent-widget.test.ts`.
155
+ The background widget is untouched.
156
+ - Session viewing (Step 4 / 4a, [#445]) → pinned by the session-navigation / session-navigator tests.
157
+ The `/subagents:sessions` command is untouched.
158
+
159
+ The deletion touches none of those files, so the full suite (minus the three deleted tests) staying green is the verification that no replacement regressed.
160
+
161
+ ## Implementation Order
162
+
163
+ This issue has no red→green test cycles (a pure interface move plus deletions verified by the existing suite), so it is a build-style change — the next step is `/build-plan`, not `/tdd-plan`.
164
+
165
+ 1. `refactor(pi-subagents): extract MenuUI to its own module`
166
+ - Add `src/ui/menu-ui.ts`; remove the interface from `agent-menu.ts` and import it; repoint the wizard and editor imports.
167
+ - Verify: `pnpm run check`, `pnpm run lint`, `pnpm run test`, `pnpm fallow dead-code` all green.
168
+ 2. `feat(pi-subagents)!: dissolve /agents and remove the conversation-viewer subtree`
169
+ - Delete the three source files and three tests; dewire `index.ts`; update `architecture.md` file tree + Step 5 `Outcome:`; update `SKILL.md` UI row.
170
+ - `BREAKING CHANGE:` footer: the `/agents` command is removed; its responsibilities are served by `/subagents:settings` (configure concurrency/turn limits), `/subagents:sessions` (read-only transcript viewing), and the always-on background widget (running-agent visibility).
171
+ - Verify: `pnpm run check`, `pnpm run lint`, `pnpm run test`, `pnpm fallow dead-code` green; confirm `/agents` no longer registers and `menu-ui.ts` retains its wizard/editor consumers.
172
+
173
+ ## Risks and Mitigations
174
+
175
+ - Risk: deleting the hub before the leaves breaks `tsc` via the `MenuUI` back-import.
176
+ Mitigation: the tidy-first Commit 1 relocates `MenuUI` to a surviving module so Commit 2 compiles; verified that only the wizard and editor consume `MenuUI` and that `subagents-settings.ts` and `ui-stubs.ts` do not.
177
+ - Risk: `FsAgentFileOps` becomes production-unused and trips `fallow dead-code`.
178
+ Mitigation: verified `test/ui/agent-file-ops.test.ts` still imports it; fallow's syntactic import analysis keeps it live until [#441].
179
+ Run `pnpm fallow dead-code` after Commit 2 to confirm.
180
+ - Risk: the transient `menu-ui.ts` looks like speculative indirection.
181
+ Mitigation: it is short-lived by design (one issue), has two live consumers immediately, and is deleted by the batch tail [#441]; the alternative (inlining a throwaway type into doomed files, or merging [#441] into [#442]) was considered and rejected via the operator decision.
182
+ - Risk: stale architecture docs mid-batch (the domain diagram and tables still show the deleted modules between [#442] and [#441]).
183
+ Mitigation: accepted deliberately — the analytical-table refresh is batched into the tail [#441] to avoid double-editing tables that [#441] also touches; the current-state file tree and SKILL.md count are kept accurate at each commit.
184
+
185
+ ## Open Questions
186
+
187
+ None.
188
+ The hub↔leaf type-cycle resolution (relocate `MenuUI`, keep two commits) and the release-timing (defer until [#441] lands) were settled with the operator during planning.
189
+
190
+ [#441]: https://github.com/gotgenes/pi-packages/issues/441
191
+ [#442]: https://github.com/gotgenes/pi-packages/issues/442
192
+ [#443]: https://github.com/gotgenes/pi-packages/issues/443
193
+ [#444]: https://github.com/gotgenes/pi-packages/issues/444
194
+ [#445]: https://github.com/gotgenes/pi-packages/issues/445
195
+ [#447]: https://github.com/gotgenes/pi-packages/issues/447