From cdd2eba5640f1729fa4bfd080e19c42a98d99341 Mon Sep 17 00:00:00 2001 From: Manas Srivastava Date: Mon, 11 May 2026 09:58:49 +0530 Subject: [PATCH 01/12] docs(plan-rollout): SYSTEM.md schema spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The semantic-contract-graph schema. Optional input to /plan-rollout — declares role-level contracts (auth mints session tokens middleware enforces; breaks-if format change without coordinated deploy). Distinct from the import graph (discovered at runtime). Repo-wide, long-lived, hand-authored. This commit lands the spec only. The consuming skill ships in the next commit. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/SYSTEM-MD.md | 217 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 docs/SYSTEM-MD.md diff --git a/docs/SYSTEM-MD.md b/docs/SYSTEM-MD.md new file mode 100644 index 000000000..3fe475bae --- /dev/null +++ b/docs/SYSTEM-MD.md @@ -0,0 +1,217 @@ +# SYSTEM.md — the semantic contract graph + +`SYSTEM.md` is a declarative file at the repo root describing what each +component *is*, what it *owns*, and the role-level contracts it has with +other components. Its consumer is `/plan-rollout`, which uses it to slice +a single large change into an ordered PR stack with reader guides and +deploy-edge awareness. + +`SYSTEM.md` is optional. `/plan-rollout` works without it — falling back +to path heuristics + import-graph discovery — and improves materially +when present. + +## What SYSTEM.md is NOT + +It is not a package manifest. It does not list: + +- Import graphs or symbol-level callers +- npm / Cargo / Gem / Go module versions +- Build dependencies or linker flags +- Test framework wiring + +Everything mechanical is discovered at runtime (AST, grep, package manifests). +Declaring it here would go stale within a week. + +## What SYSTEM.md IS + +The **semantic contract graph**: the relationships between components that +only a human knows. + +| Kind | Example | Lives where | +|------|---------|-------------| +| Role/contract dep | "auth mints session tokens middleware enforces; format change without middleware redeploy breaks sessions" | SYSTEM.md | +| Package/import dep | "`auth.ts` imports `crypto-utils`; `middleware.ts` calls `auth.verify()`" | Discovered (NOT here) | + +`/plan-rollout` reads both. Declared contracts give the *why* (what breaks +under coordinated deploy). Discovered imports give the *what* (which files +move together). Disagreements surface in the decomposition output for human +resolution rather than being silently resolved either way. + +## Schema (v1 — intra-repo) + +```yaml +--- +version: 1 +components: + - name: + path: + kind: component # or: leaf-util | types-only (optional; defaults to 'component') + role: + owns: + - + contracts: + - with: + nature: + breaks-if: + rollout-edge: + note: + rollout-order: +--- + +# System Map + + +``` + +### Field reference + +**`name`** — unique identifier used by other artifacts to reference this +component. Keep it short and stable. Renames cascade to every contract +reference. + +**`path`** — where the component lives in the repo. Can be a file or +directory. Used for component-membership lookups (is `src/auth/session.ts` +in the `auth` component? yes). + +**`kind`** — defaults to `component`. Use: +- `leaf-util` for shared utility dirs (`src/utils/`, `src/helpers/`) that + components import freely without declaring contracts. The skill skips + these when reconciling. +- `types-only` for pure type/interface modules. Skipped likewise. + +**`role`** — one sentence describing what this component is FOR. Not what +it contains, not how it's built. What it does in the system. + +**`owns`** — data surfaces, tables, APIs, or features this component is +the single source of truth for. Two components claiming ownership of the +same surface is a design smell. + +**`contracts`** — the heart of SYSTEM.md. Each contract declares a +role-level relationship with another component. + +- **`with`** — the other component's name. Must match a declared component. +- **`nature`** — plain-English description of the relationship. +- **`breaks-if`** — the specific human action that violates the contract. + This is what `/plan-rollout` reads. "Session payload schema changes + without middleware redeploy" tells the skill these two PRs must ship + as a coordinated stage. +- **`rollout-edge`**: + - `hard` = must deploy together (e.g., a session format change). The + skill places both sides of a hard edge in the same slice or marks + the slice "coordinated deploy required." + - `soft` = can lag (e.g., a logging metric addition). Noted but not + enforced. +- **`note`** (optional): + - `runtime-only` — coupling via DB, message bus, HTTP, or filesystem; + no code-level import edge exists. Suppresses the "contract without + imports" reconcile flag. + - `types-only` — TypeScript types only, not runtime values. + - `legacy` — contract exists but is being phased out. + +**`rollout-order`** — integer. Components with lower numbers ship first. +Equal numbers can ship in parallel. Used as the default ordering for +PR-stack decomposition; users can override per-call. + +## Example + +```yaml +--- +version: 1 +components: + - name: auth + path: src/auth + role: authentication + session lifecycle + owns: + - user table + - session table + - JWT minting + contracts: + - with: middleware + nature: middleware enforces session tokens auth mints + breaks-if: session payload schema changes without middleware redeploy + rollout-edge: hard + rollout-order: 1 + + - name: middleware + path: src/middleware + role: request routing + auth enforcement + owns: + - request context shape + contracts: + - with: gateway + nature: gateway consumes req.user set by middleware + breaks-if: req.user shape changes without gateway redeploy + rollout-edge: hard + rollout-order: 2 + + - name: gateway + path: src/gateway + role: external HTTP surface + owns: + - public API schema + contracts: [] + rollout-order: 3 + + - name: utils + path: src/utils + kind: leaf-util + role: shared helpers — imported freely without contracts + owns: [] + contracts: [] + rollout-order: 0 +--- + +# System Map + +auth and middleware are the security boundary. Any change to session format +or the user-context shape is a coordinated deploy (rollout-edge: hard). We +learned this after the Feb 2025 incident where a session serializer change +shipped 40 minutes ahead of middleware and logged everyone out. + +utils is declared `leaf-util` so the skill doesn't flag the many imports +into it from other components as missing contracts. +``` + +## How /plan-rollout uses it + +`/plan-rollout` reads `SYSTEM.md` (if present) at the start of every run +and applies it three ways: + +1. **File-to-component mapping** — when bucketing changed files into PR + slices, files matching a component's `path` join that component's + slice. No SYSTEM.md ⇒ slices fall back to top-level path heuristics + (one slice per top-level dir of changes). +2. **Slice ordering** — slices are ordered by their components' + `rollout-order`, lowest first. Files in `leaf-util` or `types-only` + components float to slice 0 (foundational; no contracts to honor). +3. **Hard-edge enforcement** — if changed files span both sides of a + `rollout-edge: hard` contract, the skill either merges those slices + into a single coordinated stage or annotates the decomposition with + a deploy-coordination warning. + +Reconciliation is informational in v1. The skill prints flagged +mismatches between declared contracts and discovered imports +(`import-without-contract`, `contract-without-imports`, +`rollout-order-inversion`) so the human can resolve them, but does not +gate output on them. + +## Scaffolding + +`/plan-rollout` does NOT scaffold `SYSTEM.md` for you in v1. Scaffolding +(walking top-level dirs, classifying each, inferring `role` from +README/package.json) is a v2 follow-up. For v1, write the file by hand +or copy the example above and edit it. + +## Relationship to other declarative files + +| File | Purpose | Who writes it | +|------|---------|---------------| +| `CLAUDE.md` | Project-specific instructions for Claude (routing rules, test commands) | Human | +| `CODEOWNERS` | Who reviews changes to which paths | Human | +| `SYSTEM.md` | Semantic contract graph (this file's schema) | Human | +| `decomposition.md` | Per-change PR stack | `/plan-rollout` | + +SYSTEM.md is the long-lived, repo-wide truth. `decomposition.md` is a +per-change artifact that references it. From 31c42a5456500d3fc568f1cb0314078addca8404 Mon Sep 17 00:00:00 2001 From: Manas Srivastava Date: Mon, 11 May 2026 09:58:57 +0530 Subject: [PATCH 02/12] feat(plan-rollout): /plan-rollout MVP skill MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Decomposition-as-artifact. Reads the working diff (committed + staged + unstaged + untracked) plus SYSTEM.md if present, writes decomposition.md with per-slice file lists, reader-time estimates, dependency edges, and contract-graph reconciliation flags. Positioned as the post-decision consumer to /plan-pull-request: - /plan-pull-request decides shape in conversation (pre-code). - /plan-rollout analyzes a real diff and writes the artifact (post-code). Triggers narrowed to "decompose the diff" / "write a decomposition" / "plan-rollout" to avoid collision with /plan-pull-request's pre-decision triggers. MVP boundaries (explicit): - No rollout.md, no /spill-check, no /ship-/review integrations. - No SYSTEM.md scaffolder — humans write the schema by hand or copy the example. - Reconciliation is informational, never blocking. - Step 2 explicitly handles uncommitted working-tree state via `git diff ` (not `...HEAD`) plus `git ls-files --others --exclude-standard` for untracked. Co-Authored-By: Claude Opus 4.7 (1M context) --- plan-rollout/SKILL.md | 1027 ++++++++++++++++++++++++++++++++++++ plan-rollout/SKILL.md.tmpl | 310 +++++++++++ 2 files changed, 1337 insertions(+) create mode 100644 plan-rollout/SKILL.md create mode 100644 plan-rollout/SKILL.md.tmpl diff --git a/plan-rollout/SKILL.md b/plan-rollout/SKILL.md new file mode 100644 index 000000000..d0f06dadf --- /dev/null +++ b/plan-rollout/SKILL.md @@ -0,0 +1,1027 @@ +--- +name: plan-rollout +preamble-tier: 3 +interactive: true +version: 0.1.0 +description: | + Decomposition-as-artifact. Given a real working diff (and `SYSTEM.md` if + present), produces a written `decomposition.md` with per-slice file lists, + reader-time estimates, dependency edges, and contract-graph reconciliation + flags. This is the post-decision consumer: it analyzes a diff that already + exists. For the pre-decision conversation ("should this be one PR or + many?"), use `/plan-pull-request` first. Use when asked to "decompose + the diff", "write a decomposition.md", "plan-rollout", or after + `/plan-pull-request` has already concluded the work should slice. (gstack) + Voice triggers (speech-to-text aliases): "decompose the diff", "write a decomposition", "plan-rollout". +allowed-tools: + - Read + - Write + - Grep + - Glob + - AskUserQuestion + - Bash +triggers: + - decompose the diff + - write decomposition.md + - plan rollout +--- + + + +## Preamble (run first) + +```bash +_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true) +[ -n "$_UPD" ] && echo "$_UPD" || true +mkdir -p ~/.gstack/sessions +touch ~/.gstack/sessions/"$PPID" +_SESSIONS=$(find ~/.gstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ') +find ~/.gstack/sessions -mmin +120 -type f -exec rm {} + 2>/dev/null || true +_PROACTIVE=$(~/.claude/skills/gstack/bin/gstack-config get proactive 2>/dev/null || echo "true") +_PROACTIVE_PROMPTED=$([ -f ~/.gstack/.proactive-prompted ] && echo "yes" || echo "no") +_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") +echo "BRANCH: $_BRANCH" +_SKILL_PREFIX=$(~/.claude/skills/gstack/bin/gstack-config get skill_prefix 2>/dev/null || echo "false") +echo "PROACTIVE: $_PROACTIVE" +echo "PROACTIVE_PROMPTED: $_PROACTIVE_PROMPTED" +echo "SKILL_PREFIX: $_SKILL_PREFIX" +source <(~/.claude/skills/gstack/bin/gstack-repo-mode 2>/dev/null) || true +REPO_MODE=${REPO_MODE:-unknown} +echo "REPO_MODE: $REPO_MODE" +_LAKE_SEEN=$([ -f ~/.gstack/.completeness-intro-seen ] && echo "yes" || echo "no") +echo "LAKE_INTRO: $_LAKE_SEEN" +_TEL=$(~/.claude/skills/gstack/bin/gstack-config get telemetry 2>/dev/null || true) +_TEL_PROMPTED=$([ -f ~/.gstack/.telemetry-prompted ] && echo "yes" || echo "no") +_TEL_START=$(date +%s) +_SESSION_ID="$$-$(date +%s)" +echo "TELEMETRY: ${_TEL:-off}" +echo "TEL_PROMPTED: $_TEL_PROMPTED" +_EXPLAIN_LEVEL=$(~/.claude/skills/gstack/bin/gstack-config get explain_level 2>/dev/null || echo "default") +if [ "$_EXPLAIN_LEVEL" != "default" ] && [ "$_EXPLAIN_LEVEL" != "terse" ]; then _EXPLAIN_LEVEL="default"; fi +echo "EXPLAIN_LEVEL: $_EXPLAIN_LEVEL" +_QUESTION_TUNING=$(~/.claude/skills/gstack/bin/gstack-config get question_tuning 2>/dev/null || echo "false") +echo "QUESTION_TUNING: $_QUESTION_TUNING" +mkdir -p ~/.gstack/analytics +if [ "$_TEL" != "off" ]; then +echo '{"skill":"plan-rollout","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true +fi +for _PF in $(find ~/.gstack/analytics -maxdepth 1 -name '.pending-*' 2>/dev/null); do + if [ -f "$_PF" ]; then + if [ "$_TEL" != "off" ] && [ -x "~/.claude/skills/gstack/bin/gstack-telemetry-log" ]; then + ~/.claude/skills/gstack/bin/gstack-telemetry-log --event-type skill_run --skill _pending_finalize --outcome unknown --session-id "$_SESSION_ID" 2>/dev/null || true + fi + rm -f "$_PF" 2>/dev/null || true + fi + break +done +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +_LEARN_FILE="${GSTACK_HOME:-$HOME/.gstack}/projects/${SLUG:-unknown}/learnings.jsonl" +if [ -f "$_LEARN_FILE" ]; then + _LEARN_COUNT=$(wc -l < "$_LEARN_FILE" 2>/dev/null | tr -d ' ') + echo "LEARNINGS: $_LEARN_COUNT entries loaded" + if [ "$_LEARN_COUNT" -gt 5 ] 2>/dev/null; then + ~/.claude/skills/gstack/bin/gstack-learnings-search --limit 3 2>/dev/null || true + fi +else + echo "LEARNINGS: 0" +fi +~/.claude/skills/gstack/bin/gstack-timeline-log '{"skill":"plan-rollout","event":"started","branch":"'"$_BRANCH"'","session":"'"$_SESSION_ID"'"}' 2>/dev/null & +_HAS_ROUTING="no" +if [ -f CLAUDE.md ] && grep -q "## Skill routing" CLAUDE.md 2>/dev/null; then + _HAS_ROUTING="yes" +fi +_ROUTING_DECLINED=$(~/.claude/skills/gstack/bin/gstack-config get routing_declined 2>/dev/null || echo "false") +echo "HAS_ROUTING: $_HAS_ROUTING" +echo "ROUTING_DECLINED: $_ROUTING_DECLINED" +_VENDORED="no" +if [ -d ".claude/skills/gstack" ] && [ ! -L ".claude/skills/gstack" ]; then + if [ -f ".claude/skills/gstack/VERSION" ] || [ -d ".claude/skills/gstack/.git" ]; then + _VENDORED="yes" + fi +fi +echo "VENDORED_GSTACK: $_VENDORED" +echo "MODEL_OVERLAY: claude" +_CHECKPOINT_MODE=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_mode 2>/dev/null || echo "explicit") +_CHECKPOINT_PUSH=$(~/.claude/skills/gstack/bin/gstack-config get checkpoint_push 2>/dev/null || echo "false") +echo "CHECKPOINT_MODE: $_CHECKPOINT_MODE" +echo "CHECKPOINT_PUSH: $_CHECKPOINT_PUSH" +[ -n "$OPENCLAW_SESSION" ] && echo "SPAWNED_SESSION: true" || true +``` + +## Plan Mode Safe Operations + +In plan mode, allowed because they inform the plan: `$B`, `$D`, `codex exec`/`codex review`, writes to `~/.gstack/`, writes to the plan file, and `open` for generated artifacts. + +## Skill Invocation During Plan Mode + +If the user invokes a skill in plan mode, the skill takes precedence over generic plan mode behavior. **Treat the skill file as executable instructions, not reference.** Follow it step by step starting from Step 0; the first AskUserQuestion is the workflow entering plan mode, not a violation of it. AskUserQuestion (any variant — `mcp__*__AskUserQuestion` or native; see "AskUserQuestion Format → Tool resolution") satisfies plan mode's end-of-turn requirement. If no variant is callable, fall back to writing the decision brief into the plan file as a `## Decisions to confirm` section + ExitPlanMode — never silently auto-decide. At a STOP point, stop immediately. Do not continue the workflow or call ExitPlanMode there. Commands marked "PLAN MODE EXCEPTION — ALWAYS RUN" execute. Call ExitPlanMode only after the skill workflow completes, or if the user tells you to cancel the skill or leave plan mode. + +If `PROACTIVE` is `"false"`, do not auto-invoke or proactively suggest skills. If a skill seems useful, ask: "I think /skillname might help here — want me to run it?" + +If `SKILL_PREFIX` is `"true"`, suggest/invoke `/gstack-*` names. Disk paths stay `~/.claude/skills/gstack/[skill-name]/SKILL.md`. + +If output shows `UPGRADE_AVAILABLE `: read `~/.claude/skills/gstack/gstack-upgrade/SKILL.md` and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). + +If output shows `JUST_UPGRADED `: print "Running gstack v{to} (just updated!)". If `SPAWNED_SESSION` is true, skip feature discovery. + +Feature discovery, max one prompt per session: +- Missing `~/.claude/skills/gstack/.feature-prompted-continuous-checkpoint`: AskUserQuestion for Continuous checkpoint auto-commits. If accepted, run `~/.claude/skills/gstack/bin/gstack-config set checkpoint_mode continuous`. Always touch marker. +- Missing `~/.claude/skills/gstack/.feature-prompted-model-overlay`: inform "Model overlays are active. MODEL_OVERLAY shows the patch." Always touch marker. + +After upgrade prompts, continue workflow. + +If `WRITING_STYLE_PENDING` is `yes`: ask once about writing style: + +> v1 prompts are simpler: first-use jargon glosses, outcome-framed questions, shorter prose. Keep default or restore terse? + +Options: +- A) Keep the new default (recommended — good writing helps everyone) +- B) Restore V0 prose — set `explain_level: terse` + +If A: leave `explain_level` unset (defaults to `default`). +If B: run `~/.claude/skills/gstack/bin/gstack-config set explain_level terse`. + +Always run (regardless of choice): +```bash +rm -f ~/.gstack/.writing-style-prompt-pending +touch ~/.gstack/.writing-style-prompted +``` + +Skip if `WRITING_STYLE_PENDING` is `no`. + +If `LAKE_INTRO` is `no`: say "gstack follows the **Boil the Lake** principle — do the complete thing when AI makes marginal cost near-zero. Read more: https://garryslist.org/posts/boil-the-ocean" Offer to open: + +```bash +open https://garryslist.org/posts/boil-the-ocean +touch ~/.gstack/.completeness-intro-seen +``` + +Only run `open` if yes. Always run `touch`. + +If `TEL_PROMPTED` is `no` AND `LAKE_INTRO` is `yes`: ask telemetry once via AskUserQuestion: + +> Help gstack get better. Share usage data only: skill, duration, crashes, stable device ID. No code, file paths, or repo names. + +Options: +- A) Help gstack get better! (recommended) +- B) No thanks + +If A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry community` + +If B: ask follow-up: + +> Anonymous mode sends only aggregate usage, no unique ID. + +Options: +- A) Sure, anonymous is fine +- B) No thanks, fully off + +If B→A: run `~/.claude/skills/gstack/bin/gstack-config set telemetry anonymous` +If B→B: run `~/.claude/skills/gstack/bin/gstack-config set telemetry off` + +Always run: +```bash +touch ~/.gstack/.telemetry-prompted +``` + +Skip if `TEL_PROMPTED` is `yes`. + +If `PROACTIVE_PROMPTED` is `no` AND `TEL_PROMPTED` is `yes`: ask once: + +> Let gstack proactively suggest skills, like /qa for "does this work?" or /investigate for bugs? + +Options: +- A) Keep it on (recommended) +- B) Turn it off — I'll type /commands myself + +If A: run `~/.claude/skills/gstack/bin/gstack-config set proactive true` +If B: run `~/.claude/skills/gstack/bin/gstack-config set proactive false` + +Always run: +```bash +touch ~/.gstack/.proactive-prompted +``` + +Skip if `PROACTIVE_PROMPTED` is `yes`. + +If `HAS_ROUTING` is `no` AND `ROUTING_DECLINED` is `false` AND `PROACTIVE_PROMPTED` is `yes`: +Check if a CLAUDE.md file exists in the project root. If it does not exist, create it. + +Use AskUserQuestion: + +> gstack works best when your project's CLAUDE.md includes skill routing rules. + +Options: +- A) Add routing rules to CLAUDE.md (recommended) +- B) No thanks, I'll invoke skills manually + +If A: Append this section to the end of CLAUDE.md: + +```markdown + +## Skill routing + +When the user's request matches an available skill, invoke it via the Skill tool. When in doubt, invoke the skill. + +Key routing rules: +- Product ideas/brainstorming → invoke /office-hours +- Strategy/scope → invoke /plan-ceo-review +- Architecture → invoke /plan-eng-review +- Design system/plan review → invoke /design-consultation or /plan-design-review +- Full review pipeline → invoke /autoplan +- Bugs/errors → invoke /investigate +- QA/testing site behavior → invoke /qa or /qa-only +- Code review/diff check → invoke /review +- Visual polish → invoke /design-review +- Ship/deploy/PR → invoke /ship or /land-and-deploy +- Save progress → invoke /context-save +- Resume context → invoke /context-restore +``` + +Then commit the change: `git add CLAUDE.md && git commit -m "chore: add gstack skill routing rules to CLAUDE.md"` + +If B: run `~/.claude/skills/gstack/bin/gstack-config set routing_declined true` and say they can re-enable with `gstack-config set routing_declined false`. + +This only happens once per project. Skip if `HAS_ROUTING` is `yes` or `ROUTING_DECLINED` is `true`. + +If `VENDORED_GSTACK` is `yes`, warn once via AskUserQuestion unless `~/.gstack/.vendoring-warned-$SLUG` exists: + +> This project has gstack vendored in `.claude/skills/gstack/`. Vendoring is deprecated. +> Migrate to team mode? + +Options: +- A) Yes, migrate to team mode now +- B) No, I'll handle it myself + +If A: +1. Run `git rm -r .claude/skills/gstack/` +2. Run `echo '.claude/skills/gstack/' >> .gitignore` +3. Run `~/.claude/skills/gstack/bin/gstack-team-init required` (or `optional`) +4. Run `git add .claude/ .gitignore CLAUDE.md && git commit -m "chore: migrate gstack from vendored to team mode"` +5. Tell the user: "Done. Each developer now runs: `cd ~/.claude/skills/gstack && ./setup --team`" + +If B: say "OK, you're on your own to keep the vendored copy up to date." + +Always run (regardless of choice): +```bash +eval "$(~/.claude/skills/gstack/bin/gstack-slug 2>/dev/null)" 2>/dev/null || true +touch ~/.gstack/.vendoring-warned-${SLUG:-unknown} +``` + +If marker exists, skip. + +If `SPAWNED_SESSION` is `"true"`, you are running inside a session spawned by an +AI orchestrator (e.g., OpenClaw). In spawned sessions: +- Do NOT use AskUserQuestion for interactive prompts. Auto-choose the recommended option. +- Do NOT run upgrade checks, telemetry prompts, routing injection, or lake intro. +- Focus on completing the task and reporting results via prose output. +- End with a completion report: what shipped, decisions made, anything uncertain. + +## AskUserQuestion Format + +### Tool resolution (read first) + +"AskUserQuestion" can resolve to two tools at runtime: the **host MCP variant** (e.g. `mcp__conductor__AskUserQuestion` — appears in your tool list when the host registers it) or the **native** Claude Code tool. + +**Rule:** if any `mcp__*__AskUserQuestion` variant is in your tool list, prefer it. Hosts may disable native AUQ via `--disallowedTools AskUserQuestion` (Conductor does, by default) and route through their MCP variant; calling native there silently fails. Same questions/options shape; same decision-brief format applies. + +**Fallback when neither variant is callable:** in plan mode, write the decision brief into the plan file as a `## Decisions to confirm` section + ExitPlanMode (the native "Ready to execute?" surfaces it). Outside plan mode, output the brief as prose and stop. **Never silently auto-decide** — only `/plan-tune` AUTO_DECIDE opt-ins authorize auto-picking. + +### Format + +Every AskUserQuestion is a decision brief and must be sent as tool_use, not prose. + +``` +D +Project/branch/task: <1 short grounding sentence using _BRANCH> +ELI10: +Stakes if we pick wrong: +Recommendation: because +Completeness: A=X/10, B=Y/10 (or: Note: options differ in kind, not coverage — no completeness score) +Pros / cons: +A)