Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Why Wai?

wai — pronounced like “why” — is a workflow manager for AI-driven development. It can also be read as “way”, and that’s intentional: the tool’s focus is capturing why it was built that way.

The Problem

You come back Monday morning. The code is there — merged, deployed, working. But nobody remembers why approach X was chosen over Y. The research that ruled out three alternatives? Lost in a chat thread. The design constraint that shaped the API? Buried in a meeting note nobody bookmarked. The trade-off that made the architecture click? It lived in someone’s head, and they moved on.

This happens constantly in AI-assisted development, where code is produced fast but reasoning evaporates even faster:

  • Context resets every session. AI agents start fresh each time. The research you did yesterday is gone unless you manually re-explain it.
  • Decisions outlive their rationale. Code survives; the thinking behind it doesn’t. Six months later, nobody can explain why the system works the way it does.
  • Handoffs lose signal. Switching between agents, or between human and agent, means re-discovering context that already existed.
  • Config drift. AI instructions (CLAUDE.md, .cursorrules) fall out of sync across tools, so agents get inconsistent guidance.

How Wai Helps

Wai addresses each of these pain points directly:

Pain pointHow wai solves it
Context resets every sessionwai close captures session state; wai prime restores it. Agents resume where they left off.
Decisions outlive their rationalewai add research, wai add design, and wai add plan preserve the why alongside the what.
Handoffs lose signalwai handoff create generates a high-context summary that carries reasoning across sessions and agents.
Config driftThe sync engine keeps agent configs aligned from a single source of truth.

At a Glance

wai connects your thoughts and your codebase:

  • 🧠 Capture — Record research, designs, and decisions as you work.
  • 🗺️ Context — Advance projects through phases: Research → Design → Plan → Implement → Review → Archive.
  • 🔄 Sync — Keep AI instructions automatically aligned from one source of truth.
  • 📦 Handoff — Generate high-context session summaries for yourself or other agents.

How It Fits Together

┌──────────────────────────────────────────────────────────┐
│                        .wai/                             │
│                                                          │
│  ┌─ Projects ──┐  ┌─ Areas ──┐  ┌─ Resources ─────────┐ │
│  │ my-feature/ │  │ ops/     │  │ agent-config/        │ │
│  │  research/  │  │ docs/    │  │   skills/ rules/     │ │
│  │  designs/   │  └──────────┘  │ reflections/         │ │
│  │  plans/     │                │ pipelines/           │ │
│  │  handoffs/  │  ┌─ Archives ┐ └──────────────────────┘ │
│  └─────────────┘  │ old-proj/ │                          │
│                   └───────────┘                          │
├──────────────────────────────────────────────────────────┤
│  Phases: research → design → plan → implement → review   │
│  Plugins: git · beads · openspec · custom                │
│  Sync: .wai/resources/ ──→ .claude/ .cursorrules etc.    │
└──────────────────────────────────────────────────────────┘

Key Capabilities

  • PARA Method Storage: Logical organization into Projects, Areas, Resources, and Archives.
  • Phase Tracking: Structured workflow from initial research to final archive.
  • Sync Engine: Single source of truth for agent configurations across multiple tools.
  • Plugin System: Integration with git, beads, openspec, and more.
  • Reasoning Oracle: Ask natural language “why” questions about your codebase with wai why.

Where to Go Next

Depending on your role, different parts of the docs will be most useful:

  • 👤 Adopting wai in your own repo? Start with the Quick Start, then read How to Adopt Wai for a step-by-step guide.
  • 🔧 Contributing to wai itself? This repo dogfoods wai — it uses wai, beads, and openspec to manage its own development. See Development and Architecture, and read AGENTS.md for the session workflow.
  • 🤖 AI assistant? Follow the instructions in AGENTS.md at the repo root. Key commands: wai prime (session start), wai close (session end), bd ready (find work).

Design Principles

  • 🛣️ Desire Path Alignment — Pave the cowpaths; make common workflows shortest. wai status suggests the next command based on your current phase — if you’re in research, it nudges you toward wai add research; when research is captured, it suggests advancing to design.

  • 🩹 Self-Healing Errors — Errors suggest fixes, not just report problems. wai doctor --fix auto-repairs common workspace issues. Typos in commands get “Did you mean?” suggestions. Error messages include the exact command to fix the problem.

  • 🌊 Progressive Disclosure — Simple by default, powerful when needed. wai init asks nothing beyond a project name. -v shows more detail, -vv reveals internals, -vvv shows everything. Beginners see clean output; power users get full diagnostics.

  • 💡 Context-Aware — Offer smart next steps based on your current project state. Wai auto-detects your toolchain (git, beads, openspec) by scanning for workspace markers and adapts its suggestions accordingly — no configuration required.


A note on authorship

All the code in this repository was generated by a large language model. This is not a confession, nor an apology. It’s a fact, like the one that says water boils at a hundred degrees at sea level: neutral, technical, and with consequences one discovers later.

What the human did is what tends to happen before and after things come into existence: thinking. Reviewing requirements, arguing about edge cases, understanding what needs to be built and why, deciding how the system should behave when reality —which is capricious and does not read documentation— confronts it with situations nobody anticipated. The hours of planning, of design, of reading specifications until exhaustion dissolves the boundary between understanding and hallucination.

The LLM writes. The human knows what it should say.

There is a distinction, even if looking at the commit history makes it hard to find. The distinction is that a machine can produce correct code without understanding anything, the same way a calculator can solve an integral without knowing what time is. Understanding what that integral is for, whether it actually solves the problem, whether the problem was the right problem to begin with — that remains human territory. For now.

Leer en español

Release Status

Generated artifact (docs.yml, from Cargo.toml + git ref). Do not hand-edit — the repo source files remain authoritative.

  • Version: v2026.10.19
  • Built from: main @ c4685f8

Installation

The easiest way to install wai is using a package manager.

Homebrew (macOS & Linux)

brew tap charly-vibes/charly
brew install wai

Scoop (Windows)

scoop bucket add charly https://github.com/charly-vibes/scoop-charly.git
scoop install wai

From Binary (All Platforms)

Download the latest pre-compiled binary for your architecture from the GitHub Releases page.

  1. Unpack the archive.
  2. Move the wai binary to a directory in your PATH (e.g., /usr/local/bin or C:\Windows\System32).

From Source (Rust Developers)

Requires Rust (stable toolchain).

cargo install --path .

This installs the wai binary to ~/.cargo/bin/.

⚠️ WARNING: Ensure ~/.cargo/bin/ is in your PATH and has precedence. If you’ve previously installed wai via a package manager, the cargo version might be shadowed.

Verify Installation

which wai        # Check which binary is being used
wai --version    # Check version
wai --help       # Check help

Common Installation Issues

“wai: command not found”

Problem: The directory containing the wai binary is not in your shell’s PATH.

Solution (macOS/Linux): Add this to your shell profile (.bashrc, .zshrc, or .profile):

export PATH="$HOME/.cargo/bin:$PATH"

Solution (Windows): Add %USERPROFILE%\.cargo\bin to your User PATH environment variable.

Quick Start

Get up and running with wai in 5 minutes.

1. Run the Interactive Tutorial

The best way to learn is by doing. Run:

wai tutorial

This interactive guide covers the PARA method, project phases, and basic commands in a safe sandbox.

2. Initialize Your Workspace

Navigate to your project directory and initialize:

wai init

This creates a .wai/ directory as the single source of truth for all reasoning and workflow state. Everything wai tracks lives here: artifacts, configs, plugin definitions, and project metadata. Commit this directory alongside your code.

3. Create a Project

In wai, a “Project” is an active work item with a specific goal. Create your first one:

wai new project my-feature

Projects use phases instead of jumping straight to code. This ensures research and design reasoning exist before implementation. When you or an agent revisits the project later, the why is already captured.

4. Capture Research

Projects start in the Research phase. Record your initial thoughts or findings:

wai add research "Evaluated options A and B. Choosing A for performance."

This creates a dated Markdown artifact in .wai/projects/my-feature/research/. The artifact persists across sessions and won’t disappear when an agent’s context resets.

5. Advance Through Phases

As your work progresses, advance the project’s phase:

# Advance: Research → Design
wai phase next

# Add a design artifact
wai add design "New API will use standard REST patterns."

# Optionally: deliberate the design with a decision matrix (opt-in)
wai matrix init "Which storage engine should we adopt?"
wai matrix approach add event-sourcing
wai matrix criterion add operational-cost
# fill cells by writing files directly:
#   echo "Full audit trail." > .wai/projects/myproj/designs/matrix/approaches/02-event-sourcing/01-operational-cost/fact.md
#   touch .wai/projects/myproj/designs/matrix/approaches/02-event-sourcing/01-operational-cost/green
wai matrix decide "02-event-sourcing" "Best audit story at acceptable ops cost."
wai phase next   # gate checks the matrix is decided and current

Phases (research → design → plan → implement → review → archive) guide what kind of work and artifacts are expected at each stage. They’re flexible — skip forward or go back as needed. Projects without a decision matrix skip the gate entirely — see Decision Matrix.

6. Check Your Progress

Get a context-aware overview of your workspace:

wai status

Status is the context-aware next-step command. It shows active projects, their current phases, plugin context (git status, open issues), and smart suggestions for what to do next based on your current state. It’s the first thing to run at the start of any session.


Next Steps

Now that you’ve got the basics down, explore the more powerful features of wai:


Troubleshooting

If you run into issues, check the Troubleshooting guide or run:

wai doctor  # Check workspace health

Commands

Complete CLI reference for wai.

Table of Contents


Global Flags

Available for all commands:

FlagDescription
-v, --verboseIncrease verbosity (-v, -vv, -vvv)
-q, --quietSuppress non-error output
--jsonOutput machine-readable JSON
--no-inputDisable interactive prompts
--yesAuto-confirm actions with defaults
--safeRun in read-only safe mode (blocks write operations)

Safe mode

--safe prevents all write operations. Commands that modify state — add, sync, move, pipeline start/next/init/approve/lock/bypass, phase next/back/set, and import — will exit with an error. Read-only commands like status, search, doctor, pipeline verify, and pipeline current work normally.


Workspace & Initialization

Commands for managing the wai workspace and checking repo hygiene.

CommandDescription
wai init [--name <name>]Initialize wai in current directory
wai tutorialRun interactive quickstart tutorial
wai ls [--root <dir>] [--depth <n>] [--timeout <sec>]List all wai workspaces under a root directory (default: $HOME)
wai doctor [--fix]Diagnose and repair wai workspace health (see checks)
wai way [--fix <CHECK>]Check and scaffold repository best practices
wai import <path>Import existing tool configs (.claude/, .cursorrules)

wai init

Creates the .wai/ directory structure and a default config.toml in the current repository. Run once per repo. If you omit --name, wai uses the directory name.

# Initialize in the current repo
wai init

# Initialize with an explicit workspace name
wai init --name "my-api"

Note: wai init is idempotent — running it again in an initialized repo only fills in missing files; it won’t overwrite your existing config or artifacts.

wai import

Pulls in existing tool configuration files from another tool’s directory (e.g., .claude/, .cursorrules) and registers them as wai-managed agent configs. Useful when adopting wai in a repo that already has agent instructions. See Adopt Wai in an Existing Repo for a step-by-step guide.

# Import Claude Code config from .claude/
wai import .claude/

# Import from a Cursor rules file
wai import .cursorrules

wai way

Audits your repository against AI-friendliness best practices: checks for CLAUDE.md, .editorconfig, skill files, and similar scaffolding. Unlike wai doctor, which focuses on the .wai/ workspace, wai way focuses on the repository as a whole.

It also runs a project artifact completeness check: scans .wai/projects/<project>/{research,handoffs,designs,plans,reviews}/ for stub documents (frontmatter plus fewer than 5 body lines), so session-mined findings don’t silently evaporate. Single-line structured records (UPPERCASE-KEY: ...) are exempt.

# Check which best practices are missing
wai way

# Scaffold any missing skill files
wai way --fix skills

Choosing the Right Tool

  • Use wai doctor when your .wai/ directory is missing, a project phase is stuck, or a sync command is failing.
  • Use wai way when you want to improve your overall repository for AI friendliness (e.g., adding CLAUDE.md, .editorconfig, or SKILL.md files).

Projects & Artifacts

Items & Phases

CommandDescription
wai new project <name>Create a new project (also new area, new resource)
wai move <item> <category>Move an item between PARA categories
wai status [--json]Check project status and suggest next steps
wai show [<name>]Show PARA overview or details for a specific item
wai phase [show|next|back|set]Show or change the current project phase

Available phases: research, design, plan, implement, review, archive

See Project Phases and Organizing with PARA for conceptual background.

wai new

Creates a new PARA item and scaffolds its directory structure under .wai/.

# Start a new feature project
wai new project user-auth

# Create an area for ongoing work
wai new area platform-reliability

# Add a shared resource
wai new resource api-design-guidelines

wai move

Moves an item between PARA categories. Use this when a project completes and needs archiving, or when scope shifts (e.g., a finished project becomes an area of ongoing maintenance).

# Archive a finished project
wai move user-auth archives

# Promote a resource to an active project
wai move api-design-guidelines projects

wai status

Shows the active project, current phase, recent activity, and next-step suggestions. Run this at the start of a session to orient yourself.

wai status
wai status --json | jq '.projects[].phase'

wai show

Without arguments, shows a PARA overview of all items. With a project name, shows that project’s phase, artifacts, and recent history.

# Overview of all projects and areas
wai show

# Detailed view of a specific project
wai show user-auth

wai phase

Reads or changes the current project phase. Phases gate which artifact types are expected, for example, you should add research before advancing to design.

# Check the current phase
wai phase show

# Advance to the next phase
wai phase next

# Jump to a specific phase
wai phase set implement

# Step back one phase (e.g., to add missing design artifacts)
wai phase back

Note: wai phase next does not prevent you from advancing even if the current phase has no artifacts — it just changes the phase label. Missing artifacts will show up in wai status suggestions.


Adding Artifacts

CommandDescription
wai add research <content>Add research notes (also plan, design)
wai add review --reviews <filename>Add a review artifact for an existing artifact
wai add <type> --file <path>Import artifact from file
wai add <type> --tags <tags>Add tagged artifact (frontmatter-based)
wai add <type> --bead <id>Link artifact to a beads issue ID
wai add <type> --project <name>Add to specific project (instead of current)
wai add <type> --corrects <path>Create an addendum correcting a locked artifact

Artifacts are the core of wai — they capture the why behind your decisions so future agents and contributors can reconstruct your reasoning. Each artifact is a Markdown file timestamped and stored under .wai/projects/<name>/<type>/.

Choosing an Artifact Type

  • Research (wai add research) — Use for gathering information, exploring problem spaces, and evaluating options.
    • Example: “Evaluated two DB engines; chose PostgreSQL for its JSONB support.”
  • Design (wai add design) — Use for making architectural decisions and defining system structure.
    • Example: “Proposed microservices architecture with EventBridge for communication.”
  • Plan (wai add plan) — Use for breaking down implementation into specific, actionable steps.
    • Example: “Step 1: Scaffold auth service. Step 2: Implement JWT middleware.”
  • Review (wai add review) — Use for recording validation results against an existing artifact.
    • Example: wai add review --reviews 2026-04-15-findings.md --verdict pass --severity "critical:0,high:1"
    • Requires --reviews <filename> to specify the target artifact.
    • Optional: --verdict (pass/fail/needs-work), --severity (level:count pairs), --produced_by (skill name).

Examples

# Capture a quick research note inline
wai add research "Considered Redis vs Memcached; chose Redis for pub/sub support"

# Import a detailed design from a file
wai add design --file architecture-decision.md

# Link an artifact to a beads issue for traceability
wai add plan "Scaffold the service layer first" --bead wai-abc1

# Add a research note to a specific project (not the active one)
wai add research "Benchmark results" --project payment-service

# Correct a locked artifact without modifying the original
wai add research --corrects .wai/projects/auth/research/2026-01-10.md \
  "Correction: the Redis pub/sub approach has 50ms latency at scale"

Note on --corrects: You can only correct a locked artifact (one with a SHA-256 sidecar). To lock an artifact, run wai pipeline lock at the relevant pipeline step. The correction is stored as a linked addendum — the original is not modified.


Searching & Timeline

CommandDescription
wai search <query>Search across all artifacts
wai search --type <type>Filter by type (research/plan/design/handoff)
wai search --in <project>Search within specific project
wai search --tag <tag>Filter by tag (repeatable)
wai search --regexUse regex patterns for query
wai search --latestReturn only the most recently dated match
wai search -C <n>Show N lines of context around each match
wai search --include-memoriesInclude bd memories in search results
wai timeline <project>View chronological project timeline
wai timeline --from <date>Filter by date range (YYYY-MM-DD)

Searches artifact content across your wai workspace. Results include file paths and matching lines. Use --latest to find the most recent decision on a topic rather than all mentions.

# Find all artifacts mentioning a topic
wai search "authentication"

# Find only the most recent research on a topic
wai search "database" --type research --latest

# Regex search with context lines
wai search "api.*error" --regex -C 3

# Search within a specific project
wai search "caching" --in payment-service

# Include bd memories in the search sweep
wai search "retry policy" --include-memories

wai timeline

Shows all artifacts for a project in chronological order, making it easy to trace how a decision evolved across sessions.

wai timeline user-auth
wai timeline user-auth --from 2026-01-01 --to 2026-03-01

Agent Configuration

See Agent Config Sync for how projections work.

CommandDescription
wai syncOverwrite agent configs to tool-specific locations
wai sync --statusCheck sync status without modifying files
wai sync --from-mainSync resources from main git worktree
wai config listList all agent config files
wai config add <type> <file>Add agent config (skill/rule/context)
wai config edit <path>Safe: Edit config file in $EDITOR
wai resource list skillsList all available skills
wai add skill <name> [--template <tpl>]Scaffold a new skill (templates: gather, create, tdd, rule-of-5, ubiquitous-language)
wai resource install <skill> [--global|--from-repo <path>]Install a skill globally or from another repo
wai resource export <skills...> --output <file>Export skills to a tar.gz archive
wai resource import skills [--from <dir>]Import skills from a directory
wai resource import archive <file> [--yes]Import skills from a tar.gz archive

⚠️ WARNING: wai sync is destructive to your target files. Target locations are defined in .wai/resources/agent-config/.projections.yml — the built-in claude-code target writes to .claude/commands/. Always edit the .wai/ source files; changes to the projected copies will be overwritten on the next sync.

wai sync

Writes your .wai/ agent configs out to their tool-specific target locations. Run after editing any config in .wai/ to push changes out to the agent tools.

# Write all configs to their targets
wai sync

# Preview what would change without writing
wai sync --status

# Sync from main branch when working in a git worktree
# (use when .wai/ lives on main but your branch doesn't have it)
wai sync --from-main

wai config

Manages the list of agent config files tracked by wai. Use wai config add to register a new file and wai config edit to safely modify a tracked config in your editor (edits the source in .wai/, not the projected copy).

# See what config files are registered
wai config list

# Register a new skill file
wai config add skill .wai/resources/skills/my-skill.md

# Edit a tracked config (opens $EDITOR on the source file)
wai config edit .wai/resources/skills/my-skill.md

wai resource — Skill Lifecycle

Skills are reusable agent instruction files. Use wai resource to list, install, scaffold, or share them.

# See all available skills in this workspace
wai resource list skills

# Scaffold a new TDD skill from a template
wai add skill my-tdd-workflow --template tdd

# Install a skill from another repo (e.g., a shared team template)
wai resource install code-review --from-repo ../shared-skills

# Install globally so all your repos can use it
wai resource install deploy-checklist --global

wai add skill vs wai config add: Use wai add skill to scaffold a new skill from a template (creates the file and registers it). Use wai config add skill <file> to register an existing file you created manually.

wai resource — Import/Export

Share skill bundles between repositories or teams using tar.gz archives.

# Export a set of skills to a shareable archive
wai resource export code-review deploy-checklist --output team-skills.tar.gz

# Import skills from a directory
wai resource import skills --from ../shared-skills/

# Import from an archive (prompts for confirmation per skill)
wai resource import archive team-skills.tar.gz

# Import from an archive without prompts
wai resource import archive team-skills.tar.gz --yes

AI-Driven Workflows

These commands require an LLM backend. Run wai why --no-llm or configure a provider before using them in automated contexts. See LLM Configuration under wai why.

Reasoning & Reflection

See Reasoning for conceptual background on how wai why and wai reflect work.

CommandDescription
wai why <query>Ask why a decision was made (LLM-powered)
wai why <file-path>Explain a file’s history and rationale
wai reflectSynthesize session context into a resource file
wai reflect --save-memoriesSave reflection bullets to bd memories

wai why

Answers natural-language questions about your project by combining .wai/ artifacts with git history and querying an LLM. Results include an answer, a decision chain, and references to the artifacts that informed it.

# Ask a decision question
wai why "Why did we choose TOML over YAML for config?"

# Explain a specific file's history
wai why src/plugin.rs

# Run without LLM — falls back to wai search (useful offline)
wai why --no-llm "plugin architecture"

Backend selection and fallback behavior:

Wai auto-detects the available LLM backend in this order: Agent (if inside a Claude Code session), Claude API (ANTHROPIC_API_KEY), Claude CLI binary, Ollama. If no backend is available:

  • By default, wai falls back to wai search on the same query (equivalent to --no-llm).
  • Set fallback = "error" in [llm] config to get an explicit error instead.
# .wai/config.toml
[llm]
fallback = "error"   # "search" (default) or "error"

Agent mode (zero-cost inside Claude Code):

When running inside a Claude Code session, set llm = "agent" to route the query through your agent instead of calling the API directly:

[llm]
llm = "agent"

Privacy: The first time you use an external backend (Claude API or Claude CLI), wai displays a privacy notice explaining that your artifact content will be sent to an external service. Set privacy_notice_shown = true in [llm] to suppress it after you’ve acknowledged it.

wai reflect

Synthesizes accumulated session context (handoffs, research, conversation history) into a versioned reflection file in .wai/resources/reflections/. Run approximately every 5 sessions.

# Synthesize and write a reflection file
wai reflect

# Also save key bullets to bd memories for cross-session retrieval
wai reflect --save-memories

The reflection is automatically woven into managed blocks in CLAUDE.md / AGENTS.md so the next agent session starts with the patterns, conventions, and gotchas extracted from your session history. See Reasoning for the full synthesis cycle.


Session Management

See Sessions for the session lifecycle and how handoffs preserve context.

CommandDescription
wai prime [--project <name>]Orient at session start: phase, last handoff, next step
wai close [--project <name>]Wrap up session: create handoff and next steps
wai handoff create <project>Generate handoff document with plugin context

wai prime

Runs at the start of a session to orient you: reads the last handoff, reports the current phase, and surfaces the next suggested step. It also lists the Prior context — the 5 newest research/design/review docs of the active project — so you don’t re-run investigations that already happened. Most Claude Code setups call this automatically via a startup hook.

# Orient for the active project
wai prime

# Orient for a specific project
wai prime --project payment-service

wai close

Wraps up the current session by creating a handoff document summarizing what was done and what comes next. Always run this before ending a session — it ensures the next session can resume cleanly. A startup hook in Claude Code detects a pending handoff and recovers context automatically.

# Close the active project session
wai close

# Close a specific project
wai close --project user-auth

Workflow: wai close calls wai handoff create internally. You rarely need wai handoff create directly unless you want a handoff mid-session without closing.

wai handoff

Generates a handoff document capturing the current session state, plugin context (beads status, openspec state), and next steps. Called automatically by wai close.

# Generate a handoff explicitly (mid-session)
wai handoff create user-auth

Feedback

File an issue against wai’s upstream repository with environment context attached.

CommandDescription
wai feedback bug [--title <title>]File a bug report with context
wai feedback --from-last-errorBuild report from the last wai error
wai feedback --dry-runPreview the issue without filing

wai feedback

Automatically gathers environment context (OS, wai version, git remote, debug logs), redacts secrets and paths, then files a GitHub issue via gh (with a fallback ladder to --web or manual copy-paste).

# File a bug report (prompts for kind and title)
wai feedback bug

# File from the last error (derives title and body automatically)
wai feedback --from-last-error

# Preview what would be filed
wai feedback friction --title "slow startup" --dry-run

# Open a prefilled browser URL instead of using gh
wai feedback bug --title "crash on init" --web

Pipelines

See Pipelines for conceptual background on pipeline structure and gates.

CommandDescription
wai pipeline listList all available pipelines
wai pipeline show <name>View steps and gates for a pipeline
wai pipeline init <name>Scaffold a new TOML pipeline definition
wai pipeline start <name> --topic="..."Start a run with topic substitution
wai pipeline nextAdvance to the next step in the active run
wai pipeline currentReprint current step prompt (session recovery)
wai pipeline status <name>Show run status (use --run <id> for details)
wai pipeline suggest [description]Rank pipelines by keyword match
wai pipeline gates [name] [--step=<id>]Show gate requirements and live status
wai pipeline check [--oracle=<name>]Dry-run gate evaluation without advancing
wai pipeline approveRecord human approval for current step
wai pipeline validate [name]Validate pipeline TOML definitions
wai pipeline bypass <reason>Record a disclosed gate bypass in the active run’s ledger (silent no-op with no active run)
wai pipeline lockLock current step’s artifacts (SHA-256 hash sidecars)
wai pipeline verifyVerify integrity of all locked artifacts
# Start a research pipeline
wai pipeline start scientific-research --topic="Effect of caching on P99 latency"

# Check what step you're on after a session break
wai pipeline current

# See what gates must pass before advancing
wai pipeline gates scientific-research --step=generate

# Advance once gates are satisfied
wai pipeline next

# Lock artifacts at a milestone step
wai pipeline lock

Decision Matrix

Manage the project’s decision matrix (Design in Practice methodology). See Decision Matrix for the full model.

wai matrix init

wai matrix init "Which storage engine should we adopt?"

Scaffolds .wai/projects/<project>/designs/matrix/: problem.md (the A1), criteria/, approaches/01-status-quo/ with _description.md, and an empty decision.md template (never counts as decided). One matrix per project — re-init fails and names the existing matrix.

wai matrix criterion add

wai matrix criterion add operational-cost

Creates criteria/NN-<name>.md and an empty cell directory in every existing approach (rectangular by construction).

wai matrix approach add

wai matrix approach add event-sourcing

Creates approaches/NN-<name>/ with _description.md and an empty cell directory for every existing criterion.

wai matrix decide

wai matrix decide "02-event-sourcing" "Best audit story at acceptable ops cost."

Validates the approach exists (errors list valid names), writes decision.md (approach, rationale, UTC timestamp, design-doc pointer), and scaffolds designs/<date>-<slug>.md with frontmatter and a decision-time snapshot of the winning column’s facts.

wai matrix lint

wai matrix lint

Structural errors (non-zero exit): rectangularity, one marker per filled cell, no empty fact.md, status-quo first. Methodology warnings (never block): all-green column, undistinguished columns, judgment-in-text, link-only cells, criteria-as-questions, status-quo-without-red, decided-with-unfilled-cells, empty problem.md, stale decision.

wai matrix render

wai matrix render && open .wai/projects/<project>/designs/matrix/matrix.html

Generates a self-contained matrix.html (inline CSS, no JS) as a pure function of the directory state — byte-identical for equal state. It is a generated view: never committed, always regenerable.

All subcommands accept --project <name> (otherwise resolved via WAI_PROJECT or auto-detection).

Plugin System

CommandDescription
wai plugin listList all plugins (built-in and custom)
wai plugin enable <name>Enable a plugin
wai <plugin> <command>Pass-through to plugin commands (e.g. wai beads list)

See Plugin System for how auto-detection and pass-through work.

# See which plugins are active
wai plugin list

# Pass a command through to the beads plugin
wai beads ready

# Pass a command through to the openspec plugin
wai openspec list

Doctor Checks

wai doctor runs the following checks. Use --fix to auto-repair where possible.

# Run all checks
wai doctor

# Auto-fix any repairable issues
wai doctor --fix
CheckWhat it verifies
Directory structureRequired .wai/ subdirectories exist
Configuration.wai/config.toml is parseable and valid
VersionConfig version is compatible with installed wai
Plugin toolsExternal tools (git, beads, openspec) are installed and reachable
Agent config syncProjections are in sync between source and target files
Project statePhase state files are valid and consistent
Custom pluginsTOML plugin definitions parse correctly
README badgeRepository README includes a wai badge
Claude Code session hookClaude Code hooks are configured for wai
Skills in repoSkill files are valid and importable
Agent tool coverageAgent instructions reference available skills
Agent instructionsCLAUDE.md / AGENTS.md files are present and well-formed
Managed block stalenessAuto-generated sections are up to date
Pipeline definitionsPipeline TOML files parse correctly with valid gates
WAI_PROJECT env varEnvironment variable matches active project
Artifact locksLocked artifacts match their SHA-256 hashes

Examples

Basic Workflow

# Initialize and create project
wai init
wai new project my-feature

# Orient at session start
wai prime

# Capture research before designing
wai add research "Evaluated options A and B, chose A for performance"
wai phase next

# Add design decisions
wai add design "Architecture uses microservices pattern"
wai phase next

# Close session with a handoff
wai close

Search and Timeline

# Search with filters
wai search "authentication" --type research
wai search "api.*error" --regex -C 3

# Find the most recent decision on a topic
wai search "caching strategy" --latest

# View project history
wai timeline my-feature
wai timeline my-feature --from 2026-02-01 --to 2026-02-15

Reasoning

# Ask a question grounded in your artifacts
wai why "Why did we choose event sourcing over CQRS?"

# Explain a file's purpose from its git history
wai why src/event_store.rs

# Force offline/search mode
wai why --no-llm "event store design"

# Synthesize accumulated context into a reflection
wai reflect

JSON Output for Automation

# Get structured data
wai status --json | jq '.projects[] | .name'
wai search "config" --json | jq '.results[].path'
wai plugin list --json
wai way --json | jq '.summary.pass'

Troubleshooting

Common issues and solutions for wai.

Commands Not Working

“wai: command not found”

Problem: Wai is not in your PATH after installation.

Solution:

# Check if cargo bin is in PATH
echo $PATH | grep cargo

# If not, add to your shell profile (~/.bashrc, ~/.zshrc, etc.)
export PATH="$HOME/.cargo/bin:$PATH"

# Reload shell
source ~/.bashrc  # or ~/.zshrc

“Project not found” or “Not initialized”

Problem: Running wai commands outside of an initialized directory.

Solution:

# Check if you're in a wai workspace
ls -la .wai/

# If not, initialize or navigate to the correct directory
wai init
# or
cd /path/to/your/wai/workspace

Error example:

Error: wai::error::not_initialized
  ╭─[command]
  │ wai status
  ╰────
  help: Run 'wai init' to initialize wai in this directory

Sync Issues

⚠️ WARNING: wai sync is destructive to your target files (e.g., .cursorrules, .claude/config.json). It will overwrite any manual changes in these files with the versions from your .wai/resources/agent-config/ source directory.

Sync conflicts - target file manually edited

Problem: You edited a synced file directly and wai sync overwrote your changes, or you want to keep manual changes before syncing.

Solution:

  1. Always edit source files, not targets. Use wai config list to find sources.
  2. If you’ve already edited the target, back up your changes before running wai sync.
  3. Use wai sync --status to see what will be changed before applying.
# Recommended workflow:
# 1. Check status
wai sync --status

# 2. Edit the source file correctly
wai config edit rules/my-rule.md

# 3. Apply sync
wai sync

Problem: Symlink strategy fails on Windows.

Solution: Wai automatically falls back to file copies on Windows. If you see errors:

# Check sync status
wai sync --status

# Run doctor to diagnose
wai doctor

# Try auto-fix
wai doctor --fix

Alternatively, switch to inline or reference strategy in .projections.yml.

“Permission denied” during sync

Problem: Wai can’t write to target directory.

Solution:

# Check target directory permissions
ls -ld .claude/

# Fix permissions
chmod u+w .claude/

# Or run sync with appropriate permissions
sudo wai sync  # Last resort, not recommended

Plugin Issues

Plugin not detected

Problem: Plugin shows as “not detected” in wai plugin list.

Solution:

# Check if detector file/directory exists
ls -la .beads/    # for beads
ls -la .git/      # for git
ls -la openspec/  # for openspec

# Install the plugin tool
cargo install beads  # or appropriate installation

# Verify detection
wai plugin list

Custom plugin not loading

Problem: TOML plugin in .wai/plugins/ not appearing.

Solution:

# Check TOML syntax
cat .wai/plugins/my-plugin.toml

# Verify file extension (.toml)
ls .wai/plugins/

# Check for TOML errors
wai doctor

# Example valid plugin:
cat > .wai/plugins/example.toml << 'EOF'
name = "example"
description = "Example plugin"

[detector]
type = "directory"
path = ".example"

[[commands]]
name = "status"
description = "Show status"
passthrough = "example status"
read_only = true
EOF

Plugin command fails

Problem: wai <plugin> <command> returns an error.

Solution:

# Verify plugin tool is installed and in PATH
which beads
which mytool

# Test command directly
beads list
mytool status

# Check plugin definition
wai plugin list --json | jq '.plugins[] | select(.name=="myplugin")'

Search & Timeline Issues

Search returns no results

Problem: Can’t find artifacts you know exist.

Solution:

# Check if you're searching the right project
wai search "query" --in project-name

# Try without filters
wai search "query"

# Use case-insensitive search (regex mode)
wai search "(?i)query" --regex

# Verify artifacts exist
wai timeline my-project
wai show my-project

Timeline shows wrong dates

Problem: Artifacts appear in unexpected order.

Solution: Timeline is sorted by filename date (YYYY-MM-DD prefix). Artifacts are created with the current date by default.

# Check actual filenames
ls .wai/projects/my-project/research/

# Files are named: YYYY-MM-DD-slug.md
# Timeline sorts by this date, not file modification time

Doctor Command Issues

Doctor runs 16 checks covering directory structure, configuration, plugins, agent configs, pipelines, artifact locks, and more. See the full list in Commands — Doctor Checks.

Doctor reports issues but –fix doesn’t work

Problem: wai doctor --fix doesn’t repair all issues.

Solution: Some issues require manual intervention:

# Run doctor to see all issues
wai doctor

# Check which issues can't be auto-fixed
# Doctor will show suggestions for manual fixes

