Skip to content

Interview ​

IMPORTANT

TL;DR: Before PRD drafting starts, LoopTroop runs a council-designed, adaptive interview that turns a vague ticket into an approved, structured requirements artifact. Downstream planning relies on that approved artifact as the authoritative record of user intent instead of carrying forward a raw chat transcript.

The interview is LoopTroop's ambiguity-removal stage. A ticket often starts as a short request, but implementation usually depends on decisions that are still missing: expected behavior, target users, constraints, edge cases, integrations, testing expectations, explicit non-goals, and what should stay out of scope.

LoopTroop resolves those decisions before specs drafting. The goal is not to preserve a long conversation. The goal is to produce a reviewable artifact that later phases can trust.

For the state-machine view, see Ticket Flow - Interview.

1. What The Interview Is For ​

The interview exists to make intent durable before expensive planning begins.

That matters because later phases intentionally use narrow, purpose-built context. LoopTroop does not want PRD drafting, beads planning, or execution to depend on every earlier conversational turn, abandoned model attempt, or half-formed idea. Instead, the approved interview becomes the planning baseline, and later phases only add extra context where the workflow explicitly requires it, such as ticket details, relevant-file scans, or AI-filled answers for skipped questions.

2. Lifecycle At A Glance ​

The interview phase has four distinct steps:

  1. Council drafting and voting create the initial question plan.
  2. Interactive answering presents adaptive batches of questions to the user.
  3. Coverage review checks whether anything important is still missing and may generate targeted follow-ups.
  4. Approval freezes the reviewed interview artifact before PRD drafting begins.

That means the interview is not a single prompt. It is a small workflow with its own drafting, user-input, coverage, and approval loop.

3. How Questions Are Designed ​

Interview planning starts with the LLM council. Each council member receives the ticket details and relevant-file scan, then independently drafts a candidate question set. When that bounded context cannot confirm a discoverable repository fact, drafting and refinement may inspect the smallest relevant repository area read-only; voting remains limited to the supplied anonymized drafts and context.

The drafted questions follow a three-part structure:

  • Foundation: problem framing, goals, constraints, target users, non-goals, and scope boundaries.
  • Structure: feature inventory, major workflows, priorities, sequencing, and dependencies between behaviors.
  • Assembly: feature-level behavior, edge cases, acceptance criteria, tests, implementation constraints, and integration details.

The council then votes on anonymized drafts using a structured rubric. The winning model refines the selected draft and produces the canonical compiled interview session used by the UI.

Each question keeps stable metadata, including:

  • id
  • phase
  • source
  • follow_up_round
  • answer_type
  • options for choice questions
  • answer state and timestamps

Stable question IDs matter because later artifacts can trace requirements back to the exact interview question that produced them.

4. Question Types And Sources ​

Questions can be:

  • free_text
  • single_choice
  • multiple_choice

For a single-choice question, the user can select an option or enter free text; choosing one clears the other. A multiple-choice answer can include a free-text note alongside its selected options.

Question sources are also explicit:

SourceMeaning
compiledPart of the original council-approved interview plan
prompt_follow_upA follow-up added while adapting the next batch after earlier answers; the UI labels these as PROM4 Follow-ups
coverage_follow_upA follow-up generated later by the coverage pass because important gaps remained
final_free_formThe last catch-all question for anything else the user wants recorded

This distinction is important because not all follow-ups mean the same thing. Some are local batch adaptation, while others are explicit coverage-driven gap checks.

5. Live Interview Session Behavior ​

The interview UI is backed by a live session snapshot as well as the final interview.yaml artifact.

During answering, LoopTroop persists:

  • the current batch
  • the full question list
  • recorded answers
  • skip state and the reason given for each skip
  • follow-up rounds
  • batch history
  • completion timestamps

This is what lets the UI show answered/skipped history, restore in-progress state, and continue the same interview across batches.

Questions are presented in adaptive batches of 1 to 3:

  • 1 for complex or high-priority questions
  • 2 for moderately related questions
  • 3 only for simple, tightly related questions

While a batch is open:

  • answers can be filled in any order
  • choice selections and free-text notes are tracked locally before submit
  • already answered or skipped questions remain visible in grouped history
  • previously recorded answers can still be edited while the ticket is in WAITING_INTERVIEW_ANSWERS
  • skipped questions can be unskipped and answered later
  • a skipped question takes an optional reason, saved with the rest of the draft; undoing the skip discards it, because it no longer explains anything

After submit, LoopTroop persists the batch into the session snapshot, updates the canonical interview state, and either prepares the next batch or advances to coverage.

Batch responses pass through the existing validation and normalization before becoming questions in the workspace. If all ordinary parsing candidates fail, LoopTroop can repair known field tags inside an explicit <INTERVIEW_BATCH> response that contains all five required root fields. It converts those fields to YAML while keeping the emitted values, question wording, choices, and commentary. For example, <batch_number>1</batch_number> becomes batch_number: 1, and a <questions> container keeps its existing YAML question list. Literal tags inside question text or code examples remain part of that text during repair, including when an otherwise complete questions container ends with the observed stray </parameter> closer. The corrected batch then uses the existing normalization, including whitespace trimming and batch/choice limits. This repair rejects conflicting fields, including question and option aliases, or ambiguous structures through the normal retry or error path. Rejected field-tag repairs identify the structural problem in validation errors. Fallback excerpts from the same tagged batch cannot discard its emitted final-batch flag or commentary; a malformed earlier wrapper cannot swallow later independent output. Ordinary YAML parsing keeps its existing behavior.

Accepted repair notices in the ticket log name the rule and affected fields. Short before/after excerpts are retained in the log entry's structured data; the visible log line does not show them. Successful structured retries are also recorded. If initial batch generation still fails, expand Technical details on the error page to inspect the captured model and exact OpenCode session and available finish and token/cache metrics. That section is collapsed by default. If stopping the session also fails, the original failure remains available as the underlying cause. See Output Normalization for the repair boundaries.

NOTE

Current behavior. Batch identity, durable claim recovery, delayed timeout fencing, and same-tick answer/skip guarding in this section describe the current implementation.

Every answer and skip submission includes the current positive batchNumber. The server loads the active batch before claiming it, so a stale tab or missing batch identity returns 400 when batchNumber is missing or invalid, while a valid but stale batch number returns 409, before mutation. Question IDs, option IDs, and skip reasons are checked against that batch before a claim is acquired. Generation and answer edits use the same durable claim, so an answer edit returns 409 while generation owns the batch. A foreign claim can be reclaimed after ordinary lease expiry (the fallback when liveness cannot be checked) or when its recorded process is proven gone; a live lease protects live, invalid, or otherwise unverified owners. The pending-stop marker is separate non-expiring safety ownership and cannot be bypassed by lease expiry. The browser uses one in-flight guard for submit and skip, sets it before the first await, and clears it in finally, so a same-tick double action cannot start both mutations.

NOTE

Current behavior. Editing a recorded answer also sends the active batchNumber. The edit takes the same claim as generation and compares the saved session before writing; stale or competing edits return 409. Interrupted follow-up generation keeps a durable in-flight marker. Recovery restores its answered snapshot only if that snapshot still matches, so a retry cannot overwrite newer answers.

If answer processing times out while the remote stop is uncertain, LoopTroop restores the durable current batch and leaves a non-expiring pending-stop marker for retry. Only a confirmed stop matching that exact marker can release the batch and promote the retry. A delayed timeout cannot promote a newer batch.

An unanswered compiled question may be refined under its existing ID when its answer type and options remain compatible. Once it has an answer, its ID, source, round, and answer controls cannot be changed, so later artifacts keep a stable link to the user's decision.

When a user mentions an existing component, behavior, path, command, limitation, or architecture detail, the live interview model may inspect the relevant repository area read-only before deciding whether the next batch needs a follow-up. It does not perform a broad survey or use repository contents to decide stakeholder intent: desired behavior, scope, priorities, preferences, and acceptance decisions remain questions for the user.

The progress counter is an estimate, not a hard promise. The current batch number is real, but the total can change because later questions may become unnecessary, be merged, be lightly split, or be replaced by targeted follow-ups.

6. Skips, Skip Reasons, Final Free-Form, And Coverage ​

Skipping is explicit and durable. A skipped question is not silently deleted and is not treated as answered.

In the final interview artifact, skipped answers remain present with answer.skipped: true and answered_by: user_skip. Later, during PRD drafting, each council model may fill those skipped answers in its own Full Answers artifact. Those AI-filled answers are marked with answered_by: ai_skip, so they remain distinguishable both from user-provided answers and from the skips they replaced.

Skip reasons ​

Every skip takes an optional reason. Nothing is blocked for lack of one and no screen asks twice, but a reason changes what the model filling that answer has to work with.

A reason is stored in two places, deliberately:

  • On the answer, as answer.skip_reason in interview.yaml. This is the current state, and it is what the interface reads back.
  • In an append-only receipt, recording who skipped the question, when, from which surface, and what the reason said at that moment. Editing a reason at the approval screen adds a new receipt; it does not rewrite the earlier one. Answering a question you had skipped adds a receipt too, so the trail stops reporting a decision you reversed.

Reasons are read by exactly one prompt. PROM10a, which fills skipped answers during PRD drafting, receives them as a separate read-only section of its prompt (not as part of the interview artifact it is asked to reproduce), so it has no field to write one back into. They are stripped from the interview everywhere else, so PRD drafting, PRD voting, interview coverage and every downstream prompt see the interview without them. Where a prompt reads a reason it is shortened to 500 characters, because forty skipped questions at the full storage limit is a great deal of prompt spent on notes.

The full trail for a ticket is visible in the Full Log under Skips.

Once the compiled interview has been answered, skipped, or made redundant, LoopTroop asks one final free-form question for anything else the user wants captured before specs drafting.

After that, the winning interview model runs coverage. Coverage checks for:

  • unresolved ambiguity
  • missing constraints
  • missing edge cases
  • missing non-goals or out-of-scope boundaries
  • inconsistent answers
  • gaps that would force PRD drafting to guess

Coverage may use the same focused read-only inspection to confirm technical facts, but it cannot infer product decisions from existing code.

The phase log separates coverage check numbers from response attempts and says when it reconnects to an existing session. Reconnecting keeps the same check number. If communication with OpenCode fails, the error names the operation and reported error; the model, exact session, and available connection code and cause remain in collapsed Technical details. Coverage timeouts also keep their captured model, session, operation, and diagnostic codes so existing recovery checks can use the available session.

If real gaps remain and the follow-up budget allows it, coverage generates targeted follow-up questions and sends the ticket back to WAITING_INTERVIEW_ANSWERS.

If coverage is clean, the interview moves to approval. A clean result means there are no unresolved gaps left to record and no follow-up questions left to ask.

If the follow-up budget is exhausted, including the deliberate 0% case, the interview still moves to approval, but the remaining gaps stay visible in the resulting artifacts instead of being hidden. In that case coverage can still report status: gaps, but it must leave follow_up_questions empty.

If the user chooses skip all, LoopTroop:

  1. preserves anything already answered, including choice questions answered by selecting an option
  2. marks every remaining unanswered question as skipped (which are answered by AI models at the beginning of the PRD phase)
  3. applies the single optional reason given for the action to every question it skipped that has no reason of its own, never overwriting one the user typed against a specific question and never reaching an earlier batch
  4. advances directly to interview approval
  5. writes a synthetic clean coverage record for audit continuity

That is intentionally different from real coverage. It is an explicit user bypass.

7. What Gets Stored ​

The final interview artifact is structured YAML, not a transcript. Its core fields are:

