pi-goal-list-loop-audit 0.35.71 → 0.36.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.
Files changed (55) hide show
  1. package/CHANGELOG.md +89 -0
  2. package/INSTALL.md +9 -2
  3. package/README.md +34 -9
  4. package/docs/DESIGN-long-running-supervision.md +116 -0
  5. package/docs/DESIGN.md +18 -15
  6. package/docs/INDEX.md +6 -2
  7. package/docs/VISION-ASSIST.md +42 -48
  8. package/examples/example-objective.md +3 -3
  9. package/extensions/auditor-extensions.ts +19 -4
  10. package/extensions/completion-summary.ts +258 -0
  11. package/extensions/context-checkpoint.ts +397 -0
  12. package/extensions/context-growth.ts +340 -0
  13. package/extensions/continuous-supervision.ts +191 -0
  14. package/extensions/goal-agents-panel.ts +51 -11
  15. package/extensions/goal-commands.ts +287 -42
  16. package/extensions/goal-continuation.ts +32 -12
  17. package/extensions/goal-heartbeat.ts +59 -6
  18. package/extensions/goal-loop-auditor-process.ts +363 -51
  19. package/extensions/goal-loop-auditor.ts +19 -0
  20. package/extensions/goal-loop-backoff.ts +10 -10
  21. package/extensions/goal-loop-core.ts +492 -42
  22. package/extensions/goal-loop-display.ts +49 -37
  23. package/extensions/goal-loop-forever.ts +2 -0
  24. package/extensions/goal-loop-shield.ts +84 -16
  25. package/extensions/goal-loop-subagents.ts +2 -1
  26. package/extensions/goal-loop.ts +97 -23
  27. package/extensions/goal-recovery.ts +78 -18
  28. package/extensions/goal-settings.ts +67 -28
  29. package/extensions/goal-state.ts +2 -2
  30. package/extensions/loops/goal-activation.ts +136 -27
  31. package/extensions/loops/goal-auditor-hooks.ts +571 -69
  32. package/extensions/loops/goal-list-queue.ts +23 -8
  33. package/extensions/loops/goal-orchestrator.ts +269 -46
  34. package/extensions/loops/goal-runtime-globals.ts +3 -0
  35. package/extensions/loops/goal-session.ts +122 -15
  36. package/extensions/loops/goal-settings-ui.ts +188 -78
  37. package/extensions/loops/goal-tools.ts +622 -103
  38. package/extensions/loops/goal-ui.ts +2 -1
  39. package/extensions/loops/goal.ts +1 -0
  40. package/extensions/main-model-recovery.ts +54 -13
  41. package/extensions/proactive-pre-read.ts +101 -0
  42. package/extensions/quota-retry.ts +2 -2
  43. package/extensions/reviewer.ts +15 -3
  44. package/extensions/settings-menu.ts +27 -20
  45. package/extensions/start-context.ts +299 -0
  46. package/extensions/vision-assist.ts +80 -47
  47. package/media/glla2.png +0 -0
  48. package/package.json +2 -1
  49. package/prompts/goal-loop-continuation.md +10 -2
  50. package/schemas/goal.schema.json +24 -1
  51. package/scripts/durable-wait.mjs +236 -0
  52. package/scripts/goal-auditor-worker.mjs +61 -20
  53. package/scripts/measure-context-growth.mjs +98 -0
  54. package/scripts/smoke.sh +67 -19
  55. package/scripts/verify-auditor-extensions-offline.mjs +11 -11
