pi-goal-list-loop-audit 0.33.2 → 0.33.4

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
@@ -1,8 +1,8 @@
1
1
  # pi-goal-list-loop-audit
2
2
 
3
- > **Goal. Loop. Audit. Done.**
3
+ > **Mission control for autonomous pi.**
4
4
 
5
- A pi-coding-agent extension that supervises long-running work to verified completion. The plugin writes a durable goal to disk, drives the agent through an `agent_end`-driven loop, and on each `complete_goal` spawns an **isolated auditor in a fresh pi session** to verify the work is genuinely done.
5
+ Interview-drafted goals, an audited task queue, and forever-loops (metric, spec, project-audit) that run for hours. Every goal starts as a **drafted contract you confirm** — nothing activates sight-unseen. The plugin then writes a durable goal to disk, drives the agent through an `agent_end`-driven loop, and on each `complete_goal` spawns an **isolated auditor in a fresh pi session** to verify the work is genuinely done. Stall recovery, structured decision pauses, and consent gates keep you in charge while it works.
6
6
 
7
7
  The auditor runs in a fresh session with no extensions, no skills, no prompts, no editor. It has only `read` / `grep` / `find` / `ls` / `bash`. It cannot see the implementing conversation. It cannot plant evidence. The implementer cannot fool it.
8
8
 
@@ -543,7 +543,7 @@ export const LIST_AUDIT_COLLECT_MARKER = "[LIST-AUDIT-COLLECT]";
543
543
 
544
544
  export function listAuditCollectTarget(focus?: string): string {
545
545
  const scope = focus && focus.trim() ? focus.trim() : "the whole project";
546
- return `${LIST_AUDIT_COLLECT_MARKER} Run ONE project audit pass that COLLECTS work — the follow-up fixes are queued as separate list items, so this pass changes no code. 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 — 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) Change NOTHING — no fixes, no refactors, no drive-by edits: the orchestrator queues each open FIX finding as its own list item after this pass completes, and each fix lands with its own commit and its own audit. (4) DECIDE findings are listed in the completion reportthey are presented to the user, never queued and never silently fixed. (5) Honesty law: never fabricate findings to look busy; if the pass is genuinely clean, say so plainly — an empty findings set is a success, not a failure. Done when: the audit pass is complete and every finding it surfaced is appended to ${AUDIT_FINDINGS_REL} with the right classification (or the report states plainly that nothing was found).`;
546
+ return `${LIST_AUDIT_COLLECT_MARKER} Run ONE project audit pass that COLLECTS work — the follow-up fixes are queued as separate list items, so this pass changes no code. 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 — 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) Change NOTHING — no fixes, no refactors, no drive-by edits: the orchestrator queues each open FIX finding as its own list item after this pass completes, and each fix lands with its own commit and its own audit. (4) DECIDE findings are appended as "- [?]" lines and NOTHING more the orchestrator raises them to the user as questions after the pass completes; they are never queued and never silently fixed. (5) Honesty law: never fabricate findings to look busy; if the pass is genuinely clean, say so plainly — an empty findings set is a success, not a failure. Done when: the audit pass is complete and every finding it surfaced is appended to ${AUDIT_FINDINGS_REL} with the right classification (or the report states plainly that nothing was found).`;
547
547
  }
548
548
 
549
549
  /** One parsed open finding from the audit findings file. */
@@ -604,5 +604,5 @@ export const LOOP_AUDIT_MARKER = "iteration by iteration — FIX-FIRST";
604
604
 
605
605
  export function projectAuditTarget(focus?: string): string {
606
606
  const scope = focus && focus.trim() ? focus.trim() : "the whole project";
607
- return `${GOAL_AUDIT_ONESHOT_MARKER}. 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.`;
607
+ return `${GOAL_AUDIT_ONESHOT_MARKER}. 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 — RAISE them instead: if any "- [?]" findings exist, present each one to the user with ask_user_question BEFORE calling complete_goal (one question per finding, options from the finding's own two sides plus "Defer"; prose numbered list if ask_user_question is unavailable; Esc = Defer), then record every answer in ${AUDIT_FINDINGS_REL} — replace the "- [?]" line with "- [x] DECIDED: <what was chosen> (<date>)" (or "- [x] DEFERRED") so it stops re-surfacing — and queue any chosen work with list_add. (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 has been raised to the user and recorded as DECIDED/DEFERRED (or the report states plainly that none were found).`;
608
608
  }
@@ -1385,10 +1385,24 @@ async function fanOutListAuditFindings(ctx: ExtensionContext): Promise<void> {
1385
1385
  // hundreds of items on a single Confirm.
1386
1386
  const fresh = open.filter((f) => !queuedText.includes(f.text.slice(0, 60))).slice(0, 50);
1387
1387
  const alreadyQueued = open.length - fresh.length;
1388
+ // v0.33.3: DECIDE findings are RAISED TO THE USER as real questions
1389
+ // (hegemon 2026-07-31: a truncated notify left the user typing "decide
1390
+ // what" into the void). The orchestrator can't call ask_user_question —
1391
+ // the agent can — so the full untruncated findings go to the agent as a
1392
+ // steer with the raise + record protocol. Fires BEFORE the queueing
1393
+ // early-returns below: decisions need answers even when nothing new
1394
+ // queued or the fan-out was declined.
1395
+ if (decisions.length > 0) {
1396
+ const decList = decisions.slice(0, 8).map((d, i) => `${i + 1}. ${d.slice(0, 500)}`).join("\n");
1397
+ extensionApi?.sendUserMessage(
1398
+ `[DECIDE FINDINGS — user decisions needed] The audit surfaced ${decisions.length} DECIDE finding(s) — direction calls only the user can make (a decision is not a task, so they were NOT queued):\n${decList}\nRaise them to the user NOW with ask_user_question — one question per finding, options from the finding's own two sides plus "Defer" (prose numbered list if ask_user_question is unavailable; Esc = Defer). Then record every answer in ${AUDIT_FINDINGS_REL}: replace the "- [?]" line with "- [x] DECIDED: <what was chosen> (<date>)" (or "- [x] DEFERRED") so it stops re-surfacing, and queue any chosen work with list_add — do NOT start the work inline.`,
1399
+ { deliverAs: ctx.isIdle() ? "followUp" : "steer" },
1400
+ );
1401
+ appendLedger(ctx.cwd, "list_audit_decisions_raised", { decisions: decisions.length });
1402
+ }
1388
1403
  const decideNote =
1389
1404
  decisions.length > 0
1390
- ? `\n${decisions.length} DECIDE finding(s) need YOU (not queued — a decision is not a task):\n` +
1391
- decisions.slice(0, 10).map((d) => ` ? ${d.slice(0, 110)}`).join("\n")
1405
+ ? ` ${decisions.length} DECIDE finding(s) need YOU — raising them as questions now (not queued — a decision is not a task).`
1392
1406
  : "";
1393
1407
  if (fresh.length === 0) {
1394
1408
  ctx.ui.notify(
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-goal-list-loop-audit",
3
- "version": "0.33.2",
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.",
3
+ "version": "0.33.4",
4
+ "description": "Mission control for autonomous pi: interview-drafted goals, an audited task queue, and forever-loops (metric, spec, project-audit) that run for hours. An isolated extension-less auditor re-verifies every completion with raw evidence; confirmed drafts, decision pauses and consent gates keep you in charge.",
5
5
  "license": "MIT",
6
6
  "author": "dracon",
7
7
  "type": "module",