pi-goals
Instead of a long plan, make a short list of goal in a one page markdown file. This way it's easy for you to review, and a subagent can just if each goal has been achevied.
The goals.md file looks something like this
## <short plan title>
<context: one short paragraph. What the human wants and why.>
### User voice
- │ "<the human's requirement, quoted in full word for word (with spelling fixes)>"
### Goals
1. [ ] goal: <one short jugable imperative outcome>
- subtle failure mode: <a way this could look done but isn't>
- discriminator: <the concrete observation that tells real success from that failure>
- tasks:
1. [ ] <subtask>
- evidence: (empty until sign-off)
### Future work / out of scope
Like pi-milestones and burneikis/pi-plan, it guides rather than guards. The reminder cadence is copied from tintinweb/pi-tasks and the resync-after-compaction from tmonk/pi-goal-x.
Install
pi install npm:@wassname2/pi-goals
Or for development:
git clone https://github.com/wassname/pi-goals && cd pi-goals && npm install
pi -e ./src/index.ts
Use
/goals CSV export for the report view
/goals enters plan mode and starts a conversation; the objective is an optional seed. From there:
- Plan. The agent explores read-only
- Review. The working set is printed in the transcript, then a menu asks Ready, Ready + compact,
open in
$EDITOR, or keep planning. - Work. The agent ticks subtasks, appends to
## Logand## Learnings, fillsevidence:, and callsCompleteGoalwhen a discriminator is satisfied. If it leaves the plan untouched for two turns, the working set is sent back with a short upkeep reminder.
Other commands: /goals clear deletes this session's plan file; /goals judge <model-ref> picks a
specific model for the sign-off judge (default: your current session model, else pi's default).
The plan file format (a convention, not a schema)
# ship the cache layer
Latency target came from the SLO review; keep the existing client API.
## User voice
- > "keep the client API, I don't want to touch every call site"
## Goals
1. [/] goal: Implement cache layer
- subtle failure mode: cache silently bypassed, latency ok by luck
- discriminator: hit-rate > 0.8 in load-test.log (a bypass reads ~0)
- verify: pytest tests/cache -q && python bench/p95.py --max-ms 50
- tasks:
1. [x] wire cache client
2. [/] eviction policy
- evidence:
- > load-test.log: p95=41ms, hit-rate 0.93 (not bypassed)
## Future work / out of scope
## Log
- 2026-06-15 14:02 cache client wired; eviction next
## Learnings
- the client retries on 503, so a cache miss storm looks like latency, not errors
## Appendix (context, not approved)
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,fin
Prompts
All model-facing text lives in src/prompts.ts, in flow order.
Develop
pi -e ./src/index.ts # load locally
npm test # vitest: judge argv invariants, appendLog, decideSignOff fail-forward
npm run typecheck
npm run lint
License
MIT
