Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Multi-Loop Orchestration

multi-loop turns an agent into a long-running mission operator.

The user states a mission — "start a company", "find the best ad campaign", "build this SaaS" — and stays hands-off. The operator (an MCP host agent like Claude Code or Codex, or the built-in CLI agent) interviews them once, wires up the capabilities the mission needs, then runs and supervises a portfolio of goal loops until the mission converges — reconfiguring budgets, schedules, runners, and capabilities along the way. multi-loop is the durable mission brain behind that operator: deterministic state, readiness gates, policy, verification, scheduling, lineage, and audit.

The Operator Model

Three roles, spelled out in docs/operator.md:

  • Principal (the user): owns the mission statement, side-effect approvals, and checkpoint decisions. Nothing else.
  • Operator (the agent): the executive director. Owns preparation, configuration, execution, and supervision of everyone and everything — the candidate loops, sub-agents, schedules, and capabilities. mission_readiness drives its prep; mission_configure and the schedule controls give it audited authority over every mutable mission setting.
  • Harness (multi-loop): owns control flow, state, budgets, leases, selection, convergence, and the audit ledger. Models provide judgement inside well-scoped roles; the harness makes it durable and accountable.

The basic execution pattern the harness generalizes is a bounded goal loop:

goal -> decompose -> execute workers -> aggregate -> review -> refine -> done

Multi-loop orchestration treats that whole loop as one executable unit inside a larger meta-loop. Instead of asking one loop to solve one bounded goal, the system launches, compares, mutates, and coordinates many loops against a broad mission.

mission
  -> intake and scope
  -> generate loop population
  -> run many candidate loops
  -> compare fitness
  -> preserve the best outputs
  -> mutate / cross over strategies
  -> launch the next generation
  -> converge on an integrated result

Progression

The reference model has three levels:

  1. Linear prompting: user gives a task, agent completes it, user gives the next task.
  2. Goal loop: user gives a goal, the harness decomposes, executes, reviews, and iterates until success.
  3. Multi-loop orchestration: user gives a mission, the meta-harness runs many goal loops inside a broader orchestration loop.
  4. Operated missions: an operator agent owns the meta-loop on the user's behalf — prep, configuration, execution, and supervision — and the user is only consulted for the mission itself, side-effect approvals, and checkpoints.

Design Principle

A multi-loop is a deterministic meta-harness, not a giant prompt.

The outer harness owns control flow, state, budgets, lineage, selection, convergence, and user checkpoints. Models provide judgement inside well-scoped roles: intake, strategy generation, loop planning, review, fitness scoring, and mutation.

Core Concept

A single-goal run answers: "Can this loop complete this goal?"

A multi-loop run answers: "Which collection of loops, strategies, and generations can make progress on this larger mission?"

Any mission that is too broad, uncertain, or high-variance for one loop can be turned into a portfolio of loop-driven experiments.

For broad missions like "start a company," no single loop should try to solve the whole mission directly. The multi-loop orchestrator should create specialized loops such as market research, customer discovery, product thesis, ad campaign experiments, brand, technical prototype, legal checklist, financial model, and launch plan. Each loop has its own success criteria, reviewer, budget, artifacts, and continuation state.

Experiments As First-Class Loops

Autoresearch is useful because it treats progress as experiments: mutate a candidate, run it under a fixed budget, score it, keep or discard it, and repeat. Multi-loop should generalize that pattern beyond code and model training.

An experiment can be any loop with:

  • A hypothesis.
  • A controlled scope.
  • A budget.
  • A runnable plan.
  • An artifact.
  • A fitness signal.
  • A keep, discard, mutate, or merge decision.

For a company mission, an ad campaign can be handled as an experiment portfolio:

  • Generate several campaign hypotheses for different audiences or promises.
  • Produce creative variants, landing page copy, targeting assumptions, and budget plans.
  • Score each campaign by expected conversion, clarity, differentiation, risk, cost, and evidence quality.
  • Mutate weak campaigns by narrowing the audience, changing the hook, changing the channel, or simplifying the offer.
  • Cross over strong pieces, such as combining the best audience insight with the best creative angle.

The same experiment model applies to product design, engineering architecture, sales scripts, research approaches, content strategies, and hiring plans.

Autonomy And Cost

Multi-loop is expected to consume many model calls and many tokens. That is not a bug; it is the point of moving from single-loop execution to long-running mission orchestration.

