CLAUDE.md@plugins/wise · git:20261010.292836f · 2026-10-10 · sha256 744ff77efefc9201
CLAUDE.md@plugins/wise git:20261010.292836fA
Immutable. This exact content never changes and is served at /api/v1/blob/744ff77efefc9201.
# CLAUDE.md — operational context for the `wise` plugin
Loaded automatically when a developer opens this plugin in Claude Code.
This file records **invariants** — things that must be true whenever the
plugin is at rest. Procedures (how to add an action, how to test) live
in the root [`CONTRIBUTING.md`](../../CONTRIBUTING.md); do not duplicate
them here.
**Before making any non-trivial change, read `CONTRIBUTING.md`.** It
documents the decisions that led to the current shape of the plugin —
most "obvious improvements" have already been considered and rejected
for reasons that are listed there.
---
## What this plugin is
This directory is the **`wise` plugin for Claude Code** — the
canonical, hand-edited source. Edit files here directly and validate
with `just check`.
`wise` is a standalone copilot plugin in the `wise-claude`
marketplace: a workflow engine, shared scripts, and a set of
tech-neutral action skills (`/wise-init`, `/wise-workflow-*`,
`/wise-skills-*`, `/wise-pr-*`, `/wise-commit-*`) plus the
`wise-estimation`, `wise-markitdown`, and `wise-code-comments`
reference skills, the
`wise-human-writing` and `wise-tickets` hybrid skills (auto-consulted
references + `/wise-human-writing` rewrite and `/wise-tickets`
restructure commands), and the
`/wise` natural-language helper.
Every user-facing skill is a **flat, autocomplete-visible slash
command**. No dispatcher-style routing: typing `/wise-` fans out in
Claude Code's slash menu to every action. The plugin also exposes the
`/wise` bare command as a **natural-language helper** — typing `/wise`
alone prints the catalog of every command, and typing `/wise <free-form
text>` (e.g. `/wise open a PR`) classifies the request via LLM
judgement, proposes the matching `/wise-*` command, and offers to run
it through `AskUserQuestion`.
Current actions (all standalone):
- `/wise-init` — first-time dep-install wizard; walks the user through
Python 3.11+, the selected provider CLI login, gh and markitdown, caches results
for the workflow skills' fast-path.
- `/wise-skills-create` — scaffold a new action skill via `skill-creator`.
- `/wise-skills-edit` — modify an existing action skill via `skill-creator`.
- `/wise-workflow-list` — list bundled + user workflow definitions.
- `/wise-workflow-create [--name <name>] <prompt>` - infer workflow steps,
select harness/model/effort per step through GUI/TUI, then validate and save.
- `/wise-workflow-run` - start a run on the wise engine: pre-flight
questions, run context, one line per event, gates (this conversation
is a thin conductor over the `wise_*` MCP tools).
- `/wise-workflow-resume` - resume a paused or failed engine run, or
answer a gated one, then follow it.
- `/wise-workflow-status` - list engine runs, or show one run and its
open gate.
- `/wise-workflow-remove` — delete a user workflow definition.
- `/wise-feedback` — file a feedback issue against the marketplace repo.
- `/wise-exec-on-harness` — run one free-form prompt as a headless child
on any supported harness (`claude|codex|cursor|gemini|grok`) at a chosen
model, effort and permission mode (`ask|auto|full`). First action is a
host inventory of installed and logged-in harnesses; `--on` is validated
against it, otherwise the ready ones are offered as a picker. Every other
omitted option is asked through a GUI/TUI picker; the prompt is the
trailing free text or `--p` / `--prompt`, asked last when missing.
Dispatches via `dispatch --relay`; gates relay back to the main harness.
- `/wise-profile` — set the session's token-budget profile
(`low|medium|max`, default `medium` = the standard behavior). Stored
per session; profile-sensitive skills read it via
`references/profile-read.md` and degrade silently to `medium` (no
bundled skill is profile-sensitive today: `wise-pr-watch-auto`
conducts a workflow). Workflows never read it: the engine's
pre-flight asks worktree, harness, per-provider permission floor, model and effort instead.
Budget only — model tiers, optional-step scope, panel size, retry
caps; NEVER correctness rules.
- `/wise-fork` — reorient a forked session. Inherited context becomes
read-only background; every in-flight task, plan, and promise from
before the fork is dropped (the original session owns them);
remembered file state is distrusted (the original session may touch
the same tree in parallel) and a fresh git baseline is snapshotted.
Optionally starts straight on a new goal passed as the argument.
- `/wise-report` — verified session status report. Recalls claims from
context/memory, verifies each against git, `gh` PR/CI state, workflow
runs, and files on disk, then emits a compact ref-coded report
(F/A/Q/R/L/P) where every line carries an evidence tag or is marked
`(unverified)`. `--full` expands detail; `--save` writes a handoff
file that survives compaction. Read-only apart from that file.
- `/wise-insights-mine` — the self-improvement loop (the "harvest"
pass). Mines the local insights ledger (fed by the SessionEnd hook)
for recurring task patterns, frequency-gates them, and drafts the
strongest ones into user-global `~/.claude/skills/` after
per-candidate approval.
- `/wise-insights-refine` — the "garden" pass. Enumerates the learned
skills, finds overlapping ones, and (with approval) merges them into
one aggregated skill and retires the originals — reversibly (backed
up first). Acts only on wise-managed skills (marker-tagged); never
deletes hand-written ones.
- `/wise-insights-reset` — reversible cleanup + rollback. Snapshots
then removes the auto-created skills and/or the insights index into
`snapshots/<ts>/`, and restores any snapshot. Only managed skills;
never hard-deletes (that's `insights.py purge`).
- `/wise-commit-message`, `/wise-commit`, `/wise-commit-push`,
`/wise-pr-create`, `/wise-pr-add-reviewers`, `/wise-pr-watch` —
standalone PR / git helpers. The three commit skills are a graded
trio: `/wise-commit-message` is read-only (drafts and hands back),
`/wise-commit` drafts + commits locally, `/wise-commit-push` drafts
+ commits + pushes.
- `/wise-pr-create-auto`,
`/wise-pr-watch-auto`, `/wise-implement-plan-auto`,
`/wise-simplify-auto` — the autonomous (`-auto`) building blocks:
autonomous variants of the PR / implement /
quality steps. The PR-create and simplify ones are
thin readers of a shared fragment or reference; `/wise-pr-watch-auto`
and `/wise-implement-plan-auto` are thin conductors over the bundled
`pr-watch` / `impl-plan` workflows (the engine's `pr` / `implement`
units pipelines), so harness, model and effort are asked per phase at
pre-flight on every harness. Wise never triggers a remote review
(no Copilot reviewer request, no `@coderabbitai review` comment):
the watch loop only observes a configured bot's state for the head
(`phases/verify.py`, following `references/pr/review-verification.md`,
as does `/wise-pr-watch`) and runs its own local review, the 3-lens
panel, once per new PR head; the merge needs CI green, that review
approved for the head and no open bot item.
`/wise-simplify-auto` (the lightweight per-commit tier — the
`code-simplifier` agent on Claude Code, else the same cleanup inline
per `references/simplify-instructions.md`) and the `code-review` workflow (the
heavyweight review, conducted by `/wise-code-review` over the branch,
uncommitted work or a PR — three reviewer children, a curator, an
optional verifier and a fixer, each with its own tuning group) are
the two quality passes; the `ticket-auto` workflow's engine-side
review phase follows the same discipline.
- `/wise-supervise` — attach a watchdog / supervisor loop to a running
team of background agents and keep them on task: probe each member,
nudge the idle-but-unfinished or off-goal ones, escalate the
persistently stuck (the automation of manually typing "ping all your
subagents, are you on track?"). Reads the shared
`references/supervise-loop.md`, as does the `-auto` implement phase
(`SUPERVISE=yes`). The v2 engine has its own stale policy
(`stale_after`: nudge, then kill) and does not read it.
- `/wise-revise` — the proactive planner: investigates a scope (folder /
component / whole project) against a free-form improvement intent,
read-only, via a panel of roster lenses; ranks findings by leverage and
writes self-contained `PLAN-*.md` plans + an index into `docs/plans/`
for the user to execute later. Writes only under `docs/plans/`; never
edits source and never runs a plan (execution is delegated). Reads its
own skill-local `references/audit-lenses.md` + `references/plan-format.md`.
- `/wise-grill` — the subject-understanding pass: classifies its input
(tracker ticket, doc link, free-form prompt, or question), then
deep-researches it across every reachable source (tracker comments +
screenshots, wiki, Slack, Drive, design, codebase + git history),
gap-checks the evidence, and forks by type — a ready
`docs/plans/PLAN-<ref>.md`; a `BLUEPRINT-<ref>.md` with targeted
questions (per-person for tickets / docs, asked inline when the user
is the one who can answer — prompts); or a researched
`ANSWER-<ref>.md` for a pure question (re-run with answers to
upgrade a blueprint). Facts get researched; only decisions get
asked. Writes only under `docs/plans/`; read-only against every
external system. Reads the shared `references/grill/*` routines —
the same ones the `ticket-plan` / `ticket-auto` workflows run in
their plan phases (ticket subjects only there).
- `/wise` — the natural-language helper (bare = catalog; with free-form
text = intent classifier).
Two model-invoked document-authoring skills round out the plugin —
they carry no `argument-hint`, so they auto-trigger on matching prose
rather than being typed as a flat command:
- `wise-prd-architect` — drives a structured multi-phase process for
writing Product Requirements Documents; auto-triggers on "PRD",
"product spec", "feature spec", and similar.
- `wise-trd-architect` — the engineering counterpart; auto-triggers on
"TRD", "technical design", "architecture document", "system design".
Each ships its own `agents/` and `references/` files *inside its
skill directory* (the skill spawns those agents via `Task` and reads
the reference templates). These skill-local agents are distinct from the
**plugin-level agent roster** under `agents/` (see below) — the
skill-local ones are private to one skill; the roster is shared across
every workflow.
The plugin also ships a **plugin-level `agents/` roster** — a set of
SDLC role subagents (`wise:ceo`, `wise:cto`, `wise:architect`,
`wise:software-engineer`, `wise:qa-engineer`, `wise:security-engineer`,
`wise:devops-engineer`, `wise:sre`, `wise:code-reviewer`, …), catalogued
in `AGENTS.md`. They are real Claude Code plugin subagents (invocable as
`subagent_type: wise:<name>`); a Claude child the workflow engine spawns
reaches them through its own `Task` / `Agent` tool when the step prompt
asks for a role.
---
## Layout
```
plugins/wise/
├── .claude-plugin/plugin.json # manifest (no `dependencies:` — see CONTRIBUTING §2.3)
├── .mcp.json # empty; wise-init manages host registration
├── engine/ # Python v2 workflow engine
│ ├── engine.sh # managed Python 3.11+ launcher
│ ├── pyproject.toml # Python metadata and pinned dependencies
│ ├── wise_engine/ # defs (YAML v2 schema), scheduler, executor, ledger, daemon, mcp,
│ │ │ # unit-mcp, channel, resolve, render, preflight, migrate, auth
│ │ ├── adapters/ # claude, codex, cursor-agent, gemini, grok + clean-env spawn
│ │ ├── steps/ # agent, bash, gate step runners
│ │ ├── phases/ # unit pipeline phases (claim, worktree, model phases, push, pr, ...)
│ │ └── prompts/units/ # the model-phase prompt templates + schemas
│ └── tests/ # pytest suite; just check includes Ruff and mypy
├── hooks/ # the ONE sanctioned hook (see CONTRIBUTING §2.4)
│ ├── hooks.json # auto-discovered; registers the SessionEnd hook
│ └── session-end-ingest.sh # SessionEnd → insights.py ingest (stdlib-only, exit 0, no LLM)
├── agents/ # plugin-level SDLC agent roster (auto-discovered; wise:<name>)
│ ├── ceo.md cto.md product-manager.md engineering-manager.md
│ ├── architect.md software-engineer.md qa-engineer.md
│ ├── security-engineer.md devops-engineer.md sre.md
│ └── ux-designer.md technical-writer.md code-reviewer.md
├── CLAUDE.md # this file (invariants)
├── AGENTS.md # catalog/index of the plugin-level agent roster
├── README.md # slim overview + links into /docs/wise/*
├── LICENSE
├── .gitignore # keeps .wise-init-registry.yaml out of source control
├── .wise-init-registry.yaml # RUNTIME ONLY — written by `/wise-init`, wiped on reinstall
├── scripts/
│ ├── engine.sh # thin bash bootstrap → execs engine.py (skill catalog only; not the workflow engine)
│ ├── engine.py # skill-catalog emitter (`list-skills` subcommand) — consumed by the /wise helper
│ ├── bootstrap-deps.sh # dependency probes; host setup details follow P6
│ ├── init.sh # bash-only per-dep probes used by `/wise-init` (works before Python is installed)
│ ├── init-registry.py # YAML I/O for .wise-init-registry.yaml + fast-path `check` for the workflow skills
│ ├── wise-helpers.py # stdlib session/profile/history/supervision entrypoint
│ └── insights.py # self-improvement engine: ingest/mine/gate sessions → skill candidates (STDLIB ONLY)
├── workflows/ # bundled workflow definitions (shipped defaults)
│ └── <name>/ # folder form: workflow.yaml + sibling artifacts
│ ├── workflow.yaml # the definition (YAML v2, validated by engine.sh compile-check)
│ ├── README.md # summary, flow, steps, inputs, outputs (kept in sync with the YAML)
│ ├── templates/ # optional — workflow-shipped templates; addressable as {{workflow.dir}}/templates/…
│ └── prompts/ # optional — e.g. watch-pipelines-auto.md; addressable as {{workflow.dir}}/prompts/…
├── references/ # cross-skill shared prose (addressed as ${CLAUDE_PLUGIN_ROOT}/references/<file>.md)
│ ├── subject-drafting.md # Conventional-Commits scope / type / subject rules
│ ├── branch-naming.md # the ticket = branch-name rule
│ ├── epic-expansion.md # epic -> child item specs (DAG edges, serialize keys, repo); read by the ticket-auto / ticket-plan expand-tickets steps
│ ├── init-check.md # shared init-registry fast-path protocol
│ ├── profile-read.md # session token-budget profile read (silent degrade to medium); read by profile-sensitive skills
│ ├── dispatch.md # the --on routine: run a skill's procedure as a headless child of any harness (engine.sh models + dispatch); read by the pr-create / simplify -auto skills and wise-exec-on-harness
│ ├── simplify-pass.md # canonical per-commit simplify pass (code-simplifier agent or inline)
│ ├── simplify-instructions.md # harness-neutral cleanup contract the pass applies
│ ├── code-review-pass.md # canonical high-depth branch review (reviewer-subagent panel)
│ ├── report-pass.md # canonical verified status report (recall → verify → emit; read by /wise-report + the ticket-auto / impl-plan-auto report steps)
│ ├── supervise-loop.md # the watchdog routine (idle/hung detection → nudge → escalate); read by the -auto implement phase + /wise-supervise
│ ├── insights-init-guard.md # /wise-init gate read by wise-insights-mine / -refine
│ ├── grill/ # the subject-understanding routines (context sweep + gap analysis + blueprint schema) — read by /wise-grill (any subject), ticket-plan, ticket-auto (tickets)
│ └── pr/ # shared PR/commit fragments (draft-body, ensure-pr, watch-pipelines, handle-*, commit-from-fix, paged-bulk-mode, comment-surfaces, sonar-fetch) + templates/pr-template.md — read by the wise-pr-* skills + ticket-auto
└── skills/
├── wise/SKILL.md # natural-language helper (bare catalog + intent classifier)
├── wise-init/SKILL.md # dep-install wizard
├── wise-skills-create/SKILL.md
├── wise-skills-edit/SKILL.md
├── wise-workflow-list/SKILL.md
├── wise-workflow-create/SKILL.md
├── wise-workflow-run/SKILL.md # the conductor
├── wise-workflow-resume/SKILL.md
├── wise-workflow-status/SKILL.md
├── wise-workflow-remove/SKILL.md
├── wise-prd-architect/ # model-invoked PRD authoring (SKILL.md + agents/ + references/)
├── wise-trd-architect/ # model-invoked TRD authoring (SKILL.md + agents/ + references/)
├── wise-feedback/SKILL.md # file a feedback issue
├── wise-exec-on-harness/SKILL.md # run one free-form prompt on any harness (pickers for --on/--model/--effort/--mode)
├── wise-profile/SKILL.md # session token-budget profile (low|medium|max; budget only, never correctness)
├── wise-fork/SKILL.md # reorient a forked session (context = background; pre-fork work dropped)
├── wise-report/SKILL.md # verified session status report (ref-coded, evidence-tagged; --full / --save)
├── wise-insights-mine/SKILL.md # self-improvement loop: mine sessions → draft skills
├── wise-insights-refine/SKILL.md # consolidate learned skills: merge overlaps → retire originals
├── wise-insights-reset/SKILL.md # reversible cleanup + rollback (snapshot → clear → restore)
├── wise-commit-message/SKILL.md # Conventional-Commits drafter (read-only)
├── wise-commit/ # draft + commit (no push)
│ ├── SKILL.md
│ └── commit-routine.md # shared draft + commit (+ optional push) procedure
├── wise-commit-push/SKILL.md # draft + commit + push; reads wise-commit/commit-routine.md
├── wise-estimation/SKILL.md # reference skill (Fibonacci SP scale)
├── wise-markitdown/SKILL.md # reference skill (file → markdown text extraction via markitdown)
├── wise-code-comments/SKILL.md # reference skill (code-comment rules: ELI5, concise, present-tense, no history)
├── wise-human-writing/SKILL.md # hybrid: human-first rules for all outbound tracker/PR/doc/chat writing + /wise-human-writing rewrite
├── wise-tickets/SKILL.md # hybrid: ticket structure/scoping/breakdown rules for any tracker + /wise-tickets restructure
├── wise-pr-create/SKILL.md # create or refresh a PR
├── wise-pr-add-reviewers/SKILL.md # request human reviewers (never a bot)
├── wise-pr-watch/SKILL.md # drive pipelines + comments to green
├── wise-code-review/SKILL.md # conductor of the code-review workflow (branch, working tree or PR; never requests a bot)
├── wise-pr-create-auto/SKILL.md # autonomous PR create (no prompts)
├── wise-pr-watch-auto/SKILL.md # conductor of the pr-watch workflow (local review per head, never triggers a bot)
├── wise-implement-plan-auto/ # conductor of the impl-plan workflow
│ ├── SKILL.md
│ └── agents/executor.md # per-task executor persona read by implement-plan.md (subagent or inline)
├── wise-simplify-auto/SKILL.md # autonomous simplify + commit (no prompts)
├── wise-supervise/SKILL.md # attach the watchdog loop to a running team of background agents
├── wise-revise/ # proactive planner: audit a scope → executable PLAN-*.md backlog
│ ├── SKILL.md
│ └── references/ # audit-lenses.md (the panel) + plan-format.md (the plan + index schema)
└── wise-grill/SKILL.md # subject-understanding pass (ticket / doc / prompt / question): multi-source research → PLAN, BLUEPRINT-with-questions, or ANSWER
```
No `commands/` directory is present, and one must not be added without
the discussion called for in `CONTRIBUTING.md`
[§2](../../CONTRIBUTING.md#2-conventions-that-apply-to-every-plugin). An
`agents/` directory **IS** present — the plugin-level SDLC role roster
(`AGENTS.md` + `agents/*.md`), auto-discovered by Claude Code and
addressable as `subagent_type: wise:<name>`. It is a deliberate part of
the plugin's design (Claude children spawned by the workflow engine
delegate to it); adding or editing a role follows the procedure in
`AGENTS.md`. A
`hooks/` directory IS present, holding **exactly one** sanctioned hook —
the SessionEnd insights-ingest hook (`hooks/session-end-ingest.sh` +
`hooks/hooks.json`). It is the single documented exception to the
no-hooks default; its rationale and hard constraints live in
`CONTRIBUTING.md` [§2.4](../../CONTRIBUTING.md#24-hooks). No other hook
(and no `SessionStart` hook) may be added without that same discussion.
`.mcp.json` is empty. `/wise-init` registers the single `wise-engine`
transport through the stable managed launcher for Claude Code, Codex, Cursor or
Grok. See [host control](references/workflow-host-control.md) for resolution,
upgrade refresh and diagnostics. The server starts `wise-engined` on demand. An
`engine/` directory IS present: the Python workflow engine, run from source
(no build step; `just check` runs validation, typecheck, lint,
format and tests).
---
## Invariants
Keep these true. Each one has a rationale in `CONTRIBUTING.md`; the
one-liners below are the rule, not the argument for it.
- **Two skill shapes — standalone and reference.** Every skill's
frontmatter lands in one of two buckets. Pick the right one when you
author; mixing fields breaks discovery.
- **Standalone slash-command skills** (the default shape for every
action, e.g. `wise-workflow-run`, `wise-commit-message`) —
user-invocable, shown in the slash menu as `/wise:<skill-name>`
with a bare `/<skill-name>` alias when unambiguous. Frontmatter
sets `argument-hint:` (may be an empty string). No `command:` /
`subcommand:` / `user-invocable: false` / `arguments:` fields —
those were v1 dispatcher-routing fields with no meaning in v2.
The skill body reads `$ARGUMENTS` as a raw string and parses its
own positionals.
- **Reference / guidance skills** (e.g. `wise-estimation`) —
description-triggered docs. Frontmatter has NO `argument-hint:`
and no action-oriented fields. Claude auto-consults them when the
user's prose matches the `description:`. Body is reference
content, not action logic.
- **Exactly one `disable-model-invocation: true` skill — `wise`.** It's
the natural-language helper. Users invoke it explicitly; Claude
never auto-runs it.
- **The `/wise` helper classifies intent; it does not act directly.**
Action logic lives in the action skills. The helper's job is to
(a) print the catalog when called bare, or (b) pick the best
matching `/wise-*` command and offer to invoke it via the `Skill`
tool after `AskUserQuestion` confirmation.
- **`scripts/engine.py` is a catalog emitter, nothing more.** Its
only supported subcommand is `list-skills`, which walks `skills/`
and emits a JSON document the `/wise` helper consumes. No routing,
no fuzzy matching, no argument parsing. `engine.sh` stays as the
bash bootstrap; every skill that calls `engine.sh` grants the bash
path in its `allowed-tools`.
- **Action skills never invoke other action skills.** The `/wise`
helper is the only place that calls the `Skill` tool on a
wise-namespaced action skill (and only after user confirmation).
Action-to-action work-sharing happens through `scripts/` helpers.
The exception for `wise-workflow-run` and `wise-workflow-resume`
(which compose other skills as workflow steps) is below.
- **All persistent state lives in `${CLAUDE_PLUGIN_DATA}`.** Never
write elsewhere — with these narrow exceptions:
(a) the init registry, see below;
(b) workflow run state, which is per-workspace by design and lives
under `~/.local/share/wise/runs/<cwd-slug>/` (off-tree, off
`.claude/**`, never auto-cleaned); and
(c) the **insights store** under `~/.local/share/wise/insights/`
(`ledger.jsonl` + `candidates.json` + `decisions.json` +
`skill-backups/<ts>/<name>/` + `snapshots/<ts>/{index,skills}/`), the
self-improvement loop's per-user state. `decisions.json` records
`promoted` / `dismissed` / `retired` (the last set by
`/wise-insights-refine` when it merges a skill away; `mine` resurrects
it if the merged skill is later deleted). `snapshots/` holds
`/wise-insights-reset` restore points (reversible cleanup); `purge
--yes` is the only irreversible wipe; and
(d) the **report handoff store** under
`~/.local/share/wise/reports/<cwd-slug>/` — output of the report
pass (`/wise-report --save` today; any `SAVE=yes` caller of
`references/report-pass.md`), a per-workspace sibling of the runs
tree (same slug, same XDG rules), kept off-tree for the same
reasons as run state; and
(e) the **session profile store** under
`~/.local/share/wise/profile/<session-id>` — one word
(`low|medium|max`) written atomically by `/wise-profile`
(`wise-helpers.py profile-set`), read via
`references/profile-read.md` / `profile-get` with silent degradation
to `medium`, and
GC'd opportunistically (files from sessions older than 30 days) on
each write. Routed through `wise_data_root()` (engine: `paths.py`).
New per-user persistent state
that doesn't fit `${CLAUDE_PLUGIN_DATA}` MUST route through the
`wise_data_root()` helper in `engine/wise_engine/paths.py` — never
hard-code paths so future relocations are one-function changes.
`insights.py` imports the stdlib-only canonical path helper directly. When
`${CLAUDE_PLUGIN_DATA}` is unset (e.g. the scripts are run directly,
outside Claude Code), `plugin_data_root()` falls back to
`$WISE_DATA_DIR` then `wise_data_root()`; under Claude Code the
Claude vars win, unchanged.
- **Init registry — the one file we write inside `${CLAUDE_PLUGIN_ROOT}`.**
`/wise-init` caches probe results at
`${CLAUDE_PLUGIN_ROOT}/.wise-init-registry.yaml`. It lives in the
install dir on purpose: every `/plugin install wise@…` wipes it,
giving natural invalidation. Workflow engine skills read this as a
fast-path via `scripts/init-registry.py check` before falling back
to the full `bootstrap-deps.sh` probe. Two writers: `/wise-init`
(full payload, interactive) and `bootstrap-deps.sh` itself, which
auto-populates a successful-probe subset on its way out. `.gitignore`
keeps the registry out of source control.
- **No persisted project registry.** The `{{project.*}}` template
variables a workflow run operates on are derived from the current
context - the engine's `detectProject` derives them from the run
`cwd` (`project-selection: current`). There is no `projects.yaml`
and no skill that writes one.
- **`allowed-tools` in each skill is narrowly scoped.** Expanding it
should be a deliberate decision, not an incidental fix-up.
- **Portable skills load before selecting a model.** Keep preferred model
and effort in the body, not provider-specific frontmatter pins. Every skill
reads the shared model-fallback contract before work. Unavailable models or
delegation routes require an explicit main-harness GUI/TUI choice from live
executable options, including the current model when supported. No silent
substitution or text fallback for this gate. Preserve other task permissions.
- **The agent roster is plugin-level; the engine has no roster field.**
The `agents/*.md` roster files are real Claude Code plugin subagents -
frontmatter is limited to `name` / `description` / `tools` / `model` /
`effort` / `color`; plugin subagents **ignore** `hooks` / `mcpServers` /
`permissionMode`, so never add those. Roster `model:` is `inherit`;
`effort:` is the role's default reasoning level. In YAML v2 an `agent`
step is one headless harness child (`claude -p`, `codex exec`,
`cursor-agent --print`, `gemini -p`, `grok -p`) spawned by the engine under the user's own
login, with the step's `harness` / `model` / `effort` (or its tuning
group) passed as real CLI flags; a Claude child delegates to a roster
role through its own `Task` / `Agent` tool when the prompt says so.
There is no `agent:` / `agents:` field, no teams, no conductor-side
synthesis. Model resolution (retired-id swap, capability clamp,
policy ceiling; the low-profile Opus rule stays dormant because
workflows run at `medium`) is `engine/wise_engine/resolve.py`; the model
catalog pre-flight offers is `engine/wise_engine/models.py` (the predefined
rows always come first; models an installed harness reports through its
listing command are appended in the order the harness listed them, never
substituted). Keep
`AGENTS.md`'s catalog table in sync with `agents/*.md`, the same way
workflow READMEs stay in sync with YAML.
- **Provider permissions are floors, not overrides.** Pre-flight asks
`permissions.<harness>` once for every selected or fallback provider;
`auto` is recommended and `full-access` is labelled "Bypass permissions".
The effective child mode is the stronger of that answer and the step or
unit phase's declared mode. Persist floors in `state.provider_permissions`;
keep legacy global `permissions: allowlist | full` resumable.
- **The roster is canonical; never hand-maintain a divergent copy.**
`agents/*.md` is the single source. The repo-root `AGENTS.md` and
`plugins/wise/AGENTS.md` document it as project-*instructions* (not
loadable registries); their roster tables mirror `agents/*.md` and are
kept in sync the same way workflow READMEs track their YAML.
- **Cross-skill shared prose lives in `plugins/wise/references/`.** A
rule or routine read by more than one skill — the Conventional-Commits
`subject-drafting.md` (read by the commit routine, `wise-commit-message`,
and `draft-body.md`), the workflow `init-check.md` (read by
`wise-workflow-run` / `-resume` / `-list` / `-status`), and the two
quality passes `simplify-pass.md` (read by the commit routine, the
implement phase, and `wise-simplify-auto`) and `code-review-pass.md`
(the discipline the `code-review` workflow's prompts, the engine's
review phase and `/wise-pr-watch`'s per-head local review follow), the
verified status report `report-pass.md` (read by `/wise-report`;
parameterized by `SCOPE` / `MODE` / `SAVE` so every caller runs the
identical routine), the watchdog routine `supervise-loop.md` (read
by the `-auto` implement phase and `wise-supervise`), the
`references/grill/` subject-understanding routines
(`research-sources.md` + `gap-analysis.md` + `blueprint-format.md`,
read by `/wise-grill` and the `ticket-plan` / `ticket-auto` plan
phases), and the
`references/pr/` PR/commit fragments (`draft-body.md`, `ensure-pr.md`,
`ensure-reviewers.md`, `propose-reviewers.md`, `watch-pipelines.md`,
the `handle-*.md` queue handlers, `paged-bulk-mode.md`,
the shared `comment-surfaces.md` / `sonar-fetch.md` fetch spines,
`review-verification.md` (the observe-only review-bot state rule
the engine's watch loop and `/wise-pr-watch` share),
`commit-from-fix.md`, read by the `wise-pr-*` skills and the
`ticket-auto` workflow's `prompts/`) - has a single home there, addressed as
`${CLAUDE_PLUGIN_ROOT}/references/<file>.md` and read at run time.
Skill-*local* `references/` (the architects' own templates) stay
inside the skill dir. Change a shared rule in the reference, never in
a copy.
- **Action skill directory name IS the slash command.** A skill at
`skills/wise-workflow-run/SKILL.md` with frontmatter `name:
wise-workflow-run` is invocable as `/wise-workflow-run` (bare
alias) or `/wise:wise-workflow-run` (canonical namespaced). There
is no translation layer. Rename the dir → rename the command; do
both in the same commit, and flag the change as breaking.
- **Workflow run state lives under `~/.local/share/wise/runs/<cwd-slug>/<run-ulid>/`**
(honours `XDG_DATA_HOME`). Per-workspace scoping is preserved via
the `<cwd-slug>` segment. Why off the project tree: Claude Code's
sensitive-path heuristic flags `.claude/**` paths; putting state in
the project tree also adds gitignore management and IDE noise. Why
user-scoped rather than `/tmp`: `/tmp` auto-cleans and breaks the
resume contract. Never under `${CLAUDE_PLUGIN_DATA}`. Workflow
*definitions* are the opposite — they live under a `workflows/` root
(user-authored at `${CLAUDE_PLUGIN_DATA}/workflows/definitions/`,
shipped at `${CLAUDE_PLUGIN_ROOT}/workflows/`) in one of two layouts:
- `<root>/<name>/workflow.yaml` — **folder form, preferred**. The
workflow can ship its own artifacts as siblings (`templates/`,
`prompts/`) and address them from steps via `{{workflow.dir}}`.
- `<root>/<name>.yaml` — **legacy flat form**. Still accepted; no
artifacts dir.
Folder form wins on same-root collision. User root still wins over
bundled root on cross-root collision. See
[`docs/wise/workflows.md`](../../docs/wise/workflows.md) for
the full reference.
- **The conductor never executes workflow steps itself.** It calls the
`wise_*` MCP tools or the engine CLI. Agent steps run in provider children;
`skill:` expands to a prompt on the Claude harness. V1 execution and its
prose conductor are retired; historical runs stay unchanged.
- **Workflow README.md stays in sync with `workflow.yaml` +
`prompts/`.** When you touch a bundled workflow's YAML or any of
its `prompts/*.md` fragments, update the workflow's `README.md` in
the SAME commit — Flow mermaid, Steps table, Inputs/Outputs tables,
and Related-links section must reflect the new shape.
- **The unit pipelines are idempotent on resume.** `ticket-auto`,
`impl-plan-auto`, `pr-watch` and `impl-plan` are one `units` step
each; the loop is engine code
(`engine/wise_engine/units.py`, `engine/wise_engine/phases/`), not prose. Its `claim`
phase must *ensure* (create, re-attach, or adopt) each unit's worktree
from the per-unit ledger under `<run dir>/units/` plus live `git` /
`gh` probes - never reintroduce a collide-and-fail `git worktree add
-b`. Live state is the source of truth; the ledger is a hint; a
worktree or branch the run did not claim is skipped, never adopted,
with one exception: an open same-repo PR on the unit's branch (or a
`<branch>-N`) authored by the `gh` user is adopted and resumed at the
watch loop, so a re-run never opens a duplicate PR.
`.worktreeinclude` files are carried over once per worktree
(`includes-done` ledger key). Phase prompts live under
`engine/wise_engine/prompts/units/`; change a rule there, never in a workflow.
- **Canonical Python owns workflow YAML, scheduling and state.**
`engine/wise_engine/defs.py` owns the v2 schema, `scheduler.py` the DAG,
`executor.py` the run loop and `ledger.py` persisted JSON. Skills call MCP
or `engine/engine.sh`. `scripts/wise-helpers.py` exposes standalone
profile/session/history/supervision commands; insights imports stdlib paths.
Validate with `engine.sh compile-check` and `just check`. V1 definitions
require explicit migration, and `state.yaml` runs cannot resume.
- **External-tool dependencies — bundle the static ones, probe the
open-ended ones.** When a skill needs a third-party tool, prefer
declaring it so the install is one step; but when the *set* of
possible tools is open-ended, probe and propose at run time instead.
Concretely:
- Plugin-to-plugin deps are currently NOT declared in
`.claude-plugin/plugin.json`'s `dependencies: [...]` array — a
marketplace-qualified entry silently breaks plugin loading in the
Claude desktop app (CONTRIBUTING §2.3). Optional plugins (the
`code-simplifier` agent the per-commit simplify pass dispatches)
are documented in the README's Bundled-tooling table instead, and
the consuming skill runs the same work inline when they are absent.
- Additional MCP server deps go in `.mcp.json`; `wise-engine` uses managed host registration. MCP tool
ids are derived from the plugin name, so moving an MCP between
plugins is a breaking rename.
- CLI / environment deps that neither mechanism can install (Python,
brew packages) are probed at run time by
`scripts/bootstrap-deps.sh` and surface a one-shot install prompt.
- Open-ended deps — where the workflow or skill cannot know up
front *which* tool the user needs — are probed and proposed
dynamically. The `ticket-plan` / `ticket-auto` workflows are
the reference case: they work with any task tracker, so the
conductor fetches every ticket through the session's channels
before the first pre-flight question, and the run's
`ensure-access` step re-checks first thing and fails closed with
the fix (no mid-run install proposals or questions), rather than
pre-declaring a specific tracker plugin.
See CONTRIBUTING.md [§2.2](../../CONTRIBUTING.md#22-bundled-tooling-convention) for the full convention.
---
## User-question lifecycle
Every skill links to the question lifecycle in
[`references/workflow-host-control.md`](references/workflow-host-control.md#keep-asynchronous-questions-open)
before collecting input. Shared interactive routines and delegated wizards follow
it too. An asynchronous display acknowledgement never authorizes an action, and
the asking agent keeps its turn active until an answer arrives. If no permitted
native control or rendered form is usable, the main harness uses the shared
text fallback, ending its turn for the explicit reply. Children relay questions
to the main harness in both cases. Existing
autonomous no-prompt rules still apply. Repository validation checks that every
skill retains the shared reference, including newly added skills.
## Pointers for common tasks
For the full procedure on each of these, read the linked section of
`CONTRIBUTING.md`:
| Task | See |
|---|---|
| Add a new `/wise-<action>` command | `CONTRIBUTING.md` [§4](../../CONTRIBUTING.md#4-adding-an-action-to-a-plugin) |
| Install the plugin from this clone | `CONTRIBUTING.md` [§6.1](../../CONTRIBUTING.md#61-install-the-plugin-from-a-clone) |
| Validate JSON / bash / naming before commit | `CONTRIBUTING.md` [§6.2](../../CONTRIBUTING.md#62-syntax-and-structural-checks) |
| Commit and PR style | `CONTRIBUTING.md` [§7](../../CONTRIBUTING.md#7-commit-and-pr-conventions) |
| Versioning rules for this plugin | `CONTRIBUTING.md` [§8](../../CONTRIBUTING.md#8-versioning) |
| Add or modify workflow-subsystem behaviour | `CONTRIBUTING.md` [§9](../../CONTRIBUTING.md#9-workflow-subsystem) |
---
## Why `CLAUDE.md`, `README.md`, and `CONTRIBUTING.md` all exist
Three audiences, three stability contracts:
- `README.md` — users landing on GitHub or running `/plugin info`.
Describes what the plugin does and how to use it.
- `CLAUDE.md` (this file) — an agent working inside the plugin tree.
Short list of invariants and a pointer to the full procedures.
- `CONTRIBUTING.md` — the full procedural manual. Single source of
truth for *how* to change things.
Overlap between the three is limited on purpose. If you find the same
rule documented in two of them and they disagree, the code is the truth
and both files are stale — fix both.