Trovella Wiki

Execution Loop

The end-to-end flow from plan creation through step execution to completion, including human-in-the-loop review and cross-session resume.

This page describes the full execution lifecycle of a research plan, from creation to completion. Every interaction is initiated by the AI platform (Claude Code, ChatGPT) calling MCP tools -- the server never pushes work to the client.

Phase 1: Plan Creation

The AI platform calls create_research_plan with a structured definition:

  1. Insert plan -- a research_plan row with status planning, the research question, and optional formatting notes
  2. Insert steps -- plan_step rows with sequential step_order (1-based), each starting in pending status
  3. Insert branching conditions -- plan_branching_condition rows linked to specific steps by resolving afterStepOrder to step IDs
  4. Auto-link skill execution -- if a sessionId is provided, the tool looks up the most recent started skill execution for that session and links it to the new plan by setting its planId
  5. Audit log -- writes a plan_modified event with action created

The response includes the planId, step IDs, and the first step's details so the AI platform can immediately begin execution.

Step Types

Each step has a stepType that tells the AI platform what kind of work to do:

TypePurpose
searchFind and evaluate sources
extractPull structured data from sources
analyzeInterpret data, identify patterns
critiqueEvaluate quality, identify gaps
synthesizeCombine findings into conclusions
checkpointPause for user review
customAnything not covered above

Step types are informational -- they guide the AI platform's behavior through the step instructions, not through different server-side logic.

Phase 2: Step Execution Loop

After plan creation, the AI platform enters the core execution loop.

Getting the next step

The AI platform calls get_next_step with the planId. The handler:

  1. Loads the plan and checks its status
  2. If completed -- returns { status: "plan_complete" } with formatting notes
  3. If failed -- returns { status: "plan_failed" }
  4. If awaiting_review -- returns { status: "awaiting_review" }
  5. Otherwise -- finds the first step with pending status (ordered by step_order)
  6. Transitions the step from pending to in_progress via transitionStep
  7. If the plan is in planning or stalled state, transitions it to executing via transitionPlan
  8. Writes a step_started audit log entry
  9. Returns the step's ID, order, type, and instructions

If no pending steps exist but some are in_progress or failed, the handler returns { status: "no_pending_steps" } with a count of in-progress and failed steps.

Executing the step

Between get_next_step and submit_step_result, the AI platform does the actual work. This happens entirely in the AI platform -- Trovella's server has no involvement. The AI platform may:

  • Search the web for sources
  • Call get_step_context to load prior step results and related artifacts
  • Call search_sources to query Trovella's hybrid search index
  • Call extract_data for structured extraction (the one tool that makes server-side LLM calls)
  • Call store_research to persist intermediate artifacts

Submitting results

The AI platform calls submit_step_result with the step's result data. The handler:

  1. Loads the step and validates it is in_progress (also accepts pending for timing edge cases)
  2. Transitions the step to completed
  3. Stores the resultSummary, confidence, stepExecutionReport, and outputFormattingNotes
  4. Writes a step_completed audit log entry
  5. Evaluates branching conditions for this step
  6. If a fail branch action fires, sets the plan to failed and returns immediately
  7. Otherwise, calls derivePlanStatus on all step states to determine the new plan status
  8. Updates the research_plan status and completedAt (if completed)

The AI platform then calls get_next_step again to continue the loop.

Timing edge case: pending step submission

submit_step_result accepts steps in both in_progress and pending status. This handles a race condition where the AI platform starts working on a step before the get_next_step transaction has fully committed. Rather than rejecting valid work, the handler auto-advances the step through both transitions:

if (step.status === "pending") {
  transitionStep("pending", "in_progress");
}
transitionStep("in_progress", "completed");

Phase 3: Human-in-the-Loop Review

At any point during execution, the AI platform can pause for user input.

Requesting review

The AI platform calls request_user_review with a summary and optional questions. The handler:

  1. Validates the step is in_progress (can transition to awaiting_input)
  2. Validates the plan is executing (can transition to awaiting_review)
  3. Transitions the step to awaiting_input
  4. Transitions the plan to awaiting_review
  5. Writes a user_reviewed audit log entry with action review_requested

After this, calling get_next_step returns { status: "awaiting_review" } until the user responds.

User decisions

The user responds through submit_user_decision with one of four decisions:

DecisionStep effectPlan effect
approveStep completedPlan resumes to executing
rejectStep failedPlan fails
modifyStep returns to in_progressPlan resumes to executing
skipStep skippedPlan resumes to executing

The modify decision is particularly important: it appends the user's feedback to the step's instructions (separated by a horizontal rule and "User feedback:" prefix), then returns the step to in_progress so the AI platform can re-execute it with the new guidance.

Phase 4: Plan Completion

When derivePlanStatus returns completed (all steps are in a terminal state), the plan is marked as completed. The get_next_step response includes:

  • status: "plan_complete"
  • outputMediaType -- from the linked skill execution metadata
  • outputFormattingInstructions -- from the linked skill execution metadata
  • planFormattingNotes -- from the plan's outputFormattingNotes field
  • stepFormattingNotes -- from each completed step's outputFormattingNotes field

This formatting metadata guides the AI platform in generating the final deliverable via store_research_output.

Cross-Session Resume

Plans survive session disconnects because all state is in PostgreSQL. To resume a plan from a new session:

  1. Call get_research_context with the planId -- returns the full plan context including all steps, their statuses, and prior results
  2. Call get_next_step -- if the plan was stalled, the handler transitions it back to executing; if a step was in_progress but never completed, the handler skips to the next pending step

The stalled --> executing plan transition is what enables this resume flow. See Stall Detection for how stalls are identified.

Plan Modification During Execution

The AI platform can modify plans that are in planning or executing state via modify_plan. Five modification actions are available:

ActionWhat it doesConstraint
add_stepsInserts new steps, shifting subsequent step ordersSpecify insertAfterOrder or append to end
remove_stepDeletes a step and compacts step ordersStep must be pending
reorder_stepsReassigns step orders from a provided ID sequenceProvide complete step ID list
update_step_instructionsReplaces a step's instruction textAny step status
fail_stepMarks a step as failed with a reasonStep must be pending or in_progress

Plans in awaiting_review, stalled, completed, or failed states cannot be modified.

Every modification writes a plan_modified audit log entry with the action type and an optional modificationRationale explaining why the change was made.

Audit Trail

Every state transition and mutation writes to the plan_audit_log table via writeAuditLog(). This is a hard requirement documented in packages/mcp/CLAUDE.md -- all plan/step mutations must call writeAuditLog inside the transaction, before commit.

The eight event types map to specific points in the execution loop:

Event typeWhen it fires
step_startedget_next_step transitions a step to in_progress
step_completedsubmit_step_result completes a step
step_failedA step is failed via branching or fail_step
plan_modifiedPlan created, steps added/removed/reordered, instructions updated
user_reviewedReview requested or user decision submitted
session_resumedPlan resumed from a new session
skill_startedSkill execution begins
skill_completedSkill execution finishes

In addition to the business-level audit log, every MCP tool call (except ping) is recorded in mcp_tool_call_log via the withToolCallLogging middleware. This captures request/response metadata, duration, and error flags as a fire-and-forget async write.

On this page