pi-goal-list-loop-audit 0.35.13 → 0.35.64

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.
Files changed (55) hide show
  1. package/CHANGELOG.md +977 -0
  2. package/INSTALL.md +13 -3
  3. package/LIST-PHILOSOPHY.md +90 -0
  4. package/PLAN.md +316 -0
  5. package/README.md +201 -26
  6. package/docs/DESIGN-subagent-visibility.md +76 -0
  7. package/docs/DESIGN.md +59 -8
  8. package/docs/GLLA-POSITIONING-AND-DECOMPOSITION-2026-08-08.md +6 -1
  9. package/docs/INDEX.md +4 -0
  10. package/docs/VISION-ASSIST.md +2 -2
  11. package/extensions/auditor-extensions.ts +289 -0
  12. package/extensions/context-hygiene.ts +129 -0
  13. package/extensions/faulty-objective-recovery.ts +24 -0
  14. package/extensions/glla-state-root.ts +99 -0
  15. package/extensions/goal-agents-panel.ts +211 -0
  16. package/extensions/goal-commands.ts +226 -10
  17. package/extensions/goal-continuation.ts +119 -21
  18. package/extensions/goal-heartbeat.ts +560 -35
  19. package/extensions/goal-loop-auditor-process.ts +126 -4
  20. package/extensions/goal-loop-auditor.ts +3 -5
  21. package/extensions/goal-loop-backoff.ts +79 -0
  22. package/extensions/goal-loop-core.ts +197 -15
  23. package/extensions/goal-loop-dispatch.ts +3 -2
  24. package/extensions/goal-loop-display.ts +141 -8
  25. package/extensions/goal-loop-forever.ts +52 -3
  26. package/extensions/goal-loop-shield.ts +132 -26
  27. package/extensions/goal-loop-stats.ts +3 -2
  28. package/extensions/goal-loop.ts +101 -4
  29. package/extensions/goal-recovery.ts +8 -2
  30. package/extensions/goal-settings.ts +61 -14
  31. package/extensions/goal-state.ts +20 -0
  32. package/extensions/loops/goal-activation.ts +426 -45
  33. package/extensions/loops/goal-auditor-hooks.ts +39 -3
  34. package/extensions/loops/goal-auditor-surface.ts +32 -0
  35. package/extensions/loops/goal-list-queue.ts +72 -12
  36. package/extensions/loops/goal-orchestrator.ts +33 -1
  37. package/extensions/loops/goal-runtime-globals.ts +5 -0
  38. package/extensions/loops/goal-session.ts +68 -8
  39. package/extensions/loops/goal-settings-ui.ts +116 -5
  40. package/extensions/loops/goal-tools.ts +104 -29
  41. package/extensions/loops/goal-ui.ts +106 -1
  42. package/extensions/loops/goal.ts +7 -7
  43. package/extensions/main-model-recovery.ts +10 -0
  44. package/extensions/multi-model-picker.ts +45 -7
  45. package/extensions/payload-guard.ts +172 -0
  46. package/extensions/reviewer.ts +3 -1
  47. package/extensions/settings-menu.ts +39 -4
  48. package/package.json +9 -3
  49. package/prompts/goal-loop-plan-loop.md +31 -0
  50. package/prompts/goal-loop-plan.md +51 -0
  51. package/schemas/goal.schema.json +4 -1
  52. package/scripts/auditor-extension-fixture.mjs +19 -0
  53. package/scripts/goal-auditor-launch.mjs +19 -1
  54. package/scripts/goal-auditor-worker.mjs +15 -0
  55. package/scripts/verify-auditor-extensions-offline.mjs +72 -0
package/README.md CHANGED
@@ -8,9 +8,9 @@ The auditor runs in a fresh extension-less pi RPC process with no extensions, sk
8
8
 
9
9
  This is a detached process, not a nested session in the main pi process. `complete_goal` returns after writing the claim and job request; the status surface shows `auditor queued`, `auditor running`, or `audit recovery pending` while the worker runs or awaits a fresh lifecycle.
10
10
 
11
- On Windows, npm installs the `pi.cmd` shim rather than a directly executable `pi` binary. The auditor launches it through an explicitly quoted `cmd.exe` boundary; POSIX keeps direct shell-less execution. Protocol snapshots also tolerate transient Windows file-locks without deleting the last valid snapshot first.
11
+ On Windows, npm installs the `pi.cmd` shim rather than a directly executable `pi` binary. The auditor launches it through an explicit `cmd.exe` boundary; arguments are quoted only when tokenization requires it (v0.35.27 — quoting a bare executable name breaks `.CMD` shim resolution on pnpm installs), and every argument passes the unsafe-character gate (`%`, CR, LF) before that decision. POSIX keeps direct shell-less execution. Protocol snapshots also tolerate transient Windows file-locks without deleting the last valid snapshot first.
12
12
 
13
- **Current package version:** `v0.35.13` — use `/glla version` to see the installed version and the command for comparing it with the registry latest. This checkout may contain unreleased changes; the npm registry is authoritative for published versions.
13
+ **Current package version:** `v0.35.64` — use `/glla version` to see the installed version and the command for comparing it with the registry latest. This checkout may contain unreleased changes; the npm registry is authoritative for published versions.
14
14
 
15
15
  ## Why this exists
16
16
 
@@ -44,6 +44,7 @@ Five top-level commands — `/goal`, `/list`, `/loop`, `/glla`, `/review`:
44
44
  /goal "audit the repo" # no contract clause → agent grills you first (propose is gated on it)
45
45
  /goal "Step 1. Step 2. Done when: tests pass." # has contract → starts now
46
46
  /goal start "fix the flaky login test" # explicit skip-draft: starts now, no interview (auditor infers the contract)
47
+ /goal plan "build a greenfield crawler" # extended draft for greenfield/megaplan work: research-first, multi-round interview, structured expanded objective — still Confirm-gated (v0.35.33)
47
48
  /goal status # show state
48
49
  /goal pause # pause
49
50
  /goal resume # resume
@@ -53,7 +54,7 @@ Five top-level commands — `/goal`, `/list`, `/loop`, `/glla`, `/review`:
53
54
  /goal verify # queue a detached auditor for the current goal — no agent turn (v0.28.27, renamed from /goal audit in v0.29.8)
54
55
  /goal tweak "<new objective>" # edit in place (Confirm dialog)
55
56
  /goal archive # archived goals, newest first
56
- /glla # settings UI table · actions include /glla version · /glla status · /glla stats · /glla audits [N|full] · /glla cancel (cancel the active objective) · /glla postaudit · /glla wipe (idempotent all-live-state reset, Confirm-gated)
57
+ /glla # settings UI table · actions include /glla version · /glla status · /glla stats · /glla audits [N|full] · /glla agents (tracked-subagent panel; --tail <id> reads a child transcript read-only) · /glla pause (freeze ALL supervisor automation — active work keeps running) · /glla cancel (cancel the active objective) · /glla postaudit · /glla wipe (idempotent all-live-state reset, Confirm-gated)
57
58
  /list fix the login bug, add dark mode, write docs # dump it — the agent shapes it into items, one Confirm
58
59
  /list plan.md # file detected → bulk import, one Confirm (sisyphus/Ralph style)
59
60
  /list <paste a checklist> # multi-line paste → same batch flow
@@ -74,7 +75,9 @@ matches `/list show`.
74
75
  /list remove <n> # drop item n from the list
75
76
  /list clear # empty the list
76
77
  /list cancel # stop the whole list: abort the active item + drop all waiting
78
+ /list plan "a greenfield blog engine" # extended draft: deep research + multi-round interview, then ONE Confirm proposes the whole items[] batch (v0.35.33)
77
79
  /loop # draft the loop (agent grills; measure is test-run before you confirm)
80
+ /loop plan # extended loop draft: deep research + multi-round metric design (v0.35.33)
78
81
  /loop start "keep polishing the UI" # infinite metricless loop (v0.23.6): no plateau, no cap — ends at time=/tokens= or /loop stop
79
82
  /loop respec # infinite metricless loop reconciling the codebase against the root SPEC.md / spec.md (v0.24.3) — 2 specs = you pick, 0 specs = drafting, 1 spec = auto-start (v0.24.4)
80
83
  /loop audit # project-audit loop (v0.29.0): each iteration audits fresh, appends findings to .pi-glla/audit-loop/findings.md, fixes the top ones — the orchestrator counts open findings and the plateau stop ends it when the well is dry (one-shot version: /goal audit)
@@ -87,6 +90,22 @@ matches `/list show`.
87
90
  /review <goal-id> [off|on|auto|aggressive] # re-review an archived goal (bypasses the trigger gates)