The harness should manage autonomy with explicit controls instead of pretending the work is cheap:

  • Mission-level budgets.
  • Per-loop budgets.
  • Generation limits.
  • Fitness thresholds.
  • User checkpoint policies.
  • Durable event logs.
  • Resume support.

The default mode should be autonomous enough to run for a long time, but visible enough that the user can inspect status, stop it, redirect it, or approve a major branch in the mission.

Operational Control Plane

Multi-loop needs a small runtime control plane around the model loops. The orchestrator should not expose every possible tool and policy in one giant prompt. It should maintain explicit registries for capabilities, schedules, policy gates, and child-loop delegation.

Capability Registry

Capabilities should be described as searchable cards, not hardcoded prompt text. Each card should include:

  • Name and description.
  • Toolset or backend required.
  • Inputs, outputs, and artifact types.
  • Availability check.
  • Cost and latency class.
  • Side-effect class: read-only, local write, external write, public publish, spend money, or message a person.
  • Verification method.

The planner can search or filter capabilities when building a portfolio. Core capabilities stay directly visible, while rare or expensive capabilities can be discovered on demand by a search/describe/call bridge. This keeps prompt size bounded while still letting missions discover browser, media generation, messaging, social, remote execution, and future MCP-style tools.

Policy Gates

Any candidate loop that can affect the outside world should pass through a policy gate before execution. Examples that should require explicit approval or a stored policy rule include:

  • Publishing, posting, uploading, or sending messages.
  • Spending money or launching paid ads.
  • Mutating remote services.
  • Deleting or replacing external assets.
  • Using credentials beyond read-only access.

Worker self-reports are not sufficient for side effects. Successful external actions should return verifiable handles such as URLs, object IDs, status codes, receipts, or absolute artifact paths, and the parent loop should verify them before reporting success.

Scheduled Missions

Long-running missions should be resumed by bounded scheduled jobs, not by a single never-ending agent process. A schedule tick should:

  • Load mission state and the latest ledger entries.
  • Run one bounded generation or maintenance step.
  • Save outputs and decisions.
  • Advance the next run time.
  • Deliver a status report only when there is something useful to report.

Scheduled mission jobs should be self-contained and non-interactive. They should not recursively create more schedules, ask clarifying questions, or send messages directly; delivery is handled by the scheduler. Script-only jobs are useful for cheap checks that decide whether an agent run is needed.

Delegation Semantics

Candidate loops can delegate internally, but delegation needs explicit limits. Default child loops should be leaves: isolated context, restricted tools, no user interaction, no memory writes, and no recursive spawning. Nested orchestration should be an opt-in role with a depth limit and a concurrency budget.

Use delegation for independent reasoning-heavy workstreams, not for single tool calls or mechanical steps. Durable work that must outlive the current turn should be scheduled instead of delegated synchronously.

Genetic Execution Model

The genetic layer gives the system a way to explore multiple possible paths instead of committing to the first plan.

  • Genome: a candidate strategy, plan, artifact set, or business thesis.
  • Population: multiple loop runs exploring different genomes in parallel.
  • Fitness: measurable score from reviewers, tests, market evidence, user preferences, cost, risk, and completeness.
  • Selection: preserve the strongest candidates and discard weak or redundant ones.
  • Mutation: change one candidate by adding constraints, trying a different audience, simplifying scope, changing implementation approach, or targeting a different distribution channel.
  • Crossover: combine useful parts from two candidates into a new candidate.
  • Generation: one outer cycle of run -> score -> select -> mutate -> rerun.

Outer Loop Phases

intake
  -> mission framing
  -> portfolio planning
  -> loop spawning
  -> loop monitoring
  -> artifact aggregation
  -> fitness review
  -> selection and mutation
  -> synthesis
  -> user checkpoint or next generation

1. Intake

Clarify only mission-changing unknowns. For "start a company," the system might ask about industry, budget, time horizon, risk tolerance, geography, skills, preferred business model, and whether the output should be a plan, prototype, or operating company scaffold.

2. Portfolio Planning

Create a portfolio of loops, not just a task list. Each loop should have a role, goal, success criteria, dependencies, budget, verification method, and expected artifact.

3. Loop Spawning

Run many candidate experiments as executable units. A candidate can be an agent run, MCP call, shell command, mock runner, manual task, or future custom backend. Some can be parallel, some gated by dependencies, and some intentionally redundant to compare alternate strategies.

