pi-goal-list-loop-audit 0.35.13 → 0.35.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +366 -0
- package/INSTALL.md +3 -3
- package/LIST-PHILOSOPHY.md +90 -0
- package/PLAN.md +316 -0
- package/README.md +108 -13
- package/docs/DESIGN-subagent-visibility.md +76 -0
- package/docs/DESIGN.md +59 -8
- package/docs/GLLA-POSITIONING-AND-DECOMPOSITION-2026-08-08.md +6 -1
- package/docs/INDEX.md +4 -0
- package/docs/VISION-ASSIST.md +2 -2
- package/extensions/auditor-extensions.ts +289 -0
- package/extensions/goal-agents-panel.ts +185 -0
- package/extensions/goal-commands.ts +120 -6
- package/extensions/goal-continuation.ts +45 -2
- package/extensions/goal-heartbeat.ts +176 -5
- package/extensions/goal-loop-auditor-process.ts +26 -0
- package/extensions/goal-loop-auditor.ts +3 -5
- package/extensions/goal-loop-backoff.ts +79 -0
- package/extensions/goal-loop-core.ts +97 -4
- package/extensions/goal-loop-display.ts +107 -8
- package/extensions/goal-loop-forever.ts +39 -1
- package/extensions/goal-loop-shield.ts +114 -25
- package/extensions/goal-loop.ts +66 -1
- package/extensions/goal-recovery.ts +8 -2
- package/extensions/goal-settings.ts +23 -0
- package/extensions/goal-state.ts +11 -0
- package/extensions/loops/goal-activation.ts +226 -25
- package/extensions/loops/goal-auditor-hooks.ts +39 -3
- package/extensions/loops/goal-list-queue.ts +17 -1
- package/extensions/loops/goal-orchestrator.ts +28 -1
- package/extensions/loops/goal-settings-ui.ts +96 -5
- package/extensions/loops/goal-tools.ts +82 -28
- package/extensions/loops/goal-ui.ts +105 -1
- package/extensions/loops/goal.ts +7 -7
- package/extensions/multi-model-picker.ts +45 -7
- package/extensions/settings-menu.ts +10 -0
- package/package.json +8 -3
- package/schemas/goal.schema.json +2 -0
- package/scripts/goal-auditor-launch.mjs +19 -1
- package/scripts/goal-auditor-worker.mjs +15 -0
- package/scripts/verify-auditor-extensions-offline.mjs +59 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,371 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.35.32 — hermetic settings round-trip test (2026-08-22)
|
|
4
|
+
|
|
5
|
+
### Fix
|
|
6
|
+
tests/auditor-extensions.test.ts depended on the developer machine having
|
|
7
|
+
~/.pi/agent extensions to discover: on a bare CI home the discovered list
|
|
8
|
+
was empty, the handler fell back to the input prompt, and the TUI-picker
|
|
9
|
+
branch under test never ran (publish workflow failure). The test now seeds
|
|
10
|
+
a project-scope `.pi/extensions/hermetic-ext.js` so discovery is non-empty
|
|
11
|
+
on every machine; verified green under both an empty HOME and a populated one.
|
|
12
|
+
|
|
13
|
+
## 0.35.31 — user-seed trust for /goal start; loop plateau no longer false-stops on a never-moved baseline (2026-08-22)
|
|
14
|
+
|
|
15
|
+
### Fix 1: explicit /goal start paused by the suspicious-objective heuristic
|
|
16
|
+
Field: Screenshot_20260822_193744 — `/goal start "…because we are logged in"`
|
|
17
|
+
was parked as "Suspicious objective detected (dangling-fragment)" with a
|
|
18
|
+
repair task queued instead of dispatching. The fragment heuristics exist
|
|
19
|
+
for AGENT-authored report garbage; an explicit `/goal start` whose
|
|
20
|
+
objective is verbatim a user seed now dispatches and ledgers
|
|
21
|
+
`faulty_objective_user_seed_trusted` (/goal tweak remains available).
|
|
22
|
+
### Fix 2: loop plateau vs a degenerate zero baseline
|
|
23
|
+
Field: doomtap loop stopped "plateau — best: 0" while iterations visibly
|
|
24
|
+
fixed real findings: a min-direction metric reading 0 before work starts
|
|
25
|
+
pins best at 0, so every later productive reading scores flat and burns
|
|
26
|
+
plateau slots. Flat readings now count toward plateau only once the metric
|
|
27
|
+
has demonstrably moved (an improvement on record, or best ≠ first measured
|
|
28
|
+
reading of the run); a metric that NEVER moves gets its own loud bounded
|
|
29
|
+
stop ("metric never moved …") after 2× window, not a fake plateau.
|
|
30
|
+
|
|
31
|
+
## 0.35.30 — durable last-outcome retention: the final verdict stays visible (2026-08-22)
|
|
32
|
+
|
|
33
|
+
### Gap
|
|
34
|
+
Field report with screenshots (email-api-compare, 2026-08-22): "goal gets
|
|
35
|
+
closed before final audit, so auditor never approves." Forensics showed the
|
|
36
|
+
lifecycle was CORRECT — every archived goal had an approving verdict — but
|
|
37
|
+
closeArchivedSlot nulled the widget slot the moment the goal archived, so
|
|
38
|
+
after the agent's turn ended the surface went completely blank and the only
|
|
39
|
+
trace of the approval was one transient toast. Returning later, "Auditor
|
|
40
|
+
verdict pending" was the last visible text: indistinguishable from closed-
|
|
41
|
+
without-audit.
|
|
42
|
+
### Ship
|
|
43
|
+
- State.lastOutcome {at, ok, title, recap}: written by closeArchivedSlot on
|
|
44
|
+
every terminal slot close (approved AND aborted), overwritten per outcome.
|
|
45
|
+
- Widget: while no goal/list/loop occupies the slot, one dim retention line
|
|
46
|
+
renders for 24h — "✓ done · auditor … approved · <recap>" or "▪ ended ·
|
|
47
|
+
<reason>" — then goes silent. A live goal always outranks it.
|
|
48
|
+
- /glla wipe clears the record (clean slate means clean).
|
|
49
|
+
- Tests: tests/last-outcome-retention.test.ts (5) — render shapes, expiry +
|
|
50
|
+
garbage-timestamp safety, live-goal precedence, source pins for both
|
|
51
|
+
write and wipe-clear sites.
|
|
52
|
+
|
|
53
|
+
## 0.35.29 — /glla agents: tracked-subagent panel, transcript tail, widget segment (2026-08-22, GitHub issue #15)
|
|
54
|
+
|
|
55
|
+
### Gap
|
|
56
|
+
During long fan-outs the only child visibility was the widget's 3-slot
|
|
57
|
+
recent-action ring. A child that "almost completed its final report, went
|
|
58
|
+
back to check some more, then crashed" was invisible: no live status, no
|
|
59
|
+
counters, and no post-mortem trail anyone could find (issue #15).
|
|
60
|
+
Scope agreed with the user: panel + transcript tail + widget line; a live
|
|
61
|
+
activity stream was explicitly rejected as too noisy.
|
|
62
|
+
### Ship
|
|
63
|
+
- getSubagentAgentsSnapshot() (goal-heartbeat.ts): read-only view of the
|
|
64
|
+
tracked-subagent probes with hung classification mirroring the watchdog
|
|
65
|
+
scan WITHOUT its counter mutation; record-frozen vs event-only evidence
|
|
66
|
+
named; degrades gracefully when the pi-subagents manager registry is
|
|
67
|
+
absent (as on currently installed versions).
|
|
68
|
+
- /glla agents: ranked table (hung > running > ended), per-child
|
|
69
|
+
tools/output/silent clocks, liveness hint on hung rows, 20-row cap with
|
|
70
|
+
an explicit trim notice. Read-only, stale-safe.
|
|
71
|
+
- /glla agents --tail <id> [--lines N]: locates the child's session file
|
|
72
|
+
in the cwd-munged session store by needle + newest mtime and prints the
|
|
73
|
+
last N entries tolerantly ([role] text, raw fallback). LOUD when nothing
|
|
74
|
+
matches — searched dir, transcript count, needles. Never resumes or
|
|
75
|
+
attaches to a child session.
|
|
76
|
+
- Widget segment: "● N agents · <busiest> silent Xm ⚠" appended to every
|
|
77
|
+
card shape via buildWidgetLines; hidden at zero tracked children.
|
|
78
|
+
- New pure module extensions/goal-agents-panel.ts; snapshot reaches
|
|
79
|
+
goal-commands via CommandDeps injection (no heartbeat import cycle).
|
|
80
|
+
|
|
81
|
+
## 0.35.28 — due-wait backstop: lapsed wait pauses actually resume; "you were recovered" notice (2026-08-22, GitHub issue #16)
|
|
82
|
+
|
|
83
|
+
### Root cause (field: goal paused 30min past its scheduled auto-resume while the agent narrated "the system should have auto-resumed by now")
|
|
84
|
+
Auto-resume for pauseKind "wait" relied SOLELY on in-memory timers. An
|
|
85
|
+
exhaustive map of every wait-pause site found: agent-authored waits
|
|
86
|
+
(pause_goal kind="wait") armed NO timer at all while their own copy
|
|
87
|
+
promised automatic continuation; error-brake cooldown waits were not
|
|
88
|
+
re-armed on session_start; single-slot provider-retry timers could be
|
|
89
|
+
silently clobbered by a later schedule; and no code path anywhere compared
|
|
90
|
+
wall time against pauseResumeAt outside display rendering.
|
|
91
|
+
### Fix
|
|
92
|
+
The heartbeat owns the durable invariant now: every tick, a wait whose
|
|
93
|
+
pauseResumeAt lapsed >90s is re-fired — main-model recovery waits route to
|
|
94
|
+
a provider probe, everything else clears the park and dispatches one fresh
|
|
95
|
+
continuation. supervisorPaused() still freezes it under /glla pause and
|
|
96
|
+
the load hold, one attempt per (goalId:resumeAt) key prevents storms (the
|
|
97
|
+
route re-parks with a fresh resumeAt on failure), and every fire is
|
|
98
|
+
ledgered wait_pause_overdue_resume. A stale hold persisted by a previous
|
|
99
|
+
process is released when a consenting reload arrives. Issue part 2:
|
|
100
|
+
resumed goals carry an autoResumed stamp rendered as a RECOVERY NOTICE in
|
|
101
|
+
the continuation prompt — "welcome back, YOU were recovered" — so agents
|
|
102
|
+
stop waiting for an external recovery signal that already happened.
|
|
103
|
+
|
|
104
|
+
## 0.35.27 — Windows auditor launch: quote only when needed, gate always first (2026-08-22, PR #17)
|
|
105
|
+
|
|
106
|
+
### Field report (PR #17, reproduced on Windows 11 + pnpm global shim)
|
|
107
|
+
The detached auditor died ~0.5s after launch and retried forever: quoting
|
|
108
|
+
EVERY argument wraps a bare executable name in quotes, which changes how
|
|
109
|
+
cmd.exe resolves it and how npm/pnpm .CMD shims compute their own
|
|
110
|
+
directory -> MODULE_NOT_FOUND -> "pi exited without an agent_settled RPC
|
|
111
|
+
event" in a 60s retry loop of flashing terminal windows.
|
|
112
|
+
### Fix
|
|
113
|
+
buildAuditorPiSpawnSpec now runs the WINDOWS_UNSAFE_ARG rejection on EVERY
|
|
114
|
+
argument BEFORE the quoting decision, then quotes only when tokenization
|
|
115
|
+
requires it (whitespace / cmd metacharacters / empty). Clean bare tokens
|
|
116
|
+
reach cmd.exe untouched (shims resolve; full RPC sessions work); the
|
|
117
|
+
upstream PR's variant was not mergeable as-is because its needs-quoting
|
|
118
|
+
regex also gated the unsafe-arg check, letting %/CR/LF through bare.
|
|
119
|
+
Regression tests pin all three classes through the spec builder.
|
|
120
|
+
|
|
121
|
+
## 0.35.26 — zombie watchdog recognizes pi-subagents tool names (2026-08-22, GitHub issue #13)
|
|
122
|
+
|
|
123
|
+
### Gap
|
|
124
|
+
The v0.35.4 subagent-wait carve-out matched only the legacy built-in names
|
|
125
|
+
(Agent / get_subagent_result / steer_subagent). The pi-subagents extension
|
|
126
|
+
registers its foreground dispatch tool as "subagent" and a blocking wait as
|
|
127
|
+
"subagent_wait", so a parent legitimately BUSY on a healthy foreground child
|
|
128
|
+
tripped the bounded abort: field report shows a child writing Postgres
|
|
129
|
+
records productively for 30 minutes while the parent was stream-silent on
|
|
130
|
+
`subagent` — zombie_run_suspected at 20m, loop_stopped + zombie_run_aborted
|
|
131
|
+
at 30m, productive work killed mid-write.
|
|
132
|
+
### Fix
|
|
133
|
+
One shared SUBAGENT_WAIT_TOOL_NAMES set + isSubagentWaitCall predicate in
|
|
134
|
+
goal-heartbeat.ts, consumed by BOTH sites (zombie stand-down and wedge-alert
|
|
135
|
+
hint) so the lists cannot drift apart again. New names: "subagent",
|
|
136
|
+
"subagent_wait". Behavioral tests drive the real heartbeat tick with a real
|
|
137
|
+
tool_call event: stand-down while in flight, clean abort once it settles,
|
|
138
|
+
no blanket amnesty.
|
|
139
|
+
|
|
140
|
+
## 0.35.25 — /loop resume honors the zero-stream abort park (2026-08-22, GitHub issue #14)
|
|
141
|
+
|
|
142
|
+
### Gap
|
|
143
|
+
abortZombieRun parks a loop with stopReason "stopped: automatic zero-stream
|
|
144
|
+
abort — ... (iteration N preserved; /loop resume to retry)" and its message
|
|
145
|
+
promises /loop resume — but the RESUMABLE_STOP predicate in the resume
|
|
146
|
+
handler never matched that prefix. The explicit resume answered "No held
|
|
147
|
+
loop to resume"; iteration count, best value, and preserved history were
|
|
148
|
+
unreachable without re-drafting from scratch (field report: a metricless
|
|
149
|
+
24h loop parked at iteration 210 with 200 history entries).
|
|
150
|
+
### Fix
|
|
151
|
+
RESUMABLE_STOP gains the "stopped: automatic zero-stream abort" prefix.
|
|
152
|
+
The explicit resume now re-arms the loop exactly as promised: fresh stall
|
|
153
|
+
window, re-armed counters, load hold released, one new dispatch — with
|
|
154
|
+
iteration/best/history intact. Control test pins that non-resumable stops
|
|
155
|
+
(e.g. bounds) stay stopped.
|
|
156
|
+
|
|
157
|
+
## 0.35.24 — auditor model picker at full selector parity: forbidden-models filtering (2026-08-22, note.md Next #1)
|
|
158
|
+
|
|
159
|
+
### Gap
|
|
160
|
+
The /glla -> Auditor model row already hosted the /model-style fuzzy
|
|
161
|
+
picker and persisted to the exact key resolveAuditorModel reads — but
|
|
162
|
+
unlike every main-agent flow it did NOT apply forbidden-models policy:
|
|
163
|
+
blocked models appeared in the list and the typed escape hatch accepted
|
|
164
|
+
them, yielding pins the resolver silently skips at audit time.
|
|
165
|
+
### Fix
|
|
166
|
+
promptModelRef gains an excludeRefs opt threading into buildModelPickItems
|
|
167
|
+
(list-level filter) AND validating typed entries against isForbiddenModel
|
|
168
|
+
(a policy match is refused with a warning naming the ref — never saved).
|
|
169
|
+
Both auditor slots use it: Auditor model and Auditor fallback agent.
|
|
170
|
+
A pin saved by the picker is one the resolver honors; runtime skips
|
|
171
|
+
(auditor_model_fallback reason:"forbidden") remain as belt-and-suspenders.
|
|
172
|
+
|
|
173
|
+
## 0.35.23 — load without autostart: cold sessions hold automation for an explicit decision (2026-08-22, note.md Next #2)
|
|
174
|
+
|
|
175
|
+
### Root cause
|
|
176
|
+
shouldAutoResumeOnSessionStart already demanded explicit `autoResume ===
|
|
177
|
+
true` (v0.28.21 tri-state, undefined default = HOLD) — but its only
|
|
178
|
+
consumer fed it the AGGRESSIVE-MODE COERCED value (unset -> true because
|
|
179
|
+
aggressiveMode defaults on), so stock installs auto-resumed everything on
|
|
180
|
+
every session load despite the documented default. Three further paths
|
|
181
|
+
bypassed the consent entirely.
|
|
182
|
+
### Fixes
|
|
183
|
+
- Load consent now reads the RAW global autoResume setting; aggressive
|
|
184
|
+
mode keeps owning its caps only. Default (unset/false) = restore and
|
|
185
|
+
DISPLAY state, hold automation.
|
|
186
|
+
- New durable loadHoldAt state engages through the SAME freeze gates as
|
|
187
|
+
/glla pause (continuation dispatch, loop ticks, heartbeat refires,
|
|
188
|
+
recovery timers); released by any explicit work command (/goal resume,
|
|
189
|
+
/list resume, /list next, /loop resume|start, new goal creation),
|
|
190
|
+
each release ledgered load_hold_released. Heartbeat host-loss
|
|
191
|
+
supervision stays armed under the hold — a held plane is never an
|
|
192
|
+
unprobed idle plane.
|
|
193
|
+
- Closed consent bypasses: different-pid crash successors no longer
|
|
194
|
+
auto-resume held loops or replay journals as automation (same-process
|
|
195
|
+
/reload successors keep continuity); parked completion-audit claims no
|
|
196
|
+
longer auto-retry on a bare cold start (the main-model-recovery one-
|
|
197
|
+
shot retry keeps its pinned consent).
|
|
198
|
+
|
|
199
|
+
## 0.35.22 — a queued item blocked by a live loop is loud and self-heals at loop end (2026-08-22)
|
|
200
|
+
|
|
201
|
+
### suspicious-unstartable-repair-card fix (note.md Next #3)
|
|
202
|
+
Field (screenshots 20260821_114109/114210/134442/134645): /goal start of a
|
|
203
|
+
lowercase-fragment objective paused the goal and queued a repair task; the
|
|
204
|
+
card said "/list next starts the preserved repair/replan task" — but with
|
|
205
|
+
the Chrome-Bridge loop owning the surface, activateNextListItem's
|
|
206
|
+
one-active-thing guard refused activation LEDGER-ONLY: unstartable AND
|
|
207
|
+
invisibly blocked. Two fixes:
|
|
208
|
+
- the refusal now notifies with the queued objective and the way out
|
|
209
|
+
("/loop stop … then /list next"), and the ledger names what stayed queued;
|
|
210
|
+
- when a loop ends by ANY route (/loop stop, /loop finish, plateau/bounds
|
|
211
|
+
stop), resumeQueuedListAfterLoopEnd retries list activation when no goal
|
|
212
|
+
owns the surface — the blocked entry starts instead of staying dead.
|
|
213
|
+
Also: tests/list-invisible-restart.test.ts no longer depends on co-resident
|
|
214
|
+
module state (unique owner session + explicit reset), fixing the cross-file
|
|
215
|
+
ordering failure surfaced by audit round eight.
|
|
216
|
+
|
|
217
|
+
## 0.35.21 — list queue stays visible across lifecycle boundaries (2026-08-22)
|
|
218
|
+
|
|
219
|
+
### list-invisible-until-restart fix (note.md Next #4)
|
|
220
|
+
Field: a stopped/interrupted /list exec left the queue surface blank —
|
|
221
|
+
active item only, no "N waiting · up next" line — until a session
|
|
222
|
+
restart. Root cause: the sidebar renders state.list from MEMORY while the
|
|
223
|
+
durable queue is the UNION of the state ledger and the per-item
|
|
224
|
+
.queue.json sidecars (v0.34.60 disk-first writes); a plugin re-init /
|
|
225
|
+
stale-handle window reset RAM to defaults and only some later path
|
|
226
|
+
re-ran the disk merge. session_start's restore now converges memory to
|
|
227
|
+
that union immediately (hydrateListQueueFromDisk after readState), so
|
|
228
|
+
the next lifecycle boundary heals the surface without a restart; the
|
|
229
|
+
hydration notifies with a truthful count ("restored N queued list
|
|
230
|
+
item(s)"). Regression tests: sidecar-only item is hydrated AND rendered;
|
|
231
|
+
convergence is idempotent (no duplicate for items in both stores).
|
|
232
|
+
|
|
233
|
+
## 0.35.20 — one bounded automatic retry for transient mechanical-check deaths (2026-08-21)
|
|
234
|
+
|
|
235
|
+
### Gate resilience
|
|
236
|
+
Field (sixth audit round): the pre-audit gate died MID-RUN under machine
|
|
237
|
+
load ~30 — output ends inside a passing file, no runner summary, exit 1 —
|
|
238
|
+
while the identical tree passed green twice in isolation. Resource
|
|
239
|
+
contention, not a red suite. Mechanical check commands now get exactly ONE
|
|
240
|
+
bounded automatic retry on failure: a deterministic red command stays red
|
|
241
|
+
on both attempts (final output names the retry and preserves the second
|
|
242
|
+
attempt's diagnostics); a first-attempt transient death followed by a
|
|
243
|
+
passing retry passes with an honest `recoveredRetryNote` in the result.
|
|
244
|
+
Mirrors the v0.35.17 zero-stream auto-retry philosophy at the gate level.
|
|
245
|
+
|
|
246
|
+
## 0.35.19 — load-resilient budgets for the aggressive-recovery test (2026-08-21)
|
|
247
|
+
|
|
248
|
+
### Flake hardening
|
|
249
|
+
At machine load ~50 (16 cores), the aggressive no-verdict recovery test's
|
|
250
|
+
wall-clock wait budgets (2x 25s inside a 60s per-test ceiling) expired
|
|
251
|
+
before two real subprocess-based auditor retry cycles completed — while
|
|
252
|
+
the canonical full-suite run stayed green in the same conditions. Raised:
|
|
253
|
+
per-test 60s→120s, retry waits 25s→45s, state-transition waits 8s→20s.
|
|
254
|
+
Budgets only; semantics untouched (same precedent as v0.35.15's 30s→60s).
|
|
255
|
+
|
|
256
|
+
## 0.35.18 — mechanical checks resolve raw runners to their canonical scripts (2026-08-21)
|
|
257
|
+
|
|
258
|
+
### Spurious fast-fail fix (fourth audit round)
|
|
259
|
+
A verification contract that names a RAW RUNNER in prose ("passes under
|
|
260
|
+
`bun test`") made the deterministic pre-audit execute `bun test` bare,
|
|
261
|
+
ignoring the project's own required configuration encoded in package.json
|
|
262
|
+
scripts (--parallel=1 --max-concurrency=1 --timeout; this suite shares
|
|
263
|
+
module state process-wide by design and serializes deliberately). The bare
|
|
264
|
+
invocation failed 6 tests + 5 nested-test errors while the canonical gate
|
|
265
|
+
was green twice — a spurious fast-fail of finished work. Mechanical check
|
|
266
|
+
commands that are exactly a raw runner invocation (bun test / vitest /
|
|
267
|
+
jest, no extra args) now resolve to the package script that wraps them;
|
|
268
|
+
narrower runs and non-runner programs pass through untouched. Pure resolver
|
|
269
|
+
(`resolveCanonicalRunnerCommand`) lives in goal-loop-backoff.ts with unit
|
|
270
|
+
tests; bunfig cannot express the required flags (verified empirically:
|
|
271
|
+
`[test] timeout` is not honored on bun 1.3.14).
|
|
272
|
+
|
|
273
|
+
## 0.35.17 — zero-stream abort gains ONE bounded automatic retry; tag backfill (2026-08-21)
|
|
274
|
+
|
|
275
|
+
### Post-accept hang self-heal (note.md Next §1)
|
|
276
|
+
Turns dispatched by accepting a Confirm dialog hung with zero provider
|
|
277
|
+
stream activity often enough that users repeatedly returned to parked
|
|
278
|
+
"action needed" sessions (field screenshot 20260821_152311). The watchdog's
|
|
279
|
+
bounded abort was correct; what was missing is self-heal. The FIRST silence
|
|
280
|
+
of a zero-stream streak now arms exactly ONE automatic retry ~90s after the
|
|
281
|
+
park — the parked goal/list item/loop auto-resumes through the durable
|
|
282
|
+
continuation machinery and one fresh dispatch goes out. A SECOND consecutive
|
|
283
|
+
silence refuses further retries (`zombie_auto_retry_refused_streak`) and
|
|
284
|
+
parks permanently for manual resume; real stream activity between aborts
|
|
285
|
+
resets the streak so an independent later hang earns its own single retry.
|
|
286
|
+
`/glla pause` freezes the retry like every other automatic side-effect;
|
|
287
|
+
the timer only clears a pause carrying exactly the watchdog's own reason
|
|
288
|
+
(a newer manual/recovery pause supersedes it); the heartbeat's one-shot
|
|
289
|
+
abort latch is released on retry dispatch so a fully-silent retry can still
|
|
290
|
+
be re-aborted. Pure streak decision lives in goal-loop-backoff.ts
|
|
291
|
+
(`zombieRetryDecision`) with unit tests; behavioral coverage drives the
|
|
292
|
+
full hang→abort/park→auto-resume→re-dispatch arc plus the double-hang and
|
|
293
|
+
pause-during-waystation paths (tests/post-accept-hang-retry.test.ts).
|
|
294
|
+
|
|
295
|
+
### Version tags backfilled
|
|
296
|
+
All 41 released versions missing their `v<version>` git tag (v0.34.20 …
|
|
297
|
+
v0.35.16) were tagged at the historical commit whose package.json carried
|
|
298
|
+
that exact version and pushed to all remotes. Additive-only — no history
|
|
299
|
+
rewrite.
|
|
300
|
+
|
|
301
|
+
### README currency pass
|
|
302
|
+
Documents the v0.35.15 per-phase glyphs/activity meter/silent-stretch
|
|
303
|
+
footer, `/glla pause`, and the v0.35.17 zero-stream auto-retry.
|
|
304
|
+
|
|
305
|
+
## 0.35.16 — mechanical pre-audit gate no longer kills legitimate long checks (2026-08-21)
|
|
306
|
+
|
|
307
|
+
### Deterministic pre-audit timeout fix
|
|
308
|
+
`runMechanicalPreAuditChecks` executed every contract command under a
|
|
309
|
+
hard 60-second `execFileSync` ceiling — but this repo's own contract
|
|
310
|
+
command (`npm run release:check`) legitimately needs ~3 minutes. Every
|
|
311
|
+
deterministic pre-audit therefore fast-failed with a truncated
|
|
312
|
+
head-of-output report showing only startup logs (two field rounds:
|
|
313
|
+
2026-08-21 14:17 and 16:01), burning two auditor cycles on a gate that
|
|
314
|
+
could never pass inside its own bound. The default bound is now 10 minutes
|
|
315
|
+
— still a hang guard, no longer an honest-slow-work guard. Failed output
|
|
316
|
+
keeps the TAIL (where failures live) instead of the head, truncation is
|
|
317
|
+
labeled, and a timeout kill is bannered as such instead of masquerading as
|
|
318
|
+
an exit-code-1 test failure.
|
|
319
|
+
|
|
320
|
+
## 0.35.15 — glla status-surface UX: visual footer, /glla pause, proactive quiet notify (2026-08-21)
|
|
321
|
+
|
|
322
|
+
### Visual status footer
|
|
323
|
+
The auditing footer now leads each auditor phase with a distinct glyph
|
|
324
|
+
(queued ⋯ · running ▶ · quiet ◌ · blocked ⛔ · awaiting-verdict ✓) and a
|
|
325
|
+
compact draining activity meter (▰▱) that empties as worker silence grows
|
|
326
|
+
toward the quiet threshold. A glance answers "is the audit alive?" without
|
|
327
|
+
reading the sentence.
|
|
328
|
+
|
|
329
|
+
### /glla pause | resume — broad supervisor freeze
|
|
330
|
+
`/glla pause` freezes ALL automatic machinery — heartbeat re-arms, stale
|
|
331
|
+
probes, zombie cleanup, main-model recovery probes, automatic completion-
|
|
332
|
+
audit recovery, continuation dispatch, loop ticks, and the proactive quiet
|
|
333
|
+
notification — while leaving the active goal/list item/loop and any
|
|
334
|
+
detached worker untouched. The flag persists via `supervisorPausedAt`, so a
|
|
335
|
+
session restart cannot silently re-arm machinery the user explicitly
|
|
336
|
+
stopped. `/glla resume` clears it first, then resumes whatever else is
|
|
337
|
+
resumable, and never follows with a misleading "Nothing to resume". Manual
|
|
338
|
+
user commands always still work.
|
|
339
|
+
|
|
340
|
+
### Proactive auditor quiet reporting
|
|
341
|
+
Entering the quiet phase (~3 min of zero worker activity) now fires exactly
|
|
342
|
+
ONE warning notify instead of only recoloring the status chip — the field
|
|
343
|
+
complaint was an 8-minute silent stretch the user only discovered after the
|
|
344
|
+
fact. Once activity resumes, the footer shows "silent Xm then resumed" for
|
|
345
|
+
10 minutes so a missed silence stays visible.
|
|
346
|
+
|
|
347
|
+
### Persistence fix (latent bug)
|
|
348
|
+
`persistStateLine` never serialized `lastCompactionAt` despite v0.34.97's
|
|
349
|
+
comment claiming it did — the ⏳ compacting… chip silently lost its reload
|
|
350
|
+
survival. Both epoch fields now ride the state line with explicit nulls so
|
|
351
|
+
ledger merges clear them correctly.
|
|
352
|
+
|
|
353
|
+
## 0.35.14 — full extension audit hardening (2026-08-21)
|
|
354
|
+
|
|
355
|
+
### Verification and lifecycle integrity
|
|
356
|
+
Mechanical contract checks now run through a shell-free literal-argument
|
|
357
|
+
boundary, auditor verdicts require one final terminal marker, and regression
|
|
358
|
+
shield references must appear inside `<evidence>`. Invalid persisted IDs are
|
|
359
|
+
rejected at state hydration and filesystem boundaries. Child extension
|
|
360
|
+
factories no longer claim the host API or start timers before an admitted
|
|
361
|
+
`session_start`; completion approval cannot report success when terminal
|
|
362
|
+
archiving fails, and branch-mode loop resumes refuse the wrong branch.
|
|
363
|
+
|
|
364
|
+
### Release contract
|
|
365
|
+
Published documentation includes the linked planning files, the workflow
|
|
366
|
+
runs the release contract on pushes and pull requests, and release tooling
|
|
367
|
+
uses pinned Node/npm versions.
|
|
368
|
+
|
|
3
369
|
## 0.35.13 — stale-API recovery loop fix (2026-08-20)
|
|
4
370
|
|
|
5
371
|
### Stale-handle recovery correctness
|
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).
|
|
@@ -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.
|