88
91
  ```
89
92
 
93
+ ### What the verbs mean
94
+
95
+ The same verb can mean different things on each surface — and `audit` is
96
+ deliberately three different machines:
97
+
98
+ | | **draft** (bare / text arg) | **start** | **plan** | **audit** |
99
+ |---|---|---|---|
100
+ | `/goal` | agent interviews you, one Confirm | skip the interview, start now | **extended draft**: research-first, multi-round interview, structured expanded objective — still ONE Confirm (v0.35.33) | **one-shot project audit**: a single collect-then-fix pass as an ordinary audited goal; findings are fixed in that pass, DECIDE findings come to you untouched |
101
+ | `/list` | batch-drafts your items into ONE confirmed queue | *(use drafting or direct adds)* | **extended draft for greenfield queues**: deep research + interview proposes the whole items[] batch (v0.35.33). Prose only — a file path stays bulk import (`/list plan.md` imports as-is); inside `/list plan`, files you mention become research input, never auto-imported | **collect, then drain**: queues an item that CHANGES NO CODE — it only appends findings to `.pi-glla/audit-loop/findings.md`; on completion each open finding becomes its own list item, drained fix-by-fix with its own audit (v0.31.0) |
102
+ | `/loop` | drafts the loop; your measure is test-run before Confirm | start a loop directly from args | **extended loop draft**: deep research + multi-round metric design before anything runs (v0.35.33) | **forever audit cadence** (v0.29.0): each iteration audits fresh and fixes the top findings; the plateau stop ends it when the well is dry |
103
+
104
+ Related but distinct: **`/goal verify`** audits the CURRENT goal's work right
105
+ now (detached auditor, no agent turn) — it does not survey the project.
106
+ One audit initiative per session: starting a second kind warns about
107
+ superseding the first.
108
+
90
109
  **Metricless loops** (`measure=none`): for genuinely endless work — an
91
110
  ever-improving spec, continuous hardening — where no number means "better".
92
111
  There is **no plateau stop** (nothing to stall on): the loop ends only at
@@ -117,7 +136,11 @@ grilled by the agent (proposing is mechanically blocked until you have
117
136
  replied at least once — typed chat or an answered `ask_user_question` dialog
118
137
  both count), args-with-a-clause start instantly, `/goal start` skips the
119
138
  interview by explicit command, a file path is
120
- bulk direct.** A
139
+ bulk direct.** The `plan`
140
+ verb is the fourth depth on every surface: same Confirm gate, but the agent
141
+ researches BEFORE asking and interviews across multiple rounds — for
142
+ greenfield or megaplan work where the normal 5–7-question draft would be
143
+ too shallow. A
121
144
  sisyphus-style plan file (checklists, bullets, numbered, plain lines) imports
122
145
  as-is — headings become nothing, items become goals. And the drafter itself
123
146
  batches: asking for "these 50 tasks" in a `/list` drafting session produces
@@ -203,6 +226,9 @@ product). The other three are optional; glla works without them:
203
226
 
204
227
  ## Which loop? (the decision rule)
205
228
 
229
+ (Verb semantics — what `start`, `plan`, and `audit` mean on each surface —
230
+ are tabulated above, "What the verbs mean".)
231
+
206
232
  **`/goal`** — one thing, judged *semantically*. Research, features, docs,
207
233
  anything where "done" needs a reader. The isolated auditor verifies against
208
234
  your `Done when:` contract with quoted evidence.
@@ -240,7 +266,7 @@ Each loop is a different policy class on the same status machine.
240
266
  | Flaw in pi-goal-x | Fix in pi-goal-list-loop-audit |
241
267
  |---|---|
242
268
  | `detailedSummary` is hand-concat strings | Structured JSON state + native markdown renderer |
243
- | Stuck-counter has no ceiling — 1-hour waits happen | Hard 5-minute backoff cap, fall through to user notification |
269
+ | Stuck-counter has no ceiling — 1-hour waits happen | Bounded retry envelope: eager 5s first retry, then the hourly-aligned ladder (v0.35.0); stall ladder + heartbeat nudges cap silent waits |
244
270
  | Auditor can rubber-stamp after `bash true` | **regression_shield** (shipped v0.2.0): auditor must quote raw tool output per verification-contract item; orchestrator rejects evidence-free approvals |
245
271
  | `pause_goal` is fire-and-forget | Clear `pauseReason` surfaced in status + agent feedback |
246
272
  | Vague objective + weak auditor = rubber-stamp | Drafting phase with Confirm dialog + isolated auditor + shield |
@@ -286,6 +312,29 @@ tool call or hidden reasoning interval therefore remains visibly timed; after
286
312
  three minutes without worker activity the UI changes to `auditor quiet` and
287
313
  names the cancellation/recovery path instead of presenting a frozen live card.
288
314
 
315
+ **Per-phase glyphs + activity meter (v0.35.15).** Every auditor phase carries a
316
+ distinct glyph — `⋯` queued, `▶` running, `◌` quiet, `⛔` blocked, `✓`
317
+ awaiting-verdict — beside a draining `▰▱` activity meter, with the dense text
318
+ kept as secondary detail. When a quiet stretch ends, the footer summarizes it
319
+ (`silent 8m then resumed`) so silence is reported, not just survived. A single
320
+ proactive warning fires when the detached auditor crosses the quiet threshold;
321
+ it never repeats per tick.
322
+
323
+ **Supervisor freeze (v0.35.15).** `/glla pause` silences every automatic
324
+ side-effect — heartbeat re-arms, recovery probes, auto-resume, auto-continuation
325
+ dispatch, the proactive quiet notify, and (v0.35.17) the zero-stream auto-retry
326
+ below — without touching active work or a running detached audit. The flag is
327
+ persisted and survives restarts; `/glla resume` clears it. Bare `/glla` shows
328
+ the frozen state.
329
+
330
+ **Zombie watchdog vs subagent waits (v0.35.26, issue #13).** A parent
331
+ blocked on a foreground subagent call is stream-silent by design, so the
332
+ zero-stream watchdog stands down while one is in flight. The recognized
333
+ names cover both the built-ins (`Agent`, `get_subagent_result`,
334
+ `steer_subagent`) and the pi-subagents extension's registrations
335
+ (`subagent`, `subagent_wait`), shared by the watchdog and the wedge-alert
336
+ hint so they cannot drift apart again.
337
+
289
338
  ## Provider failures: aggressive retry envelope, bounded (v0.35.0)
290
339
 
291
340
  Error text is **not trusted** to pick a retry policy. The runtime does not
@@ -299,6 +348,9 @@ adds a blind `:00:30` retry after each hour starts, so work can be picked up
299
348
  quickly after a possible provider-side change. The automatic window is 24h;
300
349
  explicit `/goal resume`, `/list resume`, or `/loop resume` starts a fresh
301
350
  window. With global `autoResume=on`, pending retries survive a session reload.
351
+ A loop parked by the zero-stream abort (v0.35.25, issue #14) is explicitly
352
+ resumable: `/loop resume` re-arms it with the preserved iteration count,
353
+ best value, and history — exactly as the abort message promises.
302
354
 
303
355
  Only failures identified by positive evidence as futile avoid automatic retry:
304
356
  context/output-token limits and user aborts (`non-recoverable`). Auditor
@@ -370,6 +422,16 @@ brake streak, so a broken provider can't spin forever. A confirmed queued
370
422
  continuation with no turn is reported by the queue-stuck probe; it does not
371
423
  inject terminal input.
372
424
 
425
+ **Zero-stream zombie abort + one bounded auto-retry (v0.35.17).** When pi stays
426
+ BUSY with zero provider stream activity for 20 minutes, glla warns; after a
427
+ 10-minute grace it aborts the zombie turn and parks the work safely. Since
428
+ v0.35.17 the FIRST such silence arms exactly ONE automatic retry ~90 seconds
429
+ later (the park becomes a waystation, not a dead end — field: turns dispatched
430
+ by accepting Confirm dialogs hung this way repeatedly). If the retry also hangs,
431
+ the second consecutive silence parks permanently for manual `/goal resume` /
432
+ `/list resume`. `/glla pause` freezes the retry like every other automatic
433
+ side-effect.
434
+
373
435
  ## Session replacement and stale handles
374
436
 
375
437
  Recovery crosses pi's lifecycle boundary. On `session_shutdown`, glla records
@@ -423,6 +485,47 @@ loser is archived (recoverable under `.pi-glla/archive/`), never silently
423
485
  wiped. Legacy `complete`/`aborted` terminal slots are also cleared once their
424
486
  archive exists, while the final summary remains available in history.
425
487
 
488
+ ### Load without autostart (v0.35.23)
489
+
490
+ On startup glla RESTORES and DISPLAYS all durable state — active/paused
491
+ goal, waiting queue, loop — but holds every automatic dispatch until you
492
+ decide. The load hold freezes the same machinery as `/glla pause`
493
+ (continuation dispatch, loop ticks, heartbeat refires, recovery timers)
494
+ through one shared gate; unlike a manual pause it keeps host-loss
495
+ supervision probing, and it is released by any explicit work command:
496
+ `/goal resume`, `/list resume`, `/list next`, `/loop resume`, `/loop start`,
497
+ or starting a new goal. Every release is ledgered (`load_hold_engaged` /
498
+ `load_hold_released`). Set global **Auto-resume = on** to restore
499
+ load-time automation for unattended rigs — the consent is the raw setting,
500
+ not the aggressive-mode default. Narrow continuity exceptions keep working
501
+ without consent: validated handoffs/rebinds, same-process session
502
+ successors, re-arming of work already in flight when a host silently died,
503
+ and the single retry a parked completion claim earns when main-model
504
+ recovery heals the provider that parked it.
505
+
506
+ ### Auditor context without autostart (v0.35.63)
507
+
508
+ A restored objective remains visible in the status/widget UI even when the
509
+ load hold is active, but GLLA does not add a new continuation or re-inject the
510
+ previous auditor report until continuation consent exists. `/goal resume`,
511
+ `/list resume`, `/list next`, `/glla resume`, admitted loop resumes, validated
512
+ session continuity, and global **Auto-resume = on** are consent paths. The
513
+ previous Pi transcript is historical and remains untouched; this gate controls
514
+ only newly projected auditor feedback and model context.
515
+
516
+ **Due-wait backstop (v0.35.28, issue #16).** A time-gated wait pause
517
+ (`pauseKind: "wait"` with a `pauseResumeAt`) is no longer trusted to
518
+ in-memory timers alone — agent-authored waits armed none, error-brake
519
+ cooldowns were not re-armed on reload, and every scheduled resume died with
520
+ its session. The heartbeat now compares wall time against `pauseResumeAt`
521
+ every tick and re-fires the route once the deadline lapses by more than
522
+ ~90s (main-model waits probe the provider; other waits clear the park and
523
+ dispatch one fresh continuation). `/glla pause` and the load hold still
524
+ freeze it; every fire is ledgered (`wait_pause_overdue_resume`). Auto-resumed
525
+ goals carry a RECOVERY NOTICE in their next continuation prompt — "welcome
526
+ back, YOU were recovered" — so the agent continues its own work instead of
527
+ waiting for an external recovery signal that already fired.
528
+
426
529
  ## Completion and destructive commands
427
530
 
428
531
  An approved objective writes its final completion summary to the archive and
@@ -442,6 +545,17 @@ Open `/glla` to edit these settings in the table (the rows show effective values
442
545
 
443
546
  - Auditor model and thinking level
444
547
  - Auditor fallback agent
548
+
549
+ **Auditor selection (v0.35.24):** the **Auditor model** row opens the same
550
+ `/model`-style fuzzy picker the main agent flows use — configured-auth models
551
+ only, with a session-model row and a typed escape hatch. It is at full parity
552
+ with the main selector on policy too: your forbidden-models patterns filter
553
+ the picker list AND a typed match is refused with a named warning, so a pin
554
+ saved here is one `resolveAuditorModel` will actually honor. The pick lands
555
+ in global `auditorModel` and is followed immediately by the auditor thinking
556
+ dialog for that model. The **Auditor fallback agent** row applies the same
557
+ filtering to the failure-over pin.
558
+
445
559
  - Notify command, token limit, and wedge-alert minutes
446
560
  - Auto-resume, auto-accept drafts, decision popup, and carryover policy
447
561
  - Main-agent current model/thinking, fallback models, recovery cadence, and preferred-primary failback policy in the Main agent tab
@@ -452,11 +566,14 @@ Open `/glla` to edit these settings in the table (the rows show effective values
452
566
  stall brakes
453
567
 
454
568
  The argument namespace is reserved for actions such as `/glla status`, `/glla
