/ouroboros:interview

SkillDev tools

Lets your agent ask you probing questions to turn vague ideas into clear requirements.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the /ouroboros:interview skill

About this capability

Socratic interview to crystallize vague requirements

What this skill tells your AI

The instructions your AI receives, as published by q00/ouroboros in skills/interview/SKILL.md and read by ahel’s review.

Socratic interview to crystallize vague requirements into clear specifications.

Required Skill Capabilities

  • ask_user — ask human-judgment questions through the active runtime's user-question surface.
  • inspect_code — answer repo-local factual questions from exact local files before asking the user.
  • call_mcp — use Ouroboros MCP tools for persistent interview state and seed generation.
  • run_lateral_review — invoke lateral thinking subagents before milestone turns and direct-answer synthesis.
  • web_research — fetch current external facts only when the interview genuinely depends on them.
  • run_shell — run bounded local commands for version checks and repository inspection.
  • refine_answer — confirm structured interpretations of free-text answers before forwarding them.
  • maintain_ledger — keep ambiguity, gates, and unresolved decisions visible in the main session.
  • run_closure_gate — audit readiness locally even when MCP reports seed-ready.
  • restate_goal — restate the goal and require explicit approval before seed generation.

Non-Skippable Gates

  • Refine free-text answers that carry scope, constraints, or decisions.
  • Maintain a visible ambiguity ledger in the main session.
  • Treat MCP seed-ready as permission to audit closure, not as completion.
  • Apply Seed Closer criteria before suggesting or running seed generation.
  • Run the Restate gate before seed generation.
  • Require explicit user approval before suggesting or running seed generation.

Usage

ooo interview [topic]
/ouroboros:interview [topic]

Trigger keywords: "interview me", "clarify requirements"

Instructions

When the user invokes this skill:

Step 0: Version Check (runs before interview)

Before starting the interview, check if a newer version is available:

# Fetch latest release tag from GitHub (timeout 3s to avoid blocking)
curl -s --max-time 3 https://api.github.com/repos/Q00/ouroboros/releases/latest | grep -o '"tag_name": "[^"]*"' | head -1

Compare the result with the current version in the active runtime's local plugin metadata (for Claude installs this is .claude-plugin/plugin.json).

  • If a newer version exists, ask the user through the active runtime's ask_user capability:
    {
      "questions": [{
        "question": "Ouroboros <latest> is available (current: <local>). Update before starting?",
        "header": "Update",
        "options": [
          {"label": "Update now", "description": "Update plugin to latest version (restart required to apply)"},
          {"label": "Skip, start interview", "description": "Continue with current version"}
        ],
        "multiSelect": false
      }]
    }
    
    • If "Update now":
      • On Claude-plugin installs only:
        1. Run claude plugin marketplace update ouroboros via the active runtime's run_shell capability (refresh marketplace index). If this fails, tell the user "⚠️ Marketplace refresh failed, continuing…" and proceed.
        2. Run claude plugin update ouroboros@ouroboros via the active runtime's run_shell capability (update plugin/skills). If this fails, inform the user and stop — do NOT proceed to the package-manager step.
      • On non-Claude runtimes, skip Claude plugin commands and proceed directly to the package-manager step for ouroboros-ai; do not require Claude-only commands or tools.
      1. Detect the user's Python package manager and upgrade the MCP server:
        • Check which tool installed ouroboros-ai by running these in order:
          • uv tool list 2>/dev/null | grep "^ouroboros-ai " → if found, use uv tool upgrade ouroboros-ai
          • pipx list 2>/dev/null | grep "^ ouroboros-ai " → if found, use pipx upgrade ouroboros-ai
          • Otherwise, print: "Also upgrade the MCP server: pip install --upgrade ouroboros-ai" (do NOT run pip automatically)
      2. Tell the user: "Updated! Restart your session to apply, then run ooo interview again."
    • If "Skip": proceed immediately.
  • If versions match, the check fails (network error, timeout, rate limit 403/429), or parsing fails/returns empty: silently skip and proceed.

Then choose the execution path:

Step 0.5: Load MCP Tools (Required before Path A/B decision)

The Ouroboros MCP tools are often registered as deferred tools that must be explicitly loaded before use. You MUST perform this step before deciding between Path A and Path B.

  1. Use the active runtime's tool-discovery capability to find and load the interview MCP tool:

    tool discovery query: "+ouroboros interview"
    

    This searches for tools with "ouroboros" in the name related to "interview".

  2. The tool will typically be named mcp__plugin_ouroboros_ouroboros__ouroboros_interview (with a plugin prefix). After runtime tool discovery returns, the tool becomes callable.

  3. If the tool is callable — already exposed, or loaded by discovery — proceed to Path A. An empty discovery result for an already-exposed tool is expected, not a failure. Proceed to Path B only if the tool is genuinely absent (no Ouroboros MCP server).

