pi-goal-list-loop-audit 0.29.6 → 0.29.8

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/README.md CHANGED
@@ -39,10 +39,11 @@ Five top-level commands — `/goal`, `/list`, `/loop`, `/glla`, `/review`:
39
39
  /goal resume # resume
40
40
  /goal cancel # abort
41
41
  /goal decide # re-open the decision picker (v0.28.23)
42
- /goal audit # run the isolated auditor on the current goal now — no agent turn (v0.28.27)
42
+ /goal audit ["focus on payments"] # one-shot project audit (v0.29.8): fix the non-decisions, present the decisions — findings in .pi-glla/audit-loop/findings.md
43
+ /goal verify # run the isolated auditor on the current goal now — no agent turn (v0.28.27, renamed from /goal audit in v0.29.8)
43
44
  /goal tweak "<new objective>" # edit in place (Confirm dialog)
44
45
  /goal archive # archived goals, newest first
45
- /glla # settings UI table · /glla key=value · /glla stats · /glla audits [N|full] · /glla postaudit · /glla autoaccept=on
46
+ /glla # settings UI table · /glla status (unified what's-running view) · /glla key=value · /glla stats · /glla audits [N|full] · /glla postaudit · /glla wipe (nuclear reset, Confirm-gated) · /glla autoaccept=on
46
47
  /list fix the login bug, add dark mode, write docs # dump it — the agent shapes it into items, one Confirm
47
48
  /list plan.md # file detected → bulk import, one Confirm (sisyphus/Ralph style)
48
49
  /list <paste a checklist> # multi-line paste → same batch flow
@@ -66,7 +67,7 @@ matches `/list show`.
66
67
  /loop # draft the loop (agent grills; measure is test-run before you confirm)
67
68
  /loop start "keep polishing the UI" # infinite metricless loop (v0.23.6): no plateau, no cap — ends at time=/tokens= or /loop stop
68
69
  /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)
69
- /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
70
+ /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)
70
71
  /loop start "reduce TODOs" measure="grep -c TODO src.txt | head -1" direction=min
71
72
  /loop start "shrink the bundle" measure="..." direction=min time=4 tokens=500000 # arbitrary bounds
72
73
  /loop start "reduce TODOs" measure="..." direction=min branch=1 # scratch-branch mode
@@ -194,7 +195,29 @@ running, you can see it — no command needed.
194
195
  A 15s heartbeat detects the precise stall condition — active goal/loop + idle
195
196
  session + nothing scheduled + quiet for 60s — and re-fires the continuation
196
197
  itself. Three consecutive zero-tool turns pause the goal / stop the loop.
197
- No external watchdog plugin needed.
198
+ No external watchdog plugin needed. It also recovers **stranded audits**
199
+ (v0.29.1): a goal stuck in `auditing` with no auditor session alive re-runs
200
+ the stored claim after 90s instead of black-holing. Storm protection: the
201
+ send→pause→notify path rearms once per cycle and loud-stops after a 6-error
202
+ brake streak, so a broken provider can't spin forever.
203
+
204
+ **User aborts mean STOP** (v0.29.4): Esc-aborting a turn stands the chain
205
+ down with a named notify (`/goal resume` to continue) — it does NOT count
206
+ toward stall warnings, does NOT auto re-fire, and the stand-down survives
207
+ the heartbeat (v0.29.5). Five consecutive aborts still pause loudly as a
208
+ backstop. A queued steer interrupt (`length`/`toolResult` races) is not an
209
+ abort and resumes normally.
210
+
211
+ ## One active thing (auto-arbitrated)
212
+
213
+ At most one goal/list-item/loop owns the active slot — activation guards
214
+ refuse a second live thing in-session, and **session loads auto-arbitrate
215
+ dirty stacked state** (v0.29.6): if a pre-guard project persisted a live
216
+ loop AND a live goal, the one with the most recent activity keeps the slot
217
+ and the loser is ARCHIVED (recoverable under `.pi-glla/archive/` / `/loop
218
+ status`), never silently wiped. No picker, no per-start arbitration chores.
219
+ The queued list is a backlog, not a second live thing — untouched.
220
+ `/glla wipe` remains the manual, Confirm-gated clean slate.
198
221
 
