# How the Ouroboros Interview Phase (Big Bang) Conducts Socratic Questioning

> Discover how the Ouroboros Interview Phase uses Socratic questioning to transform ambiguous ideas into precise requirements. Learn how this state-driven engine refines concepts before code generation.

- Repository: [Q00/ouroboros](https://github.com/Q00/ouroboros)
- Tags: how-to-guide
- Published: 2026-03-14

---

**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`](https://github.com/Q00/ouroboros/blob/main/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 fresh `InterviewState`. 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 configured `LLMAdapter`.
- **`record_response(state, user_response, question)`** – Validates the response (using `InputValidator` from [`src/ouroboros/core/security.py`](https://github.com/Q00/ouroboros/blob/main/src/ouroboros/core/security.py)), appends a new `InterviewRound`, 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`](https://github.com/Q00/ouroboros/blob/main/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`](https://github.com/Q00/ouroboros/blob/main/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`](https://github.com/Q00/ouroboros/blob/main/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`](https://github.com/Q00/ouroboros/blob/main/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:

1. **Target the biggest source of ambiguity** – e.g., "What IS this?" or "What are we assuming?"
2. **Build on previous responses** – keeping the dialogue tight and progressive.
3. **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`](https://github.com/Q00/ouroboros/blob/main/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

```python
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_interview` validates the initial context via `InputValidator` (security check).
- `ask_next_question` builds the Socratic system prompt (`_build_system_prompt`).
- `record_response` appends an `InterviewRound` and may trigger code-base exploration for brownfield projects.

### Constructing the System Prompt

The `_build_system_prompt` method assembles the constraints programmatically:

```python
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`](https://github.com/Q00/ouroboros/blob/main/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:

```markdown
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.py`](https://github.com/Q00/ouroboros/blob/main/src/ouroboros/bigbang/interview.py) manages stateful, multi-round dialogues through `InterviewState` and `InterviewRound` objects.
- The **_build_system_prompt** method enforces a hard first-round rule and always appends the static **Socratic Interviewer** constraints from [`agents/socratic-interviewer.md`](https://github.com/Q00/ouroboros/blob/main/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`](https://github.com/Q00/ouroboros/blob/main/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`](https://github.com/Q00/ouroboros/blob/main/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.