IMPORTANT: Do NOT skip this step. Do NOT assume MCP tools are unavailable just because they don't appear in your immediate tool list. They are almost always available as deferred tools that need to be loaded first.

CRITICAL — deferred-schema guard (prevents "Invalid tool parameters"): This skill makes ouroboros_* MCP calls across multiple turns, and each turn runs in a fresh tool context. A deferred tool's schema loaded on one turn is NOT guaranteed to still be loaded on the next. If you call any ouroboros_* MCP tool while its schema is not loaded in the current turn, the runtime rejects the call with "Invalid tool parameters" before it ever reaches the server. Therefore: immediately before EVERY ouroboros_* MCP call in this skill, re-run the tool-discovery load query for the specific MCP tool you are about to call (idempotent — a no-op when the schema is already loaded) so the correct schema is guaranteed present for that call. Use "+ouroboros interview" before ouroboros_interview and "+ouroboros lateral" before ouroboros_lateral_think. If a load ever returns no matching tool (and the tool is not already callable — an empty load for an already-exposed tool is an expected no-op, not absence), switch to the documented fallback / Path B instead of retrying the failing call.

Path A: MCP Mode (Preferred)

If the ouroboros_interview MCP tool is available (loaded via runtime tool discovery above), use it for persistent, structured interviews.

Architecture: MCP is a pure question generator. You (the main session) are the answerer and router.

MCP (question generator) ←→ You (answerer + router) ←→ User (human judgment only)

Role split:

  • MCP: Generates Socratic questions, manages interview state, scores ambiguity. Does NOT read code.
  • You (main session): Receives MCP questions, answers them by reading code through the active runtime's inspect_code capability, or routes to the user when human judgment is needed.
  • User: Only answers questions that require human decisions (goals, acceptance criteria, business logic, preferences).