4. Fitness Review

Score candidate outputs against mission-level criteria. Fitness can include quality, evidence, novelty, risk, cost, speed, user fit, test results, and compatibility with other artifacts.

5. Selection And Mutation

Keep the best candidates, merge compatible outputs, and create new loop goals from gaps or promising variants.

6. Synthesis

Produce an integrated mission artifact: an implementation, plan, company brief, research dossier, product prototype, content package, or operating roadmap.

Failure Learning

Every candidate run records a structured Outcome (multi_loop/models.py) alongside its fitness score, so the system can react to why a loop turned out the way it did, not just whether it succeeded. The rule-based RuleBasedClassifier (multi_loop/failures.py) maps signals already present on a finished run — policy blocks, timeouts, exit codes, exceptions, verification results, and output shape — onto a closed FailureClass taxonomy:

  • policy_blocked — an approval gate withheld the action.
  • tool_unavailable — a required capability was missing or unconfigured.
  • resource_exhausted — the run timed out or hit a budget cap.
  • execution_error — it crashed, raised, or exited nonzero.
  • verification_failed — it ran clean but its evidence check failed.
  • bad_output — it returned a thin or empty result.
  • strategy_error — it completed but in the wrong direction.
  • unknown — an unclassified failure.

Classification is deterministic (keeping generations reproducible) and feeds two feedback paths within a mission:

  • Cause-aware retries. The planner branches its recovery on the failure class instead of always narrowing scope: a timeout is rescoped with a raised budget, an execution error is handed the failure detail to debug, a verification failure is told to produce checkable evidence, and an unavailable tool becomes a human setup task rather than a blind retry that would just fail again (HeuristicPortfolioPlanner._plan_evolved).
  • Pitfall injection. Each Outcome carries a short, agent-readable remedy_hint. Before a loop runs, collect_pitfalls gathers the hints from earlier failures that share a capability with — or are a parent of — the current candidate, and injects the most recent few into its prompt so the spawned agent avoids the same rake.

Cross-mission lessons

The same Outcome records also feed learning across missions. The derived, rebuildable MissionIndex (multi_loop/index.py) carries an outcomes table keyed by candidate, role, exact failing capability, and failure class, plus a normalized mapping of every capability required by each candidate. When the orchestrator is given a lessons_index, it refreshes the index from JSON at the start of each generation and queries relevant_lessons for failures in other missions that share the spawning loop's role or any required capability. Those remedy hints are merged with the same-mission pitfalls (same-mission first, then the most recent cross-mission lessons, de-duplicated and capped) and injected into the loop's prompt — so a timeout that sank a campaign in one mission warns the campaign loop of the next.

Two properties keep this honest over time:

  • Recency weighting. Lessons are returned newest-first and capped, so fresh failures dominate and stale advice fades rather than piling up.
  • State-tied invalidation. A tool_unavailable lesson is dropped the moment the capability it complains about is configured again, instead of warning about a problem that no longer exists.

Cross-mission learning is opt-in at the library level (lessons_index=None leaves behaviour unchanged) and enabled by default in the real run paths — the run CLI command, MCP run_generation, and the scheduler. The failure class and remedy hint are also surfaced on the queryable candidate_finished event.

Examples

Start A Company

Mission: "Start a company."

Possible candidate loops:

  • Clarify founder constraints and target domains.
  • Research 5 market opportunities.
  • Generate 3 business theses.
  • Validate customer pain and willingness to pay.
  • Run ad campaign experiments.
  • Design an MVP scope.
  • Prototype the product.
  • Build a brand and positioning system.
  • Produce a 30-day launch plan.
  • Build a basic financial model.
  • Review legal, compliance, and operational risks.

Genetic behavior:

  • Run multiple business theses in parallel.
  • Score them by feasibility, demand, founder fit, speed to revenue, and risk.
  • Mutate weak but promising theses into narrower niches.
  • Cross over the strongest market insight with the strongest product idea.
  • Continue until one integrated company plan is strong enough to execute.

Run An Ad Campaign Portfolio

Mission: "Find and refine the best ad campaign for a product."

Possible candidate loops:

  • Define audiences and campaign hypotheses.
  • Generate hooks, offers, and creative directions.
  • Draft landing page variants.
  • Produce channel-specific copy for search, social, email, or creator outreach.
  • Score variants against user fit, differentiation, clarity, risk, and estimated cost.
  • Synthesize the winning campaign plan.