455
- resume`, `/glla cancel`, `/glla stats`, `/glla audits`, `/glla tooloverride`,
456
- `/glla fallbacks clear`, and `/glla wipe`. `fallbacks clear` atomically removes
457
- the global main-agent fallback chain and cancels any pending fallback switch. Cancel stops the
458
- active objective; wipe clears all live state while preserving history.
459
- There is no top-level `/glla key=value` setting syntax.
569
+ pause`, `/glla resume`, `/glla cancel`, `/glla stats`, `/glla audits`,
570
+ `/glla tooloverride`, `/glla fallbacks clear`, and `/glla wipe`. `fallbacks clear`
571
+ atomically removes the global main-agent fallback chain and cancels any pending
572
+ fallback switch. Pause freezes every automatic supervisor side-effect (heartbeat
573
+ re-arms, recovery probes, auto-resume, continuation dispatch, loop ticks, quiet
574
+ notifications) without touching active work, and survives session restarts;
575
+ resume unfreezes. Cancel stops the active objective; wipe clears all live state
576
+ while preserving history. There is no top-level `/glla key=value` setting syntax.
460
577
 
461
578
  Resolution per key: **project > global > defaults** — EXCEPT `autoResume` and
462
579
  agent recovery settings (`mainModelFallbacks`, `mainModelRetryMinutes`,
@@ -525,15 +642,21 @@ are workers** (v0.23.8):
525
642
  - A subagent session never clobbers the loop's session handle, never runs
526
643
  the restore gate, and never drives continuation — so the heartbeat,
527
644
  wedge alert, and auto-resume machinery always act on the main session.
528
- (pi hands a fresh ctx wrapper per event; `ctx.sessionManager` identity
529
- is the discriminator.)
645
+ Headless `print`/`json` child contexts are rejected before root
646
+ registration, restore, owner claims, or command/tool mutation; this also
647
+ covers persistent children, not only the usual in-memory workers.
530
648
  - Subagent tool activity counts as activity for the wedge clock — a long
531
- subagent run is work, not a hang.
649
+ productive child run is work, not a hang. If a tracked top-level child stops
650
+ changing its tool-use/output counters, glla warns at the short detection
651
+ threshold and can request one child-specific abort after
652
+ `subagentHangEscalationMinutes` (default 30; `0` = warning-only). The main
653
+ host still records lifecycle, action state, and partial output for
654
+ `/glla agents` through the event bus.
532
655
  - With `@tintinweb/pi-subagents` specifically (the one we test against):
533
656
  read-only agents (Explore, Plan) get no glla tools; general-purpose
534
657
  agents see them but state-mutating calls (`complete_goal`, `propose_*`,
535
- `list_add`, `pause_goal`, …) are refused with "report back to the main
536
- agent".
658
+ `list_add`, `pause_goal`, …) and foreign slash commands are refused with
659
+ "report back to the main agent".
537
660
 
