Commit Graph
29 Commits
Author SHA1 Message Date
wassnameandClaudypoo 7d5342f332 prompts: varglite evidence discipline -- quote what you observed, judge rejects reconstructed quotes
Dogfood: an agent with blank tool output back-filled plausible test counts into evidence and
the judge accepted (the numbers happened to be true). Norm now stated agent-side (verbatim
quotes, honest gaps beat plausible fabrication) and enforced judge-side (mismatched quotes =>
reject even when the goal looks met).

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-03 12:04:04 +08:00
wassnameandClaudypoo 72ac6cf357 nudge when plan.md exists but no goal line matches, instead of going silently inert
Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-03 12:00:01 +08:00
wassnameandClaudypoo 924910e942 persist judge transcript to .pi/judge/<stamp>.md and reference it from the sign-off log line
'Did the judge really re-run verify?' was unanswerable post-hoc; now every sign-off's full
judge output survives on disk.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-03 11:59:00 +08:00
wassnameandClaudypoo 92d3f6d725 sign-off ticks the goal [x] itself + document that the judge reads the working tree, not HEAD
Dogfood exit interview: agent bookkeeping is the drift point (tick after accept was the
step most likely forgotten), and 'committed artifact' language implied the judge sees HEAD.
Tick is exact-subject match via the existing GOAL_LINE regex; on drift the result explicitly
asks the agent to tick, so neither path is silent.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-03 11:49:31 +08:00
wassnameandClaudypoo 67daed312f docs: evidence should cite committed artifacts; .pi/ is gitignored so it's judge-time proof only
Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-03 11:12:42 +08:00
wassnameandClaudypoo 8586b26ba8 rename stale .pi/goals.md to plan.md on session start so v1 goals aren't silently invisible
Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-03 11:12:36 +08:00
wassnameandClaudypoo 485be236ce log stamps in local time so tool and agent-written lines agree (dogfood finding)
Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-03 11:12:02 +08:00
wassname 632012cc6e judge: extract decideSignOff so inconclusive always means 'ran but failed'
CompleteGoal.execute now delegates to a pure decideSignOff(input, signal,
runJudgeFn) that takes an injected judge runner. judgeModel is never checked
pre-emptively: null just omits --model (buildJudgeArgs), so pi's configured
default runs the judge. The only producers of accepted_inconclusive are now the
judge-error and no-VERDICT paths -- i.e. 'the judge ran but failed', never 'no
model'. Wording (log/result/docstring/README) updated to say 'ran but failed'.

Adds test/decide-signoff.test.ts: null judgeModel still reaches runJudge (no
pre-emptive return); judge error/timeout/no-VERDICT -> accepted_inconclusive
with a 'ran but failed' reason. 11 tests pass, typecheck + lint clean.
2026-07-03 10:55:45 +08:00
wassnameandClaudypoo c0f80b869e v2: delete the parser -- plan.md is for LLMs, the judge subsumes the machinery
The v1 lesson: the parser existed so TypeScript could read goals.md, but every
reader is a model. v2 injects .pi/plan.md verbatim each turn, teaches the format
as a convention, and hands the whole file to the judge, which now does the goal
matching (tolerates wording drift), evidence validation, verify execution, and
format reading that v1 did in code. 1874 -> 530 lines.

Deleted: plan-file.ts + tests, JSON-stream judge transport, custom tool
rendering, review menu + $EDITOR + newSession dance, pruneCompleted, unwired
continuation/loopJudge prompts, MUTATING_BASH_PATTERNS. CompleteGoal's only
write is the ## Log sign-off line (the audit trail); the agent ticks [x] itself.
Judge runs with --no-extensions so a broken global extension can't take down
sign-offs (pi-hermes-memory currently does exactly that). File renamed
goals.md -> plan.md.

UAT (real judge subprocess on a toy repo, /tmp/claude-goals-uat/judge-*.log):
accept with verify run + byte-check, reject on placeholder evidence + missing
file, accept under drifted goal wording.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-03 10:24:35 +08:00
wassnameandClaudypoo 5d88502e4d judge: omit --model when unset so pi default runs (no more inconclusive-by-default)
Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-03 10:16:40 +08:00
wassnameandClaudypoo 0dfd6612ce widget: hide finished goals entirely (no summary line)
Drop the '✔ N done' summary line -- done/cancelled goals now render
nothing in the widget. The done count is already in the status bar
(◷ n/N goals) and full history is in goals.md / the ## Log.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-02 06:44:19 +08:00
wassname acb04dbfa2 Merge branch 'main' of https://github.com/wassname/pi-goals 2026-07-02 06:29:20 +08:00
wassnameandClaudypoo de01894348 widget: show only live goals, crop finished to a one-line summary
Completed goals were listed in file order, so done goals pushed the
active/open work down the widget. Now show active+open in full and
collapse done/cancelled into a single muted '✔ N done  ✗ M cancelled'
line. Full history stays in goals.md and the ## Log.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-02 06:29:16 +08:00
wassnameandClaudypoo 87c6c4d440 goals widget: fold path into header + add 'prune completed goals'
Two space-savers for a display that grows across sessions:
- widget header now carries the clickable .pi/goals.md path (with title),
  dropping the separate muted footer -- one vertical line instead of two.
