How the Ouroboros Interview Phase (Big Bang) Conducts Socratic Questioning
The Ouroboros Interview Phase enforces Socratic questioning through a state-driven engine that constrains the LLM to always end with a clarifying question while targeting the biggest source of ambiguity, ensuring fuzzy ideas become precise requirements before any code is generated.
The Ouroboros Interview Phase—also called the Big Bang—is the first step of the Q00/ouroboros workflow, designed to transform vague project ideas into unambiguous specifications. This phase operates through a disciplined dialogue system that combines runtime state management with strict prompt engineering to enforce Socratic methodology.
Core Architecture: The InterviewEngine
The InterviewEngine class in src/ouroboros/bigbang/interview.py orchestrates the entire process. It manages conversation state, persists data across rounds, and dynamically constructs prompts that force the LLM into a Socratic mindset.
State-Driven Round Management
An InterviewState object (defined at lines 81‑92) stores every dialogue round as an InterviewRound, tracking metadata such as initial_context, is_brownfield flags, and an ambiguity score. The engine exposes three primary methods:
start_interview(initial_context, cwd=None)– Creates a freshInterviewState. If a working directory is provided, it automatically triggers brownfield code-base exploration via_trigger_codebase_exploration.ask_next_question(state)– Builds the Socratic system prompt (_build_system_prompt) and calls the LLM through the configuredLLMAdapter.record_response(state, user_response, question)– Validates the response (usingInputValidatorfromsrc/ouroboros/core/security.py), appends a newInterviewRound, updates timestamps, and conditionally re-runs code-base exploration.
Because the engine persists state to disk through save_state and load_state, interviews survive process restarts and allow the ambiguity metric to be recomputed at any time.
Brownfield Context Injection
When state.is_brownfield is true and a code-base summary exists, the engine appends an Existing Codebase Context block to the prompt. This encourages the model to ask confirmation questions referencing exact files or patterns, such as: "I see Express.js with JWT middleware in src/auth/. Should the new feature use this?" The underlying exploration logic resides in src/ouroboros/bigbang/explore.py.
The Socratic System Prompt
The heart of the Socratic behavior lives in _build_system_prompt (lines 82‑135 of interview.py). This method dynamically assembles constraints that force the LLM to behave as an interviewer rather than an implementer.
First-Round Hard Rule
When state.current_round_number == 1, the prompt injects a hard constraint:
CRITICAL: Start your FIRST response with a DIRECT QUESTION about the project. Do NOT introduce yourself. Do NOT say "I'll conduct" or "Let me ask". Just ask a specific, clarifying question immediately.
This programmatic enforcement prevents the model from delivering preambles or making implementation promises before requirements are clarified.
Dynamic Header Construction
The method constructs a dynamic header containing the current round number and the original user context. It then concatenates this header with the static Socratic Interviewer agent prompt loaded from agents/socratic-interviewer.md. This merge guarantees that every LLM response adheres to the Socratic style while maintaining awareness of the conversation history built by _build_conversation_history.
Immutable Agent Rules
The static agent file (agents/socratic-interviewer.md, lines 3‑21) codifies the non-negotiable rules:
- Role boundary: "You are ONLY an interviewer. You gather information through questions."
- Response format: "You MUST always end with a question – never end without asking something."
- Questioning strategy: "Target the biggest source of ambiguity" and "Use ontological questions: What IS this? Root cause or symptom? What are we assuming?"
Ambiguity-Driven Question Selection
After each user answer, record_response clears any stored ambiguity snapshot via clear_stored_ambiguity. The subsequent call to ask_next_question rebuilds the full conversation history, allowing the LLM to see the entire transcript and compute remaining uncertainty.
The agent’s QUESTIONING STRATEGY section explicitly instructs the model to:
- Target the biggest source of ambiguity – e.g., "What IS this?" or "What are we assuming?"
- Build on previous responses – keeping the dialogue tight and progressive.
- Use ontological questions – distinguishing root-cause from symptom through definition-level queries.
This deterministic loop continues until the user signals completion (detected via state.is_complete or the user saying "done"), at which point complete_interview sets status = COMPLETED and logs the final round count.
Execution Paths: MCP vs. Fallback
The skills/interview/SKILL.md file defines two execution paths that both enforce the "always end with a question" rule:
MCP Mode
When the ouroboros_interview MCP tool is available (most production installs), the CLI calls this tool, which internally uses InterviewEngine exactly as described above. State persists to disk with an interview ID that later steps (ooo seed) can retrieve.
Plugin Fallback Mode
If no MCP tool is found, the CLI enters fallback mode. It reads the socratic-interviewer agent and performs a pure-agent interview, manually scanning the codebase with Glob, Read, and Grep tools and feeding results into the prompt. This path follows the same Socratic rules but does not persist state between sessions.
Practical Implementation
Running a Socratic Interview Programmatically
from pathlib import Path
from ouroboros.bigbang.interview import InterviewEngine
# 1️⃣ Initialise the engine with an LLM adapter (LiteLLMAdapter is a concrete example)
engine = InterviewEngine(
llm_adapter=LiteLLMAdapter(), # ← implements Completion API
state_dir=Path.home() / ".ouroboros" / "data"
)
# 2️⃣ Start a new interview – optionally give a cwd for brownfield detection
state_res = await engine.start_interview(
initial_context="I want a CLI task‑manager with tags and sub‑tasks",
cwd=Path.cwd()
)
state = state_res.value # InterviewState instance
# 3️⃣ Loop until the interview is marked complete
while not state.is_complete:
# Generate the next Socratic question
q_res = await engine.ask_next_question(state)
question = q_res.value
print(f"❓ {question}")
# Simulate user input (replace with real input() in a CLI)
answer = input("> ")
# Record the answer and advance state
await engine.record_response(state, answer, question)
# Persist after each round (optional, but recommended)
await engine.save_state(state)
# 4️⃣ Mark interview finished (optional, the CLI does this automatically)
await engine.complete_interview(state)
print("✅ Interview finished – you can now run `ooo seed`.")
Key points in this snippet:
start_interviewvalidates the initial context viaInputValidator(security check).ask_next_questionbuilds the Socratic system prompt (_build_system_prompt).record_responseappends anInterviewRoundand may trigger code-base exploration for brownfield projects.
Constructing the System Prompt
The _build_system_prompt method assembles the constraints programmatically:
def _build_system_prompt(self, state: InterviewState) -> str:
round_info = f"Round {state.current_round_number}"
base_prompt = load_agent_prompt("socratic-interviewer")
if state.current_round_number == 1:
dynamic_header = (
f"You are an expert requirements engineer conducting a Socratic interview.\n\n"
f"CRITICAL: Start your FIRST response with a DIRECT QUESTION about the project. "
f'Do NOT introduce yourself. Do NOT say "I\'ll conduct" or "Let me ask". '
f"Just ask a specific, clarifying question immediately.\n\n"
f"This is {round_info}. Your ONLY job is to ask questions that reduce ambiguity.\n\n"
f"Initial context: {state.initial_context}\n"
)
else:
dynamic_header = (
f"You are an expert requirements engineer conducting a Socratic interview.\n\n"
f"This is {round_info}. Your ONLY job is to ask questions that reduce ambiguity.\n\n"
f"Initial context: {state.initial_context}\n"
)
# …brownfield context injection omitted for brevity…
return f"{dynamic_header}\n{base_prompt}"
The base_prompt variable loads the immutable rules from agents/socratic-interviewer.md, ensuring the LLM never promises implementation and always ends with a question.
Agent Prompt Rules
The static agent prompt defines the Socratic mindset:
You are an expert requirements engineer conducting a Socratic interview to clarify vague ideas into actionable requirements.
## CRITICAL ROLE BOUNDARIES
- You are ONLY an interviewer. You gather information through questions.
- NEVER say "I will implement X", "Let me build", ...
## RESPONSE FORMAT
- You MUST always end with a question – never end without asking something
- Keep questions focused (1‑2 sentences)
## QUESTIONING STRATEGY
- Target the biggest source of ambiguity
- Build on previous responses
- Use ontological questions: "What IS this?", "Root cause or symptom?", "What are we assuming?"
Summary
- The InterviewEngine in
src/ouroboros/bigbang/interview.pymanages stateful, multi-round dialogues throughInterviewStateandInterviewRoundobjects. - The _build_system_prompt method enforces a hard first-round rule and always appends the static Socratic Interviewer constraints from
agents/socratic-interviewer.md. - Ambiguity-driven selection targets the biggest uncertainty in each round, clearing stored ambiguity metrics after every user response.
- Dual execution paths (MCP and fallback) guarantee Socratic behavior whether running through the managed tool or pure agent mode.
- Brownfield detection injects existing codebase context to ground questions in actual file structures rather than abstractions.
Frequently Asked Questions
What is the Interview Phase (Big Bang) in Ouroboros?
The Interview Phase is the first step of the Q00/ouroboros workflow where a specialized engine conducts a structured dialogue with the user. Its sole purpose is to convert fuzzy ideas into precise, unambiguous requirements before any code generation occurs.
How does the InterviewEngine enforce Socratic rules?
The engine enforces rules through programmatic prompt construction in _build_system_prompt. It injects a CRITICAL directive for the first round demanding an immediate question, loads immutable agent rules from agents/socratic-interviewer.md requiring every response to end with a question, and tracks conversation history to ensure questions build progressively on previous answers.
What is the difference between MCP mode and fallback mode?
MCP mode uses the ouroboros_interview tool to run the full InterviewEngine with disk persistence, allowing later commands like ooo seed to retrieve the interview ID. Fallback mode operates as a pure-agent interview without the engine's state management, manually scanning the codebase with file tools and holding the conversation in memory without persistence.
How does brownfield detection affect the interview?
When the engine detects an existing codebase (via the cwd parameter), it sets is_brownfield=true and triggers exploration logic from src/ouroboros/bigbang/explore.py. The resulting context is injected into the prompt, forcing the LLM to ask confirmation questions about specific files and patterns rather than assuming greenfield architecture.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →