pi-goal-list-loop-audit 0.29.7 → 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 nowno 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 wipe (nuclear reset, Confirm-gated) · /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
@@ -361,7 +362,7 @@ prompts/
361
362
  goal-loop-forever-draft.md # /loop drafting prompt
362
363
  scripts/
363
364
  smoke.sh # live integration harness (tmux + real models)
364
- tests/ # 613 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)
365
366
  docs/DESIGN.md # architectural decisions
366
367
  PLAN.md # milestones, decisions, gates
367
368
  ```
@@ -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.7",
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",