538
661
  ## Token guard
539
662
 
@@ -598,23 +721,75 @@ customizes.
598
721
 
599
722
  ## Files
600
723
 
724
+ Post-decomposition layout (the v0.34.x monolith is gone — `loops/goal.ts` is
725
+ a thin activation/wiring installer):
726
+
601
727
  ```
602
- extensions/
603
- loops/goal.ts # /goal + /list commands, agent tools, loop driver
604
- goal-loop-core.ts # types, JSONL state, pure helpers
605
- goal-loop-auditor.ts # auditor prompt + legacy in-process helper
606
- goal-loop-auditor-process.ts # detached worker protocol + shield revalidation
728
+ extensions/ (34 files — all of them, grouped by concern)
729
+ # command + UI surface
730
+ goal-commands.ts # /goal + /list command surface, drafting, wipe/stats
731
+ settings-menu.ts # /glla settings menu sections + rows
732
+ goal-agents-panel.ts # tracked-subagent panel (/glla agents) + widget line
733
+ confirm-draft.ts # Confirm-card markdown builder
734
+ vision-assist.ts # mmx vision routing + model-switch gate
735
+ glla-version.ts # version info for /glla version (source + npm)
736
+ # state, types, pure helpers
737
+ goal-loop-core.ts # types, JSONL state reader, pure helpers
738
+ goal-state.ts # disk writer (persistStateLine serialization)
739
+ goal-settings.ts # settings load/save + global/project paths
740
+ faulty-objective-recovery.ts # suspicious-objective classification + repair derivation
741
+ goal-objective-conflict.ts # live-objective conflict resolution on start/tweak
607
742
  goal-loop-shield.ts # regression_shield (pure, dependency-free)
608
- goal-loop-display.ts # status line + /goal status rendering
743
+ goal-loop-display.ts # widget/status rendering (incl. last-outcome retention)
744
+ # continuation + recovery
745
+ goal-continuation.ts # continuation scheduling/dispatch + prompt templates
746
+ goal-loop-dispatch.ts # generation-bound dispatch records
747
+ length-continue.ts # stop_reason=length auto-continue policy
748
+ goal-heartbeat.ts # heartbeat self-watchdog, subagent probes, due-wait backstop
749
+ goal-recovery.ts # main-model recovery + completion-audit recovery
750
+ main-model-recovery.ts # pure model-fallback/probe scheduling helpers
751
+ quota-retry.ts # provider diagnostics + bounded retry windows
752
+ # loop machinery (Loop 3)
753
+ goal-loop.ts # /loop tick engine, git finish
609
754
  goal-loop-forever.ts # /loop measure/parse/plateau helpers
610
- goal-loop-backoff.ts # 5-min hard cap
611
- prompts/
612
- goal-loop-continuation.md # loop driver prompt
613
- goal-loop-draft.md # drafting prompt
755
+ goal-loop-backoff.ts # scheduling constants + stall/wedge/pending-latch decisions
756
+ goal-loop-repetition.ts # anti-repetition detectors (stuck ladder, v0.24.0)
757
+ goal-loop-stats.ts # ledger rollups + premature-success detection
758
+ goal-loop-subagents.ts # subagent markers + pinned-agent knowledge
759
+ reviewer.ts # archived-goal re-review config + classification
760
+ # auditor machinery
761
+ goal-loop-auditor.ts # auditor prompt + legacy in-process helper
762
+ goal-loop-auditor-process.ts # detached worker protocol + shield revalidation
763
+ auditor-extensions.ts # auditor-session extension discovery + allowlist
764
+ # model pickers
765
+ drafter-model.ts # drafting-only model resolution + fallbacks
766
+ model-picker.ts # single-model picker items
767
+ multi-model-picker.ts # multi-model picker UI
768
+ model-selector.ts # scope-aware fallback selector composition
769
+ loops/
770
+ goal.ts # public activation/wiring installer (thin)
771
+ goal-activation.ts # event wiring, command registration, session lifecycle
772
+ goal-tools.ts # agent tools (complete_goal, pause_goal, list_*, loop drafts)
773
+ goal-orchestrator.ts # goal lifecycle: create/archive/advance, reviewer
774
+ goal-list-queue.ts # /list queue: enqueue/advance/drain, list drafting
775
+ goal-auditor-hooks.ts # completion-audit claim/recovery machinery
776
+ goal-session.ts # session-scoped runtime globals + lifecycle state
777
+ goal-runtime-globals.ts # ambient declarations for those globals
778
+ goal-settings-ui.ts # settings editors + model pickers
779
+ goal-ui.ts # shared UI helpers (drafting state reset, notify wrappers)
780
+ prompts/ (7 — one per prompt surface; edited as .md, read at runtime)
781
+ goal-loop-continuation.md # continuation prompt template
782
+ goal-loop-draft.md # /goal + /list drafting interview
783
+ goal-loop-plan.md # extended plan draft — goal/list (v0.35.33)
784
+ goal-loop-plan-loop.md # extended plan draft — loop (v0.35.33)
614
785
  goal-loop-forever.md # /loop driver prompt
615
- goal-loop-forever-draft.md # /loop drafting prompt
786
+ goal-loop-forever-draft.md # /loop drafting interview
787
+ goal-loop-forever-metricless.md # metricless-/loop drafting variant
616
788
  scripts/
617
789
  goal-auditor-worker.mjs # extension-less RPC auditor child process
790
+ goal-auditor-launch.mjs # Windows-safe spawn spec builder (gate-before-quote)
791
+ auditor-extension-fixture.mjs # hermetic provider fixture for the auditor gate
792
+ verify-auditor-extensions-offline.mjs # mandatory gate: resolved allowlist loads offline
618
793
  smoke.sh # live integration harness (tmux + real models)
619
794
  tests/ # current test count is reported by `bun test`; no live pi required for the suite
620
795
  docs/DESIGN.md # architectural decisions
@@ -0,0 +1,76 @@
1
+ # Design — subagent visibility (`/glla agents`, issue #15)
2
+
3
+ Status: SCOPE AGREED with the user 2026-08-22 (panel + transcript tail +
4
+ widget line; live activity stream explicitly rejected as too noisy).
5
+ This document is the implementation contract for the follow-up work.
6
+
7
+ ## Problem (issue #15)
8
+
9
+ During long fan-outs the only child visibility is the widget's 3-slot
10
+ "recent actions" ring. A child that "almost completed its final report,
11
+ went back to check some more, then crashed" is invisible: the parent sees
12
+ a silent wait, the user sees nothing actionable, and post-mortem evidence
13
+ lives in files nobody knows how to find.
14
+
15
+ ## Agreed scope
16
+
17
+ ### 1. `/glla agents` — snapshot panel
18
+
19
+ One-shot table of every tracked subagent, sourced from what glla already
20
+ holds (no new instrumentation):
21
+
22
+ - `subagentHangProbes` (goal-heartbeat.ts): agentType, summary, spawnedAt,
23
+ lastProgressAt, toolUses, outputTokens, endedAt, hangAlertedAt.
24
+ - `subagentManagerPoller()` when pi-subagents publishes its registry
25
+ (absent on some installed versions — always degrade gracefully to
26
+ event-derived evidence).
27
+ - `flags.inFlightToolCalls` for which parent wait (foreground Agent /
28
+ subagent call) each running child blocks.
29
+ - Ledger history of `subagent_hang_detected` for the "Recent hangs" footer
30
+ of the panel.
31
+
32
+ Row shape:
33
+
34
+ ```
35
+ ● explore map-model-picker RUNNING 4m12s tools 18 · out 2.1k · silent 0m
36
+ ● plan audit-contract HUNG? 31m tools 6 → frozen · out 890 · silent 26m
37
+ └ blocks: foreground subagent call (zombie stand-down active)
38
+ ✓ explore schema-check ENDED ok 3m44s
39
+ ```
40
+
41
+ Hung classification reuses `classifyHungSubagents` semantics (record-frozen
42
+ vs event-only evidence). Cap display at ~20 rows; prune ended probes per
43
+ the existing SUBAGENT_HANG_PRUNE_MS rule.
44
+
45
+ ### 2. `/glla agents --tail <id>` — child transcript tail (post-mortem)
46
+
47
+ Locate the child's session file on disk (pi sessions are JSONL under the
48
+ session store; pi-subagents records expose/allow correlation by id — probe
49
+ both the manager record and the probe registry) and print the LAST N lines
50
+ (N default 20, `--lines` override) rendered as `[tool] …/[asst] …/[user] …`
51
+ with truncation. If the file cannot be located, say so LOUDLY and name the
52
+ searched paths — never silently print an empty tail. Read-only: the tail
53
+ NEVER resumes or attaches to the child session.
54
+
55
+ ### 3. Widget line — ambient awareness
56
+
57
+ One footer segment while children are tracked: `● N agents · <busiest>
58
+ silent Xm ⚠` (⚠ only past the hang threshold). Reuses the existing widget
59
+ render path in goal-loop-display/goal-ui; hidden when zero tracked
60
+ children so idle rigs see no change.
61
+
62
+ ## Non-goals (explicitly rejected with the user)
63
+
64
+ - Live streaming of child tool calls into the main transcript (noise).
65
+ - Any attach/resume capability from the panel (read-only by design).
66
+ - New cross-extension contracts beyond the existing defensive manager poll.
67
+
68
+ ## Implementation notes
69
+
70
+ - New module `extensions/goal-agents-panel.ts` (pure render functions +
71
+ data assembly), wired into the `/glla` argument namespace next to
72
+ `/glla audits`; widget segment in goal-ui.
73
+ - All rendering pure/testable: feed fixtures of probes + manager records;
74
+ pin hung classification, cap behavior, loud-missing-file behavior for
75
+ --tail, and widget hide-at-zero.
76
+ - Version + CHANGELOG + README at ship time; full release gate.
package/docs/DESIGN.md CHANGED
@@ -255,9 +255,9 @@ replacement without delivering a successor `session_start`:
255
255
  flattens extensions in load order and suffixes EVERY registration of a duplicated
256
256
  command name (`name:1`, `name:2`, …) — the bare name becomes owned by nobody and
257
257
  dispatch stops routing it while a collision exists. The model is read from the
258
- installed pi core (hermetic, never modified) and auto-records the routing table to
259
- `audit/command-registration-routing.md`, making collisions reproducible and
260
- diagnosable without touching pi.
258
+ installed pi core (hermetic, never modified) and records a process-scoped
259
+ routing diagnostic, making collisions reproducible without rewriting tracked
260
+ repository files or touching pi.
261
261
  - **Unmatched telemetry stays unmatched** (v0.34.56): tool starts/ends without a
262
262
  counterpart are represented as explicitly unmatched facts, never falsely paired —
263
263
  the report surface stays truthful (the AuditProgress/AuditorProgress dual-interface
@@ -429,15 +429,20 @@ v0.1.0 ships the same auditor behaviour as pi-goal-x. The author of pi-goal-x do
429
429
 
430
430
  We accept this caveat for v0.1.0. v0.2.0 will add **regression_shield**: an explicit requirement that the auditor's report must include raw output (a `cat`, a `grep -A 5 <file>`, a `bash <user-script>`) for every item in `verificationContract`. Without that evidence, the auditor's `<approved/>` is rejected by the orchestrator.
431
431
 
432
- ### Decision 3: Hard 5-minute backoff cap
432
+ ### Decision 3: Hard 5-minute backoff cap (SUPERSEDED v0.35.4)
433
433
 
434
434
  The #1 complaint about pi-goal-x in our audit (user-stated) was "1-hour waits". The cause is exponential backoff with no ceiling.
435
435
 
436
- v0.1.0 ships a hard 5-minute cap. After 5 minutes of consecutive backoff:
436
+ v0.1.0 shipped a hard 5-minute cap. After 5 minutes of consecutive backoff:
437
437
  1. TUI badge turns red with "Last activity: 5m+".
438
438
  2. User can press `r` to force-continue or `s` to skip to next pending task.
439
439
  3. Optional: configure Telegram/web push notification.
440
440
 
441
+ > **Superseded (v0.35.4):** the cap had zero production call sites and was
442
+ > removed (`extensions/goal-loop-backoff.ts` header). The live envelope is
443
+ > the eager 5s first retry + hourly-aligned ladder with stall-ladder/heartbeat
444
+ > coverage — see README's retry section.
445
+
441
446
  ### Decision 4: No drafting phase in v0.1.0 (deferred to v0.2.0)
442
447
 
443
448
  The user identified vague-correction as a key strength of pi-goal-x. But shipping it in v0.1.0 doubles the scope and we won't get the auditor right if we split focus.
@@ -494,8 +499,11 @@ This is a **clean break** by decision of the user. We do not interop with `pi-go
494
499
  ### Decision 8: Status machine