# Common manual fixes:
# 1. Corrupted config - restore from backup or re-init
# 2. Missing directories - create manually or re-init
# 3. Permission issues - fix with chmod/chown

Doctor false positives

Problem: Doctor reports issues that aren’t actually problems.

Solution:

# Check specific validation
wai doctor --json | jq .

# Some "warnings" are informational
# Only "error" severity items need fixing

# If you believe it's a false positive, file an issue:
# https://github.com/charly-vibes/wai/issues

Artifact Integrity Issues

Locked artifact verification fails

Problem: wai pipeline verify or wai doctor reports hash mismatches.

Solution: A mismatch means a locked artifact was modified after locking. This can happen if you edited it directly instead of creating an addendum.

# See which artifacts failed
wai pipeline verify

# If the edit was intentional, create an addendum instead:
# 1. Restore the original (git checkout the file)
git checkout -- .wai/projects/my-project/research/2026-04-15-findings.md

# 2. Record corrections as an addendum
wai add research --corrects=.wai/projects/my-project/research/2026-04-15-findings.md "corrected details"

# 3. Verify again
wai pipeline verify

If you need to re-lock after a legitimate change, delete the .lock sidecar and run wai pipeline lock again.

“artifact missing” in verify output

Problem: A .lock file references an artifact that no longer exists.

Solution: The artifact was deleted after locking. Either restore it from git history or remove the orphaned .lock file:

# Find orphaned lock files
wai pipeline verify

# Restore from git
git checkout -- <path-to-artifact>

# Or remove the orphaned lock
rm <path-to-artifact>.lock

Phase Management Issues

Can’t advance to next phase

Problem: wai phase next doesn’t work or gives unexpected results.

Solution:

# Check current phase
wai phase show

# Phases are: research → design → plan → implement → review → archive
# Can't advance past archive

# If stuck, set phase directly
wai phase set implement

# Check phase history
wai phase show  # Shows all transitions

Phase history looks wrong

Problem: Phase history shows unexpected transitions.

Solution: Phase history is stored in .wai/projects/<name>/.state. This file tracks all transitions with timestamps.

# View state file
cat .wai/projects/my-project/.state

# If corrupted, you can manually edit (advanced)
# Or reset to a phase:
wai phase set research  # Starts fresh from research

Artifact Issues

Tags not working

Problem: Tags don’t appear or can’t search by tags.

Solution: Tags are stored in YAML frontmatter for research artifacts:

# Add tags correctly (comma-separated, no spaces around commas)
wai add research "Finding" --tags "api,security,auth"

# NOT: --tags "api, security, auth"  # Extra spaces cause issues

