--- issue: 126 issue_title: "refactor: extract ExtensionPaths value object from ExtensionRuntime" --- # Retro: #126 — extract ExtensionPaths value object ## Final Retrospective (2026-05-08T00:20:00Z) ### Session summary Extracted six immutable path fields from `ExtensionRuntime` into a new `ExtensionPaths` interface and `computeExtensionPaths()` factory in `src/extension-paths.ts`. Updated `ExtensionRuntime` to `extends ExtensionPaths`, delegated path computation in `createExtensionRuntime`, and narrowed `HandlerDeps.piInfrastructureDirs` to `readonly string[]`. Shipped as v5.7.0 with zero behavioral change. 11 new unit tests; total suite 1245 tests across 55 files. ### Observations #### What went well - **Plan-to-ship pipeline was smooth.** Three phases (plan → TDD → ship) completed in a single session with no rework. The plan's risk table predicted the exact `readonly string[]` assignability issue and the `discoverGlobalNodeModulesRoot` mock-interception strategy, both of which played out as described. - **Transitive mock interception worked cleanly.** The existing `vi.mock("../src/node-modules-discovery")` in `runtime.test.ts` continued to intercept correctly through `computeExtensionPaths`, avoiding any mock-target migration. The plan listed this as the simpler of two options and it proved correct. #### What caused friction (agent side) - `missing-context` — The plan's Module-Level Changes section listed `src/handlers/types.ts` as "Unchanged" but the `readonly string[]` narrowing of `piInfrastructureDirs` in `ExtensionPaths` made `HandlerDeps.piInfrastructureDirs: string[]` incompatible at the assignment site in `src/index.ts`. Caught by `pnpm run build` during cycle 2. Impact: one extra edit to `src/handlers/types.ts` folded into the refactor commit — no rework, added ~30 seconds. Self-identified via compiler output. #### What caused friction (user side) - None observed.