package/CHANGELOG.md CHANGED
@@ -1,5 +1,94 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.36.0 — event-driven long-running supervision (2026-08-28)
4
+
5
+ ### Added
6
+ Bare `/goal start`, `/loop start`, and `/list start` now use a bounded active
7
+ branch context window only when it contains one clear actionable user
8
+ request. Ambiguous, generic, truncated, or multi-task context returns to the
9
+ existing drafting/confirmation flow; list queue activation and loop metric
10
+ settings remain explicit.
11
+
12
+ GLLA now records a six-label user-facing recap for every archived terminal
13
+ objective and loop stop. Valid recaps are preserved; missing or incomplete
14
+ claims receive a recorded-facts-only fallback with explicit `not recorded`
15
+ values instead of invented evidence.
16
+
17
+ The shared heartbeat is now an event-first continuous supervisor across
18
+ goals, list items, loops, auditors, subagents, provider recovery, and queue
19
+ state. It reacts to lifecycle/durable signals immediately and uses adaptive
20
+ fallback polling rather than guessed task-duration waits.
21
+
22
+ ### Fixed
23
+ Detached completion-auditor failures now coordinate RPC stdout EOF with the
24
+ child process close, preserving bounded exit code, signal, stderr, and
25
+ malformed-stream diagnostics while remaining fail-closed until
26
+ `agent_settled`.
27
+
28
+ ### Changed
29
+ The detached auditor now has the same ordered, deselectable, bounded fallback
30
+ chain as the main agent (`auditorModelFallbacks`, up to 10 refs), with the
31
+ former singular fallback setting migrated compatibly. An unset auditor
32
+ thinking level inherits the parent session's live dial, including `max`,
33
+ while explicit auditor levels remain overrides.
34
+
35
+ Aggressive recovery retries recoverable provider/host/auditor failures across
36
+ arbitrary durations with bounded per-attempt backoff. Ordinary auditor
37
+ objections become durable TODOs; repeated identical objections with no new
38
+ progress stop on a state-based decision boundary. Conservative mode retains
39
+ its bounded recovery horizon.
40
+
41
+ Full auditor `IMPOSSIBLE` results and list auto-drops now pass through the
42
+ terminal archive fence with durable recaps; partial impossible results keep
43
+ their explicit narrowing behavior. Every loop-stop notification includes a
44
+ compact projection of the generated six-label recap. Version-bearing
45
+ already-shipped claims, explicit goal/list cancellation, and `/glla wipe`
46
+ now include the same compact projection in their terminal notifications.
47
+
48
+ Detached-auditor first-event watchdogs start at worker spawn rather than
49
+ charging dispatch setup time, with a runtime-compatible return-time fallback;
50
+ cancellation waits for worker teardown before classifying the attempt. The
51
+ former unconditional auditor wall is compatibility metadata only; active
52
+ output, tool, durable, and child progress can continue until a result,
53
+ confirmed-silence watchdog, per-tool timeout, or explicit lifecycle stop.
54
+
55
+ Carryover replacement, `/list next` skips, and complete-without-audit now
56
+ check the archive fence before reporting success and include the same recap
57
+ projection as other terminal paths. Continuous-supervision tests now drive
58
+ durable state transitions and lifecycle signals across every declared plane.
59
+
60
+ Validation warnings are metadata rather than recap fields: an incomplete
61
+ claim whose NOTE mentions label names is still replaced by the recorded-
62
+ facts-only archive fallback. Approved terminal notifications use the same
63
+ six-label compact projection, including for long valid recaps, instead of a
64
+ raw flattened slice.
65
+
66
+ Durable-vs-defer decisions now have an explicit `record_goal_judgment` tool:
67
+ inline and deferred choices are persisted as bounded ledger events, with a
68
+ required durable follow-up for intentional deferrals. The policy keeps the
69
+ durable action ahead of defer and pins the plaque-ordering regression.
70
+ The recommendation now comes from a typed semantic decision path, including
71
+ the three-defer case, and the active goal card has a deterministic ordered
72
+ plaque fixture so UI ordering is tested rather than inferred from prose.
73
+ `record_goal_judgment` now persists bounded recommendation facts on the goal
74
+ and immediately routes them through production `refreshUI()`; the production
75
+ integration test captures the resulting durable-first card.
76
+
77
+ See `docs/DESIGN-long-running-supervision.md` for the durable policy and
78
+ future decision checklist.
79
+
80
+ ## 0.35.72 — remove duplicate terminal outcome widget (2026-08-28)
81
+
82
+ ### Fixed
83
+ Approved or aborted goals now clear the live outcome slot after the single
84
+ completion notification. The archived goal record and ledger remain the
85
+ durable history, while legacy `lastOutcome` state is read safely but no
86
+ longer paints a second `✓ done` row after archival.
87
+
88
+ ### Tests
89
+ Updated terminal-outcome regressions to verify that completed/aborted goals
90
+ leave no retained widget row, while live goals still outrank legacy state.
91
+
3
92
  ## 0.35.71 — bounded Pi-core retry containment (2026-08-26)
4
93
 
5
94
  ### Changed
package/INSTALL.md CHANGED
@@ -72,7 +72,9 @@ Done when:
72
72
  A complete `Done when:` clause starts directly. For a new or ambiguous
73
73
  objective, use bare `/goal` instead: GLLA interviews you, helps shape the
74
74
  contract, and waits for Confirm. `/goal start "..."` skips that interview only
75
- when you explicitly want it skipped.
75
+ when you explicitly want it skipped. Bare `/goal start` uses one clear recent
76
+ user request when possible and otherwise returns to the normal drafting flow;
77
+ it never guesses across ambiguous requests.
76
78
 
77
79
  The first run proceeds like this:
78
80
 
@@ -93,17 +95,22 @@ waiting for a decision.
93
95
  /list "refactor the cache. Done when: tests pass"
94
96
  /list plan.md
95
97
  /list
98
+ /list start
96
99
  /list next
97
100
  /list resume
98
101
 
99
102
  /loop
103
+ /loop start # one clear recent target, metricless
100
104
  /loop start "reduce flaky tests" measure="..." direction=min
101
105
  /loop start "keep improving the spec" measure=none max=20 cadence=900
102
106
  /loop audit