199
222
  ## Config (one global place, rarely opened)
200
223
 
@@ -206,17 +229,21 @@ No external watchdog plugin needed.
206
229
  /glla tokenlimit=10000000 # per-goal token budget (default: off) → GLOBAL
207
230
  /glla tokenlimit=0 # explicitly no cap (the default)
208
231
  /glla wedgealert=30 # hung-command alert minutes (default: 30, 0 = off)
209
- /glla autoresume=on # auto-resume goals/loops on ANY session start (default: load HELD, never auto-start — explicit /goal resume, /list resume, or /loop; off: never)
232
+ /glla autoresume=on # auto-resume goals/loops on ANY session start (default: load HELD, never auto-start — explicit /goal resume, /list resume, or /loop; off: never) — GLOBAL-only (v0.29.5): project-level keys are inert
210
233
  /glla auditcap=5 # pause the goal after N consecutive auditor disapprovals (default 5, 0 = unlimited)
211
234
  /glla aggressivemode=on # keep-going defaults: autoResume, cap 10, stuck 10, wedge off, quota auto-retry, cap→TODOs
212
235
  /glla quotaretryminutes=60 # minutes before auto-retrying a quota-exhausted auditor
213
236
  /glla stuckmax=10 # consecutive stuck interventions before a loop stops (default 5)
214
237
  /glla auditfeedbackchars=800 # cap the executor-visible auditor report (default 0 = full report)
215
- /glla autoaccept=on # drafts ACTIVATE without the Confirm dialo... (every draft dialog also offers "always auto-accept" inline)unattended rigs)
238
+ /glla autoaccept=on # drafts ACTIVATE without the Confirm dialog (v0.29.4: they start immediately — autoResume no longer gates drafts; every draft dialog also offers "always auto-accept" inline)
216
239
  /glla project tokenlimit=500 # rare per-project override
217
240
  ```
218
241
 
219
- Resolution per key: **project > global > defaults**. The auditor defaults to
242
+ Resolution per key: **project > global > defaults** — EXCEPT `autoResume`,
243
+ which is **global-only** (v0.29.5): per-project opt-ins from old versions
244
+ silently overrode the global hold at launch (the junk-runner incident), so
245
+ the launch-restore gate and the reviewer-enqueue gate read only the global
246
+ file now. The auditor defaults to
220
247
  your pi session model. When the session provider is extension-registered the
221
248
  auditor can't auth it — you're told once (info level) with the fix:
222
249
  `/glla model=provider/id`, set once, rarely touched again. The plugin never
@@ -232,7 +259,12 @@ history and is available through `/goal status` regardless.
232
259
  floor — every `propose_*` draft (goal, list batch, loop, task list)
233
260
  activates the moment the agent proposes it, with a notification and a
234
261
  `draft_autoaccepted` ledger entry (auto-accept is never silent). The seed
235
- carries the intent. Pair with `autoresume=on` for fully unattended rigs.
262
+ carries the intent. Since v0.29.4 auto-accepted drafts **start immediately**
263
+ — the draft path is decoupled from `autoResume`, which gates ONLY
264
+ launch-time restore of persisted state ("load it but don't auto-start it").
265
+ For fully unattended rigs you typically want both on; for attended rigs,
266
+ `autoaccept=on` + `autoresume=off` is the sweet spot (new drafts go, old
267
+ state holds).
236
268
 
237
269
  ## Subagents
238
270
 
@@ -330,7 +362,7 @@ prompts/
330
362
  goal-loop-forever-draft.md # /loop drafting prompt
331
363
  scripts/
332
364
  smoke.sh # live integration harness (tmux + real models)
333
- tests/ # 545 tests across 58 files, no live pi required (mock-ctx harness drives the orchestrator)
365
+ tests/ # 614 tests across 58 files, no live pi required (mock-ctx harness drives the orchestrator)
334
366
  docs/DESIGN.md # architectural decisions
335
367
  PLAN.md # milestones, decisions, gates
336
368
  ```
