--explain output

Every field in the ajq explain v1 report.

--explain prints a stable plan report and exits without executing the query. It does not contact a provider or local model.

Pure-jq report

ajq explain v1
query: ".users[] | select(.active) | .name"
execution: pure-jq deterministic
deterministic: yes
model_calls: 0
backend_calls: 0
byte_reproducible: yes
stdin: ignored
FieldMeaning
queryThe query as parsed.
executionpure-jq deterministic — no semantic call sites.
deterministicyes.
model_calls / backend_calls0.
byte_reproducibleyes.
stdinignored — pure-jq explain does not read input.

Semantic report

ajq explain v1
query: ".[] | select(sem_match(.msg; \"urgent\")) | .msg"
execution: semantic split plan
deterministic: no
model_calls: input-dependent
backend_calls: input-dependent
byte_reproducible: cache-dependent
stdin: harvested for estimates
planned_call_sites: 1
semantic_predicates: 1
semantic_values: 0
estimates:
  estimate_status: available
  static_call_sites: 1
  input_frames: 1
  harvested_judgements: 3
  post_dedup_judgements: 2
  mock_judge_batches: 1
  over_harvest_bound: post_dedup_judgements == mock distinct judgements; may be a safe superset of execute-needed judgements
subgraphs:
  deterministic: jq outside semantic call sites
  semantic: 1 planned call site(s)
semantic_plan:
  - call_id: 1
    op: "sem_match"
    kind: "predicate"
    value_expr: ".msg"
    specs: ["urgent"]
    source_range: 13:38
    gated: n/a
    execution: 3-phase
    subgraph: semantic

Header fields

FieldMeaning
executionsemantic split plan — the query has semantic call sites.
deterministicno.
model_calls / backend_callsinput-dependent.
byte_reproduciblecache-dependent — deterministic phases are byte-reproducible; semantic answers depend on backend/cache state.
stdinharvested for estimates when valid stdin is used for an estimate. With --stream on a supported plan, not harvested: inline execution has no cross-frame harvest estimate and explain leaves stdin untouched.
planned_call_sitesTotal semantic call sites found in the static plan.
semantic_predicates / semantic_valuesCounts of predicate-kind and value-kind ops.

estimates block

Present when valid stdin was supplied and the mock harvest path can estimate the query.

FieldUnit / meaning
estimate_statusavailable, or unavailable with a stable reason.
static_call_sitesSemantic call sites in the static plan; not input cardinality.
input_framesNumber of input frames read for the estimate.
harvested_judgementsPre-dedup semantic judgements collected by the mock harvest pass.
post_dedup_judgementsDistinct judgements after deduplication — the estimated backend-call count before considering persistent-cache hits in a later real run.
mock_judge_batchesBackend.Judge batch invocations in the deterministic mock path.
over_harvest_boundNotes that post-dedup judgements may be a safe superset of execute-needed judgements; it never underestimates needed decisions.

semantic_plan entries

FieldMeaning
call_idDeterministic planner call-site ID.
opThe sem_* operator.
kindpredicate or value.
value_exprThe jq expression producing the judged value.
specsOrdered literal spec arguments.
source_rangeByte offsets into the desugared query for the call site, or unavailable.
gatedFor value ops: whether the result flows into a pruning gate; n/a for predicates.
executionExecution mode: 3-phase, planner-required interleaved, or user-stream-inline when --stream selects inline execution for a supported plan.
subgraphsemantic.

When estimates are unavailable

If stdin is empty or invalid, or the query uses a semantic execution shape the current executor cannot safely estimate/execute, the static plan is still printed and estimate_status is marked unavailable with a reason.

--explain --stream is intentionally unavailable without reading stdin. Its report names semantic user-stream inline, says stdin: not harvested, and includes execution_selection: user-selected --stream interleaving, inline per-uncached-judgement batching, and disabled cross-frame pre-resolve deduplication. This is a mode choice, not a change to backend/model/cache identity or the run-global call cap.

The important distinction is execution mode. sem_score in sort_by(...) and sem_norm in group_by(...) can use the three-phase placeholder path. Gated unbounded value shapes, such as select(sem_score(.review; "positivity") > 0.8), can use interleaved fallback; their estimate status is unavailable because ajq resolves values as execution reaches them rather than harvesting a complete up-front set. Standalone sem_extract and sem_redact are registered but currently fail as unsupported in three-phase execution.