495
500
 
496
501
  ```ts
502
+ // Historical sketch from v0.2.0 planning. The SHIPPED Status union is
503
+ // "active" | "auditing" | "complete" | "paused" | "aborted" (drafting is a
504
+ // UI phase, not a persisted status).
497
505
  type Status =
498
- | "drafting" // v0.2.0
506
+ | "drafting" // v0.2.0 (planned; not a persisted Status value)
499
507
  | "active"
500
508
  | "auditing"
501
509
  | "complete"
@@ -565,10 +573,53 @@ This protects against model-generated summaries losing fidelity.
565
573
  - *Current*: Parallel subagent exploration fan-out (spawning multiple `Explore` agents in one turn) and parallel disjoint-worktree implementation (`general-purpose` workers with `isolation: "worktree"`). Detached auditor runs concurrently in background OS process.
566
574
  - *Opportunities*: Concurrent `/list` dispatch across non-conflicting tasks using isolated worktrees to eliminate head-of-line blocking for large queues, plus background contract rehearsals.
567
575
 
576
+ ## Addendum v0.35.7–v0.35.31 (consolidated behavior addenda)
577
+
578
+ Per the doc convention, these releases appended the following architectural
579
+ shapes (details in CHANGELOG.md; each is pinned by tests):
580
+
581
+ - **Supervisor freeze — `/glla pause` (v0.35.15/17)**: freezes ALL automatic
582
+ machinery (re-arms, recovery probes, auto-resume, continuation dispatch,
583
+ proactive notifies) without touching active work or a running detached
584
+ auditor. Distinct from goal pause; only `/glla resume` clears it.
585
+ - **Load hold (v0.35.23)**: a cold session load that restores pending state
586
+ WITHOUT explicit consent holds automation (`loadHoldAt`) until an explicit
587
+ work command releases it. Refines the restore-gate consent story above.
588
+ - **Auditor picker parity (v0.35.24)**: `promptModelRef` accepts
589
+ `excludeRefs`; forbiddenModels policy refs are filtered from lists AND
590
+ refused on typed input (`forbidden_model_switch`).
591
+ - **Zero-stream zombie park + RESUMABLE_STOP (v0.35.25/26)**: a run with no
592
+ provider activity parks as `stopped: automatic zero-stream abort…` and
593
+ `/loop resume` retries it; the zombie watchdog stands down while tracked
594
+ subagent waits are in flight via ONE shared `SUBAGENT_WAIT_TOOL_NAMES`
595
+ predicate (no per-site name lists).
596
+ - **Windows auditor launch, gate-before-quote (v0.35.27)**: unsafe-arg
597
+ rejection runs on EVERY argument before the quoting decision; bare tokens
598
+ reach cmd.exe untouched so pnpm .CMD shims resolve.
599
+ - **Heartbeat due-wait backstop + recovery notice (v0.35.28)**: wall-clock
600
+ comparison against persisted `pauseResumeAt` in the tick resumes lapsed
601
+ wait/error-brake parks after a 90s grace (consent-gated); successful
602
+ recoveries stamp `autoResumedAt`/`autoResumedEvent` and the continuation
603
+ prompt renders a RECOVERY NOTICE instead of waiting on a fired signal.
604
+ - **Tracked-subagent visibility (v0.35.29)**: `getSubagentAgentsSnapshot()`
605
+ (read-only probe views with hung classification) feeds `/glla agents`,
606
+ `/glla agents --tail <id>` (read-only child transcript tail), and a widget
607
+ segment — pure rendering in `extensions/goal-agents-panel.ts`.
608
+ - **Durable last-outcome retention (v0.35.30)**: archiving writes
609
+ `state.lastOutcome`; the widget keeps one dim ✓/▪ line for 24h after the
610
+ slot empties so a finished audit stays visible after the turn ends.
611
+ - **Loop plateau vs never-moved baselines (v0.35.31)**: flat metric readings
612
+ count toward plateau only once the metric has demonstrably moved; a metric
613
+ that NEVER moves gets its own loud bounded stop. Audit loops keep their
614
+ purpose-built deferred-baseline + reprieve semantics verbatim.
615
+
568
616
  ## Files
569
617
 
570
618
  - `docs/DESIGN.md` — **this file**
571
619
  - `README.md` — quickstart
572
- - `audit/pi-name-v3-registry-based.md` — naming rationale
573
- - `audit/pi-goal-loop-design.md` — earlier design (now superseded)
620
+ - `docs/INDEX.md` — shipped documentation and architecture entry points
621
+ - `README.md` — user-facing installation and operating guidance
622
+
623
+ Historical audit notes are repository-only and are intentionally not part of
624
+ the published package.
574
625
 
@@ -78,7 +78,12 @@ detached-auditor loop, but it is also a deliberate trade:
78
78
 
79
79
  ## 4. The refactor: decompose goal.ts (the plan skeleton)
80
80
 
81
- Current state: `extensions/loops/goal.ts` ≈ 10.5K lines, 189 top-level
81
+ > **STATUS (2026-08-22): IMPLEMENTED.** This plan shipped in decomposition
82
+ > steps 1–6 (v0.34.109–v0.34.114). `extensions/loops/goal.ts` is now a thin
83
+ > activation/wiring installer (~413 lines); every module below exists under
84
+ > `extensions/` and `extensions/loops/`. Kept for rationale/history.
85
+
86
+ Current state at planning time: `extensions/loops/goal.ts` ≈ 10.5K lines, 189 top-level
82
87
  functions, covering at least these domains (grep counts):
83
88
 
84
89
  ```