Genetic behavior:

  • Treat each campaign direction as a genome.
  • Mutate targeting, hook, offer, proof, format, or channel.
  • Cross over the strongest audience with the strongest message.
  • Preserve a lineage of discarded and winning variants so the user can see why a campaign was selected.

Build A Large Application

Mission: "Build a project management SaaS."

Possible candidate loops:

  • Requirements and user stories.
  • Data model and architecture.
  • Authentication and billing.
  • Core task board UI.
  • Collaboration and notifications.
  • Test strategy and Playwright coverage.
  • Deployment and observability.
  • Security and abuse review.

Genetic behavior:

  • Compare multiple architecture candidates.
  • Run competing UI directions.
  • Select the simplest implementation that passes verification.
  • Mutate failing components into smaller scoped loops.

Produce A Documentary Or Video Essay

Mission: "Make a YouTube documentary about a topic."

Possible candidate loops:

  • Research the story and timeline.
  • Find source clips and transcript evidence.
  • Generate competing narrative structures.
  • Draft narration.
  • Build an edit decision list.
  • Create title, thumbnail, and packaging options.
  • Review pacing, claims, and source support.

Genetic behavior:

  • Generate several narrative angles.
  • Score them by clarity, originality, evidence, and audience pull.
  • Cross over the strongest hook with the strongest evidence structure.

Scientific Or Technical Research

Mission: "Find the best approach to solve a hard technical problem."

Possible candidate loops:

  • Literature and prior-art review.
  • Prototype approach A.
  • Prototype approach B.
  • Benchmark and evaluate tradeoffs.
  • Failure-mode analysis.
  • Final recommendation and implementation plan.

Genetic behavior:

  • Treat each approach as a genome.
  • Use benchmarks and reviewer judgement as fitness.
  • Mutate the highest-potential approaches based on observed failures.

Initial Data Model Sketch

Mission
  id
  statement
  success_criteria
  clarifications
  budget
  schedule
  generations[]
  ledger[]

Generation
  index
  candidate_loops[]
  fitness_scores[]
  selected_lineage[]
  mutations[]
  synthesis

CandidateLoop
  id
  parent_ids[]
  goal
  success_criteria
  role
  dependencies[]
  budget
  required_capabilities[]
  policy_gates[]
  verification
  result
  artifacts[]
  fitness

Capability
  name
  description
  toolset_or_backend
  availability_check
  side_effect_class
  cost_class
  verification

Job
  id
  mission_id
  schedule
  next_run_at
  state
  max_generation_steps
  enabled_capabilities[]
  disabled_capabilities[]

LedgerEntry
  id
  mission_id
  generation_index
  candidate_loop_id
  event_type
  summary
  artifacts[]
  created_at

Conversational Main Loop

Onboarding is now a durable agent protocol rather than a fixed questionnaire. The user may keep talking to the same main-loop session before and after mission creation. Confirmed intent is stored in a canonical MissionDraft; model-written summaries help rebuild context but never authorize operations or replace mission state.

There are two execution modes:

  • CLI: multi-loop calls a connected OpenAI-compatible provider and runs its own bounded function-calling loop. Provider profiles store only an environment variable name, never the credential value.
  • MCP: the host (Codex, Claude, or another MCP client) is the main-loop agent. Multi-loop does not call a second LLM. It exposes deterministic session, drafting, policy, and generation state transitions to the host.

The session log is append-only and fsynced. Inbound user messages are persisted before a provider call, revisions prevent stale concurrent writes, context is bounded, and compaction retains the full transcript while saving a resumable working summary.

CLI agent flow

Connect the provider first, using an environment variable for its key:

export OPENAI_API_KEY=...
multi-loop provider connect work --kind openai --model <model-name>
multi-loop provider validate work
multi-loop agent chat --provider-id work --mission "Launch a useful service"

Use --message "..." for one non-interactive turn. The returned session_id can be resumed later:

multi-loop agent chat --session-id <session-id> --message "Continue where we stopped"

Custom or local OpenAI-compatible endpoints are supported with --kind openai_compatible --base-url http://127.0.0.1:11434/v1. Provider and session configuration live under .multi-loop/main-loop/; no Hermes, Pi, or other agent runtime is required.

MVP Runtime