FieldPurpose
schema_versionArtifact schema version
ticket_idExternal ticket reference
artifactAlways interview
statusdraft or approved
generated_byWinning model, generation timestamp, and canonicalization metadata
questionsCanonical question list with per-question metadata and answers
follow_up_roundsRound-by-round follow-up history with source and question IDs
summaryGoals, constraints, non-goals, and final free-form answer
approvalHuman approval metadata

Persisted session timestamps are validated rather than repaired: updatedAt, completedAt when present, answer answeredAt or skippedAt when present, and batch-history submittedAt must be non-empty and parseable. An invalid value rejects the snapshot; LoopTroop does not invent a date.

Each question answer stores:

  • skipped
  • selected_option_ids
  • free_text
  • answered_by (user, user_skip, or ai_skip)
  • answered_at
  • skip_reason, present only when a person skipped the question and explained why

user_skip and ai_skip are deliberately different values. A person choosing to skip a question and a model filling that skip in are not the same event, and a skip reason only ever belongs to the first.

In practice, this gives LoopTroop two complementary records:

  1. a live session snapshot for the interactive Q&A workflow
  2. a canonical interview artifact for review, approval, and downstream planning

8. Approval, Editing, And Downstream Impact ​

Approval is a real gate. PRD drafting does not start until the interview is approved.

At the approval step, the user can review the artifact in:

  • a structured question-and-answer view
  • a raw YAML editor

Approval includes the SHA-256 hash of the exact raw content the user reviewed. If the stored artifact changes before approval lands, the server rejects the request with a stale-content 409 instead of approving a different version by mistake.

NOTE

Current behavior. Approval-draft baseline retention and best-effort leaving flushes in this subsection describe the current save safety behavior.

The structured editor and raw YAML editor carry the content hash they loaded with a dirty draft. Both save modes send that same baseline, so a missing baseline fails closed with HTTP 428 and a stale one returns the typed HTTP 409 conflict before the authoritative interview is changed. A successful save advances the baseline; a failed save keeps the latest text visibly unsaved and retryable. Refetching or remounting does not silently rebase local edits onto newer interview content.

When an already approved interview is edited before PRE_FLIGHT_CHECK, the save holds the ticket's durable planning claim through the write, awaited restart, and downstream invalidation. A competing live writer can receive 409 before restart work begins, and an expired holder cannot apply side effects after a successor takes over. This protects the transition without turning every request into a queue or claiming that both writers succeed.

Leaving the interview or changing tickets may start a best-effort UI-state flush. Keepalive/beacon delivery has no browser-unload guarantee. If it fails, the draft remains marked unsaved/error and follows the existing retry path; retaining it in the client cache is not confirmation of a server save.

Editing rules are intentionally strict:

  • At WAITING_INTERVIEW_APPROVAL: saving edits rewrites the interview into canonical form and clears approval state, so the updated artifact must be reviewed and approved again.
  • After approval but still before PRE_FLIGHT_CHECK: interview edits are still allowed, but saving them archives the current approved interview and any downstream PRD/beads planning attempts, invalidates stale downstream planning artifacts, saves the edited interview as the new approved version, and restarts PRD drafting from that edited baseline.
  • At PRE_FLIGHT_CHECK or later: interview edits are rejected, because execution planning is already being locked for implementation.

This behavior is why the interview is more than a form. It is the first durable planning contract in the pipeline.

9. How Later Phases Use It ​

Once approved, the interview becomes the authoritative planning artifact for the rest of the pre-implementation workflow.

The PRD phase uses it to:

  • generate per-model Full Answers artifacts, using any skip reasons the user left
  • distinguish real user answers from AI-filled skipped answers
  • draft competing PRDs
  • verify PRD coverage against the approved interview baseline

Beads planning, execution setup, coding, final testing, and pull-request generation all sit downstream of that PRD. So although the interview happens early, it is the point where vague intent becomes durable, reviewable planning input for everything that follows.

LoopTroop documentation for the current runtime.