Update README.md

This commit is contained in:
wassname (Michael J Clark)
2026-08-24 21:28:56 +08:00
committed by GitHub
parent 4850b5195e
commit 9ebcd3f4a6
+6 -64
View File
@@ -1,31 +1,11 @@
# pi-goals
Plan mode for agreeing on goals before any code gets written. Each goal names the subtle failure
mode that could fake a "done" and the discriminator that tells real success from it. Everything
lives in one markdown file, `.pi/plan/<session_id>.md`, which the agent edits with its normal edit
tool and which doubles as the task list. A goal is signed off only after a fresh read-only judge
checks its evidence against the repo.
Plan mode for agreeing on goals in a one page markdown file.
A goal is signed off only after a fresh read-only judge checks its evidence against the repo.
![the widget: live goals from the session's plan file, with the active goal's open subtasks](media/screenshot.png)
One plan file per session, not per repo. Two windows on one checkout, and any subagent (pi spawns
those with `--no-session`, extensions on), each get their own path, so they can't read or overwrite
each other's plan. The file name is also the on switch: a session that never ran `/goals` has no file
at its path, so the widget, the reminders and `CompleteGoal` all stay quiet. The id survives a
`/resume` and a compaction; an explicit fork gets a new id, and so a fresh empty plan.
The file has a fold at `## Log`. Above it is the working set: title, the human's own words, goals,
discriminators. Below it is durable memory: the log, the learnings, and an unlimited unverified
appendix. The working set is re-sent when the plan goes stale for a couple of turns; the whole file
comes back at session start and after a compaction, which is when the settled context is gone.
Design bet (v2): the plan file is for LLMs and the human, not for TypeScript. There is no parser and
no schema. The format is a convention taught by a prompt; the judge, being a model, reads the file
natively, finds the claimed goal itself (wording drift is fine), and validates the evidence in
words. It cannot execute anything, so it never re-runs your `verify` command: you run it and save
the output as evidence. This deleted ~800 lines of v1 (parser, exact-string goal matching, verify
runner, JSON-stream judge transport, review menus) and with them the footguns they caused.
Like [pi-milestones](https://github.com/Neuron-Mr-White/UniPi/tree/main/packages/milestone) and
[burneikis/pi-plan](https://github.com/burneikis/pi-plan), it guides rather than guards. The
reminder cadence is copied from [tintinweb/pi-tasks](https://github.com/tintinweb/pi-tasks) and the
@@ -52,13 +32,9 @@ pi -e ./src/index.ts
`/goals` enters plan mode and starts a conversation; the objective is an optional seed. From there:
1. Plan. The agent explores read-only (edit/write are blocked except on the plan file itself), asks
about anything unclear, and drafts the goals into this session's plan file. The drafting rules
are sent once, with your objective, not re-sent every turn.
1. Plan. The agent explores read-only
2. Review. The working set is printed in the transcript, then a menu asks Ready, Ready + compact,
open in `$EDITOR`, or keep planning. To revise, just reply. Plan mode ends when you pick a Ready.
Ready + compact summarizes the planning conversation away first; the plan file comes back whole
on the next turn, so nothing you agreed is lost.
open in `$EDITOR`, or keep planning.
3. Work. The agent ticks subtasks, appends to `## Log` and `## Learnings`, fills `evidence:`, and
calls `CompleteGoal` when a discriminator is satisfied. If it leaves the plan untouched for two
turns, the working set is sent back with a short upkeep reminder.
@@ -100,45 +76,11 @@ Latency target came from the SLO review; keep the existing client API.
## Appendix (context, not approved)
```
- A goal is a checkbox line beginning `goal:` (`[ ]` open, `[/]` active, `[x]` done, `[-]`
cancelled). Indented checkbox lines under a goal are its subtasks. Those two patterns plus the
`## Log` fold are the only things the extension itself reads; everything else is prose to it.
- The `discriminator` is the success test, written while planning: the positive observation that the
goal succeeded and that none of the `subtle failure mode`s could fake. `evidence` is the proof,
filled at sign-off: each item pairs a durable artifact with a short read of it. Prefer committed
artifacts (files, tests, diffs); `.pi/` is usually gitignored, so evidence there is judge-time
proof only and won't survive in history.
- `## User voice` holds the human's requirements word for word. A paraphrase drifts, and then the
goals churn on the next reply.
- `## Learnings` is what you now know, one line per gotcha, deduped. `## Log` is what happened, one
line a turn. `## Appendix` is unlimited and unverified: alternatives, links, dead ends, and
settled detail that is not part of the approved goals.
- Small format deviations are fine; the file is read by the human and the judge, not a parser.
- The agent prunes finished goals itself when the working set gets long (evidence survives in git
history and `## Log`).
## Signing off a goal (`CompleteGoal`)
`CompleteGoal(goal)` is the one blessed tool. It spawns a strictly read-only `pi` subprocess (`-p
--no-session --no-extensions`, tools `read,grep,find,ls` -- no bash, no edit/write) with the whole
plan file and the claimed goal. The judge cannot execute anything, so it never re-runs your verify
command (which may be a 10-hour training job); the agent runs `verify` itself and saves the output
as evidence. The judge reviews evidence discipline in order -- anything here at all? each item
quoted and attributed? provenance visible (how was this produced)? do the quotes match the cited
files on disk? -- and only then the substance, returning `VERDICT: accept | reject` plus what's
missing. It reads the live working tree, not HEAD: uncommitted work counts, and committing before
sign-off is for durable evidence, not for the judge's visibility.
- accept: a sign-off line is appended to `## Log` and the goal is ticked `[x]` in the same write
(exact goal-line match only; on wording drift the result asks the agent to tick it). The
tool-written log line is the audit trail; a hand-tick without one shows in the diff.
- every run saves the judge's full transcript to `.pi/judge/<stamp>.md`, referenced from the log
line, so "what did the judge actually check?" stays answerable after the fact.
- reject: the goal stays open and the agent gets the missing list.
- judge ran but failed/errored/timed out, or returned no VERDICT line: accepted inconclusive,
logged as such. There is no pre-emptive "no model" path -- a null judgeModel just omits
`--model` so pi's configured default runs the judge, so inconclusive always means "ran but
failed", never "couldn't start". The working agent is never blocked on judge infra.
--no-session --no-extensions`, tools `read,grep,fin
## Prompts