103
107
  ```
104
108
 
105
109
  Use `/goal` for one outcome, `/list` for several independently auditable
106
- outcomes, and `/loop` for an improvement process without one final item. For
110
+ outcomes, and `/loop` for an improvement process without one final item. Bare
111
+ `/list start` activates the queued head, or seeds the normal Confirm-gated list
112
+ draft when the queue is empty. Bare `/loop start` infers only the target; it
113
+ does not invent metric, direction, bounds, cadence, or branch settings. For
107
114
  metricless loops that intentionally mature between checks, add optional
108
115
  `cadence=<seconds>`; the interval is visible in `/loop status`, while explicit
109
116
  starts/resumes remain urgent. See the README for the full command semantics.
package/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # pi-goal-list-loop-audit
2
2
 
3
+ <p align="center">
4
+ <img src="media/glla2.png" alt="GLLA mission control" width="960">
5
+ </p>
6
+
3
7
  > **Long-running, high-leverage autonomy for pi.**
4
8
  >
5
9
  > Give pi a meaningful outcome. GLLA helps it research, plan, execute,
@@ -18,13 +22,18 @@ finished without evidence**:
18
22
 
19
23
  - You state the outcome and what “done” means.
20
24
  - The agent researches, decomposes, and executes across many turns.
21
- - GLLA keeps durable state, supervises progress, and recovers bounded failures.
25
+ - GLLA keeps durable state, checks lifecycle/progress signals continuously, and
26
+ recovers failures with bounded per-attempt backoff plus policy-driven stop rules.
27
+ - Every terminal objective leaves a useful six-label recap; missing evidence is
28
+ shown as `not recorded`, never guessed.
22
29
  - Optional subagents can do parallel research and focused implementation work.
23
30
  - A separate detached auditor checks the saved completion claim before GLLA
24
31
  accepts it.
25
32
 
26
33
  The aim is not “run forever.” The aim is **more useful work per unit of
27
- attention, with better evidence at the end**.
34
+ attention, with event-driven progress instead of guessed-duration waiting, and
35
+ better evidence at the end**. See `docs/DESIGN-long-running-supervision.md` for
36
+ the long-running policy.
28
37
 
29
38
  Use `/glla version` to inspect the installed version and compare it with the
30
39
  registry. This checkout may contain unreleased changes; npm is authoritative
@@ -127,6 +136,7 @@ forcing every problem into a loop.
127
136
  /goal # interview + Confirm
128
137
  /goal "... Done when: ..." # direct contract start
129
138
  /goal start "..." # explicit no-interview start
139
+ /goal start # use one clear recent request, or draft safely
130
140
  /goal plan "..." # research-first extended plan
131
141
  /goal status # inspect the current goal
132
142
  /goal pause # pause automatic continuation
@@ -146,6 +156,7 @@ quietly inventing an unbounded backlog.
146
156
  /list "fix the cache. Done when: tests pass"
147
157
  /list plan.md # import a checklist or plan file
148
158
  /list # show active and waiting items
159
+ /list start # activate the queued head, or draft one clear recent request
149
160
  /list next # intentionally activate the next item
150
161
  /list next <n> # choose a specific item
151
162
  /list resume # explicitly retry/resume the list
@@ -162,12 +173,16 @@ If a saved item is malformed or needs a repair, the repair card preserves the
162
173
  full original target, explains the concrete recovery action, and permits one
163
174
  bounded bootstrap turn containing `propose_task_list`. Confirm the redraft;
164
175
  automatic repeats are fenced. Use `/list resume` for an intentional retry and
165
- `/list next` when you intentionally want another queued item.
176
+ `/list next` when you intentionally want another queued item. `/list start` is
177
+ also explicit: it activates the queued head, or—when the queue is empty—uses
178
+ one clear recent user request as a seed for the normal Confirm-gated list
179
+ drafting flow. Ambiguous context is never queued automatically.
166
180
 
167
181
  ### `/loop` — an improvement process
168
182
 
169
183
  ```text
170
184
  /loop # interview + Confirm
185
+ /loop start # use one clear recent target as an explicit metricless start
171
186
  /loop plan # research-first loop design
172
187
  /loop start "reduce flaky tests" measure="..." direction=min
173
188
  /loop start "keep improving the spec" measure=none max=20 cadence=900
@@ -176,6 +191,12 @@ automatic repeats are fenced. Use `/list resume` for an intentional retry and
176
191
  /loop stop