package/docs/INDEX.md CHANGED
@@ -18,6 +18,10 @@ For shipped docs, the relevant entry points are:
18
18
  failback; v0.35.9 hardened cross-version npm tarball checks; v0.35.10
19
19
  handles multi-entry npm dry-run reports; v0.35.11 accepts both npm report
20
20
  shapes; v0.35.12 supports npm 12's keyed pack reports; v0.35.13 fixes stale-API recovery loops.
21
+ v0.35.14–v0.35.31 continue through the supervisor freeze (`/glla pause`),
22
+ load hold, auditor picker parity, Windows launch fix, zombie-watchdog
23
+ subagent carve-out, due-wait backstop, the `/glla agents` visibility panel,
24
+ and durable last-outcome retention — see CHANGELOG.md for the full trail.
21
25
  - `../README.md` — what the plugin is, install, quickstart, and the
22
26
  architectural guarantee (drafting + confirm + detached auditor).
23
27
  - `../INSTALL.md` — manual install / symlink setup; the recommended
@@ -66,8 +66,8 @@ Edit: `/glla` → **Keep-going** → **Vision assist**, then choose **off**.
66
66
  | Command builder | `visionDescribeCommand(imagePath, question?)` |
67
67
  | Routing rule (pure) | `routeVisionCheck(request)` — mmx by default; forbidden target → mmx + `blockedSwitch`; preapproved target → `model-switch` allowed |
68
68
  | Ledger payload builder | `visionAssistLedger(route, request)` |
69
- | Continuation injection | `extensions/loops/goal.ts` `continuationPrompt()` (gated on `visionAssist !== false`) |
70
- | Forbidden-switch hook | `observeModelChange()` forbidden branch → `vision_assist` entry |
69
+ | Continuation injection | `extensions/goal-continuation.ts` pushes `VISION_ASSIST_GUIDANCE` into the continuation directives (gated on `visionAssist !== false`) |
70
+ | Forbidden-switch hook | forbidden-model gate in the settings editors/model pickers (`extensions/loops/goal-settings-ui.ts`, `extensions/loops/goal-activation.ts`) → `forbidden_model_switch` + `vision_assist` ledger entries |
71
71
  | Setting | `extensions/goal-settings.ts` (default true), menu row in `extensions/settings-menu.ts`, editor + `/glla` row in `extensions/loops/goal.ts` |
72
72
  | Tests | `tests/vision-assist.test.ts` |
73
73