Interview Flow
  1. Start a new interview:

    Tool: ouroboros_interview
    Arguments:
      initial_context: <user's topic or idea>
      cwd: <current working directory>
      confused_terms: <optional explicit terms the user does not understand>
      references: <optional [{reference_id, label, origin, url?, excerpt?}]>
    

    Returns a session ID and the first question.

    confused_terms and references are structured adapter context, not requirements. They are queued on the start call and MUST NOT alter the first question. On later turns, glossary help is limited to explicitly confused terms and references are used only for contrast questions. Do not infer these arguments from vocabulary density or fetch referenced URLs/files.

  2. For each question from MCP, apply the routing paths below:

    Parent-session question handoff: If an MCP response includes meta.status="parent_question_required" or meta.ask_user_directly=true, treat it as a normal interview continuation, not as an MCP/provider/tool failure. Do not tell the user MCP failed, do not expose reason_code, and do not retry the MCP question generator. Ask exactly one natural Socratic clarification question yourself, using the same routing judgement as any other interview turn. Save the exact user-facing question text. When the user answers, call:

    Tool: ouroboros_interview
    Arguments:
      session_id: <meta.session_id>
      answer: <user answer>
      last_question: <exact question you asked the user>
    

    last_question is required on this path so MCP can persist the real transcript even though the parent session generated the question.

    Question-first advisory fanout: If an MCP response includes meta.question_advisory_request, show the interview question to the user first, then use the advisory request as a parent-session assist layer. The advisory exists to help the human answer; it must not hide, replace, or delay the question itself.

    Read the stamped dispatch contract before running the lanes. With dispatch_mode="host_driven", use the declared native parallel mechanism. With dispatch_mode="host_decides", use native parallel fan-out when the current host exposes it and otherwise process the same payloads sequentially. With dispatch_mode="sequential", process payloads in order. For Claude Code the parallel mechanism is Task/Agent; for Codex, explicitly start one native subagent per payload in a single fan-out turn. Wait for every result, then synthesize. The standard lanes are:

    • code_context — inspect repo-local facts and reuse meta.code_investigation_request when present.
    • web_context — browse/search only when current external facts genuinely affect the answer.
    • data_context — take the measurements that inform the question. This lane takes the measurement; see "Data measurements" below.
    • ambiguity_contrarian — find hidden assumptions, vague terms, missing decisions, and risky defaults.
    • answer_simplifier — turn the question into 2-3 easy choices or one concise draft answer.
    • architecture_implications — check whether the answer changes ownership, interfaces, rollout, or system shape.

    Synthesize advisory results into a compact helper for the user: 2-3 answer options, one recommended draft, or a short "I found these ambiguities" note. Do not forward advisory output to ouroboros_interview until the user approves, edits, or explicitly asks you to auto-confirm a safe answer. When meta.question_advisory_subagents is present you MUST process every payload: treat each entry as spawn-ready advisory work with title, agent, prompt, and context, and pass its prompt unchanged. Obey meta.question_advisory_host_action: spawn_subagents means parallel support was declared; dispatch_subagents_if_supported means use native parallel dispatch when available and sequential fallback otherwise; process_payloads_sequentially means ordered processing is required. This is required regardless of mode—the payloads themselves are the work contract, while the host action selects the execution strategy. Never reconstruct prompts from prose. Preserve the original question text while children run.

    Submitting fan-out results back (re-entry): When the originating meta carries a fanout_id (e.g. meta.question_advisory_fanout_id, or a fanout_id in a lateral persona panel dispatch), after all advisory/persona subagents return, call ouroboros_submit_fanout_results with:

    • session_id: the session the fan-out was issued under. Required whenever the producer ran with one — an omitted session is refused rather than waived, because this is what binds a submission to its owner. Contracted lanes assert no session of their own; this argument is the binding.
    • fanout_id: the stamped id from that meta,
    • correlation_key: the stamped result_correlation_key (context.lane_id, context.persona, or code_facts). Omitting it is refused the same way whenever the fan-out recorded one — send back what the meta stamped rather than leaving it out,
    • results: one { "key": <correlation value>, "content": <child output> } per subagent, where key is that child's correlation value (its lane id, persona, or code_facts). Every result must be either { "key": <lane>, "content": ... } or exactly { "key": <lane>, "undispatched": true } — the literal true, no content beside it, and never an entry carrying neither. One entry per lane: a lane reported twice is two statements about it, and nothing here picks between them by list position. Anything else comes back as status="invalid_result_entry" with invalid_keys, listing every bad entry at once so one resubmission fixes them all.

    A complete set returns a bounded artifact envelope. Call ouroboros_fetch_artifact with its contract_id, then continue from the correlated synthesis in the fetched body. This explicit MCP fetch is required even when the host has no shell. A partial set returns status="partial" with missing_required_keys. Retry with every lane you hold, not only the missing ones — no submitted output is kept between calls, so each call is judged on what it carries. (The record stores only what was asked; retaining what children answered is durable result state, deferred with its sanitization duties to a later slice.) Sequential hosts submit after processing payloads one-by-one — same tool, same contract, so accumulate the outputs on your side and send the growing set. Continue the interview from the fetched synthesis; keep the user-facing question visible throughout.

    Only lanes marked required: true in the request block completion. A lane you ran that had nothing to say still submits its output — that is an answer. A lane you could not spawn at all (no capability for it, the child died, the user cancelled it) is submitted as { "key": <lane id>, "undispatched": true }. Never invent output for a lane you did not run: a fabricated finding is worse than a missing one, and this is exactly why the declaration exists.

    Data measurements: The data_context lane discovers what data tools this host exposes, takes the measurement itself, and returns the aggregate it read. You do not confirm anything before it runs and you do not run anything after — it has already happened by the time you read the result. There is nothing to approve because the approval already exists: the user registered these tools, and registering one is the willingness to have it called. That is the standing every other advisory lane runs on, and this lane was the only one asked to hold a line in prose that its siblings did not.

    When its output carries measurements:

    • Show the numbers beside the question as material for the user's judgment. They are never the answer. The user answers in their own words on the ordinary [from-user] path; there is no [from-data] answer to forward. This is now the whole of the boundary: the lane carries real values, so the only thing standing between a measurement and the Seed is that you put it next to the question instead of into the answer.
    • Carry the aggregate as the lane reported it, with its metric and the decision it informs. Do not re-derive, re-scale, or combine numbers across measurements; you did not run the read and cannot know what would survive the arithmetic.
    • If the user has already answered the question by the time the measurement arrives, drop it. Do not re-open a decision the user has made, and do not present the numbers as a reason to reconsider — evidence informs a decision, it does not revisit one.

    When data_needed is false the lane looked and found nothing to measure. Every reason it can give is a statement about the lane, never about the user's infrastructure — a subagent sees what reached it, not what is connected, so it is not positioned to tell anyone a data path is missing. Read them accordingly:

    • not_a_measurement / question_too_ambiguous_to_measure — about the question. Nothing to relay beyond moving on.
    • answer_would_not_be_an_aggregate — about the shape of the answer.
    • no_data_store_described — nothing the lane was shown holds this answer. Worth mentioning only if you know the store exists and the lane was not told about it; otherwise it is ordinary.
    • store_described_but_not_callablethis one is yours to handle, not the user's to hear. A store exists and the child could not reach it. You see the environment and it does not: check whether the tool is available to you, take the read yourself, or re-dispatch the lane. Do not surface it as a missing data path. This constant exists because its predecessor was relayed to a user as a fact about their own infrastructure while the store in question sat described in the child's prompt.

    no_evidence_reason is one of a fixed set of constants, so say it in your own words rather than pasting the constant.

    What this lane can reach is not classified by anyone. The child names the tool it used; it cannot prove that tool was read-only, and MCP carries no cost or mutation metadata for you to check against. That risk is accepted knowingly and is the same one the sibling advisory lanes already run under. Do not manufacture a disclaimer about it: a warning attached to every measurement is one users learn to click through, and it would be describing a check nothing performed.

    Milestone lateral-review dispatch: If an MCP response includes meta.lateral_review_recommended=true, treat it as a required lightweight subagent review for that turn. The interview just crossed an ambiguity milestone such as initial -> progress, progress -> refined, or refined -> ready, which is exactly when hidden assumptions tend to matter.

    After showing the returned question to the user:

    • Tell the user briefly that a few perspectives are checking the question.
    • Call ouroboros_lateral_think with meta.lateral_review_tool_args when present. If only the legacy advisory fields are present, call it with personas=["researcher","contrarian","simplifier"], a problem context containing the current interview session/milestone/question, and a current approach describing the next interview-routing decision.
    • Fold only concrete, user-safe findings into the next answer or user question. Do not present every subagent note as a report.
    • If lateral tooling is unavailable, continue the interview and say the review could not be run; do not restart the interview.

    The MCP interview tool is still the question generator and source of persistent state. Lateral review is a main-session assist layer: it helps the user feel supported, but it does not by itself change requirements or mark the interview complete.

    Main-session direct-answer assistance: Use lateral review frequently when the main session would otherwise answer the MCP question directly or compress the user's free-text into a decision. This is the supported "deep research style" experience for interviews: the user should see that multiple perspectives are helping, while the final prompt stays easy to answer.

    Trigger a lightweight ouroboros_lateral_think call before continuing when any of these are true:

    • You are about to synthesize a product/UX/architecture answer from partial user input.
    • The question asks for tradeoffs, priorities, non-goals, risk, success criteria, or rollout strategy.
    • The factual code answer is lower confidence than an exact config/manifest match.
    • The user seems busy, uncertain, terse, or likely to benefit from selectable options instead of another open-ended question.

    Prefer personas=["researcher","contrarian","simplifier"] for this assist. Add architect when the answer changes system shape or ownership. Summarize the result as 2-3 concrete options or one recommended answer draft, then let the user approve, tweak, or switch to auto.

    PATH 1 — Code Answer (describe current state from codebase): When the question asks about existing tech stack, frameworks, dependencies, current patterns, architecture, or file structure:

    • Use the active runtime's inspect_code capability to find the factual answer
    • Description, not prescription: "The project uses JWT" is fact. "The new feature should also use JWT" is a DECISION — route to PATH 2.
    • Evaluate confidence and choose sub-path:

    PATH 1a — Auto-confirm (high-confidence factual, no user block): When ALL of the following are true:

    • The answer is found as an exact match in a manifest or config file (e.g., pyproject.toml, package.json, Dockerfile, go.mod, .env.example)
    • The answer is purely descriptive — it describes what exists, not what the new feature should do
    • There is no ambiguity — a single, clear answer (not multiple candidates)

    Then:

    • Send the answer to MCP immediately with [from-code][auto-confirmed] prefix
    • Display a brief notification to the user (do NOT block): "ℹ️ Auto-confirmed: Python 3.12, FastAPI framework (pyproject.toml)"
    • The user can correct at any time by saying "that's wrong" — re-send correction to MCP
    • Increment the auto-confirm counter (see Dialectic Rhythm Guard below)

    Examples of auto-confirmable facts:

    • Programming language (from pyproject.toml, package.json, go.mod)
    • Framework (from dependencies in manifest)
    • Python/Node version (from config files)
    • Package manager (from lock files present)
    • CI/CD tool (from .github/workflows/, Jenkinsfile, etc.)

Shortened here. Read the whole file on GitHub.

Signals

GitHub stars
6k
Forks
594
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
interview-q00
Source
github.com/q00/ouroboros