177
192
  ```
178
193
 
194
+ Bare `/loop start` infers only one clear recent target. It does not invent a
195
+ measure, direction, bound, cadence, or branch setting; the command uses the
196
+ existing explicit metricless-start path. If the context is ambiguous, GLLA
197
+ returns to loop drafting so the target and any numeric metric/consent gates
198
+ remain visible.
199
+
179
200
  There are three loop styles:
180
201
 
181
202
  - **Metric:** a bounded command prints one number that honestly represents
@@ -343,16 +364,18 @@ proof of a quota or billing state.
343
364
  - interrupted completion claims remain available for retry and inspection.
344
365
 
345
366
  Use `/glla pause` to freeze supervisor automation without killing active work,
346
- `/glla resume` to release it, and `/glla status` or `/goal status` to inspect
367
+ `/glla resume` to release it, `/glla bug [message]` to capture failure context to `bugs/` without touching durable goal state, and `/glla status` or `/goal status` to inspect
347
368
  what happened.
348
369
 
349
370
  ### Settings worth knowing
350
371
 
351
372
  Open `/glla` for the settings table. The most important choices are:
352
373
 
353
- - **Auditor model / thinking level:** the verifier's model and depth;
354
- - **Main-agent fallback models:** an ordered recovery chain for provider
355
- failures;
374
+ - **Auditor model / thinking level:** the verifier's model and depth; when
375
+ unset, auditor thinking inherits the parent session dial (including `max`);
376
+ - **Main-agent and auditor fallback models:** both roles use the same ordered,
377
+ deselectable, bounded fallback-chain picker for provider failures; the
378
+ auditor's session model remains the final last resort;
356
379
  - **Auto-resume:** whether persisted work may restart automatically after a
357
380
  session loads; explicit resume commands are always available;
358
381
  - **State root:** `workingDir` by default, opt-in `sessionDir`;
@@ -439,8 +462,10 @@ when tracing behavior:
439
462
 
440
463
  The package contains the extension entry point
441
464
  `extensions/loops/goal.ts`, prompt templates, schemas, scripts, docs, examples,
442
- and the full test suite. `audit/` and `.research/` are repository material, not
443
- first-use package content.
465
+ and the user-facing README/install/changelog files. The full test suite remains
466
+ repository material for maintainers and is exercised by `npm run test:all`; it is
467
+ not included in the published tarball. `audit/` and `.research/` are also
468
+ repository material, not first-use package content.
444
469
 
445
470
  ## License
446
471
 
@@ -0,0 +1,116 @@
1
+ # Long-running supervision policy
2
+
3
+ **Decision record: v0.36.0 — 2026-08-28**
4
+
5
+ This document records the GLLA policy for work that can outlive one agent
6
+ turn, one provider session, or one day. It is a project decision record, not a
7
+ change to Pi core, `pi-subagents`, or `pi-memory`.
8
+
9
+ ## Decision
10
+
11
+ GLLA automation is **event-driven and progress-aware**, not duration-guessed.
12
+
13
+ - A lifecycle event, durable state transition, child-progress signal, or
14
+ process completion marker is the primary reason to inspect or advance work.
15
+ - If no public event signal exists, GLLA uses a short adaptive fallback poll
16
+ (`250ms` backoff to the normal safety cadence) rather than sleeping for an
17
+ estimated task duration. A five-second task must not inherit a ten-minute
18
+ wait merely because the system guessed wrong.
19
+ - A live process remains eligible while real output, tool activity, durable
20
+ markers, or child progress proves liveness. A silent or unreachable process
21
+ may be classified as wedged only by the existing bounded safety watchdog.
22
+ Detached auditors have no unconditional wall-clock expiry: legacy wall
23
+ metadata is ignored, while confirmed silence and an individual tool timeout
24
+ remain the bounded safety mechanisms.
25
+ - Timers remain useful for per-attempt backoff, watchdogs, and host safety. A
26
+ timer is never evidence that work completed and is not the definition of a
27
+ long-running process's lifetime. Detached-auditor first-event silence starts
28
+ at the successful worker spawn boundary (with a return-time fallback for
29
+ runtimes that deliver the spawn event too early), so dispatch setup cannot
30
+ consume the worker's startup budget. Cancellation awaits the worker's
31
+ TERM-to-KILL settlement before the attempt is classified or cleaned up.
32
+
33
+ The shared checker covers all GLLA-owned work planes: ordinary goals, list
34
+ items and their queue, metric/spec/audit loops, detached completion auditors,
35
+ tracked subagents, provider recovery, and lifecycle/session transitions.
36
+
37
+ ## Aggressive automation
38
+
39
+ Aggressive mode is the default effective keep-going policy unless the user
40
+ explicitly opts out. Its purpose is unattended long-running work:
41
+
42
+ - Recoverable provider, host, and auditor-infrastructure failures retry with
43
+ bounded per-attempt backoff and durable owner/generation fences.
44
+ - In aggressive mode, a recovery episode has no wall-clock expiry. Legacy
45
+ `autoRetryUntil` fields remain readable for compatibility, but new aggressive
46
+ scheduling must not stop solely because that old horizon elapsed.
47
+ - A semantic auditor disapproval is actionable work: its extracted objections
48
+ become a bounded durable TODO projection and the next continuation works them.
49
+ Repeated identical objections with no new progress are a state-based stop,
50
+ not an invitation to burn more turns.
51
+ - Automation stops on success, explicit user pause/cancel, a non-retriable or
52
+ contradictory semantic result, ownership loss, persistence-integrity failure,
53
+ or repeated no-progress. A cold-start consent/load hold still wins; aggressive
54
+ mode does not silently turn an unattended fresh launch into user consent.
55
+ - A retry must be idempotent with respect to durable state. It must not create
56
+ duplicate workers, overwrite a newer generation, duplicate TODOs, or erase a
57
+ recoverable claim.
58
+
59
+ Conservative mode keeps the pre-v0.36 bounded recovery horizons and explicit
60
+ manual holds. This opt-out is retained for users who prefer a finite
61
+ unattended recovery envelope.
62
+
63
+ ## User-facing completion summaries
64
+
65
+ Every archived terminal objective gets one full six-label recap:
66
+
67
+ ```text
68
+ Outcome: ...
69
+ Changed: ...
70
+ Evidence: ...
71
+ Tests: ...
72
+ Unresolved: ...
73
+ Next: ...
74
+ ```
75
+
76
+ This applies to complete, aborted/cancelled, auto-dropped, full-auditor-IMPOSSIBLE,
77
+ and already-shipped archive paths. A valid executor recap is preserved. A
78
+ partial IMPOSSIBLE verdict remains a decision pause in conservative mode (or
79
+ continues narrowing in aggressive mode); only a full impossible objective is
80
+ terminalized. A missing, generic, or incomplete recap is replaced at the
81
+ central archive boundary by a
82
+ fallback assembled only from recorded GLLA facts: the objective, terminal
83
+ status/reason, durable telemetry, captured audit verdicts, and known archive
84
+ path. It says `not recorded` when a changed-file manifest or test result is not
85
+ available. It never infers a passing test or invents a commit.
86
+
87
+ The full recap lives in the archive and status/history surfaces. Every
88
+ terminal goal notification—including version-bearing already-shipped claims,
89
+ explicit goal/list cancellation, and `/glla wipe`—includes a compact
90
+ projection of all six labels; loop notifications do the same. The terminal
91
+ notification may use a compact excerpt. The executor recap and independent
92
+ auditor verdict stay separate: an approval is not manufactured from the
93
+ presence of a summary.
94
+
95
+ Metric-loop stops use the same six-label contract in their durable loop state
96
+ and `/loop status`, and every terminal loop notification carries a compact
97
+ projection of that recap. Lifecycle/recovery holds are not falsely presented
98
+ as terminal completion.
99
+
100
+ ## Future decision checklist
101
+
102
+ Before adding a new long-running GLLA path, record answers to these questions:
103
+
104
+ 1. What durable or lifecycle signal proves start, progress, recovery, and
105
+ completion?
106
+ 2. If the host has no signal, what is the adaptive fallback, and what bounded
107
+ watchdog identifies confirmed silence without guessing task duration?
108
+ 3. Which failures are recoverable, and which state-based conditions stop
109
+ automation? Is the retry idempotent across reload and owner changes?
110
+ 4. What exact six-label user recap is available after every terminal path? Which
111
+ values are recorded facts, and which must explicitly say `not recorded`?
112
+ 5. Does the change stay at GLLA's public boundary and preserve persistence,
113
+ ownership, lifecycle, auditor, and user-stop semantics?
114
+
115
+ Do not solve an external Pi/core defect by widening GLLA's scope. Keep the
116
+ external-only issue as a documented observation or a separate upstream report.
package/docs/DESIGN.md CHANGED
@@ -117,19 +117,19 @@ architectural decisions that changed the SHAPE of the system:
117
117
  - **The durable claim owns recovery state**: `pendingCompletion.phase` is
118
118
  `running`, `recovery-pending`, or `quota-waiting`. Missing phase is legacy
119
119
  state and is treated as recovery-pending after a fresh lifecycle event.
120
- The isolated attempt id and wall deadline prevent an old generation from
121
- finalizing a newer attempt.
120
+ The isolated attempt id prevents an old generation from finalizing a newer
121
+ attempt; legacy wall-deadline metadata is not a lifetime bound.
122
122
  - **Rebind recovery is immediate but consent-aware**: a replacement
123
123
  `session_start` converts an old running claim to recovery-pending and
124
124
  retries it immediately when the lifecycle handoff or global `autoResume`
125
125
  supplies consent. A cold startup with autoResume off paints the pending
126
126
  claim and waits for `/goal resume`.
127
- - **Auditor bounds have two layers**: no-event inactivity aborts after 10m
128
- only when no auditor tool is active; a live verification tool may finish,
129
- but the complete isolated run has a 30m wall-clock cap. Each auditor tool
130
- also has an independent five-minute ceiling. Both outcomes are
131
- infrastructure failures, never verdicts, and the stored claim remains
132
- retryable.
127
+ - **Auditor liveness has event-derived layers**: no-event inactivity aborts
128
+ after 10m only when no auditor tool is active; a live verification tool may
129
+ finish, and the complete isolated run has no unconditional wall-clock cap.
130
+ Each auditor tool also has an independent five-minute ceiling. These
131
+ watchdog outcomes are infrastructure failures, never verdicts, and the
132
+ stored claim remains retryable.
133
133
 
134
134
  ## Addendum v0.34.22 (detached completion auditor)
135
135
 
@@ -140,9 +140,10 @@ architectural decisions that changed the SHAPE of the system:
140
140
  never loads glla extensions or project context files. In current power mode,
141
141
  bash is not an OS sandbox: it can write repository or goal-state files, so
142
142
  the worker's isolation is process/API isolation rather than immutability. The
143
- worker has independent per-tool and wall-clock bounds. This removes the
144
- previous nested `AgentSession` from the main pi process and prevents a
145
- provider stall in the auditor from occupying the executor's turn.
143
+ worker has independent per-tool and confirmed-silence bounds, with no
144
+ unconditional wall-clock expiry. This removes the previous nested
145
+ `AgentSession` from the main pi process and prevents a provider stall in the
146
+ auditor from occupying the executor's turn.
146
147
  - **Durable job protocol**: request, progress, lock, and result files live
147
148
  under `.pi-glla/audit-jobs/<attemptId>/`. Requests and results are hashed and
148
149
  atomically written. The parent validates attempt/request identity, verdict
@@ -160,10 +161,12 @@ architectural decisions that changed the SHAPE of the system:
160
161
  `audit recovery pending` are distinct. The main session can continue
161
162
  rendering and accepting input while the worker audits; completion/archive or
162
163
  disapproval/continuation happens only after durable result consumption.
163
- - **Bounded worker liveness**: no session event for 10 minutes while no
164
- auditor tool is active aborts the worker; a five-minute per-tool ceiling and
165
- 30-minute wall-clock bound always win. Both are infrastructure failures,
166
- never verdicts, and the claim remains retryable.
164
+ - **Event-derived worker liveness**: no session event for 10 minutes while
165
+ no auditor tool is active aborts the worker; a five-minute per-tool ceiling
166
+ remains armed while a tool is open. There is no unconditional wall-clock
167
+ bound, so active output/tool progress may continue indefinitely. Watchdog
168
+ outcomes are infrastructure failures, never verdicts, and the claim remains
169
+ retryable.
167
170
 
168
171
  ## Addendum v0.34.24 (dispatch proof and display projection safety)
169
172
 
package/docs/INDEX.md CHANGED
@@ -18,11 +18,13 @@ 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.64 continue through the supervisor freeze (`/glla pause`),
21
+ v0.35.14–v0.36.0 continue through the supervisor freeze (`/glla pause`),
22
22
  load hold, auditor picker parity, Windows launch fix, zombie-watchdog
23
23
  subagent carve-out, due-wait backstop, the `/glla agents` visibility panel,
24
24
  durable state-root selection, blank-until-resume auditor context, frozen
25
- subagent recovery, and bounded repair/replan recovery see CHANGELOG.md for
25
+ subagent recovery, bounded repair/replan recovery, production RPC child
26
+ stopping, mandatory hermetic auditor-extension validation, optional provider
27
+ extensions, and bounded zero-stream retry containment — see CHANGELOG.md for
26
28
  the full trail.
27
29
  - `../README.md` — what the plugin is, install, quickstart, and the
28
30
  architectural guarantee (drafting + confirm + detached auditor).
@@ -39,6 +41,7 @@ For shipped docs, the relevant entry points are:
39
41
 
40
42
  ## Architecture
41
43
  - `DESIGN.md` — plugin design (types, state, extension lifecycle)
44
+ - `DESIGN-long-running-supervision.md` — v0.36.0 event/progress-driven supervision, aggressive recovery, terminal recaps, and future decision checklist
42
45
  - `GLLA-POSITIONING-AND-DECOMPOSITION-2026-08-08.md` — ecosystem
43
46
  positioning, competitor review, and the goal.ts decomposition plan
44
47
  (the current strategic doc — read this before touching
@@ -51,6 +54,7 @@ For shipped docs, the relevant entry points are:
51
54
  - `../schemas/` — goal state JSON schema
52
55
  - `../examples/` — example objective files
53
56
  - `../CHANGELOG.md` — user-facing changelog (unreleased at top)
57
+ - `/glla bug` — `extensions/goal-commands.ts:cmdGllaBug` captures failure context to `<stateDir>/bugs/<ts>-<id>.md` without touching `active.jsonl`/`goals/*.md` (see `tests/glla-bug-capture.test.ts`)
54
58
 
55
59
  ## Repository-only material
56
60
  The audit history and competitor research live in `audit/` and `.research/`
@@ -1,60 +1,52 @@
1
- # Vision Assist — see with mmx, not a model switch
1
+ # Vision Assist — native vision first; external tools optional
2
2
 
3
- **v0.34.72** · note.md 2026-08-07: *"the agent is too eager when couldnt see it
4
- tried to use expensive mdoels. we need to special a vision setting where it
5
- called another model or cli like mmx vision to see if stuck. but not just this
6
- we need to specify that it cant be too eager to switch only preapproved."*
3
+ **v0.34.72 policy update** · The executor/auditor should use the native image
4
+ capability of the model currently doing the work whenever it is available.
5
+ No external vision CLI, including MMX, is assumed to be installed.
7
6
 
8
7
  ## Policy
9
8
 
10
- The executor (pi's main agent) has no eyes. When a task needs it to **look**
11
- at something — a screenshot, a UI state, an error dialog, a rendered mockup
12
- it must NOT switch models to get vision. The check routes to the **mmx vision
13
- CLI** (the `mmx-cli` skill, MiniMax VLM):
9
+ When a task needs the model to **look** at a screenshot, UI state, error dialog,
10
+ or rendered mockup:
14
11
 
15
- ```bash
16
- mmx vision describe --image <path-or-url> --prompt "<question>" --quiet --non-interactive
17
- ```
12
+ 1. Use the current model's native image capability first. This means the main
13
+ model for executor work or the configured auditor model for detached audit
14
+ work.
15
+ 2. Do not switch models merely to obtain vision.
16
+ 3. If native image input is unavailable, use an external vision provider only
17
+ after its availability has been explicitly confirmed. MMX is an optional
18
+ example, not a default or package requirement:
18
19
 
19
- - The image is usually a screenshot the user already pasted into the
20
- conversation (e.g. `/home/dracon/Pictures/Screenshots/...`). Pass its path
21
- straight through.
22
- - Keep the question short and specific: *"What does this screenshot show?"*,
23
- *"Is there an error dialog?"*, *"What is the terminal output?"*.
24
- - Reading the returned description is the agent's job — no model switch
25
- needed. (Verified 2026-08-07: `mmx vision describe` returns clean JSON/text
26
- with `status_code: 0`.)
20
+ ```bash
21
+ mmx vision describe --image <path-or-url> --prompt "<question>" --quiet --non-interactive
22
+ ```
27
23
 
28
- ## The preapproval gate (model switches)
24
+ 4. If neither native vision nor a confirmed external provider is available,
25
+ state that visual evidence is unavailable and request a supported capture or
26
+ user description. Never invent a visual observation or silently assume MMX.
29
27
 
30
- A model switch is sanctioned **only when the target is preapproved** — i.e.
31
- NOT in the `forbiddenModels` policy:
28
+ ## The preapproval gate (model switches)
32
29
 
33
- - Default forbidden list: empty no opinionated ban list ships. Users can
34
- add patterns such as `gpt-5.5`, `sonnet`, or `opus`; matches are
35
- case-insensitive substrings against the `provider/id` ref.
36
- - `/glla` → **Keep-going** → **Forbidden models** edits the list;
37
- `blockForbiddenModelSwitches` (default on) reverts an explicitly forbidden
38
- selection to the previous model.
39
- - Every switch to a forbidden model is ledgered as `forbidden_model_switch`
40
- (with `blocked: true|false`).
41
- - With vision assist on (default), the same event also appends a
42
- `vision_assist` ledger entry — the routing alternative: `{ route:
43
- "mmx-vision", blockedSwitch: <ref>, reason: "forbidden_model_switch" }`.
30
+ A model switch is not the default solution to a visual check. A preapproved
31
+ model may be selected only when the user explicitly requests it or it is needed
32
+ for the ordinary task—not as an assumed vision workaround.
44
33
 
45
- Even a preapproved vision-capable model is a second choice: mmx vision is the
46
- default for every vision check.
34
+ - Default `forbiddenModels` is empty; users may add patterns such as `gpt-5.5`,
35
+ `sonnet`, or `opus`.
36
+ - `/glla` → **Keep-going** → **Forbidden models** edits that list.
37
+ - `blockForbiddenModelSwitches` (default on) blocks explicitly forbidden
38
+ selections and records `forbidden_model_switch`.
39
+ - Vision routing is recorded as `vision_assist`, including the selected route
40
+ (`main-model`, confirmed `mmx-vision`, `model-switch`, or `unavailable`).
47
41
 
48
42
  ## The setting
49
43
 
50
44
  `visionAssist` (default **on** — opt-out):
51
45
 
52
- - **on** → every continuation prompt carries the `## VISION-ASSIST SEE WITH
53
- MMX, NOT A MODEL SWITCH` directive (`extensions/vision-assist.ts`
54
- `VISION_ASSIST_GUIDANCE`), and a forbidden switch also records the
55
- `vision_assist` routing entry.
56
- - **off** → no vision guidance is injected; the `forbiddenModels` gate still
57
- stands (forbidden switches remain blocked/ledgered).
46
+ - **on** → continuation prompts carry the native-vision-first guidance and
47
+ forbidden-switch events can record a `vision_assist` entry.
48
+ - **off** no vision guidance is injected; the forbidden-model gate still
49
+ stands.
58
50
 
59
51
  Edit: `/glla` → **Keep-going** → **Vision assist**, then choose **off**.
60
52
 
@@ -63,13 +55,15 @@ Edit: `/glla` → **Keep-going** → **Vision assist**, then choose **off**.
63
55
  | Piece | Where |
64
56
  |---|---|
65
57
  | Guidance block (single source of truth) | `extensions/vision-assist.ts` → `VISION_ASSIST_GUIDANCE` |
66
- | Command builder | `visionDescribeCommand(imagePath, question?)` |
67
- | Routing rule (pure) | `routeVisionCheck(request)` — mmx by default; forbidden target mmx + `blockedSwitch`; preapproved target `model-switch` allowed |
58
+ | Optional MMX command builder | `visionDescribeCommand(imagePath, question?)` |
59
+ | Routing rule (pure) | `routeVisionCheck(request)` — native main-model route by default; confirmed MMX is optional; forbidden target never forces an unconfirmed tool |
68
60
  | Ledger payload builder | `visionAssistLedger(route, request)` |
69
- | Continuation injection | `extensions/goal-continuation.ts` pushes `VISION_ASSIST_GUIDANCE` into the continuation directives (gated on `visionAssist !== false`) |
61
+ | Continuation injection | `extensions/goal-continuation.ts` pushes `VISION_ASSIST_GUIDANCE` into continuation directives (gated on `visionAssist !== false`) |
62
+ | Visual audit prompt | `extensions/goal-loop-auditor.ts` requires fresh evidence and does not assume an external tool |
70
63
  | 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
- | Setting | `extensions/goal-settings.ts` (default true), menu row in `extensions/settings-menu.ts`, editor + `/glla` row in `extensions/loops/goal.ts` |
64
+ | Setting | `extensions/goal-settings.ts` (default true), menu row in `extensions/settings-menu.ts` |
72
65
  | Tests | `tests/vision-assist.test.ts` |
73
66
 
74
- The `vision_assist` ledger type is the audit trail: every entry says where the
75
- check routed and (when a switch was blocked) which model was refused.
67
+ The `vision_assist` ledger entry is the audit trail: it says whether the check
68
+ used the current model, a confirmed optional provider, an explicitly allowed
69
+ model switch, or had no safe visual path.
@@ -104,13 +104,13 @@ Off by default. Set a per-goal budget and crossing it pauses the goal:
104
104
  ## The auditor model rule
105
105
 
106
106
  The detached auditor uses an explicit bounded cascade: an optional primary
107
- pin, an optional fallback pin, then your pi session model. A model that fails
107
+ pin, an ordered list of up to ten fallback pins, then your pi session model. A model that fails
108
108
  at runtime is retried once and the next detached candidate is tried; the
109
109
  plugin never falls back into the parent in-process session.
110
110
 
111
111
  ```
112
- # /glla → Auditor model row (and Auditor fallback), or .pi-glla/settings.json
113
- { "auditorModel": "provider/model-id" }
112
+ # /glla → Auditor model row (and Auditor fallback models), or .pi-glla/settings.json
113
+ { "auditorModel": "provider/model-id", "auditorModelFallbacks": ["provider/backup-1", "provider/backup-2"] }
114
114
  ```
115
115
 
116
116
  If every candidate errors with auth/provider failures, the stored completion
@@ -158,14 +158,29 @@ export function resolveAuditorAllowedExtensions(
158
158
  specs: string[] | undefined,
159
159
  home: string,
160
160
  cwd?: string,
161
+ settingsBase?: string,
161
162
  ): string[] {
162
163
  const out: string[] = [];
163
164
  const seen = new Set<string>();
165
+ const userBase = path.join(home, ".pi", "agent");
166
+ const projectBase = cwd ? path.join(cwd, ".pi") : undefined;
164
167
  for (const spec of normalizeAuditorAllowedExtensions(specs)) {
165
- const resolved = resolveAuditorExtensionSpec(spec, { home, cwd, base: path.join(home, ".pi", "agent") });
166
- if (!resolved || seen.has(resolved)) continue; // not installed here skip, don't emit a dead spec
167
- seen.add(resolved);
168
- out.push(resolved);
168
+ const trimmed = spec.trim();
169
+ const isLocal = !trimmed.startsWith("npm:") && !parseGitSpec(trimmed) && !trimmed.startsWith("~") && !path.isAbsolute(trimmed) && !/^[a-z]+:/i.test(trimmed);
170
+ const bases = settingsBase
171
+ ? [settingsBase]
172
+ : isLocal && projectBase
173
+ ? [projectBase, userBase]
174
+ : [userBase];
175
+ const candidates = bases
176
+ .map((base) => resolveAuditorExtensionSpec(trimmed, { home, cwd, base }))
177
+ .filter((resolved): resolved is string => !!resolved);
178
+ const unique = [...new Set(candidates)];
179
+ // A relative entry found in both scopes is ambiguous: silently choosing
180
+ // one could load a different extension than the settings author named.
181
+ if (unique.length !== 1 || seen.has(unique[0]!)) continue;
182
+ seen.add(unique[0]!);
183
+ out.push(unique[0]!);
169
184
  }
170
185
  return out;
171
186
  }