deep-interview
SkillDev toolsSocratic deep interview with mathematical ambiguity gating before autonomous execution
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the deep-interview skill
What this skill tells your AI
The instructions your AI receives, as published by toongri/oh-my-toong-playground in skills/deep-interview/SKILL.md and read by ahel’s review.
<Use_When>
- User has a vague idea and wants thorough requirements gathering before execution
- User says "deep interview", "interview me", "ask me everything", "don't assume", "make sure you understand"
- User says "ouroboros", "socratic", "I have a vague idea", "not sure exactly what I want"
- User wants to avoid "that's not what I meant" outcomes from autonomous execution
- Task is complex enough that jumping to code would waste cycles on scope discovery
- User wants evidence-backed clarity before committing to execution
- User wants every design decision interrogated with alternatives before building -- not just requirements clarified </Use_When>
<Do_Not_Use_When>
- User requests implementation without an interview. Respect that direction.
- A detailed request or existing PRD is useful starting evidence, not a reason to skip an explicitly requested interview. </Do_Not_Use_When>
<Why_This_Exists> AI can build anything. The hard part is knowing what to build. Deep Interview applies Socratic methodology to iteratively expose assumptions and test readiness against evidence and open decisions, ensuring the AI has genuine clarity before spending execution cycles.
Inspired by the Ouroboros project which demonstrated that specification quality is the primary bottleneck in AI-assisted development. </Why_This_Exists>
<Execution_Policy>
- Ask ONE question at a time -- never batch multiple questions
- Follow open decisions in dependency order. Choose the question whose answer most changes scope, behavior, architecture, or verification; use clarity scores to expose gaps rather than override an unresolved prerequisite.
- Among decisions with settled prerequisites, target the weakest unscored/lowest-clarity dimension by default. Name its score and gap each round; explain when a prerequisite or consequence makes another target more urgent. Keep the displaced gap open in the register.
- Gather discoverable facts before asking the user:
explorefor code,librarian/ultraresearchfor external evidence. Reuse current evidence; investigate again when a new question or changed premise makes it insufficient. Failed research remains an explicit unknown, not an assumed fact or a change of project type. - Cite the evidence behind a question. Existing code describes current behavior; it does not decide the user's desired behavior.
- Tag every evidence item by its ORIGIN at record time (provenance is assigned where evidence enters, never reconstructed later) and persist it in the
evidence_provenancestate field. Origin→label assignment: a codebase read →[from-code]; a codebase read confirmed by executed code →[from-code][auto-confirmed]; alibrarian/ultraresearchexternal fact →[from-research]; a user answer →[from-user]. Append each item via the state CLI:bun ${CLAUDE_SKILL_DIR}/scripts/deep-interview-state.ts update \ --append-provenance-item '{"evidence_id":"<id>","label":"<one-of-the-four-labels>"}' - Score ambiguity after every answer -- display the score transparently
- Keep prompt payloads budgeted: summarize or trim oversized initial context/history before composing question, scoring, spec, or handoff prompts
- If the user's initial context is oversized, create a concise prompt-safe summary first and wait for that summary before ambiguity scoring, question generation, or downstream execution handoff
- Normal completion requires the closure audit below, including ambiguity ≤ the resolved threshold. A score is not proof of understanding.
- Respect explicit stop, early delivery, and delegation; preserve unresolved decisions without presenting them as agreement.
- Persist interview state for resume across session interruptions
- Challenge assumptions whenever their consequences matter, including the first question and any later reversal. </Execution_Policy>
Phase 1: Initialize
- Parse the user's idea from
{{ARGUMENTS}} - Detect brownfield vs greenfield:
- Run
exploreagent: check if cwd has existing source code, package files, or git history - If source files exist AND the user's idea references modifying/extending something: brownfield
- Otherwise: greenfield
- Run
- For brownfield: Run
exploreagent to map relevant codebase areas; pass the summary as--codebase-contextin theinitcall (step 4) 3.5. Load runtime settings:- Read
[$CLAUDE_CONFIG_DIR|~/.claude]/settings.jsonand./.claude/settings.json(project overrides user) - Resolve
omt.deepInterview.ambiguityThresholdinto<resolvedThreshold>; if it is undefined, use0.15 - Derive
<resolvedThresholdPercent>from<resolvedThreshold>and substitute both placeholders throughout the remaining instructions before continuing 3.6. Normalize oversized initial context before state init: - Inspect the initial idea plus any pasted artifacts, logs, transcripts, or file excerpts for prompt-budget risk before writing state or generating the first question.
- If the initial context is oversized or likely to crowd out downstream prompts, produce a concise prompt-safe summary that preserves user intent, decisions, constraints, unknowns, cited files/symbols, and any explicit non-goals.
- Treat the summary as the canonical
initial_ideaand store the raw oversized material only as external/advisory context if it can be referenced safely; do not paste the raw oversized context into question-generation, ambiguity-scoring, spec-crystallization, or execution-handoff prompts. - Wait until the summary exists before ambiguity scoring, weakest-dimension selection, brownfield exploration prompts, or any bridge to prometheus or sisyphus. 3.7. Round 0 — Topology Enumeration Gate:
- Enumerate ALL topology components the parsed idea implies — do NOT narrow to a single slice. A component is a subsystem that can be interviewed and scored somewhat independently (neither forces the other to be built first; cross-cutting integration glue such as webhooks, shared identity, or event wiring is NOT itself a component). Judge this for brownfield from both the user's framing and the step-3 explore summary (codebase coupling); for greenfield (no explore), judge it from the idea prose alone. A single-system idea still enumerates as one component — Round 0 always runs, whether the count is 1 or N.
- Prefer 1-6 components. If more than 6 candidates appear, group siblings at the highest useful level and note the grouping rationale — the group, not each member, becomes the interview component (every active component is scored on all 6 dimensions each round, so an ungrouped wide list multiplies interview floor pressure without adding clarity).
- Name each component for the behavior it owns — a verb or action (
read-switch,backfill,write-path), not a storage noun that reads as a datastore.write-storereads as a database rather than the write path it names; preferwrite-path/dual-write. The name is what the user confirms and what every later section refers back to, so an ambiguous one propagates. - Surface the full enumerated list to the user via
AskUserQuestion: name each component, describe how it relates to the others, and ask the user to confirm the list, add a component you missed, merge two that are really one, split one that is really two, or defer a component out of this interview's scope. - Lock the confirmed list into state — every enumerated component, active or deferred, is recorded:
bun ${CLAUDE_SKILL_DIR}/scripts/deep-interview-state.ts set-topology \ --json '[{"id":"<id>","name":"<name>","status":"active|deferred"}]' - Every named component is either active (scored across all 6 dimensions in Phase 2) or explicitly deferred (visible in
state.topology, excluded from active-component floor pressure) — never silently dropped. - Resume + legacy migration (topology-floor-evolution Stage 6, UC11): when resuming an interrupted session,
deep-interview-state.ts get's output carries amigration_statusfield derived fromcomputeTopologyMigrationStatus. Ifmigration_statusislegacy_missing— this state predates thetopologyfield entirely, never having run Round 0 — run this Round 0 gate now, before any further per-component scoring write, even if the resumed state already has rounds or a scored ambiguity from before topology existed.currentmeans topology is already locked; resume straight into Phase 2 as usual. 3.8. Revision identity gate: - A revision of an existing PM parent must either resume/adopt the established interview state or start the current state with the established
interview_idandparent_id. For the latter, pass both--interview-id "<established interview_id>"and--parent-id "<established parent ID or URL>"toinit; do not generate a new UUID for a known parent. - Never pair a newly generated UUID/anchor with an old known parent. If the established identity cannot be recovered, explicitly treat this as a new design: use a new interview ID, omit the old
parentId, letcraft-tasksresolve/create a parent by the new anchor, and do not claim it revises the old parent.
- Read
- Initialize state by invoking the CLI:
bun ${CLAUDE_SKILL_DIR}/scripts/deep-interview-state.ts init \
--initial-idea "$(cat <<'OMT_DI_PAYLOAD_EOF'
<prompt-safe initial-context summary or user input>
OMT_DI_PAYLOAD_EOF
)" \
--interview-id "<uuid>" \
--type "greenfield|brownfield" \
--current-phase "deep-interview" \
--threshold <resolvedThreshold>
# brownfield only: append --codebase-context "$(cat <<'OMT_DI_PAYLOAD_EOF'
# <explore summary>
# OMT_DI_PAYLOAD_EOF
# )"
Use "$(cat <<'OMT_DI_PAYLOAD_EOF' ... OMT_DI_PAYLOAD_EOF)" for --initial-idea and --codebase-context so apostrophes and $/backtick sequences in user text are passed verbatim without shell expansion.
The init subcommand performs a strict overlay of the rich state shape into the seed file that the PreToolUse hook already created. The full shape written to state is:
{
"active": true,
"current_phase": "deep-interview",
"state": {
"interview_id": "<uuid>",
"type": "greenfield|brownfield",
"initial_idea": "<prompt-safe initial-context summary or user input>",
"initial_context_summary": null,
"rounds": [],
"current_ambiguity": 1.0,
"threshold": <resolvedThreshold>,
"codebase_context": null,
"challenge_modes_used": [],
"ontology_snapshots": []
}
}
- Announce the interview to the user:
Starting deep interview. I'll ask targeted questions to understand your idea thoroughly before building anything. After each answer, I'll show your clarity score. We will work through open decisions and concrete counterexamples, then check readiness together. The ambiguity threshold is one check, not an automatic finish.
Your idea: "{initial_idea}" Project type: {greenfield|brownfield} Current ambiguity: 100% (we haven't started yet)
Phase 2: Interview Loop
Use the same decision loop for requirements and design. Keep going while an in-scope decision could change the agreed result, architecture, or verification. Round counts only describe history.
Step 2-exit: Closure Audit
Before transitioning from requirements to design, audit requirements decisions; before crystallizing, audit requirements and all design branches. A low score starts this audit, never skips it.
Closure Guard (precondition): before running steps 1-2 below, check every active topology component's clarity_scores in state. If any active component still carries an unscored (null) dimension, convergence cannot be declared — loop back into the interview loop targeting that component's weakest (unscored) dimension instead of running this seam. An ambiguity ≤ threshold reading that ignores an unscored sibling component is not real convergence; it means the interview has not yet asked, not that there is nothing left to ask.
This precondition is enforced in code, not just here: the Stop-hook refuses a <deep-interview-done/> token while any active component still carries an unscored dimension, independent of the ambiguity reading and of whichever threshold this run resolved. Emitting the token early does not end the interview — it loops you back.
Closure Guard (non-goal decider precondition): also check, before running steps 1-2 below, whether the interview has secured at least one non-goal carrying a decider — an excluded item paired with a way to tell whether a given finding falls inside it, the same {excluded item} | decider: {...} shape the Phase 4 template's Non-Goals section requires. If zero non-goal-with-decider pairs exist yet, convergence cannot be declared either — loop back into the interview loop and ask for one, regardless of what the ambiguity reading says: this is a categorical precondition, not a term folded into the ambiguity arithmetic. The check is existence-only — it asks whether a decider was stated, never how precise it is; grading precision here would turn a mechanical gate into an interpretation dispute.
This precondition is enforced in code too, symmetric with the topology guard above: the Stop-hook refuses a <deep-interview-done/> token while state.non_goals holds zero entries with a non-empty decider, independent of the ambiguity reading. Emitting the token early does not end the interview — it loops you back. Record each confirmed non-goal/decider pair into state as soon as it is secured — during the Non-Goal Decider question (Step 2b) or here at the Closure Guard — so the hook can read it:
bun ${CLAUDE_SKILL_DIR}/scripts/deep-interview-state.ts set-nongoals \
--json '[{"item":"<excluded item>","decider":"<how to tell a finding belongs to it>"}]'
set-nongoals is a full-replace, same convention as set-topology — pass the complete accumulated list of non-goal/decider pairs on every call, not just the newest one.
- Review the decision register across every active component, including dependencies between components. Check scope, ownership, contracts, lifecycle/recovery, and how success will be demonstrated. An open or reopened decision that can change these keeps the interview open regardless of score.
- For each settled decision, check its evidence and the concrete counterexample or failure scenario tested against it. Surface contradictions and unsupported assumptions. Wordsmithing with no effect on behavior is not a new decision.
- Restate the goal, selected approach, boundaries, and explicitly delegated/deferred assumptions. Ask whether this matches the user's understanding. A correction reopens the affected decisions and their dependents; incorporate it before repeating this audit. An earlier explicit confirmation still applies while its premises remain unchanged.
User control: stop/cancel pauses immediately and preserves state. An explicit request to deliver early uses Draft delivery below; it is not a passed interview or an execution-ready design. Do not lower scores, mark gaps resolved, or emit <deep-interview-done/> to make a draft pass the normal completion gate. Explicit delegation ("your call") lets the agent research, recommend, and record a choice with its basis; uncertainty ("I don't know yet") keeps the decision open. A defer records what is excluded now and what would reopen it. Resolve the user's intent with one focused question when these meanings are unclear.
Draft delivery: read the current state and spec template, then save the available content to $OMT_DIR/deep-interview/{slug}.draft.md with Status DRAFT, the existing design anchor, the complete decision register, and unresolved decisions, owners, and consequences. An unknown owner or metadata value stays explicitly unknown; do not invent an output shape or ask another question when the user requested delivery without questions. This incomplete working document uses the template as an outline, not as a completed-spec validation claim. Share the draft and preserve interview state for resume. Draft delivery ends here: Phase 4's completed-spec self-review, presentation submission, handoff transition, completion token, and Phase 5 execution bridge apply only after normal closure. A request to defer execution after a completed interview still receives the full spec and presentation.
Step 2-head: Update the Decision Register
Maintain one register throughout requirements and design. Each entry contains:
| Field | Content |
|---|---|
id, question, component | Stable decision identity and the behavior it concerns |
depends_on | IDs of prerequisite decisions |
status | open, settled, delegated, or deferred |
choice, basis | Current choice, who decided it, and the user/code/research evidence; distinguish an agent's inference |
alternatives | Real alternatives considered, why rejected, and the tradeoff accepted |
assumptions, checks | Remaining assumptions and concrete counterexamples, failure cases, or verification that tested the choice |
reopen_reason | New evidence or changed premise invalidating the choice; empty while current |
After each answer or finding, update this register before asking again:
- Extract what was decided and what remains uncertain. Add the new decisions this answer exposes.
- Compare with prior decisions and assumptions. On contradiction, set the affected entry and every dependent entry back to
open, preserving the old choice and why it is being reconsidered. Use the dispute mechanism in Step 2c for any established fact that was retracted. - Select among open decisions with settled prerequisites. Resolve conflicting prerequisites first. When dependencies form a cycle, ask about the shared assumption tying them together rather than inventing an order.
- Look across all components and their interactions before drilling deeper. A newly exposed ownership or failure-path gap may matter more than another detail in the current topic.
Persist the complete current register as decision_register inside each recorded round (Step 2e, Step 2-fact, or a design round). This uses the existing JSON round payload, not a new CLI option. On resume, recover the most recent round containing decision_register; preserve all settled choices. For an older transcript without it, reconstruct the register from recorded evidence, leaving unsupported choices open.
Questioning Stance
The five stances are existing questioning behaviors, not separate agents:
- Clarify — sharpen the weakest unresolved meaning or requirement.
- Fact-ground — investigate the evidence a decision depends on.
- Contrarian — test a core assumption against its opposite or a concrete counterexample.
- Simplifier — test whether removing complexity still achieves the required outcome.
- Ontologist — examine what the core concept is and how its entities relate.
Choose the stance for the selected decision's current gap. Missing discoverable evidence calls for Fact-ground even if another fact in the same dimension was researched earlier. An unsupported premise calls for Contrarian; unjustified complexity for Simplifier; unstable meaning or relationships for Ontologist; an unresolved concrete meaning for Clarify. A stance can be used on the first round and repeated when new evidence justifies it.
Numerical stagnation signal: when ambiguity stays within ±0.05 for three rounds, inspect both the scores and the decision changes. If the same gap remains, explain what has not advanced and change the evidence source, counterexample, or stance. Stable entity definitions call for investigating the unresolved fact or tradeoff, not asking the same ontology question again. Use stance_history to notice neglected perspectives and unproductive repetition; it is not a once-only quota.
Perspective coverage: before closure, inspect whether the load-bearing premises were challenged, unnecessary complexity was tested, and unstable concepts were clarified. Record the concrete probe and result in checks; a stance name or round count alone does not establish coverage.
Use the matching question frame when it fits the gap:
- Contrarian: “What if the opposite were true?” / “What if this constraint doesn't actually exist?” Test whether the framing is supported or habitual.
- Simplifier: “What's the simplest version that would still be valuable?” / “Which constraints are necessary versus assumed?” Test which required outcome would fail without the complexity.
- Ontologist: use the latest ontology snapshot's entities: “Which is the core concept, and which are supporting?” Test whether the discussion addresses a symptom instead of the underlying problem.
Record the selected stance so the interview can inspect which perspectives it has used:
bun ${CLAUDE_SKILL_DIR}/scripts/deep-interview-state.ts update \
--append-stance "<selected-stance>"
Step 2-fact: Ground a Discoverable Fact
Use explore for codebase facts. Use librarian for a focused external source lookup; use ultraresearch in pre-work grounding posture when a decision needs multiple sources, competing claims resolved, or deeper verification. The in-interview research call remains Scoped (≤3 workers): this bounds one investigation, not the number of questions or later investigations. Pass the precise unknown, its decision impact, prior evidence, and what would resolve the conflict. Reuse evidence for the same still-valid claim; a new fact or changed premise can trigger another call in the same dimension.
If ultraresearch is unavailable or fails, continue with librarian for external facts and explore for code facts. Report what remains unverified; an available code lookup cannot substitute for missing external evidence. Continue independent decisions while a dependent question remains open.
When a decision needs a discoverable fact, investigate it before asking the user to decide. Record its provenance at entry, update the register, and re-score the affected component using Step 2c. Research results are evidence, not user answers:
bun ${CLAUDE_SKILL_DIR}/scripts/deep-interview-state.ts update \
--append-round-stdin <<'OMT_DI_PAYLOAD_EOF'
{"n":<round_number>,"kind":"fact-ground","component":"<component_id>","dimension":"<dimension>","fact":"<grounded fact>","provenance":"<origin label>","scores":{"intent":<intent>,"outcome":<outcome>,"scope":<scope>,"constraints":<constraints>,"success":<success>,"context":<context>},"ambiguity":<ambiguity>,"decision_register":[<current entries>]}
OMT_DI_PAYLOAD_EOF
After appending the round, persist the calculated overall ambiguity in the dedicated state field, then persist the grounded evidence's evidence_id and origin label in the dedicated provenance state field. Reuse the four origin labels above ([from-code], [from-code][auto-confirmed], [from-research], or [from-user]):
bun ${CLAUDE_SKILL_DIR}/scripts/deep-interview-state.ts update \
--current-phase "deep-interview" \
--current-ambiguity <ambiguity>
bun ${CLAUDE_SKILL_DIR}/scripts/deep-interview-state.ts update \
--append-provenance-item '{"evidence_id":"<evidence_id>","label":"<origin label>"}'
Shortened here. Read the whole file on GitHub.
Signals
- GitHub stars
- 25
- Forks
- 1
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
deep-interview-toongri- Source
- github.com/toongri/oh-my-toong-playground