---
name: soly-framework
description: Use when the user invokes soly workflow commands (`/plan`, `/execute`, `/discuss`, `/inspect`, `/pause`, `/resume`, `/quick`, `/soly init`, `/soly-status`, `/soly-log`) or asks how to use soly in pi-coding-agent — phases, plans, tasks, intent docs, ROADMAP/STATE state machine, rules, close-out order, and the available soly_* tools. Loaded as the complete reference for managing a soly project end-to-end (init → plan → execute → summary → state update).
priority: high
---

# soly framework

The **soly** extension adds project-management workflow to [pi-coding-agent](https://github.com/nicobailon/pi-coding-agent): intent docs, ROADMAP/STATE/PHASE state machine, and LLM-driven plan execution. This skill is your complete reference for using it.

## Quick start (read first if new)

**Mental model — three layers, always in system prompt, in this order:**

1. **Project intent** (`.agents/docs/`) — the 0-point. What the user wants the app to be. Written BEFORE plans, by humans.
2. **Project state** (`.agents/STATE.md`, `ROADMAP.md`) — where we are, current phase, recent decisions.
3. **Project rules** (`.agents/rules/`, `~/.agents/rules/`) — how to behave in this project.

**Workflow model — phases and tasks (unified):**

- A **phase** is a milestone (e.g. "01-foundation"). It groups **tasks** under `phases/<NN>-<slug>/tasks/`.
- A **task** is the unit of execution: its own dir with `PLAN.md` (frontmatter: `id`, `kind`, `status`, `depends-on`, optional `feature`) and, when done, `SUMMARY.md`. Tasks run in dependency order.
- `soly plan <N>` writes a phase's tasks · `soly execute <N>` runs its ready tasks (deps met) in order · `soly verify` reviews.
- **Close-out** (per task): production commits → task `SUMMARY.md` → flip `status: done` → `STATE.md` / ROADMAP check.
- Legacy projects (standalone `NN-MM-PLAN.md` files, or a `features/` dir) still load and run alongside the unified `phases/<N>/tasks/` layout.

## Commands

Workflow verbs are **plain text** — type `soly <verb>` (NOT a slash command):

| Verb | What it does |
|---|---|
| `soly discuss <N>` | Discussion-driven scoping for phase N — interactive, uses the `ask_pro` picker |
| `soly plan <N>` | Generate `PLAN.md` for phase N (also `<task-id>`, `--new-task`, `--feature`) |
| `soly execute <N[.MM]>` | Execute a phase / one plan / a task / `--all` / `--feature` |
| `soly verify [N] [fresh]` | Self-review loop until "No issues found." (max N; `verify stop` to exit; `fresh` = fresh-context) |
| `soly pause` · `soly compact` | Save a handoff (compact also compresses the session) |
| `soly resume [N]` | Restore from a handoff |
| `soly status` · `log` · `diff` · `doctor` · `iterations` · `todos` | Quick read-outs (no LLM round-trip) |

**Slash commands** (pi's command surface):

| Command | What it does |
|---|---|
| `/rules` · `/docs` | Open the rules / intent-docs **modal** (fuzzy list + preview; `e/d/r` enable·disable·reload on rules). A subcommand (`/rules stats`, `/docs stats`, …) prints to chat instead of opening the modal. |
| `/soly [<sub>]` | Project-state inspection (position, state, plan, roadmap, phases, tasks, …); bare `/soly` opens the picker. `/soly init` scaffolds a new project (template: minimal/web-app/library/cli) |
| `/why` | What rules + state grounded the last turn |
| `/rulewizard` | Rule vs .editorconfig vs linter guide |

## How work runs (inline — no subagent plugin)

soly runs everything **inline, in the main session**. `soly plan` and
`soly execute` transform your request into a detailed instruction (the relevant
workflow markdown, the iteration context bundle, the close-out discipline) and
the model does the work itself — production commits → `SUMMARY.md` → `STATE.md`
→ then `soly verify`. There is **no dependency on the external pi-subagents
plugin** (removed in 2.0.0); nothing breaks when that plugin changes.

**Two ways to drive the workflow — both hit the same code:**

1. **Let the model propose and run it (preferred).** soly injects a "suggested
   next step" into the system prompt every turn. Just say what you want in
   plain language ("let's plan this", "go", "start executing", "wrap it up")
   and the model calls the `soly_workflow` tool for you — you never have to
   memorize a verb.
2. **Type the verb yourself.** `soly plan <slug>`, `soly execute <slug>`, etc.
   still work as plain-text input (a fallback for power users).

`soly discuss` is always interactive in the main session. `soly verify` is a
stateful self-review loop you start by typing `soly verify` (it's not a
`soly_workflow` action).

## File structure

```
<project-root>/
├── AGENTS.md                      # vendor-neutral agent context (loaded by pi)
├── agents.md                      # same as AGENTS.md, lowercase accepted
├── .agents/                       # the one home: soly state + vendor-neutral agent config
│   ├── soly.json                  # soly config (per-project; ~/.agents/soly.json = global)
│   ├── ROADMAP.md                 # phase table
│   ├── STATE.md                   # current position + decisions log
│   ├── docs/                      # 0-point intent docs (human-written, locked)
│   │   ├── vision.md
│   │   └── architecture.md
│   ├── rules/                     # project rules (version-controlled)
│   │   ├── code-style.md
│   │   └── testing.md
│   ├── phases/
│   │   ├── 01-foundation/
│   │   │   ├── 01-CONTEXT.md       # domain + decisions for phase 1
│   │   │   ├── 01-RESEARCH.md      # what we looked up
│   │   │   └── tasks/              # unified model: one dir per task
│   │   │       ├── auth-login-a3f9/
│   │   │       │   ├── PLAN.md     # frontmatter: id, kind, status, depends-on
│   │   │       │   └── SUMMARY.md
│   │   │       └── auth-token-b1c2/
│   │   │           └── PLAN.md
│   │   └── 02-feature-x/
│   │       └── ...
│   ├── skills/                    # project-scoped skills (pi auto-discovers)
│   │   └── my-skill/SKILL.md
│   ├── agents/                    # project-specific agent definitions
│   ├── iterations/                # per-execution context bundles (auto)
│   ├── HANDOFF.json               # pause snapshot
│   └── .continue-here.md          # pause resume marker
```

**One home:** everything lives under `.agents/` — soly's workflow artifacts (PLAN.md, SUMMARY.md, phases, STATE), project rules/docs, and the vendor-neutral config (skills, agents) other AI tools also read. Global rules/config live under `~/.agents/`. `AGENTS.md` at the project root carries top-level agent conventions.

## Frontmatter conventions

### PLAN.md frontmatter (required)

```markdown
---
id: 01-02                    # phase-plan, zero-padded
title: Add OAuth flow
status: pending              # pending | in_progress | done
phase: 1
depends-on: []               # other plan ids
parallelizable: true         # can run alongside siblings
---

# Add OAuth flow

## read_first
- .agents/STATE.md
- .agents/ROADMAP.md
- .agents/rules/code-style.md

## tasks
- [ ] **type: implement**, description: Add token refresh logic
  - files: src/auth/refresh.ts
  - verify: bun test src/auth/refresh.test.ts
  - accept: Refresh succeeds when token is expired; fails when refresh_token is also expired

- [ ] **type: tdd**, description: Write integration test for the auth flow
  - verify: bun test src/auth/

- [ ] **type: checkpoint**, description: Pause for human review of UX

## verification
- bun test
- bun run typecheck
- bun run lint

## risks
- Token storage depends on the encryption scheme (see .agents/docs/architecture.md)
```

### SUMMARY.md frontmatter

```markdown
---
plan: 01-02
completed: 2026-06-15
duration: 47min
files-touched: 7
---

# Summary

## Tasks
- [x] Add token refresh logic
- [x] Write integration test
- [x] Pause for human review

## Deviations
- Refactored `auth/refresh.ts` to use singleton pattern (was factory). Documented in `architecture.md`.

## Verification
- `bun test`: 142 passing
- `bun run typecheck`: clean
- `bun run lint`: 0 warnings

## Next
- Phase 02 plan 01: User profile page
```

### Rules file frontmatter (optional)

```markdown
---
applyTo: "src/**/*.ts"        # glob (optional, default: all)
priority: 50                   # higher wins on conflict (default: 0)
---

# TypeScript style

- Strict mode required
- Never use `any` — use `unknown` and narrow
```

## Path discipline (NON-NEGOTIABLE)

**All soly-managed files live under `.agents/`.** Source code lives in the project's normal source tree.

| File kind | Goes to |
|---|---|
| `PLAN.md`, `SUMMARY.md`, `CONTEXT.md`, `RESEARCH.md` | `.agents/phases/<NN>-<slug>/` |
| Intent docs (0-point) | `.agents/docs/` |
| Rules | `.agents/rules/` (project) or `~/.agents/rules/` (user) |
| Handoff | `.agents/HANDOFF.json`, `.agents/.continue-here.md` |
| Iteration context | `.agents/iterations/` (auto-generated) |
| Production code, tests | project's normal `src/`, `tests/`, `app/`, etc. |

Use absolute paths (or paths starting with `$SOLY_DIR`) when calling tools. Never bare relative names that could land in cwd.

## Close-out order

The only legal sequence for finishing a plan:

1. Production code commits (1+)
2. `SUMMARY.md` committed
3. `STATE.md` "Current Position" block updated
4. `ROADMAP.md` phase checkbox updated
5. `PLAN.md` frontmatter `status: done`

Once production commits exist, returning without a committed `SUMMARY.md` is an **illegal partial-plan state** — the next `/execute` will detect it and refuse to start.

## Tools the LLM can call

| Tool | Purpose |
|---|---|
| `soly_workflow(action, target?)` | Drive the lifecycle inline: `new` / `discuss` / `plan` / `execute` / `done`. Call it on the user's natural-language intent instead of making them type `soly <verb>`. Returns the workflow instruction to follow in this session |
| `soly_read(artifact, phase, taskId)` | Read soly artifacts: STATE, plan, context, research, ROADMAP, requirements, project, milestone, task |
| `soly_log_decision(decision, rationale, phase)` | Append to STATE.md Decisions table |
| `soly_list_phases()` | List all phases with plan counts, C/R markers |
| `soly_list_tasks()` | List all tasks across features (kind, status, priority, deps) |
| `soly_todos(paths, limit)` | Scan working tree for TODO/FIXME/HACK/XXX/NOTE |
| `soly_env()` | Detect runtime (package manager, runtimes, services, scripts) |
| `soly_snippet(path, offset, limit)` | Read bounded line range with line numbers |
| `soly_doc_search(query, limit)` | Search .md/.html under cwd (prioritizes intent docs) |
| `soly_scratchpad(limit)` | Recent conversation recap (one line per turn) |
| `ask_pro(questions)` | Multi-question picker (tabbed, single/multi-select, ⭐, `preview` w/ code highlight, `allowOther`, `freeText`, `minSelect`/`maxSelect`, `s` to skip, notes) — preferred for structured input |
| `decision_deck(options)` | Full-screen TUI deck — one card per option with a highlighted code snippet + pros/cons. For design/architecture forks where the choice hinges on the concrete code shape |
| `html_artifact(title, html, id?, assets?)` | Render HTML (full doc or body fragment) and serve it from a per-session browser gallery SPA (sidebar + iframe + filter + live updates, one stable URL) — soly's "artifacts". `id` updates in place; `assets` writes sibling files. For visual output: example galleries, comparisons, diagrams |
| `soly_save_discuss_checkpoint(...)` · `soly_finish_discuss(...)` | Save / finalize a `soly discuss` session (writes CONTEXT.md) |
| `soly_ask_user(...)` | Single-question picker — **deprecated**, prefer `ask_pro` |

### Visual & interaction tools — when to reach for each

The main system prompt only points at these; the detail is here.

**`ask_pro`** — multi-question picker. Use for 1–6 related questions where the user picks concrete answers to move forward (e.g. `soly discuss` scoping). NOT for simple yes/no, a single open-ended prompt, questions already answered, or trivial clarifications — use plain text. Per option, `preview` shows a side panel while focused (put a code/API/config snippet there; fenced ```code is highlighted). `freeText` = optional typed answer; `allowOther` = escape hatch; `minSelect`/`maxSelect` bound multi-select. The user can skip (`s`, returned `(skipped)`) or note (`n`, returned `// note:` — treat as a hard constraint).

**`decision_deck`** — full-screen cards (one per option) with a highlighted code snippet + pros/cons. Reach for it when the choice hinges on the concrete code/structure of each option, not a label, and there are 2–6 alternatives worth comparing side-by-side. Prefer `ask_pro` for short-label choices; don't use it for trivial/yes-no.

**`html_artifact`** — render HTML served from a per-session browser gallery SPA (sidebar + iframe + filter + live SSE updates, one stable localhost URL). Use when a visual rendered result beats terminal text: example galleries, before/after or side-by-side comparisons, tables, diagrams, a small HTML/CSS/SVG demo. Pass `title` + `html` (a body fragment is fine — it's wrapped in a themed skeleton; put code in `<pre><code>`). Pass `id` to re-render/update an artifact in place (instead of piling up copies); pass `assets: [{path, content, encoding?}]` to write sibling files the HTML references by relative path (e.g. an image or `data.json`). The theme is overridable per project via `.agents/artifact-theme.css`. Keep it self-contained unless you use `assets` — no external/CDN requests. Don't use it for a single snippet (markdown code block) or prose. Mention the returned URL to the user.

## Common workflows

### Start a new project

1. `soly init` (or manually create `.agents/`, `docs/`, `rules/`)
2. Write 1-3 intent docs in `.agents/docs/`
3. Optionally write `AGENTS.md` (or `agents.md`) at project root with project conventions
4. Create `ROADMAP.md` with phase table
5. `/plan 1` to start the first phase

### Add project-specific agents

Drop a markdown file in `.agents/agents/<name>.md` (project) or `~/.agents/agents/<name>.md` (user):

```markdown
---
name: data-scientist
description: Reads CSVs, runs pandas, plots results
thinking: medium
tools: read, bash
---

You are a data scientist. ...
```

**Discovered from 4 locations** (priority order):
1. `<project>/.agents/` — project vendor-neutral (preferred)
2. `<project>/.pi/agent/agents/` — project pi native (legacy)
3. `~/.agents/` — user vendor-neutral (preferred)
4. `~/.pi/agent/agents/` — user pi native (legacy)

### Add a feature to an existing phase

1. `/plan 1.05` (next plan number)
2. Edit the generated `PLAN.md`
3. `/execute 1.05`

### Pause a long session

1. `/pause` → writes `HANDOFF.json` + `.continue-here.md`
2. Later, in a new session: `/resume`

### Troubleshoot a partial plan

If `/execute` complains about illegal partial state:

1. `cat .agents/iterations/<latest>.md` — see what the last run did
2. Check if `SUMMARY.md` exists for the last plan
3. If yes, finish close-out: update `STATE.md` + `ROADMAP.md`
4. If no, either commit the SUMMARY or revert the production commits

## When in doubt

Call `soly_read(artifact: "state")` and `soly_read(artifact: "roadmap")` first. The system prompt has the layers, but `soly_read` gives you full content. Then check `soly_doc_search` for any other relevant docs.

## Don'ts

- ❌ Edit `.agents/rules/` files you didn't write — those are project invariants
- ❌ Skip the SUMMARY — illegal partial state
- ❌ Reach for a `subagent(...)` tool — soly runs inline, in this session. There is no soly subagent and no dependency on pi-subagents (removed in 2.0.0). Use `soly_workflow` (or the plain `soly <verb>` text) instead.
- ❌ Edit `.agents/phases/*/PLAN.md` after `status: in_progress` — create a new plan
- ❌ Put intent docs anywhere other than `.agents/docs/`