The current MVP has a deterministic one-generation runtime:

  • MissionOrchestrator.create_mission(...) creates a persisted mission.
  • MissionOrchestrator.run_generation(...) plans a candidate portfolio, runs it, scores fitness, selects lineage, writes synthesis, and appends event/ledger data. The planner is genetic, not a fixed candidate count:
    • The first generation seeds three base loops (research, strategy, review), plus any mission-specific loops, plus one loop per selected capability.
    • Later generations evolve from the previous result: refine selected winners, retry failures with narrower scope, resume now-approved blocked candidates, cross over the strongest winners, and add a synthesis worker.
  • MockRunner produces deterministic local artifacts for tests and demos.
  • ShellRunner runs a configured shell command.
  • AgentCommandRunner runs an external agent CLI command with the candidate prompt on stdin.
  • Verification commands can run after a candidate and affect its success score.

Note: in the current MVP, candidate loops within a generation run sequentially, not in parallel. The parallel-population behavior described above is the design target, not yet the runtime behavior.

By default a run uses the deterministic MockRunner. To make a generation do real work, pass --runner-command: it is applied to every candidate's runner config so the shell/agent_command runners execute it. With agent_command (the default when a command is given), each candidate's self-contained prompt is piped to the command on stdin, so a real CLI agent works each candidate loop:

# real agents work each candidate loop in the generation:
python3 -m multi_loop run <mission-id> --runner-command "claude -p"
# or run a deterministic shell command per candidate:
python3 -m multi_loop run <mission-id> --runner shell --runner-command "pytest -q"
# or run each candidate through the installed Hermes CLI (Stage 1 subprocess bridge):
python3 -m multi_loop run <mission-id> --runner hermes

The hermes runner needs no command: it launches one hermes chat -q ... -Q subprocess per candidate with a bounded toolset grant (default web,file), prepends the mission's side-effect directive to the prompt, and collects evidence from the candidate's artifact directory — the files the agent actually wrote, not what it claims. Per-candidate runner_config accepts toolsets, model, and executable overrides.

Real runs are governed by two safety rails:

  • Side effects are denied by default. Every spawned agent is instructed to stay read-only and local — no merging, publishing, sending, spending, or mutating remote services. An outward action requires a recorded approval for the specific side-effecting capability used by that candidate. The legacy --allow-side-effects flag cannot bypass this scope. Approved actions must return verifiable handles.
  • Verification is authoritative. Pass --verify "<command>" (repeatable) and the command's exit code — not the runner's — decides success. This rescues a candidate that did the work but whose runner was killed (e.g. timed out before reporting), and fails one that exited cleanly but cannot prove its claimed work, so fitness reflects evidence rather than the worker's self-report.

Every grant, use, and revocation of side-effect authority is also written to a durable per-mission permission ledger (permissions.jsonl), inspectable at any time — this is what keeps hands-off operation from becoming hidden operation:

python3 -m multi_loop approve <mission-id> browser_automation --by user
python3 -m multi_loop revoke <mission-id> browser_automation --by user
python3 -m multi_loop permissions <mission-id>
# after approving the candidate's specific GitHub write capability, verify the action:
python3 -m multi_loop approve <mission-id> browser_automation --by user
python3 -m multi_loop run <mission-id> --runner-command "claude -p" \
  --verify "gh pr view 42 --json state -q .state | grep -qx MERGED"

CLI examples:

python3 -m multi_loop onboard --mission "Start a company"
python3 -m multi_loop create "Start a company" --success-criteria "Produce a launch plan"
python3 -m multi_loop run <mission-id>
python3 -m multi_loop status <mission-id>
python3 -m multi_loop list

Scheduling

Missions can carry a schedule that the tick command advances one bounded generation at a time. Supported expressions:

  • One-shot: 30m, 2h, 1d, or an ISO timestamp like 2026-07-01T09:00:00.
  • Recurring interval: every 30m, every 2h, every 1d.
  • Cron: 0 9 * * * (requires the optional croniter package; other kinds stay dependency-free).

A schedule tracks operational state (scheduled, paused, completed, error) plus the last run's outcome (last_status, last_error). Recurring runs are pre-advanced before execution (at-most-once on crash), missed runs past their catch-up grace window are fast-forwarded instead of firing a stale burst, and a recurring schedule that can no longer compute its next run is surfaced as error rather than silently disabled.

