pi-goal-list-loop-audit 0.35.13 → 0.35.32
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 +366 -0
- package/INSTALL.md +3 -3
- package/LIST-PHILOSOPHY.md +90 -0
- package/PLAN.md +316 -0
- package/README.md +108 -13
- package/docs/DESIGN-subagent-visibility.md +76 -0
- package/docs/DESIGN.md +59 -8
- package/docs/GLLA-POSITIONING-AND-DECOMPOSITION-2026-08-08.md +6 -1
- package/docs/INDEX.md +4 -0
- package/docs/VISION-ASSIST.md +2 -2
- package/extensions/auditor-extensions.ts +289 -0
- package/extensions/goal-agents-panel.ts +185 -0
- package/extensions/goal-commands.ts +120 -6
- package/extensions/goal-continuation.ts +45 -2
- package/extensions/goal-heartbeat.ts +176 -5
- package/extensions/goal-loop-auditor-process.ts +26 -0
- package/extensions/goal-loop-auditor.ts +3 -5
- package/extensions/goal-loop-backoff.ts +79 -0
- package/extensions/goal-loop-core.ts +97 -4
- package/extensions/goal-loop-display.ts +107 -8
- package/extensions/goal-loop-forever.ts +39 -1
- package/extensions/goal-loop-shield.ts +114 -25
- package/extensions/goal-loop.ts +66 -1
- package/extensions/goal-recovery.ts +8 -2
- package/extensions/goal-settings.ts +23 -0
- package/extensions/goal-state.ts +11 -0
- package/extensions/loops/goal-activation.ts +226 -25
- package/extensions/loops/goal-auditor-hooks.ts +39 -3
- package/extensions/loops/goal-list-queue.ts +17 -1
- package/extensions/loops/goal-orchestrator.ts +28 -1
- package/extensions/loops/goal-settings-ui.ts +96 -5
- package/extensions/loops/goal-tools.ts +82 -28
- package/extensions/loops/goal-ui.ts +105 -1
- package/extensions/loops/goal.ts +7 -7
- package/extensions/multi-model-picker.ts +45 -7
- package/extensions/settings-menu.ts +10 -0
- package/package.json +8 -3
- package/schemas/goal.schema.json +2 -0
- package/scripts/goal-auditor-launch.mjs +19 -1
- package/scripts/goal-auditor-worker.mjs +15 -0
- package/scripts/verify-auditor-extensions-offline.mjs +59 -0
package/PLAN.md
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
# PLAN — pi-goal-list-loop-audit
|
|
2
|
+
|
|
3
|
+
Living plan for the project. Update this file as decisions land or milestones close.
|
|
4
|
+
New here? Start with README.md and INSTALL.md — this file is the historical
|
|
5
|
+
plan, not the onboarding path.
|
|
6
|
+
Last updated: v0.29.6 (header refresh). The milestones
|
|
7
|
+
below cover the v0.1.0–v0.7.0 scaffold era; later decisions live in CHANGELOG.md
|
|
8
|
+
(current through v0.29.6) and the current-state addendum in docs/DESIGN.md.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 0. Product definition (frozen)
|
|
13
|
+
|
|
14
|
+
- **What it is**: a pi-coding-agent extension that supervises long-running work to *verified* completion.
|
|
15
|
+
- **Core mechanism**: a shared goal state machine + an `agent_end`-driven continuation loop + an **isolated auditor** (fresh pi session, no extensions, no skills, power-mode audit tools: read/grep/find/ls/bash) that must approve before a goal is marked complete.
|
|
16
|
+
- **Three loops on one machine**:
|
|
17
|
+
- **goal** — one ordered goal, audited (`/goal`)
|
|
18
|
+
- **list** — a queue of goals, each audited in turn (`/list`)
|
|
19
|
+
- **loop** — a forever-polish loop around a measurable target (`/loop`)
|
|
20
|
+
- **Naming is frozen**: commands are `/goal*`, `/list*`, `/loop*`. No `pi-gla-` prefix, no `oracle/sisyphus/squad/forge` metaphors anywhere (code, files, docs, keywords).
|
|
21
|
+
|
|
22
|
+
### Non-goals (v0.x)
|
|
23
|
+
|
|
24
|
+
- No interop with `pi-goal-x` state (`.pi/goals/`). Clean break, `.pi-gla/` only.
|
|
25
|
+
- No web dashboard, no remote control, no multi-machine coordination.
|
|
26
|
+
- No planner/decomposer that invents the goal for the user (drafting *clarifies*; it does not originate).
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 1. Milestones & acceptance criteria
|
|
31
|
+
|
|
32
|
+
### M0 — v0.1.0-alpha.1 scaffold ✅ (done)
|
|
33
|
+
|
|
34
|
+
- [x] Package layout, LICENSE, README, CHANGELOG, DESIGN, tsconfig
|
|
35
|
+
- [x] `extensions/loops/goal.ts` — commands + agent tools + agent_end loop
|
|
36
|
+
- [x] `extensions/goal-loop-core.ts` — types, JSONL ledger, markdown renderer
|
|
37
|
+
- [x] `extensions/goal-loop-auditor.ts` — isolated auditor session
|
|
38
|
+
- [x] `extensions/goal-loop-backoff.ts` — 5-min hard cap
|
|
39
|
+
- [x] `prompts/goal-loop-continuation.md`, `schemas/goal.schema.json`
|
|
40
|
+
- [x] 24 unit tests green (`npm test`)
|
|
41
|
+
- **Exit evidence**: `npm test` → 24/24 pass (verified 2026-07-20).
|
|
42
|
+
|
|
43
|
+
### M1 — v0.1.0 (first real release)
|
|
44
|
+
|
|
45
|
+
Scope: make the goal loop actually work end-to-end in a live pi session. No new features.
|
|
46
|
+
|
|
47
|
+
- [ ] **Type-check clean**: `npm run check` (tsc --noEmit) → 0 errors.
|
|
48
|
+
- Known risk: `ExtensionContext`, `defineTool` import path, `pi.registerCommand` arg shapes were written against memory of pi-goal-x, not verified against the installed pi 0.74 API.
|
|
49
|
+
- [x] **Live smoke test** ✅ 2026-07-20 — full loop verified end-to-end in tmux: `/goal` → agent works → `complete_goal` → isolated auditor (opencode/deepseek-v4-flash-free, extension-less) approves → archived with clean 1-entry history + real auditor report.
|
|
50
|
+
- [x] **Fix whatever the smoke test breaks** ✅ — 6 real fixes: (1) API imports from public entrypoint + pi-ai/pi-agent-core types; (2) `sendMessage` on `pi` API not `ctx`; (3) stale-ctx crash → `lastCtx`/`rememberCtx` pattern; (4) `details:{}` in tool results, async handlers, `tool_call` event name; (5) auditor model default → `ctx.model` + string-ref resolver; (6) audit-history pollution — record only non-empty reports, cap at 20, include `error` field.
|
|
51
|
+
- [x] **Escape hatch verified** ✅ (with caveat) — Esc during audit aborts the pi turn; the auditor session may complete detached. Loop recovers cleanly via `agent_end` (verified live: 3 empty audits then approval). pi-goal-x's fancy Escape dialog is v0.2.0 scope. Abort signal is threaded into the auditor for when pi wires tool-level abort properly.
|
|
52
|
+
- [x] **Backoff cap verified** ✅ (incidentally, live) — openrouter 403 storm triggered exactly "Goal paused: 5 consecutive errors" auto-pause.
|
|
53
|
+
- [ ] Update CHANGELOG, tag `v0.1.0`, `npm publish`.
|
|
54
|
+
|
|
55
|
+
**Live smoke script** (target: < 5 min):
|
|
56
|
+
```
|
|
57
|
+
pi -e /home/dracon/Dev/pi-goal-list-loop-audit
|
|
58
|
+
> /goal "Create file hello.txt containing the word world. Done when: grep -q world hello.txt"
|
|
59
|
+
# expect: agent writes file, calls complete_goal, auditor approves, goal archived
|
|
60
|
+
> /goal status # expect: complete, audit history shows 1 approved
|
|
61
|
+
cat .pi-gla/active.jsonl | tail -3
|
|
62
|
+
ls .pi-gla/archive/ # expect: one .md file
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### M2 — v0.2.0 (list + drafting + regression_shield) ✅ (2026-07-20)
|
|
66
|
+
|
|
67
|
+
- [x] **Loop 2: `/list`** — `add|show|next|remove <n>|clear`; each item is a full goal; completing/aborting one auto-activates the next; session restart resumes a non-empty queue. Live-verified: two items auto-advanced through audit to archive.
|
|
68
|
+
- [x] **Drafting**: `/goal` no-args → agent grills one question at a time → `propose_goal_draft` → real Confirm dialog. Live-verified end-to-end (drafted goal completed with shield).
|
|
69
|
+
- [x] **regression_shield**: auditor must quote raw output per contract item in an `<evidence>` block; orchestrator converts evidence-free `<approved/>` into disapproval. Pure logic in `goal-loop-shield.ts`; 14 unit tests + live verification (verbatim `<evidence>` in history).
|
|
70
|
+
- [x] **Escape dialog**: abort → complete-without-audit / continue choice.
|
|
71
|
+
- [x] **Provider warning**: one-time `session_start` notice when the session provider isn't a confirmed built-in and no auditorModel is set. Live-verified on kilocode.
|
|
72
|
+
- [x] **Inline contract extraction**: one-liner `Done when:` now extracts (was silently skipped before — the shield never engaged on one-liners).
|
|
73
|
+
- [x] **Live integration harness**: `scripts/smoke.sh [goal|list|draft]` — goal scenario 5/5 assertions green.
|
|
74
|
+
- [x] CHANGELOG, version 0.2.0, publish.
|
|
75
|
+
- [ ] `max_subtasks_per_task` cap → moved to M3 (no task-list creation tool exists yet; capping nothing is premature).
|
|
76
|
+
|
|
77
|
+
### M3 — v0.3.0 (loop) ✅ (2026-07-20) — design
|
|
78
|
+
|
|
79
|
+
**Loop 3 is metric-driven, not vibes-driven.** This is the anti-doorknob design:
|
|
80
|
+
pi-loop-mode's failure mode was endless "improvement" churn (the DOORKNOB problem).
|
|
81
|
+
Our loop only believes a number.
|
|
82
|
+
|
|
83
|
+
**Model**:
|
|
84
|
+
- User supplies: `target` (what to improve), `measure` (shell command that prints
|
|
85
|
+
a number), `direction` (min|max). Optional: `window` (plateau window, default 5),
|
|
86
|
+
`max` (iteration cap, default 50).
|
|
87
|
+
- On `/loop start`: orchestrator runs `measure` → baseline.
|
|
88
|
+
- On every `agent_end` while active: orchestrator runs `measure` → compare to best:
|
|
89
|
+
- improved (min: value < best; max: value > best) → new best, stall=0
|
|
90
|
+
- not improved / measure failed → stall++
|
|
91
|
+
- The **orchestrator** runs the measure (via `pi.exec`), never the agent —
|
|
92
|
+
the agent cannot fake the number.
|
|
93
|
+
- Stop conditions: `stall >= window` (plateau), `iteration >= max`, or `/loop stop`.
|
|
94
|
+
- No git-based auto-revert in v0.3.0 (too dangerous with uncommitted user work);
|
|
95
|
+
on regression the agent is instructed to undo its own last change, and the next
|
|
96
|
+
measure verifies.
|
|
97
|
+
- **No auditor in loop 3**: the metric IS the verdict. Documented.
|
|
98
|
+
- Mutual exclusion: a `/loop` cannot start while a goal/list is active and vice versa.
|
|
99
|
+
|
|
100
|
+
**Command shape**: `/loop start "<target>" measure="<cmd>" direction=min [window=5] [max=50]`
|
|
101
|
+
`/loop` (status) · `/loop stop`
|
|
102
|
+
|
|
103
|
+
**Collision note**: `/loop` collides with pi-loop-mode — the M1 collision detector
|
|
104
|
+
handles UX; smoke tests run under a bare `PI_CODING_AGENT_DIR` to isolate.
|
|
105
|
+
|
|
106
|
+
**Also in M3**:
|
|
107
|
+
- `propose_task_list` tool + `max_subtasks_per_task: 5` cap (M2 carry-over — makes
|
|
108
|
+
the existing complete_task/update_task_status tools actually usable).
|
|
109
|
+
- `notify=<cmd>` setting: shell out on goal complete / goal pause / loop stop
|
|
110
|
+
(message passed as `$1`; config-gated, no deps).
|
|
111
|
+
- Unit tests (metric parse, plateau logic, task cap) + `/loop` smoke scenario.
|
|
112
|
+
|
|
113
|
+
**M3 verification evidence** (all live, 2026-07-20):
|
|
114
|
+
- `/loop` smoke: metric 5→0 over 5 improving iterations (stall reset each time),
|
|
115
|
+
3 stall iterations at 0, plateau stop at window=3, `loop_stopped` + per-iteration
|
|
116
|
+
`loop_measured` in ledger, notify fired on stop. `scripts/smoke.sh loop` 5/5.
|
|
117
|
+
- Regression check: `goal` 5/5, `list` 4/4, `draft` 3/3 — all scenarios hermetic
|
|
118
|
+
(bare agent dir + readiness wait) after two collision/REPL-race flakes.
|
|
119
|
+
- 73 unit tests green; `tsc --noEmit` clean.
|
|
120
|
+
- Found + fixed during M3: `/gla` whitespace split mangled quoted
|
|
121
|
+
notify commands; smoke `wait_for "plateau"` matched agent prose instead of
|
|
122
|
+
the orchestrator's stop text (assertions raced the loop).
|
|
123
|
+
|
|
124
|
+
### M7 — v0.7.0 (global config tier) ✅ (2026-07-21)
|
|
125
|
+
|
|
126
|
+
User directive: settings are not per-goal/loop/list — there should be ONE
|
|
127
|
+
global config you set once and rarely open. Shipped: project > global >
|
|
128
|
+
defaults resolution, `/gla` writes global by default (`project`
|
|
129
|
+
prefix for local overrides), provenance display, 4 mergeSettings unit tests,
|
|
130
|
+
live-verified both tiers + no-leak smoke. Docs updated.
|
|
131
|
+
|
|
132
|
+
### M6 — v0.6.0 (draft everything) ✅ (2026-07-20)
|
|
133
|
+
|
|
134
|
+
User directive: for a long-running thing, a draft up front is better. Drafting
|
|
135
|
+
exists only for `/goal`; `/list add` takes raw strings, and `/loop start`
|
|
136
|
+
demands a correct target+measure+direction in one blind shot — the most
|
|
137
|
+
expensive place to be wrong (up to 50 iterations before plateau stops a bad
|
|
138
|
+
metric). Draft all three loops; for `/loop`, validate the metric BEFORE
|
|
139
|
+
confirming.
|
|
140
|
+
|
|
141
|
+
1. **Unified drafting modes**: drafting target becomes `"goal" | "list" |
|
|
142
|
+
"loop"`. `/goal` (existing), `/list add` with no args (draft → confirmed
|
|
143
|
+
contract goes into the QUEUE instead of activating), `/loop` with no args
|
|
144
|
+
(draft → confirmed loop config starts the loop).
|
|
145
|
+
2. **`/loop` drafting with measure test-run** (centerpiece): the agent grills
|
|
146
|
+
about target + what number represents progress, then calls
|
|
147
|
+
`propose_loop_draft(target, measureCmd, direction, window?, max?)`. The
|
|
148
|
+
**orchestrator runs the measure command once** and shows target + measure +
|
|
149
|
+
real output + parsed number + direction in the Confirm dialog:
|
|
150
|
+
"`grep -c TODO src.txt` → `42` (min). Start?" A broken measure (no number)
|
|
151
|
+
is shown as such and the agent is told to fix the proposal. User validates
|
|
152
|
+
the metric before a single iteration burns tokens.
|
|
153
|
+
3. **`/goals` archive browser**: list archived goals (id, status, stop reason,
|
|
154
|
+
objective head) from `.pi-gla/archive/`. Long-running tool needs history.
|
|
155
|
+
4. Gates: unit tests (draft-mode routing, loop-draft measure parsing), smoke
|
|
156
|
+
scenarios for loop-drafting and list-drafting, publish v0.6.0.
|
|
157
|
+
|
|
158
|
+
**M6 evidence** (2026-07-20):
|
|
159
|
+
- Loop drafting live: agent located num.txt itself, proposed `cat num.txt`;
|
|
160
|
+
Confirm dialog showed the real test-run ("Parsed number: 10, lower is
|
|
161
|
+
better"); confirmed loop ran improving iterations immediately.
|
|
162
|
+
- List drafting live: confirmed contract → list_added → auto-activate →
|
|
163
|
+
audited → archived.
|
|
164
|
+
- `/goals` parsing verified against real archive entries.
|
|
165
|
+
- 89 unit tests, tsc clean.
|
|
166
|
+
|
|
167
|
+
**Still deferred**: live footer/TUI widget (now the ONLY remaining scoreboard
|
|
168
|
+
gap vs pi-loop-mode/pi-goal-x).
|
|
169
|
+
|
|
170
|
+
### M5 — v0.5.0 (self-sufficiency) ✅ (2026-07-20)
|
|
171
|
+
|
|
172
|
+
User directive: a goal loop that dies silently after compaction and needs an
|
|
173
|
+
EXTERNAL plugin (`@badliveware/pi-compaction-continue`) to restart it is a hole
|
|
174
|
+
in OUR plugin. Liveness is the loop's own job. Bake it in; cut the watchdog.
|
|
175
|
+
|
|
176
|
+
1. **Heartbeat self-watchdog** (replaces pi-compaction-continue for our loops):
|
|
177
|
+
a 15s interval checks: active goal-or-loop AND session idle AND no pending
|
|
178
|
+
continuation/loop timer AND no activity for 60s → re-fire the continuation.
|
|
179
|
+
One check covers every stall cause (compaction-eaten turn, dropped message,
|
|
180
|
+
stale ctx). Stall accounting: a heartbeat-nudged turn with ZERO tool calls
|
|
181
|
+
counts as a nudge; 3 consecutive → pause (mirrors the watchdog's 3-nudge cap,
|
|
182
|
+
but scoped to real goal progress). Pure decision function unit-tested.
|
|
183
|
+
Scope note: this covers stalls while a goal/loop is active. Non-goal sessions
|
|
184
|
+
are the user's own business — they are at the keyboard.
|
|
185
|
+
2. **`/goal tweak "<text>"`** — edit the active goal's objective in place
|
|
186
|
+
(Confirm dialog shows old vs new; contract re-extracted from the new text).
|
|
187
|
+
Closes the last pi-goal-x feature gap we use.
|
|
188
|
+
3. **Structured drafting forms**: drafting prompt prefers `ask_user_question`
|
|
189
|
+
(rpiv-ask-user-question) when the tool is available in the session — closes
|
|
190
|
+
the structured-forms gap vs pi-goal-x without a hard dependency.
|
|
191
|
+
4. **Rig cuts** (after publish): `pi-codex-goal`, `pi-loop-mode`,
|
|
192
|
+
`@badliveware/pi-compaction-continue`. AGENTS.md stack table rewritten:
|
|
193
|
+
goal plane = pi-goal-list-loop-audit.
|
|
194
|
+
|
|
195
|
+
**M5 evidence** (2026-07-20):
|
|
196
|
+
- Heartbeat: 8 unit tests for the stall predicate + nudge accounting; `goal`
|
|
197
|
+
smoke 5/5 with the heartbeat interval live through the full cycle.
|
|
198
|
+
- `/goal tweak`: implemented with Confirm dialog + contract re-extraction.
|
|
199
|
+
- Drafting prompt prefers `ask_user_question` when available.
|
|
200
|
+
- 89 unit tests, tsc clean.
|
|
201
|
+
|
|
202
|
+
**Deferred**: live footer/TUI widget (pi-loop-mode's dashboard is the one thing
|
|
203
|
+
we genuinely lose by cutting it; v0.6.0 candidate if missed).
|
|
204
|
+
|
|
205
|
+
### M4 — v0.4.0 (completion release) ✅ (2026-07-20)
|
|
206
|
+
|
|
207
|
+
Everything left, in one release. Completes the 6-flaw list and makes the docs honest.
|
|
208
|
+
|
|
209
|
+
1. **Auditor compaction (flaw #3 — the LAST open flaw)**. Enable pi's built-in
|
|
210
|
+
compaction in the auditor session (currently `compaction: { enabled: false }`).
|
|
211
|
+
Safety argument: regression_shield is orchestrator-side — a compaction-degraded
|
|
212
|
+
auditor produces weaker evidence → disapproval, never false approval. The risky
|
|
213
|
+
direction (silent false approval) is structurally impossible.
|
|
214
|
+
2. **Schema + examples + docs sync**. `schemas/goal.schema.json` still says "oracle"
|
|
215
|
+
and "v0.1.0 loop 1 only"; `examples/example-objective.md` used `/pi-gla-set`;
|
|
216
|
+
`tests/README.md` has stale counts; `docs/DESIGN.md` needs the v0.2/v0.3 addendum.
|
|
217
|
+
3. **tokensUsed wiring + limit enforcement**. `AgentEndEvent.messages` carries
|
|
218
|
+
`usage.totalTokens` per assistant message — accumulate per goal. `tokensLimit`
|
|
219
|
+
becomes a real cost guard: crossing it pauses the goal with a clear reason
|
|
220
|
+
(configurable via `/glla tokenlimit=`).
|
|
221
|
+
4. **Resumption notice** on `session_start`: if a goal is active or a loop is
|
|
222
|
+
running, say so. (The "plugin vanished" self-check from D4 is impossible from
|
|
223
|
+
inside the plugin — absent code cannot run. Recorded as rejected.)
|
|
224
|
+
5. **Loop 3 git-branch mode** (`branch=1` flag): at `/loop start`, create scratch
|
|
225
|
+
branch `pi-glla-loop/<id>`; commit after each improving iteration; on regression
|
|
226
|
+
`git reset --hard` to the last improving commit ON THE SCRATCH BRANCH ONLY.
|
|
227
|
+
The user's branch and uncommitted work are never touched. Requires: git repo,
|
|
228
|
+
and we refuse `branch=1` with a dirty tree (refuse to mix user work into the
|
|
229
|
+
scratch branch).
|
|
230
|
+
6. **Draft reject path** in the smoke harness (Confirm → No → agent refines).
|
|
231
|
+
|
|
232
|
+
After M4 the 6-flaw list is closed and the roadmap table is all-shipped.
|
|
233
|
+
|
|
234
|
+
**M4 verification evidence** (all live, 2026-07-20):
|
|
235
|
+
- Auditor compaction enabled; `goal` smoke 5/5 green after the change.
|
|
236
|
+
- Token guard: 3 unit tests for dedup accumulation; limit-pause path wired in
|
|
237
|
+
agent_end with settings-configurable budget.
|
|
238
|
+
- branch=1 live: 5 improvement commits on scratch branch, 0 for stalls, main
|
|
239
|
+
untouched, returned to main on plateau with merge instructions.
|
|
240
|
+
- `draft-reject` smoke 6/6: Confirm → reject → refine → Confirm → approval.
|
|
241
|
+
- Resumption notice on session_start for active goal/loop.
|
|
242
|
+
- 81 unit tests, tsc clean, all 5 smoke scenarios green.
|
|
243
|
+
- **6/6 pi-goal-x flaws now closed.** The D4 "plugin vanished" self-check is
|
|
244
|
+
recorded as REJECTED (absent code cannot run); replaced by the resumption
|
|
245
|
+
notice.
|
|
246
|
+
|
|
247
|
+
**Deferred to v0.4.0 (with justification)**: (superseded — this release)
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## 2. Open decisions (must resolve before M1 publish)
|
|
252
|
+
|
|
253
|
+
### D1 — Command collision strategy ✅ RESOLVED
|
|
254
|
+
|
|
255
|
+
**Verified in installed pi source** (`dist/core/extensions/runner.js:resolveRegisteredCommands`):
|
|
256
|
+
- Duplicate command names **never throw** and **never clobber** — both survive.
|
|
257
|
+
- First registrant keeps the bare name (`/goal`); later ones get `/goal:2`, `/goal:3`, …
|
|
258
|
+
- So the failure mode is degraded UX (our command reachable as `/goal:2`), never breakage.
|
|
259
|
+
|
|
260
|
+
**Decision: option 1 — plain names + detect-and-warn.** Implemented in `extensions/loops/goal.ts:warnOnCommandCollision`: at `session_start` we count registered command names via `pi.getCommands()`, and if any of ours (`goal`, `list`, `loop`, `goal-*`) appears more than once we notify the user with the degraded invocation name. Collision check is fail-silent (non-fatal by design).
|
|
261
|
+
|
|
262
|
+
### D2 — Auditor model default ✅ RESOLVED (with a hard discovered constraint)
|
|
263
|
+
|
|
264
|
+
**Discovered during M1 smoke (2026-07-20): the auditor session has no extensions, so it can only use BUILT-IN providers.** On this rig the main session ran kilocode (`tencent/hy3:free`) — an extension-registered provider — and every auditor spawn failed with `No API key found for kilocode`. Verified bare-session matrix: `opencode/deepseek-v4-flash-free` works extension-less; kilocode/zenmux/kimi-coding do not.
|
|
265
|
+
|
|
266
|
+
**Decision**: default = session model (works when the session model is built-in); `/gla model=provider/id` overrides for rigs running extension-provided session models. The `/gla` save message now warns about the built-in-provider constraint. `resolveAuditorModel` documents it in code. v0.2.0 should add a startup check: if session model's provider is extension-registered and no auditorModel is set, warn once.
|
|
267
|
+
|
|
268
|
+
### D3 — State dir name ✅ RESOLVED
|
|
269
|
+
|
|
270
|
+
**Keep `.pi-gla/`.** Internal-only path; renaming costs a migration for zero user-visible gain. If we ever regret it, the rename is a one-line constant (`piGlaDir` in `goal-loop-core.ts`) plus a migrate-on-read.
|
|
271
|
+
|
|
272
|
+
### D4 — Persistence across pi updates ✅ RESOLVED
|
|
273
|
+
|
|
274
|
+
Known rig behavior (from earlier audits): `pi update` overwrites `~/.pi/agent/npm/node_modules/`, which can wipe npm-installed plugins. **Decision: document both install paths in INSTALL.md** — `pi install npm:pi-goal-list-loop-audit` (convenient, re-install after `pi update`) and project-local `.pi/extensions/` (permanent, survives updates). The `-e <path>` dev flow is unaffected. v0.2.0 should add a `session_start` self-check that notifies if the plugin vanished from the loaded set while `.pi-gla/active.jsonl` shows an active goal.
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## 3. Verification gates (apply to every milestone)
|
|
279
|
+
|
|
280
|
+
A milestone is not done until:
|
|
281
|
+
|
|
282
|
+
1. `npm test` green (unit).
|
|
283
|
+
2. `npm run check` clean (types).
|
|
284
|
+
3. Live smoke passes (M1+).
|
|
285
|
+
4. CHANGELOG entry written.
|
|
286
|
+
5. No `oracle|sisyphus|squad|forge|pi-gla-` string outside `.pi-gla/` dir name (run the grep).
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
grep -rn "oracle\|sisyphus\|squad\|forge" \
|
|
290
|
+
tests/ extensions/ prompts/ docs/ examples/ README.md INSTALL.md CHANGELOG.md package.json \
|
|
291
|
+
| grep -v node_modules
|
|
292
|
+
# expect: no output
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## 4. Risks
|
|
298
|
+
|
|
299
|
+
| Risk | Likelihood | Mitigation |
|
|
300
|
+
|---|---|---|
|
|
301
|
+
| pi extension API drift (0.74 → next) | medium | pin peerDeps `*`; smoke test after every pi update |
|
|
302
|
+
| Command collision (D1) | high | resolve D1 before publish |
|
|
303
|
+
| Auditor cost (every complete_goal = extra session) | medium | D2 settings; document cost expectation in README |
|
|
304
|
+
| User installs alongside pi-goal-x and gets two loops fighting | medium | README "conflicts" section; loud notify if `.pi/goals/` detected |
|
|
305
|
+
| v0.1.0's auditor is rubber-stampable (`bash true`) until v0.2.0 regression_shield | known/accepted | documented in DESIGN + README; ship v0.2.0 fast |
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## 5. Publish checklist (M1)
|
|
310
|
+
|
|
311
|
+
- [ ] D1–D4 resolved and recorded in this file
|
|
312
|
+
- [ ] `npm test` + `npm run check` + live smoke all green
|
|
313
|
+
- [ ] Version bump `0.1.0-alpha.1` → `0.1.0`
|
|
314
|
+
- [ ] git init + initial commit + GitHub repo `dracon/pi-goal-list-loop-audit`
|
|
315
|
+
- [ ] `npm publish --access public`
|
|
316
|
+
- [ ] Verify: `pi install npm:pi-goal-list-loop-audit` on a clean rig
|
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
|
|
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
|
+
**Current package version:** `v0.35.32` — 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
|
|
|
@@ -53,7 +53,7 @@ Five top-level commands — `/goal`, `/list`, `/loop`, `/glla`, `/review`:
|
|
|
53
53
|
/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
54
|
/goal tweak "<new objective>" # edit in place (Confirm dialog)
|
|
55
55
|
/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)
|
|
56
|
+
/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
57
|
/list fix the login bug, add dark mode, write docs # dump it — the agent shapes it into items, one Confirm
|
|
58
58
|
/list plan.md # file detected → bulk import, one Confirm (sisyphus/Ralph style)
|
|
59
59
|
/list <paste a checklist> # multi-line paste → same batch flow
|
|
@@ -240,7 +240,7 @@ Each loop is a different policy class on the same status machine.
|
|
|
240
240
|
| Flaw in pi-goal-x | Fix in pi-goal-list-loop-audit |
|
|
241
241
|
|---|---|
|
|
242
242
|
| `detailedSummary` is hand-concat strings | Structured JSON state + native markdown renderer |
|
|
243
|
-
| Stuck-counter has no ceiling — 1-hour waits happen |
|
|
243
|
+
| 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
244
|
| 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
245
|
| `pause_goal` is fire-and-forget | Clear `pauseReason` surfaced in status + agent feedback |
|
|
246
246
|
| Vague objective + weak auditor = rubber-stamp | Drafting phase with Confirm dialog + isolated auditor + shield |
|
|
@@ -286,6 +286,29 @@ tool call or hidden reasoning interval therefore remains visibly timed; after
|
|
|
286
286
|
three minutes without worker activity the UI changes to `auditor quiet` and
|
|
287
287
|
names the cancellation/recovery path instead of presenting a frozen live card.
|
|
288
288
|
|
|
289
|
+
**Per-phase glyphs + activity meter (v0.35.15).** Every auditor phase carries a
|
|
290
|
+
distinct glyph — `⋯` queued, `▶` running, `◌` quiet, `⛔` blocked, `✓`
|
|
291
|
+
awaiting-verdict — beside a draining `▰▱` activity meter, with the dense text
|
|
292
|
+
kept as secondary detail. When a quiet stretch ends, the footer summarizes it
|
|
293
|
+
(`silent 8m then resumed`) so silence is reported, not just survived. A single
|
|
294
|
+
proactive warning fires when the detached auditor crosses the quiet threshold;
|
|
295
|
+
it never repeats per tick.
|
|
296
|
+
|
|
297
|
+
**Supervisor freeze (v0.35.15).** `/glla pause` silences every automatic
|
|
298
|
+
side-effect — heartbeat re-arms, recovery probes, auto-resume, auto-continuation
|
|
299
|
+
dispatch, the proactive quiet notify, and (v0.35.17) the zero-stream auto-retry
|
|
300
|
+
below — without touching active work or a running detached audit. The flag is
|
|
301
|
+
persisted and survives restarts; `/glla resume` clears it. Bare `/glla` shows
|
|
302
|
+
the frozen state.
|
|
303
|
+
|
|
304
|
+
**Zombie watchdog vs subagent waits (v0.35.26, issue #13).** A parent
|
|
305
|
+
blocked on a foreground subagent call is stream-silent by design, so the
|
|
306
|
+
zero-stream watchdog stands down while one is in flight. The recognized
|
|
307
|
+
names cover both the built-ins (`Agent`, `get_subagent_result`,
|
|
308
|
+
`steer_subagent`) and the pi-subagents extension's registrations
|
|
309
|
+
(`subagent`, `subagent_wait`), shared by the watchdog and the wedge-alert
|
|
310
|
+
hint so they cannot drift apart again.
|
|
311
|
+
|
|
289
312
|
## Provider failures: aggressive retry envelope, bounded (v0.35.0)
|
|
290
313
|
|
|
291
314
|
Error text is **not trusted** to pick a retry policy. The runtime does not
|
|
@@ -299,6 +322,9 @@ adds a blind `:00:30` retry after each hour starts, so work can be picked up
|
|
|
299
322
|
quickly after a possible provider-side change. The automatic window is 24h;
|
|
300
323
|
explicit `/goal resume`, `/list resume`, or `/loop resume` starts a fresh
|
|
301
324
|
window. With global `autoResume=on`, pending retries survive a session reload.
|
|
325
|
+
A loop parked by the zero-stream abort (v0.35.25, issue #14) is explicitly
|
|
326
|
+
resumable: `/loop resume` re-arms it with the preserved iteration count,
|
|
327
|
+
best value, and history — exactly as the abort message promises.
|
|
302
328
|
|
|
303
329
|
Only failures identified by positive evidence as futile avoid automatic retry:
|
|
304
330
|
context/output-token limits and user aborts (`non-recoverable`). Auditor
|
|
@@ -370,6 +396,16 @@ brake streak, so a broken provider can't spin forever. A confirmed queued
|
|
|
370
396
|
continuation with no turn is reported by the queue-stuck probe; it does not
|
|
371
397
|
inject terminal input.
|
|
372
398
|
|
|
399
|
+
**Zero-stream zombie abort + one bounded auto-retry (v0.35.17).** When pi stays
|
|
400
|
+
BUSY with zero provider stream activity for 20 minutes, glla warns; after a
|
|
401
|
+
10-minute grace it aborts the zombie turn and parks the work safely. Since
|
|
402
|
+
v0.35.17 the FIRST such silence arms exactly ONE automatic retry ~90 seconds
|
|
403
|
+
later (the park becomes a waystation, not a dead end — field: turns dispatched
|
|
404
|
+
by accepting Confirm dialogs hung this way repeatedly). If the retry also hangs,
|
|
405
|
+
the second consecutive silence parks permanently for manual `/goal resume` /
|
|
406
|
+
`/list resume`. `/glla pause` freezes the retry like every other automatic
|
|
407
|
+
side-effect.
|
|
408
|
+
|
|
373
409
|
## Session replacement and stale handles
|
|
374
410
|
|
|
375
411
|
Recovery crosses pi's lifecycle boundary. On `session_shutdown`, glla records
|
|
@@ -423,6 +459,37 @@ loser is archived (recoverable under `.pi-glla/archive/`), never silently
|
|
|
423
459
|
wiped. Legacy `complete`/`aborted` terminal slots are also cleared once their
|
|
424
460
|
archive exists, while the final summary remains available in history.
|
|
425
461
|
|
|
462
|
+
### Load without autostart (v0.35.23)
|
|
463
|
+
|
|
464
|
+
On startup glla RESTORES and DISPLAYS all durable state — active/paused
|
|
465
|
+
goal, waiting queue, loop — but holds every automatic dispatch until you
|
|
466
|
+
decide. The load hold freezes the same machinery as `/glla pause`
|
|
467
|
+
(continuation dispatch, loop ticks, heartbeat refires, recovery timers)
|
|
468
|
+
through one shared gate; unlike a manual pause it keeps host-loss
|
|
469
|
+
supervision probing, and it is released by any explicit work command:
|
|
470
|
+
`/goal resume`, `/list resume`, `/list next`, `/loop resume`, `/loop start`,
|
|
471
|
+
or starting a new goal. Every release is ledgered (`load_hold_engaged` /
|
|
472
|
+
`load_hold_released`). Set global **Auto-resume = on** to restore
|
|
473
|
+
load-time automation for unattended rigs — the consent is the raw setting,
|
|
474
|
+
not the aggressive-mode default. Narrow continuity exceptions keep working
|
|
475
|
+
without consent: validated handoffs/rebinds, same-process session
|
|
476
|
+
successors, re-arming of work already in flight when a host silently died,
|
|
477
|
+
and the single retry a parked completion claim earns when main-model
|
|
478
|
+
recovery heals the provider that parked it.
|
|
479
|
+
|
|
480
|
+
**Due-wait backstop (v0.35.28, issue #16).** A time-gated wait pause
|
|
481
|
+
(`pauseKind: "wait"` with a `pauseResumeAt`) is no longer trusted to
|
|
482
|
+
in-memory timers alone — agent-authored waits armed none, error-brake
|
|
483
|
+
cooldowns were not re-armed on reload, and every scheduled resume died with
|
|
484
|
+
its session. The heartbeat now compares wall time against `pauseResumeAt`
|
|
485
|
+
every tick and re-fires the route once the deadline lapses by more than
|
|
486
|
+
~90s (main-model waits probe the provider; other waits clear the park and
|
|
487
|
+
dispatch one fresh continuation). `/glla pause` and the load hold still
|
|
488
|
+
freeze it; every fire is ledgered (`wait_pause_overdue_resume`). Auto-resumed
|
|
489
|
+
goals carry a RECOVERY NOTICE in their next continuation prompt — "welcome
|
|
490
|
+
back, YOU were recovered" — so the agent continues its own work instead of
|
|
491
|
+
waiting for an external recovery signal that already fired.
|
|
492
|
+
|
|
426
493
|
## Completion and destructive commands
|
|
427
494
|
|
|
428
495
|
An approved objective writes its final completion summary to the archive and
|
|
@@ -442,6 +509,17 @@ Open `/glla` to edit these settings in the table (the rows show effective values
|
|
|
442
509
|
|
|
443
510
|
- Auditor model and thinking level
|
|
444
511
|
- Auditor fallback agent
|
|
512
|
+
|
|
513
|
+
**Auditor selection (v0.35.24):** the **Auditor model** row opens the same
|
|
514
|
+
`/model`-style fuzzy picker the main agent flows use — configured-auth models
|
|
515
|
+
only, with a session-model row and a typed escape hatch. It is at full parity
|
|
516
|
+
with the main selector on policy too: your forbidden-models patterns filter
|
|
517
|
+
the picker list AND a typed match is refused with a named warning, so a pin
|
|
518
|
+
saved here is one `resolveAuditorModel` will actually honor. The pick lands
|
|
519
|
+
in global `auditorModel` and is followed immediately by the auditor thinking
|
|
520
|
+
dialog for that model. The **Auditor fallback agent** row applies the same
|
|
521
|
+
filtering to the failure-over pin.
|
|
522
|
+
|
|
445
523
|
- Notify command, token limit, and wedge-alert minutes
|
|
446
524
|
- Auto-resume, auto-accept drafts, decision popup, and carryover policy
|
|
447
525
|
- Main-agent current model/thinking, fallback models, recovery cadence, and preferred-primary failback policy in the Main agent tab
|
|
@@ -452,11 +530,14 @@ Open `/glla` to edit these settings in the table (the rows show effective values
|
|
|
452
530
|
stall brakes
|
|
453
531
|
|
|
454
532
|
The argument namespace is reserved for actions such as `/glla status`, `/glla
|
|
455
|
-
|
|
456
|
-
`/glla fallbacks clear`, and `/glla wipe`. `fallbacks clear`
|
|
457
|
-
the global main-agent fallback chain and cancels any pending
|
|
458
|
-
|
|
459
|
-
|
|
533
|
+
pause`, `/glla resume`, `/glla cancel`, `/glla stats`, `/glla audits`,
|
|
534
|
+
`/glla tooloverride`, `/glla fallbacks clear`, and `/glla wipe`. `fallbacks clear`
|
|
535
|
+
atomically removes the global main-agent fallback chain and cancels any pending
|
|
536
|
+
fallback switch. Pause freezes every automatic supervisor side-effect (heartbeat
|
|
537
|
+
re-arms, recovery probes, auto-resume, continuation dispatch, loop ticks, quiet
|
|
538
|
+
notifications) without touching active work, and survives session restarts;
|
|
539
|
+
resume unfreezes. Cancel stops the active objective; wipe clears all live state
|
|
540
|
+
while preserving history. There is no top-level `/glla key=value` setting syntax.
|
|
460
541
|
|
|
461
542
|
Resolution per key: **project > global > defaults** — EXCEPT `autoResume` and
|
|
462
543
|
agent recovery settings (`mainModelFallbacks`, `mainModelRetryMinutes`,
|
|
@@ -598,23 +679,37 @@ customizes.
|
|
|
598
679
|
|
|
599
680
|
## Files
|
|
600
681
|
|
|
682
|
+
Post-decomposition layout (the v0.34.x monolith is gone — `loops/goal.ts` is
|
|
683
|
+
a thin activation/wiring installer):
|
|
684
|
+
|
|
601
685
|
```
|
|
602
686
|
extensions/
|
|
603
|
-
|
|
687
|
+
goal-commands.ts # /goal + /list command surface, drafting, wipe/stats
|
|
688
|
+
loops/goal.ts # public activation/wiring installer (thin)
|
|
689
|
+
loops/goal-tools.ts # agent tools (complete_goal, pause_goal, list_*, loop drafts)
|
|
690
|
+
loops/goal-orchestrator.ts # goal lifecycle: create/archive/advance, reviewer
|
|
691
|
+
loops/goal-auditor-hooks.ts # completion-audit claim/recovery machinery
|
|
692
|
+
loops/goal-activation.ts # event wiring, command registration, session lifecycle
|
|
693
|
+
loops/goal-settings-ui.ts # settings editors + model pickers
|
|
604
694
|
goal-loop-core.ts # types, JSONL state, pure helpers
|
|
605
695
|
goal-loop-auditor.ts # auditor prompt + legacy in-process helper
|
|
606
696
|
goal-loop-auditor-process.ts # detached worker protocol + shield revalidation
|
|
607
697
|
goal-loop-shield.ts # regression_shield (pure, dependency-free)
|
|
608
|
-
goal-loop-display.ts # status
|
|
698
|
+
goal-loop-display.ts # widget/status rendering (incl. last-outcome retention)
|
|
699
|
+
goal-heartbeat.ts # heartbeat self-watchdog, subagent probes, due-wait backstop
|
|
700
|
+
goal-continuation.ts # continuation scheduling/dispatch + prompts
|
|
701
|
+
goal-recovery.ts # main-model recovery + completion-audit recovery
|
|
702
|
+
goal-loop.ts # Loop 3 machinery: /loop tick engine, git finish
|
|
609
703
|
goal-loop-forever.ts # /loop measure/parse/plateau helpers
|
|
610
|
-
goal-loop-backoff.ts #
|
|
704
|
+
goal-loop-backoff.ts # scheduling constants + stall/wedge/pending-latch decisions
|
|
611
705
|
prompts/
|
|
612
|
-
goal-loop-continuation.md #
|
|
706
|
+
goal-loop-continuation.md # continuation prompt
|
|
613
707
|
goal-loop-draft.md # drafting prompt
|
|
614
708
|
goal-loop-forever.md # /loop driver prompt
|
|
615
709
|
goal-loop-forever-draft.md # /loop drafting prompt
|
|
616
710
|
scripts/
|
|
617
711
|
goal-auditor-worker.mjs # extension-less RPC auditor child process
|
|
712
|
+
goal-auditor-launch.mjs # Windows-safe spawn spec builder (gate-before-quote)
|
|
618
713
|
smoke.sh # live integration harness (tmux + real models)
|
|
619
714
|
tests/ # current test count is reported by `bun test`; no live pi required for the suite
|
|
620
715
|
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.
|