package/docs/DESIGN.md CHANGED
@@ -44,6 +44,52 @@ below; later releases append addenda rather than rewrite history.
44
44
  - **`notify=<cmd>`**: fire-and-forget shell-out on goal complete / goal pause /
45
45
  loop stop, message as `$1`. Settings parser is quote-aware.
46
46
 
47
+ ## Addendum v0.5.0–v0.29.6 (current state — the long-session era)
48
+
49
+ The v0.4.0 addendum closed the scaffold era. v0.5.0 through v0.29.6 are 25+
50
+ releases of unattended-rig hardening; the full record is CHANGELOG.md. The
51
+ architectural decisions that changed the SHAPE of the system:
52
+
53
+ - **Self-watchdog is baked in** (v0.5.0): a 15s heartbeat owns liveness —
54
+ supervising + idle + nothing scheduled + 60s quiet → re-fire. External
55
+ liveness plugins are retired.
56
+ - **The restore gate** (v0.26.9 tri-state; hardened v0.28.30, v0.29.4): a
57
+ bare `pi` start HOLDS everything and paints it — nothing auto-starts from
58
+ persisted state. In-session reload/fork/compaction continues automatically.
59
+ `autoResume` (on → any session start resumes; off → never) is **global-only**
60
+ (v0.29.5) after a stale per-project opt-in silently overrode the global hold.
61
+ - **Drafts and restores are decoupled** (v0.29.4): `autoAcceptDrafts` is the
62
+ pre-consent for in-session drafts — they START immediately. `autoResume`
63
+ gates only launch-time restore. "The session auto-starts in some cases ok;
64
+ launching pi must not."
65
+ - **User aborts mean STOP** (v0.29.4/0.29.5): an aborted turn is exempt from
66
+ stall accounting, stands the chain down with no auto re-fire, and the
67
+ stand-down gates the heartbeat + post-compaction refires. The 5-abort loud
68
+ pause is the backstop.
69
+ - **One active thing, auto-arbitrated** (v0.28.21 guards; v0.29.6 load-time
70
+ arbitration): at most one live artifact. Dirty stacked states at load are
71
+ resolved deterministically — most recent activity keeps the slot, the loser
72
+ is archived (recoverable), no picker. `/glla wipe` (v0.28.31) is the manual,
73
+ Confirm-gated clean slate.
74
+ - **The completion lifecycle owns its pauses** (v0.29.1): storm/stall
75
+ escalation never pauses `auditing` goals; a stranded `auditing` state (no
76
+ live auditor, 90s stale) re-runs the stored claim; send/pause/notify storms
77
+ rearm once per cycle; the provider-error brake (v0.28.13) keeps cross-cycle
78
+ memory and parks after 6 consecutive errors.
79
+ - **The audit loop is the project reviewer** (v0.29.0): `/loop audit` runs
80
+ fresh audit passes every iteration, appends findings to
81
+ `.pi-glla/audit-loop/findings.md`, fixes the top open ones; the orchestrator
82
+ counts open boxes as the measure and the plateau stop ends it. The
83
+ reviewer's reflexive fire-audit-on-clean cascade is opt-in (it paid for
84
+ verification twice and was hydra fuel).
85
+ - **Git discipline is prompt-law** (v0.29.2): continuation/draft prompts
86
+ forbid inventing git identities or branches (field incidents: agents
87
+ committing as `phase-e-agent <phase-e@local>`).
88
+ - **Reviewer = strategist, not verifier** (v0.24.6–v0.29.0): the reviewer
89
+ scans sources and proposes list items through the standard drafting +
90
+ Confirm path; it never audits work — the isolated auditor is the only
91
+ verifier.
92
+
47
93
  ## Addendum v0.4.0 (completion)
48
94
 
