# Comet Design Handoff - Change: goal-driven-loop - Phase: design - Mode: compact - Context hash: 5c51d4f35f110e68c474f79b7d0839423c1efcb5136485917d2c70fff7e515f7 Generated-by: comet-handoff.sh OpenSpec remains the canonical capability spec. This handoff is a deterministic, source-traceable context pack, not an agent-authored summary. ## openspec/changes/goal-driven-loop/proposal.md - Source: openspec/changes/goal-driven-loop/proposal.md - Lines: 1-28 - SHA256: 4a0c87e85ab5b7b5aeeeccd429430a0e06e9fc158a4e8b65ec9e460ada48d908 ```md ## Why Long-running coding sessions drift. The user states a goal, the agent works on it, gets sidetracked, and loses sight of the original target. When context compaction occurs, the goal may be forgotten entirely. Pure skill-only designs force user interaction at every checkpoint, which breaks the "set and forget" intent. ## What Changes - Add a Pi skill `goal-driven-loop` that detects goal-setting phrases (Chinese, English, other languages), persists goal + acceptance criteria to `.agents/goal/GOAL.md`, and runs an instruction-based loop iterating until all criteria pass or genuine stagnation is detected - Add a Pi extension `goal-driven-loop` that automates trigger detection, state injection on every agent turn (resists context compaction), context tension detection via `ctx.getContextUsage()`, timed auto-default confirms (eliminates user-interaction hang-ups), and automatic delegation to comet for coarse-grained goals - Auto-generate verifiable acceptance criteria when not provided by the user - Per-iteration exponential backoff retry (10 retries, ~37min coverage) for transient failures - Dual-signal stagnation detection with auto-recovery injection before user notification - Deslop pass and clean exit on completion ## Capabilities ### New Capabilities - `goal-driven-loop`: Goal persistence and iteration loop with acceptance criteria verification, trigger/anti-trigger detection, state injection, and automatic retry/recovery ### Modified Capabilities ## Impact - New files: `.pi/skills/goal-driven-loop/` (skill instructions + error-handling reference), `.pi/extensions/goal-driven-loop/` (4 TypeScript modules + package.json) - Runtime: Extension subscribes to `input` and `before_agent_start` events - State: `.agents/goal/GOAL.md` created per-project during active goals, deleted on completion - Dependencies: Pi Extension API (`@earendil-works/pi-coding-agent`), node:fs, node:path - Integration: Delegates to `comet-open` for coarse-grained goals; no changes to comet itself ``` ## openspec/changes/goal-driven-loop/design.md - Source: openspec/changes/goal-driven-loop/design.md - Lines: 1-48 - SHA256: 8bb842618779ee28eabdc781950c15c8ddeb477598022c9e0619e40f9370e035 ```md ## Context Pi coding agent has no built-in mechanism for persisting a user-defined goal across a session. Skills can provide instructions, but cannot subscribe to events or inject state automatically. Extensions can, but have no declarative goal-tracking format. This change combines both layers. ## Goals / Non-Goals **Goals:** - Detect goal-setting phrases in user messages across languages - Persist goal state to a file that survives context compaction - Automatically inject goal context on every agent turn - Eliminate unnecessary user interaction (timed auto-defaults, auto-retry, auto-recovery) - Delegate coarse-grained goals to comet automatically - Verify completion against explicit acceptance criteria before declaring done **Non-Goals:** - Multi-goal concurrent tracking (only one active goal at a time) - Cross-session goal tracking beyond file persistence - Subagent orchestration (agent uses existing Pi tools) - Comet skill modifications ## Decisions 1. **Two-layer architecture (skill + extension)**: Skill provides instructions the agent reads; extension provides mechanical automation. This separates judgment (criteria quality, iteration work) from mechanics (trigger detection, state injection, timed confirms). 2. **File-based state (`.agents/goal/GOAL.md`)**: Markdown with YAML frontmatter. Survives context compaction. Human-readable and editable. Deleted on completion. 3. **Extension-driven state injection via `before_agent_start`**: Every agent turn re-injects goal context from the file. This is the primary mechanism for context-compaction resistance — even if conversation is compacted, the extension rebuilds goal context. 4. **Timed auto-default confirms (10s timeout)**: Stale state resolution, criteria confirmation, and other checkpoints use `ctx.ui.select({ timeout: 10000 })` with safe defaults. User can intervene but doesn't have to. 5. **Per-iteration exponential backoff (10 retries, ~37min)**: Tool failures and LLM API errors retry automatically. Counter resets per-iteration. After 10 retries, status becomes `blocked` and extension injects strategy-change prompt. 6. **Dual-signal stagnation detection**: Criteria passing count unchanged for 3 iterations AND no progress keywords in Progress Log. Both required. Extension auto-injects recovery prompt twice before notifying user. 7. **Granularity split with comet delegation**: Coarse-grained goals (file count > 5, multi-module, architectural) automatically invoke `comet-open`. Fallback to multi-stage mode if comet unavailable. 8. **Anti-trigger rules are mechanical**: Quote blocks, code blocks, reported speech, trivial-task keywords, and short descriptions without architectural keywords — all checked programmatically in the extension, not subjectively by the agent. ## Risks / Trade-offs | Risk | Mitigation | |------|------------| | Agent rationalizes skipping criteria | Red flags list in error-handling reference; criteria modification requires logged reason | | Sleep timeout in Pi bash tool | `timeout = delay + 30` parameter | | Extension bugs block the loop | Extension failures degrade gracefully — skill instructions still work without extension | | User loses ability to intervene | Explicit abandon and material criteria change still user-controllable | | Context tension detection imprecise | `ctx.getContextUsage() > 0.8` threshold with auto-save directive | | Mid-loop granularity upgrade needs skill-side signal | Skill can set `status: needs-upgrade` in GOAL.md; extension reads it on next turn | ``` ## openspec/changes/goal-driven-loop/tasks.md - Source: openspec/changes/goal-driven-loop/tasks.md - Lines: 1-19 - SHA256: c19183865d2d41dccde557a933fc8d3043a6f875d3d8a8419926111897b7f687 ```md ## Tasks - [x] Create skill directory structure (`.pi/skills/goal-driven-loop/`) - [x] Write `SKILL.md` (≤500 words, Agent Skills standard compliant) - [x] Write `references/error-handling.md` (retry strategy, exception classification, stagnation rules, red flags) - [x] Create extension directory (`.pi/extensions/goal-driven-loop/`) - [x] Write `trigger-detector.ts` (trigger phrase matching + anti-trigger logic) - [x] Write `state-injector.ts` (GOAL.md parsing + injection text generation) - [x] Write `ui-prompts.ts` (timed auto-default confirms + notification helpers) - [x] Write `index.ts` (event wiring: input, before_agent_start) - [x] Add `package.json` for extension discovery - [x] Fix code block anti-trigger (strip code blocks before pattern matching) - [x] Fix quote block anti-trigger (only block if trigger exclusively in quotes) - [x] Fix blocker parsing (strip markdown list prefix) - [x] Add stagnation auto-recovery injection in extension - [x] Add comet fallback when openspec unavailable - [x] Replace `any` types with `ExtensionContext` - [x] Unit tests: 27/27 trigger-detector, 17/17 state-injector - [x] E2E tests: trigger, anti-trigger, abandon, stale state, state injection ```