AutoRAG uses a mandatory two-tier pi-subagents workflow for document
retrieval. A configured parent model is the orchestrator and configured child
models are explorers. There is no single-agent fallback.
| Role | Model | Owns |
|---|---|---|
| Orchestrator | user-configured reasoning/high-context model | judgment, sufficiency, conflicts, freshness, timing, follow-ups, and final curation |
| Explorer | user-configured fast, high-recall model | high-recall search/read work and candidate evidence handoff |
The roles are configured independently with agents.orchestrator and
agents.explorer; each value is a { "provider": "...", "id": "..." }
object. AutoRAG does not ship a private provider default. Setup selects models
from the user's authenticated runtime or requires explicit role configuration.
The pi-subagents extension and its subagent capability are required. A
missing capability is fatal for the run; do not silently complete the request
with one agent.
autorag health checks model/provider auth and explorer subagent setup without
touching indexes. It resolves both role models, verifies credential presence,
and (unless --skip-probes is set) runs a lightweight completion probe per
role. Use it before a search to confirm that the mandatory two-tier workflow
can dispatch:
autorag health
autorag health --skip-probes # auth + model resolution only, no network probesWhen autorag search fails for a model, provider, auth, timeout, or subagent
reason, the error output includes a hint pointing to autorag health:
error: Mandatory pi-subagents extension failed to load
Run autorag health to diagnose model/provider and explorer subagent setup.
autorag status remains the model-free index-health command (corpus freshness,
BM25/MinSync readiness). It does not check models or subagent dispatch — use
autorag health for that.
The default home state is separate from workspace indexes:
~/.autorag/
├── config.json
├── memory.json
├── logs/
│ └── runs.jsonl
└── pi-agent/
├── auth.json
├── models.json
├── settings.json
└── sessions/
Config path precedence is --config > AUTORAG_CONFIG >
~/.autorag/config.json. If the home config is absent and
<cwd>/autorag.config.json exists, AutoRAG copies the legacy file to the home
path without deleting or modifying it. Workspace parsed mirrors and indexes
remain under <workspace>/.autorag. Durable Pi models, settings, and sessions
stay under ~/.autorag/pi-agent.
The orchestrator is the only agent that owns:
- relevance and evidence-quality judgment;
- deciding whether the collected evidence is sufficient;
- conflict resolution across documents, retrieval methods, and explorers;
- freshness judgment and selection of the relevant creation, publication, update, modification, or observation time;
- deciding when a document or artifact was created or modified for the answer;
- follow-up assignments and changes to the retrieval plan;
- final answer synthesis and curation.
Explorers may report signals and uncertainty, but their ranking or conclusion is never the final decision.
Explorers are high-recall retrieval and reading workers. They receive an assignment containing:
- the original query, unchanged;
- one selected retrieval method;
- multiple query variants, including exact, synonymous, identifier, and broader or narrower forms;
- the allowed scope and inherited policy constraints.
The assignment is a sentinel-wrapped JSON block (Assignment V1):
<<<AUTORAG_ASSIGNMENT_V1>>>
{"originalQuery":"<caller query verbatim>","method":"<selected retrieval method>","queryVariants":["<variant 1>","<variant 2>"]}
<<<END_AUTORAG_ASSIGNMENT_V1>>>
Required handoff: include retrievedAt.
Required handoff: include temporal metadata.
The JSON body has exactly three keys: originalQuery (the caller query
verbatim), method (the selected retrieval or discovery path), and
queryVariants (a nonempty array of query variant strings). A legacy labeled
format (Original query:, Selected retrieval method:, Query variants:)
is accepted for compatibility; the V1 sentinel format is preferred and
required for multiline or special content.
Each explorer is assigned exactly one normalized configured search root as its
cwd. The top-level subagent invocation sets agentScope: "user" and
artifacts: false exactly once for single, tasks, chain, or parallel
dispatch. Nested explorer task items omit agentScope and artifacts;
project-local .pi-subagents debug artifacts are disabled.
They search and read a large set of candidate documents. They should return weakly relevant candidates when those candidates may illuminate a conflict, missing evidence, or an alternate time interpretation. They do not decide whether the overall answer is sufficient, settle conflicts, make the final freshness judgment, assign more work, or produce the caller-facing answer.
Read-only read/grep/find/ls exploration runs inside the luna child
process. BM25, MinSync, Jikji, and datasource methods are AutoRAG
process-bound tools because they close over the live indexes, policy gates, and
trusted datasource context. The sol orchestrator invokes those retrieval tools
only to build a bounded seed pack, then delegates the seed paths/results,
unchanged original query, and query variants to a luna explorer. The explorer
reads the underlying documents broadly and returns the evidence handoff. Seed
retrieval does not permit the orchestrator to skip delegation, read the
documents, or make a final answer without explorer evidence.
Each explorer returns candidate findings with enough detail for the orchestrator to make an independent decision:
original_query: the unchanged caller query
retrieval_method: the selected method
query_variants: every variant actually tried
candidates:
- source: real file path or authorized datasource id
relevance: strong | moderate | weak
evidence: excerpts or structured facts with location context
retrievedAt: when this candidate was retrieved
temporal_metadata:
created_at: when available
published_at: when available
updated_at: when available
modified_at: when available
observed_at: when the value was observed
asOf: source as-of time when available, otherwise explicit unknown
temporal_basis: which timestamp supports the finding
uncertainty: missing, ambiguous, or conflicting metadata
The fields are a handoff contract, not permission for an explorer to infer a missing date. Preserve the source and method so the orchestrator can compare results and record feedback accurately.
An explorer may report an unknown temporal value, but it must not manufacture
one from retrievedAt. The orchestrator decides which creation/modification
timing and freshness interpretation is relevant to the caller.
- The orchestrator checks memory and chooses one or more retrieval methods.
- For process-bound methods, it creates a bounded seed pack with the selected AutoRAG retrieval tool; for read/grep/find/ls it delegates discovery directly.
- It dispatches
gpt-5.6-lunaexplorers throughpi-subagents, passing the original query, selected method, multiple query variants, and any seed pack. - Explorers search and read broadly, then return strong, moderate, and weak candidates with evidence and temporal metadata.
- The orchestrator compares candidates, resolves conflicts, evaluates sufficiency and freshness, and assigns follow-ups when gaps remain.
- Only the orchestrator performs final curation and calls
emit_autorag_resultsexactly once as the final action.
If the extension cannot dispatch explorers, the run is blocked/degraded. Do not silently replace the two-tier workflow with a single-agent search.
The canonical single-root and multi-root dispatch payloads set
agentScope: "user" and artifacts: false exactly once at the top level.
Each executable leaf carries agent: "autorag-explorer", the configured
explorer model, an explicit cwd set to one allowed root, and a task
containing an Assignment V1 block.
Single-root dispatch:
{
"agentScope": "user",
"artifacts": false,
"agent": "autorag-explorer",
"model": "<configured-model>",
"cwd": "<allowed-root>",
"task": "<Assignment V1 block>"
}Multi-root dispatch (one task per configured root):
{
"agentScope": "user",
"artifacts": false,
"tasks": [
{
"agent": "autorag-explorer",
"model": "<configured-model>",
"cwd": "<allowed-root>",
"task": "<Assignment V1 block>"
}
]
}Missing or null top-level artifacts, agentScope, and leaf model fields
are autofilled before validation: artifacts to false, agentScope to
"user", and leaf model to the configured explorer model. This reduces
retry cascades from safe envelope omissions. Explicit wrong values
(artifacts: true, agentScope: "project", a non-configured model) remain
rejected. Diagnostics (list, get, models, status, doctor) are
separate from launch dispatch and never receive these defaults. There is no
single-agent fallback.
- Nested
artifacts/agentScopeon task items — these fields are set only once at the top level and are never injected into leaves; nested presence is rejected as malformed. - Wrong root (
cwdoutside configured roots) — every executable leafcwdmust be one of the configured search roots; paths outside the allowed roots or with symlink escape are rejected. - Wrong agent (not
autorag-explorer) — every executable leafagentmust be exactly"autorag-explorer". - Explicit unsafe values —
artifacts: true,agentScope: "project", or a non-configured model are rejected even though their missing/null counterparts are safely autofilled.
Only the gpt-5.6-sol orchestrator may turn explorer handoffs into the
caller-facing answer. It must preserve source, method, evidence, and temporal
metadata in the curated mapping, then call emit_autorag_results exactly once
as its final action. Explorers never call the terminating tool, and no
assistant-prose answer follows it.
The subagent workflow does not change retrieval policy:
- When Jikji is configured,
jikji_findremains the first local-discovery action. Explorers must honoranswer_paths,agent_should_not_rerank,handoff_action, andtool_call_policy. Rawread/grep/find/lsdiscovery is permitted only when the answer-pack allows the fallback after the required retry, or when Jikji is unavailable/unconfigured. - Datasource access remains default-deny and server-bound. Explorers cannot
grant themselves
allowedTagsorallowedScopes;scopemay only narrow trusted access. Datasource results are filtered before merge. emit_autorag_resultsremains the structured terminating tool. Explorers return evidence to the orchestrator and never call it.
When a dispatch is rejected, AutoRAG emits a stable error code, the failing
field path, and a one-line exactFix string. The error format is:
[<CODE>] field=<field> fix=<exactFix>
<selected skeleton>
forceCorrectable marks whether the caller can retry with the fix applied.
Non-correctable codes (ADMIN_MUTATION_FORBIDDEN, CONTROL_FORBIDDEN,
SCHEDULE_FORBIDDEN, AGENT_IDENTITY, CWD_OUTSIDE_ROOTS,
NO_ACTIVE_QUERY) require a structurally different request or an active
search context. Canonical role lines (retrievedAt, temporal metadata) are
normalized idempotently by ensureRoleLines rather than rejected — no
role-metadata rejection code exists in the catalog.
| Code | exactFix | forceCorrectable |
|---|---|---|
DISPATCH_MALFORMED |
remove fields not owned by this action | yes |
DISPATCH_ACTION_UNKNOWN |
use list|get|models|status|doctor or a supported launch shape | yes |
DISPATCH_ADMIN_MUTATION_FORBIDDEN |
do not mutate subagent definitions during AutoRAG search | no |
DISPATCH_CONTROL_FORBIDDEN |
launch a fresh autorag-explorer assignment instead of controlling an existing run | no |
DISPATCH_SCHEDULE_FORBIDDEN |
dispatch autorag-explorer work immediately; scheduling is disabled | no |
DISPATCH_ARTIFACTS_INVALID |
set args.artifacts = false | yes |
DISPATCH_AGENT_SCOPE_INVALID |
set args.agentScope = "user" | yes |
DISPATCH_AGENT_IDENTITY |
set every executable leaf agent = "autorag-explorer" | no |
DISPATCH_MODEL_MISMATCH |
set the referenced model field to the configured explorer model | yes |
DISPATCH_ASSIGNMENT_INVALID |
replace the task assignment with the canonical AUTORAG_ASSIGNMENT_V1 block | yes |
DISPATCH_QUERY_MISMATCH |
set originalQuery to the active user query verbatim | yes |
DISPATCH_CWD_MISSING |
set each executable leaf cwd to one configured search root | yes |
DISPATCH_CWD_OUTSIDE_ROOTS |
use a configured search root without symlink escape | no |
DISPATCH_NO_ACTIVE_QUERY |
dispatch only while an AutoRAG search query is active | no |
Diagnostics (list, get, models, status, doctor) bypass the
assignment, root, and model launch gates. They never receive artifacts,
agentScope, or model defaults. Control, mutation, and scheduling actions are
forbidden regardless of payload.
Prompt tests should assert the role split and handoff fields as parsed contract signals rather than snapshotting the full prompt. The RED-GREEN cases cover:
- mandatory
pi-subagentsand fatal missing-capability behavior; - exclusive
gpt-5.6-soldecisions andgpt-5.6-lunasearch/read work; - original query, selected method, multiple variants, weak candidates,
evidence,
retrievedAt, andasOf/unknown metadata; - unchanged Jikji, datasource trust, and exactly-once
emit_autorag_resultstermination rules.