# Check frontmatter
head -10 .wai/projects/my-project/research/*.md

# Should see:
# ---
# tags: [api, security, auth]
# ---

Can’t import file

Problem: wai add research --file path.md fails.

Solution:

# Check file exists and is readable
ls -la path.md
cat path.md

# Use absolute or relative path
wai add research --file ./notes/research.md
wai add research --file /full/path/to/research.md

# Check file isn't binary
file notes/research.md  # Should say "text"

JSON Output Issues

JSON output malformed

Problem: --json flag produces invalid JSON.

Solution:

# Ensure no extra output
wai status --json --quiet

# Check for errors on stderr
wai status --json 2>&1 | jq .

# Validate JSON
wai status --json | jq empty

Can’t parse JSON in scripts

Problem: Automation scripts fail to parse wai JSON output.

Solution:

# Capture only stdout
wai status --json 2>/dev/null | jq .

# Handle errors separately
if ! output=$(wai status --json 2>&1); then
  echo "Error: $output" >&2
  exit 1
fi
echo "$output" | jq .

Performance Issues

Commands are slow

Problem: Wai commands take a long time to execute.

Solution:

# Check project size
du -sh .wai/

# Large artifact counts can slow search/timeline
find .wai/projects -name "*.md" | wc -l

# Use filters to limit scope
wai search "query" --in specific-project -n 10
wai timeline project --from 2026-02-01

# For very large projects, consider archiving old work
wai move old-project archives

Getting Help

Where to find more help

Resources:

  • Built-in help: wai <command> --help
  • Verbose help: wai --help -v (shows advanced options)
  • Status check: wai doctor (diagnoses workspace issues)
  • GitHub Issues: https://github.com/charly-vibes/wai/issues
  • Documentation: Check docs/ directory

Filing a bug report

Include:

  1. Wai version: wai --version
  2. Operating system: uname -a
  3. Command that failed: Full command with flags
  4. Error message: Complete error output
  5. Doctor output: wai doctor
# Create comprehensive debug report
{
  echo "=== Version ==="
  wai --version

  echo -e "\n=== System ==="
  uname -a

  echo -e "\n=== Doctor ==="
  wai doctor

  echo -e "\n=== Config ==="
  cat .wai/config.toml
} > wai-debug-report.txt

Then attach wai-debug-report.txt to your issue.

PARA Method

Why PARA? Without structure, project artifacts end up scattered across flat directories, wikis, Slack threads, and local notes. Finding that design decision from three weeks ago becomes an archaeological dig. PARA gives every artifact a clear home based on its lifecycle stage — active work goes in Projects, ongoing responsibilities in Areas, reference material in Resources, and completed work in Archives. You always know where to look.

Wai organizes artifacts using the PARA method — a system for organizing digital information into four categories:

.wai/
├── projects/          ← Active work with a goal and phases
│   ├── auth-feature/     research/ designs/ plans/ handoffs/
│   └── api-redesign/     research/ designs/ plans/ handoffs/
├── areas/             ← Ongoing responsibilities (no end date)
│   └── security/
├── resources/         ← Reference material and reusable assets
│   ├── agent-config/     skills/ rules/ context/
│   ├── reflections/
│   └── pipelines/
└── archives/          ← Completed items (searchable, hidden from status)
    └── old-feature/

Projects

Active work with a defined goal and deadline. Each project has its own directory under .wai/projects/ containing research notes, plans, designs, and handoff documents.

.wai/projects/my-app/
├── .state           # Phase state machine (YAML)
├── research/        # Date-prefixed research notes
├── plans/           # Date-prefixed plan documents
├── designs/         # Date-prefixed design documents
└── handoffs/        # Date-prefixed handoff documents

Areas

Ongoing areas of responsibility with no end date. These live under .wai/areas/.

Resources

Reference material and reusable assets. Stored under .wai/resources/:

.wai/resources/
├── agent-config/    # Single source of truth for agent configs
│   ├── skills/
│   ├── rules/
│   ├── context/
│   └── .projections.yml
├── templates/
└── patterns/

Archives

Completed or inactive items moved here for reference. Located at .wai/archives/.

Moving between categories

Use wai move to reclassify items as their status changes:

wai move my-app archives    # Archive a completed project

Project Phases

Why phases? When teams skip straight to code, they build the wrong thing — or the right thing the wrong way. Decisions get made implicitly, trade-offs go unrecorded, and the first sign of trouble triggers a rewrite. Formalizing research → design → plan → implement → review → archive doesn’t slow you down; it forces the reasoning to exist before the code, so when you revisit the project later, the why is already captured.

Projects in wai progress through six phases:

          ┌──────────────────────────────────────────┐
          │                                          │
          ▼                                          │
  ┌──────────┐   ┌────────┐   ┌──────┐   ┌─────────────┐   ┌────────┐   ┌─────────┐
  │ research │──▶│ design │──▶│ plan │──▶│ implement   │──▶│ review │──▶│ archive │
  └──────────┘   └────────┘   └──────┘   └─────────────┘   └────────┘   └─────────┘
       ▲              ▲                        │
       └──────────────┴────────────────────────┘
                  (back-transitions allowed)

Phases

  1. Research — Gather information, explore the problem space, understand constraints
  2. Design — Define architecture, make key decisions, document trade-offs
  3. Plan — Break work into tasks, define milestones, set priorities
  4. Implement — Build the solution, write code, integrate components
  5. Review — Validate the work, run tests, gather feedback
  6. Archive — Complete the project, generate final handoff, move to archives

Managing phases

wai phase              # Show current phase
wai phase next         # Advance to next phase
wai phase back         # Return to previous phase
wai phase set design   # Jump to a specific phase

Flexibility

Transitions are flexible — skip forward or go back as needed. Phase history is tracked with timestamps so you can see how a project evolved over time.

Adding artifacts by phase

Each phase has associated artifact types. Wai encourages capturing the right kind of documentation at each stage:

  • Research phase → wai add research "..."
  • Design phase → wai add design "..."
  • Plan phase → wai add plan "..."

Archive Phase vs. Category

The word “archive” is used in two ways in wai, and they serve different purposes:

1. The Archive Phase (wai phase set archive)

This is a status for a project. It indicates that the project is complete, all final handoffs are generated, and no further work is planned. It stays in its current PARA category (usually Projects).

Use when: A project is finished but you still want it to appear in wai status and your active workspace overview.

2. The Archives Category (wai move my-project archives)

This is a storage location. Moving an item to archives reclassifies it in the PARA system, moving its directory from .wai/projects/ to .wai/archives/.

Use when: You want to declutter your workspace. Archived items are hidden from default wai status views and most context suggestions, but remain fully searchable.

Recommended Workflow:

  1. Set phase to archive when the work is done.
  2. Generate a final handoff (wai close).
  3. Move to the archives category when you no longer need it in your active projects list.

Sessions

Context is expensive. Every time an AI agent starts a new session, it begins with a blank slate — no memory of what was tried, what failed, or what decision was made and why. Humans face the same problem at smaller scale: you close your laptop Friday, and by Monday the thread of reasoning has frayed.

Wai’s session lifecycle exists to solve this: capture context at the end of a session, and restore it at the beginning of the next one.

The Prime → Work → Close Loop

A wai session follows a three-step loop:

┌─────────┐      ┌──────┐      ┌───────┐
│  prime   │ ───▶ │ work │ ───▶ │ close │
└─────────┘      └──────┘      └───────┘
     ▲                              │
     └──────────────────────────────┘
  1. wai prime — Orient yourself. Prime reads the latest handoff, shows active projects and their phases, surfaces plugin context (git status, open issues), and suggests next steps. It also warns (advisory, silent when green) on cross-agent collision signals: agent-provenance stash entries and unexpired agent lock-files under .wai/. If a previous session was interrupted, it detects this automatically.

  2. Work — Do your actual work: add artifacts, advance phases, write code. Wai stays out of the way.

  3. wai close — Capture state. Close generates a handoff document summarizing the session, writes a .pending-resume signal, and shows what to do before ending (close issues, commit, push).

Resume Detection

When you run wai prime after a wai close, wai checks for a .pending-resume file. If one exists and is less than 12 hours old, prime enters ⚡ RESUMING mode:

  • It reads the linked handoff document
  • Extracts the ## Next Steps section
  • Displays them prominently so you (or an agent) can pick up exactly where you left off

This is what makes session continuity work across agent boundaries — the next agent doesn’t need to rediscover context; it’s handed a precise resumption point.

What Goes Into a Handoff

A handoff document is a Markdown file stored in .wai/projects/<name>/handoffs/. It contains:

  • Session summary — What was accomplished
  • Current state — Active phase, open issues, uncommitted changes
  • Plugin context — Git status, beads issue counts, and other plugin-contributed data (gathered via the on_handoff_generate hook)
  • Next steps — Concrete actions for the next session
  • Decisions made — Key choices and their rationale

wai close vs wai handoff create

Both generate handoff documents, but they serve different purposes:

CommandWhen to use
wai closeEnd of a session. Generates a handoff and writes the .pending-resume signal so the next wai prime can detect it.
wai handoff createMid-session or explicit handoff to another person/agent. Generates the document without the resume signal.

Use wai close when you’re done working. Use wai handoff create when you need to hand context to someone else but aren’t stopping yet.

The Autonomous Loop

For AI agents running in autonomous mode, the session loop becomes a tight cycle:

  1. wai prime — orient (detects ⚡ RESUMING if mid-task)
  2. Work on one task
  3. wai close — capture state
  4. git commit and push
  5. Clear context (e.g., /clear)

The next session starts with wai prime again, which shows RESUMING with exact next steps. This pattern keeps agents productive across context window boundaries without losing the thread.

Reasoning

Capturing artifacts — research notes, design decisions, plans — is the foundation. But artifacts alone don’t answer the questions that come up later: Why did we choose this approach? What patterns have emerged across sessions? What does this file’s history tell us?

Wai’s reasoning features bridge this gap with two LLM-powered commands that query and synthesize your captured knowledge.

wai why — The Reasoning Oracle

wai why answers natural-language questions about your project by combining your artifacts with git history and feeding them to an LLM.

How It Works

  1. Context gathering — Wai collects relevant PARA artifacts (research, designs, plans) and recent git history, scoped to your query.
  2. LLM query — The gathered context and your question are sent to the configured LLM backend.
  3. Structured response — The answer comes back with a decision chain and references to the artifacts that informed it.

Query Types

You can ask wai why two kinds of questions:

# Ask a question about your project
wai why "Why did we choose TOML over YAML for config?"

# Ask about a specific file's history and purpose
wai why src/config.rs

Questions work best when they’re specific and tied to decisions your project has already made. The oracle is only as good as the artifacts you’ve captured — it queries what you recorded.

When It Shines

  • Onboarding: A new contributor asks “why does the plugin system use auto-detection?” and gets an answer grounded in actual design artifacts, not guesses.
  • Revisiting decisions: Six months later, you wonder why a particular architecture was chosen. The oracle traces it back through research and design notes.
  • File archaeology: Pointing wai why at a file explains its role in the project based on commit history and related artifacts.

wai reflect — Project Synthesis

Where wai why answers specific questions, wai reflect steps back and synthesizes patterns across your entire project history.

How It Works

  1. Context aggregation — Wai gathers conversation transcripts, handoff documents, and session history up to a character budget.
  2. Pattern synthesis — An LLM distills the accumulated context into recurring patterns, conventions, and architectural notes.
  3. Persistent output — The synthesis is written as a versioned Markdown file in .wai/resources/reflections/.
  4. Instruction updates — Wai detects instruction files (CLAUDE.md, AGENTS.md) and updates them with the new reflection, so agents pick up the patterns automatically.

When to Run It

Run wai reflect approximately every 5 sessions, or whenever you feel the project has accumulated enough new context to be worth synthesizing. It’s not meant to run after every change — it’s a periodic distillation.

wai reflect

What It Produces

The output is a reflection file containing:

  • Project conventions — Naming patterns, code style preferences, framework choices that emerged organically
  • Architectural notes — How components relate, where boundaries are, what invariants matter
  • Gotchas — Things that tripped you up and shouldn’t trip someone else

These reflections feed back into agent instructions via managed blocks, so the next agent session starts with accumulated project wisdom — not just the raw artifacts.

LLM Configuration

Both commands support multiple backends:

  • Claude API — Uses the Anthropic REST API directly (requires ANTHROPIC_API_KEY)
  • Claude CLI — Delegates to the claude binary
  • Ollama — Local LLM for offline use

Wai auto-detects the available backend. No configuration is needed if you have one of these set up.

How They Build on Artifacts

Both wai why and wai reflect are only as useful as the artifacts you’ve captured. They don’t hallucinate project context — they query and synthesize what exists in your .wai/ directory and git history.

This creates a virtuous cycle:

  1. You capture research, designs, and decisions with wai add
  2. wai why makes that knowledge queryable on demand
  3. wai reflect distills it into persistent patterns
  4. Those patterns inform the next session via managed blocks
  5. The next session captures more artifacts, and the cycle continues

Decision Matrix

The decision matrix is wai’s representation of the central artifact from the Design in Practice methodology (Rich Hickey, “Design in Practice”; Alex Miller, “Design in Practice in Practice”). Where wai add design records the conclusion, the matrix captures the deliberation: the approaches considered, the criteria that mattered, the facts gathered, and the judgment made on each intersection.

One matrix per project

The matrix lives at a fixed location inside the project’s design area:

.wai/projects/<project>/designs/matrix/
├── problem.md                     # A1: the decision being deliberated
├── criteria/                      # rows: one definition file per criterion
│   ├── 01-impact.md
│   └── 02-risk.md
├── approaches/                    # columns
│   ├── 01-status-quo/             # always first
│   │   ├── _description.md
│   │   ├── 01-impact/
│   │   │   ├── fact.md            # the aspect — facts, not judgment
│   │   │   └── red                # judgment marker
│   │   └── 02-risk/
│   │       └── fact.md            # no marker yet → not assessed
│   └── 02-event-sourcing/
│       └── ...
├── decision.md                    # current decision (written by `wai matrix decide`)
└── matrix.html                    # generated on demand, never committed

It is a standing surface, re-anchored by editing problem.md as new decisions arise, and it grows over the project’s lifetime — new approaches are born in it, new criteria appear as deliberation makes them salient.

A1: start with the problem

problem.md holds the answer to the methodology’s first question — what decision are you trying to make? It is rendered as the banner in matrix.html and shown by wai status during the design phase. Re-anchor the matrix for a new decision by rewriting it.

The cell: fact and judgment separated

Each cell holds exactly two things:

  • fact.md — the aspect: how the approach meets the criterion. Facts, not judgment. “Audit trail exists by construction”, not “this is good”.
  • One marker file — empty, named neutral, green, yellow, or red. The judgment lives in exactly one place, and the encoding cannot be malformed: there is no syntax to break.

Completeness is defined by the fact, never the color. A cell with a missing or empty fact.md is not yet assessed — the renderer shows a gray placeholder, never a judgment color. neutral is a legitimate judgment (“clear, nothing special”), distinct from incomplete.

Filling a cell is two trivial file operations — this is the primary editing path, for humans and agents alike:

# fill a cell
echo "Audit trail exists by construction." > approaches/02-event-sourcing/01-impact/fact.md
touch approaches/02-event-sourcing/01-impact/green
# change a judgment
rm approaches/02-event-sourcing/01-impact/green
touch approaches/02-event-sourcing/01-impact/yellow

The ? convention: write a line starting with ? anywhere in the matrix to record an open question — wai search "?" finds them. Keep criteria statements; questions stay searchable.

Commands

The CLI exists only where one logical action spans many directories:

CommandBehavior
wai matrix init "<problem>"Scaffold problem.md, criteria/, approaches/01-status-quo/, decision.md template
wai matrix criterion add <name>Add criteria/NN-name.md + a cell dir in every approach
wai matrix approach add <name>Add approaches/NN-name/ with _description.md + empty cells for all criteria
wai matrix decide <approach> "<rationale>"Write decision.md + scaffold a design doc with a decision-time snapshot
wai matrix lintStructural errors + methodology warnings
wai matrix renderGenerate self-contained matrix.html

There is deliberately no wai matrix set: filling a cell is writing one file and touching one marker — sugar over trivial file I/O would only obscure the model.

Linting: structure is enforced, methodology is taught

wai matrix lint reports structural errors (non-zero exit): rectangularity, exactly one known marker per filled cell, no empty fact.md, status-quo-first.

Methodology warnings never block — each maps 1:1 to a tip from the source talks: all-green column (“are you rationalizing?”), undistinguished columns (likely a missing criterion), judgment-in-text, link-only cells, criteria phrased as questions, status quo with no red cell (Miller: show what’s wrong with today), deciding with unfilled cells, empty problem.md, and stale decisions (matrix edited after deciding).

The design → plan gate

Leaving the design phase requires the matrix to be decided and current: decision.md names an existing approach, and no file under approaches/ or criteria/ is newer than the decision timestamp recorded inside decision.md (content timestamps survive clone/rebase; mtimes don’t). Edited-after-decision blocks the transition with a self-healing message; ambiguous timestamps (e.g. a fresh clone, where everything shares the checkout time) downgrade to a warning, never a false block. Projects without a matrix are never gated.

Deciding

wai matrix decide "02-event-sourcing" "Best audit story at acceptable ops cost." does two things:

  1. Writes decision.md — approach, rationale, UTC timestamp, design-doc pointer. A scaffolded decision.md names no approach, so a bare init never passes the gate.
  2. Scaffolds designs/<date>-<slug>.md with standard frontmatter and a decision-time snapshot of the winning column’s facts. The matrix keeps growing; the design doc records what was true when decided.

The human/agent then fleshes out the design doc’s narrative — rationale, trade-offs — with the matrix one wai search away.

Adoption

The matrix is opt-in: nothing exists until wai matrix init. Projects that don’t use it behave exactly as before — no gating, no status output, no handoff sections.

Plugin System

Why plugins? Every team uses different tools — issue trackers, spec managers, version control. Building all of these into wai would make it opinionated and brittle. Instead, wai auto-detects what’s already in your workspace and integrates through a plugin architecture. You get seamless context (git status in handoffs, open issues in wai status) without wai prescribing your toolchain.

Wai auto-detects and integrates with external tools through a flexible plugin architecture.

Built-in Plugins

Beads

  • Detection: .beads/ directory
  • Description: Issue tracking with tasks, bugs, and dependencies
  • Commands: list, show, ready (read-only)
  • Hooks:
    • on_handoff_generate — Includes open issues in handoffs
    • on_status — Shows issue statistics

Example:

wai beads list        # Pass-through to beads plugin
wai beads ready       # Show issues ready to work on

Git

  • Detection: .git/ directory
  • Description: Version control integration
  • Hooks:
    • on_handoff_generate — Includes git status
    • on_status — Shows recent commits

OpenSpec

  • Detection: openspec/ directory
  • Description: Specification and change management
  • Integration: Status display shows active specs and change proposals with progress

Plugin Commands

Pass-through commands allow direct access to plugin functionality:

wai <plugin> <command> [args...]

Example:

wai beads list --status=open
wai beads show beads-123

Plugin Hooks

Plugins can inject context into wai workflows through hooks:

Available Hooks

HookWhen TriggeredPurpose
on_statuswai status calledAdd plugin context to status output
on_handoff_generatewai handoff create calledInclude plugin state in handoffs
on_phase_transitionPhase changesReact to project phase changes

Custom Plugins

Wai scans the .wai/plugins/ directory at your workspace root for any files with a .toml extension.

Example Plugin Definition

name = "my-tool"
description = "Custom tool integration"

[detector]
type = "directory"
path = ".mytool"   # Relative to workspace root

[[commands]]
name = "list"
description = "List items"
passthrough = "mytool list"
read_only = true

[[commands]]
name = "sync"
description = "Sync data"
passthrough = "mytool sync"
read_only = false

[hooks.on_status]
command = "mytool stats"
inject_as = "mytool_stats"

[hooks.on_handoff_generate]
command = "mytool status --format=summary"
inject_as = "mytool_context"

Detector Types

  • directory — Detect by directory presence. The path attribute is relative to the workspace root.
  • file — Detect by file presence. The path attribute is relative to the workspace root.
  • command — Detect by command availability. The path (or command) attribute is the shell command to execute (must return exit code 0).

Note: For the command detector in TOML, use the path field to specify the command to run (e.g. path = "mytool --version").

Command Attributes

  • name — Command name (e.g., list)
  • description — Human-readable description
  • command — Shell command to execute
  • read_only — Whether command modifies state (respects --safe mode)

Managing Plugins

List All Plugins

wai plugin list

Shows:

  • Plugin name and description
  • Detection status (detected/not found)
  • Available commands
  • Configured hooks

Enable/Disable Plugins

wai plugin enable my-tool
wai plugin disable my-tool

Note: Built-in plugins cannot be disabled.

JSON Output

Get structured plugin information:

wai plugin list --json

Returns:

{
  "plugins": [
    {
      "name": "beads",
      "description": "Issue tracking",
      "detected": true,
      "commands": ["list", "show", "ready"],
      "hooks": ["on_status", "on_handoff_generate"]
    }
  ]
}

Safe Mode

Plugin commands that modify state are blocked in safe mode:

wai beads list --safe         # OK - read-only
wai my-tool sync --safe       # Blocked if not read_only

Plugin Troubleshooting

Plugin Not Detected

Symptom: wai plugin list shows plugin as “not detected”

Common Causes:

  1. Detector file/directory missing

    # Check if detector path exists
    ls -la .beads/     # for beads plugin
    ls -la .git/       # for git plugin
    ls -la openspec/   # for openspec plugin
    
  2. Plugin tool not installed

    # Verify tool is available
    which beads
    which mytool
    
    # Install if missing
    cargo install beads
    
  3. Custom plugin TOML syntax error

    # Validate TOML
    cat .wai/plugins/my-plugin.toml
    
    # Check for common issues:
    # - Missing required fields (name, description, detector)
    # - Wrong detector type (must be: directory, file, or command)
    

Plugin Command Fails

Symptom: wai <plugin> <command> returns error

Debugging Steps:

# 1. Verify plugin is detected
wai plugin list | grep myplugin

# 2. Test command directly
mytool command args

# 3. Check command definition
wai plugin list --json | jq '.plugins[] | select(.name=="myplugin") | .commands'

# 4. Verify passthrough is in PATH
which mytool

# 5. Check for command output issues
mytool command 2>&1 | head

Custom Plugin Not Loading

Symptom: Custom plugin in .wai/plugins/ doesn’t appear

Checklist:

  • ✅ File has .toml extension
  • ✅ File is in .wai/plugins/ directory
  • ✅ TOML syntax is valid
  • ✅ Required fields present: name, description, detector
  • ✅ Detector path exists (for directory/file detectors)

Example Valid Plugin:

name = "example-tool"
description = "Example tool integration"

[detector]
type = "directory"
path = ".example"

[[commands]]
name = "status"
description = "Show status"
passthrough = "example status"
read_only = true

[[commands]]
name = "sync"
description = "Sync data"
passthrough = "example sync"
read_only = false

[hooks.on_status]
command = "example stats"
inject_as = "example_stats"

Hook Output Not Showing

Symptom: Plugin hooks defined but output doesn’t appear in status/handoffs

Debugging:

# 1. Check if plugin is detected
wai plugin list | grep myplugin

# 2. Verify hook command runs successfully
example stats  # Run hook command directly

# 3. Check hook definition
wai plugin list --json | jq '.plugins[] | select(.name=="example") | .hooks'

# 4. Look for hook output in status
wai status -v  # Verbose mode shows more detail

# 5. Check JSON output for hook_outputs
wai status --json | jq '.hook_outputs'

Permission Errors

Symptom: “Permission denied” when running plugin commands

Solutions:

# 1. Check plugin tool permissions
ls -l $(which mytool)

# 2. Verify tool is executable
chmod +x $(which mytool)

# 3. For safe mode issues, check read_only flag
wai plugin list --json | jq '.plugins[] | select(.name=="myplugin") | .commands[] | {name, read_only}'

Detector Not Working

Symptom: Plugin should be detected but shows as “not detected”

Detector Types and Requirements:

Directory Detector:

[detector]
type = "directory"
path = ".mytool"  # Directory must exist at workspace root

Check: ls -la .mytool/

File Detector:

[detector]
type = "file"
path = "mytool.config"  # File must exist at workspace root

Check: ls -la mytool.config

Command Detector:

[detector]
type = "command"
path = "mytool --version"  # Command must exit 0 and be in PATH

Check: which mytool && mytool --version

Getting Help

If you can’t resolve plugin issues:

# Create debug report
{
  echo "=== Plugin List ==="
  wai plugin list

  echo -e "\n=== Plugin JSON ==="
  wai plugin list --json

  echo -e "\n=== Custom Plugins ==="
  ls -la .wai/plugins/

  echo -e "\n=== Doctor Check ==="
  wai doctor
} > plugin-debug.txt

File an issue at https://github.com/charly-vibes/wai/issues with plugin-debug.txt attached.

See Also

Pipelines

Why pipelines? Some tasks are too complex or error-prone for a single pass. When an AI agent tries to do research, validation, and synthesis all at once, errors compound — context drifts, assumptions go unchecked, and the final output is built on shaky foundations. Pipelines break these tasks into discrete steps with validation gates between them, so each step is verified before the next one begins.

Pipelines are ordered, multi-step workflows that guide you through a structured process. Each step provides a prompt with deliverables and instructions, and you advance through steps sequentially.

Pipelines are useful when a task is too large or too error-prone for a single pass — for example, research that spans many subtasks, or a process where intermediate validation prevents compounding errors. If your work fits naturally into wai’s project phases without extra structure, you probably don’t need a pipeline.

Prerequisite: an initialized wai workspace (wai init). See Quick Start.

Overview

wai pipeline list                                # List available pipelines
wai pipeline show <name>                         # View steps and gates
wai pipeline start <name> --topic="<objective>"  # Start a run
wai pipeline next                                # Mark current step done, move to next

Pipelines are defined as TOML files in .wai/resources/pipelines/. When you run wai init, built-in templates are installed into this directory. You can modify your local copy without affecting the built-in defaults.

Creating Custom Pipelines

Pipelines are TOML files with a simple structure:

[pipeline]
name = "my-workflow"
description = "What this pipeline does"

[pipeline.metadata]
when = "When to use this pipeline"
skills = ["skill-a", "skill-b"]    # Optional: skills used by steps

[[steps]]
id = "step-one"
prompt = """
{topic}: Instructions for this step.

Deliverables:
- What to produce

Record findings: `wai add research "..."`
Advance: `wai pipeline next`
"""

[[steps]]
id = "step-two"
prompt = """
{topic}: Instructions for this step.
"""

The {topic} placeholder is replaced with the --topic value when the run starts.

Place custom pipelines in .wai/resources/pipelines/ and run wai init to refresh the managed block in CLAUDE.md.

Pipeline Gates

Steps can optionally define gates — conditions that must be satisfied before advancing. Gates enforce validation at step boundaries and are checked when you run wai pipeline next.

Gate tiers

Gates evaluate in order. The first failure blocks advancement — wai pipeline next prints the failing gate and what’s missing, and blocks until the condition is satisfied.

TierTypePurpose
1StructuralVerify the step produced expected outputs (artifact count/type)
2ProceduralVerify the validation process was followed (reviews exist, verdicts pass)
3aOracleDomain-specific machine-verifiable checks (user-written scripts)
3bApprovalForced human checkpoint

Configuring gates in TOML

Gate sections go inside the [[steps]] entry they belong to. Here is a complete step with all four gate tiers:

[[steps]]
id = "generate-validate-accrue"
prompt = """
{topic}: Execute subtasks with intermediate validation.
...
"""

[steps.gate.structural]
min_artifacts = 1
types = ["research"]

[steps.gate.procedural]
require_review = true
review_verdict = "pass"
max_critical = 0
max_high = 0

[[steps.gate.oracles]]
name = "dimensional-analysis"
description = "Verify dimensional consistency"
timeout = 300

[steps.gate.approval]
required = true
message = "Review all accrued artifacts before advancing"

Oracle scripts

Oracles are user-written scripts that perform domain-specific checks:

  • Location: .wai/resources/oracles/<name>.sh or .wai/resources/oracles/<name>.py
  • Contract: receives the artifact path as an argument, exits 0 on pass, writes failure reason to stderr
  • Timeout: default 30 seconds, configurable per oracle

Gate commands

wai pipeline gates <name>              # Show gate requirements per step
wai pipeline check                     # Dry-run gates without advancing
wai pipeline approve                   # Human approval for current step
wai pipeline validate <name>           # Validate pipeline TOML and gate config

Disclosing gate bypasses

Hooks cannot self-record a --no-verify bypass — the flag skips them. If you bypass a git hook while a pipeline run is active, record the bypass discipline at bypass time:

wai pipeline bypass "skipped pre-push hook: flaky timing test wai-z25x"

The command appends a timestamped entry (timestamp + reason) to the active run’s state ledger and wai pipeline status surfaces the bypass count and the most recent reason. Bypass telemetry is a ledger, not enforcement — it makes disclosed bypasses pokeable instead of invisible. With no active run the command is a silent no-op (nothing recorded, no error).

Built-in: Scientific Research Pipeline

The scientific-research pipeline is designed for frontier-level theoretical or computational research where an LLM generates mathematical derivations, proofs, or data analysis across many subtasks and a human supervisor needs systematic validation.

It addresses three common failure modes in AI-assisted research:

  • Context drift — the research gradually shifts away from the original problem
  • Sycophancy — the model confirms what it thinks you want rather than what’s true
  • Hallucinated data smoothing — gaps are filled with plausible but unverified claims

Starting a run

wai pipeline start scientific-research --topic="Your research objective here"

This creates a pipeline run and places you at step 1. Each step provides a detailed prompt explaining what to do, what deliverables to produce, and how to record them.

Steps

The pipeline has five framing steps (Describe, Diagnose, Delimit, Direction, Decompose), a core execution loop (Generate-Validate-Accrue), and two closing steps (Synthesize, Final Review).

Every step ends with recording artifacts and advancing:

wai add research "findings..."   # or design/plan as appropriate
wai pipeline next

1. Describe

Capture the research problem neutrally. Focus on observed symptoms, signals, metrics, boundary conditions, and known constraints. Do not propose solutions or hypotheses yet.

Deliverables: neutral problem statement, known constraints, data sources, success criteria.

2. Diagnose

Generate and test competing hypotheses — at least three. For each, state its predictions and identify confirming/refuting evidence. Use negative progress (ruling out false leads) rather than converging too early.

Deliverables: hypothesis map, evidence for/against each, eliminated paths.

3. Delimit

Define explicit boundaries and scope. This is the primary defense against context drift. Document what is in scope, what is explicitly out, constraints, and assumptions taken as given.

Deliverables: scope document (referenced throughout remaining steps).

4. Direction

Select the research approach using a decision matrix. Compare surviving hypotheses against feasibility, rigor, falsifiability, and compute cost. Include a null hypothesis baseline. Document what would cause you to revisit the decision.

Deliverables: decision matrix, selected approach with justification.

5. Decompose

Break the selected approach into a master task tree of discrete, independently verifiable subtasks. Each subtask gets a unique ID, input dependencies, expected output format, and validation criteria.

Deliverables: task tree (created as beads issues with dependencies).

bd create --title="<subtask>" --description="<details>" --type=task
bd dep add <blocked> <blocker>
wai add plan "task decomposition..."

6. Generate-Validate-Accrue (core loop)

Execute each subtask from the task tree. For every subtask:

  1. Generate — produce the derivation, code, analysis, or argument
  2. Validate — run /ro5 (Rule of 5, a wai review skill) on the artifact:
    • Accuracy — verify facts, citations, mathematical correctness
    • Completeness — check for skipped steps, missing edge cases
    • Clarity — ensure unambiguous terminology and notation
    • Actionability — confirm output is usable by the next subtask
    • Integration — check consistency with all previously accrued artifacts
  3. Accrue — if validation passes, commit the artifact:
    wai add research "<subtask findings>"
    bd close <subtask-id>
    

Critical rules:

  • Do not skip validation. Do not accrue unvalidated artifacts.
  • If a subtask contradicts a previously accrued artifact, halt and surface the contradiction for human review.
  • Fix and re-validate before accruing if validation fails.

7. Synthesize

Assemble the final output from all accrued artifacts. Check for logical flow, notation consistency, gap detection, and whether boundary conditions from the delimit step are satisfied.

Deliverables: coherent final output (paper, report, derivation).

8. Final Review

Run /ro5 on the complete synthesized output. Verify:

  • The result satisfies success criteria from step 1
  • The scope document from step 3 was respected
  • The decision matrix from step 4 is still valid
  • All beads subtasks are closed

If critical issues are found, route back to step 6 for the specific subtask that introduced the error.

Visual overview

┌─────────┐   ┌───────────┐   ┌─────────┐   ┌───────────┐   ┌───────────┐
│ Describe │──▶│ Diagnose  │──▶│ Delimit │──▶│ Direction │──▶│ Decompose │
│          │   │           │   │         │   │           │   │           │
│ Problem  │   │ Hypotheses│   │ Scope   │   │ Decision  │   │ Task tree │
└─────────┘   └───────────┘   └─────────┘   └───────────┘   └─────┬─────┘
                                                                   │
                                                                   ▼
┌──────────────┐   ┌─────────────┐   ┌─────────────────────────────────┐
│ Final Review │◀──│ Synthesize  │◀──│ Generate → Validate → Accrue    │
│              │   │             │   │         (repeat per subtask)     │
│ Quality gate │   │ Assembly    │   └─────────────────────────────────┘
└──────────────┘   └─────────────┘

Built-in: TDD + Rule of 5 Pipeline

The tdd-ro5 pipeline is designed for autonomous implementation work where an agent should keep moving without routine confirmations, but must prove correctness before shipping.

Start it with:

wai pipeline start tdd-ro5 --topic="Your feature or bug fix"

The pipeline uses nine gated steps:

  1. Orient — run wai prime, wai status, available work discovery, and wai search before editing.
  2. Plan — record desired behavior, out of scope, test cases, and verification commands.
  3. Red — write failing tests and record expected failure evidence.
  4. Green — implement the minimum code and pass relevant tests.
  5. Refactor — tidy safely while tests remain green.
  6. RO5U Review — run Universal Rule of 5 review and record findings without fixing yet.
  7. Fix Review — address review findings and keep tests green.
  8. Quality Ledger — record Changed, Verified, Review, Risks, and Next.
  9. Ship Close — inspect the diff, update linked workflow tools, commit atomically, and run wai close.

Review and fixing are intentionally separate steps: the review step observes and records evidence; the fix step applies bounded remediation. Push/release/deploy remains outside the default pipeline unless explicitly authorized by project policy or user instruction.

Built-in: Epic-Orchestrator Pipeline

The epic-orchestrator pipeline is designed for epic execution where a lead agent orchestrates only — one ready child ticket per run — and subagents do the implementation. It encodes the orchestrator + subagents pattern as enforceable steps instead of hoping agents follow prose: the lead’s job is claim → gates → brief → spawn → verify → ship → STOP, never inline implementation.

Starting a run

wai pipeline start epic-orchestrator --topic="<child ticket id>"

Each run handles exactly one child ticket. The next ticket starts a fresh run — the loop ends in an explicit STOP at the ticket boundary and never chains past it.

Steps

  1. Claim — orient (wai prime, wai status, bd ready) and claim exactly one ready, unblocked child issue atomically (bd update <id> --claim). Write the per-ticket state file (see below).
  2. Gates — run the project’s pre-work quality gates and establish a green test-suite baseline so later failures are attributable to this change only. No implementation yet.
  3. Brief — write the subagent brief as a committed repo artifact at .wai/projects/<project>/briefs/<slug>.md, with mandatory ## Why (delegation rationale), ## Completion criteria (runnable commands only — exit 0 = done), and ## Spawn model (model plus a context ceiling expressed as ≤ N% of the actual model window; fixed token counts are invalid). Commit the brief before spawning so the subagent starts from a clean tree.
  4. Spawn — spawn a named, resumable subagent session for the brief, streaming output to a known log path the orchestrator can tail. Spawn is a named session (retry is a fresh -retry-suffixed session, never an in-place resume).
  5. Verify — verify before trust. With a second model family configured, a read-only verifier session (subagent:<ticket>:verify) cross-checks the implementor’s report against reality: commits vs git log, report claims vs ticket-tracker state.
  6. Ship — inspect the diff, commit atomically, update the ticket tracker and openspec tasks. Push only when project policy or user instruction explicitly authorizes it.
  7. STOP — hard stop at the ticket boundary. Record the final checkpoint and start the next ticket as a new run.

Every step ends with recording an artifact (wai add), appending a step id + sha checkpoint to the state file, and wai pipeline next.

Per-ticket state file

The claim step creates a durable state file at .wai/projects/<project>/runs/<ticket>.state, e.g.:

ticket: wai-hr0w
branch: main
brief_path: .wai/projects/<project>/briefs/<slug>.md
step_history: []
- claim @ 52c6de8604ad86f87c4a6a3defe4800a23b3b1bf
- gates @ 52c6de8604ad86f87c4a6a3defe4800a23b3b1bf
- brief @ 939dae26e2b7aefa0e4200d09a41c4259029d4b4

It records the ticket id, the branch, the brief path (empty until the brief step), and a step history of step id + sha checkpoints appended before each advance.

Retry and drift: if the state file already exists at claim, the retry reads it and runs a drift check before resuming — it refuses to resume when HEAD advanced without a completed step accounting for the advance. A mid-run advance is expected (the implementor commits) and is never flagged as drift. Retries resume from the last completed gate, not from the beginning.

Refusal conditions:

  • Spawn refuses to run without a committed brief at its recorded path.
  • Spawn refuses to run without the state file — the spawn must be resumable through it.
  • The retry-entry drift check refuses to resume a state file whose HEAD advanced without an accounting step.

Single-model degradation

The primary verify path spawns a verifier from a different model family. Single-model setups degrade to lead-side checks instead of a spawned verifier: record the branch head at verify entry, diff git log/git diff against the report, run the repo’s test suite, and check the ticket tracker. This degradation is non-blocking — the run may advance once the lead-side checks pass. A contradiction between the report and reality always blocks the run, degraded or not.

Oracle requirement

The verify and ship steps carry a tests-pass oracle gate, and the verify step additionally carries a verify-evidence oracle: a review artifact may record CONFIRM only when it cites the artifacts it read and includes fresh test-run output — evidence gaps must be recorded as REVIEW_REQUIRED. wai pipeline init epic-orchestrator ships both scripts (see Oracle scripts) to .wai/resources/oracles/, so the gates resolve out of the box; if you remove one, advancing past those steps fails.

Provenance: the evidence base and design proposal for this pipeline live in the orchestrator-tooling project (~/.wai/projects/orchestrator-tooling/); the openspec change is openspec/changes/add-epic-orchestrator-template/.

Artifact Locking

Steps can declare lock = true to freeze their artifacts with SHA-256 hashes when you advance past them. This prevents accidental modification of validated work — once a step’s artifacts are locked, any change will be caught by wai pipeline verify or wai doctor.

How it works

When a step with lock = true completes (via wai pipeline next), wai computes a SHA-256 hash of each artifact tagged with that step and writes a .lock sidecar file alongside it. The sidecar records the hash, run ID, step ID, and timestamp.

You can also lock manually at any time:

wai pipeline lock      # Lock current step's artifacts now

Verifying integrity

wai pipeline verify    # Check all locked artifacts across the workspace

Verify reports:

  • Missing artifacts — a .lock file exists but the artifact was deleted
  • Hash mismatches — an artifact was modified after locking

wai doctor also checks artifact lock integrity as part of its health checks.

Correcting locked artifacts

Locked artifacts should not be edited directly. Instead, create an addendum — a new artifact that references the original:

wai add research --corrects=<path-to-locked-artifact> "correction details"

This preserves the audit trail: the original artifact stays intact and the addendum records what changed and why.

Configuring lock in pipeline TOML

Add lock = true to any step definition:

[[steps]]
id = "synthesize"
lock = true
prompt = """
{topic}: Assemble findings into a coherent output.
"""

Command reference

CommandDescription
wai pipeline listList all available pipelines
wai pipeline show <name>View steps and gates for a pipeline
wai pipeline start <name> --topic="..."Start a new run
wai pipeline nextAdvance to the next step
wai pipeline currentReprint the active step
wai pipeline current --jsonEmit machine-readable active run context
wai pipeline statusAlias for machine-readable active run context
wai pipeline gates <name>Show gate requirements
wai pipeline checkDry-run gate evaluation
wai pipeline approveHuman approval for current step
wai pipeline validate <name>Validate pipeline TOML
wai pipeline lockLock current step’s artifacts (SHA-256)
wai pipeline verifyVerify integrity of all locked artifacts

See Also

Agent Config Sync

Why a single source of truth? When agent instructions live in multiple files (CLAUDE.md, .cursorrules, .gemini/), they inevitably drift apart. One tool gets the updated security rules, another doesn’t. Copy-pasting between configs is tedious and error-prone. Wai solves this by storing configs once and projecting them to each tool’s expected location — edit in one place, sync everywhere.

Wai maintains a single source of truth for agent configurations and syncs them to tool-specific locations using configurable projection strategies.

Directory Structure

Agent configs are stored in .wai/resources/agent-config/:

.wai/resources/agent-config/
├── .projections.yml          # Sync configuration
├── skills/                   # Agent skills
│   ├── code-review.md
│   └── commit.md
├── rules/                    # System rules
│   ├── security.md
│   └── style.md
└── context/                  # Context files
    └── project-context.md

Projection Strategies

Configure syncs in .wai/resources/agent-config/.projections.yml:

Creates target directory with symlinks (or copies on Windows) to source files.

Note on Windows: Windows doesn’t support symlinks in all configurations (requires Developer Mode or admin privileges). Wai automatically falls back to file copies when symlinks aren’t available.

Use when: Tools expect a directory structure with individual files.

projections:
  - strategy: symlink
    sources:
      - skills/
    target: .claude/skills/

Result:

  • .claude/skills/code-review.md → symlink to .wai/resources/agent-config/skills/code-review.md
  • .claude/skills/commit.md → symlink to .wai/resources/agent-config/skills/commit.md

2. Inline Strategy

Concatenates multiple source files into a single target file.

Use when: Tools expect a single configuration file (e.g., .cursorrules).

projections:
  - strategy: inline
    sources:
      - rules/base.md
      - rules/security.md
      - rules/style.md
    target: .cursorrules

Result:

<!-- AUTO-GENERATED FILE - DO NOT EDIT DIRECTLY -->
<!-- Source: .wai/resources/agent-config/rules/base.md -->

[content of base.md]

<!-- Source: .wai/resources/agent-config/rules/security.md -->

[content of security.md]

<!-- Source: .wai/resources/agent-config/rules/style.md -->

[content of style.md]

3. Reference Strategy

Creates a markdown file listing paths to source files.

Use when: Tools can follow references to external files.

projections:
  - strategy: reference
    sources:
      - context/
    target: .agents/context-refs.md

Result:

# Agent Context References

This file references agent context files managed by wai.

## Files

- .wai/resources/agent-config/context/project-context.md

Specialized Targets

Wai provides built-in specialized targets that handle complex tool-specific transformations automatically.

Claude Code (claude-code)

The claude-code target is a high-level projection that translates hierarchical skills into Claude Code custom slash commands.

Instead of manual file mapping, use the special target: claude-code:

projections:
  - target: claude-code

How it works:

  1. Source Discovery: It automatically scans .wai/resources/agent-config/skills/ for hierarchical directories (e.g., skills/git/commit/SKILL.md).
  2. Translation:
    • It translates the directory hierarchy into a human-readable skill name (e.g., git/commit → Git: Commit).
    • It updates the frontmatter of the destination file to match Claude Code’s expected format (including name, description, and category).
  3. Destination: Files are synced to .claude/commands/<category>/<action>.md.
  4. Smart Syncing: wai sync --status uses file modification times (mtime) to detect if Claude Code commands are out of date with your source skills.

Note: “Flat” skills (e.g., skills/my-skill/SKILL.md) are skipped by this target. Only hierarchical skills (e.g., skills/category/action/SKILL.md) are processed to ensure clean command grouping in Claude Code.

Configuration Format

Full .projections.yml example:

projections:
  # Symlink skills to Claude Code
  - strategy: symlink
    sources:
      - skills/
    target: .claude/skills/

  # Inline rules to Cursor
  - strategy: inline
    sources:
      - rules/base.md
      - rules/security.md
    target: .cursorrules

  # Reference context files
  - strategy: reference
    sources:
      - context/
    target: .gemini/context-refs.md

Commands

Check Sync Status

wai sync --status

Shows:

  • Current projections
  • Source files
  • Target status (in sync / out of sync)
  • Files that would be created/updated

Apply Sync

wai sync

Applies all configured projections:

  • Creates/updates symlinks
  • Regenerates inline files
  • Updates reference files

Managing Configs

Add New Config

wai config add skill my-skill.md

Copies my-skill.md to .wai/resources/agent-config/skills/my-skill.md.

List Configs

wai config list

Shows all configs organized by type (skills, rules, context).

Edit Config

wai config edit skills/my-skill.md

Opens config in $EDITOR (or $VISUAL, falls back to vi).

Import Existing Configs

wai import .claude/
wai import .cursorrules

Imports existing tool configs into wai’s single source of truth.

Workflow

  1. Add/Edit configs in .wai/resources/agent-config/
  2. Check status: wai sync --status
  3. Apply sync: wai sync
  4. Verify: wai doctor

Doctor Checks

The wai doctor command validates:

  • Projection configuration syntax
  • Source files exist
  • Target directories are writable
  • Symlinks are valid
  • Inline files match sources
  • Reference files are current

Auto-fix mode can repair common issues:

wai doctor --fix

Conflict Resolution

Important: Wai always overwrites target files during sync. The source files in .wai/resources/agent-config/ are the single source of truth.

What Happens When You Edit Synced Files

If you manually edit a synced target file (e.g., .cursorrules, .claude/skills/my-skill.md):

  1. Your changes will be overwritten the next time you run wai sync
  2. No warning is given - wai assumes sources are authoritative

Best Practices

✅ DO:

  • Edit files in .wai/resources/agent-config/
  • Use wai config edit skills/my-skill.md
  • Run wai sync --status before syncing to preview changes
  • Keep sources under version control

❌ DON’T:

  • Edit target files directly (.cursorrules, .claude/skills/, etc.)
  • Manually create files in target directories
  • Expect wai to merge changes from targets back to sources

Missing Source Files

If a source file listed in .projections.yml is missing:

  1. Sync behavior: wai sync will skip the missing file and continue with the remaining sources. For inline strategies, the output file will be generated without the missing content.
  2. Reporting: wai sync --status will not show a specific error, but the target may appear as “out of sync”.
  3. Diagnosis: Run wai doctor to identify exactly which source files are missing from your configuration.

Recovering Manual Edits

If you accidentally edited a target file:

# Copy your changes to a backup
cp .cursorrules my-changes-backup.md

# Check what the source contains
cat .wai/resources/agent-config/rules/*.md

# Manually merge your changes into the source files
wai config edit rules/base.md

# Re-sync to apply
wai sync

Migration Workflow

When importing from existing tool configs:

# Import existing configs (one-time)
wai import .cursorrules
wai import .claude/

# From now on, edit only in .wai/resources/agent-config/
wai config edit rules/imported-rules.md

# Sync to propagate changes
wai sync

Benefits

  • Single Source of Truth — Edit once, sync everywhere
  • Version Control — All configs tracked in .wai/
  • Consistency — Same configs across all tools
  • Flexibility — Different strategies for different tools
  • Auditability — Clear projection configuration
  • No Conflicts — Unidirectional sync prevents merge conflicts

See Also

Ubiquitous Language

Domain-driven design talks about a ubiquitous language — a shared vocabulary that developers and domain experts use consistently in code, conversations, and documentation. Without it, agents guess at terminology and hallucinate synonyms: is “order” the same as “purchase”? Does “customer” overlap with “user”? Is “shipment” the same as “delivery”?

Wai gives teams a first-class home for this vocabulary under .wai/resources/ubiquitous-language/.

The Directory Layout

.wai/resources/ubiquitous-language/
├── README.md              # navigation index (required)
├── shared.md              # cross-context terms (optional)
└── contexts/
    ├── orders.md
    ├── inventory.md
    └── billing.md

Three layers:

  • README.md — a lightweight index that describes the tree, lists available bounded contexts (self-contained parts of the domain with their own consistent terminology, e.g. Orders, Billing), and tells agents how to navigate it. This is the only file agents read by default.
  • shared.md — optional. Holds terms that are genuinely shared across multiple bounded contexts. Keep it short; most terms belong in a context file.
  • contexts/*.md — one file per bounded context. Each file records the preferred term, a concise definition, discouraged synonyms or anti-terms, and related terms. Each bounded context should be a single .md file directly under contexts/. Subdirectories and non-Markdown files are not currently recognized by wai way.

Getting Started

Create the directory and a minimal index:

mkdir -p .wai/resources/ubiquitous-language/contexts

Then write README.md as a short navigation guide:

# Ubiquitous Language

This directory contains domain terminology for this project.

## Bounded Contexts

- [Orders](contexts/orders.md) — fulfillment, line items, cancellation
- [Inventory](contexts/inventory.md) — SKUs, stock levels, reservations

## Usage

Read this file first. Open only the context file(s) relevant to your task.

Add a bounded-context file when you encounter ambiguous or domain-specific terms:

# Orders Context

## Order

**Definition:** A customer's confirmed intent to purchase one or more items.

**Anti-terms:** Do not use "cart" or "basket" — those refer to the pre-checkout state, not a confirmed order.

**Related:** Line Item, Fulfillment, Cancellation

Run wai way after setup to confirm the tree is fully configured.

Progressive Disclosure

Agents work better when they load terminology on demand rather than dumping an entire glossary into context. The layout is designed for this:

  1. Agent reads README.md to learn what contexts exist.
  2. Agent opens only the bounded-context file(s) relevant to the current task.
  3. Agent ignores unrelated context files entirely.

The managed block injection (see below) is what makes agents aware of this pattern — the directory layout alone is not enough. Running wai sync is the step that teaches agents to navigate it correctly.

This matters in large codebases with many domains — loading every term file wastes context and increases noise.

wai way Detection

wai way checks the state of your ubiquitous-language tree and surfaces it alongside other project health signals:

StateResult
README.md + at least one contexts/*.mdPASS — fully configured
README.md + shared.md, no context filesINFO — valid skeleton, add context files
README.md onlyINFO — needs bounded-context files
Directory exists, no README.mdINFO — index required first
Directory absentINFO — not yet set up, with suggestion

Run wai way to see the result alongside other project health checks.

Managed Block Injection

When wai sync regenerates your CLAUDE.md, AGENTS.md, or .wai/AGENTS.md managed blocks, it checks whether README.md exists. If it does, it injects a usage note:

## Ubiquitous Language

If `.wai/resources/ubiquitous-language/README.md` exists, read it first as the
navigation index, then open only the bounded-context files relevant to the task.
Avoid loading every terminology file unless the work truly spans multiple contexts.

Every agent reading your CLAUDE.md will automatically know where the vocabulary lives and how to use it without you having to explain it in each session prompt.

Maintenance Workflow

Use the ubiquitous-language skill template to scaffold a skill that keeps the tree up to date:

wai add skill update-terminology --template ubiquitous-language

The generated skill guides an agent to:

  1. Search existing artifacts and code for domain terminology.
  2. Identify the appropriate bounded context for each term.
  3. Update README.md, shared.md, or the relevant contexts/*.md file.
  4. Prefer incremental edits over rewriting the whole tree.

Run the skill whenever new domain concepts emerge or existing terms need clarification. Invoke it directly with wai skill run update-terminology or by referencing the generated SKILL.md in your agent prompt.

See Also

  • wai way — project health check command that detects the ubiquitous-language tree state
  • Managed Blocks — how wai sync injects guidance into CLAUDE.md and AGENTS.md
  • wai add skill — scaffold skill templates including ubiquitous-language

Toolchain Synergy

Wai is the suite orchestrator for the full charly-vibes toolchain — eight tools that together cover the complete lifecycle from proposal to implementation to archival. Each tool owns a distinct concern and is detected automatically by its on-disk marker:

ToolOwnsDetection SignalQuestion it answers
waiReasoning and context.wai/Why was this decision made?
bd (beads)Tasks and work items.beads/What needs to be done?
openspecSpecifications and proposalsopenspec/What should the system look like?
pretenderStructural code quality (AST linting)pretender.tomlDoes the code match our rules?
dontDecision-logged conventions.dont/What have we agreed not to do?
espectacularSpec-to-test correspondence.espectacular/Does the test match the spec?
testarudaTest harness & property testingtestaruda.tomlIs the behavior correct?
vampiro / crua / livinSpec-stage static analysis (planned)TBDDoes the design hold up under analysis?

All tools live under the charly-vibes GitHub organisation except:

When to Use What

I need to…Use
Record why I chose approach X over Ywai add research "..."
Track a bug or taskbd create --title="..."
Propose a system change with requirementsopenspec create <id>
Lint code for structural qualitypretender check .
Enforce a team convention with a decision logdont define
Verify spec-to-test correspondenceah check (espectacular)
Run property or harness teststestaruda check
Resume where I left offwai prime
Find available workbd ready
Validate a proposal is completeopenspec validate --strict
Search past decisionswai search "..."
Close a completed taskbd close <id>
Archive a deployed changeopenspec archive <id>

How They Integrate

All tools connect through wai’s plugin system, which auto-detects each tool by its on-disk marker:

  • beads — detected when .beads/ exists. Open issue counts appear in wai status, and wai handoff create includes issue context in handoff documents.
  • openspec — detected when openspec/ exists. Active change proposals and their progress appear in wai status.
  • pretender — detected when pretender.toml exists. Wai can help bootstrap its config via wai way.
  • dont — detected when .dont/ exists. Dont managed blocks in AGENTS.md are refreshed by wai sync.
  • espectacular — detected when .espectacular/ exists. Espectacular signals (spec-test gaps) are surfaced in wai status.
  • testaruda — detected when testaruda.toml exists. Test harness state is reported in wai status.
  • vampiro / crua / livin — detection signals to be defined as the tools ship (expected: vampiro.toml, crua.toml, livin.toml or equivalent config files). Currently spec-stage only — presence is tracked via their spec documents (e.g. crua-ears-spec.md, vampiro-ears-spec.md). The trio’s state will appear in wai status once detected.

Cross-references tie them together: beads tickets reference openspec tasks (e.g., add-why-command:7.1 in the description), and completing a beads ticket means checking the box in the openspec tasks.md. Wai’s wai doctor --suite will eventually validate suite-wide consistency (see wai-bdqw.8).

Detection is additive and optional — each tool works independently, but when multiple are present wai becomes the unified dashboard.

Worked Example: Adding a Feature

Here’s how a ticket flows through the core trio (wai + beads + openspec):

# 1. Propose the change in openspec
openspec create add-search-filters
# Edit the spec: requirements, acceptance criteria, task breakdown

# 2. Create beads tickets for the implementation tasks
bd create --title="Add --tag flag to search" --description="add-search-filters:3.1"
bd create --title="Add --type flag to search" --description="add-search-filters:3.2"

# 3. Research the approach in wai
wai add research "Evaluated regex vs glob for tag matching — chose glob for simplicity"

# 4. Work the ticket
bd update wai-abc1 --status in_progress
wai add design "Tags stored in YAML frontmatter, filtered at search time"

# 5. Close the loop
bd close wai-abc1
# Check [x] for task 3.1 in openspec's tasks.md

With the suite tools integrated, the workflow extends further:

# Enforce code quality conventions
dont define "No unwrap() in library code"

# Verify spec-to-test coverage before merging
ah check       # espectacular — does the test match the spec?
testaruda check  # property-based test coverage

# Lint for structural quality
pretender check .

What You Lose by Skipping One

  • Without wai: Tasks get done, but nobody remembers why decisions were made. Six months later, the code is a black box.
  • Without beads: Reasoning is captured, but there’s no task decomposition, no dependency tracking, and no way to find available work.
  • Without openspec: Changes happen ad hoc — no requirements, no acceptance criteria, no validation that the system matches the spec.
  • Without pretender: Code quality standards are enforced by human review alone — slower, more inconsistent, and harder to enforce in CI.
  • Without dont: Conventions live in READMEs or Slack — unenforceable and easy to forget.
  • Without espectacular: Specs and tests drift independently; no automated signal that they disagree.
  • Without testaruda: Property-based and harness testing must be set up manually, with no unified test dashboard.
  • Without vampiro/crua/livin (planned): Spec-stage analysis must be done manually or deferred until implementation.

Each tool is optional. Wai works fine alone. But together, the full suite covers the entire lifecycle — from proposal through implementation, quality assurance, and archival.

See also: Suite Conventions for canonical policies on edition, license, version scheme, and justfile setup.

Suite Conventions

This document defines the canonical policies for the charly-vibes tool suite. It covers the infrastructure-level conventions (edition, license, versioning, justfile setup) that every suite tool should follow.

Design principles, verb grammar, flag consistency, error patterns, and AIX artefacts are documented in the genesis tool-craft playbook.

Current State vs Policy

Unless a tool documents a deliberate deviation below, it SHOULD conform to the canonical policy. Deviations are tracked and converging through the wai-bdqw.6 task.


1. Rust Edition

Canonical: 2024 (the latest stable edition as of 2026).

ToolCurrentStatus
wai2024✅
genesis2024✅
dont2024✅
pretender2021🎯 update to 2024
espectacular2021🎯 update to 2024
testaruda2021🎯 update to 2024
vampiro / crua / livinTBD🎯 start with 2024

Rationale: 2024 adds unsafe attributes in scope, if let chains without nesting, and impl Trait in RPIT — all useful patterns in the suite’s codebase. The two-cycle lag policy means tools on 2021 should migrate before the next edition.


2. License

Canonical: Apache-2.0.

ToolCurrentStatus
pretenderApache-2.0✅
dontApache-2.0✅
espectacularApache-2.0✅
testarudaApache-2.0✅
genesisApache-2.0✅
vampiro / crua / livinApache-2.0 (vampiro)✅ planned
waiMIT⚠️ deliberate deviation

Rationale: Apache 2.0 is the suite standard — it provides express patent grant and is the de-facto standard for Rust open-source CLI tools. Wai uses MIT as a deliberate choice (permissive, no notice requirement in binary distributions). A future suite MAY dual-license or converge on a single license; this is not blocked on the current state.


3. Version Scheme

Canonical: Semantic Versioning (SemVer) 0.x.y or MAJOR.MINOR.PATCH.

ToolCurrentStatus
pretender0.3.1✅ SemVer
dont0.2.2✅ SemVer
espectacular0.3.0✅ SemVer
testaruda0.2.4✅ SemVer
genesis0.2.0✅ SemVer
vampiro / crua / livinTBD🎯 start with 0.1.0
wai2026.7.16 (CalVer)⚠️ deliberate deviation

Rationale: crates.io requires SemVer for crate dependencies, and every CLI tool in the suite ships as a crate. Wai uses CalVer because its releases are coupled to the project timeline (weekly-ish), not to API stability contracts — the wai binary is never depended on as a library. The suite standard is SemVer; wai’s CalVer is a documented outlier.

Convention: Tools at 0.x.y MAY bump minor (0.x+1.0) for breaking changes until 1.0.0. Once stable, follow SemVer strictly.


4. Just Recipes

Canonical recipe set (every tool ships these four):

RecipePurposeOutput
defaultBuild + test (or --list if build/test not applicable)just
buildCompile the tooljust build
testRun the test suitejust test
validateFull quality gate (clippy + test + fmt)just validate

Optional recipes (tool-specific):

RecipePurposeExamples
installInstall the toolcargo install --path .
publishRelease to crates.iocargo publish
docsBuild documentationmdbook build docs
prime / statusOrchestrator workflowswai, dont, espectacular

Canonical recipe NOT to use: ah (testaruda uses this for its test runner — rename to test for consistency).

TooldefaultbuildtestvalidateStatus
waibuild+test✅✅✅✅
pretender--list✅✅✅✅
dont--list✅✅✅✅
espectacular--list✅✅✅✅
testaruda--list✅✅ (as ah)❌🎯 rename ah → test, add validate
vampiro / crua / livinbuild+test✅✅✅🎯 start aligned

5. Justfile Shell

Canonical:

set shell := ["bash", "-uc"]

The -u flag treats unset variables as errors, preventing silent failures in recipe pipelines. The -c flag is required by just for shell execution.

Toolset shellStatus
wai["bash", "-uc"]✅
genesis["bash", "-uc"]✅
vampiro["bash", "-uc"]✅ planned
crua["bash", "-uc"]✅ planned
livin["bash", "-uc"]✅ planned
dont["bash", "-cu"]🎯 add -u
pretenderabsent🎯 add set shell
espectacularabsent🎯 add set shell
testarudaabsent🎯 add set shell

6. Default Just Recipe

Canonical: just runs build + test (not --list).

A fresh clone should be buildable with a single just command. Using --list as default means the developer must look up the recipe name before building, which is friction for new contributors.

ToolDefaultStatus
waibuild test✅
genesisbuild test✅
vampirobuild🎯 add test
cruabuild🎯 add test
livinbuild🎯 add test
pretender--list🎯 change to build test
dont--list🎯 change to build test
espectacular--list🎯 change to build test
testaruda--list🎯 change to build test

Summary of Required Changes

ToolEditionLicenseVersionJust recipesShellDefault
pretender⬆️ 2024✅✅✅➕ add🔁 → build test
dont✅✅✅✅🔧 -cu→-uc🔁 → build test
espectacular⬆️ 2024✅✅✅➕ add🔁 → build test
testaruda⬆️ 2024✅✅🔧 ah→test, ➕ validate➕ add🔁 → build test
vampiro🆕 2024✅🆕 0.1.0✅✅🔧 → build test
crua🆕 2024✅🆕 0.1.0✅✅🔧 → build test
livin🆕 2024✅🆕 0.1.0✅✅🔧 → build test

✅ = conforms · 🎯 = target · ➕ = missing · 🔧 = needs change · ⬆️ = upgrade · 🆕 = initial setup

Each tool SHOULD implement its own changes as separate tickets. This document is the suite-level source of truth that those tickets trace to.


References

How to Adopt Wai in an Existing Repository

This guide walks through adding wai to a repository that already has code, history, and an established workflow.

Prerequisite: Install wai first — see the Installation page.

1. Initialize the Workspace

From your repository root:

wai init

This creates a .wai/ directory. Commit it — wai artifacts are designed to live alongside your code.

2. Create a Project for Your Current Work

If you’re actively working on something, create a project for it:

wai new project my-current-feature

If you have multiple workstreams, create one project per feature or initiative.

3. Capture What You Already Know

Don’t start from scratch — import the reasoning that already exists:

# Record decisions you've already made
wai add research "Chose PostgreSQL over SQLite for concurrent write support"
wai add design "REST API with versioned endpoints (/v1/, /v2/)"

# Import existing notes or docs
wai add research --file docs/architecture-notes.md

Set the phase to match where you actually are:

wai phase set implement    # if you're already writing code

4. Set Up Agent Config Sync (Optional)

If you use AI assistants (Claude Code, Cursor, etc.), consolidate your configs:

# Import existing configs into wai's single source of truth
wai import .cursorrules
wai import .claude/

# Check what was imported
wai config list

# Sync back to tool locations
wai sync

5. Start Using the Session Loop

From now on, use wai prime at the start of each session and wai close at the end:

# Beginning of session
wai prime                  # Shows status, phase, suggestions

# ... do your work, capture decisions as you go ...
wai add research "Discovered edge case with auth tokens"

# End of session
wai close                  # Creates handoff for next session

6. Check Your Setup

Verify everything is healthy:

wai doctor                 # Workspace health check
wai way                    # Repository best practices

What Not to Do

  • Don’t try to backfill all history. Capture decisions going forward. The value compounds over time.
  • Don’t skip phases. Even if you set the phase to implement, record the reasoning that got you there.
  • Don’t forget to commit .wai/. It’s part of your repository.

JSON Output

All major wai commands support --json flag for machine-readable output, enabling integration with scripts, automation tools, and other software.

Usage

wai <command> --json

JSON output is written to stdout, errors to stderr. This allows you to separate data from errors:

# Capture JSON output only
wai status --json > status.json

# Capture errors only
wai status --json 2> errors.log

# Capture both separately
wai status --json > status.json 2> errors.log

# Pipe JSON directly to processing tools
wai status --json | jq '.projects[].name'

Supported Commands

Status

wai status --json

Output:

{
  "project_root": "/path/to/project",
  "projects": [
    {
      "name": "my-app",
      "phase": "implement",
      "path": ".wai/projects/my-app"
    }
  ],
  "plugins": [
    {
      "name": "beads",
      "detected": true,
      "description": "Issue tracking"
    },
    {
      "name": "git",
      "detected": true,
      "description": "Version control"
    }
  ],
  "hook_outputs": {
    "git_status": "M src/main.rs\n",
    "beads_stats": "Open: 5, Closed: 12"
  },
  "openspec": {
    "specs": ["cli-core", "plugin-system"],
    "changes": [
      {
        "name": "add-feature-x",
        "progress": 75
      }
    ]
  },
  "suggestions": [
    {
      "pattern": "ImplementPhaseActive",
      "suggestion": "Consider running tests",
      "command": "cargo test"
    }
  ]
}
wai search "authentication" --json

Output:

{
  "query": "authentication",
  "results": [
    {
      "path": ".wai/projects/my-app/research/2026-02-15-auth-research.md",
      "type": "research",
      "project": "my-app",
      "line": 12,
      "context": [
        "Evaluated JWT vs session-based authentication.",
        "Chose JWT for stateless API design.",
        "Will store tokens in httpOnly cookies."
      ]
    }
  ]
}

Timeline

wai timeline my-app --json

Output:

{
  "project": "my-app",
  "entries": [
    {
      "date": "2026-02-15",
      "type": "research",
      "title": "auth-research",
      "path": ".wai/projects/my-app/research/2026-02-15-auth-research.md"
    },
    {
      "date": "2026-02-16",
      "type": "design",
      "title": "api-design",
      "path": ".wai/projects/my-app/designs/2026-02-16-api-design.md"
    }
  ]
}

Plugin List

wai plugin list --json

Output:

{
  "plugins": [
    {
      "name": "beads",
      "description": "Issue tracking",
      "detected": true,
      "commands": [
        {
          "name": "list",
          "description": "List issues",
          "read_only": true
        },
        {
          "name": "show",
          "description": "Show issue details",
          "read_only": true
        }
      ],
      "hooks": [
        {
          "type": "on_status",
          "command": "bd stats"
        },
        {
          "type": "on_handoff_generate",
          "command": "bd list --status=open"
        }
      ]
    }
  ]
}

Resource List

wai resource list skills --json

Output:

{
  "skills": [
    {
      "name": "code-review",
      "path": ".wai/resources/agent-config/skills/code-review.md"
    },
    {
      "name": "commit",
      "path": ".wai/resources/agent-config/skills/commit.md"
    }
  ]
}

Error Handling

Errors are returned as JSON when --json is used:

{
  "code": "wai::error::project_not_found",
  "message": "Project 'missing-app' not found",
  "help": "Use 'wai show' to list available projects",
  "details": null
}

JSON Schema Stability

Current Policy: JSON output schemas are considered stable within a major version.

  • ✅ Safe: Adding new optional fields
  • ✅ Safe: Adding new values to enums
  • ❌ Breaking: Removing fields
  • ❌ Breaking: Changing field types
  • ❌ Breaking: Renaming fields

Recommendation: When writing automation scripts, handle unknown fields gracefully and validate expected fields exist.

Example resilient parsing:

# Good - checks for field existence
if jq -e '.projects[]? | select(.name == "my-app")' status.json; then
  echo "Project exists"
fi

# Good - provides defaults for missing fields
jq '.projects[]? | {name, phase: (.phase // "unknown")}' status.json

Processing with jq

Use jq for powerful JSON processing:

# Extract project names
wai status --json | jq '.projects[].name'

# Get all research artifacts
wai search ".*" --regex --type research --json | jq '.results[].path'

# Count plugins detected
wai plugin list --json | jq '[.plugins[] | select(.detected)] | length'

# Get recent timeline entries
wai timeline my-app --json | jq '.entries | .[-5:]'

# Check if sync is needed
wai sync --status --json | jq '.projections[] | select(.status != "in_sync")'

Automation Examples

CI/CD Integration

#!/bin/bash
# Check if handoff exists for current branch
BRANCH=$(git branch --show-current)
HANDOFFS=$(wai search "$BRANCH" --type handoff --json | jq -r '.results[].path')

if [ -z "$HANDOFFS" ]; then
  echo "No handoff found for branch $BRANCH"
  exit 1
fi

Slack Notifications

#!/bin/bash
# Send status to Slack
STATUS=$(wai status --json)
PROJECTS=$(echo "$STATUS" | jq -r '.projects[] | "\(.name): \(.phase)"' | tr '\n' ', ')

curl -X POST "$SLACK_WEBHOOK" \
  -H 'Content-Type: application/json' \
  -d "{\"text\":\"Project Status: $PROJECTS\"}"

Dashboard Generation

import json
import subprocess

# Get status
result = subprocess.run(['wai', 'status', '--json'], capture_output=True, text=True)
status = json.loads(result.stdout)

# Generate HTML dashboard
html = "<h1>Project Status</h1>"
for project in status['projects']:
    html += f"<div><strong>{project['name']}</strong>: {project['phase']}</div>"

print(html)

Non-Interactive Mode

Combine --json with --no-input for fully automated scripts:

wai status --json --no-input
wai search "query" --json --no-input

This prevents any interactive prompts that might block automation.

Safe Mode

Use --safe with --json for read-only automation:

wai status --json --safe

Ensures no modifications occur during automated queries.

See Also

Workflow Detection

Wai automatically detects project patterns and provides context-aware suggestions based on your current state.

How It Works

When you run wai status, wai analyzes:

  • Current project phase
  • Number and type of artifacts
  • Plugin state (git status, open issues, etc.)
  • Recent activity

Based on this analysis, it detects workflow patterns and suggests relevant next steps.

Detected Patterns

NewProject

Condition: Project exists but has no artifacts yet, in research phase.

Suggestions:

  • Add initial research with wai add research "..."
  • Import existing research with wai add research --file notes.md
  • Run tutorial for guidance: wai tutorial

Example:

$ wai status
Project: my-app
Phase: research
Artifacts: 0

Pattern: NewProject
Suggestions:
  - Start gathering research: wai add research "Initial findings"
  - Import existing notes: wai add research --file notes.md

ResearchPhaseMinimal

Condition: In research phase with few (≤1) research artifacts.

Suggestions:

  • Continue gathering information
  • Add more research artifacts
  • Consider when you have enough to move to design

Example:

$ wai status
Project: my-app
Phase: research
Research artifacts: 1

Pattern: ResearchPhaseMinimal
Suggestions:
  - Add more research: wai add research "Additional findings"
  - When ready, advance: wai phase next

ReadyToImplement

Condition: In plan or design phase with design documents created.

Suggestions:

  • Move to implement phase
  • Review designs before starting
  • Set up development environment

Example:

$ wai status
Project: my-app
Phase: design
Design artifacts: 2
Plan artifacts: 1

Pattern: ReadyToImplement
Suggestions:
  - Ready to implement: wai phase next
  - Review designs: wai search "design" --in my-app
  - Create handoff: wai handoff create my-app

ImplementPhaseActive

Condition: Currently in implement phase.

Suggestions:

  • Run tests regularly
  • Document implementation decisions
  • Consider moving to review when done

Example:

$ wai status
Project: my-app
Phase: implement

Pattern: ImplementPhaseActive
Suggestions:
  - Run tests: cargo test
  - Document decisions: wai add design "Implementation notes"
  - When done, advance: wai phase next

Context-Aware Commands

Suggestions include specific commands tailored to your project:

$ wai status
Project: api-server
Phase: implement
Plugin: beads (5 open issues)
Plugin: git (uncommitted changes)

Suggestions:
  - Review open issues: wai beads ready
  - Check git status: git status
  - Run tests: cargo test
  - Commit changes: git add -A && git commit

Plugin Integration

Workflow detection incorporates plugin context:

With beads plugin:

  • Suggests reviewing open issues
  • Recommends closing completed work
  • Highlights blockers

With git plugin:

  • Detects uncommitted changes
  • Suggests creating commits
  • Recommends pushing to remote

With openspec plugin:

  • Shows active change proposals
  • Displays implementation progress
  • Suggests next specification steps

JSON Output

Get structured workflow information:

wai status --json | jq '.suggestions'

Output:

[
  {
    "pattern": "ReadyToImplement",
    "suggestion": "Move to implement phase",
    "command": "wai phase next"
  },
  {
    "pattern": "ReadyToImplement",
    "suggestion": "Review designs before implementing",
    "command": "wai search \"design\" --in my-app"
  }
]

Custom Patterns

While wai detects common patterns automatically, you can create custom workflow patterns through plugins.

Example Custom Pattern Plugin

name = "my-workflow"
description = "Custom workflow detector"

[hooks.on_status]
command = """
if [ -f .needs-review ]; then
  echo "Ready for review - run: make review"
fi
"""
inject_as = "custom_workflow"

Best Practices

Follow Suggestions

Wai’s suggestions are designed to guide you through proven workflows:

  1. Research → gather information
  2. Design → make decisions
  3. Plan → break down work
  4. Implement → build
  5. Review → validate
  6. Archive → document and close

Ignore When Needed

Suggestions are guidance, not rules. Feel free to:

  • Skip phases that don’t apply
  • Go back when you need more research
  • Add artifacts in any phase
  • Move forward at your own pace

Use with Plugins

Workflow detection works best with plugins:

  • beads — Track concrete tasks alongside high-level workflow
  • git — Keep version control in sync with project phases
  • openspec — Align specifications with implementation phases

Disable Suggestions

To hide workflow suggestions:

wai status --quiet

Or suppress output:

wai status -q

See Also

Implementation Status

At-a-glance view of wai’s implemented commands and their relation to formal change proposals tracked in openspec/.


Commands

CommandDescription
wai initInitialize wai in any directory
wai tutorialRun the interactive quickstart tutorial
wai statusProject overview and next-step suggestions
wai primeOrient the session; detect resume state
wai closeCapture session state and signal pending resume
wai handoff create <project>Generate a handoff document explicitly
wai showInspect projects, areas, and resources
wai lsList all wai workspaces under a root
wai newCreate projects, areas, and resources
wai addAdd research, plans, designs, and reviews
wai searchFull-text artifact search with tag filtering
wai timelineChronological artifact view across projects
wai whyAsk the LLM oracle about design decisions
wai reflectSynthesize project patterns into CLAUDE.md
wai syncPull remote artifact updates
wai moveRelocate projects and areas
wai importImport existing AI tool configs (.claude/, .cursorrules)
wai phaseShow, advance, or set the current project phase
wai doctorDiagnose and repair workspace health
wai wayCheck and scaffold repository best practices
wai configInspect workspace configuration
wai resourceManage skills, rules, and context resources
wai pluginEnable and disable workspace plugins
wai pipelineRun structured multi-step research workflows
wai projectSession-scope a project (WAI_PROJECT env var)
wai trace(Planned) Import session traces from agent tools

For the authoritative list run wai --help.


Change Proposals

Formal changes are tracked in openspec/changes/. Each entry links a capability to the reasoning that motivated it. Status values come from openspec list; task counts from tasks.md in each change directory.

ChangeStatusRelated Commands
add-cross-tool-trace-ingestionIn progress (0/10)wai trace, wai reflect
add-artifact-integrityCompletewai pipeline lock/verify, wai doctor
add-project-resolutionCompletewai project use, wai ls

Run openspec list for the full list including archived changes.


Capability Specs

Stable capabilities have formal specs in openspec/specs/. These define the expected behavior independently of any single change.

Run openspec list --specs to see current specs.


Release History

Releases follow calendar versioning (vYYYY.M.N). See the GitHub Releases page for the full changelog.

Frequently Asked Questions

General

What is wai?

Wai (pronounced “why”) is a command-line workflow manager for AI-driven development. It helps you capture and organize the research, reasoning, and decisions behind your code - the “why” that’s often lost between sessions.

How is wai different from other documentation tools?

Most tools focus on what you built. Wai captures why you built it that way:

  • Research findings and trade-offs
  • Design decisions and alternatives considered
  • Implementation plans and reasoning
  • Session handoffs with context

Do I need to use git with wai?

No, wai works independently. However, wai integrates nicely with git through the plugin system, including git status in handoffs and status output.

Can I use wai with existing projects?

Yes! Run wai init in any directory to start using wai. You can import existing documentation with wai import or wai add research --file.

Usage

Which phase should I be in?

Phases are guidelines, not gates. Use what makes sense:

  • Research - Exploring, learning, gathering information
  • Design - Making architectural decisions
  • Plan - Breaking down implementation steps
  • Implement - Writing code
  • Review - Testing, validating, refining
  • Archive - Wrapping up, documenting outcomes

You can skip phases or go backward anytime.

How do I choose between projects, areas, and resources?

PARA method:

  • Projects - Active work with a goal and end date (e.g., “user-auth-feature”)
  • Areas - Ongoing responsibilities without end date (e.g., “performance-monitoring”)
  • Resources - Reference material (e.g., agent configs, templates)
  • Archives - Completed or inactive items

Should I use wai for every project?

Wai is most valuable for:

  • Complex features requiring research and design
  • Work spanning multiple sessions
  • Collaboration requiring knowledge transfer
  • Projects where “why” matters (architecture decisions, trade-offs)

For quick fixes or trivial changes, standard git commits may be enough.

How often should I create handoffs?

Create handoffs when:

  • Ending a work session (especially multi-hour sessions)
  • Switching context to another project
  • Handing work to another developer
  • Taking a break and might forget context

Think of handoffs as “save points” for your reasoning.

Agent Configuration

What’s the difference between skills, rules, and context?

  • Skills - Task-specific instructions (e.g., “how to review code”, “how to commit”)
  • Rules - System-wide constraints (e.g., “always add tests”, “follow security practices”)
  • Context - Project-specific background (e.g., “architecture overview”, “team conventions”)

Which sync strategy should I use?

StrategyUse WhenExample
SymlinkTool expects directory of filesClaude Code, Aider
InlineTool expects single concatenated fileCursor (.cursorrules)
ReferenceTool can follow pathsCustom scripts

See Agent Config Sync for details.

Can I use multiple sync strategies?

Yes! You can have different projections for different tools:

projections:
  - strategy: symlink
    sources: [skills/]
    target: .claude/skills/
  - strategy: inline
    sources: [rules/]
    target: .cursorrules

What happens if I edit synced files directly?

Wai will overwrite them on the next sync. Always edit source files in .wai/resources/agent-config/, never the synced targets.

Plugins

How do I create a custom plugin?

Create a TOML file in .wai/plugins/:

name = "my-tool"
description = "My tool integration"

[detector]
type = "directory"
path = ".mytool"

[[commands]]
name = "status"
description = "Show status"
passthrough = "mytool status"
read_only = true

[hooks.on_status]
command = "mytool stats"
inject_as = "mytool_stats"

See Plugin System for complete guide.

Can I disable built-in plugins?

No, built-in plugins (git, beads, openspec) cannot be disabled. They’re only active when their detector finds the relevant files (e.g., .git/ for git).

Why isn’t my plugin detected?

Common reasons:

  1. Detector path doesn’t exist (e.g., .mytool/ directory missing)
  2. TOML syntax error in plugin definition
  3. Plugin tool not installed or not in PATH

Run wai doctor to diagnose plugin issues.

Workflow & Patterns

What are workflow patterns?

Wai automatically detects your project state and suggests next steps:

  • NewProject - No artifacts yet → suggests adding research
  • ResearchPhaseMinimal - Few artifacts → suggests gathering more info
  • ReadyToImplement - Designs complete → suggests moving to implementation
  • ImplementPhaseActive - Currently implementing → suggests testing

Can I customize workflow suggestions?

Not yet, but it’s planned. For now, you can ignore suggestions that don’t fit your workflow.

How does wai know what to suggest?

Wai analyzes:

  • Current project phase
  • Number and type of artifacts
  • Plugin state (git status, open issues, etc.)
  • Recent activity

Based on this, it matches patterns and suggests relevant commands.

Technical

Where is data stored?

Everything is in .wai/ directory:

.wai/
├── config.toml           # Project configuration
├── projects/             # Active projects with artifacts
├── resources/            # Agent configs, templates
└── plugins/              # Custom plugin definitions

Safe to version control with git!

Is wai data portable?

Yes! The entire .wai/ directory can be:

  • Committed to git
  • Copied to another machine
  • Backed up
  • Shared with team members

Can I use wai in CI/CD?

Yes! Use non-interactive mode with JSON output:

wai status --json --no-input
wai search "query" --json --no-input
wai doctor --json --no-input

Does wai work offline?

Yes, wai is completely local. No network required.

What’s the performance impact?

Minimal. Wai is a lightweight CLI tool. Most commands complete in milliseconds. Large projects (hundreds of artifacts) may see slower search/timeline commands, but typically still under 1 second.

Troubleshooting

Command not found after installation

Add cargo bin to PATH:

export PATH="$HOME/.cargo/bin:$PATH"

Add to ~/.bashrc or ~/.zshrc to make permanent.

Doctor reports issues I don’t understand

Run with verbose mode:

wai doctor -v

Check Troubleshooting for common issues.

My synced files keep getting overwritten

This is expected behavior. Wai syncs from source files in .wai/resources/agent-config/ to target locations. Always edit source files, never the synced targets.

See Agent Config Sync - Conflict Resolution.

Search returns no results but files exist

Check:

  1. Are you searching the right project? Use --in project-name
  2. Is the search term exact? Try regex mode: --regex
  3. Do artifacts exist? Check: wai timeline project-name

Getting More Help

  • Documentation: Read full docs in docs/ directory
  • Tutorial: Run wai tutorial for interactive guide
  • Command help: wai <command> --help
  • Workspace health: wai doctor
  • GitHub Issues: https://github.com/charly-vibes/wai/issues

See Also

Glossary

Domain-specific terms used throughout the wai documentation.


Addendum A correction artifact that references a locked artifact via --corrects=<path>. Preserves the original’s integrity while recording what changed and why. See Pipelines — Artifact Locking.

Artifact A dated Markdown file capturing reasoning at a specific point in time. Types include research, design, plan, handoff, and review. Stored in project subdirectories under .wai/projects/. See Project Phases.

Artifact lock A SHA-256 hash sidecar (.lock file) written alongside a pipeline artifact to freeze its content. Created automatically when a step with lock = true advances, or manually via wai pipeline lock. Verified by wai pipeline verify and wai doctor. See Pipelines — Artifact Locking.

Frontmatter YAML metadata at the top of an artifact file (between --- markers). Contains fields like title, date, tags, and project name. Used by wai search for filtering and by wai why for context gathering.

Handoff A session context transfer document generated by wai close or wai handoff create. Contains a session summary, current state, plugin context, and next steps. Enables continuity across sessions and agents. See Sessions.

Managed block An auto-generated section in instruction files (AGENTS.md, CLAUDE.md) delimited by <!-- WAI:START --> / <!-- WAI:END --> markers. Updated automatically by wai init and wai reflect. Do not edit manually — changes will be overwritten.

Oracle The LLM-powered reasoning engine behind wai why. Queries your project artifacts and git history to answer natural-language questions about design decisions. See Reasoning. Not to be confused with oracle scripts — see Pipeline gate.

Oracle script A user-defined validation script executed during pipeline gate checks. Placed in .wai/resources/oracles/ and referenced from pipeline TOML definitions. Exit 0 = pass, non-zero = fail. See Pipelines — Gates.

PARA An organizational system with four categories: Projects (active work with a goal), Areas (ongoing responsibilities), Resources (reference material), Archives (completed items). See PARA Method.

Phase One of six lifecycle stages a project moves through: research → design → plan → implement → review → archive. Phases guide what kind of work and artifacts are expected. See Project Phases.

Pipeline An ordered, multi-step workflow defined in TOML. Pipelines structure complex tasks (like research) into sequential steps with validation between them. See Pipelines.

Pipeline gate A condition that must be satisfied before advancing to the next pipeline step. Gate tiers include structural (artifact counts), procedural (review verdicts), oracle (custom scripts), and approval (human checkpoints). See Pipelines — Gates.

Pipeline run An active execution of a pipeline, scoped to a topic. Created with wai pipeline start and advanced with wai pipeline next. State is tracked so you can resume across sessions.

Review artifact An artifact that records validation results against another artifact. Created with wai add review --reviews <target>. Includes optional verdict (pass/fail/needs-work), severity counts, and the producing skill name. Used by pipeline procedural gates to enforce review requirements. See Commands — Adding Artifacts.

Plugin An integration module that connects wai with external tools (git, beads, openspec). Plugins are auto-detected based on workspace markers (e.g., .git/, .beads/). See Plugin System.

Projection A sync strategy that maps source files in .wai/resources/agent-config/ to tool-specific target locations. Strategies include symlink, inline, and reference. See Agent Config Sync.

Hook A plugin extension point triggered during wai operations. Hooks like on_status and on_handoff_generate let plugins inject context into wai’s output. See Plugin System — Hooks.

Passthrough A plugin command that delegates directly to the underlying tool. For example, wai beads list passes through to the beads CLI. See Plugin System — Commands.

Safe mode A read-only execution mode activated by the --safe global flag. Blocks all write operations (add, sync, move, pipeline start/next/init/approve/lock, phase changes, import). Read-only commands work normally. See Commands — Safe mode.

Reflection A synthesized summary of project patterns, conventions, and architectural notes produced by wai reflect. Stored as versioned Markdown in .wai/resources/reflections/ and injected into instruction files. See Reasoning.

Session A unit of work bounded by wai prime (start) and wai close (end). Sessions preserve context across agent restarts and context window boundaries. See Sessions.

Development

Prerequisites

  • Rust (stable toolchain)
  • just (command runner)

Architecture Overview

wai is built as a modular CLI tool in Rust, focusing on local-first storage and tool-agnostic integration.

For a deeper dive into the codebase structure and ADRs, see Architecture.

Core Systems

1. Registry & Workspace (src/workspace.rs, src/config.rs)

Manages the .wai/ directory structure and the PARA method (Projects, Areas, Resources, Archives).

  • Project state: Tracked via .state files in each project.
  • Artifacts: Stored as date-prefixed markdown files with optional frontmatter.

2. Plugin System (src/plugin.rs)

A flexible architecture for detecting and interacting with external tools.

  • Built-in plugins: git, beads, openspec.
  • Custom plugins: Loaded from .wai/plugins/*.toml.
  • Hooks: Allows tools to inject context into wai status (on_status) and wai handoff create (on_handoff_generate).
  • Passthrough: Direct execution of tool commands (e.g., wai beads list).

3. Agent-Config Sync Engine (src/sync_core.rs, src/commands/sync.rs)

Syncs a single source of truth for agent configurations to tool-specific locations.

  • Projections: Defined in .projections.yml.
  • Strategies: symlink, inline (concatenation), reference (path listing), and copy.
  • Specialized Targets: Built-in logic for tools like claude-code.

4. Reasoning Oracle (src/llm.rs, src/commands/why.rs)

Interfaces with LLMs (Claude, Ollama) to answer natural language questions about the codebase using project artifacts as context.

5. Pipelines (src/commands/pipeline.rs)

Multi-step, prompt-driven workflows that track run IDs and automatically tag artifacts.

Building

just build           # Debug build
just build-release   # Release build

Testing

just test            # Run all tests
just test-verbose    # Run tests with output
just test-one <name> # Run a specific test

Linting & formatting

just lint            # Run clippy
just fmt             # Format code
just fmt-check       # Check formatting without changes

Full CI pipeline

Run the same checks that CI runs:

just ci

Documentation

Build and preview the docs locally:

just docs            # Build docs
just docs-serve      # Live preview at localhost:3000

Requires mdBook:

cargo install mdbook

Architecture

This page describes wai’s internal architecture for contributors who want to understand or modify the codebase.

High-Level Structure

Wai is a modular Rust CLI organized into five core subsystems:

src/
├── main.rs                 # Entry point
├── cli.rs                  # Clap argument definitions
├── commands/               # One file per subcommand
│   ├── status.rs           # wai status
│   ├── add.rs              # wai add
│   ├── search.rs           # wai search
│   ├── prime.rs            # wai prime
│   ├── close.rs            # wai close
│   ├── why.rs              # wai why (reasoning oracle)
│   ├── reflect.rs          # wai reflect (synthesis)
│   ├── doctor.rs           # wai doctor
│   ├── way.rs              # wai way (best practices)
│   ├── pipeline.rs         # wai pipeline
│   └── ...
├── workspace.rs            # Registry & PARA directory management
├── config.rs               # Config loading (.wai/config.toml)
├── plugin.rs               # Plugin detection, hooks, passthrough
├── sync_core.rs            # Agent config sync engine
├── llm.rs                  # LLM backend abstraction
├── suggestions.rs          # Context-aware next-step suggestions
└── help.rs                 # Tiered help system

Subsystems

1. Registry & Workspace

Files: src/workspace.rs, src/config.rs

Manages the .wai/ directory structure and the PARA method. Project state is tracked via .state files. Artifacts are stored as date-prefixed Markdown files with optional YAML frontmatter.

2. Plugin System

Files: src/plugin.rs

Auto-detects external tools by scanning for workspace markers (.git/, .beads/, openspec/). Plugins contribute context through hooks (on_status, on_handoff_generate, on_phase_transition) and expose commands via passthrough. Custom plugins are loaded from .wai/plugins/*.toml.

3. Agent Config Sync Engine

Files: src/sync_core.rs, src/commands/sync.rs

Projects agent configurations from .wai/resources/agent-config/ to tool-specific locations using configurable strategies (symlink, inline, reference, copy). Specialized targets like claude-code handle complex tool-specific transformations.

4. Reasoning Oracle & Synthesis

Files: src/llm.rs, src/commands/why.rs, src/commands/reflect.rs

Interfaces with LLMs (Claude API, Claude CLI, Ollama) to answer questions about the codebase (wai why) and synthesize project patterns (wai reflect). The LlmClient trait abstracts backend differences.

5. Pipelines

Files: src/commands/pipeline.rs

Multi-step, prompt-driven workflows defined in TOML. Tracks run state, supports pipeline gates (structural, procedural, oracle, approval), and auto-tags artifacts with run IDs.

Design Decisions

Significant trade-offs and architectural choices are captured as wai artifacts. Run wai search "design" to browse design decisions, or check .wai/resources/reflections/ for synthesized project patterns.

Agent Config Sync

Purpose

Define how wai manages AI agent configurations as a single source of truth, with projections to tool-specific formats like .claude/, .cursorrules, .windsurfrules, and AGENTS.md.

Problem Statement

Modern development involves multiple AI coding assistants (Claude Code, Cursor, Windsurf, etc.), each requiring its own configuration format and location. Maintaining consistent agent instructions across these tools leads to configuration drift, duplicated effort, and inconsistent behavior. Developers need a single source of truth for agent configurations that can be projected to each tool’s expected format automatically.

Design Rationale

Single Source of Truth

Storing all agent configuration in .wai/resources/agent-config/ is a Type 1 decision. This centralizes skills, rules, and context files in one location, making them versionable, reviewable, and consistent. Tool-specific files become projections of this canonical source rather than independent configurations.

Projection Strategies

Three projection strategies (symlink, inline, reference) provide flexibility for different tool requirements. This is a Type 2 decision — the strategies may evolve, but the concept of projecting from a single source is foundational.

  • Symlink: Creates filesystem symlinks from tool locations to the canonical files. Most efficient, but requires symlink support.
  • Inline: Concatenates source files into a single output file with auto-generated headers. Works everywhere, but requires re-running sync after changes.
  • Reference: Generates an index file pointing to .wai/ locations. Lightweight, but requires tool support for following references.

Auto-Generated Headers

Projected files include # Auto-generated by wai — do not edit directly headers to prevent accidental direct edits and make the generation pipeline visible.

Scope and Requirements

This spec covers the storage, organization, and projection of agent configuration files.

Non-Goals

  • Defining the content or semantics of agent rules/skills
  • Managing tool-specific settings beyond agent instructions (e.g., Cursor’s editor settings)
  • Automatic detection and sync on file change (manual wai sync is required)
  • Remote or team-wide config sharing

Requirement: Agent Config Storage

Agent configurations SHALL be stored in a structured directory within .wai/resources/.

Scenario: Config directory structure

  • WHEN wai is initialized
  • THEN the agent-config directory structure is:
    .wai/resources/agent-config/
    ├── skills/       # Reusable agent capabilities
    ├── rules/        # Behavioral guidelines
    ├── context/      # Project-specific context
    └── .projections.yml
    

Requirement: Projections Configuration

A .projections.yml file SHALL define how configs are projected to tool-specific locations.

Scenario: Projections file format

  • WHEN configuring projections
  • THEN .projections.yml follows this format:
    projections:
      - target: .claude/
        strategy: symlink
        sources:
          - skills/
          - rules/
      - target: .cursorrules
        strategy: inline
        sources:
          - rules/
          - context/
      - target: AGENTS.md
        strategy: inline
        sources:
          - context/
    

Requirement: Sync Command

The CLI SHALL provide a wai sync command to execute projections.

Scenario: Execute projections

  • WHEN user runs wai sync
  • THEN the system reads .projections.yml
  • AND generates projected files according to each target’s strategy
  • AND reports which files were created or updated

Scenario: Check sync status

  • WHEN user runs wai sync --status
  • THEN the system shows which projections are up-to-date and which need syncing
  • AND does not modify any files

Requirement: Config Management

The CLI SHALL support managing agent config files.

Scenario: Add a skill

  • WHEN user runs wai config add skill <file>
  • THEN the system copies the file to .wai/resources/agent-config/skills/

Scenario: Add a rule

  • WHEN user runs wai config add rule <file>
  • THEN the system copies the file to .wai/resources/agent-config/rules/

Scenario: List configs

  • WHEN user runs wai config list
  • THEN the system shows all files in skills/, rules/, and context/ directories

Requirement: Import Existing Configs

The CLI SHALL support importing configurations from existing tool-specific files.

Scenario: Import from Claude directory

  • WHEN user runs wai import .claude/
  • THEN the system detects Claude-specific config files
  • AND copies them into the appropriate agent-config subdirectories

Scenario: Import from cursorrules

  • WHEN user runs wai import .cursorrules
  • THEN the system reads the cursorrules file
  • AND imports the content as agent rules

Requirement: Auto-Generated Headers

Projected files SHALL include headers indicating they are auto-generated.

Scenario: Generated file header

  • WHEN a file is generated via wai sync
  • THEN it begins with a comment: # Auto-generated by wai — do not edit directly
  • AND includes the source path for reference

Requirements

Requirement: Claude Code Built-in Projection Target

The sync system SHALL support claude-code as a built-in projection target that automatically maps hierarchical wai skills to Claude Code command files with translated frontmatter.

Scenario: Built-in target activation

  • WHEN a projection defines target: claude-code
  • THEN the system treats it as a built-in target, not a filesystem path
  • AND scans skills/<category>/<action>/SKILL.md for all hierarchical skills

Scenario: Skill file generated at correct path

  • WHEN wai sync processes a claude-code target
  • AND a skill exists at skills/issue/gather/SKILL.md
  • THEN the system writes .claude/commands/issue/gather.md
  • AND creates the .claude/commands/issue/ directory if it does not exist

Scenario: Frontmatter translation

  • WHEN a wai SKILL.md has frontmatter name: issue/gather and description: "Gather issues from codebase"
  • THEN the generated Claude Code file has frontmatter:
    name: "Issue: Gather"
    description: "Gather issues from codebase"
    category: "Issue"
    
  • AND the skill body is written unchanged after the frontmatter block
  • AND the name field is derived by capitalising the first letter of each path segment and joining with : (e.g., issue/gather → Issue: Gather)

Scenario: Auto-generated header

  • WHEN a Claude Code file is generated by wai sync
  • THEN the --- frontmatter delimiter is on line 1 of the generated file (required for frontmatter parsers that enforce strict position)
  • AND the file body (after the closing --- of the frontmatter) begins with: <!-- Auto-generated by wai — do not edit directly -->
  • AND the source path is noted (e.g., <!-- Source: skills/issue/gather/SKILL.md -->)

Requirement: Hierarchical Skill Names

Skill names SHALL support a single / separator to enable category/action grouping that maps directly to Claude Code’s invocation path convention (/category:action).

Scenario: Create hierarchical skill

  • WHEN user runs wai resource add skill issue/gather
  • THEN the system creates .wai/resources/agent-config/skills/issue/gather/SKILL.md
  • AND the skill is listed with name issue/gather

Scenario: Flat names unchanged

  • WHEN user runs wai resource add skill my-skill
  • THEN the system creates .wai/resources/agent-config/skills/my-skill/SKILL.md
  • AND existing flat naming behavior is preserved

Scenario: Invalid hierarchical names rejected

  • WHEN user provides a skill name with two or more slashes (e.g., a/b/c)
  • THEN the system rejects it with a clear error: only one / is allowed

Scenario: Empty segments rejected

  • WHEN user provides a name with an empty segment (e.g., /gather or issue/)
  • THEN the system rejects it with an error explaining both segments must be non-empty

Scenario: Category grouping in list output

  • WHEN user runs wai resource list skills
  • AND hierarchical skills exist (e.g., issue/gather, issue/create)
  • THEN skills are displayed with their full hierarchical name (e.g., issue/gather)
  • AND the JSON output includes a category field for hierarchical skills

Scenario: Frontmatter name for hierarchical skill

  • WHEN user runs wai resource add skill issue/gather
  • THEN the generated SKILL.md frontmatter contains name: issue/gather (the full hierarchical name, not just the action segment)
  • AND this name is what add-claude-code-projection reads for frontmatter translation

Scenario: Flat-name collision with category directory rejected

  • WHEN a flat skill named issue already exists at skills/issue/SKILL.md
  • AND user runs wai resource add skill issue/gather
  • THEN the system errors with a message explaining that issue is already a flat skill and cannot also be used as a category name
  • AND suggests renaming the existing flat skill before creating the category

Requirement: Skill Template Library

The CLI SHALL provide built-in templates that scaffold common agent pipeline skill patterns when creating a new skill.

Scenario: Create skill from template

  • WHEN user runs wai resource add skill issue/gather --template gather
  • THEN the system creates SKILL.md with the gather template body
  • AND the template uses $ARGUMENTS, $PROJECT, $REPO_ROOT placeholders
  • AND the SKILL.md is ready to use without further editing of placeholders

Scenario: Available templates

  • WHEN user runs wai resource add skill <name> --template <name>
  • THEN the system accepts the following template names:
    • gather — research stub: wai search $ARGUMENTS, codebase exploration, wai add research
    • create — creation stub: artifact retrieval via wai search --latest, item loop with output tracking
    • tdd — test-first stub: RED/GREEN/REFACTOR loop with cargo test / just check
    • rule-of-5 — review stub: 5-pass review with convergence check and APPROVED / NEEDS_CHANGES / NEEDS_HUMAN verdict

Scenario: Unknown template name rejected

  • WHEN user runs wai resource add skill <name> --template unknown-template
  • THEN the system rejects the command with an error
  • AND lists the valid template names in the error message

Scenario: No template gives bare stub

  • WHEN user runs wai resource add skill <name> without --template
  • THEN the system creates the existing minimal stub (no regression)

Scenario: Templates are portable

  • WHEN a template-generated SKILL.md is used in a different project
  • THEN all project-specific values are provided via $ARGUMENTS, $PROJECT, or $REPO_ROOT at runtime — no hardcoded project names exist in the template

agnostic-capabilities Specification

Purpose

TBD - created by archiving change refactor-way-agnostic. Update Purpose after archive.

Requirements

Requirement: Agnostic Repository Best Practice Checks

The wai way command SHALL report on agnostic repository capabilities rather than specific tool implementations. Each check SHALL include its intent and success criteria to provide context for both human users and AI agents.

Scenario: Check output with intent and success criteria (Verbose)

  • GIVEN a project with a justfile
  • WHEN user runs wai way -v
  • THEN the output SHALL show the capability name “Command standardization” instead of “Task runner”
  • AND the output SHALL include an “Intent:” line with the agnostic purpose of the check
  • AND the output SHALL include a “Success:” line with the agnostic criteria for passing the check

Scenario: Check output with intent and success criteria (JSON)

  • GIVEN any project
  • WHEN user runs wai way --json
  • THEN the JSON payload SHALL include intent and success_criteria fields for every check result
  • AND these fields SHALL be optional (null if not provided) to ensure backward compatibility

Scenario: Agnostic Check Mapping

The system SHALL map tool-specific checks to agnostic capabilities, each with defined intent and success criteria:

CapabilityIntentSuccess Criteria
Command standardizationProvide a single, tool-agnostic entry point for common repository tasks (build, test, deploy).A standard interface exists for common tasks.
Pre-commit quality gatesPrevent low-quality commits by running automated checks before code is saved to history.Automated checks run automatically before code is committed.
Consistent formattingEnsure consistent code formatting across different editors and IDEs.Project-wide style rules are enforced by a shared configuration file.
Project documentationProvide essential project identity, onboarding, and legal/contribution guidance.Essential files provide project context and rules.
AI-agent contextProvide persistent “rules of the road” and project context for AI collaborators.Persistent instructions define coding standards and context for AI assistants.
LLM-friendly contextProvide machine-readable project context and navigation for LLMs.Machine-readable project documentation (llm.txt) exists.
Extended agent capabilitiesEnhance agent functionality with specialized iterative review and commit workflows.Specialized agent workflows are active.
Integration & automationStreamline repository interactions (PRs, issues, releases) from the CLI.CLI tools are configured for seamless integration with the hosting provider.
Automated verificationEnsure code quality and correctness through automated builds and tests on every change.Every change is automatically validated by a remote build/test pipeline.
Reproducible environmentsProvide a standardized, containerized environment for all contributors.A configuration exists for a consistent, reproducible dev environment.
Automated deliveryAutomate the process of building, packaging, and publishing software releases.Software releases and distribution are fully automated.

Requirement: Plugin Agnostic Context Support

The plugin system SHALL allow TOML-defined plugins to define their own intent and success_criteria.

Scenario: Plugin with custom context

  • GIVEN a plugin TOML with intent and success_criteria defined
  • WHEN the plugin definition is parsed
  • THEN these fields are available on the PluginDef struct
  • AND default to None if not present in the TOML

CLI Core

Purpose

Define the core command structure and patterns for the wai CLI, including the verb-noun command hierarchy, global flags, and foundational commands for managing PARA-organized artifacts, project phases, agent config sync, handoffs, and cross-artifact search.

See also: onboarding spec for first-run and no-args welcome behavior.

Problem Statement

For wai to effectively support development and research projects, it requires a stable and predictable foundation. Without a clearly defined and consistent core command structure and project organization, users would face a steep learning curve, inconsistent interactions, and an unstable platform for automation. This lack of a standardized and predictable interface would hinder adoption and make it difficult to build reliable workflows around wai.

Design Rationale

The design of the CLI core follows a few key principles to establish a stable foundation that is intuitive, consistent, and extensible, making it a reliable platform for future growth.

Command Structure: Verb-Noun

The chosen verb-noun pattern (e.g., wai new project) is a foundational Type 1 decision for wai’s grammar. It was selected for its readability and similarity to natural language, establishing a predictable and consistent rhythm for the user. This stable grammar makes commands easy to discover and remember, and crucially, enables future extensibility by providing a clear framework for applying existing verbs to new nouns. An alternative noun-verb pattern (e.g., wai project new) was considered but deemed less intuitive for wai’s action-oriented approach.

Core Verbs

The primary verbs (new, add, show, move) provide a minimal, orthogonal set of operations. Additional top-level commands (phase, sync, config, handoff, search, timeline, doctor) provide direct access to frequently-used workflows that don’t fit the verb-noun pattern naturally.

PARA-Based Organization

Wai organizes artifacts using the PARA method (Projects, Areas, Resources, Archives). This replaces the previous bead-centric model with a proven organizational framework. Beads (.beads/) is an external tool that wai detects via its plugin system but does not manage directly.

Scope and Requirements

This spec covers the foundational elements of the CLI.

Non-Goals

  • The detailed implementation of every command’s functionality.
  • The internal plugin execution model (covered in plugin-system spec).
  • Specific output formats like JSON or YAML, beyond the standard text output.
  • A graphical user interface.

Requirement: Command Structure

The CLI SHALL use consistent verb-noun command patterns with primary verbs: new, add, show, move, plus dedicated top-level commands for phase, sync, config, handoff, search, timeline, why, reflect, and doctor.

Scenario: Create new items

  • WHEN user runs wai new project <name>, wai new area <name>, or wai new resource <name>
  • THEN the system creates the requested PARA item with appropriate directory structure

Scenario: Add artifacts and resources to a project

  • WHEN user runs wai add research <content>, wai add plan <content>, wai add design <content>, or wai add skill <name>
  • THEN the system creates the requested artifact or resource file in the appropriate directory

Scenario: Add skill — creates skill file

  • WHEN user runs wai add skill <name>
  • THEN the system creates a skill file at .wai/resources/skills/<name>.md (or .wai/resources/skills/<category>/<action>.md for hierarchical names)
  • AND the same name validation rules apply as for wai resource add skill: flat or one-level-hierarchical, lowercase letters/digits/hyphens only

Scenario: Add skill with template

  • WHEN user runs wai add skill <name> --template <template>
  • THEN the system creates the skill file pre-populated with the named template
  • AND valid built-in templates are: gather, create, tdd, rule-of-5

Scenario: Deprecated alias still works

  • WHEN user runs wai resource add skill <name>
  • THEN the system emits a one-line deprecation warning to stderr: ⚠ 'wai resource add skill' is deprecated. Use: wai add skill <name>
  • AND creates the skill file identically to wai add skill <name>
  • AND exits with the same exit code as wai add skill

Scenario: Show information

  • WHEN user runs wai show <item>
  • THEN the system displays the requested information

Scenario: Move items between PARA categories

  • WHEN user runs wai move <item> archives
  • THEN the system moves the item to the archives category

Scenario: Manage project phases

  • WHEN user runs wai phase, wai phase next, wai phase set <phase>, or wai phase back
  • THEN the system shows or transitions the current project’s phase

Scenario: Sync agent configurations

  • WHEN user runs wai sync
  • THEN the system projects agent configs to tool-specific locations

Scenario: Manage agent configs

  • WHEN user runs wai config add skill <file>, wai config list, or wai config edit <path>
  • THEN the system manages agent configuration files

Scenario: Generate handoffs

  • WHEN user runs wai handoff create <project>
  • THEN the system generates a handoff document enriched with plugin data

Scenario: Search artifacts

  • WHEN user runs wai search <query>
  • THEN the system searches across all .wai/ artifacts

Scenario: View timeline

  • WHEN user runs wai timeline <project>
  • THEN the system displays a chronological view of the project’s artifacts

Scenario: Ask reasoning questions

  • WHEN user runs wai why <query>
  • THEN the system uses LLM synthesis to answer why decisions were made
  • AND displays relevant artifacts, decision chains, and suggestions
  • AND gracefully falls back to wai search if no LLM available

Scenario: Reflect on session history

  • WHEN user runs wai reflect
  • THEN the system reads accumulated handoffs and artifacts
  • AND optionally accepts a conversation transcript via --conversation <file>
  • AND uses LLM synthesis to surface project-specific conventions, gotchas, and patterns
  • AND shows a unified diff of old vs proposed REFLECT block content
  • AND requires user confirmation before writing to CLAUDE.md and/or AGENTS.md
  • AND updates whichever AI config files exist in the repo root by default
  • AND fails with a clear diagnostic if no LLM is available (does not fall back)

Scenario: Diagnose workspace health

  • WHEN user runs wai doctor
  • THEN the system runs diagnostic checks against the workspace
  • AND reports pass/warn/fail status for each check with fix suggestions
  • AND exits with code 0 when all checks pass, 1 when any check fails

Requirement: Global Flags

The CLI SHALL support global verbosity and quiet flags that work with all commands.

Scenario: Verbose output (level 1)

  • WHEN user passes -v or --verbose
  • THEN output includes additional context and metadata

Scenario: Verbose output (level 2)

  • WHEN user passes -vv or --verbose --verbose
  • THEN output includes debug information

Scenario: Verbose output (level 3)

  • WHEN user passes -vvv or --verbose --verbose --verbose
  • THEN output includes trace-level details

Scenario: Quiet mode

  • WHEN user passes -q or --quiet
  • THEN only errors are shown

Scenario: Non-interactive mode

  • WHEN user passes --no-input
  • THEN the system disables interactive prompts and fails with a diagnostic error if input is required

Scenario: Auto-confirm

  • WHEN user passes --yes
  • THEN the system proceeds with default choices for confirmations

Scenario: Safe mode

  • WHEN user passes --safe
  • THEN the system runs in read-only mode and refuses operations that mutate state, returning a diagnostic error with a suggested non-safe command

Requirement: JSON Output

Commands that return multi-line structured information SHALL support --json output for machine parsing.

Scenario: Status as JSON

  • WHEN user runs wai status --json
  • THEN the system outputs JSON containing phase, plugin statuses, and suggestion lists

Scenario: Search as JSON

  • WHEN user runs wai search <query> --json
  • THEN the system outputs JSON containing matches with file paths, line numbers, and context

Scenario: Timeline as JSON

  • WHEN user runs wai timeline <project> --json
  • THEN the system outputs JSON containing entries with date, type, title, and path

Scenario: Plugin list as JSON

  • WHEN user runs wai plugin list --json
  • THEN the system outputs JSON containing plugin name, status, and detector metadata

Requirement: Project Initialization

The CLI SHALL provide wai init to initialize a project in the current directory.

Scenario: Interactive initialization

  • WHEN user runs wai init without arguments
  • THEN the system prompts for project name (defaulting to directory name)
  • AND creates .wai/ structure with PARA directories (projects, areas, resources, archives, plugins)
  • AND creates default agent-config directory with .projections.yml
  • AND auto-detects available plugins (beads, openspec, git)

Scenario: Named initialization

  • WHEN user runs wai init --name my-project
  • THEN the system creates the project with the specified name without prompting

Scenario: Already initialized

  • WHEN user runs wai init in an already-initialized directory
  • THEN the system shows a warning and suggests wai status

Requirement: Status Command

The CLI SHALL provide wai status to show project overview and suggest next steps.

Scenario: Show project phase and status

  • WHEN user runs wai status
  • THEN the system displays the current project’s phase
  • AND shows plugin status summaries (beads issues, openspec changes, git status)
  • AND shows contextual suggestions based on current phase

Scenario: Contextual suggestions

See context-suggestions for the complete suggestion logic.

Requirement: Doctor Command

The CLI SHALL provide wai doctor to diagnose workspace health and report issues with actionable fix suggestions.

Scenario: Directory structure check

  • WHEN wai doctor runs
  • THEN it verifies that all expected .wai/ subdirectories exist (projects, areas, resources, archives, plugins)
  • AND reports pass if all present, fail with mkdir suggestion for each missing directory

Scenario: Configuration validation

  • WHEN wai doctor runs
  • THEN it attempts to parse .wai/config.toml
  • AND reports pass if valid, fail with the parse error and suggestion to check the file

Scenario: Plugin tool availability

  • WHEN wai doctor runs and plugins are detected
  • THEN it checks whether each detected plugin’s CLI tool is installed (e.g., git, bd, openspec)
  • AND reports pass if reachable, warn if not installed with install guidance

Scenario: Agent config sync status

  • WHEN wai doctor runs and .projections.yml exists
  • THEN it validates the projections file parses correctly
  • AND checks whether each projection target exists and is up to date
  • AND reports pass if synced, warn if targets are missing with wai sync suggestion

Scenario: Project state integrity

  • WHEN wai doctor runs and projects exist
  • THEN it validates each project’s .state file parses as valid YAML with a recognized phase
  • AND reports pass if valid, fail with the error for each invalid state file

Scenario: Custom plugin validation

  • WHEN wai doctor runs and .wai/plugins/ contains YAML files
  • THEN it validates each plugin YAML parses correctly as a PluginDef
  • AND reports pass if valid, fail with the parse error for each invalid file

Scenario: Summary output

  • WHEN all diagnostic checks complete
  • THEN the system prints a summary line with total pass, warn, and fail counts
  • AND exits with code 0 if no failures, code 1 if any failures

Scenario: Not initialized

  • WHEN user runs wai doctor outside a wai workspace
  • THEN the system reports the standard not-initialized error with wai init suggestion

Requirements

Requirement: Way Command

The CLI SHALL provide wai way to validate repository best practices and provide opinionated recommendations (“the wai way”) using a dedicated status model separate from wai doctor.

Scenario: Repository standards check

  • WHEN wai way runs
  • THEN it checks for repository best practices as defined in repository-best-practices
  • AND includes checks for task runner, git hook manager (prek/pre-commit), EditorConfig, documentation, AI instructions, llm.txt, agent skills, CI/CD, and dev containers
  • AND reports each check as WayStatus::Pass (✓) or WayStatus::Info (ℹ) with actionable suggestions

Scenario: Works without wai initialization

  • WHEN user runs wai way in any directory (wai workspace or not)
  • THEN the command succeeds and runs all repository checks
  • AND does NOT require .wai/ to exist
  • AND helps users prepare repositories before running wai init

Scenario: Summary output

  • WHEN all checks complete
  • THEN the system prints a summary: “X/Y best practices adopted”
  • AND suggests quick-start priorities if many checks are info status
  • AND always exits with code 0 (recommendations never fail)

Scenario: Output format

  • WHEN wai way runs
  • THEN output is grouped under “The wai way” header
  • AND uses ✓ (green) for WayStatus::Pass, ℹ (blue) for WayStatus::Info
  • AND each check follows format: “Category: Status (details)”
  • AND includes actionable fix text with URLs (in parentheses) for each WayStatus::Info
  • AND supports --json flag for machine-readable output
  • AND critical recommendations (missing .gitignore/README.md) display with ⚠️ marker

Scenario: Fix skills

  • WHEN user runs wai way --fix skills
  • THEN the system scaffolds missing recommended agent skills (rule-of-5-universal, commit)
  • AND skips skills that already exist
  • AND exits with code 0
  • AND does NOT run the normal check output (fix mode is separate from check mode)

Requirement: Session Close Command

wai close SHALL write a .pending-resume signal after every successful handoff creation.

Scenario: Pending-resume written on success

  • WHEN wai close successfully creates a handoff document
  • THEN the system writes .wai/projects/<project>/.pending-resume containing the path to the new handoff, relative to the project directory
  • AND this file is not mentioned in the command’s terminal output
  • AND the file appears in the uncommitted-changes list (it is a tracked workspace artifact, committed with other .wai/ changes)

Requirement: Global Workspace View

The CLI SHALL provide wai ls to scan for wai workspaces under a root directory and display each project’s phase and open issue count as a single line per project.

The expected terminal output shape is:

why-command   [review]    3 open, 2 ready
para          [plan]      7 open, 0 ready
rizomas       [implement] 1 open, 1 ready

Columns are left-aligned and padded to the longest project name in the result set. The counts column is a global toggle: it appears for ALL rows when at least one workspace has beads data (rows without beads show a blank cell), and is omitted entirely when no workspace has beads. When no workspaces are found, the system prints a single message indicating the root that was scanned. When two projects in different workspaces share the same name, a short path suffix disambiguates each: name (~/path/to/repo).

The default root is $HOME; the default depth is 3. Both are overridable via flags. The filesystem walker never follows symlinks.

Scenario: Workspaces found — table rendered

  • WHEN user runs wai ls and at least one .wai/config.toml exists under $HOME at depth ≤ 3
  • THEN the system displays one line per (workspace, project) pair
  • AND each line shows the project name, phase in brackets, and beads counts when available

Scenario: No workspaces found

  • WHEN user runs wai ls and no .wai/config.toml is found under the root
  • THEN the system prints No wai workspaces found under <root>

Scenario: Custom root

  • WHEN user runs wai ls --root <path>
  • THEN the system scans from <path> instead of $HOME

Scenario: Custom depth

  • WHEN user runs wai ls --depth <n>
  • THEN the system limits filesystem traversal to <n> levels below the root

Scenario: At least one workspace has beads — counts column shown globally

  • WHEN at least one discovered workspace has .beads/ present and bd is installed
  • THEN the counts column appears for all rows in the output
  • AND rows for projects in beads-enabled workspaces show N open, M ready
  • AND rows for projects in workspaces without beads show a blank counts cell

Scenario: No workspace has beads — counts column omitted

  • WHEN no discovered workspace has .beads/ present or bd is not installed anywhere
  • THEN the counts column is omitted entirely from the output

Scenario: Multiple projects in one workspace

  • WHEN a discovered workspace contains more than one project
  • THEN each project appears as a separate line in the output

Scenario: Duplicate project names across workspaces

  • WHEN two projects from different workspaces share the same name
  • THEN each line appends a short path suffix to disambiguate: name (~/path/to/repo)

Scenario: Invalid root path

  • WHEN user runs wai ls --root <path> and <path> does not exist
  • THEN the system fails with a diagnostic error naming the invalid path

Requirement: Session Orientation Command

wai prime SHALL detect a .pending-resume signal and render a ⚡ RESUMING block when the referenced handoff is dated today.

Scenario: Resume mode — today’s handoff

  • WHEN user runs wai prime
  • AND .wai/projects/<project>/.pending-resume exists
  • AND the referenced handoff file exists and its frontmatter date equals today’s date
  • THEN the system renders a ⚡ RESUMING block before the plugin status lines
  • AND the block shows the handoff date and one-line snippet on the first line
  • AND the block shows the contents of the handoff’s ## Next Steps section immediately below, rendered as described in “Resume mode — next steps rendering”
  • AND the normal • Handoff: line is omitted (replaced by the RESUMING block)
  • AND the .pending-resume file is NOT modified or deleted

Scenario: Resume mode — next steps rendering

  • WHEN the RESUMING block is rendered
  • THEN the Next Steps: label is printed indented two spaces from the left margin, with no ## heading markers and with a trailing colon
  • AND each content line from the ## Next Steps section is printed indented four spaces from the left margin
  • AND blank lines and lines starting with <!-- within the section are skipped

Scenario: Resume mode — next steps present

  • WHEN the handoff referenced by .pending-resume contains a ## Next Steps section with renderable content (non-blank, non-comment lines)
  • THEN the RESUMING block shows the Next Steps: label followed by the items

Scenario: Resume mode — no next steps section

  • WHEN the handoff referenced by .pending-resume does not contain a ## Next Steps section, or the section contains only blank lines and HTML comments
  • THEN the RESUMING block shows only the ⚡ RESUMING: {date} — '{snippet}' header line with no indented items

Scenario: Signal not consumed by prime

  • WHEN user runs wai prime and a RESUMING block is rendered
  • THEN the .pending-resume file is NOT modified or deleted
  • AND a subsequent wai prime call in the same session renders the same RESUMING block again

Scenario: Stale signal — not today’s handoff

  • WHEN user runs wai prime
  • AND .wai/projects/<project>/.pending-resume exists
  • AND the referenced handoff’s frontmatter date is before today, or the date field is missing or unparseable
  • THEN the system ignores the signal entirely
  • AND renders the normal • Handoff: line using the latest handoff

Scenario: Missing handoff — signal ignored

  • WHEN user runs wai prime
  • AND .pending-resume exists but the referenced file does not exist on disk
  • THEN the system ignores the signal
  • AND renders the normal • Handoff: line (or omits the line if no handoffs exist at all)

Context Suggestions

Purpose

Define context-aware suggestion patterns that help users discover the next logical step based on current project state and phase.

Problem Statement

A status command that only presents data often leaves the user with the question, “What should I do next?” Without proactive guidance, users experience decision fatigue, make suboptimal choices about where to focus effort, and lose workflow momentum. This spec proposes a Type 1 commitment to integrating a proactive suggestion system within the wai status command, bridging the gap between information and action, and making the user more effective.

Design Rationale

The suggestion system is designed to be proactive, integrated, and based on project phase awareness, representing Type 1 decisions that establish a core UX pattern.

  • Integrated with status: Placing suggestions directly within the wai status output is a deliberate Type 1 decision. It establishes a proactive UX pattern where wai guides the user immediately after reviewing the project’s state, reducing cognitive load and driving workflow.
  • Phase-Based Priority: Suggestions are driven by the current project phase (research, design, plan, implement, review, archive) and available plugin data. Each phase has natural next actions that wai can suggest contextually.

Scope, Dependencies, and Requirements

This spec defines the logic for generating suggestions within the wai status command.

Dependencies

  • Project State Machine: The suggestion logic depends on the phase definitions outlined in the project-state-machine spec.
  • Plugin System: Plugins (beads, git, openspec) provide additional context for richer suggestions.

Non-Goals

  • Implementation of suggested actions — suggestions are informational only
  • Suggestions in commands other than wai status
  • Exact UI/formatting — this spec defines logic, not presentation

Requirements

Requirement: Phase-Based Suggestions

The status command SHALL provide contextual next-step suggestions based on the current project phase. When the project is in the design phase and has a decision matrix, wai status SHALL additionally show the matrix’s current problem statement, its cell completion count, and a suggestion for the next unfilled cell.

Scenario: Research phase

  • WHEN project is in “research” phase
  • THEN suggest adding research notes: wai add research "..."
  • AND suggest advancing when ready: wai phase next

Scenario: Plan phase

  • WHEN project is in “plan” phase
  • THEN suggest adding a plan: wai add plan "..."
  • AND suggest advancing to design: wai phase next

Scenario: Design phase with a matrix

  • GIVEN a project in the design phase with a matrix having 5 of 6 cells filled
  • WHEN wai status runs
  • THEN suggestions include the problem statement, 5/6 cells filled, and a pointer to the unfilled cell

Scenario: Design phase without a matrix

  • GIVEN a project in the design phase that never initialized a matrix
  • WHEN wai status runs
  • THEN no matrix information or suggestion is shown

Requirement: Plugin-Enhanced Suggestions

When plugins are active, suggestions SHALL incorporate plugin context.

Scenario: Beads plugin active

  • WHEN beads plugin reports open issues
  • THEN status includes issue count and suggests reviewing: wai beads list

Scenario: Git plugin active

  • WHEN git plugin reports uncommitted changes
  • THEN status includes change summary

Requirement: Empty Project Suggestions

When a project has no artifacts, suggestions SHALL guide initial setup.

Scenario: New empty project

  • WHEN project has no research, plans, or designs
  • THEN suggest starting with research: wai add research "..."
  • AND suggest checking phase: wai phase

Requirement: Pipeline Suggestions

When pipelines are configured, suggestions SHALL surface pipeline discovery and recovery actions.

Scenario: Active pipeline run

  • WHEN a pipeline run is active (resolved from WAI_PIPELINE_RUN env var or .wai/resources/pipelines/.last-run)
  • THEN status emits a “⚡ PIPELINE ACTIVE: <name> step N/M” line in a Pipeline section
  • AND suggests reprinting the current step: wai pipeline current

Scenario: Pipelines available but no active run

  • WHEN no active pipeline run exists
  • AND .wai/resources/pipelines/ contains at least one valid .toml pipeline definition
  • THEN status emits an “Available pipelines” section listing each pipeline with name, description, and step count
  • AND suggests discovering pipelines: wai pipeline suggest

Scenario: Stale pipeline pointer

  • WHEN .last-run pointer exists but the referenced run file is missing
  • THEN the stale pointer is silently ignored
  • AND status falls back to the “available pipelines” or idle state

Requirement: Suggestion Output Blocks

Status output SHALL include a clearly labeled suggestion block for human and machine parsing.

Scenario: Suggestion block formatting

  • WHEN status suggestions are shown
  • THEN they appear under a Suggestions: heading
  • AND each suggestion includes a short label and a suggested command

Scenario: Suggestions as JSON

  • WHEN user runs wai status --json
  • THEN the suggestions are returned as an array with label and command fields

Requirement: Stale Phase Detection

The status command SHALL detect when a project has not advanced phases in more than 14 days and surface a suggestion to either advance or archive.

Detection criteria:

  • Current phase is NOT archive
  • Time elapsed since the current phase started exceeds 14 days
  • Applies to all non-archive phases (research, design, plan, implement, review)

Scenario: Project stuck in implement phase

  • WHEN a project is in implement phase
  • AND the phase started more than 14 days ago
  • THEN wai status includes a stale-phase suggestion
  • AND the suggestion offers wai phase next to advance
  • AND the suggestion offers wai move <name> archives to abandon

Scenario: Active project within threshold is not flagged

  • WHEN a project’s current phase started 13 days ago
  • THEN wai status does NOT include a stale-phase suggestion for that project

Scenario: Archived project is not flagged

  • WHEN a project is in archive phase regardless of elapsed time
  • THEN wai status does NOT include a stale-phase suggestion for that project

Scenario: Stale signal in JSON output

  • WHEN the user runs wai status --json and a project is stale
  • THEN the suggestions array includes an entry with a label indicating staleness
  • AND includes commands for advancing or archiving

Requirement: Completion Readiness Signal

The status command SHALL detect when a project in review phase has at least one handoff artifact and surface a suggestion to archive it.

Detection criteria:

  • Current phase is review
  • At least one handoff artifact exists in the project’s handoffs/ directory

Scenario: Review phase with handoff suggests archiving

  • WHEN a project is in review phase
  • AND the project has at least one handoff artifact
  • THEN wai status includes a completion-readiness suggestion
  • AND the suggestion offers wai move <name> archives
  • AND the suggestion offers wai phase next as an alternative

Scenario: Review phase without handoff does not trigger

  • WHEN a project is in review phase
  • AND the project has zero handoff artifacts
  • THEN wai status does NOT include a completion-readiness suggestion for that project

Scenario: Completion signal in JSON output

  • WHEN the user runs wai status --json and a project looks complete
  • THEN the suggestions array includes an entry indicating the project is ready to archive

decision-matrix Specification

Purpose

TBD - created by archiving change add-decision-matrix. Update Purpose after archive.

Requirements

Requirement: Matrix location and identity

The decision matrix SHALL be a single directory tree per project at .wai/projects/<project>/designs/matrix/. It SHALL contain problem.md (the decision being deliberated), criteria/, approaches/, and decision.md. The filesystem is the source of truth; the CLI is sugar over plain file operations.

Scenario: Init scaffolds the matrix

  • GIVEN a project without a matrix
  • WHEN wai matrix init runs with a problem statement
  • THEN designs/matrix/ contains problem.md, criteria/, approaches/01-status-quo/ with _description.md, and an empty decision.md

Scenario: One matrix per project

  • GIVEN a project that already has designs/matrix/
  • WHEN wai matrix init runs
  • THEN the command fails with an error naming the existing matrix

Requirement: Cell encoding

Each cell SHALL be the directory approaches/<approach>/<criterion>/ containing fact.md (the aspect: facts, not judgment) and exactly one judgment marker file named neutral, green, yellow, or red. A cell is incomplete if and only if fact.md is missing or empty. neutral is a legitimate judgment, distinct from incomplete.

Scenario: Neutral judgment is explicit

  • GIVEN a cell with a non-empty fact.md and a marker file named neutral
  • WHEN wai matrix lint runs
  • THEN the cell passes validation

Scenario: Multiple markers are a structural error

  • GIVEN a cell containing both green and red marker files
  • WHEN wai matrix lint runs
  • THEN lint exits non-zero and names the offending cell

Scenario: Missing fact means incomplete, not judged

  • GIVEN a cell directory with a marker but no fact.md
  • WHEN wai matrix lint runs
  • THEN the cell is reported as incomplete

Requirement: Status quo first

wai matrix init SHALL create approaches/01-status-quo/ first, and lint SHALL report an error if it is missing.

Scenario: Init creates status quo

  • GIVEN a project without a matrix
  • WHEN wai matrix init runs
  • THEN approaches/01-status-quo/_description.md exists

Requirement: Multi-operation helpers

wai matrix criterion add <name> SHALL create the criterion definition file and cell directories in every existing approach. wai matrix approach add <name> SHALL create the approach directory with _description.md and empty cell directories for every existing criterion. These exist because one logical action spans multiple directories; no command is provided for single-cell writes, which are direct file edits.

Scenario: Criterion add touches every approach

  • GIVEN a matrix with two approaches
  • WHEN wai matrix criterion add "operational-cost" runs
  • THEN criteria/NN-operational-cost.md exists
  • AND approaches/*/03-operational-cost/ exists for every approach