- /goals clear now offers 'Prune completed goals' (pure pruneCompleted:
  drops done+cancelled goal blocks, keeps active/open, title, and the log)
  alongside the existing full clear. Gives a way to shed old goals without
  losing the audit trail.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-02 06:26:46 +08:00
wassname 14e757cfe1 Make goal judge use explicit session model 2026-06-29 05:28:17 +08:00
wassname 9a4da96d56 Fail forward when goal judge is inconclusive 2026-06-29 05:14:23 +08:00
wassname e0470a0c6d Judge: read-only + bash (no edit/write), renderCall/renderResult, streaming progress
- Judge gets read, bash, grep, find, ls but edit+write are blocked via --exclude-tools
- Added renderCall: shows goal name while running
- Added renderResult: shows accept/reject icon, model, duration, collapsed/expanded view
- Wired onUpdate through decideSignOff -> runJudge so the TUI shows progress while judging
- Added SignOffDetails type for structured metadata
- Added 120s timeout on judge subprocess
2026-06-17 18:21:45 +08:00
wassname 39c83994fa FIXME: judge side-effect clones pollute user workspace
pi -p --no-session clones the repo into the parent of cwd, leaving a stale
directory that the NEXT judge then finds and rejects the goal over. Needs a
temp-dir fix or in-repo inspection.
2026-06-17 18:16:32 +08:00
wassname 489f9b8c35 Clean pi-plan references, add judge timeout, fix heading format
- Rename spec doc to 2026-06-15_pi-goals.md, update title
- Update review.md spec reference
- Rename piPlanExtension -> piGoalsExtension in src/index.ts
- Add 120s timeout to judge subprocess (was unbounded, caused hang)
- Change planInjection heading from 'Goals (goals.md):' to '.pi/goals.md:'
- Add FIXMEs for tool label, progress visibility, heading format
2026-06-17 18:09:03 +08:00
wassnameandClaudypoo 0a1503dc04 pi-goals: move CompleteGoal desc into prompts.ts; trim README
The tool description and param doc are model-facing, so they belong in
prompts.ts with the rest. Add them as step 6 (completeGoalTool) and
renumber the evidence judge to 7; prompts.ts is now ordered the way the
agent meets each text, so it reads as one pass.

The moved desc also carries the positive-success framing: evidence must
show the success happened, not just that a failure was avoided.

README trimmed (saying less, voice unchanged): tighter intro and
comparison, less prose around the examples and sign-off steps. Humanizer
lint clean.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-16 11:50:12 +08:00
wassnameandClaudypoo 838c42d7bd pi-goals: discriminator/failure-mode format + visible sign-off judge
Replace done_when with a discriminator + subtle-failure-mode pair as the
heart of each goal. The discriminator is the POSITIVE success observation
that no failure mode could fake, not just failure-avoidance: a run can
dodge every trap and still produce nothing. Carried through planDrafting,
the sign-off judge, README, and the parser doc.

Format migration: flat numbered markdown goals (`1. [/] goal: ...`),
keyword-anchored parsing (indentation cosmetic), goals matched by text,
subtask states [ ]/[/]/[x]/[-] plus ~~strike~~. Evidence empty at
planning, filled at sign-off, multi-line supported.

CompleteGoal now returns the judge's reasoning under a
`--- sign-off judge ---` block (was just "Signed off"), so the verdict is
visible. Plan mode is read-only: edit/write (except goals.md) and
mutating bash are blocked by a tool hook.

17 parser tests, typecheck + biome clean.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-16 11:45:08 +08:00
wassnameandClaudypoo a65c822bf9 pi-plan -> pi-goals: rename package, command, and file to goals.md
Distinguishes this from the other pi-plan extensions by foregrounding what's
different (goals tracked to verified completion). Mechanical rename only, no
behavior change:
- package @wassname2/pi-plan -> @wassname2/pi-goals (+ repo url)
- plan.md -> goals.md (the canonical file)
- command /plan -> /goals
- file H1 marker "# Plan:" -> "# Goals:", widget/session labels likewise
- internal state keys pi-plan-* -> pi-goals-*

Internal source filename (plan-file.ts) and identifiers (planDrafting, PlanDoc,
setGoalStatus) keep "plan"; they're not user-visible. External burneikis/pi-plan
references are left intact.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-16 05:53:22 +08:00
wassnameandClaudypoo bb00314932 pi-plan: checkbox-in-header goal state + evidence block + widget/judge fixes
Goal state moves from a `status:` line into a checkbox on the goal header
(single source of truth, renders natively): [ ] open, [/] active, [x] done,
[-] cancelled. Only CompleteGoal writes [x]; the agent sets [/] when starting.
The GoalStatus enum and all consumers (widget, injection, counts) are unchanged.

