pi-goal-list-loop-audit 0.34.20 → 0.34.48
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 +150 -47
- package/docs/DESIGN.md +99 -10
- package/docs/RELEASING.md +49 -0
- package/extensions/goal-loop-auditor-process.ts +387 -0
- package/extensions/goal-loop-auditor.ts +32 -10
- package/extensions/goal-loop-backoff.ts +25 -0
- package/extensions/goal-loop-core.ts +86 -6
- package/extensions/goal-loop-dispatch.ts +155 -0
- package/extensions/goal-loop-display.ts +559 -49
- package/extensions/goal-settings.ts +14 -3
- package/extensions/loops/goal.ts +2445 -660
- package/extensions/main-model-recovery.ts +141 -0
- package/extensions/model-picker.ts +10 -1
- package/extensions/quota-retry.ts +126 -35
- package/extensions/settings-menu.ts +45 -6
- package/package.json +4 -3
- package/schemas/goal.schema.json +20 -1
- package/scripts/goal-auditor-worker.mjs +419 -0
package/README.md
CHANGED
|
@@ -2,15 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
> **Mission control for autonomous pi.**
|
|
4
4
|
|
|
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`
|
|
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` queues a **detached auditor worker process** to verify the work without holding the main pi turn open. Stall recovery, structured decision pauses, and consent gates keep you in charge while it works.
|
|
6
6
|
|
|
7
|
-
The auditor runs in a fresh
|
|
7
|
+
The auditor runs in a fresh extension-less pi RPC process with no extensions, skills, prompts, themes, or context files. It has only `read` / `grep` / `find` / `ls` / `bash`. It cannot see the implementing conversation, cannot mutate glla state, and cannot plant evidence. Its durable result is identity-checked and revalidated by the parent before it can archive a goal.
|
|
8
|
+
|
|
9
|
+
This is a detached process, not a nested session in the main pi process. `complete_goal` returns after writing the claim and job request; the status surface shows `auditor queued`, `auditor running`, or `audit recovery pending` while the worker runs or awaits a fresh lifecycle.
|
|
8
10
|
|
|
9
11
|
## Why this exists
|
|
10
12
|
|
|
11
13
|
Most pi goal extensions — `pi-goal`, `pi-goal-x`, `pi-loop-mode`, `ralphi`, `tmustier-pi-ralph-wiggum` — let the same agent that did the work also be the verifier. **That's the bamboozle trap.** The agent that wrote the implementation also says "I'm done", and the loop trusts them.
|
|
12
14
|
|
|
13
|
-
`pi-goal-list-loop-audit` separates **implementation** from **verification**. Two independent
|
|
15
|
+
`pi-goal-list-loop-audit` separates **implementation** from **verification**. Two independent processes, two independent read paths, two perspectives.
|
|
14
16
|
|
|
15
17
|
### Architectural guarantee
|
|
16
18
|
|
|
@@ -18,7 +20,7 @@ Most pi goal extensions — `pi-goal`, `pi-goal-x`, `pi-loop-mode`, `ralphi`, `t
|
|
|
18
20
|
|---|---|
|
|
19
21
|
| Goal intake | Drafting + Confirm/Reject dialog; nothing activates unconfirmed |
|
|
20
22
|
| Implementation | `agent_end`-driven continuation loop with 5-minute hard backoff cap |
|
|
21
|
-
| Completion |
|
|
23
|
+
| Completion | Detached extension-less auditor process + **regression_shield**: raw command output required per verification-contract item, enforced orchestrator-side |
|
|
22
24
|
|
|
23
25
|
## Quick start
|
|
24
26
|
|
|
@@ -40,11 +42,11 @@ Five top-level commands — `/goal`, `/list`, `/loop`, `/glla`, `/review`:
|
|
|
40
42
|
/goal resume # resume
|
|
41
43
|
/goal cancel # abort
|
|
42
44
|
/goal decide # re-open the decision picker (v0.28.23)
|
|
43
|
-
/goal audit
|
|
44
|
-
/goal verify #
|
|
45
|
+
/goal audit "focus on payments" # one-shot project audit; optional focus text
|
|
46
|
+
/goal verify # queue a detached auditor for the current goal — no agent turn (v0.28.27, renamed from /goal audit in v0.29.8)
|
|
45
47
|
/goal tweak "<new objective>" # edit in place (Confirm dialog)
|
|
46
48
|
/goal archive # archived goals, newest first
|
|
47
|
-
/glla # settings UI table ·
|
|
49
|
+
/glla # settings UI table · arguments are actions: /glla status · /glla stats · /glla audits [N|full] · /glla postaudit · /glla wipe (nuclear reset, Confirm-gated)
|
|
48
50
|
/list fix the login bug, add dark mode, write docs # dump it — the agent shapes it into items, one Confirm
|
|
49
51
|
/list plan.md # file detected → bulk import, one Confirm (sisyphus/Ralph style)
|
|
50
52
|
/list <paste a checklist> # multi-line paste → same batch flow
|
|
@@ -215,16 +217,94 @@ Each loop is a different policy class on the same status machine.
|
|
|
215
217
|
| Auditor can rubber-stamp after `bash true` | **regression_shield** (shipped v0.2.0): auditor must quote raw tool output per verification-contract item; orchestrator rejects evidence-free approvals |
|
|
216
218
|
| `pause_goal` is fire-and-forget | Clear `pauseReason` surfaced in status + agent feedback |
|
|
217
219
|
| Vague objective + weak auditor = rubber-stamp | Drafting phase with Confirm dialog + isolated auditor + shield |
|
|
218
|
-
|
|
|
220
|
+
| Auditor holds the main turn open | Detached worker returns control immediately; `/goal cancel` discards the pending claim |
|
|
219
221
|
| Auditor can't compact — context exhaustion mid-audit | Compaction enabled (v0.4.0); safe because the shield is orchestrator-side |
|
|
220
222
|
| Agent can grow subtasks indefinitely | `propose_task_list` with 20/5 caps + Confirm dialog (v0.3.0) |
|
|
221
223
|
|
|
222
224
|
## Live TUI (always know it's on)
|
|
223
225
|
|
|
224
226
|
A persistent `glla:` status segment + an above-editor widget show the current
|
|
225
|
-
goal/loop at all times: objective,
|
|
226
|
-
metric, pause reason, and live auditor progress
|
|
227
|
-
running, you can see it — no command needed.
|
|
227
|
+
goal/list item/loop at all times: objective, durable state, elapsed time,
|
|
228
|
+
tokens, next task or loop metric, pause reason, and live auditor progress
|
|
229
|
+
during audits. If something is running, you can see it — no command needed.
|
|
230
|
+
|
|
231
|
+
The status bar is the single activity HUD. It uses compact state capsules plus
|
|
232
|
+
an animated pulse waveform so live work is obvious at a glance without turning
|
|
233
|
+
the line into a progress meter. Fresh stream age is the proof of live work:
|
|
234
|
+
|
|
235
|
+
```text
|
|
236
|
+
glla: [▁▂▄▆█▆ LIVE · WORKING] 1m 09s · last stream 11s ago · 3 queued
|
|
237
|
+
glla: [QUEUED] 44s · 18 queued
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
The waveform is evidence-gated and indeterminate: it moves only while fresh
|
|
241
|
+
stream/tool activity is present, and says nothing about completion percentage.
|
|
242
|
+
Activity is otherwise intentionally honest:
|
|
243
|
+
|
|
244
|
+
| Indicator | Meaning |
|
|
245
|
+
|---|---|
|
|
246
|
+
| `LIVE · WORKING` | Fresh stream/tool evidence is arriving; the pulse and `last stream` age make that visible. |
|
|
247
|
+
| `BUSY` | pi is occupied, but no fresh stream evidence justifies a live pulse. |
|
|
248
|
+
| `QUEUED` | A continuation is waiting to start; no work is fabricated. |
|
|
249
|
+
| `IDLE` | The durable item remains active, but no recent work is observed. |
|
|
250
|
+
| `auditor …` | A detached, extension-less verifier is queued, running, quiet, or waiting for its verdict. |
|
|
251
|
+
| `QUOTA WALL` | The provider rejected the request for a quota/plan window; saved work is waiting for a durable probe. |
|
|
252
|
+
|
|
253
|
+
Quota walls deliberately do **not** get more blind request retries. A bare
|
|
254
|
+
429/rate-limit response is treated as a transient throttle; explicit plan,
|
|
255
|
+
usage, billing, reset, and provider-code language is classified more strongly.
|
|
256
|
+
For example, MiniMax's `Token Plan rate limit reached … (2062)` asks for an
|
|
257
|
+
upgrade or pay-as-you-go billing and is not the same thing as a per-minute
|
|
258
|
+
throttle. Output/context-token stops are handled separately and never become a
|
|
259
|
+
quota wall. pi's request-local retry counter is bounded; glla owns the longer
|
|
260
|
+
recovery window: generic throttles use `15m → 30m → 1h → 2h → 4h → 5h`; a
|
|
261
|
+
plan wall with no reset hint starts at `1h → 2h → 4h → 5h`. Automatic probes
|
|
262
|
+
stop after 24h.
|
|
263
|
+
A provider hint is honored when it is within the five-hour probe budget; a
|
|
264
|
+
week-long hint is shown and held for manual action instead of scheduling a
|
|
265
|
+
hidden week-long timer. With global `autoResume=on`, pending probes survive a
|
|
266
|
+
session reload. After the safety horizon, `/list resume`, `/goal resume`, or
|
|
267
|
+
`/loop resume` explicitly starts a fresh bounded window. For continuous work,
|
|
268
|
+
configure ordered **Main model backups** in `/glla` using a model from a
|
|
269
|
+
different provider or billing/quota pool — another model on the same exhausted
|
|
270
|
+
plan is not a real fallback.
|
|
271
|
+
|
|
272
|
+
Classification is conservative: explicit 429/rate-limit/plan-limit/token-plan
|
|
273
|
+
signals are quota walls; ordinary `503 temporarily unavailable`, `403
|
|
274
|
+
forbidden`, auth failures, and ambiguous provider prose are not relabeled as
|
|
275
|
+
quota. Credit/billing exhaustion gets a manual-action hold. The raw provider
|
|
276
|
+
message remains in the ledger/durable state for diagnosis, while the card
|
|
277
|
+
shows the classified reason and recovery action.
|
|
278
|
+
|
|
279
|
+
The quota-specific card hides raw provider JSON while preserving it in durable
|
|
280
|
+
state and the ledger:
|
|
281
|
+
|
|
282
|
+
```text
|
|
283
|
+
glla: ⟦⏳ QUOTA WALL · next probe in 10m 48s⟧ · 1 queued
|
|
284
|
+
├─ QUOTA WALL · Token Plan usage limit · 1 waiting in list
|
|
285
|
+
├─ waiting — nothing for you to do · next probe in 10m 48s
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Increasing pi's per-request retry count is usually the wrong fix for a
|
|
289
|
+
multi-hour plan cap: it prolongs the 429 noise and delays the durable pause;
|
|
290
|
+
it does not make the provider reset sooner. A provider that says "reset in a
|
|
291
|
+
week" therefore does not cause a week of unattended probes.
|
|
292
|
+
|
|
293
|
+
For long-running `/list` work, the card adds a compact queue trail with the
|
|
294
|
+
immediate next item and its truthful wait age while `/list` remains the
|
|
295
|
+
canonical full queue view:
|
|
296
|
+
|
|
297
|
+
```text
|
|
298
|
+
● Fix the current issue · list item · active · 42m
|
|
299
|
+
├─ ✓ bash tests/display.test.ts (35s) · next: update docs
|
|
300
|
+
├─ ↳ 23 waiting · up next: refresh the release notes · waiting 12m 04s
|
|
301
|
+
└─ 23 queued · /list · /glla
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
The card does not duplicate the animated activity badge. This keeps the
|
|
305
|
+
visual surface calm while still making a long-running list feel alive and
|
|
306
|
+
answering the useful questions: **what is active, is it really moving, and
|
|
307
|
+
what is next?**
|
|
228
308
|
|
|
229
309
|
## Self-watchdog (liveness is built in)
|
|
230
310
|
|
|
@@ -232,7 +312,7 @@ A 15s heartbeat detects the precise stall condition — active goal/loop + idle
|
|
|
232
312
|
session + nothing scheduled + quiet for 60s — and re-fires the continuation
|
|
233
313
|
itself. Three consecutive zero-tool turns pause the goal / stop the loop.
|
|
234
314
|
No external watchdog plugin needed. It also recovers **stranded audits**
|
|
235
|
-
(v0.29.1): a goal stuck in `auditing` with no
|
|
315
|
+
(v0.29.1): a goal stuck in `auditing` with no detached worker alive re-runs
|
|
236
316
|
the stored claim after 90s instead of black-holing. Storm protection: the
|
|
237
317
|
send→pause→notify path rearms once per cycle and loud-stops after a 6-error
|
|
238
318
|
brake streak, so a broken provider can't spin forever. A confirmed queued
|
|
@@ -277,33 +357,39 @@ The queued list is a backlog, not a second live thing — untouched.
|
|
|
277
357
|
|
|
278
358
|
## Config (one global place, rarely opened)
|
|
279
359
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
/
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
/glla stuckmax=10 # consecutive stuck interventions before a loop stops (default 5)
|
|
293
|
-
/glla auditfeedbackchars=800 # cap the executor-visible auditor report (default 0 = full report)
|
|
294
|
-
/glla autoaccept=on # drafts ACTIVATE without the Confirm dialog (v0.29.4: they start immediately — autoResume no longer gates drafts; every draft dialog also offers "always auto-accept" inline)
|
|
295
|
-
/glla project tokenlimit=500 # rare per-project override
|
|
296
|
-
```
|
|
360
|
+
Open `/glla` to edit these settings in the table (the rows show effective values and provenance):
|
|
361
|
+
|
|
362
|
+
- Auditor model and thinking level
|
|
363
|
+
- Auditor fallback model
|
|
364
|
+
- Notify command, token limit, and wedge-alert minutes
|
|
365
|
+
- Auto-resume, auto-accept drafts, decision popup, and carryover policy
|
|
366
|
+
- Ordered main-session backups and recovery cadence
|
|
367
|
+
- Audit cap/report size, aggressive mode, quota retry, and stall brakes
|
|
368
|
+
|
|
369
|
+
The argument namespace is reserved for actions such as `/glla status`, `/glla
|
|
370
|
+
resume`, `/glla stats`, `/glla audits`, `/glla tooloverride`, and `/glla wipe`.
|
|
371
|
+
There is no top-level `/glla key=value` setting syntax.
|
|
297
372
|
|
|
298
373
|
Resolution per key: **project > global > defaults** — EXCEPT `autoResume`,
|
|
299
374
|
which is **global-only** (v0.29.5): per-project opt-ins from old versions
|
|
300
375
|
silently overrode the global hold at launch (the junk-runner incident), so
|
|
301
376
|
the launch-restore gate and the reviewer-enqueue gate read only the global
|
|
302
|
-
file now.
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
377
|
+
file now. Main-session backups are global and ordered: a quota/provider error
|
|
378
|
+
switches to the next authenticated candidate before another supervised turn;
|
|
379
|
+
when every candidate is down, glla cancels the provider-held retry and uses a
|
|
380
|
+
bounded `15m → 30m → 1h → 2h → 4h → 5h` probe ladder. Automatic recovery stops
|
|
381
|
+
at 24h (or earlier when the provider supplies a reset beyond the five-hour
|
|
382
|
+
budget), preserves the saved work, and requires an explicit `/goal resume`,
|
|
383
|
+
`/list resume`, or `/loop resume` to start a fresh window. A quota window
|
|
384
|
+
returning within that horizon therefore resumes saved work without manual
|
|
385
|
+
intervention; no blind 50ms resend loop is introduced. The detached auditor uses an explicit cascade: primary
|
|
386
|
+
`auditorModel` → optional fallback pin → the pi session model. If a selected
|
|
387
|
+
model fails after launch, the worker retries it once and then advances through
|
|
388
|
+
that same cascade; every candidate is still audited in a detached,
|
|
389
|
+
extension-less process. There is no in-process fallback into the parent
|
|
390
|
+
session. If the bounded cascade is exhausted, the exact completion claim is
|
|
391
|
+
stored and the goal pauses for `/goal resume`; infrastructure is never treated
|
|
392
|
+
as a verdict.
|
|
307
393
|
|
|
308
394
|
On disapproval, the executor receives the full auditor report by default
|
|
309
395
|
(`auditFeedbackChars=0`, since v0.24.9 — a truncated report loses exactly the
|
|
@@ -313,9 +399,10 @@ history and is available through `/goal status` regardless.
|
|
|
313
399
|
|
|
314
400
|
`autoaccept=on` skips BOTH the Confirm dialog and the drafting interview
|
|
315
401
|
floor — every `propose_*` draft (goal, list batch, loop, task list)
|
|
316
|
-
activates the moment the agent proposes it,
|
|
317
|
-
|
|
318
|
-
|
|
402
|
+
activates the moment the agent proposes it, and a completed `/list audit`
|
|
403
|
+
fan-out queues its generated finding items without a second confirmation.
|
|
404
|
+
Both paths notify loudly; auto-accept is never silent. The seed carries the
|
|
405
|
+
intent. Since v0.29.4 auto-accepted drafts **start immediately**
|
|
319
406
|
— the draft path is decoupled from `autoResume`, which gates ONLY
|
|
320
407
|
launch-time restore of persisted state ("load it but don't auto-start it").
|
|
321
408
|
For fully unattended rigs you typically want both on; for attended rigs,
|
|
@@ -346,8 +433,8 @@ are workers** (v0.23.8):
|
|
|
346
433
|
## Token guard
|
|
347
434
|
|
|
348
435
|
Every goal tracks real token usage; crossing the budget pauses the goal.
|
|
349
|
-
Off by default (opt-in) — set
|
|
350
|
-
value like 10000000 is a runaway threshold, not a big-goal threshold
|
|
436
|
+
Off by default (opt-in) — set Token limit in the `/glla` settings table. A
|
|
437
|
+
high value like 10000000 is a runaway threshold, not a big-goal threshold
|
|
351
438
|
(real research/feature goals legitimately burn 2-4M). Loop 3 doesn't need
|
|
352
439
|
this cap — it has its own brakes
|
|
353
440
|
(max iterations + plateau).
|
|
@@ -359,12 +446,15 @@ but silent for a long stretch because ONE unbounded command (a test suite
|
|
|
359
446
|
that never exits, a dev server) is holding the whole goal hostage. The
|
|
360
447
|
heartbeat watches the wall clock: busy + no activity for 30 minutes →
|
|
361
448
|
in-session warning + your configured notify push, once per interval while
|
|
362
|
-
it persists. Tune
|
|
449
|
+
it persists. Tune Wedge alert minutes in the `/glla` settings table (0 = off).
|
|
363
450
|
|
|
364
451
|
Every other wait is bounded too: continuation retries are milliseconds,
|
|
365
452
|
stuck backoff caps at 5 minutes then pauses, measure commands get a 10m
|
|
366
|
-
hard timeout, and the auditor aborts after 10m with
|
|
367
|
-
|
|
453
|
+
hard timeout, and the detached auditor aborts after 10m with no activity while no
|
|
454
|
+
read-only tool is running. A long-running verification tool is allowed to
|
|
455
|
+
finish, but the worker has a 30m wall-clock safety cap. Both paths are
|
|
456
|
+
infrastructure errors, never verdicts; interrupted claims remain stored for a
|
|
457
|
+
direct retry after `/goal resume`.
|
|
368
458
|
|
|
369
459
|
## Compatibility (what goes well, what conflicts)
|
|
370
460
|
|
|
@@ -391,10 +481,10 @@ and removed pi-tasks. If you truly need session-wide dependency DAGs beyond
|
|
|
391
481
|
one ordered queue, it exists — but installing both is not the ideal combo.
|
|
392
482
|
|
|
393
483
|
**Two footnotes**: (1) extension-registered providers work in the main session
|
|
394
|
-
but not the auditor's extension-less session — if audits fail auth,
|
|
395
|
-
|
|
484
|
+
but not the auditor's extension-less session — if audits fail auth, choose
|
|
485
|
+
an auditor model in `/glla` settings. (2) `pi-notify-agent` notifies on every
|
|
396
486
|
turn; glla pushes fire only where there is something to DO (pauses, verdicts,
|
|
397
|
-
storms, wedge) and work out of the box — with no
|
|
487
|
+
storms, wedge) and work out of the box — with no notify command configured glla
|
|
398
488
|
auto-detects `notify-send`/`osascript`; `notify=off` silences, `notify='<cmd>'`
|
|
399
489
|
customizes.
|
|
400
490
|
|
|
@@ -404,7 +494,8 @@ customizes.
|
|
|
404
494
|
extensions/
|
|
405
495
|
loops/goal.ts # /goal + /list commands, agent tools, loop driver
|
|
406
496
|
goal-loop-core.ts # types, JSONL state, pure helpers
|
|
407
|
-
goal-loop-auditor.ts #
|
|
497
|
+
goal-loop-auditor.ts # auditor prompt + legacy in-process helper
|
|
498
|
+
goal-loop-auditor-process.ts # detached worker protocol + shield revalidation
|
|
408
499
|
goal-loop-shield.ts # regression_shield (pure, dependency-free)
|
|
409
500
|
goal-loop-display.ts # status line + /goal status rendering
|
|
410
501
|
goal-loop-forever.ts # /loop measure/parse/plateau helpers
|
|
@@ -415,8 +506,9 @@ prompts/
|
|
|
415
506
|
goal-loop-forever.md # /loop driver prompt
|
|
416
507
|
goal-loop-forever-draft.md # /loop drafting prompt
|
|
417
508
|
scripts/
|
|
509
|
+
goal-auditor-worker.mjs # extension-less RPC auditor child process
|
|
418
510
|
smoke.sh # live integration harness (tmux + real models)
|
|
419
|
-
tests/ #
|
|
511
|
+
tests/ # current test count is reported by `bun test`; no live pi required for the suite
|
|
420
512
|
docs/DESIGN.md # architectural decisions
|
|
421
513
|
PLAN.md # milestones, decisions, gates
|
|
422
514
|
```
|
|
@@ -433,6 +525,17 @@ cd pi-goal-list-loop-audit
|
|
|
433
525
|
pi install .
|
|
434
526
|
```
|
|
435
527
|
|
|
528
|
+
## Publishing for other users
|
|
529
|
+
|
|
530
|
+
The npm package is public, but `publishConfig.access=public` does not publish
|
|
531
|
+
it by itself. Maintainers should configure npm Trusted Publishing for
|
|
532
|
+
`.github/workflows/publish.yml`, run `npm run release:check`, push a matching
|
|
533
|
+
`v<version>` tag, and publish a GitHub Release. That workflow then runs the
|
|
534
|
+
full checks and `npm publish --provenance --access public` without a long-lived
|
|
535
|
+
npm token. See [`docs/RELEASING.md`](docs/RELEASING.md); verify the result with
|
|
536
|
+
`npm view pi-goal-list-loop-audit version dist-tags.latest` before telling
|
|
537
|
+
users to upgrade.
|
|
538
|
+
|
|
436
539
|
## License
|
|
437
540
|
|
|
438
541
|
MIT
|
package/docs/DESIGN.md
CHANGED
|
@@ -59,9 +59,10 @@ architectural decisions that changed the SHAPE of the system:
|
|
|
59
59
|
`autoResume` (on → any session start resumes; off → never) is **global-only**
|
|
60
60
|
(v0.29.5) after a stale per-project opt-in silently overrode the global hold.
|
|
61
61
|
- **Drafts and restores are decoupled** (v0.29.4): `autoAcceptDrafts` is the
|
|
62
|
-
pre-consent for in-session drafts — they START immediately
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
pre-consent for in-session drafts — they START immediately — and for the
|
|
63
|
+
generated finding batch at the end of `/list audit`. Direct bulk imports
|
|
64
|
+
remain Confirm-gated. `autoResume` gates only launch-time restore. "The
|
|
65
|
+
session auto-starts in some cases ok; launching pi must not."
|
|
65
66
|
- **User aborts mean STOP** (v0.29.4/0.29.5): an aborted turn is exempt from
|
|
66
67
|
stall accounting, stands the chain down with no auto re-fire, and the
|
|
67
68
|
stand-down gates the heartbeat + post-compaction refires. The 5-abort loud
|
|
@@ -73,7 +74,8 @@ architectural decisions that changed the SHAPE of the system:
|
|
|
73
74
|
Confirm-gated clean slate.
|
|
74
75
|
- **The completion lifecycle owns its pauses** (v0.29.1): storm/stall
|
|
75
76
|
escalation never pauses `auditing` goals; a stranded `auditing` state (no
|
|
76
|
-
live auditor
|
|
77
|
+
live auditor; lifecycle rebinds retry stored claims immediately (the 90s
|
|
78
|
+
heartbeat path is only a fallback); send/pause/notify storms
|
|
77
79
|
rearm once per cycle; the provider-error brake (v0.28.13) keeps cross-cycle
|
|
78
80
|
memory and parks after 6 consecutive errors.
|
|
79
81
|
- **The audit loop is the project reviewer** (v0.29.0): `/loop audit` runs
|
|
@@ -110,6 +112,91 @@ architectural decisions that changed the SHAPE of the system:
|
|
|
110
112
|
deprecated deserialization compatibility fields; they do not select a
|
|
111
113
|
transport.
|
|
112
114
|
|
|
115
|
+
## Addendum v0.34.21 (completion-audit lifecycle observability)
|
|
116
|
+
|
|
117
|
+
- **The durable claim owns recovery state**: `pendingCompletion.phase` is
|
|
118
|
+
`running`, `recovery-pending`, or `quota-waiting`. Missing phase is legacy
|
|
119
|
+
state and is treated as recovery-pending after a fresh lifecycle event.
|
|
120
|
+
The isolated attempt id and wall deadline prevent an old generation from
|
|
121
|
+
finalizing a newer attempt.
|
|
122
|
+
- **Rebind recovery is immediate but consent-aware**: a replacement
|
|
123
|
+
`session_start` converts an old running claim to recovery-pending and
|
|
124
|
+
retries it immediately when the lifecycle handoff or global `autoResume`
|
|
125
|
+
supplies consent. A cold startup with autoResume off paints the pending
|
|
126
|
+
claim and waits for `/goal resume`.
|
|
127
|
+
- **Auditor bounds have two layers**: no-event inactivity aborts after 10m
|
|
128
|
+
only when no read-only tool is active; a live verification tool may finish,
|
|
129
|
+
but the complete isolated run has a 30m wall-clock cap. Both outcomes are
|
|
130
|
+
infrastructure failures, never verdicts, and the stored claim remains
|
|
131
|
+
retryable.
|
|
132
|
+
|
|
133
|
+
## Addendum v0.34.22 (detached completion auditor)
|
|
134
|
+
|
|
135
|
+
- **Completion verification is process-isolated, not nested**: `complete_goal`
|
|
136
|
+
persists the claim and job request, then returns immediately. A detached
|
|
137
|
+
extension-less worker launches `pi --mode rpc` with only `read`, `grep`,
|
|
138
|
+
`find`, `ls`, and `bash`; it never receives the parent `ExtensionContext`,
|
|
139
|
+
never loads glla extensions or project context files, and never writes goal
|
|
140
|
+
state. This removes the previous nested `AgentSession` from the main pi
|
|
141
|
+
process and prevents a provider stall in the auditor from occupying the
|
|
142
|
+
executor's turn.
|
|
143
|
+
- **Durable job protocol**: request, progress, lock, and result files live
|
|
144
|
+
under `.pi-glla/audit-jobs/<attemptId>/`. Requests and results are hashed and
|
|
145
|
+
atomically written. The parent validates attempt/request identity, verdict
|
|
146
|
+
markers, read-tool use, and `regression_shield` before applying any result.
|
|
147
|
+
A result from a stale generation is ignored; fresh lifecycle recovery creates
|
|
148
|
+
a new attempt. Cancellation clears the pending claim and best-effort stops
|
|
149
|
+
the worker.
|
|
150
|
+
- **Truthful asynchronous UI**: `auditor queued`, `auditor running`, and
|
|
151
|
+
`audit recovery pending` are distinct. The main session can continue
|
|
152
|
+
rendering and accepting input while the worker audits; completion/archive or
|
|
153
|
+
disapproval/continuation happens only after durable result consumption.
|
|
154
|
+
- **Bounded worker liveness**: no session event for 10 minutes while no
|
|
155
|
+
read-only tool is active aborts the worker; a 30-minute wall-clock bound
|
|
156
|
+
always wins. Both are infrastructure failures, never verdicts, and the claim
|
|
157
|
+
remains retryable.
|
|
158
|
+
|
|
159
|
+
## Addendum v0.34.24 (dispatch proof and display projection safety)
|
|
160
|
+
|
|
161
|
+
- **Accepted is not started**: every automated follow-up records a versioned,
|
|
162
|
+
generation/owner-bound dispatch in `.pi-glla/continuation-dispatch.json`
|
|
163
|
+
before calling `sendMessage({ triggerTurn: true })`. `before_agent_start`
|
|
164
|
+
with the matching marker is the strongest proof; compatible low-level start
|
|
165
|
+
events are accepted for older pi builds. The sidecar is cleared only after
|
|
166
|
+
proof or an explicit terminal send outcome.
|
|
167
|
+
- **No blind trigger storm**: an accepted dispatch has one bounded start-proof
|
|
168
|
+
timer. If no start event arrives, glla records an unresolved dispatch, keeps
|
|
169
|
+
the goal/list item durable, stands down automatic sends, and tells the user
|
|
170
|
+
how to use a fresh lifecycle or explicit resume. It does not inject terminal
|
|
171
|
+
input, restart pi, or treat a successful API return as a turn.
|
|
172
|
+
- **Generation-safe recovery**: replacement/shutdown clears in-memory pending
|
|
173
|
+
state; a new session records and clears any old sidecar, then the existing
|
|
174
|
+
restore/autoResume consent rules decide whether to retry. Late foreign or
|
|
175
|
+
old-generation events cannot acknowledge a new dispatch.
|
|
176
|
+
- **Display-only sanitization**: terminal/ANSI/OSC, bidi, and zero-width
|
|
177
|
+
controls are removed from status, widget, notification, confirmation, and
|
|
178
|
+
status-tool projections. Persisted objectives, contracts, prompts, ledger
|
|
179
|
+
values, and auditor inputs remain unchanged.
|
|
180
|
+
|
|
181
|
+
## Addendum v0.34.31 (main-session model recovery)
|
|
182
|
+
|
|
183
|
+
- **Ordered global backups**: `mainModelFallbacks` is an explicit ordered list
|
|
184
|
+
of `provider/model` references. A provider/quota error can rotate the MAIN
|
|
185
|
+
session through authenticated candidates; the detached auditor's model
|
|
186
|
+
cascade remains a separate subsystem.
|
|
187
|
+
- **No accepted-send inference**: model rotation occurs only after a provider
|
|
188
|
+
failure is observed (or after a 15-minute, five-minute-silent provider-held
|
|
189
|
+
retry storm). A successful `sendMessage()` return is never treated as a
|
|
190
|
+
started turn.
|
|
191
|
+
- **Durable recovery instead of abandonment**: when all candidates fail,
|
|
192
|
+
`.pi-glla/active.jsonl` stores the primary, active candidate, attempted set,
|
|
193
|
+
retry time, and supervisor kind. Recovery probes back off 15m → 30m →
|
|
194
|
+
hourly forever (configurable base), while a paused goal/held loop remains
|
|
195
|
+
resumable. A fresh startup obeys the existing `autoResume` consent gate.
|
|
196
|
+
- **Successful-turn reset**: a real non-error agent end clears the recovery
|
|
197
|
+
cycle. Manual model selection cancels it; goal/list/loop cancellation clears
|
|
198
|
+
its timer and durable state.
|
|
199
|
+
|
|
113
200
|
## Addendum v0.4.0 (completion)
|
|
114
201
|
|
|
115
202
|
- **Auditor compaction enabled** (flaw #3 — the last open one). Safety:
|
|
@@ -137,10 +224,10 @@ Single loop only — **loop 1**, the single ordered goal.
|
|
|
137
224
|
|
|
138
225
|
The single most important property of this plugin is that the implementing agent cannot bamboozle the verifier. The way to achieve this structurally:
|
|
139
226
|
|
|
140
|
-
1. The auditor runs in a **
|
|
141
|
-
2. The auditor has **no extensions, no skills, no prompts, no themes**.
|
|
227
|
+
1. The auditor runs in a **detached pi RPC process with a fresh agent session**.
|
|
228
|
+
2. The auditor has **no extensions, no skills, no prompts, no themes, and no context files**.
|
|
142
229
|
3. The auditor has only **read-only tools**: `read`, `grep`, `find`, `ls`, `bash` (and `bash` is for re-running user's verifier scripts, not arbitrary).
|
|
143
|
-
4. The auditor **cannot see the implementing conversation**.
|
|
230
|
+
4. The auditor **cannot see the implementing conversation or mutate glla state**.
|
|
144
231
|
|
|
145
232
|
This is borrowed directly from `pi-goal-x/extensions/goal-auditor.ts:148-156`. The pattern is sound; we don't improve on it in v0.1.0, we just **fork the proven source and add regression_shield**.
|
|
146
233
|
|
|
@@ -205,7 +292,9 @@ This is a **clean break** by decision of the user. We do not interop with `pi-go
|
|
|
205
292
|
| `extensions/loops/goal.ts` | Loops 1+2 (single goal + list of goals) | shipped |
|
|
206
293
|
| `extensions/loops/forever.ts` | Loop 3 (metric loop helpers) | shipped |
|
|
207
294
|
| `extensions/goal-loop-core.ts` | Shared state machine, types, JSONL | shipped |
|
|
208
|
-
| `extensions/goal-loop-auditor.ts` |
|
|
295
|
+
| `extensions/goal-loop-auditor.ts` | Auditor prompt + compatibility helper | shipped |
|
|
296
|
+
| `extensions/goal-loop-auditor-process.ts` | Detached worker protocol, IPC, and shield revalidation | shipped |
|
|
297
|
+
| `scripts/goal-auditor-worker.mjs` | Extension-less RPC auditor child | shipped |
|
|
209
298
|
| `extensions/goal-loop-display.ts` | Status line + /goal status rendering | shipped |
|
|
210
299
|
| `prompts/goal-loop-continuation.md` | Templated continuation prompt | ~80 |
|
|
211
300
|
| `prompts/goal-loop-auditor.md` | Templated auditor prompt | ~80 |
|
|
@@ -226,7 +315,7 @@ type Status =
|
|
|
226
315
|
|
|
227
316
|
States owned by the orchestrator:
|
|
228
317
|
- `active` → next iteration
|
|
229
|
-
- `auditing` → auditor running
|
|
318
|
+
- `auditing` → detached auditor queued/running (or recovery pending)
|
|
230
319
|
- `complete` → archived
|
|
231
320
|
- `paused` → user-resumable
|
|
232
321
|
- `aborted` → user-cancelled
|
|
@@ -253,7 +342,7 @@ This protects against model-generated summaries losing fidelity.
|
|
|
253
342
|
|
|
254
343
|
| Trigger | Action |
|
|
255
344
|
|---|---|
|
|
256
|
-
|
|
|
345
|
+
| Detached auditor running | Main turn remains free; `/goal cancel` discards the pending claim and stops the worker best-effort |
|
|
257
346
|
| `Esc` during agent turn | Pause |
|
|
258
347
|
| User `/goal pause` | Pause |
|
|
259
348
|
| User `/goal cancel` | Abort (wipes active goal) |
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Releasing to npm
|
|
2
|
+
|
|
3
|
+
This repository publishes `pi-goal-list-loop-audit` through the GitHub Release
|
|
4
|
+
workflow at `.github/workflows/publish.yml`.
|
|
5
|
+
|
|
6
|
+
## One-time npm setup
|
|
7
|
+
|
|
8
|
+
In npm package settings, add a **Trusted Publisher** for:
|
|
9
|
+
|
|
10
|
+
- GitHub owner/repository: `DraconDev/pi-goal-list-loop-audit`
|
|
11
|
+
- workflow file: `.github/workflows/publish.yml`
|
|
12
|
+
- environment: leave unset unless the repository deliberately protects the job
|
|
13
|
+
with an npm environment
|
|
14
|
+
|
|
15
|
+
The workflow uses npm OIDC provenance. Do not add a long-lived `NPM_TOKEN` to
|
|
16
|
+
the repository.
|
|
17
|
+
|
|
18
|
+
## Release checklist
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm version <major.minor.patch> --no-git-tag-version
|
|
22
|
+
npm run release:check
|
|
23
|
+
# review the diff, then commit package.json + package-lock.json + changelog
|
|
24
|
+
# create and push the matching tag, for example:
|
|
25
|
+
git tag v<major.minor.patch>
|
|
26
|
+
git push origin main v<major.minor.patch>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Create a GitHub Release from that tag. Publishing happens only after the
|
|
30
|
+
release is marked **published**; the workflow checks that the tag equals the
|
|
31
|
+
`package.json` version, runs the complete test/typecheck/package inspection,
|
|
32
|
+
and then runs:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm publish --provenance --access public
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Verify availability from a separate machine or shell:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm view pi-goal-list-loop-audit version dist-tags.latest
|
|
42
|
+
npm install -g pi-goal-list-loop-audit
|
|
43
|
+
# or in pi:
|
|
44
|
+
pi install npm:pi-goal-list-loop-audit
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`publishConfig.access=public` is necessary for the scoped/public policy, but
|
|
48
|
+
it does not publish anything by itself. A commit, tag, or GitHub Release alone
|
|
49
|
+
is not proof that npm has the package; the registry check above is the proof.
|