Requirement: Deciding produces a current-answer marker and a design doc

wai matrix decide <approach> <rationale> SHALL validate the approach directory exists, write decision.md (selected approach, rationale, date, pointer to the design doc), and scaffold a design artifact in designs/<date>-<slug>.md with standard frontmatter (tracks supported) and a decision-time snapshot of the winning column’s cell texts.

Scenario: Decide writes both artifacts

  • GIVEN a matrix with two approaches and filled cells
  • WHEN wai matrix decide "02-event-sourcing" "rationale text" runs
  • THEN decision.md names approach 02-event-sourcing
  • AND a new design artifact exists in designs/ containing the rationale and the winning column’s aspect texts

Scenario: Decide rejects unknown approach

  • GIVEN no approach directory matches the argument
  • WHEN wai matrix decide runs
  • THEN the command fails, listing valid approach names

Requirement: Deterministic HTML render on demand

wai matrix render SHALL generate a self-contained matrix.html (inline CSS, no JS) as a pure function of the directory state: problem.md banner, criteria as rows, approaches as columns, marker files as judgment chips, assessment key included. Output is deterministic (byte-identical for equal input) and is a generated view — it SHALL NOT be committed or treated as a source of truth. Empty cells render as a gray “not yet assessed” placeholder, never a judgment color.

Scenario: Same state, same output

  • GIVEN an unchanged matrix directory
  • WHEN wai matrix render runs twice
  • THEN both runs produce byte-identical HTML

Scenario: Unfilled cell is not a judgment

  • GIVEN an approach/criterion pair with no fact.md
  • WHEN wai matrix render runs
  • THEN that cell renders with a neutral “not yet assessed” placeholder that is not colored green, yellow, or red

Requirement: Structural lints

wai matrix lint SHALL enforce, as errors (non-zero exit):

  • Rectangularity: every approach directory contains a cell directory for every criterion
  • Exactly one non-empty-named marker from {neutral, green, yellow, red} per filled cell
  • No empty fact.md files
  • 01-status-quo present as first column

Scenario: Missing cell in one approach fails lint

  • GIVEN an approach directory lacking a cell directory present in the other approaches
  • WHEN wai matrix lint runs
  • THEN exit code is non-zero and the missing path is named

Requirement: Methodology lints are warnings

wai matrix lint SHALL report, as warnings that never affect exit code:

  • All-green column (possible rationalization)
  • Undistinguished columns (identical cell texts across approaches for all criteria — likely a missing criterion)
  • Subjective judgment words as the body of fact.md
  • Link-only cells (bare URL, no summary text)
  • Criteria definitions phrased as questions (trailing ?)
  • Status-quo column with no red cell (something important was missed — per Miller, “Design in Practice in Practice”)
  • Decision recorded while the selected approach has unfilled cells
  • Empty problem.md
  • Matrix files newer than the decision timestamp in decision.md (stale decision; inconclusive timestamp comparison after a fresh clone downgrades to this warning rather than a gate block)

Scenario: All-green column warns but passes

  • GIVEN one approach whose filled cells all have green markers
  • WHEN wai matrix lint runs
  • THEN a warning names the approach
  • AND exit code is 0

Scenario: Undistinguished columns warn

  • GIVEN two approaches whose cell texts are identical for every criterion
  • WHEN wai matrix lint runs
  • THEN a warning suggests a distinguishing criterion is missing

Requirement: Design-to-plan phase gate

The design → plan phase transition SHALL be blocked when a matrix exists and any of the following hold: problem.md is empty, decision.md does not record a selected approach that exists under approaches/, or any file under approaches/ or criteria/ has an mtime strictly newer than the decision UTC timestamp recorded inside decision.md. Staleness checks whose comparison is inconclusive (equal or missing timestamps, e.g. after a fresh clone) SHALL downgrade to a warning instead of blocking. The failure message SHALL be self-healing: it names the offending files and points at wai matrix decide. Projects without a matrix are never gated.

Scenario: Current decision passes the gate

  • GIVEN a matrix whose decision.md names an existing approach and no matrix file is newer than the recorded decision timestamp
  • WHEN wai phase next advances from design
  • THEN the transition proceeds

Scenario: Scaffolded decision does not pass the gate

  • GIVEN a freshly initialized matrix whose decision.md is still the template (no approach recorded)
  • WHEN the design → plan transition is attempted
  • THEN the transition is blocked
  • AND the message indicates no decision has been made

Scenario: Edited-after-decision blocks the gate

  • GIVEN a cell file modified after decision.md was written
  • WHEN the design → plan transition is attempted
  • THEN the transition is blocked
  • AND the message names the stale-decision condition and suggests wai matrix decide

Scenario: Ambiguous timestamps after a fresh clone warn instead of blocking

  • GIVEN a decided matrix checked out fresh from git so that all matrix files share the checkout timestamp
  • WHEN the design → plan transition is attempted
  • THEN the transition proceeds
  • AND a stale-decision warning is reported with a pointer to wai matrix lint

Scenario: No matrix means no gate

  • GIVEN a project that never ran wai matrix init
  • WHEN the design → plan transition is attempted
  • THEN the transition proceeds as before this change

Requirement: Status and handoff matrix awareness

wai status in the design phase SHALL show the current problem statement, cell completion count, and a suggestion for the next unfilled cell. wai close handoffs SHALL include the problem statement, the selected approach with rationale, and links to both the matrix directory and the scaffolded design doc.

Scenario: Status shows completion

  • GIVEN a matrix with 5 of 6 cells filled
  • WHEN wai status runs during the design phase
  • THEN output includes the problem statement, 5/6 cells filled, and a pointer to the unfilled cell

doctor-auto-fix Specification

Purpose