49
95
  - **Auditor compaction enabled** (flaw #3 — the last open one). Safety:
@@ -216,10 +216,14 @@ export interface Goal {
216
216
  export type GoalRoute =
217
217
  | { kind: "draft" }
218
218
  | { kind: "set"; text: string }
219
- | { kind: "sub"; name: "status" | "pause" | "resume" | "cancel" | "decide" | "audit" | "tweak" | "archive" | "start"; rest: string };
219
+ | { kind: "sub"; name: "status" | "pause" | "resume" | "cancel" | "decide" | "verify" | "audit" | "tweak" | "archive" | "start"; rest: string };
220
220
 
221
- const GOAL_EXACT_SUBS = new Set(["status", "pause", "resume", "cancel", "decide", "audit"]);
222
- const GOAL_ARG_SUBS = new Set(["tweak", "archive", "start"]);
221
+ // v0.29.8: "audit" moved to ARG subs ("/goal audit [focus]" is the one-shot
222
+ // project audit — user: "/goal audit IS the audit goal"); the v0.28.27
223
+ // manual current-goal verification moved to "verify" (it happens
224
+ // automatically at completion anyway — verify is the on-demand handle).
225
+ const GOAL_EXACT_SUBS = new Set(["status", "pause", "resume", "cancel", "decide", "verify"]);
226
+ const GOAL_ARG_SUBS = new Set(["audit", "tweak", "archive", "start"]);
223
227
 
224
228
  export function routeGoalArgs(raw: string): GoalRoute {
225
229
  const trimmed = raw.trim();
@@ -228,10 +232,10 @@ export function routeGoalArgs(raw: string): GoalRoute {
228
232
  const first = (space === -1 ? trimmed : trimmed.slice(0, space)).toLowerCase();
229
233
  const rest = space === -1 ? "" : trimmed.slice(space + 1).trim();
230
234
  if (GOAL_EXACT_SUBS.has(first) && rest === "") {
231
- return { kind: "sub", name: first as "status" | "pause" | "resume" | "cancel" | "decide", rest: "" };
235
+ return { kind: "sub", name: first as "status" | "pause" | "resume" | "cancel" | "decide" | "verify", rest: "" };
232
236
  }
233
237
  if (GOAL_ARG_SUBS.has(first)) {
234
- return { kind: "sub", name: first as "tweak" | "archive" | "start", rest };
238
+ return { kind: "sub", name: first as "audit" | "tweak" | "archive" | "start", rest };
235
239
  }
236
240
  return { kind: "set", text: trimmed };
237
241
  }
@@ -423,3 +423,22 @@ export function auditMeasureCmd(): string {
423
423
  export function auditTarget(): string {
424
424
  return `Audit the project for real problems and fix them, iteration by iteration. Every iteration: (1) run a FRESH audit pass over the codebase — spawn Explore subagents for breadth — hunting real issues: bugs, broken flows, regressions, drift between docs and code, dead code, security holes. Not style nits, not speculative refactors. (2) Append every NEW finding as one checkbox line "- [ ] SEVERITY: short description (file:line)" to ${AUDIT_FINDINGS_REL} (create the file on the first finding; append-only — never delete, rewrite, or reorder existing lines; never re-report a finding already listed). (3) Fix the highest-severity OPEN finding(s) — real fixes, committed — then check the box: "- [x] … — fixed in <commit>". (4) Honesty law: never fabricate findings to look busy; never mark a finding fixed without the fix commit existing. When a full audit pass surfaces nothing new AND no open findings remain, say so plainly — the orchestrator counts open findings every iteration and the plateau stop ends the loop when the well is dry.`;
425
425
  }
426
+
427
+ // ---- /goal audit-project (v0.29.8) ----
428
+
429
+ /**
430
+ * The one-shot project audit (user design 2026-07-30): "/loop audit keeps
431
+ * firing — this would be fire and address what you can, present what is to
432
+ * be decided; whether to fix a bug is not a decision." Same findings file
433
+ * as the audit loop (one ledger per project — the loop can keep working
434
+ * what the one-shot surfaced), but exactly ONE pass with a finish line the
435
+ * isolated auditor verifies, and the triage law the loop doesn't have:
436
+ * FIX findings (bugs, polish — nobody would say "leave that bug in") are
437
+ * fixed autonomously; DECIDE findings (direction, trade-offs — two
438
+ * reasonable answers exist) are presented, never touched. DECIDE lines use
439
+ * "- [?]" so they never inflate the loop's open-findings measure.
440
+ */
441
+ export function projectAuditTarget(focus?: string): string {
442
+ const scope = focus && focus.trim() ? focus.trim() : "the whole project";
443
+ return `Run ONE project audit pass and leave the project in a known state. Scope: ${scope}. (1) Run a FRESH audit pass over the codebase — spawn Explore subagents for breadth — hunting real problems: bugs, broken flows, regressions, drift between docs and code, dead code, security holes. Not style nits, not speculative refactors. (2) Append every NEW finding to ${AUDIT_FINDINGS_REL} (create the file on the first finding; append-only — never delete, rewrite, or reorder existing lines; never re-report a finding already listed), classified: "- [ ] FIX: SEVERITY: short description (file:line)" for bugs and polish — whether to fix these is NOT a decision — and "- [?] DECIDE: short description (what the choice is, what each side costs)" for direction, trade-offs, and scope questions where two reasonable answers exist. (3) Fix every NEW FIX finding from this pass — real fixes, committed with the repo's configured identity on the current branch (no invented identities or branches) — then check the box: "- [x] … — fixed in <commit>". (4) Change NOTHING for DECIDE findings — present them in the completion report instead. (5) Honesty law: never fabricate findings to look busy; never check a box without the fix commit existing; never silently turn a DECIDE into a fix. Done when: the audit pass is complete, every new FIX finding has a fix commit and a checked box in ${AUDIT_FINDINGS_REL}, and every DECIDE finding is listed in the file and presented in the completion report.`;
444
+ }
@@ -165,6 +165,7 @@ import {
165
165
  respecTarget,
166
166
  auditMeasureCmd,
167
167
  auditTarget,
168
+ projectAuditTarget,
168
169
  HELD_ON_RESTORE,
169
170
  type LoopState,
170
171
  } from "../goal-loop-forever.js";
@@ -1106,7 +1107,7 @@ async function retryStoredCompletionAudit(ctx: ExtensionContext, origin: "quota-
1106
1107
  updateGoal({ status: "auditing" }, liveCtx);
1107
1108
  appendLedger(liveCtx.cwd, "goal_resumed", { via: origin === "manual" ? "manual-audit" : "quota-retry-direct-audit" });
1108
1109
  liveCtx.ui.notify(origin === "manual"
1109
- ? "Manual /goal audit — running the isolated auditor now (no agent turn needed)."
1110
+ ? "Manual /goal verify — running the isolated auditor now (no agent turn needed)."
1110
1111
  : "Auditor quota window elapsed — retrying the audit with your stored completion claim (no agent turn needed).", "info");
1111
1112
  const settings = loadSettings(liveCtx.cwd);
1112
1113
  const { model: auditorModel, error: modelError, via } = resolveAuditorModel(liveCtx, settings.auditorModel);
@@ -1164,7 +1165,7 @@ async function retryStoredCompletionAudit(ctx: ExtensionContext, origin: "quota-
1164
1165
  updateGoal({ auditHistory: history, pendingCompletion: undefined }, liveCtx);
1165
1166
  const objective = state.goal.objective;
1166
1167
  archiveCurrentGoal(liveCtx, "complete", `auditor ${result.model} approved (${origin})`);
1167
- liveCtx.ui.notify(`Goal complete — auditor ${result.model} approved${origin === "manual" ? " on /goal audit" : " on the quota retry"}.`, "info");
1168
+ liveCtx.ui.notify(`Goal complete — auditor ${result.model} approved${origin === "manual" ? " on /goal verify" : " on the quota retry"}.`, "info");
1168
1169
  notifyExternal(liveCtx, `Goal complete (auditor approved, ${origin}): ${objective.slice(0, 120)}`);
1169
1170
  return;
1170
1171
  }
@@ -1445,14 +1446,24 @@ async function cmdGoal(args: string, ctx: ExtensionContext): Promise<void> {
1445
1446
  if (!shown) ctx.ui.notify("No pending decision — the goal isn't paused on a choice (or no UI).", "info");
1446
1447
  return;
1447
1448
  }
1448
- // v0.28.27: /goal audit — run the isolated auditor on the current goal
1449
+ // v0.29.8: /goal audit [focus] — the ONE-SHOT project audit (user:
1450
+ // "/goal audit IS the audit goal — we are not auditing the current
1451
+ // goal, that happens automatically"). Fire-and-address: one audit
1452
+ // pass, FIX findings fixed autonomously (a bug is not a decision),
1453
+ // DECIDE findings presented, untouched. Runs as a normal goal through
1454
+ // cmdSet — the isolated auditor verifies the finish line.
1455
+ if (route.name === "audit") {
1456
+ return cmdSet(projectAuditTarget(route.rest || undefined), ctx, true);
1457
+ }
1458
+ // v0.28.27 (renamed /goal audit → /goal verify in v0.29.8): run the
1459
+ // isolated auditor on the current goal
1449
1460
  // RIGHT NOW, without engaging the agent. The user's "the work looks
1450
1461
  // done — just verify it" handle (and the manual counterpart of the
1451
1462
  // v0.28.26 stored-claim quota retry). Seeds a synthesized claim so a
1452
1463
  // quota block falls into the same pendingCompletion retry machinery.
1453
- if (route.name === "audit") {
1464
+ if (route.name === "verify") {
1454
1465
  if (!state.goal) {
1455
- ctx.ui.notify("No active goal — /goal audit needs a goal to verify.", "warning");
1466
+ ctx.ui.notify("No active goal — /goal verify needs a goal to verify.", "warning");
1456
1467
  return;
1457
1468
  }
1458
1469
  if (completionAuditInFlight) {
@@ -1461,7 +1472,7 @@ async function cmdGoal(args: string, ctx: ExtensionContext): Promise<void> {
1461
1472
  }
1462
1473
  updateGoal({
1463
1474
  pendingCompletion: {
1464
- completionSummary: "Manual audit requested by the user via /goal audit (no agent completion claim). Verify the objective against the repo directly.",
1475
+ completionSummary: "Manual audit requested by the user via /goal verify (no agent completion claim). Verify the objective against the repo directly.",
1465
1476
  at: nowIso(),
1466
1477
  },
1467
1478
  }, ctx);
@@ -4551,6 +4562,37 @@ function cmdAudits(args: string, ctx: ExtensionContext): void {
4551
4562
  ctx.ui.notify(`glla audits — last ${entries.length} verdict(s) in ${ctx.cwd}\n${formatAuditLog(entries)}`, "info");
4552
4563
  }
4553
4564
 
4565
+ // v0.29.8: /glla status — the unified "what's running" surface (user: "we
4566
+ // need to type goal status [to check], so that command at least is missing
4567
+ // for checking on whatever active process we have"). Read-only aggregate of
4568
+ // the ONE state — goal, list queue, loop, pending decisions — with pointers
4569
+ // to the deep surfaces.
4570
+ function cmdGllaStatus(ctx: ExtensionContext): void {
4571
+ const lines: string[] = [];
4572
+ const g = state.goal;
4573
+ if (g) {
4574
+ const tok = (g.usage?.tokensUsed ?? 0) > 0 ? ` · ${g.usage!.tokensUsed} tok` : "";
4575
+ const audit = g.status === "auditing" ? " (auditor running…)" : "";
4576
+ const pause = g.status === "paused" && g.pauseReason ? ` — ${g.pauseReason.slice(0, 90)}` : "";
4577
+ lines.push(`goal [${g.policy}] ${g.status}${audit}${tok}: ${g.objective.slice(0, 90)}${pause}`);
4578
+ } else {
4579
+ lines.push("goal: none");
4580
+ }
4581
+ const q = listQueue();
4582
+ lines.push(`list: ${q.length === 0 ? "empty" : `${q.length} queued — head: ${(q[0]?.objective ?? "").slice(0, 70)}`}`);
4583
+ const l = state.loop;
4584
+ if (l) {
4585
+ lines.push(`loop: ${l.active ? "ACTIVE" : `held/stopped — ${l.stopReason ?? "n/a"}`} · iter ${l.iteration}/${l.maxIterations > 0 ? l.maxIterations : "∞"} · best ${l.bestValue ?? "n/a"} · stall ${l.stallCount} — ${l.target.slice(0, 60)}`);
4586
+ } else {
4587
+ lines.push("loop: none");
4588
+ }
4589
+ if (g?.status === "paused" && g.pauseKind === "decision" && g.pauseOptions?.length) {
4590
+ lines.push(`decision pending (${g.pauseOptions.length} options) — /goal decide`);
4591
+ }
4592
+ lines.push("deep: /goal status · /list · /loop status · /glla stats · /glla audits · /glla log");
4593
+ ctx.ui.notify(`glla status\n${lines.join("\n")}`, "info");
4594
+ }
4595
+
4554
4596
  async function cmdSettings(args: string, ctx: ExtensionContext): Promise<void> {
4555
4597
  // The plugin's ONE config surface — global by default, rarely opened.
4556
4598
  // /glla show effective values + where each comes from
@@ -4573,6 +4615,11 @@ async function cmdSettings(args: string, ctx: ExtensionContext): Promise<void> {
4573
4615
  cmdAudits(trimmed.slice("audits".length).trim(), ctx);
4574
4616
  return;
4575
4617
  }
4618
+ // v0.29.8: /glla status — the unified what's-running view.
4619
+ if (/^status\b/.test(trimmed)) {
4620
+ cmdGllaStatus(ctx);
4621
+ return;
4622
+ }
4576
4623
  // v0.28.28: /glla log [N] — the raw event trail, human-readable. "Log it
4577
4624
  // so we can look back and see where we are doing things wrong."
4578
4625
  if (/^log\b/.test(trimmed)) {
@@ -4970,10 +5017,13 @@ export default function (pi: ExtensionAPI): void {
4970
5017
  description: "Set/draft a goal, or /goal status|pause|resume|cancel|tweak <text>|archive|start <objective>. Objectives without a 'Done when:' clause are grilled into a contract first; include the clause or use /goal start to skip the interview and activate instantly.",
4971
5018
  getArgumentCompletions: completions([
4972
5019
  ["start", "skip drafting — /goal start <objective> activates immediately"],
5020
+ ["audit", "one-shot project audit goal: /goal audit [focus] — fix the non-decisions, present the decisions (v0.29.8)"],
5021
+ ["verify", "run the isolated auditor on the current goal NOW (v0.28.27, renamed from /goal audit)"],
4973
5022
  ["status", "show the active goal and its task list"],
4974
5023
  ["pause", "pause the active goal"],
4975
5024
  ["resume", "resume a paused goal (and the list, when items are queued)"],
4976
5025
  ["cancel", "abort the active goal"],
5026
+ ["decide", "re-open the decision picker for a decision pause"],
4977
5027
  ["tweak", "change the objective: /goal tweak <text>"],
4978
5028
  ["archive", "list archived goals"],
4979
5029
  ]),
@@ -4990,6 +5040,7 @@ export default function (pi: ExtensionAPI): void {
4990
5040
  ["autoresume=", "default: hold when a session is loaded, auto-resume on reload/fork; on: always auto-resume; off: never"],
4991
5041
  ["decisionpopup=", "on|off: decision pauses pop the select() picker (default on; the widget card always lists the options, /goal decide reopens the picker)"],
4992
5042
  ["auditcap=", "N: pause goal after N consecutive auditor disapprovals (default 5, 0 = unlimited)"],
5043
+ ["status", "unified what's-running view: goal + list queue + loop + pending decisions (v0.29.8)"],
4993
5044
  ["log", "event-trail tail: /glla log [N] — who created/resumed/paused what, from where (v0.28.28)"],
4994
5045
  ["wipe", "WIPE live glla state (goal archived, list cleared, loop stopped) — one-shot cleanup for leftover-laden projects"],
4995
5046
  ["resume", "resume WHATEVER is paused/held (goal, list item, or held loop) — no need to know the type"],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-goal-list-loop-audit",
3
- "version": "0.29.6",
3
+ "version": "0.29.8",
4
4
  "description": "Goal. Loop. Audit. Done. \u2014 a pi-coding-agent extension that supervises long-running work, with isolated auditor on each completion. Beat bamboozling by design: the auditor runs in a fresh session with no extensions, no skills, no editor \u2014 only the read tools needed to verify your goal.",
5
5
  "license": "MIT",
6
6
  "author": "dracon",