Evidence becomes a goal field, not an ephemeral tool argument: an `evidence:`
block the agent fills before sign-off, read by CompleteGoal from the file
(git-tracked, reviewable). The tool is now CompleteGoal(goal_id) only.

Also:
- format reorder: subtasks under the goal; failure_modes + evidence as
  separated trailing blocks (no abutting dash-lists)
- widget: (done/total tasks), and done goals show checked instead of hiding
- drafting prompt: guard against a circular done_when (one that points at the
  file's own checkbox/log, which the sign-off writes, so it can never pass)
- drafting template now includes the H1 and the <!-- id --> line CompleteGoal
  needs to locate a goal
- strip ANSI/CSI control codes from the judge subprocess output

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-16 05:49:22 +08:00
wassnameandClaudypoo f2f9e6a1b9 pi-plan: finish stale-pi crash fix, print plan on start, todo->task
- The Ready->fresh-context crash was a stale pi.* call inside
  withSession. Prior commit moved sendUserMessage to sessionCtx but
  left pi.setSessionName inside withSession (also stale -> crash).
  Drop it (cosmetic) and use only sessionCtx in the swap window.
- Print plan.md on execution start (both fresh and in-place) so the
  user sees what's being worked on after a context switch. Plan text
  captured before newSession since ctx goes stale.
- Widget: "(N todo)" -> "(N task[s])"

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-15 20:49:57 +08:00
wassnameandClaudypoo 3134adf203 pi-plan: fix crash on Ready->fresh-context; drop em-dashes in prompts
- startExecution: inside withSession, send via the ReplacedSessionContext
  (sessionCtx.sendUserMessage) and set the session name there. The old
  code used the global pi.* handle bound to the replaced session, which
  is stale after newSession (runner.assertActive) -> crash on the
  "fresh, compacted context" choice.
- prompts: replace em-dashes in model-facing strings with commas/
  semicolons/periods (humanizer pass; comments left as-is)

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-15 20:32:30 +08:00
wassnameandClaudypoo 861b2ea157 pi-plan: right-size plans (fewer goals), lean done_when/failure_modes
The drafting prompt over-decomposed: one goal per item, long run-on
done_when (criterion + failure symptom in one line), and 3 mandatory
failure_modes. Plans came out verbose and hard to read.

- planDrafting: default to ONE goal; add another only for a genuinely
  separate checkpoint; near-identical items become subtasks. Subtasks
  only for 3+ step goals. Don't invent phases. (granularity heuristic
  adapted from tintinweb/pi-tasks when-to/when-not guidance)
- done_when: one falsifiable check, no embedded "if wrong" clause (the
  failure symptom belongs in failure_modes)
- failure_modes: 0-2 terse items, optional
- Sync the stale done_when wording in README and plan-file.ts comment

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-15 20:28:02 +08:00
wassnameandClaudypoo 158e04f4ac pi-plan: fix corrupted index.ts, queue revise msg, bare /plan prompts
- Restore exitPlanMode closing brace + CompleteGoal tool registration
  opening that an earlier edit dropped (parse error at 224)
- Edit-revise path now sends with deliverAs:"followUp" so it doesn't
  throw "Agent is already processing" mid-stream
- Bare /plan now prompts for an objective and enters plan mode instead
  of only showing the current plan

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-15 20:23:55 +08:00
wassnameandClaudypoo c74f625b65 Fix newSession context bug + mark unwired loop prompts (external review)
External review (deepseek-v4-pro, docs/reviews/review.md) found:
- Real bug: reviewLoop cast agent_end's ExtensionContext to ExtensionCommandContext
  and called newSession on it, which would crash the "fresh context" path. Now the
  /plan command handler's context (which has newSession) is saved and reused, with a
  graceful in-place fallback (burneikis pattern).
- Dead code: continuation + loopJudge prompts are unused (the autonomous loop is
  intentionally cut). Marked NOT-YET-WIRED in the prompts.ts flow header rather than
  removed, so the full intended flow stays reviewable.
Review also confirmed: no comment bloat, no over-engineering.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-15 18:40:19 +08:00
wassnameandClaudypoo d97b532d7b pi-plan: plan-mode goals + evidence in one plan.md, subagent sign-off
Small, guide-not-gate plan/goal tracker for pi. The agent edits plan.md with
its normal Edit tool; CompleteGoal is the one blessed path that runs verify +
a read-only judge and records the result. Plan mode drafts goals (done_when +
failure_modes + subtasks), a per-turn injection keeps the active goal alive
through compaction, and a reminder drives upkeep + autonomy.

- src/plan-file.ts: pure parse + the two writes CompleteGoal needs + recordSignOff
- src/index.ts: plan mode, review menu, injection, reminder, widget, CompleteGoal, oracle spawn
- src/prompts.ts: all model-facing text in flow order
- test/: 15 unit tests (parser, disambiguation, sign-off record logic)

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-15 18:15:03 +08:00