TBD - created by archiving change add-doctor-fix-flag. Update Purpose after archive.

Requirements

Requirement: Doctor command accepts –fix flag

The wai doctor command SHALL accept a --fix flag that automatically applies fixes for diagnosed issues where safe to do so.

Scenario: User runs doctor with –fix

$ wai doctor --fix

GIVEN workspace has fixable issues WHEN user runs wai doctor --fix THEN system prompts for confirmation AND applies fixes for all confirmed issues AND displays success/failure for each fix AND exits with code 0 if all succeeded, 1 if any failed


Requirement: Auto-fix respects global flags

The doctor –fix flow SHALL respect global flags for confirmation and safety.

Scenario: Skip confirmation with –yes

$ wai doctor --fix --yes

GIVEN workspace has fixable issues WHEN user runs wai doctor --fix --yes THEN system skips confirmation prompt AND applies all fixes immediately

Scenario: JSON output with –fix

$ wai doctor --fix --json

GIVEN workspace has fixable issues WHEN user runs wai doctor --fix --json THEN system outputs structured JSON with fixes_applied and fixes_failed arrays AND skips interactive confirmation

Scenario: Refuse in safe mode

$ wai doctor --fix --safe

GIVEN workspace has any state WHEN user runs wai doctor --fix --safe THEN system refuses with SafeModeViolation error AND exits with non-zero code


Requirement: Missing PARA directories are auto-fixable

The doctor –fix flow SHALL create missing directories including PARA directories, agent-config subdirectories, and resource subdirectories.

Scenario: Fix missing directories

  • GIVEN .wai/archives/ directory is missing
  • WHEN user runs wai doctor --fix --yes
  • THEN system creates .wai/archives/ directory
  • AND reports success for “Directory structure” fix

Scenario: Fix missing agent-config subdirectories

  • GIVEN .wai/resources/agent-config/skills/ directory is missing
  • WHEN user runs wai doctor --fix --yes
  • THEN system creates the missing agent-config subdirectory
  • AND reports success for “Directory structure” fix

Scenario: Fix missing resource subdirectories

  • GIVEN .wai/resources/templates/ directory is missing
  • WHEN user runs wai doctor --fix --yes
  • THEN system creates the missing resource subdirectory
  • AND reports success for “Directory structure” fix

Scenario: Fix missing default files

  • GIVEN .wai/.gitignore is missing
  • WHEN user runs wai doctor --fix --yes
  • THEN system creates the default .gitignore file
  • AND reports success for “Directory structure” fix

Requirement: Stale projections are auto-fixable

The doctor –fix flow SHALL re-sync stale projections using the appropriate strategy (symlink, inline, or reference).

Scenario: Fix stale inline projection

GIVEN a projection with strategy “inline” is out of sync WHEN user runs wai doctor --fix --yes THEN system calls sync_core::execute_inline() for that projection AND reports success for “Projection → ” fix


Requirement: Missing project .state files are auto-fixable

The doctor –fix flow SHALL create default .state files for projects that are missing them (Warn status only, not corrupted files with Fail status).

Scenario: Fix missing .state file

GIVEN project “my-project” exists without .state file WHEN user runs wai doctor --fix --yes THEN system creates .wai/projects/my-project/.state with ProjectState::default() AND reports success for “Project state: my-project” fix

Scenario: Skip corrupted .state file

GIVEN project has corrupted .state file (invalid YAML) WHEN user runs wai doctor --fix --yes THEN system does NOT overwrite the corrupted file AND reports no fix available


Requirement: Missing AGENTS.md managed block is auto-fixable

The doctor –fix flow SHALL inject the wai managed block into AGENTS.md if it exists but is missing the block.

Scenario: Fix missing managed block

GIVEN AGENTS.md exists without wai managed block WHEN user runs wai doctor --fix --yes THEN system calls inject_managed_block() with detected plugins AND reports success for “Agent instructions” fix


Requirement: Non-fixable issues are identified

The doctor –fix flow SHALL NOT attempt to fix issues that require manual intervention or external dependencies.

Scenario: Cannot fix missing plugin tools

GIVEN check reports missing CLI tool (e.g., bd not in PATH) WHEN user runs wai doctor --fix --yes THEN system does NOT attempt to install the tool AND reports “No fixable issues” (if only non-fixable issues exist)

Scenario: Cannot fix corrupted config.toml

GIVEN config.toml is missing or invalid WHEN user runs wai doctor --fix --yes THEN system does NOT attempt to create/fix config AND suggests running wai init instead

Requirement: Version staleness check

The wai doctor command SHALL compare the workspace version (from config.toml) against the running binary version and report when they differ.

Scenario: Workspace version matches binary

  • WHEN config.toml project.version equals env!("CARGO_PKG_VERSION")
  • THEN check reports Pass with message “Version current”

Scenario: Workspace version is stale

  • WHEN config.toml project.version differs from env!("CARGO_PKG_VERSION")
  • THEN check reports Warn with message showing both versions
  • AND fix suggestion says “Run: wai init (to update workspace)”

Scenario: Fix version staleness

  • WHEN user runs wai doctor --fix --yes with stale version
  • THEN system calls ensure_workspace_current to repair workspace
  • AND config.toml version is updated to current binary version
  • AND any missing directories or files are also created

Error Recovery

Purpose

Define self-healing error message patterns that suggest fixes instead of just reporting problems, making errors educational and actionable.

Problem Statement

Cryptic, unhelpful error messages are a major source of user frustration in command-line tools. When an error occurs and the application simply reports “failed” or “invalid input,” it forces the user to halt their workflow, consult external documentation, and waste time diagnosing the issue. This increases cognitive load and creates a steep, frustrating learning curve. This spec represents a Type 1 commitment to transforming this experience by making errors educational and actionable, significantly enhancing user productivity and satisfaction.

Design Rationale

The error recovery strategy for wai is to treat errors not as failures, but as opportunities to guide the user toward the correct action, representing Type 1 decisions that establish a core UX pattern and architectural dependency.

  • Actionable, “Self-Healing” Errors: This is a Type 1 decision for wai’s core user experience. Instead of just reporting what went wrong, wai errors will explain the problem and suggest the specific command to fix it. This approach makes the tool feel more like a helpful assistant and less like a rigid instruction parser, significantly reducing user friction.
  • Use of miette: The selection of the miette library is a Type 1 architectural dependency. It was chosen specifically for its ability to produce rich, diagnostic error messages with features like error codes, actionable help text, and code snippets, which are key components of our “self-healing” error philosophy.
  • Diagnostic Codes: Every wai-specific error includes a stable, machine-readable code (e.g., wai::project::not_found). This is a Type 1 decision for error identification, aiding in debugging, enabling more specific documentation, and providing a reliable way to reference errors in tests or external tools.

Scope and Requirements

This spec defines the user-facing format and content for common, recoverable errors in wai.

Non-Goals

  • Internal Error Logging: This spec focuses on the user-facing error experience and does not cover how errors are logged internally for developer analysis.
  • Automated Fixes: The system will only suggest corrective actions; it will not execute commands automatically on the user’s behalf.
  • Localization: All error messages will be presented in a single language.
  • Exhaustive Error Catalog: This document specifies the pattern for key errors but is not an exhaustive list of every possible error condition; rather, it defines the approach to error messaging.

Requirements

Requirement: Diagnostic Error Format

All errors SHALL include a diagnostic code and actionable help text using miette.

Scenario: Error structure

  • WHEN any error occurs
  • THEN the error includes a code (e.g., wai::project::not_found)
  • AND the error includes help text with a suggested fix
  • AND when --json is provided, the system outputs a JSON error object with code, message, help, and details

Requirement: Project Not Initialized Error

When commands require a project context but none exists, the error SHALL suggest initialization.

Scenario: Missing project context

  • WHEN user runs a project-scoped command outside a project
  • THEN error message is “No project initialized in current directory”
  • AND help suggests “Run wai init or wai new project <name> first”
  • AND the diagnostic code is wai::project::not_initialized

Requirement: Project Not Found Error

When a referenced project doesn’t exist, the error SHALL suggest how to find valid projects.

Scenario: Invalid project reference

  • WHEN user references a project name that doesn’t exist
  • THEN error message is “Project ‘{name}’ not found”
  • AND help suggests “Run wai show projects to see available projects”
  • AND the diagnostic code is wai::project::not_found

Requirement: Area Not Found Error

When a referenced area doesn’t exist, the error SHALL suggest alternatives.

Scenario: Invalid area reference

  • WHEN user references an area name that doesn’t exist
  • THEN error message is “Area ‘{name}’ not found”
  • AND help suggests “Run wai show areas to see available areas”
  • AND the diagnostic code is wai::area::not_found

Requirement: Resource Not Found Error

When a referenced resource doesn’t exist, the error SHALL suggest alternatives.

Scenario: Invalid resource reference

  • WHEN user references a resource name that doesn’t exist
  • THEN error message is “Resource ‘{name}’ not found”
  • AND help suggests “Run wai show resources to see available resources”
  • AND the diagnostic code is wai::resource::not_found

Requirement: Invalid Phase Transition Error

When a phase transition is invalid, the error SHALL show valid options.

Scenario: Invalid transition

  • WHEN user attempts an invalid phase transition (e.g., already at the last phase and running phase next)
  • THEN error message is “Invalid phase transition from ‘{from}’ to ‘{to}’”
  • AND help lists valid target phases from the current phase
  • AND the diagnostic code is wai::phase::invalid_transition

Requirement: Config Sync Error

When agent config sync fails, the error SHALL explain what went wrong and suggest remediation.

Scenario: Sync failure

  • WHEN a projection fails during wai sync
  • THEN error message describes which projection failed and why
  • AND help suggests checking .projections.yml configuration
  • AND the diagnostic code is wai::config::sync_failed

Requirement: Handoff Error

When handoff generation fails, the error SHALL explain the issue.

Scenario: Handoff generation failure

  • WHEN wai handoff create fails
  • THEN error message describes the failure (e.g., project not found, template missing)
  • AND help suggests the corrective action
  • AND the diagnostic code is wai::handoff::failed

Requirement: Plugin Not Found Error

When a plugin doesn’t exist, the error SHALL suggest how to find available plugins.

Scenario: Missing plugin

  • WHEN user references a plugin that isn’t installed
  • THEN error message is “Plugin ‘{name}’ not found”
  • AND help suggests “Run wai plugin list to see available plugins”
  • AND the diagnostic code is wai::plugin::not_found

Handoff System

Purpose

Define first-class handoff artifacts that capture session context, decisions, and next steps for seamless transitions between work sessions or between human and AI collaborators.

Problem Statement

Context loss between work sessions is one of the biggest productivity drains in software development. When a developer (or AI agent) picks up work, they spend significant time reconstructing what was done, what decisions were made, and what comes next. Handoff documents formalize this context transfer, but without tooling support they are inconsistently created and often incomplete. A built-in handoff system ensures that context is captured systematically and enriched with data from other tools.

Design Rationale

First-Class Artifact

Making handoffs a first-class artifact type rather than ad-hoc notes is a Type 1 decision. This ensures they have consistent structure, are stored in predictable locations, and can be enriched by plugins (e.g., beads issues, git status, openspec changes).

Template-Based Generation

Handoffs are generated from templates with frontmatter metadata. This is a Type 2 decision — templates can evolve, but the pattern of structured generation with metadata is foundational.

Plugin Enrichment

The handoff generation process calls plugin hooks to gather contextual data. This means a handoff can automatically include:

  • Open beads issues and their status
  • Recent git commits and uncommitted changes
  • OpenSpec changes in progress

Scope and Requirements

This spec covers the handoff artifact format, generation command, and plugin integration points.

Non-Goals

  • Automatic handoff generation (handoffs are explicitly created by the user)
  • Handoff consumption or parsing by other tools
  • Multi-format output (PDF, HTML, etc.)
  • Collaborative editing of handoffs

Requirement: Handoff Format

Handoffs SHALL be markdown files with structured frontmatter, including dedicated sections for operational nuances that serve as high-signal input to wai reflect.

Scenario: Handoff file structure

  • WHEN a handoff is generated
  • THEN it follows this format:
    ---
    date: 2026-01-22
    project: my-project
    phase: implement
    agent: claude
    ---
    
    # Session Handoff
    
    ## What Was Done
    <!-- Summary of completed work -->
    
    ## Key Decisions
    <!-- Decisions made and rationale -->
    
    ## Gotchas & Surprises
    <!-- What behaved unexpectedly? Non-obvious requirements? Hidden dependencies? -->
    
    ## What Took Longer Than Expected
    <!-- Steps that needed multiple attempts. Commands that failed before the right one. -->
    
    ## Open Questions
    <!-- Unresolved questions -->
    
    ## Next Steps
    <!-- Prioritized list of what to do next -->
    
    ## Context
    <!-- Plugin-enriched context (beads, git, etc.) -->
    

Requirement: Handoff Generation

The CLI SHALL provide a command to generate handoff documents.

Scenario: Create handoff

  • WHEN user runs wai handoff create <project>
  • THEN the system generates a handoff from the default template
  • AND enriches it with data from enabled plugins
  • AND stores it in .wai/projects/<project>/handoffs/YYYY-MM-DD-session-end.md

Scenario: Handoff with plugin data

  • WHEN generating a handoff with the beads plugin enabled
  • THEN the Context section includes open beads issues and their status
  • WHEN generating a handoff with the git plugin enabled
  • THEN the Context section includes recent commits and uncommitted changes

Requirement: Handoff Storage

Handoffs SHALL be stored in the project’s handoffs directory with date prefixes.

Scenario: Handoff location

  • WHEN a handoff is created for project “my-app”
  • THEN it is stored at .wai/projects/my-app/handoffs/YYYY-MM-DD-session-end.md
  • AND multiple handoffs per day are differentiated by suffix

Requirements

Requirement: Pending-Resume Signal

wai close SHALL write a .pending-resume file to the project directory after every successful handoff creation, enabling wai prime to detect resume context without requiring the user to manually open the handoff.

Scenario: Signal written on close

  • WHEN wai close successfully creates a handoff
  • THEN the system writes .wai/projects/<project>/.pending-resume
  • AND the file contains the path to the new handoff, relative to the project directory (e.g. handoffs/2026-02-24-session-end.md)

Scenario: Signal overwritten on repeated close

  • WHEN user runs wai close more than once (same day or different days)
  • THEN the .pending-resume file is overwritten with the path of the newest handoff

Requirement: Handoff Decision-Matrix Summary

When the project has a decision matrix, handoffs SHALL additionally include a decision-matrix summary: the problem statement, the selected approach with rationale (or “not decided yet”), the matrix directory link with cell completion count, and the scaffolded design doc link when a decision exists.

Scenario: Handoff includes matrix summary

  • GIVEN a project with a matrix whose decision.md records a decision
  • WHEN a handoff is generated
  • THEN it includes the problem statement, the selected approach with rationale, and links to the matrix directory and the design doc

Scenario: Handoff without a matrix

  • GIVEN a project that never initialized a matrix
  • WHEN a handoff is generated
  • THEN no matrix section is added and the format is unchanged

Help System

Purpose

Define progressive disclosure patterns for help and command output, showing simple information by default with more detail available on demand.

Problem Statement

Effective command-line tools require an intuitive and helpful user assistance system. Without one, users face a steep learning curve, leading to frustration and inefficient use. This spec addresses the need for a help system that serves both audiences effectively by being clear, concise, and progressively more detailed on demand, representing a Type 1 commitment to an improved user experience. A “one-size-fits-all” help output is insufficient, being either too verbose for novices trying to perform a simple task, or too sparse for experts needing advanced details.

Design Rationale

The design of the help system is centered on the principle of progressive disclosure, which represents a Type 1 architectural decision for help content structure and rendering logic, significantly enhancing usability for all user levels.

  • Progressive Disclosure: By default, help is concise and focused on common use cases. Users can request more detail using verbosity flags (-v, -vv). This commits to a layered content structure and respects the user’s attention, avoiding overwhelming them with irrelevant information while still making advanced details accessible. This pattern is consistent with the CLI’s global verbosity flags.
  • In-line Usage Examples: Including practical examples directly within the help output is a highly effective way to teach users how to perform common tasks, reducing the need to consult external documentation.
  • Adherence to Convention: Using the standard --help and -h flags ensures that the help system is immediately familiar and predictable to anyone with prior CLI experience.

Scope and Requirements

This spec defines the user-facing behavior and output structure of the CLI’s help system.

Non-Goals

  • Help Content Generation: This spec defines the desired output and behavior of the help system. The internal mechanism for authoring and maintaining help text is an implementation detail not covered here.
  • Interactive Help Systems: Features like a man-style pager, guided tutorials, or interactive prompts are out of scope.
  • Localization: Translating help content into multiple languages is not covered by this specification.
  • Web-based Documentation: This spec is limited to the help available directly within the CLI application.

Requirements

Requirement: Basic Help

All commands SHALL provide --help with usage examples.

Scenario: Root help

  • WHEN user runs wai --help or wai -h
  • THEN the system shows a brief description of wai
  • AND lists all top-level commands with one-line descriptions
  • AND shows global flags (-v, -q, --help, --version, --json, --no-input, --yes, --safe)

Scenario: Command help

  • WHEN user runs wai <command> --help
  • THEN the system shows command description, arguments, and options
  • AND includes at least one usage example

Scenario: Subcommand help

  • WHEN user runs wai <command> <subcommand> --help
  • THEN the system shows subcommand-specific description and options
  • AND includes examples relevant to that subcommand

Scenario: No arguments shows contextual help

  • WHEN user runs wai with no arguments
  • THEN the system defers to onboarding behavior for context-aware output

Requirement: Usage Examples

All help output SHALL include practical usage examples.

Scenario: Command examples

  • WHEN user views help for any command
  • THEN the help includes an “Examples” section
  • AND examples show realistic use cases with expected outcomes

Scenario: Example formatting

  • WHEN examples are displayed
  • THEN each example shows the command invocation
  • AND optionally includes a brief explanation of what it does

Requirement: Progressive Disclosure

Help SHALL support brief and detailed modes for different user needs.

Scenario: Brief help (default)

  • WHEN user runs wai <command> --help
  • THEN the system shows concise help focused on common usage
  • AND omits advanced options and edge cases

Scenario: Detailed help

  • WHEN user runs wai <command> --help --verbose or wai <command> --help -v
  • THEN the system shows comprehensive help including all options
  • AND includes advanced usage patterns and configuration details

Scenario: Help verbosity levels

  • WHEN user increases verbosity (-v, -vv, -vvv)
  • THEN help output includes progressively more detail:
    • -v: all options including advanced ones
    • -vv: adds environment variables and configuration
    • -vvv: adds internal details and debugging information

managed-block Specification

Purpose

TBD - created by archiving change add-managed-block-openspec-checklist. Update Purpose after archive.

Requirements

Requirement: Openspec step in session-close checklist

The generated WAI block’s session-close checklist SHALL include a step to mark completed openspec tasks [x] when the openspec plugin is detected. The step SHALL appear after the beads steps (if present) and before wai reflect.

Scenario: Openspec detected at init time

  • WHEN wai init or wai reflect runs
  • AND the openspec plugin is detected
  • THEN the generated WAI block’s “Ending a Session” checklist includes: [ ] openspec tasks.md — mark completed tasks [x]

Scenario: Openspec not detected

  • WHEN wai init or wai reflect runs
  • AND the openspec plugin is NOT detected
  • THEN the generated WAI block does NOT include the openspec checklist step

Requirement: Cross-tool tracking convention

When both beads and openspec plugins are detected, the generated WAI block SHALL include a “Tracking Work Across Tools” section that defines the cross-reference convention for linking beads tickets to openspec task IDs.

The section SHALL appear after the “Capturing Work” section and before “Ending a Session”.

The convention SHALL specify:

  • When creating a beads ticket for an openspec task, include the task reference (format: <change-id>:<phase>.<task>, e.g. add-why-command:7.1) in the ticket description.
  • When closing a beads ticket linked to an openspec task, also check the corresponding box ([x]) in the change’s tasks.md.

Scenario: Both plugins detected

  • WHEN wai init or wai reflect runs
  • AND both beads and openspec plugins are detected
  • THEN the generated WAI block includes a “Tracking Work Across Tools” section with the cross-reference format and sync rule

Scenario: Only one plugin detected

  • WHEN wai init or wai reflect runs
  • AND only one of beads or openspec is detected (not both)
  • THEN the “Tracking Work Across Tools” section is NOT included

Requirement: Pre-claim implementation check

The generated WAI block’s “Starting a Session” section SHALL include a pre-claim guard (when beads is detected) reminding the agent to verify an issue is not already implemented before claiming it.

Scenario: Beads detected — pre-claim note present

  • WHEN wai init or wai reflect runs
  • AND the beads plugin is detected
  • THEN the “Starting a Session” section includes a note after bd ready that reads: before claiming an issue, read the relevant source files to confirm the work is not already done

Scenario: Beads not detected — no pre-claim note

  • WHEN wai init or wai reflect runs
  • AND the beads plugin is NOT detected
  • THEN no pre-claim note is included

Requirement: Epic closure reminder in session-close checklist

The generated WAI block’s session-close checklist bd close step SHALL include a note (when beads is detected) to also close the parent epic when the last sub-task of a group is completed.

Scenario: Beads detected — epic note on close step

  • WHEN wai init or wai reflect runs
  • AND the beads plugin is detected
  • THEN the bd close <id> checklist step includes an inline comment noting that parent epics should be closed when their last sub-task is done

Scenario: Beads not detected — no epic note

  • WHEN wai init or wai reflect runs
  • AND the beads plugin is NOT detected
  • THEN no epic closure reminder is included

Requirement: Available Pipelines in managed block

The generated WAI block SHALL include an “Available Pipelines” section when pipelines with [pipeline.metadata] are installed, listing each pipeline’s name, when description, and start command. The section SHALL also note that pipeline steps may have gates and reference wai pipeline gates for gate details.

Scenario: Pipelines with metadata installed

  • WHEN wai init runs
  • AND .wai/resources/pipelines/ contains one or more pipelines with [pipeline.metadata]
  • THEN the generated WAI block includes an “Available Pipelines” table with columns: Pipeline, When to Use, Start command
  • AND a note: “Pipeline steps have gates that enforce artifact creation, review coverage, and oracle checks before advancement.”

Scenario: No pipelines installed

  • WHEN wai init runs
  • AND no pipelines exist in .wai/resources/pipelines/
  • THEN no “Available Pipelines” section is generated

Scenario: Pipeline without metadata

  • WHEN a pipeline exists but lacks [pipeline.metadata]
  • THEN that pipeline is NOT included in the “Available Pipelines” table
  • AND wai doctor warns about the missing metadata

Requirement: Managed block staleness detection

wai doctor SHALL detect when the managed block in CLAUDE.md or AGENTS.md is out of date relative to the current workspace state (installed pipelines, plugins, skills). Detection SHALL compare the generated block content against the actual content between WAI:START and WAI:END markers.

Scenario: Block is stale after pipeline added

  • WHEN wai doctor runs
  • AND a pipeline with metadata has been added since the last wai init
  • AND the CLAUDE.md managed block does not include that pipeline
  • THEN doctor reports warning: “CLAUDE.md managed block outdated — run ‘wai init’ to refresh”

Scenario: Block is current

  • WHEN wai doctor runs
  • AND the managed block content matches what would be generated
  • THEN no staleness warning is reported

Scenario: AGENTS.md also checked

  • WHEN wai doctor runs
  • AND AGENTS.md exists with WAI:START/WAI:END markers
  • THEN staleness detection runs on AGENTS.md as well

Scenario: User-modified managed block always shows stale

  • WHEN wai doctor runs
  • AND the user has manually edited content between WAI:START and WAI:END markers
  • THEN doctor reports the block as outdated
  • AND running wai init will overwrite the user’s modifications (content between markers is managed by wai)

Onboarding

Purpose

Define the first-run experience and welcome flow that helps new users get started quickly with wai.

This spec owns the no-args welcome behavior for both first-run (no project) and in-project contexts.

Problem Statement

The initial user experience with a new command-line tool can be a significant barrier to adoption. If a user runs wai for the first time without arguments and is met with a cryptic error, an overwhelming help page, or an unhelpful generic message, it can lead to frustration, confusion, and ultimately, abandonment of the tool. This spec represents a Type 1 commitment to improving this fundamental user experience. Even experienced users inside a project might run wai without arguments and benefit from quick, context-relevant reminders or next steps rather than a full help display.

Design Rationale

The onboarding experience is designed to be intuitive, context-aware, and minimalist, providing immediate value without unnecessary complexity. The Context-Aware “No-Args” Behavior is a Type 1 decision for the fundamental user experience.

  • Context-Aware “No-Args” Behavior: Tailoring the output based on whether a project exists (.wai/ directory) provides immediate, relevant guidance. For first-time users, it suggests how to begin; for in-project users, it offers quick access to common next actions. This avoids generic responses, reduces user friction, and establishes a proactive engagement pattern.
  • Minimalist Guidance: Instead of an interactive wizard or verbose documentation, the system offers direct, actionable command suggestions. This respects the CLI user’s preference for efficiency and direct control, allowing them to quickly engage with the tool.

Scope and Requirements

This spec exclusively defines the output and suggested actions when the wai command is executed without any arguments.

Non-Goals

  • Full Implementation of Suggested Commands: This spec outlines what to suggest, but not the detailed implementation of commands like wai init or wai new project.
  • Interactive Setup Wizards: The onboarding process is non-interactive, relying on clear textual suggestions.
  • Complex User Preference Tracking: This spec does not cover tracking user preferences or progress beyond detecting the presence of a project.

Requirements

Requirement: Welcome Screen

When wai is run without arguments and no project is detected, it SHALL show a welcoming entry point.

Scenario: No project detected

  • WHEN user runs wai with no arguments
  • AND no .wai/ directory exists in current or parent directories
  • THEN the system shows “wai - Workflow manager for AI-driven development”
  • AND shows context: “No project detected in current directory”
  • AND suggests: wai init, wai new project, wai --help
  • AND includes a note that detailed help is available via wai --help

Requirement: Project Context Welcome

When wai is run without arguments inside a project, it SHALL show project-relevant suggestions.

Scenario: Inside project

  • WHEN user runs wai with no arguments
  • AND a .wai/ directory exists
  • THEN the system suggests: wai status, wai phase, wai new project
  • AND includes a note that detailed help is available via wai --help

Requirement: Comprehensive re-initialization

When wai init is run in an already-initialized workspace, it SHALL comprehensively repair the workspace to match the current version’s expectations, not just update config and managed blocks.

Scenario: Re-init creates missing directories

  • WHEN user runs wai init in an initialized workspace
  • AND some expected directories are missing (e.g. .wai/resources/agent-config/skills/)
  • THEN system creates all missing directories
  • AND reports what was created

Scenario: Re-init creates missing default files

  • WHEN user runs wai init in an initialized workspace
  • AND .wai/.gitignore or .wai/resources/agent-config/.projections.yml is missing
  • THEN system creates the missing default files
  • AND does not overwrite existing files

Scenario: Re-init updates version

  • WHEN user runs wai init in an initialized workspace
  • AND config.toml version differs from binary version
  • THEN system updates config.toml version to current binary version

Scenario: Re-init is idempotent

  • WHEN user runs wai init twice in succession
  • THEN the second run produces no errors
  • AND the workspace state is identical after both runs

PARA Structure

Purpose

Define the PARA-based organizational structure for wai, where artifacts are categorized into Projects, Areas, Resources, and Archives within the .wai/ directory.

Problem Statement

Development workflows generate diverse artifacts — research notes, design documents, plans, handoffs, and configuration files. Without a consistent organizational framework, these artifacts become scattered and hard to find, leading to context loss between sessions and across team members. The PARA method (Projects, Areas, Resources, Archives) provides a proven categorization framework that maps naturally to how developers think about their work: active projects with defined outcomes, ongoing areas of responsibility, reference resources, and completed/inactive items.

Design Rationale

PARA Method

The PARA categorization (Projects, Areas, Resources, Archives) is a Type 1 foundational decision for wai’s organizational model. It was selected because:

  • Projects have defined outcomes and timelines, matching active development work
  • Areas represent ongoing responsibilities without end dates (e.g., infrastructure, documentation standards)
  • Resources hold reference material used across projects (agent configs, templates, patterns)
  • Archives preserve completed or inactive items for future reference

This four-category model is simple enough to learn immediately yet expressive enough to handle real-world complexity.

Per-Project Subdirectories

Each project contains standard subdirectories (research/, plans/, designs/, handoffs/) to provide consistent internal structure. This is a Type 2 decision — the specific subdirectories may evolve, but the pattern of structured subdirectories is foundational.

Date-Prefixed Filenames

Artifacts use date-prefixed filenames (e.g., 2026-01-20-initial-research.md) for chronological sorting. This convention enables timeline views and makes recency immediately visible in file listings.

Scope and Requirements

This spec defines the directory structure and organizational rules for artifacts within .wai/.

Non-Goals

  • Content format of individual artifacts (covered by other specs)
  • Full-text search across artifacts (covered by timeline-search spec)
  • State machine for project phases (covered by project-state-machine spec)
  • Plugin storage and configuration (covered by plugin-system spec)

Requirement: PARA Directory Structure

The .wai/ directory SHALL organize artifacts into four PARA categories.

Scenario: Initialize PARA structure

  • WHEN user runs wai init
  • THEN the system creates the following directory structure:
    .wai/
    ├── config.toml
    ├── projects/
    ├── areas/
    ├── resources/
    │   ├── agent-config/
    │   ├── templates/
    │   └── patterns/
    ├── archives/
    └── plugins/
    

Requirement: Project Structure

Each project SHALL have a consistent internal directory structure.

Scenario: Create new project

  • WHEN user runs wai new project <name>
  • THEN the system creates:
    .wai/projects/<name>/
    ├── .state
    ├── research/
    ├── plans/
    ├── designs/
    └── handoffs/
    
  • AND initializes .state with the default phase

Scenario: Create new area

  • WHEN user runs wai new area <name>
  • THEN the system creates:
    .wai/areas/<name>/
    ├── research/
    └── plans/
    

Scenario: Create new resource

  • WHEN user runs wai new resource <name>
  • THEN the system creates the directory .wai/resources/<name>/

Requirement: Date-Prefixed Filenames

Artifacts SHALL use date-prefixed filenames for chronological sorting.

Scenario: Add artifact with date prefix

  • WHEN user adds a research note, plan, design, or handoff
  • THEN the filename follows the pattern YYYY-MM-DD-<slug>.md
  • AND the artifact is sorted chronologically in directory listings

Requirement: Archival

Items SHALL be movable to archives to keep active categories clean.

Scenario: Archive a project

  • WHEN user runs wai move <project> archives
  • THEN the system moves the project directory from projects/ to archives/
  • AND preserves all project contents and history

Scenario: Archive an area

  • WHEN user runs wai move <area> archives
  • THEN the system moves the area directory from areas/ to archives/

pipeline-resource Specification

Purpose

TBD - created by archiving change add-pipeline-resource. Update Purpose after archive.

Requirements

Requirement: Pipeline Definition

The CLI SHALL support defining ordered multi-skill pipelines where each stage declares the skill to invoke and the artifact type it produces.

Scenario: Create a pipeline

  • WHEN user runs: wai pipeline create issue-pipeline --stages="issue/gather:research,issue/create:tickets,issue/review:audit"
  • THEN the system saves the pipeline definition in .wai/resources/pipelines/issue-pipeline.yml
  • AND validates that each stage references a known skill name

Scenario: Invalid stage format rejected

  • WHEN a --stages value contains an entry without the skill:artifact format
  • THEN the system rejects it with a clear error showing the expected format

Requirement: Pipeline Run Lifecycle

The CLI SHALL support running a pipeline and tracking per-step completion.

Scenario: Start a pipeline run

  • WHEN user runs wai pipeline start issue-pipeline --topic="ant-forager"
  • THEN the system validates the pipeline definition (blocking on errors)
  • AND generates a run ID (e.g., issue-pipeline-2026-02-25-ant-forager)
  • AND stores initial run state in .wai/pipeline-runs/<run-id>.yml
  • AND outputs the run ID and a hint to invoke the first step

Scenario: Step artifact tagged with run and step ID

  • WHEN a skill runs in the context of a pipeline run
  • AND the environment variable WAI_PIPELINE_RUN=<run-id> is set or .wai/.pipeline-run exists
  • AND the skill calls any wai add <type> command (research, plan, design, review, or handoff)
  • THEN the artifact is automatically tagged with pipeline-run:<run-id> and pipeline-step:<step-id>

Scenario: Advance pipeline to next step

  • WHEN user runs wai pipeline next
  • AND all configured gates for the current step pass (or no gates configured)
  • THEN the system marks the current step complete
  • AND outputs the next step prompt (or completion message if last step)

Scenario: Advance blocked by gate failure

  • WHEN user runs wai pipeline next
  • AND a gate check fails
  • THEN the system does NOT advance
  • AND outputs the failure reason and suggests corrective action

Scenario: Advance past last step rejected

  • WHEN user runs wai pipeline next
  • AND all steps are already marked complete
  • THEN the system errors with a message indicating the pipeline run is finished
  • AND suggests starting a new run with wai pipeline start

Scenario: Advance with unknown run ID

  • WHEN user runs wai pipeline next
  • AND no active run exists
  • THEN the system errors with a clear message and lists available pipelines

Requirement: Pipeline Status

The CLI SHALL provide a status view showing per-run, per-stage completion state.

Scenario: View pipeline status

  • WHEN user runs wai pipeline status issue-pipeline
  • THEN the system lists all runs with per-stage status:
    • Stage name and skill
    • Status: pending / complete
    • Artifact path (if complete)

Scenario: View single run detail

  • WHEN user runs wai pipeline status issue-pipeline --run <run-id>
  • THEN the system shows detailed state for that run only

Requirement: Step-Level Artifact Tagging

Artifacts created during a pipeline run SHALL be tagged with both pipeline-run:<run-id> and pipeline-step:<step-id> where step-id is the ID of the currently active step in the run state.

Scenario: Artifact created during active step

  • WHEN wai add research "findings" is called
  • AND a pipeline run is active with run ID sci-2026-04-02-qcd
  • AND the current step is describe
  • THEN the artifact frontmatter includes: tags: [pipeline-run:sci-2026-04-02-qcd, pipeline-step:describe]

Scenario: No active pipeline run

  • WHEN wai add research "findings" is called
  • AND no pipeline run is active
  • THEN no pipeline tags are injected (existing behavior unchanged)

Scenario: Retroactive tagging not supported

  • WHEN wai pipeline next advances from step decompose to step generate
  • AND the user then creates an artifact intended for step decompose
  • THEN the artifact is tagged with pipeline-step:generate (the current step)
  • AND the user must use --tags pipeline-step:decompose to override manually

Requirement: Review Artifact Type

The CLI SHALL support a review artifact type created via wai add review. Review artifacts SHALL have structured frontmatter with reviews (target artifact filename, scoped to the current project), verdict (pass, fail, or needs-work), and optional severity (object with critical, high, medium, low counts) and produced_by (skill name) fields. The --reviews target SHALL be validated against existing artifacts in the current project at creation time.

Scenario: Create a review artifact

  • WHEN user runs wai add review "Accuracy: all citations verified..." --reviews 2026-04-02-nlo-structure.md
  • AND 2026-04-02-nlo-structure.md exists in the current project
  • THEN the system creates a file in .wai/projects/<project>/reviews/
  • AND the frontmatter includes reviews: 2026-04-02-nlo-structure.md

Scenario: Review with structured metadata

  • WHEN user runs wai add review "..." --reviews artifact.md --verdict pass --produced-by ro5 --severity critical:0,high:1,medium:3,low:2
  • THEN the frontmatter includes:
    reviews: artifact.md
    verdict: pass
    produced_by: ro5
    severity: {critical: 0, high: 1, medium: 3, low: 2}
    
  • AND produced_by is informational only (no automatic severity parsing)
  • AND --severity accepts comma-separated level:count pairs; omitted levels default to 0

Scenario: Review without target rejected

  • WHEN user runs wai add review "..." without --reviews
  • THEN the system rejects with error: “review requires –reviews ”

Scenario: Invalid verdict rejected

  • WHEN user runs wai add review "..." --reviews x.md --verdict excellent
  • THEN the system rejects with error listing valid values: pass, fail, needs-work

Scenario: Review target does not exist

  • WHEN user runs wai add review "..." --reviews nonexistent.md
  • AND no artifact named nonexistent.md exists in the current project
  • THEN the system rejects with error: “artifact ‘nonexistent.md’ not found in project ‘’”

Requirement: Pipeline Gate Protocol

The CLI SHALL evaluate pipeline gates in strict order when wai pipeline next is called on a step with gates configured. A gate is a validation check on a pipeline step. Gates are organized into four tiers: structural (artifact existence), procedural (review coverage), oracle (domain-specific checks), and approval (human checkpoint). The first failing tier SHALL block advancement with a descriptive reason. Steps without gates SHALL advance freely (existing behavior).

Scenario: Structural gate blocks on missing artifacts

  • WHEN step generate declares [steps.gate.structural] with min_artifacts = 1, types = ["research"]
  • AND user runs wai pipeline next
  • AND no research artifacts exist tagged with this step and run
  • THEN advancement is blocked with message: “Step ‘generate’ requires at least 1 research artifact(s). Found 0.”

Scenario: Procedural gate blocks on missing review

  • WHEN step declares [steps.gate.procedural] with require_review = true
  • AND a research artifact exists for this step
  • AND no review artifact references that research artifact
  • THEN advancement is blocked with message: “Artifact ‘2026-04-02-findings.md’ has no review.”

Scenario: Procedural gate scopes reviewable types

  • WHEN step declares [steps.gate.procedural] with require_review = true and review_types = ["research", "plan"]
  • AND a research artifact and a design artifact exist for this step
  • THEN the procedural gate requires a review for the research artifact
  • AND the design artifact is not required to have a review (not in review_types)

Scenario: Procedural gate defaults exclude reviews

  • WHEN step declares [steps.gate.procedural] with require_review = true and no review_types
  • THEN the procedural gate requires reviews for all artifact types EXCEPT review artifacts
  • AND review artifacts are never required to have reviews of their own

Scenario: Procedural gate blocks on severity threshold

  • WHEN step declares [steps.gate.procedural] with max_critical = 0
  • AND a review artifact exists with severity: {critical: 2}
  • THEN advancement is blocked with message: “Review of ‘findings.md’ has 2 critical findings (max: 0).”

Scenario: Oracle gate blocks on script failure

  • WHEN step declares an oracle named dimensional-analysis
  • AND the oracle script exits with code 1 and stderr “Dimensional mismatch in eq. 14”
  • THEN advancement is blocked with message: “Oracle ‘dimensional-analysis’ failed for ‘findings.md’: Dimensional mismatch in eq. 14”

Scenario: Oracle timeout

  • WHEN an oracle declares timeout = 30
  • AND the oracle script does not exit within 30 seconds
  • THEN the oracle is killed and treated as a failure with message: “Oracle ‘name’ timed out after 30s”

Scenario: Approval gate blocks until approved

  • WHEN step declares [steps.gate.approval] with required = true
  • AND all other gates pass
  • AND the step has not been approved via wai pipeline approve
  • THEN advancement is blocked with message: “This step requires human approval. Run ‘wai pipeline approve’ when ready.”

Scenario: Approval gate passes after approval

  • WHEN wai pipeline approve has been run for the current step
  • AND all other gates pass
  • THEN wai pipeline next advances to the next step

Scenario: Approval invalidated by new artifacts

  • WHEN wai pipeline approve has been run for the current step
  • AND new artifacts are created for this step after the approval timestamp
  • THEN the approval is invalidated
  • AND wai pipeline next blocks with message: “Approval invalidated — new artifacts created after approval. Run ‘wai pipeline approve’ again.”

Scenario: No gates configured

  • WHEN a step has no gate configuration in TOML
  • THEN wai pipeline next advances immediately (existing behavior)

Requirement: Oracle Script Resolution

Oracle gates SHALL resolve scripts by name from .wai/resources/oracles/. Resolution SHALL probe for <name>, <name>.sh, and <name>.py in order, selecting the first match. Resolved scripts MUST be executable (shebang + executable permission) and SHALL be invoked directly, not via an interpreter prefix. An explicit command field in the oracle TOML SHALL override name resolution and is executed as-is via the shell.

Scenario: Name-based resolution with executable script

  • WHEN oracle declares name = "dimensional-analysis" without command
  • AND .wai/resources/oracles/dimensional-analysis.py exists and is executable
  • THEN the system executes .wai/resources/oracles/dimensional-analysis.py <artifact-path>

Scenario: Explicit command override

  • WHEN oracle declares name = "custom-check" with command = "python research/validate.py"
  • THEN the system executes python research/validate.py <artifact-path> via the shell
  • AND name resolution is skipped

Scenario: Oracle not found

  • WHEN oracle declares name = "nonexistent" without command
  • AND no file matching the name exists in .wai/resources/oracles/
  • THEN wai pipeline validate reports a warning
  • AND the oracle gate fails at runtime with: “Oracle ‘nonexistent’ not found in .wai/resources/oracles/”

Scenario: Ambiguous oracle resolution

  • WHEN oracle declares name = "check" without command
  • AND both .wai/resources/oracles/check.sh and .wai/resources/oracles/check.py exist
  • THEN the system selects the first match in probe order (check.sh)
  • AND wai pipeline validate reports a warning: “oracle ‘check’ has multiple matches, using ‘check.sh’”

Scenario: Oracle not executable

  • WHEN oracle resolves to .wai/resources/oracles/check.py
  • AND the file is not executable (missing execute permission)
  • THEN the oracle gate fails with: “Oracle ‘check’ is not executable. Run: chmod +x .wai/resources/oracles/check.py”

Scenario: Cross-artifact oracle

  • WHEN oracle declares scope = "all"
  • THEN the system invokes the oracle once, passing all matching artifact paths as arguments: <oracle> <path1> <path2> ... <pathN>
  • AND the oracle can read all artifacts for cross-artifact consistency checks (e.g., notation consistency, conservation laws)

Scenario: Default oracle scope is per-artifact

  • WHEN oracle does not declare scope
  • THEN the system invokes the oracle once per applicable artifact: <oracle> <artifact-path>

Requirement: Pipeline Show Command

The CLI SHALL support wai pipeline show <name> displaying the pipeline description, metadata, steps, and per-step gate configuration.

Scenario: Show pipeline with gates

  • WHEN user runs wai pipeline show scientific-research
  • THEN the system displays: pipeline name, description, metadata (when, skills), step list with gate summary per step (e.g., “structural + procedural + oracles + approval”), and oracle directory path

Scenario: Show nonexistent pipeline

  • WHEN user runs wai pipeline show nonexistent
  • THEN the system errors with message listing available pipelines

Requirement: Pipeline Gates Command

The CLI SHALL support wai pipeline gates [pipeline-name] [--step=<id>] to show gate requirements and live status. With an active run (and no arguments), it shows live status for the current step. Without an active run, the pipeline name is required and --step selects the step to display.

Scenario: Gates with active run

  • WHEN a pipeline run is active at step generate-validate-accrue
  • AND user runs wai pipeline gates
  • THEN the system displays each gate tier with pass/fail/blocked status and counts (e.g., “✗ min 1 research artifact — found 0”)

Scenario: Gates without active run

  • WHEN no pipeline run is active
  • AND user runs wai pipeline gates scientific-research --step=generate-validate-accrue
  • THEN the system displays gate definitions (not live status) for that step

Scenario: Gates on step without gates

  • WHEN a pipeline run is active at a step with no gate configuration
  • AND user runs wai pipeline gates
  • THEN the system displays: “No gates configured for step ‘’.”

Scenario: Gates without active run and no pipeline name

  • WHEN no pipeline run is active
  • AND user runs wai pipeline gates without arguments
  • THEN the system errors: “No active pipeline run. Specify a pipeline name: wai pipeline gates ”

Requirement: Pipeline Check Command

The CLI SHALL support wai pipeline check to evaluate all gates for the current step without advancing. An optional --oracle=<name> flag SHALL run a single oracle against all applicable artifacts. Output SHALL include per-tier status with pass/fail/blocked indicators and a summary result.

Scenario: Check all gates

  • WHEN user runs wai pipeline check
  • THEN the system evaluates structural, procedural, oracle, and approval gates
  • AND reports pass/fail/blocked per tier with details (counts, reasons)
  • AND reports a summary: “Result: PASS” or “Result: BLOCKED — resolve N failures”
  • AND does NOT advance the step

Scenario: Check on step without gates

  • WHEN user runs wai pipeline check
  • AND the current step has no gate configuration
  • THEN the system reports: “No gates configured for step ‘’. Result: PASS”

Scenario: Check single oracle

  • WHEN user runs wai pipeline check --oracle=dimensional-analysis
  • THEN the system runs only that oracle against all applicable artifacts
  • AND reports per-artifact pass/fail with stderr output on failure

Requirement: Pipeline Approve Command

The CLI SHALL support wai pipeline approve to record human approval for the current step. Approval SHALL be stored as a timestamp in the run state YAML. Approval is invalidated if any artifact tagged with the current step has a creation timestamp later than the approval timestamp.

Scenario: Approve current step

  • WHEN a pipeline run is active
  • AND user runs wai pipeline approve
  • THEN the run state records an approval timestamp for the current step
  • AND the system confirms: “Approved step ‘step-id’. Run ‘wai pipeline next’ to advance.”

Scenario: Approve without active run

  • WHEN no pipeline run is active
  • AND user runs wai pipeline approve
  • THEN the system errors: “No active pipeline run.”

Requirement: Pipeline Validate Command

The CLI SHALL support wai pipeline validate [name] to check pipeline TOML definitions for correctness. Validation SHALL also run during wai doctor and before wai pipeline start.

Scenario: Validate a valid pipeline

  • WHEN user runs wai pipeline validate scientific-research
  • AND the TOML is well-formed with valid gates and existing oracles
  • THEN the system reports success with step count and gate summary

Scenario: Validate catches missing metadata

  • WHEN a pipeline lacks [pipeline.metadata]
  • THEN validation reports warning: “missing [pipeline.metadata] — pipeline won’t appear in managed block”

Scenario: Validate catches missing oracle

  • WHEN a pipeline references oracle check-dims and no matching file exists
  • THEN validation reports warning: “gate oracle ‘check-dims’ — command not found”

Scenario: Validate catches non-executable oracle

  • WHEN a pipeline references oracle check-dims and the file exists but is not executable
  • THEN validation reports warning: “gate oracle ‘check-dims’ — not executable”

Scenario: Validate catches duplicate names

  • WHEN two TOML files declare the same pipeline.name
  • THEN validation reports error: “duplicate pipeline name”

Scenario: Start blocked by validation errors

  • WHEN user runs wai pipeline start broken-pipeline --topic="test"
  • AND the pipeline has validation errors (not warnings)
  • THEN the system refuses to start and shows the errors

Requirement: Pipeline Metadata

Pipeline TOML definitions SHALL support an optional [pipeline.metadata] section with when (string describing when to suggest the pipeline) and skills (list of skill names the pipeline depends on).

Scenario: Metadata in TOML

  • WHEN a pipeline defines:
    [pipeline.metadata]
    when = "Frontier-level research requiring systematic validation"
    skills = ["design-practice", "ro5"]
    
  • THEN wai pipeline show displays the metadata
  • AND wai pipeline validate checks that referenced skills are installed

Scenario: Missing metadata

  • WHEN a pipeline omits [pipeline.metadata]
  • THEN the pipeline functions normally but wai pipeline validate warns that it won’t appear in the managed block

Plugin System

Purpose

Define the plugin architecture that allows extending wai with additional capabilities, including YAML-based configuration, hook points, command pass-through, and built-in plugins for common tools.

Problem Statement

As the wai tool matures, the diversity of user needs for specialized functionality and integrations will grow. Without a robust extension mechanism, wai risks becoming either bloated from incorporating every niche feature request, or insufficient for users with specific workflow demands. A plugin system is a foundational Type 1 architectural decision needed to prevent core bloat, meet community-driven and user-specific extension needs, and keep the core tool lean, focused, and maintainable.

Design Rationale

YAML-Based Plugin Configuration

Plugins are configured via YAML files in .wai/plugins/, replacing the earlier TOML-based manifest approach. YAML provides better support for complex nested structures like hook definitions and command mappings. Each plugin declares:

  • Detector patterns: How to detect if the plugin’s tool is present (e.g., .beads/ directory, .git/ directory)
  • Commands: CLI commands the plugin provides or passes through to external tools
  • Hooks: Event handlers for project lifecycle events

Hook Points

Plugins can respond to lifecycle events through defined hook points. This is a Type 1 decision establishing the integration pattern:

  • on_project_create — called when a new project is created
  • on_phase_transition — called when a project changes phase
  • on_handoff_generate — called when generating a handoff document
  • on_status — called when displaying project status

Built-in Plugins

Three plugins ship with wai as built-ins:

  • beads — detects .beads/ directory, provides issue data for handoffs and status
  • openspec — detects openspec/ directory, provides spec change data
  • git — detects .git/ directory, provides commit history and status

Command Pass-Through

Plugins can register commands that pass through to external CLIs. For example, wai beads list delegates to bd list --json. This provides a unified interface while leveraging existing tools.

Scope and Requirements

This spec covers the plugin configuration format, lifecycle hooks, command routing, and built-in plugin definitions.

Non-Goals

  • Plugin registry or marketplace
  • Plugin sandboxing or security model
  • Plugin versioning or dependency resolution
  • Remote plugin installation

Requirement: Plugin Configuration

Plugins SHALL be configured via YAML files in .wai/plugins/.

Scenario: Plugin config format

  • WHEN a plugin is defined
  • THEN its configuration file follows this format:
    name: beads
    description: Integration with beads issue tracker
    detector:
      type: directory
      path: .beads/
    commands:
      - name: list
        description: List beads issues
        passthrough: bd list --json
      - name: show
        description: Show beads issue details
        passthrough: bd show
    hooks:
      on_handoff_generate:
        command: bd list --status=open --json
        inject_as: open_issues
      on_status:
        command: bd stats --json
        inject_as: beads_status
    

Requirement: Plugin Detection

Plugins SHALL auto-detect whether their associated tool is present.

Scenario: Auto-detect on init

  • WHEN user runs wai init
  • THEN the system checks each built-in plugin’s detector pattern
  • AND enables plugins whose tools are detected

Scenario: Detector types

  • WHEN a plugin has a directory detector
  • THEN the system checks for the specified directory relative to project root
  • WHEN a plugin has a file detector
  • THEN the system checks for the specified file

Requirement: Plugin Hooks

Plugins SHALL respond to lifecycle events through hook points.

Scenario: Hook execution

  • WHEN a lifecycle event occurs (e.g., project creation, phase transition)
  • THEN the system calls all registered hooks for that event
  • AND collects hook output for use by the triggering command

Scenario: Handoff enrichment

  • WHEN generating a handoff
  • THEN the system calls on_handoff_generate hooks on all enabled plugins
  • AND injects the collected data into the handoff template

Requirement: Command Pass-Through

Plugins SHALL support routing CLI commands to external tools.

Scenario: Plugin command execution

  • WHEN user runs wai <plugin-name> <command>
  • THEN the system looks up the command in the plugin’s command list
  • AND executes the passthrough command

Scenario: Safe mode passthrough

  • WHEN user passes --safe
  • THEN the system refuses passthrough commands unless the plugin command is explicitly marked read_only: true
  • AND returns a diagnostic error that suggests rerunning without --safe

Scenario: Non-interactive passthrough

  • WHEN user passes --no-input
  • THEN the system refuses passthrough commands that would prompt for input and returns a diagnostic error

Requirement: Plugin Management

The CLI SHALL support listing, enabling, and disabling plugins.

Scenario: List plugins

  • WHEN user runs wai plugin list
  • THEN the system shows all known plugins with their status (enabled/disabled/not detected)

Scenario: List plugins as JSON

  • WHEN user runs wai plugin list --json
  • THEN the system outputs JSON containing plugin name, status, and detector metadata

Scenario: Enable plugin

  • WHEN user runs wai plugin enable <name>
  • THEN the system enables the specified plugin

Scenario: Disable plugin

  • WHEN user runs wai plugin disable <name>
  • THEN the system disables the specified plugin without removing its configuration

Project Reflection

Purpose

Define the wai reflect command, which synthesizes accumulated session context into project-specific AI-assistant guidance and writes the result to a versioned resource file in .wai/resources/reflections/.

Problem Statement

As projects accumulate sessions and artifacts (research, designs, plans, handoffs), valuable project-specific conventions, gotchas, and architectural patterns remain buried in session history. The CLAUDE.md and AGENTS.md managed blocks provide generic tool instructions but contain nothing project-specific — every new AI session must rediscover the same codebase patterns from scratch.

wai why answers specific questions reactively. wai reflect complements it proactively: given accumulated session context, ask the LLM “what project-specific context should AI assistants know that isn’t already documented?” and inject the answer into CLAUDE.md and/or AGENTS.md as a persistent, project-aware section.

Design Rationale

Three-Tier Context Model

Context sources are prioritized from richest to most distilled:

  1. Conversation transcripts — raw Claude session content (ephemeral unless captured)
  2. Handoffs — structured session summaries with gotchas and next steps
  3. Artifacts — research, design, and plan documents

LLM-Required (No Fallback)

Unlike wai why, wai reflect does not fall back to search. Reflection requires LLM synthesis to surface non-obvious patterns; keyword search cannot substitute.

Resource File Storage

wai reflect writes each run to a new dated file in .wai/resources/reflections/. Files accumulate across sessions, are committed and versioned, and are searchable via wai search. A slim WAI:REFLECT:REF block in CLAUDE.md/AGENTS.md points agents to the resource directory and instructs them to search before starting work.

Scope and Requirements

This spec covers the wai reflect command, REFLECT block management, context gathering, and the session nudge heuristic.

Non-Goals

  • Streaming LLM responses during reflection
  • Automatic reflection without user confirmation
  • Reflection of non-wai project history

Requirements

Requirement: Reflect Command

The CLI SHALL provide wai reflect to synthesize accumulated session context into project-specific AI-assistant guidance and inject it into CLAUDE.md and/or AGENTS.md.

Scenario: Basic reflect run

  • WHEN user runs wai reflect
  • THEN the system reads all handoff files from all projects as the primary source
  • AND reads research, design, and plan artifacts as secondary sources
  • AND reads previous reflections from .wai/resources/reflections/ as additional context
  • AND sends a structured prompt to the configured LLM (reusing [llm] config)
  • AND writes the result to .wai/resources/reflections/<date>-<project>.md
  • AND prints the path of the written resource file

Scenario: Conversation transcript as input

  • WHEN user runs wai reflect --conversation <file>
  • THEN the system reads the file as plain text (any format accepted)
  • AND includes it as the highest-priority context source in the LLM prompt
  • AND caps the transcript at ~30K chars, truncating from the beginning (oldest exchange removed) to preserve the most recent content
  • AND proceeds with handoffs and artifacts filling the remaining context budget

Scenario: Output target selection

  • WHEN user runs wai reflect without --output

  • THEN the system detects which of CLAUDE.md and AGENTS.md exist in the repo root

  • AND updates all files that exist (both, if both are present)

  • WHEN user runs wai reflect --output claude.md

  • THEN the system updates only CLAUDE.md, regardless of what exists

  • WHEN user runs wai reflect --output agents.md

  • THEN the system updates only AGENTS.md, regardless of what exists

  • WHEN user runs wai reflect --output both

  • THEN the system updates both CLAUDE.md and AGENTS.md

Scenario: No target file found

  • WHEN user runs wai reflect and neither CLAUDE.md nor AGENTS.md exist
  • THEN the system fails with a diagnostic error: “No CLAUDE.md or AGENTS.md found — run wai init first or create the target file”

Scenario: Dry run mode

  • WHEN user runs wai reflect --dry-run
  • THEN the system shows the resource file path that would be written
  • AND exits without writing to any file
  • AND still performs migration of any old WAI:REFLECT block if present

Scenario: Scoped to a project

  • WHEN user runs wai reflect --project <name>
  • THEN the system reads only artifacts from the specified project
  • AND proceeds with LLM synthesis and injection as normal

Scenario: No LLM available

  • WHEN user runs wai reflect and no LLM backend is configured or reachable
  • THEN the system displays an informational message explaining that LLM is required
  • AND suggests configuring [why] in .wai/config.toml or installing Ollama
  • AND does NOT fall back to search (reflection requires LLM synthesis)

Scenario: No handoffs and no conversation file

  • WHEN user runs wai reflect with no --conversation file
  • AND the workspace has no handoff artifacts
  • THEN the system warns that no session context is available
  • AND suggests running wai handoff create <project> to capture session context
  • AND exits without calling the LLM

Requirement: Reflect Output Storage

The system SHALL write wai reflect output to a versioned resource file in .wai/resources/reflections/ instead of injecting a full block into CLAUDE.md or AGENTS.md.

Scenario: Reflect writes to resource file

  • WHEN user runs wai reflect
  • THEN the system writes the synthesized content to .wai/resources/reflections/YYYY-MM-DD-<project>.md
  • AND the file is created (never overwritten; a second run on the same day appends a -2, -3 suffix)
  • AND the file begins with YAML front-matter:
    ---
    date: YYYY-MM-DD
    project: <project-name>
    sessions_analyzed: N
    type: reflection
    ---
    
  • AND the LLM-generated content follows the front-matter

Scenario: Resource file is searchable

  • WHEN user runs wai search "<topic>"
  • THEN reflection files in .wai/resources/reflections/ are included in search results

Scenario: Previous reflections included as context

  • WHEN gathering context for a new wai reflect run
  • THEN existing files in .wai/resources/reflections/ are included as an additional context tier (lower priority than handoffs)
  • AND the LLM prompt instructs the LLM to extend and correct existing patterns rather than repeat them

Requirement: Slim Reference Block in CLAUDE.md / AGENTS.md

The system SHALL maintain a WAI:REFLECT:REF block in CLAUDE.md and/or AGENTS.md that contains only a brief pointer to the resource files and a mandatory search instruction.

Scenario: wai init injects WAI:REFLECT:REF block

  • WHEN user runs wai init (fresh or refresh)
  • THEN the system injects or refreshes a WAI:REFLECT:REF:START/END block after the WAI:END marker
  • AND the block instructs agents to run wai search "<topic>" before starting research

Scenario: wai reflect does NOT touch CLAUDE.md

  • WHEN user runs wai reflect
  • THEN the system writes only to .wai/resources/reflections/<date>-<project>.md
  • AND does NOT modify CLAUDE.md or AGENTS.md

Scenario: Migration from old WAI:REFLECT block

  • WHEN user runs wai reflect
  • AND CLAUDE.md or AGENTS.md contains an existing WAI:REFLECT:START/END block
  • THEN the system migrates the block content to .wai/resources/reflections/<today>-<project>-migrated.md (if not already migrated)
  • AND replaces the WAI:REFLECT:START/END block in all target files with the slim WAI:REFLECT:REF:START/END block

Requirement: Search-Before-Research Instruction in Managed Block

The wai init managed block template SHALL include an explicit instruction for agents to search for known patterns before beginning research or creating tickets.

Scenario: Managed block includes search instruction when companions detected

  • WHEN wai init generates the managed block
  • AND beads or openspec companion tools are detected
  • THEN the managed block includes a search-before-research instruction

Scenario: No instruction without companions

  • WHEN wai init generates the managed block
  • AND no companion tools are detected
  • THEN the managed block does NOT include the search instruction

Requirement: Context Sources and Budget

The system SHALL gather context in a three-tier priority order with dynamic budget allocation.

Scenario: Conversation transcript fills first tier

  • WHEN --conversation <file> is provided
  • THEN the transcript is the highest-priority source in the LLM prompt
  • AND capped at ~30K chars, truncated from the beginning if larger
  • AND the LLM prompt labels this source: “Conversation transcript (richest: raw session including failed attempts and surprises)”

Scenario: Handoffs fill second tier

  • WHEN gathering context (with or without conversation transcript)
  • THEN handoff files are read sorted by modification time (newest first)
  • AND fill up to ~40K chars of the budget (or the remaining budget after the conversation transcript)
  • AND the LLM prompt labels these: “Session handoffs (intent, next steps, gotchas captured at session end)”

Scenario: Secondary artifacts fill remaining budget

  • WHEN context budget remains after handoffs
  • THEN research, design, and plan artifacts fill the remaining ~30K chars
  • AND the LLM prompt labels these: “Research and design artifacts (explicit decisions and domain knowledge)”

Scenario: Budget exceeded

  • WHEN total content exceeds the budget (~100K chars)
  • THEN each tier is truncated to its cap from the least-recent end
  • AND the prompt includes a note that context was truncated

Scenario: Staleness flag

  • WHEN the LLM prompt includes artifacts
  • THEN each artifact is labeled with its creation date
  • AND the prompt instructs the LLM to flag patterns from artifacts older than 6 months as “potentially stale — verify still applies”

Requirement: Reflect Metadata

The system SHALL track reflection run metadata in a dedicated file to support the session nudge heuristic.

Scenario: Metadata written after successful reflect

  • WHEN wai reflect successfully writes to one or more target files
  • THEN the system writes .wai/projects/<project>/.reflect-meta containing:
    last_reflected = "YYYY-MM-DD"
    session_count = N
    
    where N is the number of handoff files processed in this run
  • AND the file is created if absent or overwritten if present

Scenario: Missing metadata treated as never reflected

  • WHEN wai close or wai reflect reads .reflect-meta and the file does not exist
  • THEN the system treats last_reflected as the epoch (all handoffs are newer)

Requirement: Session Nudge

The system SHALL suggest running wai reflect from wai close when enough sessions have accumulated without a reflect.

Scenario: Nudge after threshold exceeded

  • WHEN user runs wai close and creates a handoff
  • AND 5 or more handoff files have mtime newer than the last_reflected date in .wai/projects/<project>/.reflect-meta
  • THEN the system appends a suggestion after normal close output: → N sessions since last reflect — run 'wai reflect' to update <target> where <target> lists the AI config files found in the repo root
  • AND the nudge is informational only (does not block close or change exit code)

Scenario: No nudge when current

  • WHEN user runs wai close
  • AND fewer than 5 handoffs are newer than the last reflect
  • THEN the system does NOT display the reflect nudge

Requirement: Improved Handoff Nuance Capture

The handoff template SHALL include dedicated sections for capturing operational nuances that are most valuable as reflect input.

Scenario: Handoff includes nuance sections

  • WHEN user runs wai handoff create <project>
  • THEN the generated handoff includes these sections (in addition to existing ones):
    ## Gotchas & Surprises
    <!-- What behaved unexpectedly? Non-obvious requirements? Hidden dependencies? -->
    
    ## What Took Longer Than Expected
    <!-- Steps that needed multiple attempts. Commands that failed before the right one. -->
    
  • AND both sections are empty template placeholders for the user to fill in

Scenario: Reflect prioritizes nuance sections

  • WHEN building the LLM prompt and handoffs contain Gotchas or Longer-Than-Expected sections
  • THEN the LLM prompt instructs the LLM to treat content in those sections as high-signal input for the Conventions and Common Gotchas sections of the REFLECT block

Requirement: Agent Backend for wai reflect

When running inside an agent session, wai reflect SHALL output the prepared reflection context block to stdout — using the same [AGENT CONTEXT] / [/AGENT CONTEXT] delimiters as wai why — rather than calling an external LLM. The invoking agent synthesizes the REFLECT content and feeds it back via --inject-content.

Scenario: Agent mode activated in wai reflect

  • WHEN user (or agent) runs wai reflect
  • AND in_agent_session() returns true
  • AND no API key is configured
  • THEN wai reflect selects the Agent backend via detect_backend()
  • AND outputs the prepared reflection context block delimited by [AGENT CONTEXT] / [/AGENT CONTEXT] markers
  • AND prints a status line: ◆ Agent mode — context sent to agent.
  • AND prints a follow-up instruction: Once the agent provides the REFLECT content, run: wai reflect --inject-content '<content>'
  • AND exits 0 without writing any resource file

Scenario: Agent provides reflect content via –inject-content

  • WHEN the invoking agent synthesizes the REFLECT content from the context block
  • AND runs wai reflect --inject-content '<synthesized content>'
  • THEN wai reflect skips the LLM call and uses the injected content directly
  • AND writes the content to .wai/resources/reflections/<date>-<project>.md
  • AND completes normally (updates metadata, prints resource file path)

Scenario: Detection uses same three-env contract

  • WHEN determining whether agent mode should activate for wai reflect
  • THEN the system uses in_agent_session() identically to wai why: WAI_AGENT, then CLAUDECODE, then CURSOR_AGENT
  • AND the agent backend is selected by detect_backend() using the shared [why] LLM config section

Scenario: Non-agent invocation unchanged

  • WHEN in_agent_session() returns false
  • THEN wai reflect behaves exactly as before: calls the configured LLM backend and writes the result directly to the resource file
  • AND no [AGENT CONTEXT] block is emitted

Project State Machine

Purpose

Define the phase-based state machine for projects, providing a structured workflow from initial research through completion and archival.

Problem Statement

Development projects progress through natural phases — from research and planning through design, implementation, and review. Without a formalized state model, the current phase of a project becomes ambiguous, making it difficult to provide contextual suggestions, generate meaningful handoffs, or track progress over time. A state machine provides the structure needed for phase-aware tooling while remaining flexible enough for real-world workflows where phases may be revisited.

Design Rationale

Six-Phase Model

The six-phase model (research → design → plan → implement → review → archive) is a Type 1 foundational decision. Unlike the simpler four-phase bead lifecycle it replaces at the project level, this model captures the full arc of a development effort:

  • Research: Gathering context, understanding the problem space
  • Design: Creating technical designs, API contracts, architecture
  • Plan: Defining implementation steps, scope, and success criteria after design direction is selected
  • Implement: Writing code, building features
  • Review: Testing, code review, validation against requirements
  • Archive: Completed work preserved for reference

Flexible Transitions

Unlike strict linear workflows, wai allows flexible transitions — users can skip forward or go back as needed. This is a deliberate Type 2 decision that prioritizes developer autonomy over process enforcement. The state machine tracks transitions for auditability without preventing valid workflow patterns.

File-Based State

Project state is stored as a YAML .state file within the project directory. This keeps state co-located with the project’s artifacts and naturally version-controllable.

Scope and Requirements

This spec defines the state machine phases, transitions, and persistence format for projects.

Non-Goals

  • Automated phase transitions based on external signals
  • Phase-specific validation rules (e.g., requiring certain artifacts before advancing)
  • Multi-project phase coordination
  • Custom user-defined phases

Requirement: Phase Definitions

Projects SHALL progress through defined phases that represent workflow stages.

Scenario: Default phase

  • WHEN a new project is created
  • THEN it starts in the “research” phase

Scenario: Phase list

  • WHEN querying available phases
  • THEN the system returns: research, design, plan, implement, review, archive

Requirement: Phase Transitions

The system SHALL support flexible phase transitions with history tracking.

Scenario: Advance to next phase

  • WHEN user runs wai phase next
  • THEN the project moves to the next sequential phase
  • AND the transition is recorded with timestamp

Scenario: Set specific phase

  • WHEN user runs wai phase set <phase>
  • THEN the project moves to the specified phase
  • AND the transition is recorded with timestamp

Scenario: Go back to previous phase

  • WHEN user runs wai phase back
  • THEN the project moves to the previous sequential phase
  • AND the transition is recorded with timestamp

Scenario: Show current phase

  • WHEN user runs wai phase
  • THEN the system displays the current phase and phase history

Requirement: State Persistence

Project phase state SHALL be persisted in a YAML file within the project directory.

Scenario: State file format

  • WHEN a project has phase state
  • THEN it is stored in .wai/projects/<name>/.state as:
    current: plan
    history:
      - phase: research
        started: 2026-01-20T10:00:00Z
        completed: 2026-01-22T15:30:00Z
      - phase: plan
        started: 2026-01-22T15:30:00Z
    

Requirement: Phase History

The system SHALL maintain a complete history of phase transitions.

Scenario: Transition recorded

  • WHEN a project changes phase
  • THEN the system records the previous phase completion time
  • AND records the new phase start time
  • AND the history is visible via wai phase

Requirements

Requirement: Matrix-Aware Design to Plan Transition

The system SHALL gate the design → plan phase transition on matrix currency when a project has a decision matrix (designs/matrix/): problem.md must be non-empty, decision.md must record a selected approach that exists under approaches/, and no file under approaches/ or criteria/ may be newer than the decision UTC timestamp recorded inside decision.md. Projects without a matrix are never gated by it. The gate applies to every design → plan transition path, including wai phase next and wai phase set plan.

Scenario: Matrix gates design-to-plan when undecided

  • GIVEN a project with a decision matrix whose decision.md is still the scaffolded template
  • WHEN the design → plan transition is attempted
  • THEN the transition is blocked
  • AND the failure message indicates no decision has been made and suggests wai matrix decide

Scenario: Matrix gates design-to-plan when stale

  • GIVEN a project with a decision matrix whose cell or criterion files were modified after the recorded decision timestamp
  • WHEN the design → plan transition is attempted
  • THEN the transition is blocked
  • AND the failure message names the offending files and suggests wai matrix decide

Scenario: Inconclusive staleness warns instead of blocking

  • GIVEN a decided matrix checked out fresh from git so that all matrix files share the checkout timestamp with the decision timestamp
  • WHEN the design → plan transition is attempted
  • THEN the transition proceeds
  • AND a stale-decision warning is reported with a pointer to wai matrix lint

Scenario: Set cannot bypass the gate

  • GIVEN a project in the design phase with an undecided matrix
  • WHEN user runs wai phase set plan
  • THEN the transition is blocked with the same message as wai phase next

Scenario: No matrix leaves transitions unchanged

  • GIVEN a project that never initialized a matrix
  • WHEN the design → plan transition is attempted
  • THEN the transition behaves exactly as before this change

Reasoning Oracle

Purpose

Define the LLM-powered reasoning oracle that helps developers understand why code exists as it does by synthesizing context from artifacts, git history, and project metadata.

The term “oracle” refers to the system’s ability to proactively surface relevant context and synthesize reasoning chains from multiple sources, like consulting a knowledgeable advisor who can connect disparate information and explain the evolution of decisions.

This capability builds on the existing wai search command (see timeline-search) by adding an LLM synthesis layer that transforms keyword matches into reasoned explanations.

Problem Statement

As projects accumulate research notes, design documents, and plans, developers struggle to rediscover the reasoning behind past decisions. While wai search provides keyword matching, understanding why requires semantic synthesis: connecting related artifacts, building decision chains, and explaining trade-offs in natural language. These are tasks that LLMs excel at, making them ideal for reasoning discovery.

Design Rationale

LLM-First Architecture

This is a Type 1 decision: delegate reasoning to LLMs rather than implementing custom ranking algorithms. The design makes wai a context orchestrator that gathers artifacts and formats prompts, trusting the LLM to handle semantic understanding, relevance ranking, and narrative synthesis.

Why LLM-first:

  • LLMs naturally understand semantic similarity (“config” ↔ “configuration”)
  • LLMs rank by relevance (design docs > research notes for architectural questions)
  • LLMs build reasoning chains (research → design → plan) without explicit programming
  • Implementation is 3x simpler (~400 LOC vs ~1200 LOC for custom algorithms)
  • Quality improves automatically as LLMs improve

Alternative considered: Custom keyword extraction + Jaccard similarity + temporal scoring. Rejected due to complexity, brittleness, and inferior results.

Multi-Backend Support

Support multiple LLM backends (Claude API, local Ollama, future: Gemini, OpenAI) via trait abstraction. Auto-detect available backend and gracefully degrade to wai search if no LLM is accessible.

Scope and Requirements

This spec covers the wai why command, LLM integration, and configuration.

Non-Goals

  • Multi-turn conversation mode (future consideration)
  • Custom ranking algorithms or ML models
  • Vector embeddings or semantic search infrastructure
  • Local-only operation (LLM is recommended but optional)

Requirements

Requirement: Why Command

The CLI SHALL provide wai why <query> to answer reasoning questions using LLM synthesis of gathered context.

Scenario: Natural language query

  • WHEN user runs wai why "why use TOML for config?"
  • THEN the system gathers all artifacts and git context
  • AND sends a structured prompt to the configured LLM
  • AND displays the LLM’s synthesized answer with relevant artifacts, decision chains, and suggestions

Scenario: File path query

  • WHEN user runs wai why src/config.rs
  • THEN the system detects the file path
  • AND gathers git blame and log for that file
  • AND gathers all artifacts (prioritizing those mentioning the file or from similar timeframe)
  • AND asks the LLM to explain why this file exists

Scenario: Output format

  • WHEN displaying the answer
  • THEN the output shows:
    • Direct answer to the question
    • 3-5 relevant artifacts with relevance explanation
    • Decision chain (temporal evolution of reasoning)
    • Suggestions for further exploration
  • AND artifact references include file paths for verification

Scenario: JSON output

  • WHEN user runs wai why <query> --json
  • THEN the system outputs structured JSON with:
    • query (original question)
    • answer (LLM response text)
    • artifacts (array of artifact paths with relevance indicators parsed from LLM response: “High”/“Medium”/“Low”)
    • suggestions (array of suggested follow-up commands)

Note: The system handles diverse query types including natural language questions ("why use TOML for config?"), file paths (src/config.rs), design decisions ("why not async-std?"), feature rationale ("plugin system design"), and rejection rationale ("why was dynamic loading rejected?").

Requirement: LLM Backend Selection

The system SHALL support multiple LLM backends via configuration and context-aware auto-detection.

Scenario: Auto-detect backend inside an agent session

  • WHEN user runs wai why with no explicit [why] llm config
  • AND in_agent_session() returns true — i.e. at least one of WAI_AGENT, CLAUDECODE, or CURSOR_AGENT is set and non-empty
  • THEN the system checks available backends in this priority order:
    1. ANTHROPIC_API_KEY env var set → Claude API
    2. in_agent_session() true → Agent mode
    3. ollama binary + model available → Ollama
  • AND uses the first available backend
  • AND falls back to wai search with a warning if none available

Note: Agent mode is preferred over Ollama inside any agent session because it requires no external service and uses the already-present LLM without subprocess overhead.

Scenario: Explicit agent mode outside an agent session

  • WHEN .wai/config.toml contains [why] llm = "agent"
  • AND in_agent_session() returns false (no supported agent env var set)
  • THEN the system warns: “agent mode requires an active agent session; no synthesized answer will be produced”
  • AND still outputs the context block (allowing manual inspection)
  • AND exits 0 — this is a misconfiguration warning, not a fatal error

Requirement: Graceful Degradation

The system SHALL fall back to wai search when LLM is unavailable or fails.

Scenario: No LLM available

  • WHEN user runs wai why with no API key and no Ollama installed
  • THEN the system displays a warning that no LLM is available
  • AND displays remediation guidance (install Ollama or set API key)
  • AND runs wai search <query> and displays keyword matches

Scenario: LLM API error with diagnostic codes

  • WHEN LLM API returns error (rate limit, invalid key, network failure)
  • THEN the system displays a miette diagnostic error with an appropriate code (e.g., wai::llm::invalid_api_key, wai::llm::rate_limit, wai::llm::network_error, wai::llm::model_not_found)
  • AND includes actionable remediation in the error help text
  • AND falls back to wai search with explanation

Scenario: Malformed LLM response

  • WHEN LLM returns response that doesn’t match expected markdown format
  • THEN the system displays the raw response with a warning about unexpected format
  • AND shows the response anyway (user can still read it)
  • AND does NOT fall back to search (LLM did respond, just oddly)

Requirement: Context Gathering

The system SHALL gather comprehensive context to send to the LLM while managing context size to stay within LLM limits.

Scenario: Gather artifacts

  • WHEN preparing context for LLM
  • THEN the system reads all artifacts from .wai/:
    • Research notes from all projects
    • Design documents from all projects
    • Plans from all projects
    • Handoffs from all projects
  • AND includes artifact metadata (date, type, project)

Scenario: Gather git context for file queries

  • WHEN the system detects the query as a file path
  • AND the repository is a git repository
  • AND the file is tracked by git
  • THEN the system runs git blame <file> to get line-level authorship and commit info
  • AND runs git log --follow <file> to get file history
  • AND includes recent commits that touched the file

Scenario: Git unavailable or file not tracked

  • WHEN query looks like a file path but:
    • Repository is not a git repository, OR
    • Git command fails, OR
    • File is not tracked by git
  • THEN the system skips git context gathering
  • AND displays an informational message suggesting git initialization or file tracking for better context
  • AND proceeds with artifacts-only context

Scenario: Gather project metadata

  • WHEN preparing context
  • THEN the system includes:
    • Current project phase
    • Recent commits (last 10)
    • Active beads issues (if plugin detected)
    • Active openspec changes (if plugin detected)

Scenario: Plugin-contributed context

  • WHEN preparing context and detected plugins expose relevant data
  • THEN the system MAY incorporate context from detected plugins via the plugin interface (e.g., beads issues, openspec changes)
  • AND plugin context is included alongside artifacts and git context in the LLM prompt

Scenario: No artifacts available

  • WHEN preparing context and .wai/ contains zero artifacts
  • THEN the system warns that no artifacts were found and suggests using wai add
  • AND still proceeds with LLM call using only git context and project metadata
  • AND the prompt instructs the LLM to note that no project artifacts were available

Scenario: Context size management for large projects

  • WHEN total artifact content exceeds the configured model’s context budget
  • THEN the system selects a subset of artifacts, prioritizing relevance to the query and recency
  • AND informs the user that context was truncated and suggests wai search for broader coverage
  • AND includes a truncation note in the prompt for LLM awareness

Requirement: Prompt Construction

The system SHALL build structured prompts that guide the LLM to produce consistent, useful answers.

Scenario: Basic prompt structure

  • WHEN building a prompt
  • THEN the prompt includes:
    • Role definition (“You are an oracle…”)
    • User question
    • Project context (phase, commits)
    • Artifacts with metadata (in escaped code blocks to prevent markdown injection)
    • Git context (if file query)
    • Task instructions (identify relevant artifacts, synthesize narrative, suggest next steps)
    • Output format instructions (markdown sections)
  • AND all artifact content is escaped or quoted to prevent:
    • Markdown injection (triple backticks, special characters)
    • Prompt injection (instructions embedded in artifacts)
    • Format breaking (malformed markdown)

Scenario: Verbosity levels

  • WHEN user runs wai why <query> with global verbosity flags (-v, -vv, -vvv)
  • THEN the system provides progressively more detail:
    • -v: backend selected, artifact count, estimated cost
    • -vv: full prompt sent to the LLM
    • -vvv: raw LLM response, timing breakdown, token counts

Requirement: Cost Awareness

The system SHALL default to cost-effective LLM models and provide usage transparency.

Scenario: Default to cost-effective models

  • WHEN using Claude without explicit model configuration
  • THEN the system defaults to the most cost-effective available model
  • AND allows users to configure a more capable model via the model config field

Note: The system SHALL warn when estimated query cost exceeds a configurable threshold (default $0.05) due to large context or expensive model selection.

Scenario: Display cost estimate

  • WHEN user runs wai why <query> with verbosity level 1 or higher (-v)
  • THEN the output includes estimated cost for the query
  • AND shows token counts (input and output) at verbosity level 3 (-vvv)

Requirement: Privacy Considerations

The system SHALL inform users when sending artifacts to external APIs and provide local alternatives.

Scenario: Privacy warning for external APIs

  • WHEN using external LLM API (Claude, Gemini, OpenAI) for the first time
  • AND .wai/config.toml does not have privacy_notice_shown = true
  • THEN the system displays a one-time notice informing the user that artifacts will be sent to the external provider
  • AND suggests local Ollama as a privacy-preserving alternative
  • AND records acknowledgment in .wai/config.toml
  • AND proceeds with the query after displaying the notice

Scenario: Local-only mode

  • WHEN configured to use Ollama
  • THEN the system processes all queries locally without network calls
  • AND indicates local-only operation at verbosity level 1 or higher

Requirement: Badge Recommendation

The system SHALL nudge project maintainers to add a wai badge to their README, improving discoverability.

  • WHEN user runs wai why <query> (terminal mode, not --json)
  • AND the project root contains a README file (README.md, README.rst, README.txt)
  • AND that README does not contain a wai badge (detected by ![ markdown containing “wai” or img.shields.io URL containing “wai”)
  • THEN the system appends a one-line footer after the main output suggesting the badge markdown

Scenario: No README present

  • WHEN user runs wai why <query>
  • AND no README file exists at the project root
  • THEN the system does NOT show a badge suggestion (no README → no context to add a badge)

Scenario: Badge already present

  • WHEN user runs wai why <query>
  • AND the README already contains a wai badge
  • THEN the system does NOT show a badge suggestion

Scenario: Badge check in wai doctor

  • WHEN user runs wai doctor
  • AND a README exists but has no wai badge
  • THEN the system reports a “README badge” check with warn status
  • AND includes the badge markdown in the fix suggestion
  • WHEN the README already has a wai badge
  • THEN the “README badge” check reports pass
  • WHEN no README exists
  • THEN the “README badge” check is skipped entirely

Requirement: Documentation

The wai why command SHALL be self-documenting through help text, onboarding, and agent instructions.

Scenario: Help text

  • WHEN user runs wai why --help
  • THEN the output includes:
    • Three query type categories with examples (natural language, file path)
    • Full [why] config section template showing all options
    • All LLM error codes with remediation hints
    • Reference to --no-llm fallback flag

Scenario: Tutorial integration

  • WHEN user runs wai tutorial
  • THEN the Core Commands step lists wai why "<question>" with usage examples

Scenario: Agent instruction blocks

  • WHEN wai init creates or updates CLAUDE.md / AGENTS.md
  • THEN the wai managed block Quick Reference section includes wai why examples

Requirement: Agent Backend

When running inside an agent session, the system SHALL delegate reasoning to the invoking agent by outputting the prepared context to stdout rather than calling an external LLM.

Scenario: Agent mode activated automatically

  • WHEN in_agent_session() returns true
  • AND no API key is configured
  • THEN the system prints a brief status line indicating agent mode is active
  • AND outputs the full prepared context block, delimited by [AGENT CONTEXT] / [/AGENT CONTEXT] markers
  • AND exits cleanly — the invoking agent synthesizes the answer in its next response

Scenario: Detection env var priority

  • WHEN determining whether agent mode should activate
  • THEN the system checks env vars in this order:
    1. WAI_AGENT non-empty → agent mode (universal override)
    2. CLAUDECODE non-empty → agent mode (Claude Code)
    3. CURSOR_AGENT non-empty → agent mode (Cursor IDE)
  • AND the first non-empty match activates agent mode
  • AND all other unset env vars do not affect the result

Requirement: Claude CLI Backend

The system SHALL support delegating wai why queries to the claude binary in print mode, for users who have Claude Code installed but no direct API key configured.

Scenario: Claude CLI backend behaviour

  • WHEN the Claude CLI backend is selected (auto or explicit)
  • THEN the system spawns claude -p with the prompt passed via stdin
  • AND captures stdout as the LLM response
  • AND processes and displays the response identically to the Claude API backend

Scenario: Claude CLI is not used inside Claude Code sessions (auto-detect)

  • WHEN auto-detection runs
  • AND CLAUDECODE is non-empty (inside a Claude Code session)
  • THEN the Claude CLI backend is NOT selected (agent mode is preferred)

Rationale: Inside Claude Code, spawning claude -p requires bypassing the nested-session guard (CLAUDECODE=""). This is a fragile workaround; agent mode is the correct mechanism for that context.

Scenario: No LLM available — remediation guidance mentions agent mode

  • WHEN no LLM backend is available and the system falls back to wai search
  • AND CLAUDECODE is set and non-empty
  • THEN the fallback warning mentions that running inside a Claude Code session should enable agent mode automatically
  • AND suggests checking [why] llm = "agent" as an explicit override if needed

repository-best-practices Specification

Purpose

The wai way command reports on agnostic repository capabilities rather than specific tool implementations. Each capability check includes its intent and success criteria to provide context for both human users and AI agents. Verbose output (-v) shows intent and criteria; JSON output (--json) always includes them.

Requirements

Requirement: Command Standardization

Intent: Provide a single, tool-agnostic entry point for common repository tasks (build, test, deploy). Success Criteria: A standard interface (justfile, Makefile, npm scripts) exists for common tasks.

The system SHALL check for a task runner (justfile or Makefile) and recommend adoption if missing. When a justfile is found, the system SHALL parse it for useful recipes and display contextual suggestions to help users discover key workflows.

Scenario: Task runner present

  • WHEN wai way runs
  • THEN it checks for justfile or Makefile in current directory
  • AND reports pass if either exists
  • AND the capability name in output is “Command standardization”

Scenario: Justfile with useful recipes

  • WHEN wai way runs and a justfile is found
  • THEN it parses the justfile for known useful recipe names
  • AND displays a message listing matched recipes

Scenario: No task runner

  • WHEN wai way runs and neither justfile nor Makefile exists
  • THEN it reports info status
  • AND suggests adding a justfile

Requirement: Pre-commit Quality Gates

Intent: Prevent low-quality commits by running automated checks before code is saved to history. Success Criteria: Automated checks (linters, tests) run automatically before code is committed.

The system SHALL check for git hook manager configuration (prek or pre-commit) and recommend prek if missing.

Scenario: Prek configured

  • WHEN wai way runs and .prek.toml exists
  • THEN it reports pass
  • AND the capability name in output is “Pre-commit quality gates”

Scenario: Pre-commit configured (legacy)

  • WHEN wai way runs and .pre-commit-config.yaml exists (but not .prek.toml)
  • THEN it reports pass
  • AND suggests migrating to prek

Scenario: No hook manager config

  • WHEN wai way runs and neither .prek.toml nor .pre-commit-config.yaml exists
  • THEN it reports info status
  • AND suggests adding prek

Requirement: Consistent Formatting

Intent: Ensure consistent code formatting across different editors and IDEs. Success Criteria: Project-wide style rules are enforced by a shared configuration file.

The system SHALL check for EditorConfig and recommend it for editor-agnostic formatting rules.

Scenario: EditorConfig present

  • WHEN wai way runs and .editorconfig exists
  • THEN it reports pass
  • AND the capability name in output is “Consistent formatting”

Scenario: No EditorConfig

  • WHEN wai way runs and .editorconfig doesn’t exist
  • THEN it reports info status
  • AND suggests adding .editorconfig

Requirement: Project Documentation

Intent: Provide essential project identity, onboarding, and legal/contribution guidance. Success Criteria: Essential files (README, .gitignore, LICENSE) provide project context and rules.

The system SHALL check for essential documentation files (.gitignore, README.md, CONTRIBUTING.md, LICENSE) and recommend creating missing ones.

Scenario: All documentation present

  • WHEN wai way runs and all four files exist
  • THEN it reports pass
  • AND the capability name in output is “Project documentation”

Scenario: Missing critical files

  • WHEN wai way runs and .gitignore or README.md are missing
  • THEN it reports info status with ⚠️ indicator
  • AND suggests adding the missing critical files

Scenario: Partial documentation

  • WHEN wai way runs and some files are present but not all
  • THEN it reports based on whether critical files exist

Scenario: No documentation

  • WHEN wai way runs and none of the documentation files exist
  • THEN it reports info status

Requirement: AI-Agent Context

Intent: Provide persistent “rules of the road” and project context for AI collaborators. Success Criteria: Persistent instructions define coding standards and context for AI assistants.

The system SHALL check for AI assistant instructions file and recommend one if missing.

Scenario: CLAUDE.md present

  • WHEN wai way runs and CLAUDE.md exists
  • THEN it reports pass
  • AND the capability name in output is “AI-agent context”
  • AND if no WAI:REFLECT block is found, suggests running wai reflect

Scenario: AGENTS.md present

  • WHEN wai way runs and AGENTS.md exists (but not CLAUDE.md)
  • THEN it reports pass
  • AND suggests adding CLAUDE.md for Claude Code compatibility

Scenario: No AI instructions

  • WHEN wai way runs and neither CLAUDE.md nor AGENTS.md exists
  • THEN it reports info status
  • AND suggests creating CLAUDE.md

Requirement: Automated Verification

Intent: Ensure code quality and correctness through automated builds and tests on every change. Success Criteria: Every change is automatically validated by a remote build/test pipeline.

The system SHALL check for CI/CD configuration and recommend setup if missing.

Scenario: GitHub Actions configured

  • WHEN wai way runs and .github/workflows/ contains at least one workflow file
  • THEN it reports pass
  • AND the capability name in output is “Automated verification”

Scenario: Empty workflows directory

  • WHEN wai way runs and .github/workflows/ exists but is empty
  • THEN it reports info status

Scenario: GitLab CI or CircleCI configured

  • WHEN wai way runs and .gitlab-ci.yml or .circleci/config.yml exists
  • THEN it reports pass

Scenario: No CI/CD configuration

  • WHEN wai way runs and no CI/CD config is found
  • THEN it reports info status
  • AND suggests setting up continuous integration

Requirement: Reproducible Environments

Intent: Provide a standardized, containerized environment for all contributors. Success Criteria: A configuration exists to spin up a consistent, reproducible dev environment.

The system SHALL check for dev container configuration and recommend it for environment consistency.

Scenario: Dev container directory exists

  • WHEN wai way runs and .devcontainer/ directory exists
  • THEN it reports pass
  • AND the capability name in output is “Reproducible environments”

Scenario: Dev container file exists

  • WHEN wai way runs and .devcontainer.json exists
  • THEN it reports pass

Scenario: No dev container

  • WHEN wai way runs and neither .devcontainer/ nor .devcontainer.json exists
  • THEN it reports info status
  • AND suggests adding .devcontainer/

Requirement: LLM-Friendly Context

Intent: Provide machine-readable project context and navigation for LLMs. Success Criteria: Machine-readable project documentation (llm.txt) exists for AI tools.

The system SHALL check for llm.txt file and recommend it for AI-friendly project documentation.

Scenario: llm.txt present

  • WHEN wai way runs and llm.txt exists
  • THEN it reports pass
  • AND the capability name in output is “LLM-friendly context”

Scenario: No llm.txt

  • WHEN wai way runs and llm.txt doesn’t exist
  • THEN it reports info status
  • AND suggests adding llm.txt

Requirement: Extended Agent Capabilities

Intent: Enhance agent functionality with specialized iterative review and commit workflows. Success Criteria: Specialized agent workflows (Rule of 5, Deliberate Commits) are active.

The system SHALL check for agent skills in .wai/resources/agent-config/skills/ and recommend rule-of-5-universal and commit. Skill identity is resolved by directory name OR by aliases declared in SKILL.md frontmatter.

  • WHEN wai way runs and both rule-of-5-universal (or ro5) and commit exist
  • THEN it reports pass
  • AND the capability name in output is “Extended agent capabilities”

Scenario: Skills present via alias (ro5)

  • WHEN a skill directory exists with aliases: [ro5] in SKILL.md frontmatter
  • THEN that skill satisfies the rule-of-5-universal check

Scenario: Partial skills configuration

  • WHEN skills directory exists but one or both recommended skills are missing
  • THEN it reports info status and lists what’s missing

Scenario: No skills configured

  • WHEN .wai/resources/agent-config/skills/ does not exist
  • THEN it reports info status

Scenario: Skills directory empty

  • WHEN .wai/resources/agent-config/skills/ exists but contains no SKILL.md files
  • THEN it reports info status

Requirement: Agent Skills Fix

The system SHALL provide wai way --fix skills to scaffold missing recommended skills.

Scenario: Fix scaffolds missing skills

  • WHEN user runs wai way --fix skills
  • THEN the system creates the skills directory if it does not exist
  • AND creates rule-of-5-universal/SKILL.md if not present
  • AND creates commit/SKILL.md if not present
  • AND reports each created skill

Scenario: Fix skips existing skills

  • WHEN user runs wai way --fix skills and a recommended skill already exists
  • THEN the system skips that skill and reports “already present”

Scenario: Unknown fix target

  • WHEN user runs wai way --fix <unknown>
  • THEN the system exits with an error: “Unknown fix target ‘{value}’. Available: skills”

Requirement: Integration & Automation

Intent: Streamline repository interactions (PRs, issues, releases) from the CLI. Success Criteria: CLI tools are configured for seamless integration with the hosting provider.

The system SHALL check for the GitHub CLI (gh) and recommend it for streamlined GitHub workflows.

Scenario: gh CLI available and authenticated

  • WHEN wai way runs and gh is on PATH and gh auth status succeeds
  • THEN it reports pass
  • AND the capability name in output is “Integration & automation”

Scenario: gh CLI available but not authenticated

  • WHEN wai way runs and gh is on PATH but gh auth status fails
  • THEN it reports info status
  • AND suggests running gh auth login

Scenario: gh CLI not installed

  • WHEN wai way runs and gh is not on PATH
  • THEN it reports info status
  • AND suggests installing gh

Requirement: Automated Delivery

Intent: Automate the process of building, packaging, and publishing software releases. Success Criteria: Software releases and distribution (packages, binaries) are fully automated.

The system SHALL check for a release pipeline in binary projects and recommend setup if missing. Library projects are exempt.

Scenario: Library project

  • WHEN wai way runs and the project has no binary target
  • THEN it reports pass with “Library project — release pipeline not required”
  • AND the capability name in output is “Automated delivery”

Scenario: Release tool detected

  • WHEN wai way runs and goreleaser, cargo-dist, or a release workflow is found
  • THEN it reports pass

Scenario: No release pipeline

  • WHEN wai way runs, the project has a binary target, and no release tool is found
  • THEN it reports info status
  • AND suggests goreleaser or cargo-dist

Requirement: Verbose Output

The system SHALL show intent and success_criteria for each capability when --verbose (-v) is used.

Scenario: Verbose output includes agnostic context

  • GIVEN any project
  • WHEN user runs wai way -v
  • THEN each capability line is followed by an “Intent:” line and a “Success:” line
  • AND normal (non-verbose) output does not show these lines

Requirement: JSON Output

The system SHALL include intent and success_criteria in JSON output. These fields are optional (null if not set) for backward compatibility.

Scenario: JSON includes agnostic fields

  • GIVEN any project
  • WHEN user runs wai way --json
  • THEN the JSON payload includes intent and success_criteria for every check result

Requirement: Plugin Agnostic Context Support

The plugin system SHALL allow TOML-defined plugins to define their own intent and success_criteria.

Scenario: Plugin with custom context

  • GIVEN a plugin TOML with intent and success_criteria defined
  • WHEN the plugin definition is parsed
  • THEN these fields are available on the PluginDef struct
  • AND default to None if not present in the TOML

Scenario: TOML plugin file parsed correctly

  • GIVEN a .toml plugin file in .wai/plugins/ with content:
    name = "my-check"
    intent = "Ensure the repo has a CODEOWNERS file."
    success_criteria = "CODEOWNERS file exists in the repo root or .github/ directory."
    
  • WHEN the plugin loader scans .wai/plugins/ for *.toml files
  • THEN the file is parsed with toml::from_str
  • AND intent and success_criteria are available on the resulting PluginDef
  • AND YAML files (*.yml, *.yaml) are not loaded

Requirement: Output Format

The system SHALL format all checks consistently.

Scenario: All checks pass

  • WHEN wai way runs and all checks return pass
  • THEN output shows checkmarks (✓) for each
  • AND summary displays “excellent! All best practices adopted”

Scenario: Fresh repository

  • WHEN wai way runs on a fresh repository with no tools configured
  • THEN output shows info markers (ℹ) for each check
  • AND summary displays “0/{n} best practices adopted — quick-start: add README.md, justfile, .gitignore”

Research Management

Purpose

Define how research artifacts (notes, links, documents) are captured, organized, and stored within project and area subdirectories to support informed decision-making.

Problem Statement

Valuable insights, notes, and external resources in development and research workflows are often scattered, making it challenging to consistently link supporting research directly to specific projects or areas of work. This leads to lost context, hindered decision-making, and duplicated effort. A Type 1 strategic decision is made here to address this by integrating research management directly within wai’s PARA structure, ensuring research is organized alongside the work it supports.

Design Rationale

  • Within PARA Structure: Research lives inside project or area subdirectories (e.g., .wai/projects/my-app/research/), not in a top-level directory. This keeps research co-located with its context and naturally scoped.
  • Date-Prefixed Files: Research entries use date-prefixed markdown filenames (e.g., 2026-01-20-api-analysis.md) for chronological sorting and easy timeline integration.
  • Optional Association: Research can optionally reference external tracking (e.g., a beads issue ID via frontmatter) without requiring it. This keeps research useful even without external tools.
  • File-based Storage: Storing research as transparent, accessible files ensures data portability and resilience. This avoids the overhead of a dedicated database and keeps user data accessible outside wai.

Scope and Requirements

This spec focuses on the core functionality for capturing and organizing research within the PARA structure.

Non-Goals

  • Editing and deleting existing research (use standard file operations)
  • Full-text search (covered by timeline-search spec)
  • Rich media or complex formatting
  • Integration with external research management software
  • Version control for individual entries (use git)

Requirements

Requirement: Adding Research

The CLI SHALL support capturing research content within a project or area.

Scenario: Add research to current project

  • WHEN user runs wai add research <content>
  • THEN the system creates a date-prefixed research file in the current project’s research/ directory
  • AND stores the content as markdown

Scenario: Add research to specific project

  • WHEN user runs wai add research <content> --project <name>
  • THEN the system creates the research entry in the specified project’s research/ directory

Scenario: Add research from file

  • WHEN user runs wai add research --file <path>
  • THEN the system copies the file content as a research entry with date prefix

Scenario: Research with frontmatter

  • WHEN user runs wai add research <content> --tags <tag1,tag2>
  • THEN the research file includes YAML frontmatter with tags
  • AND optionally includes a bead field for external tracking association

skill-sharing Specification

Purpose

TBD - created by archiving change add-skill-sharing. Update Purpose after archive.

Requirements

Requirement: Global Skill Library

The system SHALL maintain a global skill library at ~/.wai/resources/skills/ that is available in all projects, with project-local skills taking priority over global skills when names conflict.

Scenario: Global skill available in all projects

  • WHEN a skill is installed globally via wai resource install <skill> --global
  • THEN it is accessible in any project via wai resource list skills
  • AND is marked as [global] in the listing output

Scenario: Local skill overrides global

  • WHEN a skill named issue/gather exists both locally and globally
  • THEN the local version is used in all operations within that project
  • AND the global version remains unchanged

Requirement: Skill Installation

The CLI SHALL support installing skills from the current project or another local repository into the global library.

Scenario: Install skill globally

  • WHEN user runs wai resource install issue/gather --global
  • THEN the system copies the skill from the current project’s skills directory to ~/.wai/resources/skills/issue/gather/SKILL.md
  • AND confirms the installation path

Scenario: Install skill from another repository

  • WHEN user runs wai resource install issue/gather --from-repo ../other-project
  • THEN the system copies the skill from ../other-project/.wai/resources/agent-config/skills/issue/gather/SKILL.md into the current project’s skills directory
  • AND confirms the installation path

Scenario: Hardcoded project names warned

  • WHEN installing a skill whose content contains the literal value of the current project name or absolute paths beginning with the repository root
  • THEN the system issues a warning listing the suspicious strings
  • AND proceeds with installation (warning, not error)

Requirement: Skill Export and Import

The CLI SHALL support bundling skills for sharing and importing bundles from external sources.

Scenario: Export skills to archive

  • WHEN user runs wai resource export issue/gather impl/run --output skills.tar.gz
  • THEN the system creates a tar.gz archive containing the SKILL.md files preserving the <category>/<name>/SKILL.md directory structure

Scenario: Import skills from archive

  • WHEN user runs wai resource import skills.tar.gz
  • THEN the system extracts skill files into the current project’s skills directory
  • AND prompts before overwriting any existing skill
  • AND reports which skills were installed

Scenario: Non-interactive import with –yes

  • WHEN user runs wai resource import skills.tar.gz --yes
  • THEN the system overwrites existing skills without prompting
  • AND reports all skills that were overwritten

Timeline & Search

Purpose

Define cross-artifact search and chronological timeline views that help users find and navigate artifacts across the entire .wai/ structure.

Problem Statement

As a project accumulates research notes, plans, designs, and handoffs across multiple projects and areas, finding specific information becomes increasingly difficult. Users need two complementary navigation modes: chronological (what happened when?) and content-based (where is this mentioned?). Without built-in search and timeline capabilities, users fall back to manual file browsing or external grep commands that lack context about wai’s organizational structure.

Design Rationale

Dual Navigation Modes

Providing both timeline and search views is a Type 2 decision based on two fundamental ways developers navigate information:

  • Timeline answers “what happened?” — useful for reconstructing context, reviewing progress, and generating reports
  • Search answers “where is this?” — useful for finding specific decisions, references, or artifacts

Project-Scoped and Global

Both timeline and search support project-scoped queries (most common) and global queries (cross-project discovery). This dual scope matches how developers think: usually focused on one project, occasionally needing to find something across all work.

Scope and Requirements

This spec covers the timeline and search commands and their filtering capabilities.

Non-Goals

  • Full-text indexing or database-backed search
  • Search ranking or relevance scoring
  • Real-time search updates or watch mode
  • Integration with external search tools

Requirement: Timeline View

The CLI SHALL provide a chronological view of artifacts within a project.

Scenario: Project timeline

  • WHEN user runs wai timeline <project>
  • THEN the system scans all dated artifacts in the project directory
  • AND displays them chronologically with date, type, and title

Scenario: Timeline output format

  • WHEN displaying a timeline
  • THEN each entry shows:
    • Date (from filename prefix)
    • Artifact type (research, plan, design, handoff)
    • Title or filename
  • AND entries are sorted newest-first by default

Scenario: Timeline output as JSON

  • WHEN user runs wai timeline <project> --json
  • THEN the system outputs JSON entries with date, type, title, and path

The CLI SHALL provide full-text search across all artifacts.

  • WHEN user runs wai search <query>
  • THEN the system searches across all .wai/ artifacts
  • AND displays matching files with context lines
  • WHEN user runs wai search <query> --type research
  • THEN the system searches only within research artifacts
  • WHEN user runs wai search <query> --in <project>
  • THEN the system searches only within the specified project’s artifacts

Scenario: Search output format

  • WHEN displaying search results
  • THEN each result shows:
    • File path (relative to .wai/)
    • Matching line with query highlighted
    • Context (lines before and after the match)

Scenario: Search output as JSON

  • WHEN user runs wai search <query> --json
  • THEN the system outputs JSON results with path, line_number, line, and context