python3 -m multi_loop create "Monitor competitors" --schedule "every 1d"
python3 -m multi_loop pause <mission-id> --reason "holding for review"
python3 -m multi_loop resume <mission-id>
python3 -m multi_loop trigger <mission-id>   # mark due now
python3 -m multi_loop tick                    # run all missions that are due
python3 -m multi_loop serve --interval 60     # keep ticking until interrupted

serve is the unattended continuation path: leave it running (tmux, systemd, cron wrapper) and every scheduled mission advances one bounded generation per due tick with no session attached.

Executive Report

After every generation the orchestrator writes a user-facing report to reports/generation-<n>.md inside the mission directory, and the same report can be rendered on demand from current state:

python3 -m multi_loop report <mission-id>

It summarizes progress, evidence paths, granted/used authority, items that need the user's decision (policy-blocked candidates, failures, schedule errors), and what happens next — rendered deterministically from mission state, no LLM involved.

The legacy deterministic onboard command remains available for scripts. The interactive path is the main-loop agent:

  1. The user states the mission.
  2. The orchestrator explains relevant configured capabilities and capabilities that need setup.
  3. The user answers mission-critical questions: success criteria, time horizon, constraints, available resources, autonomy level, approval policy, schedule, and preferred tools.
  4. The orchestrator creates the mission with those clarifications saved.
  5. The first generation runs as a dry/local pass unless the user approves broader tools or external side effects.

Use this for a legacy non-interactive dry setup:

python3 -m multi_loop onboard --mission "Run a company" --defaults

Runtime state is stored under .multi-loop/runs/<mission-id>/:

  • mission.json: mission state, generations, candidates, scores, selected lineage.
  • ledger.jsonl: durable mission history.
  • events.jsonl: event stream for monitoring/debugging.
  • artifacts/: candidate outputs and generation synthesis.
  • results/: structured candidate run results.
  • .run.lock: exclusive run lease. A generation holds this lock for its whole duration, so a scheduled tick, a detached MCP run, and a manual CLI run can never produce a duplicate generation on the same mission; concurrent callers raise MissionBusy (the scheduler reports this as an already_running skip). The lock is process-held, so a crashed runner releases it automatically.

A derived SQLite index lives at .multi-loop/index.db. It is rebuilt from the JSON state on demand (the JSON files remain the source of truth) and powers cross-mission ledger/mission search and candidate lineage queries via the search and lineage commands and MCP tools.

MCP Server

multi-loop can also run as an MCP server. The MCP package is optional so the core CLI and tests stay dependency-free:

pip install -e ".[mcp]"
python3 -m multi_loop.mcp_server

If installed as a package, the console script is available too:

multi-loop-mcp

