- Rename spec doc to 2026-06-15_pi-goals.md, update title - Update review.md spec reference - Rename piPlanExtension -> piGoalsExtension in src/index.ts - Add 120s timeout to judge subprocess (was unbounded, caused hang) - Change planInjection heading from 'Goals (goals.md):' to '.pi/goals.md:' - Add FIXMEs for tool label, progress visibility, heading format
3.7 KiB
Code review against spec docs/spec/2026-06-15_pi-goals.md.
(A) SPEC MISMATCH — code does not match spec intent
-
No loop judge (spec §9, §3b). The extension lacks any per‑turn evaluation that would decide continue/pause; the loop‑judge prompt (
loopJudgeSystem,loopJudgeUser) is defined but never invoked. No motion. -
/goalcommand missing (spec §7). No handler for/goal(restart loop, pause, resume, clear, status). The only command is/plan. -
/subgoalcommand missing (spec §7). Not implemented. -
CancelGoaltool not implemented (spec §5, optional but present in spec). Not a blocker but a gap. -
Plan‑phase model selection (D12) not implemented.
planDraftingalways runs on the default model; there is no sticky per‑phase model choice, no selection menu, and no persisting of a plan‑phase model reference. -
Widget does not flag
donegoals that lack a sign‑off log line (spec §7, §6). The widget hides all done goals unconditionally; the visibility guard is missing. -
/plan(no args) does not render the task‑list widget (spec §7).showPlan()dumps raw file content vianotify; the widget is only set throughupdateWidget()on other events, not by the command itself. -
Injection message role (spec §11). The
before_agent_starthook returns acustomTypemessage withdisplay: false. The spec demands a late user‑role message to avoid system‑prompt mutation; the actual message role depends on the pi API and may be system, not user, risking cache breakage. -
Missing pre‑compact hook (spec §8). No
pre‑compacthook to flush any in‑memory state (even just ensuringplan.mdis up‑to‑date) before compaction. -
Reminder cadence deviates (spec §8a). The spec calls for firing after N file‑modifying turns since last
plan.mdupdate. The code fires ifplan.mdis byte‑identical between agent starts, which is a coarser proxy.
(B) DEAD/UNUSED CODE
| File | Lines | Reason |
|---|---|---|
src/prompts.ts |
128‑146 | loopJudgeSystem and loopJudgeUser exported but never used. |
src/prompts.ts |
115‑118 | continuation exported but never used (the loop is not built). |
(C) OVERLY LONG OR REDUNDANT COMMENTS
The file‑header comments in index.ts (lines 1‑20) and plan‑file.ts (lines 1‑26) are fairly concise descriptions of the design; they are not excessive. No comment bloat worth flagging.
(D) OVER‑ENGINEERING vs. “super simple” goal
None. The line‑scanner in plan‑file.ts is minimal; the getPiInvocation() helper is a straightforward copy from the oracle extension; no unnecessary abstraction or defensive layers.
(E) REAL BUGS
-
cmdCtx.newSessioncast risk (src/index.ts:272, 201).
reviewLoopcastsctx(typeExtensionContext) toExtensionCommandContextto pass tostartExecution, which callscmdCtx.newSession(...). If the concrete context does not carry that method, it fails at runtime. (In practice the same object may satisfy it, but the cast hides the truth.) -
showPlanraw content instead of widget (src/index.ts:136‑143).
/planwith no arguments shows the file content viactx.ui.notify, not the structured task‑list widget the spec expects. The widget is rendered separately viaupdateWidget, but the command does not trigger it, so the output is inconsistent.
No other obvious logic errors; the sign‑off flow, logging, and parsing work as intended.
Verdict: A clean scaffold for the sign‑off path, but missing the autonomous loop, /goal command, and plan‑phase model selection means it’s not yet the “work autonomously” extension the spec describes.