pi-goal-list-loop-audit 0.35.13 → 0.35.64
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 +977 -0
- package/INSTALL.md +13 -3
- package/LIST-PHILOSOPHY.md +90 -0
- package/PLAN.md +316 -0
- package/README.md +201 -26
- 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/context-hygiene.ts +129 -0
- package/extensions/faulty-objective-recovery.ts +24 -0
- package/extensions/glla-state-root.ts +99 -0
- package/extensions/goal-agents-panel.ts +211 -0
- package/extensions/goal-commands.ts +226 -10
- package/extensions/goal-continuation.ts +119 -21
- package/extensions/goal-heartbeat.ts +560 -35
- package/extensions/goal-loop-auditor-process.ts +126 -4
- package/extensions/goal-loop-auditor.ts +3 -5
- package/extensions/goal-loop-backoff.ts +79 -0
- package/extensions/goal-loop-core.ts +197 -15
- package/extensions/goal-loop-dispatch.ts +3 -2
- package/extensions/goal-loop-display.ts +141 -8
- package/extensions/goal-loop-forever.ts +52 -3
- package/extensions/goal-loop-shield.ts +132 -26
- package/extensions/goal-loop-stats.ts +3 -2
- package/extensions/goal-loop.ts +101 -4
- package/extensions/goal-recovery.ts +8 -2
- package/extensions/goal-settings.ts +61 -14
- package/extensions/goal-state.ts +20 -0
- package/extensions/loops/goal-activation.ts +426 -45
- package/extensions/loops/goal-auditor-hooks.ts +39 -3
- package/extensions/loops/goal-auditor-surface.ts +32 -0
- package/extensions/loops/goal-list-queue.ts +72 -12
- package/extensions/loops/goal-orchestrator.ts +33 -1
- package/extensions/loops/goal-runtime-globals.ts +5 -0
- package/extensions/loops/goal-session.ts +68 -8
- package/extensions/loops/goal-settings-ui.ts +116 -5
- package/extensions/loops/goal-tools.ts +104 -29
- package/extensions/loops/goal-ui.ts +106 -1
- package/extensions/loops/goal.ts +7 -7
- package/extensions/main-model-recovery.ts +10 -0
- package/extensions/multi-model-picker.ts +45 -7
- package/extensions/payload-guard.ts +172 -0
- package/extensions/reviewer.ts +3 -1
- package/extensions/settings-menu.ts +39 -4
- package/package.json +9 -3
- package/prompts/goal-loop-plan-loop.md +31 -0
- package/prompts/goal-loop-plan.md +51 -0
- package/schemas/goal.schema.json +4 -1
- package/scripts/auditor-extension-fixture.mjs +19 -0
- package/scripts/goal-auditor-launch.mjs +19 -1
- package/scripts/goal-auditor-worker.mjs +15 -0
- package/scripts/verify-auditor-extensions-offline.mjs +72 -0
package/INSTALL.md
CHANGED
|
@@ -52,7 +52,7 @@ Then the other two modes:
|
|
|
52
52
|
|
|
53
53
|
## Install from source (developers)
|
|
54
54
|
|
|
55
|
-
Prerequisites: Node 22+ and bun (the test runner — `bun test`), pi-coding-agent, TypeScript 5.9+ (for `tsc --noEmit`).
|
|
55
|
+
Prerequisites: Node 22.19.0+ and bun (the test runner — `bun test`), pi-coding-agent, TypeScript 5.9+ (for `tsc --noEmit`).
|
|
56
56
|
|
|
57
57
|
```bash
|
|
58
58
|
git clone https://github.com/DraconDev/pi-goal-list-loop-audit.git # or use the local dir
|
|
@@ -111,8 +111,8 @@ a file or committed — narration alone is the narrate-but-don't-ship loop)
|
|
|
111
111
|
Why it changed: the v0.24.0 single-signal detector (same tool + same
|
|
112
112
|
result hash 3×) killed two real user loops that were shipping work with
|
|
113
113
|
stable verification output — stable verification is the GOAL state of a
|
|
114
|
-
metricless loop, not the stuck state.
|
|
115
|
-
|
|
114
|
+
metricless loop, not the stuck state. See `docs/DESIGN.md` for the shipped
|
|
115
|
+
design overview. `/loop start toolsamerepeat=0`
|
|
116
116
|
disables the legacy check entirely; `/loop finish [reason]` ends a loop
|
|
117
117
|
cleanly with stopReason `completed: <reason>` (distinct from
|
|
118
118
|
stuck/plateau/stopped-by-user).
|
|
@@ -143,6 +143,16 @@ NOT pause: the auditor's objections become a TODO list (`pendingTasks`)
|
|
|
143
143
|
rendered into every continuation, and the goal stays ACTIVE. Every
|
|
144
144
|
auto-event announces itself with a one-line notify.
|
|
145
145
|
|
|
146
|
+
## Subagent stall action (v0.35.64)
|
|
147
|
+
|
|
148
|
+
The subagent watchdog warns after short no-progress windows. A top-level
|
|
149
|
+
tracked child that remains frozen for the longer
|
|
150
|
+
`subagentHangEscalationMinutes` threshold (default `30`) receives one
|
|
151
|
+
child-specific abort request; the parent goal is not aborted. Set the value to
|
|
152
|
+
`0` under `/glla` for warning/telemetry only. Unreachable, nested, or
|
|
153
|
+
ownership-ambiguous children remain warning-only, and partial output stays
|
|
154
|
+
available for inspection.
|
|
155
|
+
|
|
146
156
|
## Subagent model inheritance (v0.24.6)
|
|
147
157
|
|
|
148
158
|
If you use `@tintinweb/pi-subagents`: its default `Explore` agent pins
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# List philosophy — the three-mode hierarchy
|
|
2
|
+
|
|
3
|
+
pi-goal-list-loop-audit ships three loops. They are NOT redundant — each
|
|
4
|
+
has a **distinct source of long-running-ness**:
|
|
5
|
+
|
|
6
|
+
| Mode | Item size | Long-running by | Typical lifetime |
|
|
7
|
+
|---|---|---|---|
|
|
8
|
+
| `/goal` | ONE big multi-hour task | **Scope** | Hours |
|
|
9
|
+
| `/list` | N items × short (minutes each) | **Queue depth** | Hours → days → weeks |
|
|
10
|
+
| `/loop` | 1 metric × infinite polish | **Bounds** | Until plateau/stop/finish |
|
|
11
|
+
|
|
12
|
+
## `/goal` — one big long task
|
|
13
|
+
|
|
14
|
+
`/goal` is the multi-hour mode. Its long-running property is **scope**:
|
|
15
|
+
one task that spans multiple agent runs, requires deep research, or would
|
|
16
|
+
take hours end-to-end. It ends only when the isolated auditor approves
|
|
17
|
+
the verification contract. If your work fits in a single agent run — a
|
|
18
|
+
focused change, one audit, a small refactor — it belongs in `/list`.
|
|
19
|
+
|
|
20
|
+
## `/list` — hundreds of short items
|
|
21
|
+
|
|
22
|
+
`/list` items are **short tasks, not multi-hour objectives**. Each item
|
|
23
|
+
should fit comfortably in a single agent run: minutes of work, a single
|
|
24
|
+
focused change. The list's long-running property is **queue depth** — the
|
|
25
|
+
queue can hold hundreds of items, activated one at a time, pushed over
|
|
26
|
+
days or weeks. An item longer than ~30 minutes probably wants breaking
|
|
27
|
+
up; much longer and it wants `/goal`.
|
|
28
|
+
|
|
29
|
+
`/list depth` shows the long-running state: queue depth, oldest item age,
|
|
30
|
+
and average item duration from your archived list items.
|
|
31
|
+
|
|
32
|
+
## `/loop` — metric-driven infinite polish
|
|
33
|
+
|
|
34
|
+
`/loop` improves ONE metric forever. Its long-running property is
|
|
35
|
+
**bounds**: it ends on plateau, on bounds (max iterations / time /
|
|
36
|
+
tokens), on `/loop stop`, or on `/loop finish` (graceful stop after the
|
|
37
|
+
current iteration).
|
|
38
|
+
|
|
39
|
+
## The wrapper-goal anti-pattern (why this doc exists)
|
|
40
|
+
|
|
41
|
+
Real incidents, 2026-07-24, two projects on the same day:
|
|
42
|
+
|
|
43
|
+
> "Close every weak point in `docs/per-screen-weak-points.md` (76 items,
|
|
44
|
+
> one commit each)" and "land all 40 findings as a tasklist, ordered by
|
|
45
|
+
> ROI" — each folded into **ONE** list item with an **aggregate**
|
|
46
|
+
> verification contract ("≥ 76 commits with `CLOSED:`", "≥ 32 fix(Wn)
|
|
47
|
+
> commits").
|
|
48
|
+
|
|
49
|
+
The work got done; the auto-committer squashed intermediate commits; the
|
|
50
|
+
literal commit count failed; the isolated auditor **correctly
|
|
51
|
+
disapproved** finished work. The failure was at step 1 — task
|
|
52
|
+
designation — not at the audit.
|
|
53
|
+
|
|
54
|
+
The fix: **N independent short items → N `/list` items**, each closing
|
|
55
|
+
exactly ONE finding with its own per-item contract ("close IMP-AUD3-68:
|
|
56
|
+
`Map.svelte:1528` missing `role`"). Per-item contracts are impossible to
|
|
57
|
+
squash. Any aggregate re-audit becomes the FINAL `/goal`, not the first.
|
|
58
|
+
|
|
59
|
+
Since v0.25.3 the drafting flow detects this shape ("N items" + "each" +
|
|
60
|
+
"one commit") and steers you to `items[]` — see the cross-recommend
|
|
61
|
+
block in `prompts/goal-loop-draft.md`.
|
|
62
|
+
|
|
63
|
+
Since v0.26.0 the **Reviewer** is the post-completion glue layer across
|
|
64
|
+
all three modes' terminal states: it converts completion findings into
|
|
65
|
+
`/list` items (bug/refactor, no Confirm), proposes architectural work as
|
|
66
|
+
`/goal` (Confirm), fires a regression-scan audit on clean completions,
|
|
67
|
+
and notifies + idles otherwise. See `INSTALL.md` "Reviewer".
|
|
68
|
+
|
|
69
|
+
## Audit Cadence: Why Every `/list` Task is Audited
|
|
70
|
+
|
|
71
|
+
Auditing occurs at the completion boundary of **every single `/list` task** (via the detached isolated auditor) before the next item in the queue can activate.
|
|
72
|
+
|
|
73
|
+
While auditing every item requires rigorous verification, it prevents **queue drift**:
|
|
74
|
+
- In a 50-item list, an unverified error in item #2 would otherwise silently corrupt the codebase, causing items #3 through #50 to fail or build on broken invariants.
|
|
75
|
+
- Per-task auditing ensures each item represents a rock-solid, verified invariant before the next task begins.
|
|
76
|
+
|
|
77
|
+
## Single-Trunk Execution Law & Parallelization
|
|
78
|
+
|
|
79
|
+
### Why "Main-Only" Outperforms Branch Swarms in Autonomous Loops
|
|
80
|
+
Speculative feature branching across autonomous subagents creates **stale context bubbles** and **merge collision debt**:
|
|
81
|
+
1. Agent A on branch-1 and Agent B on branch-2 both read from snapshot $T_0$.
|
|
82
|
+
2. Once Agent A lands a commit, Agent B is working on an obsolete codebase without knowing it.
|
|
83
|
+
3. Merging parallel LLM branches frequently causes semantic regressions and broken invariants.
|
|
84
|
+
|
|
85
|
+
### The Single-Trunk Operating Rule:
|
|
86
|
+
* **Serial Queue on `main`**: All queue items drain sequentially on the single primary working tree. Item $N+1$ always executes with 100% truthful, up-to-date context left by item $N$.
|
|
87
|
+
* **Transactional Green-or-Revert**: Every task either lands green (verified by tests and the detached auditor) and commits, or cleanly rolls back on `main` before the next backlog item is touched.
|
|
88
|
+
* **Safe Subagent Parallelism**: Subagents are used for **read-only research fan-out** (e.g. concurrent `Explore` queries across subsystems in a single turn) or standalone verification, rather than speculative mutating branches.
|
|
89
|
+
|
|
90
|
+
See `INSTALL.md` for the command surface.
|
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
|