@tsuuanmi/pi-workflows
v0.1.3
Published
Workflow runtime skills for Pi: deep-interview, ralplan, team, and ultragoal
Downloads
432
Readme
@tsuuanmi/pi-workflows
Workflow runtime skills for Pi: deep-interview, ralplan, team, and ultragoal. This package provides the pi workflow control plane, the four bundled Skills, reusable role agent profiles, and the harness runtime that backs them.
The four skills form a gated pipeline:
deep-interview (clarity gate) → ralplan (feasibility gate) → explicit approval (consent gate) → team / ultragoal (execution)Each stage can be skipped, but skipping reduces quality assurance. Workflows are planning/execution agents, not a replacement for the user's judgment — no skill mutates product code or invokes execution until the user explicitly approves.
Table of Contents
- Installation
- Package Scope
- Built-in Skills
- Skill Pipeline and Gating
pi workflowControl Plane- Reusable Agent Profiles
- Model-Visible Tools
- Harness Runtime
- Public API
- Development
- Further Reading
- License
Installation
This package is bundled with Pi and normally consumed transitively via @tsuuanmi/pi-coding-agent. To depend on it directly:
npm install @tsuuanmi/pi-workflowsPackage Scope
@tsuuanmi/pi-workflows ships the workflow runtime: the pi workflow CLI, the harness control plane (sessions, leases, RPC, GC), the four workflow skills and their model-visible tools, and the reusable role agent profiles. Application-level wiring (session persistence, compaction, system-prompt assembly) lives in @tsuuanmi/pi-coding-agent, which depends on this package.
State root: PI_HARNESS_STATE_ROOT or <workspace>/.pi/state/harness. Runtime artifacts persist under the current session root, e.g. .pi/<session-id>/workflows/<skill>/ and .pi/<session-id>/state/.
Built-in Skills
| Skill | Purpose | When to use |
|-------|---------|-------------|
| deep-interview | Socratic requirements interview with ambiguity scoring before planning or execution. | Vague, complex, or high-risk requests where assumptions must be exposed before work starts. |
| ralplan | Consensus planning that turns a task or deep-interview spec into a pending-approval implementation plan using planner, architect, and critic passes. | Turning a spec or task into an explicit, reviewed, approvable plan. |
| team | Coordinate parallel implementation workers after an approved plan exists. | When parallel workstreams are useful and execution has been explicitly approved. |
| ultragoal | Goal-tracked autonomous execution for an approved, concrete plan. | Implementation after explicit approval, with verification and concise progress tracking. |
Invoke a skill with /skill:<name> (e.g. /skill:ralplan). Each skill has a SKILL.md under src/skills/<name>/.
deep-interview
/skill:deep-interview [--quick|--standard|--deep] <idea>| Mode | Description |
|------|-------------|
| --quick | Fewer rounds, broader questions |
| --standard | Default depth |
| --deep | More rounds, deeper probing |
Deep Interview turns a vague idea into a concrete spec before any mutation starts. It asks "what are you assuming?" instead of "what do you want?", scores clarity across weighted dimensions every round, and refuses to finalize until ambiguity drops below a pinned threshold (0.05 / 5%) and an independent closure guard plus a one-sentence goal restatement both pass.
Phases:
- Threshold marker (blocking prerequisite): the first line emitted is exactly
Deep Interview threshold: 5% (source: default). - Initialize: classify greenfield vs brownfield (using
read/bashor a read-onlyplanner/architectsubagent), normalize oversized initial context, init state. - Round 0 — Topology enumeration gate: lock 1–6 top-level components before depth-first questioning can overfit to the most-described component. Multi-component fixtures must surface every sibling (e.g. Ingestion, Normalization, Review UI, Export) even when one is detailed.
- Interview loop: ask ONE question per round, targeting the weakest component/dimension pair, rotating across active components. Score ambiguity after each answer.
- Lateral review panel: convene
researcher,contrarian,simplifier(andarchitectwhen scope shape changed) as parallel read-only subagents at ambiguity-milestone transitions and before synthesizing agent-supplied answers. - Crystallize spec: run
deep_interview_closure_check, thendeep_interview_restate_goal(two-loop cap on Adjust/Missing), then persist viadeep_interview_write_specto.pi/<session-id>/specs/deep-interview-<slug>.md. - Execution bridge: present options (ralplan / ultragoal / team / refine / stop) and hand off only after explicit selection.
Ambiguity is bidirectional and non-monotonic. A later answer can raise ambiguity (contradiction, internal inconsistency, low-quality/evasive, or scope expansion). Triggers lower the affected dimension score; the weighted formula raises ambiguity — there is no separate penalty term. Raises are silent and surface via the per-round report and next-question targeting.
Weights:
- Greenfield:
ambiguity = 1 - (goal × 0.40 + constraints × 0.30 + criteria × 0.30) - Brownfield:
ambiguity = 1 - (goal × 0.35 + constraints × 0.25 + criteria × 0.25 + context × 0.15)
Score every active component independently; the overall dimension score is the minimum (or coverage-weighted weakest) across active components. Deferred components are excluded from the math but remain listed.
Tools: pi_workflow_state, deep_interview_plan_question, deep_interview_record_answer, deep_interview_record_scoring, deep_interview_read_compact, deep_interview_closure_check, deep_interview_restate_goal, deep_interview_write_spec, plus subagent_spawn/subagent_await for read-only research, auto-research, auto-answer, and lateral-panel personas.
Boundaries: planning only — edit/write are runtime-blocked while a deep-interview workflow is active in a non-finished phase (only .pi/** is always blocked; only system-temp scratch outside the project is writable). Ask one question at a time. Do not proceed to execution until ambiguity ≤ threshold, closure passes, the restate is confirmed, and the user explicitly approves an execution path.
ralplan
/skill:ralplan [--interactive] [--deliberate] <task or spec path>| Flag | Description |
|------|-------------|
| --interactive | Require user approval at each stage |
| --deliberate | Enable deeper deliberation passes |
Ralplan produces a durable pending-approval plan through three role agents run as separate ralplan_run_agent invocations (not simulated inline):
- Planner (
stage: "planner") — problem statement, principles, ≥2 viable options (or rationale for one), recommended approach, risks, verification plan, open questions. - Architect (
stage: "architect") — strongest architectural objection, integration/ownership concerns, tradeoff tensions, synthesis. - Critic (
stage: "critic") — acceptance criteria quality, risk mitigation, testability, missing edge cases, verdict:APPROVE/ITERATE/REJECT. - Revision (
stage: "revision") — if the critic requests iteration, the Planner revises with consolidated feedback; Architect/Critic re-review. Cap at five iterations. - Final (
stage: "final") — persist the pending-approval plan;pending-approval.mdis also written. - Stop and ask for explicit execution approval.
After explicit approval or rejection, call ralplan_approve_plan. Default approved handoff is target: "ultragoal"; use target: "team" when coordinated parallel workers are needed, or target: "stop" to record approval without starting another workflow.
Critic-verdict enforcement: ralplan_approve_plan refuses to approve when the latest critic verdict is REJECT (set overrideCriticVerdict: true to force), and warns when it is ITERATE. ralplan_doctor surfaces the same signal as a warning while a plan is pending.
Pre-execution vagueness gate: when team or ultragoal is dispatched with a vague prompt (no concrete signals and ≤ 15 words), the workflow tools redirect to ralplan instead of starting execution. Concrete signals include file paths, issue references (#123), snake_case/CamelCase symbols, numbered steps, acceptance/criteria/must/should language, error/exception/traceback, and fenced code blocks. The gate checks specificity, not file existence. Prefix the prompt with force: or ! to bypass.
Tools: pi_workflow_state, ralplan_status, ralplan_read_compact, ralplan_doctor, ralplan_run_agent, ralplan_write_artifact, ralplan_record_explorer_gate, ralplan_approve_plan.
Boundaries: planning only. Persist artifacts with ralplan_write_artifact; do not directly edit .pi/<session-id>/plans or .pi/<session-id>/workflows unless recovering with explicit user approval. Planner/Architect/Critic passes must use ralplan_run_agent and be sequential: planner first, architect second, critic third. Role agents persist durable output and return receipt-only summaries (run id, stage, stage_n, path).
team
/skill:team <approved plan or task>Team coordinates multiple implementation workstreams as subagent sessions. Use it only after the user explicitly approves execution.
- Read the approved plan or task.
- Start runtime coordination with
team_start; inspect withteam_snapshot/team_read_compact. - Split work into independent workstreams with clear ownership, files, and verification.
- Persist each workstream with
team_create_task. - Use
team_transition_taskfor starts, blocking, failure, and completion. Completed tasks require completion evidence. - Use
team_send_messagefor cross-workstream coordination. - Merge results, resolve conflicts, run requested checks.
- Close the run with
team_complete.
Task states: pending → active → completed (or blocked / failed).
Gates: completed tasks require a reviewer review_report (team_record_review_gate) and completion requires a prover evidence_matrix (team_record_completion_gate). Both are fail-closed validated; blocking artifacts escalate to human_blocked on the second blocking attempt (bounded retry).
Tools: pi_workflow_state, team_start, team_snapshot, team_read_compact, team_create_task, team_transition_task, team_send_message, team_record_review_gate, team_record_completion_gate, team_spawn_task_agent, team_complete.
Boundaries: if the request is vague or lacks acceptance criteria, route to /skill:ralplan first. If a single autonomous worker is enough, prefer /skill:ultragoal. Keep workers scoped to non-overlapping files/components when possible.
ultragoal
/skill:ultragoal <approved plan or concrete task>Ultragoal executes an approved concrete goal end-to-end with verification.
- Restate the approved goal and acceptance criteria.
- Create or resume runtime goal state with
ultragoal_status,ultragoal_read_compact, andultragoal_create_planwhen no plan exists. - Start the next runnable goal with
ultragoal_start_next. - Inspect files, make the smallest complete set of changes, run required checks.
- Checkpoint each goal with
ultragoal_checkpoint. Complete checkpoints require substantive evidence and the full quality gate:architectReview,executorQa, anditeration. OldexecutorQa + contractCoveragetop-level gates and free-form{status}gates are rejected (fail closed). - Use
ultragoal_record_review_blockerswhen review/verification finds blockers that must become durable follow-up work; useultragoal_classify_blockeronly when afailed/blockedcheckpoint is truly human-blocked. - Use
ultragoal_guardbefore treating a stored completion receipt as complete — it reports stale/missing/dirty receipts and fail-closed unreadable state.
Goal states: pending → active → completed (or failed / blocked / review_blocked).
Tools: pi_workflow_state, ultragoal_create_plan, ultragoal_status, ultragoal_read_compact, ultragoal_start_next, ultragoal_checkpoint, ultragoal_record_review_blockers, ultragoal_classify_blocker, ultragoal_guard, ultragoal_spawn_goal_agent.
Boundaries: if the request is vague, run /skill:deep-interview or /skill:ralplan first. If no execution approval exists, stop and ask. Do not widen scope beyond the approved goal. If the plan proves wrong, stop and ask or route back to /skill:ralplan rather than improvising a larger scope.
Skill Pipeline and Gating
| Gate | Skill | What it enforces | |------|-------|------------------| | Clarity | deep-interview | Ambiguity ≤ 5%, closure guard, restated goal confirmed before a spec is written | | Feasibility | ralplan | Planner/Architect/Critic consensus; critic REJECT blocks approval | | Consent | (separate) | User explicitly approves before any execution skill runs | | Execution | team / ultragoal | Approved plan only; vagueness gate redirects underspecified prompts to ralplan |
deep-interview persists its spec to .pi/<session-id>/specs/deep-interview-<slug>.md; ralplan persists plans under .pi/<session-id>/plans/ralplan/<run-id>/. Both stop for explicit approval rather than mutating product code.
pi workflow Control Plane
pi workflow is the CLI front end for the harness control plane. Every verb accepts --json for machine-readable output and --input '<JSON object>' for structured arguments.
pi workflow state <skill> read --json
pi workflow start --input '{"workspace":".","sessionId":"optional","detach":true}' --json
pi workflow submit --input '{"sessionId":"h-...","prompt":"work"}' --json
pi workflow observe --input '{"sessionId":"h-..."}' --json
pi workflow classify --input '{"sessionId":"h-..."}' --json
pi workflow recover --input '{"sessionId":"h-..."}' --json
pi workflow validate --input '{"sessionId":"h-...","checks":[{"name":"check","command":"npm run check"}]}' --json
pi workflow finalize --input '{"sessionId":"h-..."}' --json
pi workflow operate --input '{"sessionId":"h-...","goal":"...","maxIterations":10}' --json
pi workflow gc [--prune] [--dry-run] --json
pi workflow events --input '{"sessionId":"h-..."}' --json
pi workflow retire --input '{"sessionId":"h-..."}' --jsonMost verbs route to a live runtime owner when one is running for the session (start --detach spawns a detached owner); otherwise they fall back to a primitive (no-owner) path so the CLI can inspect and drive sessions without a running owner.
pi workflow gc
A liveness-only garbage-collection sweep for harness owner sessions. It reaps only confirmed-dead owner sessions: a session is removable iff its lease classifies as dead (liveness-only, TTL-irrelevant) and a fail-closed pid probe confirms the process is gone (ESRCH). It keeps expired-but-alive (flagged expired-alive but never removed), EPERM, malformed, missing, and no-pid leases. Dry-run by default; --prune performs deletion; --dry-run is forced when both are passed. The probe is fail-closed: ambiguous/invalid pids fold into unknown, which keeps the session.
pi workflow gc --json # dry run (default): report only
pi workflow gc --json --prune # delete confirmed-dead sessions
pi workflow gc --json --dry-run # explicit dry runJSON report shape (committed contract):
{
"dry_run": true,
"stores": [{ "store": "harness-leases", "roots": ["/path/.pi/state/harness"], "sessions": [] }],
"counts": { "total": 0, "removable": 0, "kept": 0, "expiredAlive": 0, "errors": 0 },
"errors": []
}State root: PI_HARNESS_STATE_ROOT or <workspace>/.pi/state/harness. See docs/workflow.md for the full control-plane reference, including the deferred-seam registry, validateReceiptFamilyConsistency, and syncWorkflowHudUi internals.
Reusable Agent Profiles
Workflows dispatch isolated role agents using reusable agent profiles. This package provides default profiles under src/agents/:
| Profile | Role | Default thinking | Default tools |
|---------|------|------------------|---------------|
| planner | Turn requirements into executable plans. | high | read, grep, find, bash, ralplan_write_artifact |
| architect | Feasibility, architecture, and integration review. | high | read, grep, find, bash, ralplan_write_artifact |
| critic | Risks, tests, edge cases, and failure modes. | high | read, grep, find, bash, ralplan_write_artifact |
| worker | Execute an assigned task or goal. | medium | read, bash, write, edit |
| explorer | Pre-planner context mapping for ralplan. | high | read, grep, find, bash |
| expert-strategist | Expert-stage escalation after iterate-cap or explorer-gate human_blocked. | high | read, grep, find, bash, ralplan_write_artifact |
| prover | Produce the team completion evidence_matrix. | medium | read, bash, write, edit |
| reviewer | Produce the team task review_report. | medium | read, bash |
All bundled workflow profiles default to persistent: true so their session context can be resumed. Per-invocation overrides (model, thinkingLevel, tools, excludeTools on ralplan_run_agent, team_spawn_task_agent, ultragoal_spawn_goal_agent, and the subagent_* tools) take precedence over the loaded profile.
Profiles are authored as markdown files with YAML frontmatter. Pi discovers them from user ~/.agent/~/.agents, enabled package agents/*.md resources (including these), and trusted project .agent/.agents directories. Project ancestor profiles closest to the current directory win. See docs/workflow.md for the full discovery rules, frontmatter fields, and the standard .agent/.agents resource layout.
Model-Visible Tools
All workflow-owned tools (deep-interview_*, ralplan_*, team_*, ultragoal_*) are always exposed in the model-visible tool list alongside normal coding tools. There is no dynamic tool pruning: workflow-skill tools remain available regardless of whether a workflow is active, so workflows can be started, continued, and resumed without "tool not found" errors. Hard filters such as explicit tool allowlists and excludeTools still take precedence.
Harness Runtime
The harness runtime backs the pi workflow CLI and the four skills. It lives under src/harness/ and is organized by concern: runtime/ (sessions, leases, RPC, GC, mutation, storage, receipt rules, owner), shared/ (cross-skill utilities), subagents/ (spawn tools), tools/ (yield, fetch), and one directory per skill.
Key seams for contributors:
- Deferred-seam registry (
harness/runtime/seams.ts): an explicit, extensible list of designed-not-built harness extensions (tmux-session-orchestration,git-worktree-isolation,cross-harness-omx-fallback[permanently blocked],remote-transport,global-daemon,capability-token-auth). Requesting an unsupported seam fails closed with a self-documentingseam_unsupported:<name>token instead of a silent no-op. Add entries viaDeferredSeamRegistry.registerwithout changing the orchestrator. validateReceiptFamilyConsistency(harness/runtime/receipt-rules.ts): a write-path guard insidemutateRuntimeSessionthat rejects receipts whose post-state lifecycle contradicts their family target. It throws before any write so a contradiction leaves zero orphan events/receipts/state. Conservative and pluggable; future receipt families register rules inreceiptFamilyConsistencyRules.syncWorkflowHudUi(extensions/workflows.ts): keeps the interactive HUD in sync after team/ultragoal state mutations.
Session Layout
All session-aware path builders require a sessionId — there is no global fallback for session-scoped state. This ensures workflow state is isolated per session.
| Path | Description |
|------|-------------|
| .pi/{sessionId}/state/ | Session state directory |
| .pi/{sessionId}/workflows/{skill}/ | Workflow-specific state |
| .pi/{sessionId}/specs/ | Generated specs (deep-interview) |
| .pi/{sessionId}/plans/ | Generated plans (ralplan) |
| .pi/{sessionId}/activity.json | Session activity file |
| .pi/{sessionId}/team/{teamId}/ | Team coordination state |
| .pi/audit.jsonl | Global audit log (append-only JSONL) |
Team coordination state lives under .pi/{sessionId}/team/{teamId}/, scoped to the session that started the team run.
Session-Scoped Isolation
Workflow state and artifacts are isolated per session. A fresh session sees an empty per-session bucket by construction — no state leaks from prior sessions. A session id is required: the workflow tools resolve it from the active session, and the pi workflow CLI requires --session <id> or PI_SESSION_ID. There is no global .pi/ fallback; without a session id the CLI errors out.
Corrupt-State Recovery
If a skill's state becomes corrupt or stuck in a terminal phase, use pi workflow state <skill> clear --force to reset (optionally with --session <id>). The --force flag bypasses normal transition guards and re-seeds the state for a fresh start. pi workflow state <skill> doctor reports the resolved session id and state path, and emits the --force recovery hint for terminal skills.
Shared Modules
src/harness/shared/ provides common utilities used by all four skills:
| Module | Description |
|--------|-------------|
| paths.ts / session-layout.ts | Session-scoped path builders (require a sessionId) |
| session-resolution.ts | Session ID resolution and directory naming |
| state-schema.ts | Type assertions and validators for workflow state |
| state-writer.ts | Atomic state writes (temp-file + rename) |
| active-state.ts | Active workflow tracking per session |
| audit-log.ts | Append-only JSONL audit logging |
| receipts.ts | Receipt tracking for mutation verification |
| tamper-detection.ts | Tamper detection for state files |
| canonical-json.ts | Deterministic JSON serialization for state hashing |
| transaction-journal.ts | Transaction journal for state mutations |
| workflow-id.ts / workflow-manifest.ts | Workflow ID generation/parsing and instance tracking |
| workflow-state.ts / workflow-state-tool.ts | Base workflow state type and read tool |
| workflow-tool-utils.ts | Shared workflow tool utilities |
| handoff.ts | Inter-phase handoff utilities |
| gate-verdicts.ts | Gate verdict helpers |
| expected-next-role.ts | Scoped expected-next role helpers for guarded workflow spawns |
| context-templates.ts / compact-state-registry.ts / compact-budget.ts | Shared context templates and prompt-budget compact helpers |
Workflow types:
type WorkflowSkill = "deep-interview" | "ralplan" | "team" | "ultragoal";
type RalplanStage = "planner" | "architect" | "critic" | "revision" | "adr" | "final";Public API
The package entry point re-exports the workflow commands, the extension entry point, and the full harness runtime modules:
import {
handleWorkflowCommand,
runWorkflowCommand,
runStateCommand,
} from "@tsuuanmi/pi-workflows";The default export is the workflows extension that the coding agent loads. Subpath exports:
@tsuuanmi/pi-workflows/commands/state-command— thepi workflow statecommand.@tsuuanmi/pi-workflows/runtime/*— individual harness runtime modules (sessions, leases, RPC, GC, mutation, storage, receipt rules, etc.).
See src/index.ts for the complete barrel.
Development
# Build (after any src change, rebuild before vitest/tsgo in this monorepo)
npm run build
# Typecheck
tsgo --noEmit
# Lint/format
biome check --write --error-on-warnings .
# Targeted tests
npx vitest --run <file>Workspace tests import packages from the gitignored dist/, so rebuild this package after any src/ change before running vitest or tsgo.
Further Reading
- docs/workflow.md — full
pi workflowcontrol-plane reference, agent profiles, and internals. - docs/skills/ — per-skill design docs.
- docs/harness/ — harness runtime, shared modules, subagent, and tool docs.
- CHANGELOG.md — changes.
- Skills — Pi skill format and installation paths.
- Subagents — Pi-native SubagentManager and subagent tools.
License
MIT
