pi-goal-x 0.24.0 → 0.25.1

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.
@@ -0,0 +1,86 @@
1
+ {
2
+ "version": 3,
3
+ "id": "mshg3jex-svqfyt",
4
+ "objective": "Benchmark every non-agent flow of pi-goal-x on current main with the existing agent-free B1–B9 harness (extended to also cover the 0.24.0 unified-dashboard render surface that shipped after the harness was built), then optimize each non-agent flow that has meaningful headroom so it measures at least an order of magnitude (≥10x) faster than a freshly captured BEFORE baseline on current main — with zero regressions on the rest.\n\nSuccess criteria: (1) fresh BEFORE baseline captured on main before any optimization: agent-free run (no live agents, no network, no unauthorized child processes), harness extended so the full current non-agent surface is covered (including unified dashboard task-list / expanded / audit render rows), `npm run bench:gate` passes pre-change, baseline JSON + BENCH-BEFORE.md committed; (2) explicit headroom/exemption list defined in the spec (noise-floor rows = local p50 <0.5ms with ≤1 fs op are exempt from 10x but must not regress; everything else has headroom); (3) AFTER run shows ≥10x p50 improvement vs the fresh BEFORE baseline on its primary cost metric (wall-clock p50, fs ops/turn, or estimated prompt tokens where a flow is prompt-bound) for every headroom row — no exemptions left unexplained; (4) B6 gate extended with a ≥10x invariant for headroom rows and a no-regression rule for exempt rows — gate PASSES; (5) `npm test` 0 failures and `npm run check` (tsc --noEmit) clean; (6) AGENTS.md conventions followed: new spec dir specs/2026-08-06-non-agent-flow-optimization/ with PRODUCT.md (where behavior-relevant), TECH.md (as useful), MILESTONES.md log, and BENCH-BEFORE/AFTER/DIFF.md committed; (7) user signs off on the before/after tables in a real terminal.\n\nBoundaries: in scope = the full non-agent surface on current main as covered by B1–B9 plus the dashboard-render additions, performance-only optimizations that preserve behavior (unit tests pin it), bench-harness extension, and docs. Out of scope = anything requiring live agent sessions or model/network calls (LLM latency cannot be guaranteed 10x), auditor agent-session logic, feature changes, new slash commands, branch/merge mechanics, and the still-blocked 2026-08-04 review-plan goal's signoff (separate concern; its work is already merged to main).\n\nConstraints: benchmarks stay agent-free (B8: no live agents, no network, no unauthorized child processes); fresh BEFORE baselines must be captured before any optimization change; no new runtime dependencies without explicit user approval; the four goal dialogs (questionnaire, accept-goal confirmation, task-list confirmation, escape dialog) and goal tool-call headings stay byte-identical unless a change is flagged to the user first and approved; no new slash commands; optimizations must not change behavior (tests stay green); AGENTS.md spec conventions; descriptive commits via commit_changes.\n\n\nIf blocked: stop and ask the user.",
5
+ "status": "paused",
6
+ "autoContinue": false,
7
+ "usage": {
8
+ "tokensUsed": 318093,
9
+ "activeSeconds": 2189
10
+ },
11
+ "sisyphus": false,
12
+ "createdAt": "2026-08-06T11:41:19.497Z",
13
+ "updatedAt": "2026-08-06T12:54:33.984Z",
14
+ "activePath": ".pi/goals/active_goal_2026080612411949_mshg3jex-svqfyt.md",
15
+ "stopReason": "agent",
16
+ "pauseReason": "All deliverables verified and committed; the goal cannot complete without the user's signoff (criterion 7) and their acceptance of the documented B4 content-floor exemption (recommendation (a)). Presenting for review in the terminal.",
17
+ "pauseSuggestedAction": "Open specs/2026-08-06-non-agent-flow-optimization/BENCH-DIFF.md + HEADROOM.md and sign off: confirm the B4 content-floor exemption (or run /goal-tweak to relax targets / authorize guidance removal instead). Then tell me to complete the goal.",
18
+ "skipAuditor": true,
19
+ "revision": 162,
20
+ "taskList": {
21
+ "tasks": [
22
+ {
23
+ "id": "task-1",
24
+ "title": "Baseline + coverage: extend harness to cover dashboard flows, fresh agent-free BEFORE run on main, gate PASS, commit baseline + BENCH-BEFORE.md + spec scaffolding; define the explicit headroom vs noise-floor exemption list",
25
+ "status": "complete",
26
+ "completedAt": "2026-08-06T11:55:42.332Z",
27
+ "evidence": "Harness extended (B7 section D: 15 dashboard rows; B1/B5 op counts; campaign isolation via campaigns.mjs + run-bench/b6-gate parameterization). Fresh agent-free BEFORE: 87 rows, 0 B8 violations, commi"
28
+ },
29
+ {
30
+ "id": "task-2",
31
+ "title": "Optimize: implement ≥10x improvements for every non-agent flow with headroom (per-flow before→after verified by the harness, each tracked in MILESTONES.md)",
32
+ "status": "complete",
33
+ "completedAt": "2026-08-06T12:12:21.664Z",
34
+ "evidence": "Implemented: zero-op write-through session caches (settings/pool/ledger) invalidated on extension writes + session_start; direct batched ledger appends (per-dir mkdir memo); lock default window 8x25ms"
35
+ },
36
+ {
37
+ "id": "task-3",
38
+ "title": "AFTER run + gate: re-run bench, commit BENCH-AFTER.md + BENCH-DIFF.md + budgets, extend B6 gate with the ≥10x headroom invariant and no-regression rule for exempt rows — gate PASS",
39
+ "status": "complete",
40
+ "completedAt": "2026-08-06T12:21:11.192Z",
41
+ "evidence": "AFTER run regenerated (87 rows, agent-free). BENCH-AFTER.md + BENCH-DIFF.md + HEADROOM.md regenerated and committed (5bc2d3f). b6-gate.mjs is campaign-aware: no-regression rule for ALL rows (p50 + ops"
42
+ },
43
+ {
44
+ "id": "task-4",
45
+ "title": "Validation + signoff: npm test 0 failures, tsc clean, PRODUCT/TECH/MILESTONES + CHANGELOG updated, dialogs byte-identical check, user signoff in real terminal",
46
+ "status": "pending"
47
+ }
48
+ ],
49
+ "blockCompletion": false,
50
+ "proposedAt": "2026-08-06T11:38:58.636Z"
51
+ },
52
+ "currentTaskId": "task-4",
53
+ "verificationContract": "run `npm run bench` (fresh BEFORE committed, then AFTER), `npm run bench:gate` PASS (including the new ≥10x invariant), `npm test` 0 failures, `npm run check` clean, re-read this goal and confirm every success criterion is met, then user signoff in a real terminal."
54
+ }
55
+
56
+ # Goal Prompt
57
+
58
+ Benchmark every non-agent flow of pi-goal-x on current main with the existing agent-free B1–B9 harness (extended to also cover the 0.24.0 unified-dashboard render surface that shipped after the harness was built), then optimize each non-agent flow that has meaningful headroom so it measures at least an order of magnitude (≥10x) faster than a freshly captured BEFORE baseline on current main — with zero regressions on the rest.
59
+
60
+ Success criteria: (1) fresh BEFORE baseline captured on main before any optimization: agent-free run (no live agents, no network, no unauthorized child processes), harness extended so the full current non-agent surface is covered (including unified dashboard task-list / expanded / audit render rows), `npm run bench:gate` passes pre-change, baseline JSON + BENCH-BEFORE.md committed; (2) explicit headroom/exemption list defined in the spec (noise-floor rows = local p50 <0.5ms with ≤1 fs op are exempt from 10x but must not regress; everything else has headroom); (3) AFTER run shows ≥10x p50 improvement vs the fresh BEFORE baseline on its primary cost metric (wall-clock p50, fs ops/turn, or estimated prompt tokens where a flow is prompt-bound) for every headroom row — no exemptions left unexplained; (4) B6 gate extended with a ≥10x invariant for headroom rows and a no-regression rule for exempt rows — gate PASSES; (5) `npm test` 0 failures and `npm run check` (tsc --noEmit) clean; (6) AGENTS.md conventions followed: new spec dir specs/2026-08-06-non-agent-flow-optimization/ with PRODUCT.md (where behavior-relevant), TECH.md (as useful), MILESTONES.md log, and BENCH-BEFORE/AFTER/DIFF.md committed; (7) user signs off on the before/after tables in a real terminal.
61
+
62
+ Boundaries: in scope = the full non-agent surface on current main as covered by B1–B9 plus the dashboard-render additions, performance-only optimizations that preserve behavior (unit tests pin it), bench-harness extension, and docs. Out of scope = anything requiring live agent sessions or model/network calls (LLM latency cannot be guaranteed 10x), auditor agent-session logic, feature changes, new slash commands, branch/merge mechanics, and the still-blocked 2026-08-04 review-plan goal's signoff (separate concern; its work is already merged to main).
63
+
64
+ Constraints: benchmarks stay agent-free (B8: no live agents, no network, no unauthorized child processes); fresh BEFORE baselines must be captured before any optimization change; no new runtime dependencies without explicit user approval; the four goal dialogs (questionnaire, accept-goal confirmation, task-list confirmation, escape dialog) and goal tool-call headings stay byte-identical unless a change is flagged to the user first and approved; no new slash commands; optimizations must not change behavior (tests stay green); AGENTS.md spec conventions; descriptive commits via commit_changes.
65
+
66
+
67
+ If blocked: stop and ask the user.
68
+
69
+ ## Progress
70
+
71
+ - Status: paused (agent)
72
+ - Auto-continue: off
73
+ - Sisyphus mode: no
74
+ - Time spent: 36m29s
75
+ - Tokens used: 318K (318,093) tokens
76
+ - Verification contract: run `npm run bench` (fresh BEFORE committed, then AFTER), `npm run bench:gate` PASS (including the new ≥10x invariant), `npm test` 0 failures, `npm run check` clean, re-read this goal and confirm every success criterion is met, then user signoff in a real terminal.
77
+ ## Tasks
78
+
79
+ <!-- blockCompletion: false -->
80
+ - [x] task-1: Baseline + coverage: extend harness to cover dashboard flows, fresh agent-free BEFORE run on main, gate PASS, commit baseline + BENCH-BEFORE.md + spec scaffolding; define the explicit headroom vs noise-floor exemption list — evidence: Harness extended (B7 section D: 15 dashboard rows; B1/B5 op counts; campaign isolation via campaigns.mjs + run-bench/b6-gate parameterization). Fresh agent-free BEFORE: 87 rows, 0 B8 violations, commi
81
+ - [x] task-2: Optimize: implement ≥10x improvements for every non-agent flow with headroom (per-flow before→after verified by the harness, each tracked in MILESTONES.md) — evidence: Implemented: zero-op write-through session caches (settings/pool/ledger) invalidated on extension writes + session_start; direct batched ledger appends (per-dir mkdir memo); lock default window 8x25ms
82
+ - [x] task-3: AFTER run + gate: re-run bench, commit BENCH-AFTER.md + BENCH-DIFF.md + budgets, extend B6 gate with the ≥10x headroom invariant and no-regression rule for exempt rows — gate PASS — evidence: AFTER run regenerated (87 rows, agent-free). BENCH-AFTER.md + BENCH-DIFF.md + HEADROOM.md regenerated and committed (5bc2d3f). b6-gate.mjs is campaign-aware: no-regression rule for ALL rows (p50 + ops
83
+ - [ ] task-4: Validation + signoff: npm test 0 failures, tsc clean, PRODUCT/TECH/MILESTONES + CHANGELOG updated, dialogs byte-identical check, user signoff in real terminal
84
+
85
+ - Agent pause reason: All deliverables verified and committed; the goal cannot complete without the user's signoff (criterion 7) and their acceptance of the documented B4 content-floor exemption (recommendation (a)). Presenting for review in the terminal.
86
+ - Agent suggests: Open specs/2026-08-06-non-agent-flow-optimization/BENCH-DIFF.md + HEADROOM.md and sign off: confirm the B4 content-floor exemption (or run /goal-tweak to relax targets / authorize guidance removal instead). Then tell me to complete the goal.
@@ -0,0 +1,82 @@
1
+ {
2
+ "version": 3,
3
+ "id": "mshisjml-bl1gar",
4
+ "objective": "On a new branch off main (proposed name: fix/open-issues), fix the four actionable open issues on tmonk/pi-goal-x — #19 (settings menu positive-integer rows: row-driven lower bound so stall timeout can be set), #20 (parseAuditorDecision: verdict marker must be the final line, not anywhere in the report), #21 (auditor prompt: delimiter-safe interpolation of objective/completion summary), #22 (update_goal blocked/paused flows must surface failure instead of reporting success) — with regression tests, a spec dir (specs/2026-08-06-fix-open-issues/ with MILESTONES.md, plus PRODUCT.md/TECH.md as needed per AGENTS.md), a CHANGELOG entry with patch bump (0.25.1), and the full test suite + typecheck green. Also close the four junk issues #15–18 via gh with an explanatory comment (user-confirmed).",
5
+ "status": "paused",
6
+ "autoContinue": false,
7
+ "usage": {
8
+ "tokensUsed": 115927,
9
+ "activeSeconds": 475
10
+ },
11
+ "sisyphus": false,
12
+ "createdAt": "2026-08-06T12:56:45.405Z",
13
+ "updatedAt": "2026-08-06T13:05:26.542Z",
14
+ "activePath": ".pi/goals/active_goal_2026080613564540_mshisjml-bl1gar.md",
15
+ "stopReason": "user",
16
+ "skipAuditor": true,
17
+ "revision": 80,
18
+ "taskList": {
19
+ "tasks": [
20
+ {
21
+ "id": "task-1",
22
+ "title": "Create branch fix/open-issues off main and scaffold specs/2026-08-06-fix-open-issues/ (MILESTONES.md; PRODUCT.md/TECH.md if planning is useful)",
23
+ "status": "complete",
24
+ "completedAt": "2026-08-06T12:58:01.791Z"
25
+ },
26
+ {
27
+ "id": "task-2",
28
+ "title": "Fix #19: settings menu positive-integer rows use a row-driven lower bound (stallTimeoutMinutes accepts 0+, subtaskDepth 1+) + regression test",
29
+ "status": "complete",
30
+ "completedAt": "2026-08-06T12:59:12.353Z"
31
+ },
32
+ {
33
+ "id": "task-3",
34
+ "title": "Fix #20 + #21: parseAuditorDecision matches only the final non-empty line; buildGoalAuditorPrompt interpolates objective/completion summary safely (escaping or non-colliding delimiters) + regression tests",
35
+ "status": "complete",
36
+ "completedAt": "2026-08-06T13:01:27.636Z"
37
+ },
38
+ {
39
+ "id": "task-4",
40
+ "title": "Fix #22: runGoalBlockedFlow and the agent-pause flow return the apply() failure message when the mutation failed instead of claiming success + regression test",
41
+ "status": "complete",
42
+ "completedAt": "2026-08-06T13:03:18.851Z"
43
+ },
44
+ {
45
+ "id": "task-5",
46
+ "title": "Close junk issues #15–18 via gh with a comment noting they are invalid empty-body duplicates of #19–22",
47
+ "status": "complete",
48
+ "completedAt": "2026-08-06T13:03:37.231Z"
49
+ },
50
+ {
51
+ "id": "task-6",
52
+ "title": "Validation & wrap-up: npm run check clean, npm test 0 failures, CHANGELOG entry + patch bump, MILESTONES.md maps each issue fix to evidence, all committed on the branch",
53
+ "status": "pending"
54
+ }
55
+ ],
56
+ "blockCompletion": true,
57
+ "proposedAt": "2026-08-06T12:56:41.516Z"
58
+ },
59
+ "currentTaskId": "task-6"
60
+ }
61
+
62
+ # Goal Prompt
63
+
64
+ On a new branch off main (proposed name: fix/open-issues), fix the four actionable open issues on tmonk/pi-goal-x — #19 (settings menu positive-integer rows: row-driven lower bound so stall timeout can be set), #20 (parseAuditorDecision: verdict marker must be the final line, not anywhere in the report), #21 (auditor prompt: delimiter-safe interpolation of objective/completion summary), #22 (update_goal blocked/paused flows must surface failure instead of reporting success) — with regression tests, a spec dir (specs/2026-08-06-fix-open-issues/ with MILESTONES.md, plus PRODUCT.md/TECH.md as needed per AGENTS.md), a CHANGELOG entry with patch bump (0.25.1), and the full test suite + typecheck green. Also close the four junk issues #15–18 via gh with an explanatory comment (user-confirmed).
65
+
66
+ ## Progress
67
+
68
+ - Status: paused
69
+ - Auto-continue: off
70
+ - Sisyphus mode: no
71
+ - Time spent: 7m55s
72
+ - Tokens used: 116K (115,927) tokens
73
+ ## Tasks
74
+
75
+ <!-- blockCompletion: true -->
76
+ - [x] task-1: Create branch fix/open-issues off main and scaffold specs/2026-08-06-fix-open-issues/ (MILESTONES.md; PRODUCT.md/TECH.md if planning is useful)
77
+ - [x] task-2: Fix #19: settings menu positive-integer rows use a row-driven lower bound (stallTimeoutMinutes accepts 0+, subtaskDepth 1+) + regression test
78
+ - [x] task-3: Fix #20 + #21: parseAuditorDecision matches only the final non-empty line; buildGoalAuditorPrompt interpolates objective/completion summary safely (escaping or non-colliding delimiters) + regression tests
79
+ - [x] task-4: Fix #22: runGoalBlockedFlow and the agent-pause flow return the apply() failure message when the mutation failed instead of claiming success + regression test
80
+ - [x] task-5: Close junk issues #15–18 via gh with a comment noting they are invalid empty-body duplicates of #19–22
81
+ - [ ] task-6: Validation & wrap-up: npm run check clean, npm test 0 failures, CHANGELOG entry + patch bump, MILESTONES.md maps each issue fix to evidence, all committed on the branch
82
+
@@ -0,0 +1,72 @@
1
+ {
2
+ "version": 3,
3
+ "id": "mshjewld-9z3e9p",
4
+ "objective": "Fix the goal-widget Escape handling so that pressing Escape stops the working as well as pausing: on a live (active + autoContinue) goal, Escape still pauses the goal but is no longer consumed — it is passed back to pi so the running tool execution / current turn is aborted too — and on an already-paused goal, Escape is passed back to pi to stop the current turn without changing goal state (restoring the pre-fix behavior). Continue on the existing fix/open-issues branch: first commit the validated pending issue fixes (#19–#22 + tests + CHANGELOG + spec docs) directly, then implement the escape fix with regression tests, spec-doc updates, and a full green validation.",
5
+ "status": "complete",
6
+ "autoContinue": true,
7
+ "usage": {
8
+ "tokensUsed": 49792,
9
+ "activeSeconds": 107
10
+ },
11
+ "sisyphus": false,
12
+ "createdAt": "2026-08-06T13:14:08.641Z",
13
+ "updatedAt": "2026-08-06T13:17:34.176Z",
14
+ "stopReason": "agent",
15
+ "skipAuditor": true,
16
+ "revision": 30,
17
+ "taskList": {
18
+ "tasks": [
19
+ {
20
+ "id": "task-1",
21
+ "title": "Commit the pending validated fix/open-issues work (issues #19–22 fixes, tests, CHANGELOG 0.25.1, spec docs) directly on fix/open-issues",
22
+ "status": "complete",
23
+ "completedAt": "2026-08-06T13:15:43.315Z",
24
+ "evidence": "Direct git commit 9bd218f on fix/open-issues: 12 staged files (4 issue fixes + tests + spec docs + CHANGELOG 0.25.1); working tree clean after commit."
25
+ },
26
+ {
27
+ "id": "task-2",
28
+ "title": "Fix goal-widget.ts Escape handling: live-goal Escape still calls pauseActiveGoal but returns undefined (passes Escape to pi so the running turn stops); confirm paused-goal Escape already passes through; update the handler comments to explain consume-vs-passthrough split",
29
+ "status": "complete",
30
+ "completedAt": "2026-08-06T13:16:04.725Z",
31
+ "evidence": "goal-widget.ts: live-pause branch keeps pauseActiveGoal but returns undefined (Escape passes to pi, aborting the running turn); top comment updated to explain consume-vs-passthrough split; paused-goal"
32
+ },
33
+ {
34
+ "id": "task-3",
35
+ "title": "Regression tests in tests/goal-modal-escape.test.ts: live-goal Escape pauses AND is not consumed; paused-goal Escape returns undefined and leaves the goal paused with no state change; existing escape tests still pass",
36
+ "status": "complete",
37
+ "completedAt": "2026-08-06T13:16:32.821Z",
38
+ "evidence": "tests/goal-modal-escape.test.ts: added 2 regression tests (live-goal Escape pauses + returns undefined/passthrough; paused-goal Escape passes through with no re-pause/state change). npx tsx --test tes"
39
+ },
40
+ {
41
+ "id": "task-4",
42
+ "title": "Docs + validation + commit: fold the escape fix into the 0.25.1 CHANGELOG entry and the branch's PRODUCT/TECH/MILESTONES docs, npm run check clean, npm test 0 failures, commit on fix/open-issues",
43
+ "status": "complete",
44
+ "completedAt": "2026-08-06T13:17:29.781Z",
45
+ "evidence": "CHANGELOG 0.25.1 + PRODUCT/TECH/MILESTONES docs updated; npm run check clean; npm test 664/664 pass (2 new escape tests); committed ddf4a28 on fix/open-issues, tree clean."
46
+ }
47
+ ],
48
+ "blockCompletion": true,
49
+ "proposedAt": "2026-08-06T13:13:49.755Z"
50
+ },
51
+ "archivedPath": ".pi/goals/archived/goal_2026080614173417_mshjewld-9z3e9p.md"
52
+ }
53
+
54
+ # Goal Prompt
55
+
56
+ Fix the goal-widget Escape handling so that pressing Escape stops the working as well as pausing: on a live (active + autoContinue) goal, Escape still pauses the goal but is no longer consumed — it is passed back to pi so the running tool execution / current turn is aborted too — and on an already-paused goal, Escape is passed back to pi to stop the current turn without changing goal state (restoring the pre-fix behavior). Continue on the existing fix/open-issues branch: first commit the validated pending issue fixes (#19–#22 + tests + CHANGELOG + spec docs) directly, then implement the escape fix with regression tests, spec-doc updates, and a full green validation.
57
+
58
+ ## Progress
59
+
60
+ - Status: complete
61
+ - Auto-continue: on
62
+ - Sisyphus mode: no
63
+ - Time spent: 1m47s
64
+ - Tokens used: 50K (49,792) tokens
65
+ ## Tasks
66
+
67
+ <!-- blockCompletion: true -->
68
+ - [x] task-1: Commit the pending validated fix/open-issues work (issues #19–22 fixes, tests, CHANGELOG 0.25.1, spec docs) directly on fix/open-issues — evidence: Direct git commit 9bd218f on fix/open-issues: 12 staged files (4 issue fixes + tests + spec docs + CHANGELOG 0.25.1); working tree clean after commit.
69
+ - [x] task-2: Fix goal-widget.ts Escape handling: live-goal Escape still calls pauseActiveGoal but returns undefined (passes Escape to pi so the running turn stops); confirm paused-goal Escape already passes through; update the handler comments to explain consume-vs-passthrough split — evidence: goal-widget.ts: live-pause branch keeps pauseActiveGoal but returns undefined (Escape passes to pi, aborting the running turn); top comment updated to explain consume-vs-passthrough split; paused-goal
70
+ - [x] task-3: Regression tests in tests/goal-modal-escape.test.ts: live-goal Escape pauses AND is not consumed; paused-goal Escape returns undefined and leaves the goal paused with no state change; existing escape tests still pass — evidence: tests/goal-modal-escape.test.ts: added 2 regression tests (live-goal Escape pauses + returns undefined/passthrough; paused-goal Escape passes through with no re-pause/state change). npx tsx --test tes
71
+ - [x] task-4: Docs + validation + commit: fold the escape fix into the 0.25.1 CHANGELOG entry and the branch's PRODUCT/TECH/MILESTONES docs, npm run check clean, npm test 0 failures, commit on fix/open-issues — evidence: CHANGELOG 0.25.1 + PRODUCT/TECH/MILESTONES docs updated; npm run check clean; npm test 664/664 pass (2 new escape tests); committed ddf4a28 on fix/open-issues, tree clean.
72
+
@@ -38,3 +38,43 @@
38
38
  {"type":"completion_requested","goalId":"mshc1y08-b6pnc1","at":"2026-08-06T10:06:53.639Z"}
39
39
  {"type":"audit_skipped","goalId":"mshc1y08-b6pnc1","reason":"disabled","at":"2026-08-06T10:06:53.640Z"}
40
40
  {"type":"goal_completed","goalId":"mshc1y08-b6pnc1","archivePath":".pi/goals/archived/goal_2026080611065364_mshc1y08-b6pnc1.md","at":"2026-08-06T10:06:53.643Z"}
41
+ {"type":"goal_created","goalId":"mshg3jex-svqfyt","objective":"Benchmark every non-agent flow of pi-goal-x on current main with the existing agent-free B1–B9 harness (extended to also cover the 0.24.0 unified-dashboard render surface that shipped after the harness was built), then optimize each non-agent flow that has meaningful headroom so it measures at least an order of magnitude (≥10x) faster than a freshly captured BEFORE baseline on current main — with zero regressions on the rest.\n\nSuccess criteria: (1) fresh BEFORE baseline captured on main before any optimization: agent-free run (no live agents, no network, no unauthorized child processes), harness extended so the full current non-agent surface is covered (including unified dashboard task-list / expanded / audit render rows), `npm run bench:gate` passes pre-change, baseline JSON + BENCH-BEFORE.md committed; (2) explicit headroom/exemption list defined in the spec (noise-floor rows = local p50 <0.5ms with ≤1 fs op are exempt from 10x but must not regress; everything else has headroom); (3) AFTER run shows ≥10x p50 improvement vs the fresh BEFORE baseline on its primary cost metric (wall-clock p50, fs ops/turn, or estimated prompt tokens where a flow is prompt-bound) for every headroom row — no exemptions left unexplained; (4) B6 gate extended with a ≥10x invariant for headroom rows and a no-regression rule for exempt rows — gate PASSES; (5) `npm test` 0 failures and `npm run check` (tsc --noEmit) clean; (6) AGENTS.md conventions followed: new spec dir specs/2026-08-06-non-agent-flow-optimization/ with PRODUCT.md (where behavior-relevant), TECH.md (as useful), MILESTONES.md log, and BENCH-BEFORE/AFTER/DIFF.md committed; (7) user signs off on the before/after tables in a real terminal.\n\nBoundaries: in scope = the full non-agent surface on current main as covered by B1–B9 plus the dashboard-render additions, performance-only optimizations that preserve behavior (unit tests pin it), bench-harness extension, and docs. Out of scope = anything requiring live agent sessions or model/network calls (LLM latency cannot be guaranteed 10x), auditor agent-session logic, feature changes, new slash commands, branch/merge mechanics, and the still-blocked 2026-08-04 review-plan goal's signoff (separate concern; its work is already merged to main).\n\nConstraints: benchmarks stay agent-free (B8: no live agents, no network, no unauthorized child processes); fresh BEFORE baselines must be captured before any optimization change; no new runtime dependencies without explicit user approval; the four goal dialogs (questionnaire, accept-goal confirmation, task-list confirmation, escape dialog) and goal tool-call headings stay byte-identical unless a change is flagged to the user first and approved; no new slash commands; optimizations must not change behavior (tests stay green); AGENTS.md spec conventions; descriptive commits via commit_changes.\n\n\nIf blocked: stop and ask the user.","sisyphus":false,"autoContinue":true,"at":"2026-08-06T11:41:19.497Z"}
42
+ {"type":"task_list_set","goalId":"mshg3jex-svqfyt","taskCount":4,"blockCompletion":false,"at":"2026-08-06T11:41:19.497Z"}
43
+ {"type":"task_started","goalId":"mshg3jex-svqfyt","taskId":"task-1","at":"2026-08-06T11:41:24.247Z"}
44
+ {"type":"task_complete","goalId":"mshg3jex-svqfyt","taskId":"task-1","evidence":"Harness extended (B7 section D: 15 dashboard rows; B1/B5 op counts; campaign isolation via campaigns.mjs + run-bench/b6-gate parameterization). Fresh agent-free BEFORE: 87 rows, 0 B8 violations, commi","at":"2026-08-06T11:55:42.332Z"}
45
+ {"type":"task_started","goalId":"mshg3jex-svqfyt","taskId":"task-2","at":"2026-08-06T11:55:46.276Z"}
46
+ {"type":"task_complete","goalId":"mshg3jex-svqfyt","taskId":"task-2","evidence":"Implemented: zero-op write-through session caches (settings/pool/ledger) invalidated on extension writes + session_start; direct batched ledger appends (per-dir mkdir memo); lock default window 8x25ms","at":"2026-08-06T12:12:21.664Z"}
47
+ {"type":"task_started","goalId":"mshg3jex-svqfyt","taskId":"task-3","at":"2026-08-06T12:12:25.979Z"}
48
+ {"type":"goal_paused","goalId":"mshg3jex-svqfyt","reason":"Contract decision required: the 6 B4 prompt-token rows (taskListBlock/continuationPrompt/goalPrompt at 10t/50t) cannot reach their 10x token targets without deleting agent-facing guidance (the [OUTCOMES] policy, audit-before-complete and blocker instructions, tools line ≈ 548 tokens of the 1084-token continuation prompt) — that is a behavior change the goal's no-behavior-change constraint forbids. The gate now encodes the full 10x contract and fails on exactly these 6 rows; all other 22 headroom rows meet their targets and zero rows regressed. I need the user to choose how to handle B4 before the goal can complete.","suggestedAction":"Pick one: (a) accept the documented content-floor exemption for B4 (recommended — guidance is the extension's behavioral contract with the agent; the safe formatting compaction stays), (b) /goal-tweak to relax the B4 target to something achievable (e.g. ≥2x on the goal block), or (c) authorize trimming the guidance text (behavior change). Then review the before/after tables in BENCH-DIFF.md and sign off in the terminal.","source":"agent","at":"2026-08-06T12:14:57.475Z"}
49
+ {"type":"goal_resumed","goalId":"mshg3jex-svqfyt","reason":"user","at":"2026-08-06T12:17:12.498Z"}
50
+ {"type":"task_complete","goalId":"mshg3jex-svqfyt","taskId":"task-3","evidence":"AFTER run regenerated (87 rows, agent-free). BENCH-AFTER.md + BENCH-DIFF.md + HEADROOM.md regenerated and committed (5bc2d3f). b6-gate.mjs is campaign-aware: no-regression rule for ALL rows (p50 + ops","at":"2026-08-06T12:21:11.193Z"}
51
+ {"type":"task_started","goalId":"mshg3jex-svqfyt","taskId":"task-4","at":"2026-08-06T12:21:13.775Z"}
52
+ {"type":"goal_paused","goalId":"mshg3jex-svqfyt","reason":"All deliverables verified and committed; the goal cannot complete without the user's signoff (criterion 7) and their acceptance of the documented B4 content-floor exemption (recommendation (a)). Presenting for review in the terminal.","suggestedAction":"Open specs/2026-08-06-non-agent-flow-optimization/BENCH-DIFF.md + HEADROOM.md and sign off: confirm the B4 content-floor exemption (or run /goal-tweak to relax targets / authorize guidance removal instead). Then tell me to complete the goal.","source":"agent","at":"2026-08-06T12:21:22.570Z"}
53
+ {"type":"goal_created","goalId":"mshisjml-bl1gar","objective":"On a new branch off main (proposed name: fix/open-issues), fix the four actionable open issues on tmonk/pi-goal-x — #19 (settings menu positive-integer rows: row-driven lower bound so stall timeout can be set), #20 (parseAuditorDecision: verdict marker must be the final line, not anywhere in the report), #21 (auditor prompt: delimiter-safe interpolation of objective/completion summary), #22 (update_goal blocked/paused flows must surface failure instead of reporting success) — with regression tests, a spec dir (specs/2026-08-06-fix-open-issues/ with MILESTONES.md, plus PRODUCT.md/TECH.md as needed per AGENTS.md), a CHANGELOG entry with patch bump (0.25.1), and the full test suite + typecheck green. Also close the four junk issues #15–18 via gh with an explanatory comment (user-confirmed).","sisyphus":false,"autoContinue":true,"at":"2026-08-06T12:56:45.405Z"}
54
+ {"type":"task_list_set","goalId":"mshisjml-bl1gar","taskCount":6,"blockCompletion":true,"at":"2026-08-06T12:56:45.405Z"}
55
+ {"type":"task_started","goalId":"mshisjml-bl1gar","taskId":"task-1","at":"2026-08-06T12:56:52.283Z"}
56
+ {"type":"task_complete","goalId":"mshisjml-bl1gar","taskId":"task-1","at":"2026-08-06T12:58:01.791Z"}
57
+ {"type":"task_started","goalId":"mshisjml-bl1gar","taskId":"task-2","at":"2026-08-06T12:58:01.792Z"}
58
+ {"type":"task_complete","goalId":"mshisjml-bl1gar","taskId":"task-2","at":"2026-08-06T12:59:12.353Z"}
59
+ {"type":"task_started","goalId":"mshisjml-bl1gar","taskId":"task-3","at":"2026-08-06T12:59:12.355Z"}
60
+ {"type":"task_complete","goalId":"mshisjml-bl1gar","taskId":"task-3","at":"2026-08-06T13:01:27.636Z"}
61
+ {"type":"task_started","goalId":"mshisjml-bl1gar","taskId":"task-4","at":"2026-08-06T13:01:27.637Z"}
62
+ {"type":"task_complete","goalId":"mshisjml-bl1gar","taskId":"task-4","at":"2026-08-06T13:03:18.851Z"}
63
+ {"type":"task_started","goalId":"mshisjml-bl1gar","taskId":"task-5","at":"2026-08-06T13:03:18.852Z"}
64
+ {"type":"task_complete","goalId":"mshisjml-bl1gar","taskId":"task-5","at":"2026-08-06T13:03:37.231Z"}
65
+ {"type":"task_started","goalId":"mshisjml-bl1gar","taskId":"task-6","at":"2026-08-06T13:03:37.232Z"}
66
+ {"type":"goal_paused","goalId":"mshisjml-bl1gar","reason":"user","status":"paused","at":"2026-08-06T13:05:26.541Z"}
67
+ {"type":"goal_created","goalId":"mshjewld-9z3e9p","objective":"Fix the goal-widget Escape handling so that pressing Escape stops the working as well as pausing: on a live (active + autoContinue) goal, Escape still pauses the goal but is no longer consumed — it is passed back to pi so the running tool execution / current turn is aborted too — and on an already-paused goal, Escape is passed back to pi to stop the current turn without changing goal state (restoring the pre-fix behavior). Continue on the existing fix/open-issues branch: first commit the validated pending issue fixes (#19–#22 + tests + CHANGELOG + spec docs) directly, then implement the escape fix with regression tests, spec-doc updates, and a full green validation.","sisyphus":false,"autoContinue":true,"at":"2026-08-06T13:14:08.641Z"}
68
+ {"type":"task_list_set","goalId":"mshjewld-9z3e9p","taskCount":4,"blockCompletion":true,"at":"2026-08-06T13:14:08.641Z"}
69
+ {"type":"task_started","goalId":"mshjewld-9z3e9p","taskId":"task-1","at":"2026-08-06T13:15:33.912Z"}
70
+ {"type":"task_complete","goalId":"mshjewld-9z3e9p","taskId":"task-1","evidence":"Direct git commit 9bd218f on fix/open-issues: 12 staged files (4 issue fixes + tests + spec docs + CHANGELOG 0.25.1); working tree clean after commit.","at":"2026-08-06T13:15:43.315Z"}
71
+ {"type":"task_started","goalId":"mshjewld-9z3e9p","taskId":"task-2","at":"2026-08-06T13:15:43.317Z"}
72
+ {"type":"task_complete","goalId":"mshjewld-9z3e9p","taskId":"task-2","evidence":"goal-widget.ts: live-pause branch keeps pauseActiveGoal but returns undefined (Escape passes to pi, aborting the running turn); top comment updated to explain consume-vs-passthrough split; paused-goal","at":"2026-08-06T13:16:04.725Z"}
73
+ {"type":"task_started","goalId":"mshjewld-9z3e9p","taskId":"task-3","at":"2026-08-06T13:16:04.726Z"}
74
+ {"type":"task_complete","goalId":"mshjewld-9z3e9p","taskId":"task-3","evidence":"tests/goal-modal-escape.test.ts: added 2 regression tests (live-goal Escape pauses + returns undefined/passthrough; paused-goal Escape passes through with no re-pause/state change). npx tsx --test tes","at":"2026-08-06T13:16:32.821Z"}
75
+ {"type":"task_started","goalId":"mshjewld-9z3e9p","taskId":"task-4","at":"2026-08-06T13:16:32.823Z"}
76
+ {"type":"task_complete","goalId":"mshjewld-9z3e9p","taskId":"task-4","evidence":"CHANGELOG 0.25.1 + PRODUCT/TECH/MILESTONES docs updated; npm run check clean; npm test 664/664 pass (2 new escape tests); committed ddf4a28 on fix/open-issues, tree clean.","at":"2026-08-06T13:17:29.781Z"}
77
+ {"type":"completion_requested","goalId":"mshjewld-9z3e9p","at":"2026-08-06T13:17:34.171Z"}
78
+ {"type":"audit_skipped","goalId":"mshjewld-9z3e9p","reason":"disabled","at":"2026-08-06T13:17:34.172Z"}
79
+ {"type":"goal_completed","goalId":"mshjewld-9z3e9p","archivePath":".pi/goals/archived/goal_2026080614173417_mshjewld-9z3e9p.md","at":"2026-08-06T13:17:34.177Z"}
80
+ {"type":"goal_archived","goalId":"mshjewld-9z3e9p","archivePath":".pi/goals/archived/goal_2026080614173417_mshjewld-9z3e9p.md","at":"2026-08-06T13:17:34.178Z"}
@@ -60,9 +60,12 @@ function asThinkingLevel(value: unknown): ThinkingLevel | undefined {
60
60
 
61
61
 
62
62
  export function parseAuditorDecision(output: string): { approved: boolean; disapproved: boolean } {
63
- const approved = /<approved\s*\/>/.test(output);
64
- const disapproved = /<disapproved\s*\/>/.test(output);
65
- return { approved: approved && !disapproved, disapproved };
63
+ // The prompt contract: the verdict marker must be the FINAL line of the
64
+ // report. Matching anywhere lets a prose mention of the marker (e.g. "I
65
+ // would only emit <approved/> if ...") be misread as the verdict.
66
+ const lines = output.split("\n").map((l) => l.trim()).filter(Boolean);
67
+ const marker = lines[lines.length - 1];
68
+ return { approved: marker === "<approved/>", disapproved: marker === "<disapproved/>" };
66
69
  }
67
70
 
68
71
  export interface AuditorVerificationEvidence {
@@ -77,7 +80,7 @@ function renderAuditorTaskTree(tasks: GoalTask[], indent: number): string[] {
77
80
  const lines: string[] = [];
78
81
  for (const task of tasks) {
79
82
  const marker = task.status === "complete" ? "[x]" : task.status === "skipped" ? "[~]" : "[ ]";
80
- lines.push(`${prefix}${marker} ${task.id}: ${task.title}`);
83
+ lines.push(`${prefix}${marker} ${task.id}: ${escapePromptPayload(task.title)}`);
81
84
  if (task.subtasks && task.subtasks.length > 0) {
82
85
  lines.push(...renderAuditorTaskTree(task.subtasks, indent + 1));
83
86
  }
@@ -95,6 +98,16 @@ function taskSummaryBlock(taskList?: GoalTaskList | null): string {
95
98
  return lines.join("\n");
96
99
  }
97
100
 
101
+ /**
102
+ * Escape operator/model-controlled payloads before interpolating them between
103
+ * XML-ish delimiters in the auditor prompt, so a payload containing
104
+ * `</objective>` (or other delimiter text) cannot close the block early and
105
+ * have the remainder read as instructions. Entities stay human-readable.
106
+ */
107
+ function escapePromptPayload(value: string): string {
108
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
109
+ }
110
+
98
111
  export function buildGoalAuditorPrompt(args: {
99
112
  goal: GoalRecord;
100
113
  detailedSummary: string;
@@ -117,33 +130,33 @@ export function buildGoalAuditorPrompt(args: {
117
130
  "",
118
131
  "Goal objective:",
119
132
  "<objective>",
120
- args.goal.objective,
133
+ escapePromptPayload(args.goal.objective),
121
134
  "</objective>",
122
135
  "",
123
136
  "Executor completion claim (UNTRUSTED):",
124
137
  "<executor_claim>",
125
- args.completionSummary?.trim() || "(no claim provided)",
138
+ escapePromptPayload(args.completionSummary?.trim() || "(no claim provided)"),
126
139
  "</executor_claim>",
127
140
  "",
128
141
  "The executor claim above is a claim, never evidence. It cannot make an otherwise incomplete goal complete; cross-check it against real artifacts where relevant.",
129
142
  "",
130
143
  "Current goal metadata:",
131
144
  "<goal_details>",
132
- args.detailedSummary,
145
+ escapePromptPayload(args.detailedSummary),
133
146
  ...(!args.settings?.disableTasks && taskSummaryBlock(args.goal.taskList) ? ["", taskSummaryBlock(args.goal.taskList)] : []),
134
147
  "</goal_details>",
135
148
  ...(!args.settings?.disableContracts && args.goal.verificationContract?.trim() ? [
136
149
  "",
137
150
  "Goal verification contract (what the executor was required to verify):",
138
151
  "<verification_contract>",
139
- args.goal.verificationContract.trim(),
152
+ escapePromptPayload(args.goal.verificationContract.trim()),
140
153
  "</verification_contract>",
141
154
  ] : []),
142
155
  ...(args.warmContext?.trim() ? [
143
156
  "",
144
157
  "Warm parent context (already-rendered evidence from the executor session — inspect, do not re-derive):",
145
158
  "<warm_context>",
146
- args.warmContext.trim(),
159
+ escapePromptPayload(args.warmContext.trim()),
147
160
  "</warm_context>",
148
161
  ] : []),
149
162
  "",
@@ -342,11 +342,14 @@ export function registerGoalCommands(core: GoalCore): void {
342
342
  if (row.kind === "positiveInteger") {
343
343
  const input = await ctx.ui.input(`Set ${row.label}`, settingsValue(config, key));
344
344
  if (input === undefined) continue;
345
+ // Row-driven lower bound: subtaskDepth is a nesting depth (min 1);
346
+ // stallTimeoutMinutes defaults to 0 meaning "no stall timeout".
347
+ const min = row.key === "stallTimeoutMinutes" ? 0 : 1;
345
348
  // Full-string decimal validation: no partial parseInt. Rejects
346
- // 1.5, 1x, 0, negatives, infinity, and unsafe integers alike.
349
+ // 1.5, 1x, negatives, infinity, and unsafe integers alike.
347
350
  const trimmed = input.trim();
348
- if (!/^[0-9]+$/.test(trimmed) || !Number.isSafeInteger(Number(trimmed)) || Number(trimmed) < 1) {
349
- ctx.ui.notify(`${row.label} must be a positive integer (e.g. 1, 2, 3)`, "warning");
351
+ if (!/^[0-9]+$/.test(trimmed) || !Number.isSafeInteger(Number(trimmed)) || Number(trimmed) < min) {
352
+ ctx.ui.notify(`${row.label} must be an integer >= ${min} (e.g. ${min}, ${min + 1}, ${min + 2})`, "warning");
350
353
  continue;
351
354
  }
352
355
  const next = { ...config, [key]: Number(trimmed) };
@@ -205,14 +205,22 @@ async function runGoalBlockedFlow(ctx: ExtensionContext): Promise<AgentToolResul
205
205
  core.clearActiveAccounting();
206
206
  if (result.goal) core.runtime.markTurnStopped(result.goal.id);
207
207
  core.updateUI(ctx);
208
+ return {
209
+ content: [{
210
+ type: "text",
211
+ text: "Goal blocked. Continuation stopped; the goal is waiting for the user to resume, revise, or clear it. Stop now; do not start another tool call.",
212
+ }],
213
+ details: goalDetails(core.state.goal),
214
+ terminate: true,
215
+ };
208
216
  }
217
+ // The mutation failed (lock contention, revision conflict, goal archived by
218
+ // another process): surface the conflict instead of claiming the goal is
219
+ // blocked, and keep the turn alive so the agent can retry.
209
220
  return {
210
- content: [{
211
- type: "text",
212
- text: "Goal blocked. Continuation stopped; the goal is waiting for the user to resume, revise, or clear it. Stop now; do not start another tool call.",
213
- }],
221
+ content: [{ type: "text", text: `Goal blocked state update failed: ${result.message ?? "the state mutation was rejected"}. The goal was NOT marked blocked. Retry after resolving the conflict.` }],
214
222
  details: goalDetails(core.state.goal),
215
- terminate: true,
223
+ terminate: false,
216
224
  };
217
225
  }
218
226
 
@@ -262,12 +270,19 @@ async function runGoalAgentPauseFlow(ctx: ExtensionContext, reason: string | und
262
270
  core.clearActiveAccounting();
263
271
  if (result.goal) core.runtime.markTurnStopped(result.goal.id);
264
272
  core.updateUI(ctx);
273
+ const suggestion = trimmedAction ? ` Suggested next step: ${trimmedAction}` : "";
274
+ return {
275
+ content: [{ type: "text", text: `Goal paused by the agent: ${trimmedReason}.${suggestion} Stop now; the user can resume with /goal-resume or revise with /goal-tweak.` }],
276
+ details: goalDetails(core.state.goal, `Pause reason: ${trimmedReason}${trimmedAction ? `\nSuggested action: ${trimmedAction}` : ""}`), // E7
277
+ terminate: true,
278
+ };
265
279
  }
266
- const suggestion = trimmedAction ? ` Suggested next step: ${trimmedAction}` : "";
280
+ // The mutation failed: surface the conflict instead of claiming the goal is
281
+ // paused, and keep the turn alive so the agent can retry.
267
282
  return {
268
- content: [{ type: "text", text: `Goal paused by the agent: ${trimmedReason}.${suggestion} Stop now; the user can resume with /goal-resume or revise with /goal-tweak.` }],
269
- details: goalDetails(core.state.goal, `Pause reason: ${trimmedReason}${trimmedAction ? `\nSuggested action: ${trimmedAction}` : ""}`), // E7
270
- terminate: true,
283
+ content: [{ type: "text", text: `Goal pause update failed: ${result.message ?? "the state mutation was rejected"}. The goal was NOT paused. Retry after resolving the conflict.` }],
284
+ details: goalDetails(core.state.goal),
285
+ terminate: false,
271
286
  };
272
287
  }
273
288
 
@@ -12,14 +12,14 @@ import {
12
12
  isToolUseAssistantMessage,
13
13
  } from "./goal-format.ts";
14
14
  import { buildCompactionSummary } from "./goal-compaction.ts";
15
- import { latestAuditorResultForGoal, readGoalLedger } from "./goal-ledger.ts";
15
+ import { latestAuditorResultForGoal, readGoalLedger, invalidateGoalLedgerCache } from "./goal-ledger.ts";
16
16
  import { shouldArmPostCompactReminder, shouldInjectPostCompactReminder } from "./goal-policy.ts";
17
17
  import { formatTokenValue } from "./goal-core.ts";
18
- import { loadGoalSettings } from "./goal-settings.ts";
18
+ import { loadGoalSettings, invalidateGoalSettingsCache } from "./goal-settings.ts";
19
19
  import { budgetLine, budgetRemaining } from "./goal-accounting.ts";
20
20
  import { asRecord, nowIso, type AssistantMessageLike } from "./goal-record.ts";
21
21
  import { goalSelectorLabel } from "./goal-pool.ts";
22
- import {
22
+ import { invalidateGoalPoolCache } from "./storage/goal-files.ts";import {
23
23
  goalPrompt,
24
24
  staleContinuationPrompt,
25
25
  unfocusedOpenGoalsPrompt,
@@ -229,6 +229,12 @@ export function registerGoalEvents(core: GoalCore): void {
229
229
  });
230
230
 
231
231
  pi.on("session_start", async (event, ctx) => {
232
+ // NAF: the zero-op read caches are session-scoped — a new session always
233
+ // re-reads settings/pool/ledger fresh from disk (cross-process and
234
+ // hand-edited changes are picked up at the session boundary).
235
+ invalidateGoalSettingsCache();
236
+ invalidateGoalPoolCache();
237
+ invalidateGoalLedgerCache();
232
238
  core.goalService.flushTurn(ctx); // P1-3: persist any buffered transaction before reload
233
239
  await core.loadState(ctx);
234
240
  core.installGoalToolProfile(!loadGoalSettings(ctx.cwd).disableTasks);