The server exposes the mission runtime directly:

  • main_loop_open, main_loop_list, main_loop_context, main_loop_pause, main_loop_resume, main_loop_record_turn, main_loop_checkpoint, and main_loop_compact provide durable host-agent sessions.
  • mission_draft_update, mission_draft_validate, and mission_confirm let the host agent scope a mission conversationally and commit it only after explicit user confirmation.
  • generation_prepare, candidate_claim, candidate_artifact_write, candidate_submit_result, and generation_finalize are the host-execution protocol. Codex can claim work, execute it with its own tools, store evidence, submit an idempotent result, and let multi-loop deterministically select and synthesize the generation. No nested model is invoked.
  • onboard builds an onboarding plan and can create the mission.
  • capability_setup_plan and capability_setup_apply drive interactive capability configuration on a draft session: plan the required config/approval changes, show them to the user, and apply them only with a confirmation_quote. capability_add_command persists a user-approved command as a brand-new capability (with its side_effect_class) and attaches it to the draft. mission_capability_setup_plan and mission_capability_setup_apply are the same plan/apply pair for an already-created mission. None of these embed credentials.
  • create_mission, mission_status, list_missions, and approve_capability manage persisted mission state.
  • mission_report renders the user-facing executive report for a mission — what the host agent should show the user instead of raw status.
  • mission_readiness is the operator's prep instrument: for a draft session or a created mission it classifies every required capability (ready, needs_setup, needs_approval, unknown) with concrete fixes, checks that scheduled missions have a real unattended runner, and returns blockers, notices, and next actions. Run it before confirming, before the first generation, and after any capability or approval change.
  • mission_configure gives the operator audited authority over every mutable mission setting after creation: success criteria, clarifications, budget, schedule (null clears it), execution profile (runner, runner command, verification, workspace, autonomy level), and the selected capability list. The mission statement and side-effect approvals are deliberately excluded; each applied patch is validated atomically and recorded as a mission_configured event plus ledger entry.
  • mission_pause, mission_resume, and mission_trigger control mission schedules over MCP, mirroring the CLI's pause/resume/trigger.
  • run_generation runs one generation. It detaches by default and returns a run_id immediately.
  • run_status, run_tail, run_result, and run_list monitor detached runs.
  • tick runs scheduled mission ticks that are currently due.
  • list_backends and doctor report local runner/capability and storage health.
  • capability_search, capability_describe, and capability_list are the on-demand discovery bridge: search returns matching capability cards, describe returns one full card (including available, requires_env, and missing_env), and list enumerates all cards. The same surface is available from the CLI via multi-loop capabilities [--search Q | --describe NAME | --available].
  • toolset_list and toolset_resolve work with named capability bundles. Toolsets compose via includes (e.g. company folds in research, outreach, and media), and resolution accepts a mix of toolset names, capability names, and all/*, returning a deduped capability list. The CLI mirrors this with multi-loop toolsets [--resolve "company,agent_loop"].
  • search and lineage query the derived SQLite index: search finds ledger entries (or mission statements with missions=true) across all missions, and lineage returns a candidate loop's ancestry. The CLI mirrors these with multi-loop search "<text>" [--missions] and multi-loop lineage <loop-id>.

Detached MCP run logs live under .multi-loop/mcp-runs/<run-id>/ with events.jsonl, status.json, and result.json. Mission state remains under .multi-loop/runs/<mission-id>/.

Mission Console (TUI)

multi-loop tui opens multi-loop's own agent environment — the product surface, not a third-party chat pointed at files:

  • Dashboard — every mission with generation progress, schedule state, and next-run time; selecting a mission renders its executive report inline.
  • Chat — the operator room. The app assembles a fresh state snapshot every turn and feeds it to the engine (codex headless with the multi-loop MCP tools), so the operator already knows the mission state; you never explain or point it anywhere. /approve <capability> and /revoke <capability> are handled locally and written straight to the permission ledger.
  • Settings — schedule, runner, and authority grants per mission.

A serve loop ticks scheduled missions inside the app: when a generation finishes, its executive report is pushed into the chat feed automatically.

pip install -e ".[tui]"
multi-loop tui

The engine is deliberately swappable: the TUI owns presentation and context assembly, the harness owns policy and durability, and codex is just inference plus tools behind the chat pane.

Codex As The Operator

With the MCP server registered in Codex, the Codex CLI (ChatGPT OAuth) is the executive-director agent: you state the mission in a codex chat, and it drives draft → confirm → capability setup → run → report through the MCP tools while multi-loop keeps ownership of policy, ledgers, and evidence.

# ~/.codex/config.toml
[mcp_servers.multi-loop]
command = "/path/to/multi-loop/.venv/bin/multi-loop-mcp"
default_tools_approval_mode = "approve"   # multi-loop's own policy gates side effects

Auto-approving the MCP call layer is safe because the harness, not the host agent, enforces the side-effect policy: outward actions still require a recorded approve_capability grant, and every grant/use/revocation lands in the permission ledger.

Program Files

The program.md idea from autoresearch maps well to multi-loop, but it should be generalized into mission operating files instead of one hardcoded research prompt.

Possible files:

  • program.md: the meta-loop operating procedure.
  • mission.md: the user's mission, clarifications, constraints, and success criteria.
  • portfolio.md: the current set of candidate loops and experiments.
  • fitness.md: scoring rubrics and thresholds.
  • capabilities/: searchable capability cards and policy metadata.
  • ledger.tsv or ledger.jsonl: durable experiment history.

These files become editable "organization code." The user and agents improve how the autonomous organization behaves by editing the program files, while the Python harness enforces the loop mechanics.

Open Design Questions

  • Should candidate runs execute in separate worktrees by default, then merge selected artifacts back into a mission workspace?
  • Should fitness be a single numeric score, a rubric object, or both?
  • How much autonomy should mutation have before asking the user?
  • Should multi-loop be exposed as a separate MCP tool, or as an extension of the existing orchestrate server?

About

Deterministic multi-loop mission orchestration harness — run, compare, and evolve many goal loops against a broad mission

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages