Skip to main content

WADE — Workflow for AI-Driven Engineering

WADE

AI tools write the code. WADE handles everything else.

Every Wade does the dirty work so the heroes don't have to.

Branches, worktrees, context loading, model routing, PR creation — all the workflow friction that surrounds AI coding sessions. WADE eliminates it. It works with Claude Code, Codex, Copilot, Cursor, Antigravity CLI, and more, and pulls tasks from GitHub Issues, ClickUp, or a committed Markdown file. Run wade init once per project, then drive your work from task numbers while WADE handles the git and GitHub plumbing around every AI session.

Highlights

  • Deterministic planning — wade plan turns a goal into validated plan files that become lightweight tasks plus draft PRs, each labeled by complexity.
  • Isolated worktrees — every task gets its own git worktree, so parallel sessions never collide or stash-juggle.
  • Full context, zero copy-paste — the task, its description, labels, and your project conventions are loaded into the AI automatically.
  • Agent guardrails — on hook-capable AI tools, per-session hooks keep the AI inside its worktree and route it through a completion gate before any push; hookless tools retain the same fixed workflow and deterministic service gates (see the tool support table).
  • Quality gates — opt-in pre-commit lint/test and conventional-commit checks, plus an AI code-review pass before the PR is marked ready.
  • Pluggable task providers — GitHub Issues, ClickUp, or a committed Markdown file; PRs and reviews always run through GitHub.
  • Multi-tool — automatic model routing by task complexity across every supported AI coding tool.

See It in Action

Starting work on task #42:

Without WADE:

git fetch origin && git checkout main && git pull
git checkout -b feat/issue-42-user-auth
# paste task title + description into AI chat
# explain your branching rules, test locations, linters to run...

With WADE:

wade 42

With no open PR for task #42 yet, WADE starts an implementation session: it creates an isolated git worktree, launches your AI tool with the full task loaded — title, description, labels, and all your project conventions — and a fixed workflow plus selected methodology guide it from first commit to open PR. Want the AI to break the work down first? Run wade plan — planning is a deliberate step, not something wade 42 guesses at from a missing plan.

Finishing work and opening the PR:

Without WADE:

git checkout main && git pull
git checkout feat/issue-42-user-auth
git merge main          # resolve conflicts yourself, if any
git push
gh pr create --title "User Auth (#42)" --body "..."   # write description manually
# don't forget to link the task, clean up the branch...

With WADE (the AI handles all of this):

wade implementation-session done

The AI merges the latest main into the branch, resolves any conflicts, writes the PR description from what it built, and marks it ready for review — you get a clean, already-integrated diff with no noise for your reviewer.

Working on multiple tasks at once:

wade implement-batch 42 43 44   # three worktrees, three AI sessions, zero stashing

Why WADE

Without WADE With WADE
git fetch && checkout && pull && checkout -b ... before every task wade 42 — one command, done
Copy-paste task title + description into AI chat every time Full task context + project conventions loaded automatically
One task at a time, or stash-juggle between branches Parallel tasks in isolated worktrees, zero conflicts
Re-explain lifecycle and review rules every session A fixed workflow carries them; dynamic skills add your methodology
PRs opened on stale branches — reviewer sees conflict noise, asks for a rebase, CI fails AI merges the latest main and resolves conflicts before the PR — reviewer sees only your changes
Write the PR description, link the task, clean up the branch — manually The AI ships the PR. You just review
Manually pick the right model for each task Automatic model routing based on task complexity
Which terminal tab has which task? No idea Terminal title shows wade implement #42 — Feature Name
Which AI session worked on this task? Which tool? Which model? Every PR and task logs the tool, model, and session resume command — for both Plan and Implement phases

Installation

One-line install script (installs uv automatically if missing):

curl -LsSf https://raw.githubusercontent.com/ivanviragine/wade/main/install.sh | sh

Or, if you already have uv or pipx:

uv tool install wade-cli    # recommended
pipx install wade-cli

Requires gh CLI (authenticated) and at least one supported AI coding tool.

gh auth login    # if not already authenticated

To let WADE move issues across a GitHub Projects (v2) board (e.g. to In Progress), also grant the project scope. This is optional — everything else works without it:

gh auth refresh -s project

Quick Start

Initialize WADE in your project (once):

wade init

Then work in two deliberate steps — plan, then implement:

# Plan deliberately — the AI writes validated plan files, each becoming a
# lightweight task plus a draft PR
wade plan

# Start (or resume) implementation on task 42
wade 42

wade <N> routes on the task's PR state, not on whether a plan exists:

  • No PR yet, or a closed unmerged one → starts (or resumes) an implementation session.
  • Open draft PR → continue the in-flight session (or start it if the worktree is gone).
  • Open ready PR → choose to continue working, address review comments, merge, or open the PR in your browser.
  • Merged PR → reports the task is already merged and stops — no session.

It never launches a planning session on its own — reach for wade plan when you want planning.

The WADE lifecycle

wade plan ─▶ tasks + draft PRs ─▶ wade <N> ─▶ AI implements in an isolated worktree ─▶ PR opened ─▶ wade review pr-comments <N> ─▶ merge
  • You run the entry points: wade plan, wade <N> / wade implement <N>, wade review pr-comments <N>, and wade cd <N>.
  • The AI runs the session commands that enforce the workflow and open/update the PR: wade implementation-session {check,sync,done}, wade review-pr-comments-session {check,sync,done,fetch,resolve}. Native planning returns an artifact; the parent runs its review and validation gates.

Commands

Commands you run

Command Description
wade <N> Smart entry — routes by the task's PR state to implement, continue, review, merge, or open-in-browser
wade plan AI planning session — writes validated plans that become tasks + draft PRs
wade implement <N> Create a worktree and start an implementation session for a task
wade implement-batch <N> <M> ... Start parallel sessions for multiple tasks (beta)
wade review pr-comments <N> Start a session to address PR review comments
wade review trigger <N> Post configured bot-review triggers on the task's PR
wade review plan <file> AI-powered plan review
wade review implementation AI-powered code review of the current diff
wade review batch <N> Coherence review across parallel implementation branches
wade cd <N> Navigate to a task's worktree (requires shell integration)
wade task create Create a task interactively (in your configured provider)
wade task list List open tasks
wade task read <N> Show task details
wade task update <N> Update a task body or add a comment
wade task close <N> Close a task
wade task deps <N> <M> ... Analyze dependencies between tasks
wade worktree list List active worktrees
wade worktree remove <N> Remove a worktree
wade init Initialize WADE in the current project
wade update Upgrade WADE and refresh project files
wade deinit Remove WADE from the current project
wade check-config Validate .wade.yml configuration
wade skills list List built-in methods and discovered project skills
wade skills resolve --session <kind> Explain effective session bindings and precedence
wade skills resolve --delegation <kind> Explain an effective standalone delegation binding
wade skills check Deep-check discovered trees and configured skill refs
wade session describe Show the active session's frozen workflow/bindings
wade session refresh-skills Explicitly rediscover and replace active skill snapshots
wade knowledge add Append a project learning from stdin (unavailable in a plan/deps session)
wade knowledge get Print the current project knowledge file
wade knowledge rate Record an up / down / stale vote for a knowledge entry
wade knowledge status Show uncommitted knowledge/ratings changes and any pending ratings migration
wade knowledge enable [--path PATH] Enable knowledge capture and optionally set custom file path
wade knowledge disable Disable knowledge capture (keeps existing knowledge file)

Short aliases: wade p (plan), wade i <N> (implement), wade r <N> (review pr-comments).

Interactive pickers (the arrow-key menus commands like wade task create show) wrap long choices to the terminal width instead of cropping them, so no option text is lost in narrow terminals and the list reflows automatically on resize.

Session commands the AI runs

These are invoked by the AI during a session — you normally don't run them by hand.

Command Description
wade implementation-session check Verify the implementation session's Git, GitHub, and required local capabilities before edits
wade implementation-session docs --updated | --not-needed "reason" Record the required documentation-impact decision for current HEAD
wade implementation-session sync Sync the branch onto the base branch
wade implementation-session done Completion gate — runs the gates, pushes, and opens/updates the PR
wade review-pr-comments-session check | docs | sync | done Same lifecycle and documentation receipt for a review session
wade review-pr-comments-session fetch <N> Fetch unresolved PR review comments as markdown
wade review-pr-comments-session resolve <thread> Mark a PR review thread as resolved on GitHub
wade plan-session check Verify detached planning capabilities before writing plan artefacts or knowledge votes
wade plan-session done <plan_dir> Import an optional native plan (--from-file / --from-stdin), validate, and complete the reviewed handoff
wade deps-session check Verify the detached dependency-analysis runtime before writing output or staging a knowledge vote

Most workflow commands accept --ai <tool>, --model <model>, --effort <level>, --permission-mode <tier>, and --yolo to override configured defaults. review pr-comments additionally accepts --effort none to pin the tool default instead of a configured effort across a later wait/relaunch. plan, implement, and review pr-comments accept repeatable --skill and --review-skill methodology bindings plus --refresh-skills for an existing frozen session; implement-batch forwards the same binding request to every child session. Standalone plan/code/batch review and task deps accept repeatable --skill. plan, implement, implement-batch, standalone reviews (review plan, review implementation, review batch), review pr-comments, task deps, and the wade <N> shorthand also accept --sandbox / --no-sandbox (see AI runtime sandbox profile); batch and shorthand forward an explicit flag to the child session they launch. implement additionally supports --detach (new terminal tab), --cd (print worktree path only), and --base <branch> (see Planning & base branches).

Planning & base branches

wade plan launches Claude, Cursor, Copilot, OpenCode, Antigravity CLI, and Codex in their own interactive terminal, with native Plan mode active before the first task turn. You keep the tool's UI, questions, and conversation. Crossby validates native support and translates approval flags. For Codex, Crossby submits /plan first and WADE sends the task on its ready event. Native questions and subsequent interaction stay in the tool.

Use --permission-mode (or --yolo) for the native approval policy:

CLI Supported modes while planning
Claude default, auto, yolo
Cursor default, auto, yolo
Copilot default, accept-edits, yolo
OpenCode default, yolo
Antigravity CLI default, yolo
Codex CLI default, accept-edits, auto, yolo

Unsupported combinations fail before creating a planning worktree. These are native approval settings, not permission to implement the plan. The later implementation offer still requires an explicit decision.

Where the tool supports a native output-directory setting (Claude), WADE uses .wade/plans/native/. Other tools can keep their native location. Before exit, the planning workflow submits it with wade plan-session done .wade/plans --from-file <path>; --from-stdin accepts explicit Markdown when no file is available. WADE writes its canonical copies. wade review plan <file> reviews those copies inside the session; prompt-mode review emits the frozen method and requires actual self-review followed by --ack-self-review. Run done again after review. Changed content requires a current review before completion. A missing-review error on the first import means the file was imported and awaits review.

One task can be plain Markdown (# feat: title, ## Complexity, tasks and acceptance criteria). Multiple tasks use the explicit versioned plan bundle contract, with filenames and depends_on relationships; headings do not imply task boundaries. Knowledge-enabled sessions include knowledge_votes in that bundle, including an explicit empty list when appropriate. The parent revalidates the completed handoff after exit, then creates tasks and draft PRs. Failed or missing handoffs retain output and create no tasks.

Codex requires CLI 0.154.x and a POSIX terminal (macOS/Linux). Crossby's current startup adapter waits for the rendered Plan indicator before WADE sends the initial task; unknown versions or an unrecognized startup screen fail without retrying the task. This temporary terminal adapter can be replaced by a native launch flag when Codex provides one. WADE requires the task-submitted event before collecting the explicit reviewed handoff. Codex can submit plan Markdown through --from-stdin; no native file destination is assumed.

All native terminals now use the ordinary sandbox default (off), including Codex; use --sandbox or ai.plan.sandbox: true to retain confinement. The retained collector fallback has its own safe default (on). Explicit --sandbox, --network-access / --no-network-access, and --trusted-dir require support from the selected tool. No network flag adds no network grant and does not promise isolation. --approval-policy on-request|untrusted|never and --timeout are collector settings; interactive terminals use --permission-mode and have no time limit. Set ai.plan.mode to interactive or leave it unset for native terminals. GUI launchers remain unsupported for planning.

Authentication, model availability, and successful handoff are runtime checks. Native terminal output is retained for recovery; usage is reported only when the adapter can extract it from that output. WADE's handoff ID is not a native CLI session ID.

If the OS denies the parent access after the terminal exits, WADE reports the permission failure instead of calling the handoff absent, leaves the detached planning worktree intact, and prints a recovery command. Restore filesystem access, then run wade plan --recover <planning-worktree> from the source repo. Recovery does not launch an AI or regenerate content: it accepts only a retained registered detached worktree, then rechecks the frozen bindings, completed state, exact plan content, review receipts, dependencies, and plan validation before any task/provider write. It rejects a handoff whose original launch binding was never durably recorded rather than applying settings changed after collection. If even the plans directory cannot be enumerated, WADE says the retained plan count is unknown rather than reporting zero. WADE never changes OS privacy or sandbox settings for you.

wade plan --issue <N> re-plans an existing task. If the session produces a single plan file, it's attached to #N and the task stays open. If the session decides the work should be split into several independent pieces (2+ plan files), #N is superseded: a new task + draft PR is created per plan file, a comment and a > **Superseded by ...** banner are added to #N, and it's closed as not planned (confirmed via prompt unless --yolo/non-interactive). If any plan file fails to become a task, #N is left open with a warning instead of superseding on a partial split.

Base branch

By default WADE branches from and merges into the project's configured main branch (project.main_branch in .wade.yml, falling back to the repo's detected default). To target a different branch — e.g. develop or a release/* branch — declare it once, at planning time, in an optional ## Base Branch section of the plan file:

## Base Branch
develop

The draft PR is then branched from and targeted at develop, and wade implement cuts the worktree from it and merges back into it. Omit the section to keep the default (main). The base is persisted as the draft PR's own base, so wade implement <N> recovers it automatically — no extra flags needed.

To choose or override the base at implement time, pass --base:

wade implement 42 --base develop   # branch from, target, and merge into develop

--base overrides the plan-declared base and retargets the existing draft PR to match. A malformed base value is rejected up front — whether declared in the plan (fails wade plan-session done) or passed as --base (fails fast when you run wade implement); a well-formed base branch that does not exist fails draft-PR creation with an actionable message. Changing the base of a PR whose work is already in flight — whether by re-running planning or by wade implement --base — is not applied silently: it requires explicit confirmation, because the branch's existing history cannot be moved onto the new base without discarding it.

Reviews & bot triggers

WADE splits review into an AI review pass you or the agent can invoke, and external bot triggers for services like CodeRabbit, Codex, and Bugbot.

Command What it reviews
wade review plan <file> A plan file, before it becomes tasks
wade review implementation The current implementation change (mandatory gate before done)
wade review batch <N> Coherence across parallel implementation branches
wade review pr-comments <N> Starts a session to address human/bot PR comments
wade review trigger <N> Posts configured bot-review trigger comments on the task's PR

Prompt-mode implementation review prints the bounded review prompt and exits 2; printing it does not certify that a review happened. After performing that self-review and addressing its findings, run wade review implementation --ack-self-review to write the current commit and frozen-review-binding receipt. Successful headless or interactive reviews write the same receipt directly. In an implementation session, once the active frozen review binding has consumed done.max_review_passes (default 2), wade review implementation exits successfully without launching another reviewer and directs you to wade implementation-session done. The dispatch cap does not block a valid --ack-self-review, which still writes its active-binding receipt.

The first implementation review for a frozen reviewer binding receives the complete branch change. After a successful review and a new fix commit, a re-review receives only the committed delta since that successful same-binding review, plus any staged or unstaged changes and the local PLAN.md when safely available. This narrows repeated review work without weakening done: the final receipt is still written for the exact current commit. An unreadable record, changed binding, unreachable baseline, or merge on the baseline-to-HEAD path falls back to the complete branch change.

To fetch the unresolved comments themselves during a review session, the agent runs wade review-pr-comments-session fetch <N>; it resolves individual threads with wade review-pr-comments-session resolve.

When a PR-comment session starts, WADE records its pre-edit commit and a feedback snapshot under local .wade/review-cycles/ state, outside the immutable session bundle. Re-fetching retains prior feedback while adding new feedback, but never advances that baseline. Its closing review receives the accumulated feedback and the cycle delta. Unsafe, mismatched, stale, or merged lineage instead uses the complete branch change and its full-branch result contract, which overrides the feedback-fix method's narrow scope. A successful review-pr-comments-session done clears the cycle so later feedback starts from the then-current PR head.

The auto-launched review session

The auto-launched review session — the one started when you pick "Wait for reviews" after wade implementation-session done and comments land — resolves its tool, model, effort, and autonomy tier from a dedicated ai.review_pr_comments section (the same keys every ai.<command> section accepts: tool, model, effort, mode, permission_mode / yolo, sandbox, enabled, timeout):

ai:
  review_pr_comments:
    tool: claude
    model: claude-sonnet-5
    effort: high
    permission_mode: yolo   # auto-launched review runs unattended

With this set, the review session runs in the configured tier even when the implementation session ran without it (the permission_mode: yolo above starts the review session with no prompts). With ai.review_pr_comments unset, tool / model / autonomy fall back to the global ai.* defaults (default_tool, default_model, ai.permission_mode / ai.yolo) — not through ai.implement.*. Projects that relied on ai.implement.tool / model implicitly governing the review session should set ai.review_pr_comments.tool / model (or the global defaults). An explicit wade implement --yolo / --permission-mode still carries into the auto-launched review session.

Triggering external bot reviews

External review bots (CodeRabbit, Codex, Bugbot) normally auto-review on push, but WADE can post a trigger comment to force a fresh review — after addressing comments, pushing fixups, or when a bot has paused. The workflow gains an explicit trigger phase: implement → done → trigger bots → poll/address comments.

wade review trigger <N>            # post every enabled bot's trigger to #N's PR
wade review trigger <N> --bot codex --bot bugbot   # only a named subset
wade review trigger <N> --dry-run  # print what would be posted, post nothing

Each bot reports its own status line — posted / skipped (disabled) / failed: <error> / would post (dry-run). A failing post for one bot never stops the others; the command exits non-zero only when the PR can't be resolved, an unknown --bot name is given, or every attempted post fails. An explicit --bot <name> triggers that bot even if it is enabled: false.

The bots and their trigger phrases live in an optional top-level bot_review: block. It is fully defaulted — a project with no block still triggers CodeRabbit, Codex, and Bugbot — and every field is overridable:

bot_review:
  auto_trigger: false            # opt-in; when true, `done` posts triggers after it pushes
  offer_on_done: true            # default; when auto_trigger is off, `done` OFFERS them
  arrival_timeout: 300           # seconds to wait for an enabled bot to review HEAD
  ack_timeout: 900               # longer ceiling once a bot acknowledges (👀/+1 reaction)
  bots:
    - { name: coderabbit, trigger: "@coderabbitai review", enabled: true }
    - { name: codex,      trigger: "@codex review",        enabled: true }
    - { name: bugbot,     trigger: "bugbot run",           enabled: true }

Each bot's name keys both --bot selection and the per-bot trigger marker (a file under .wade/), so it must be unique and a safe identifier — letters, digits, ., _, - only (no path separators or spaces). A duplicate or invalid name is rejected when the config loads, not only under wade check-config.

With auto_trigger: true, both wade implementation-session done and wade review-pr-comments-session done post the enabled bots' triggers after a successful push, at most once per bot per commit SHA (repeated done/sync on the same commit post nothing further; a bot whose post failed retries). The manual wade review trigger command always fires and ignores those markers, so a same-SHA done still auto-triggers independently. wade init writes the block for you and asks which of the three modes below you want. Whatever a bot posts back is untrusted context — the review session's verify-before-fixing rule still applies.

Not auto-triggering? WADE offers instead of forgetting

With auto_trigger: false (the default) WADE does not silently drop the triggers — offer_on_done: true (also the default) makes it offer them once the work is pushed, so you never have to remember wade review trigger <N>:

Where What you see
done, at a terminal Post the bot-review triggers now (coderabbit, codex)?
done, in an AI session (no TTY) a line telling the agent to offer it in its closing dialog
the post-session menu (Merge PR / Wait for reviews) an extra Trigger bot reviews (…), then wait entry
the quiet-PR menu (Keep polling / …) an extra Trigger bot reviews (…) entry

Both done commands also take an explicit override for a single run:

wade implementation-session done --trigger-bots      # post them, whatever the config says
wade review-pr-comments-session done --no-trigger-bots  # stay quiet, even with auto_trigger: true

Every one of these paths is once per bot per commit SHA, like the auto-trigger: a bot already triggered for the current commit is neither posted again nor offered again (wade review trigger <N> remains the way to force a re-post). Repos whose bots already review every push automatically can turn the whole offer off with offer_on_done: false — then WADE stays silent unless you ask.

Expectation-verified completion. WADE no longer reports a review "done" just because no blocking comments are present — it verifies that every enabled bot has actually posted a review covering the latest commit. While an expected bot has not, wade review pr-comments / poll / fetch keep waiting (and name the bot) rather than printing "All review comments resolved". The wait is bounded by arrival_timeout (default 300s); past it the bot stops blocking and is surfaced distinctly (⚠ No review from <bot>), never silently swallowed into "done". A bot that acknowledges with a reaction (👀 / +1) is treated as actively reviewing and waited for up to the longer ack_timeout (default 900s). Latency note: because all three bots ship enabled, a repo without one installed adds up to arrival_timeout to each review check before proceeding — disable an unused bot (enabled: false) to remove its floor. ack_timeout must be >= arrival_timeout.

Guardrails & completion gates

Session guards

When WADE creates a worktree it installs hooks into whichever tools your project uses, so session rules are enforced in code rather than left to the agent to honour. Guards are written per-worktree at session start — upgrading WADE is enough to pick up improvements, with no re-init or migration.

Guard What it blocks
Worktree containment Writes that land outside your worktree
Plan-artifact During wade plan, writes to anything but plan artifacts
Session completion Finishing an implement/review session with unfinished work not yet run through done (nudges once)
Native plan completion (parent gate) Creating tasks before authoritative import, review, and strict plan validation

The session-completion guard keys on the same fact done records — a sha-keyed .wade/done@<HEAD> marker written when done's gates pass — so it nudges only when the branch has commits ahead of its base and done has not finalized the current commit. An early "stopping to ask a question" turn (no commits ahead) never triggers it. This Stop nudge fails open. Native planning does not install the old file-based Stop nudge. Interactive sessions explicitly import, review, and complete their plans before exit; the parent revalidates them. Codex retains parent-side collection and review. Native transports may differ in hook support; completion does not depend on hooks firing.

Independently of that nudge, wade plan now strictly validates plan files before creating tasks: a PLAN*.md missing a valid ## Complexity or a conventional-commit title is dropped with a loud error instead of silently becoming a task with no complexity label.

wade task create enforces the same conventional-commit title rule (the type list is the single Python source in utils/conventional.py): a non-conventional --title (or a plan file's # Title) is rejected, and interactive create re-prompts. The PR title is derived from the task title verbatim, so this is what keeps a wade-opened PR from ever failing the PR Title Lint CI check; done also blocks on — and syncs — a stale non-conventional title on an already open PR (see the completion-gate table below).

Like wade plan, wade task create also reads a ## Complexity section from the task body (from --body, a plan file, or interactive input): when present, its value is attached as a complexity:X label on top of the project label — the same signal that drives automatic model routing, so a hand-created task routes to the right model just like a planned one. Labeling is best-effort: a failure to apply the label never fails task creation, and a body with no ## Complexity section just skips it. An explicit --label complexity:X takes precedence over the body value, so the task never ends up with two conflicting complexity labels.

If some files pass and others fail, a human must explicitly accept a dependency-closed valid subset, even with --yolo. Noninteractive runs abort. If you decline, or if every plan file fails validation, no tasks are created — the generated PLAN*.md are preserved to a temp directory so you can fix the reported errors and re-run instead of regenerating from scratch.

Both write guards cover shell commands as well as file edits, so a redirect like printf x > ../other-repo/app.py is blocked, not just an Edit call. Shell coverage is best-effort defense-in-depth: it catches ordinary commands, not deliberate obfuscation (variable indirection, command substitution, subshells).

Tool Write guard Session-completion guard
Claude Code ✅ ✅
Cursor ✅ ✅
GitHub Copilot ✅ ✅
OpenAI Codex ✅ shell (writes are sandboxed natively) ✅
Antigravity CLI ✅ ✅

The remaining supported tools (OpenCode, VS Code, Antigravity IDE) expose no hook mechanism WADE can install into, so they receive neither hook guard. Their session still loads the fixed workflow, and deterministic lifecycle commands and completion gates remain authoritative.

Completion gates

wade implementation-session done (and review-pr-comments-session done) is the authoritative completion gate: it refuses to finalize until the work is actually ready, then writes the .wade/done@<HEAD> marker and pushes. Policy gates normally have an escape hatch under a done: block in .wade.yml (all default on). Decision and integrity gates deliberately require an explicit valid outcome:

Gate Refuses when… Hatch
PR-SUMMARY PR-SUMMARY.md is missing, empty, or still a template placeholder (both change-producing session types) done.require_pr_summary: false
Documentation decision neither an --updated nor reasoned --not-needed receipt exists for current HEAD no disable toggle; docs --not-needed "<reason>" records the explicit no-change outcome
Sync the branch is behind main — auto-syncs first, refuses only on conflict (both change-producing session types) done.require_sync: false
Review ran wade review implementation has no successful external-review or explicitly acknowledged self-review record for the current commit and frozen REVIEW binding, or the frozen workflow/skill bundle no longer matches its manifest. Bundle validation happens before receipts or pass counts are trusted. Prompt emission alone never satisfies this gate. Implementation sessions bound this loop: at done.max_review_passes (default 2), wade review implementation stops before launching an excess reviewer, while a valid --ack-self-review may still record its receipt; done remains authoritative and completes an unreviewed later commit with a cap-reached status instead of looping forever --skip-review, done.require_review: false (auto-off when ai.review_implementation.enabled: false)
Resolved threads unresolved PR review threads remain (review-comments only) done.require_resolved_threads: false
Conventional title the task title is not a conventional-commit title (the PR title is derived from it, so it would fail PR Title Lint) — blocks; when valid but the open PR's title differs, syncs the PR title to match (both session types) — if that sync fails while the PR's current title is itself non-conventional (lint would fail), done fails so it can be retried done.require_conventional_title: false
Knowledge valid the knowledge file is structurally corrupt — duplicate entry IDs or unresolved conflict markers (e.g. from a merge=union merge) none — gated by knowledge.enabled; no done.* hatch

A pre-push git hook (done.pre_push_backstop, default on) backs the gate up: a push of the session branch without a current .wade/done@<sha> marker is refused, so committing-and-pushing straight past done doesn't work. It is worktree-scoped (never touches your main checkout or sibling worktrees) and chains to any pre-existing pre-push hook. Honesty: git push --no-verify bypasses the backstop in one flag — this is a quality/backstop layer that makes the gate hard to skip, not an airtight boundary.

done also writes a ## Review Status line into the PR body recording the review outcome — reviewed at <sha>, reviewer changed, skipped via --skip-review, gate disabled (done.require_review: false / ai.review_implementation.enabled: false), or completed at the active review binding's pass cap. A skipped, stale-reviewer, or never-run review is therefore visible to reviewers rather than hidden in worktree state.

Task Providers

WADE can pull tasks from three backends — pick one when you run wade init:

Provider Where tasks live Auth
github (default) GitHub Issues gh CLI
clickup ClickUp list API token in env var
markdown A single committed ISSUES.md None

PRs and reviews always flow through GitHub, regardless of the task provider. Non-GitHub providers compose a delegate that forwards every PR/review operation — review-thread listing and resolution, PR comments, and review status — to GitHub via the gh CLI, so wade review pr-comments, the auto-poll loop, and wade review-pr-comments-session fetch / resolve behave identically across providers. Only where a task itself lives differs.

Markdown provider

Useful when you want tasks versioned alongside the code, with no external service. Each task is one ## heading in the file:

# Wade Issues

## #47239185 Add login feature

<!-- wade
state: open
labels: feature, complexity:medium
-->

Description body here. Sub-headings, code blocks, anything markdown.
  • The file is resolved against the main worktree, so every linked worktree reads/writes the same physical file. No textual merge conflicts on ISSUES.md.

  • IDs are random 8-digit decimal so two parallel wade implement sessions in different worktrees can't collide. They stay numeric so existing #NN checklist refs in tracking-issue bodies still work.

  • Configure via .wade.yml:

    provider:
      name: markdown
      settings:
        path: ISSUES.md      # relative to repo root, or absolute
        auto_commit: false   # if true, close_task auto-commits the change
    
  • After a PR merges, provider.close_task flips the section's state to closed in ISSUES.md. By default the file is left modified in your working tree — commit it yourself. Set auto_commit: true to have wade commit the change with a chore: close #N message; failures (not a git repo, hook rejection, signing required) are logged and swallowed so the close itself never blocks.

  • Tracking tasks with - [ ] #N checklist bodies work the same as with GitHub Issues — markdown's find_parent_issue scans every section's body for child refs.

Permission modes, autonomy & sandboxing

Permission modes

These autonomy tiers apply to ordinary launches and supported native Plan terminals. Codex planning retains parent-only default/YOLO with a separate collector approval policy, as described above.

--permission-mode sets how much autonomy the AI tool is granted — an axis independent of the delegation --mode (which controls how a tool is dispatched: prompt/interactive/headless). The tiers, most→least permissive, are yolo > auto > accept-edits > default:

Tier Behavior
default Prompt for every action (no autonomy grant).
accept-edits Auto-apply file edits; still prompt for shell/commands. Claude and Antigravity CLI.
auto Classifier-mediated auto mode (a model reviews each non-read action). Claude and Cursor.
yolo Full autonomy — no prompts.

--yolo is a back-compat alias for --permission-mode yolo; an explicit --permission-mode wins when both are given. The same values are accepted in .wade.yml as ai.permission_mode (global) or ai.<command>.permission_mode (per-command), with yolo: true still honored as the alias. A tier a tool doesn't support is downgraded automatically for ordinary launches (for example, auto → accept-edits when classifier auto is unavailable), with a warning — WADE forwards the requested tier and crossby owns the downgrade ladder. Native Plan combinations are validated strictly and rejected if unsupported. Headless launches are always read-only — any of deps / review_plan / review_implementation / review_batch dispatched in headless delegation mode runs at default regardless of the configured tier, and no --yolo is forwarded to the subprocess. The interactive variants honor the tier: wade review plan, wade review implementation, wade review batch, and wade task deps all accept --yolo / --permission-mode (matching wade review pr-comments), and ai.review_batch.yolo: true / ai.deps.yolo: true apply when those commands run interactively; the auto-launched review session honors its own tier via ai.review_pr_comments (see above). plan is not a permission mode — it's driven separately — and is rejected (warn + fall back to default) if configured.

The resolved permission mode is always displayed at launch, on every path (TTY, non-TTY, headless, all-flags-explicit), with a one-line descriptor — so a default session states what default means, and what is shown always equals what is applied.

Headless review budget

Those headless commands auto-scale their subprocess budget from the prompt size and reasoning effort (600s floor → 1500s ceiling), so a large diff or a high-effort run no longer times out at a flat budget. If a run does time out, wade keeps whatever partial output the reviewer produced (rather than discarding it) and retries once with a longer budget (1.5x the first attempt, always strictly more time than the run that just timed out), bounded to a ~62.5-minute worst-case total that the pre-launch advisory announces. Set ai.<command>.timeout (seconds) to override: an explicit value is used verbatim and turns off both the scaling and the retry — the escape hatch when your terminal/orchestrator enforces a hard tool-timeout (set it just under that limit).

A headless reviewer also gets told its own deadline: the plan/code/batch review prompt states the current attempt's budget in seconds, so it can prioritize the highest-severity findings and wrap up before being cut off rather than getting killed mid-thought. Interactive and self-review (prompt) reviews have no subprocess kill, so they get "no hard deadline" wording instead. When a headless subprocess exits non-zero, wade retains trimmed stdout and appends a clearly labeled stderr tail containing at most the final 20 non-empty lines and 4,000 characters; if stdout is empty, that diagnostic is shown as the failure feedback, and any truncation is labeled.

AI runtime sandbox profile

The defaults below apply to non-plan launches. Native planning uses the independent request policies described in Planning & base branches.

ai.sandbox is a single cross-tool boolean that decides whether WADE launches the AI runtime inside its own filesystem sandbox. It governs the external runtime boundary only — it never relaxes WADE's own guards (see below).

Setting Meaning
sandbox: false (default) Launch the runtime unrestricted. Codex gets --sandbox danger-full-access, Cursor --sandbox disabled. Repository commands and delegated child tools keep normal host access and credentials.
sandbox: true Launch the runtime confined. Codex gets --sandbox workspace-write, Cursor --sandbox enabled.

Network access is on in both non-plan profiles and is not configurable for ordinary launches. Not every phase needs it (dependency analysis does not), but the phases that do — git fetch/push, gh, package installs — cannot work without it, and the profile is fixed at launch.

Set it globally or per command, and override it on any launch command (implement, implement-batch, plan, review pr-comments, task deps, smart-start, and the i/r/p aliases) with --sandbox / --no-sandbox:

ai:
  sandbox: true                 # confine every session's runtime
  implement:
    sandbox: false              # ...except implementation (per-command wins)

Precedence: --sandbox/--no-sandbox > ai.<command>.sandbox > ai.sandbox > unrestricted. WADE pins the resolved profile explicitly in both directions, so an ambient setting in your own Codex config.toml can never silently move the boundary of a WADE-managed session. The resolved profile is printed at launch next to the tool, model, effort, and permission mode, with its meaning spelled out — the security posture is never left implicit.

Why unrestricted is the default. WADE runs a deliberately multi-model workflow: a session delegates to reviewers and dependency analysers that authenticate separately. Every wade command is a child of the AI runtime, so a sandboxed outer runtime hands its sandbox to every child — and a separately authenticated reviewer such as Claude Code loses its normal host login. That is what makes delegated multi-model sessions fail in practice (#478).

unrestricted is not "unattended". The profile is orthogonal to permission_mode: it moves the OS boundary, not the approval tier. Codex's --sandbox danger-full-access is a distinct flag from --dangerously-bypass-approvals-and-sandbox, so disabling the sandbox never implies yolo and never changes the resolved autonomy tier. Treat it as an intentional project opt-in to host access, not as a synonym for skipping prompts.

Only tools with a sandbox toggle (Codex, Cursor) act on the setting. The capability handling is deliberately asymmetric, because the default is false:

  • sandbox: false on a tool that never sandboxed anything (Claude, Copilot, …) is a silent no-op — those runtimes are already unrestricted.
  • sandbox: true explicitly requested on a tool with no sandbox toggle is a visible error naming the tool. WADE cannot impose a boundary the runtime does not have, and will not pretend it did. No tool ever receives an invented flag.

Worktree git metadata under sandbox: true

A worktree's git metadata lives outside the worktree tree (<main>/.git/worktrees/<wt> and <main>/.git), so under workspace-write every git write — git add/commit, ref updates, stash, and wade sync/done — would fail with Unable to create …/index.lock or could not write index. WADE fixes this automatically: it passes the worktree's absolute path to the launcher, which grants those out-of-root git-metadata dirs as sandbox writable roots (the OS sandbox otherwise stays fully enabled — this widens nothing else). It is transparent, needs no Codex config or manual approval, and is inert under sandbox: false, where there is no boundary to widen.

WADE's own guards are unaffected

Disabling the runtime sandbox does not disable WADE's containment. The worktree-containment guard actually gets wider: under sandbox: true it is narrowed to the shell token (Codex's sandbox already covers tool-call writes, but permits /tmp and $TMPDIR, so a shell redirect can still escape), while under sandbox: false the full matcher is installed because nothing else covers tool-call writes outside the worktree. The plan-artifact guard, lifecycle hooks, the Stop hook, and the pre-push backstop are identical in both profiles.

Plan → implement handoff

The sandbox is a launch-time OS property: a process started confined cannot drop its sandbox later. An accepted plan handoff runs after the planner child exits, so WADE assesses the actual parent runtime enclosing the handoff, not the former planner's requested profile. When that runtime is detected as sandboxed and implementation resolves to unrestricted, WADE fails the handoff rather than claiming a terminal child escaped the parent boundary. It names the runtime it could not escape, and you open a new host terminal and run the displayed wade implement <issue> --no-sandbox command. Without a published sandbox signal, the ordinary nested-launch guard applies rather than guessing.

An inner wade process cannot escape a parent sandbox

Every wade command you run from inside an AI CLI session is a child of that session. If the session was launched under an OS sandbox, every descendant inherits the boundary — no profile WADE resolves, and no flag it passes to a delegated runtime, can widen it. WADE will never claim otherwise, and there is no setting that changes it. The fix is always to relaunch the outer session with the profile you want, from a host terminal.

What WADE does instead is say so. When the resolved profile is unrestricted and the enclosing runtime is known to be sandboxed, it names that runtime when it can (or says the enclosing AI runtime when an identity marker is absent) and prints the exact command to re-run — on implementation, plan, PR-comment review, and every delegated operation (dependency analysis, plan/code review, batch review), plus batch implementation before it dispatches terminal brokers. That command preserves the resolved tool, model, effort, and permission mode; only the sandbox profile changes to --no-sandbox. Implementation and PR-comment retries reuse their frozen method bindings rather than repeating --skill / --review-skill flags, while fresh delegated operations carry their requested bindings. It warns and proceeds rather than blocking: a delegated tool whose credentials happen to be reachable from inside the sandbox may still succeed, so refusing to try would break sessions that work today.

Detection is deliberately best-effort and conservative. WADE reads only sandbox signals a runtime actually publishes and never infers confinement from tool identity — a tool that can be sandboxed is not a tool that is sandboxed. Today Codex publishes CODEX_SANDBOX for macOS Seatbelt, but its Linux Landlock sandbox with network enabled publishes neither that marker nor a usable CODEX_SANDBOX_NETWORK_DISABLED marker. WADE must report that Linux environment as unknown, not unrestricted; if the distinction matters, relaunch from a host terminal rather than expecting a diagnostic. When there is no signal WADE stays silent rather than asserting a cause it cannot support. A confident wrong diagnosis is worse than the opaque error it would replace. Managed Codex sessions are still recognised when they expose session/thread markers instead of the legacy CODEX_CLI marker; their displayed identity remains Codex CLI.

An explicit unrestricted signal (for example, Codex's CODEX_SANDBOX=danger-full-access) is different from an absent signal: WADE does not recommend relaunching the outer session for a permission- or network-shaped launch failure in that case. The parent has already confirmed it is unrestricted, so check executable permissions and network configuration instead.

Troubleshooting order when a delegated tool fails to launch:

  1. Read what WADE printed. An explicit sandbox-policy denial plus a named runtime and command means relaunch the outer session with that command. A generic permission or network denial also needs local checks below.
  2. Check whether the reviewer actually started. A reviewer that ran and exited non-zero is a different problem; "relaunch the outer session" is wrong advice for it. WADE distinguishes the two. A generic launch denial can also be bad executable permissions or network configuration; a refusal WADE made itself (an unknown tool, a tool with no headless mode) never reached the sandbox and gets generic remediation instead.
  3. Check executable permissions, network, and the tool's own login/PATH in the runtime where it must run (gh auth status, the delegate's own auth command). A separately authenticated delegate needs its own credentials, not WADE's.
  4. Re-run the phase readiness check (wade implementation-session check, wade review-pr-comments-session check, …) for a narrow reason=… and its least-privilege remediation.
  5. Only then widen the profile — and widen the outer session, not the child.

Narrow, optional exception: Codex project prefix rules. Codex can be configured to run specific command prefixes outside its sandbox, which elevates a single command without relaunching the session. It is a Codex-side setting WADE neither writes nor reads, it applies per command rather than to the session, and it does not change anything above: the session is still sandboxed and every other child still inherits that. Treat it as an escape hatch for one stubborn command, not as WADE's path for running unrestricted — that path is relaunching the outer session.

Migrating from ai.network_access

ai.network_access was a Codex-only network pin, enabled by default for implement and review_pr_comments and off everywhere else. It is retired. An existing .wade.yml that still carries it keeps loading and passes wade check with a warning, not an error; the key is ignored, and wade update strips it — that is the only command that runs the config migration pipeline. Replace it with ai.sandbox if you want the old confinement back:

ai:
  sandbox: true                 # restores the pre-#478 Codex behaviour

Session readiness and least-privilege remediation

Every wade command an agent runs is a child of the AI tool. It inherits that tool runtime's filesystem sandbox, environment/PATH, network policy, gh credentials, and the effects of any command or hook approval. WADE does not become privileged because it launched the session: a wade … done call and its own git/gh subprocesses are subject to the same containment.

Run the phase-specific readiness check as the first agent action. The implementation and PR-comment lifecycle commands also repeat the same non-mutating check immediately before catchup, sync, done, fetch, or resolve, so a resumed session cannot turn a changed sandbox/PATH/credential state into a late raw Git or GitHub failure. done checks the worktree it will act on, so running it from the main checkout with a worktree/issue target or --plan still works. It reports stable capability failures: WORKTREE_GIT_BLOCKED (3), GITHUB_CLI_BLOCKED (4), GITHUB_AUTH_BLOCKED (5), GITHUB_API_BLOCKED (6), KNOWLEDGE_STAGING_BLOCKED (7), and PLAN_DIR_BLOCKED (8) — plus one non-failure state, PLAN_DIR_ONLY (exit 0), described next. The result includes a machine-readable reason=… and narrow remediation; do not disable a sandbox globally or give the AI write access to the main checkout.

When wade plan cannot create a planning worktree — bootstrap failed, or you are not in a git repo — it falls back to a standalone plan directory and runs the agent from your checkout. That supported mode reports PLAN_DIR_ONLY (exit 0) with a plandir=…: planning proceeds, but the agent may write only that directory. PLAN_DIR_BLOCKED means even the plan directory is not writable.

Agent session Run in the AI runtime Required there Intentionally not required there
Planning wade plan-session check a worktree and, when knowledge is enabled, local .wade/ vote staging — or, in the PLAN_DIR_ONLY fallback, just a writable plan directory (no worktree, no vote staging) GitHub, remote network, and writable out-of-worktree Git metadata — the parent wade plan finalizes tasks/PRs after exit
Dependency analysis wade deps-session check worktree output and optional local vote staging GitHub and Git metadata writes — the parent wade task deps reads/updates task data after exit
Implementation wade implementation-session check worktree plus Git metadata writes, usable gh authentication, and a read-only GitHub API route main-checkout writes
PR comments wade review-pr-comments-session check the same Git/GitHub capabilities as implementation, because it fetches threads, syncs, resolves, and completes a PR main-checkout writes

Implementation and PR-comment checks require GitHub regardless of the task provider: Markdown and ClickUp can own tasks, but PR creation, review threads, and done still use GitHub. The check first verifies that gh can start in the actual runtime (GITHUB_CLI_BLOCKED distinguishes a missing/blocked executable from bad credentials), then runs gh auth status and gh api user --method GET; all three are non-mutating and have a short bounded timeout. It cannot prove credentials for an arbitrary Git remote, test dependencies, or a project-specific hook — those run later under the same sandbox and surface their own exact error.

permissions.allowed_commands and a tool's approval UI only decide whether the agent may launch a command such as wade; they do not grant filesystem or network authority to the child process. Likewise, WADE's installed hooks are guardrails, not privilege escalation: a failing hook may block a command, but cannot make gh, Git metadata, or a network route available.

If wade review implementation cannot launch its reviewer because of missing credentials, PATH, or sandbox execution access, it does not consume a done.max_review_passes slot: repair the runtime and retry. A real headless timeout still counts as a bounded review attempt, so the review/fix loop cannot run forever.

A reviewer that never started — including a sandbox-capability refusal before the launch — is recorded as an unattempted review so the state is auditable, and that record is deliberately inert: it satisfies no review requirement, spends no review pass, cannot overwrite a real receipt already written for the same commit, and leaves wade implementation-session done and wade review-pr-comments-session done closed. An infrastructure failure must never be able to certify a commit. A reviewer that started and exited non-zero stays distinguishable from one that never ran, because the two need opposite remediation.

For Codex, WADE launches unsandboxed by default so delegated tools keep their own host credentials; set ai.sandbox: true (or pass --sandbox) to keep --sandbox workspace-write, where WADE/crossby add only the linked worktree's private/common Git metadata directories. Every session has network access in both profiles for its GitHub lifecycle. Standalone wade review plan, wade review implementation, and wade review batch runs also accept --sandbox / --no-sandbox; an inherited-sandbox diagnosis gives the host-terminal relaunch command with --no-sandbox so it overrides an ai.sandbox: true configuration. The command also preserves the selected review mode, tool, model, effort, permission mode, staged scope, and review-skill overrides so the retry reviews the same operation. For Claude Code and Cursor, allowlist the worktree/Git metadata paths and only the GitHub domains needed by the session rather than choosing unrestricted shell access. Copilot and VS Code need network plus usable gh credentials in their host runtime. OpenCode shells execute with host authority, so treat the selected host runtime and its credentials as the boundary rather than assuming a worktree is one. These are external tool/runtime settings; WADE reports missing capabilities but never rewrites them.

Detached plan and dependency sessions stage knowledge-rating events in their own ignored .wade/ area. Wade flushes those durable-ID events into the main ratings spool before removing the throwaway worktree; a failed handoff preserves the worktree, and the next wade plan or wade task deps automatically hands off what it finds there and tells you what it recovered — no recovery command to remember. Only a worktree wade itself created for one of those two lifecycles stages votes — it is marked at creation by the same parent that will flush it. Any other detached checkout (a CI checkout, git checkout <sha>, your own git worktree add --detach) records votes normally, so nothing is left staged with no one to deliver it. Dependency sessions also save their returned edge analysis there before handoff, so a blocked main checkout does not discard the generated output. The next attached worktree remains the only path that commits the ratings log into a PR.

Supported AI Tools

Adapters, model/effort resolution, and per-tool config (allowlists, hooks) are powered by crossby, WADE's AI-tool-integration dependency.

Tool Binary
Claude Code claude
Cursor cursor
GitHub Copilot copilot
OpenAI Codex codex
OpenCode opencode
VS Code code
Antigravity IDE antigravity
Antigravity CLI agy

In .wade.yml, refer to a tool by its config ID, which matches the binary above except for VS Code (vscode) and Antigravity CLI (antigravity-cli). Antigravity IDE (config ID antigravity) is launch-only — WADE opens your workspace in the desktop app; its workflow files are provisioned via the Antigravity CLI's shared .agents/ layout.

Agent Skills

WADE keeps the workflow fixed while letting you replace the methodology. Every interactive session gets an authoritative .wade/session/WORKFLOW.md; it still contains planning/implementation/review steps, documentation, synchronization, and done regardless of which skills are selected. Agent Skills control only how the WORK or REVIEW step reasons.

Default replaceable methods:

Operation WORK method REVIEW method
planning session builtin:planning builtin:plan-review
implementation session builtin:implementation builtin:code-review
PR-comment session builtin:review-comments builtin:feedback-fix-review
batch review builtin:batch-review —
dependency analysis builtin:dependency-analysis —

Custom skills stay generic: they do not need to mention WADE, worktrees, session commands, markers, review budgets, or done. WADE wraps their methodology in its fixed lifecycle or bounded operation contract.

Project skills are discovered from every skill root supported by the selected tool integration, including real or symlinked .claude/skills, .agents/skills, .cursor/skills, and .github/skills layouts. WADE merges the new worktree inventory with the main checkout so local-only/ignored skills are available too, while worktree content wins for matching tracked paths. Generated task and knowledge command-support projections are excluded from methodology discovery, so they cannot shadow a project skill with the same name. WADE copies the complete skill directory—SKILL.md, references, scripts, and assets—into the session snapshot; source directories are never overwritten or pruned.

Use explicit refs:

  • builtin:<name> for a bundled default;
  • project:<name> for a unique discovered project skill;
  • path:<repo-relative-directory> to select one exact source when names collide.

Bindings are ordered and frozen in .wade/session/manifest.json. Resuming uses the same physical copies even if config or the main checkout changes. To change an active session, use --refresh-skills with the session command or run wade session refresh-skills; an override without explicit refresh fails. In a worktree-less planning fallback, session diagnostics and refresh target the temporary bundle advertised to the agent while continuing to load config and project skills from the checkout that launched it.

Example configuration (all sections are optional; omitted values keep the defaults):

skills:
  project:
    discover: true
    include: ["*"]
    exclude: []

sessions:
  implementation:
    skills:
      work: [project:django-implementation]
      review: [project:security-review]
  plan:
    skills:
      work: [builtin:planning]
  review_pr_comments:
    skills:
      work: [builtin:review-comments]
      # Omit review to use builtin:feedback-fix-review.

delegations:
  code_review:
    skills:
      work: [project:security-review]
  plan_review:
    skills:
      work: [builtin:plan-review]
  batch_review:
    skills:
      work: [builtin:batch-review]
  dependency_analysis:
    skills:
      work: [builtin:dependency-analysis]

For a new session the order is CLI override, session binding, mapped delegation binding for REVIEW, then built-in default. A session REVIEW binding wins over a different delegations.code_review/plan_review value for that session. Standalone review, batch, and dependency operations use their delegation binding. wade skills resolve prints every candidate and the winner.

The shared delegations.code_review.skills.work setting is an explicit fallback for both implementation and PR-comment session REVIEW slots. It intentionally replaces the stage-specific built-in default—including builtin:feedback-fix-review for PR-comment sessions—unless that session sets its own skills.review; existing frozen sessions keep their recorded binding until explicitly refreshed.

Tool-native roots receive only fixed command-support skills. Session lifecycle comes from the rendered workflow, while default or custom methodology is frozen inside the session bundle. Deprecated phase skills are not installed. Resume revalidates workflow identity and the complete physical bundle against its manifest digest; completion does the same before trusting a review receipt. Stale metadata and edited, missing, extra, or unsafe snapshot content require an explicit --refresh-skills or wade session refresh-skills replacement.

This redesign is a clean cutover. It does not import pre-redesign phase-skill or review-marker state. Resuming an older in-flight worktree creates the current session bundle, and its current commit must complete the new review and documentation-decision gates before done can accept it.

Session communication

While a session works, it reports by exception: terse on success — just the actionable handles (task/PR numbers, URLs, the next command), no running recap. When something needs your attention or a decision only you can make, the agent reports it in 1–2 sentences with brief context, its complexity (easy/medium/complex/very_complex), and a recommendation. It then asks through the native question component, with the recommended option first and labelled "(recommended)".

Each session ends with a compact emoji step-status summary instead of a prose recap: one glyph per step (✅ done · ⚠️ needs your attention · ❌ failed/blocked · ⏭️ skipped/disabled) on a single line, the handles, an explicit attention line (either "Nothing needs your attention" or the items that do), and a bold Next: action. Every finite-choice decision — including whether to exit — is a native dialog with the recommended option first.

Extension Hooks

Configure automated setup when worktrees are created via wade implement or wade implement-batch. Add a hooks section to .wade.yml:

hooks:
  post_worktree_create: scripts/setup-worktree.sh
  copy_to_worktree:
    - .env
    - .env.example

post_worktree_create — A setup script to run after each worktree is created. Use it to install dependencies, run builds, or prepare the environment so worktrees are ready to use immediately.

copy_to_worktree — Files to copy from the project root into the worktree before running the hook. Useful for secrets and config files (e.g., .env) that are gitignored and wouldn't otherwise be present in a new worktree.

See templates/setup-worktree.sh.example for a starter script.

Repo-quality gates

Three opt-in, off-by-default quality gates enforce code hygiene at the commit boundary (and in-turn). Nothing is installed unless you configure it:

hooks:
  pre_commit:
    lint: ./scripts/check.sh --lint   # runs on `git commit`; non-zero blocks it
    test: ./scripts/test.sh           # runs on `git commit`; non-zero blocks it
  commit_msg:
    conventional: true                # rejects a non-Conventional-Commit subject
  post_tool_use:
    enabled: true                     # feed lint findings back to the agent in-turn
    lint_cmd: ruff check              # FILE-SCOPED linter (the edited path is appended)
    timeout: 10                       # seconds; the linter is skipped on overrun
  • pre_commit installs a per-worktree pre-commit git hook that runs the configured lint, then test, command(s). A non-zero exit blocks the commit and surfaces to the agent as a normal error. Set only the step(s) you want. Running the full test suite on every commit can be slow — prefer a fast subset there, or use lint alone.
  • commit_msg installs a per-worktree commit-msg git hook that validates the subject line against Conventional Commits. A non-conforming subject blocks the commit. A BREAKING CHANGE: footer only marks an already-typed commit as breaking (an alternative to the subject !); it does not exempt the subject from the type requirement.
  • post_tool_use feeds lint findings back to the agent in-turn — the cheapest moment to fix them, while the edit is still in working memory. It is file-scoped: lint_cmd runs on just the edited path (appended as a positional arg), on tools whose hooks can inject context back to the agent (Claude, Cursor, Codex, Copilot; Antigravity CLI is skipped). If lint_cmd is unset, wade falls back to pre_commit.lint run whole-repo on every edit — which is slower and may error on an unexpected positional arg, so prefer configuring a file-scoped lint_cmd. This layer never blocks.

Like the pre-push backstop, the git hooks are worktree-scoped (never touch your main checkout or sibling worktrees) and chain to any pre-existing hook of the same name. Honesty: git commit --no-verify bypasses the pre-commit and commit-msg hooks in one flag — these are quality gates that make messy or untested commits hard to land, not airtight enforcement boundaries.

Shell Integration

To make wade cd <N> actually change your directory (instead of just printing the path), add this to your shell profile:

eval "$(wade shell-init)"

Tab completion:

wade --install-completion bash   # or zsh / fish

Upgrading

wade update

Detects your install method (uv tool, pipx, Homebrew) and upgrades automatically, then refreshes all managed project files.

Contributing

See CONTRIBUTING.md.

License

MIT

Release files for wade-cli 1.2.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for wade-cli 1.2.8
File Size Uploaded
wade_cli-1.2.8.tar.gz 1.5 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for wade-cli 1.2.8
File Interpreter ABI Platform
wade_cli-1.2.8-py3-none-any.whl Python 3 none any Details

Total release size: 2.1 MB

Release files / wade_cli-1.2.8.tar.gz

Download URL wade_cli-1.2.8.tar.gz
Size 1.5 MB
Tags Source
SHA-256 checksum
How to use checksums
aefe5f3d874f74403ab07f1f36c701113f318fb3b8871237a5549277ac26f407
BLAKE2b-256 checksum
How to use checksums
c9541227d7edb22843036908973011e189c1428824580d2ad43cfd66b88982ab
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release files / wade_cli-1.2.8-py3-none-any.whl

Download URL wade_cli-1.2.8-py3-none-any.whl
Size 662.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b21f86729ca00a251a24504934c467bbe48d2f57689ca628837609d5bcd08d96
BLAKE2b-256 checksum
How to use checksums
cc40496e0948c43768377692e84ea7f4a7443f3eeff7f2972c582a9e293c0482
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release history Release notifications | RSS feed

1.2.10

2 release files

This release

1.2.8 This release

2 release files

1.2.7

2 release files

1.2.6

2 release files

1.2.5

2 release files

1.2.4

2 release files

1.2.3

2 release files

1.2.2

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.3

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.54.0

2 release files

0.53.1

2 release files

0.53.0

2 release files

0.52.0

2 release files

0.51.0

2 release files

0.50.7

2 release files

0.50.6

2 release files

0.50.5

2 release files

0.50.4

2 release files

0.50.3

2 release files

0.50.2

2 release files

0.48.1

2 release files

0.35.3

2 release files

0.35.1

2 release files

0.35.0

2 release files

0.33.0

2 release files

0.30.2

2 release files

0.30.1

2 release files

0.29.6

2 release files

0.29.5

2 release files

0.29.3

2 release files

0.29.2

2 release files

0.29.0

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page