Skip to content
RAGRAF

The 22 operations: full facade reference

Every operation — purpose, key flags, what the result contains and which limits it declares. The answer envelope and reading rules.

How the contract works #

All operations are available three ways: the Python facade (op_), the CLI (ragraf query …) and MCP tools (ragraf_, 23 of them — list_capabilities additionally exposes the mode). Every answer is an envelope of a single format:

JSON
{
  "op": "impact", "index_rev": "rev-0016", "capability": "full",
  "drift": {"files": 0, "symbols": 0, "entries": 0},
  "provenance": "index",
  "limits": ["static analysis; dynamics not covered"],
  "stale_warnings": [],
  "result": [ ... ]
}

Reading rules: limits are declared always (their absence is a bug, not luck); stale_warnings populate automatically from the drift ledger; capability: degraded means the CPG layer is unavailable and slice will refuse; CLI exit codes: 0 success · 1 arguments/corpus · 2 internal error · 3 "operation impossible in this state".

Operations by group #

OperationWhat it doesKey flagsLimits
symbolsymbol definition by name/FQN: file:line, signature, kind, provenance--name, --kind, --scope, --limit, --live, --reasonambiguous name → multiple facts; dynamic declarations not covered
referenceswhere a symbol is mentioned (incl. string FQN mentions)--name, --exclude-definition, --limitstring mentions ≠ calls — separated in output
callersincoming calls of a symbol--name, --mode hard|all, --limithard — stated edges only; dynamics (call_user_func) — separate block in all
calleesoutgoing callssamesame
memberscomposition of a class/module--name—
impacttransitive change impact (BFS over the graph)--name, --depth, --mode, --limitdynamic paths marked derived; depth capped by config
sliceinterprocedural slice (Joern CPG)--name, --direction, --depthcapability=full only; under degraded — refusal with reason
live_readdirect file read bypassing the index--path, --from, --toalways available; result provenance: live
live_grepregex search over the tree bypassing the index--pattern, --globalways available
searchhybrid search (FTS5 BM25 + vectors)--query, --top, --with-text, --modesemantics bounded by the 384d model; --with-text returns fragments in one call
codechunk text by entry ids--entry-ids—

Data schema (DB) #

OperationWhat it doesLimits
schematables/columns/FKs from migrations and information_schemaschema facts have no path:line — M6 verifiability does not count them (an honest 24.4% instead of 100%)
table_usagewhere a table is read/written in codebinding via SQL literals; dynamically built SQL not covered
write_checkvalidates a write plan (table+columns) against the schema before executionreturns nearest-name suggestions on a column typo; does not check business rules
column_usageusages of a columnlike table_usage
data_flow (schema)data flow table→codestatic, via SQL literals

Routes and policies #

OperationWhat it doesLimits
routesweb routes (path→handler) from config/annotationscoverage depends on the project's route parser
policy_traceaccess-rights trace: route→middleware→role checkstatic tracing; runtime ACL configuration is not executed

State and metrics #

OperationWhat it does
statusrevision summary: files, nodes, edges, chunks, capability, stage timings
healthself-diagnosis: store files, schemas, degradations
index_statusdetailed indexing and ledger state
reindexexplicit revision rebuild with ledger archiving
drift_reportthe "what changed in the knowledge" report from the ledger/archive
usage_statscall telemetry: by operation, facts, spans, tokens
selftestreport on 9 mandatory + 2 optional components (always exit 0 — it is a report, not a gate)
The exact composition of the 22 facade operations may differ slightly from the pedagogical grouping above — the source of truth is src/ragraf/facade.py and docs/operations.md in the repository. Grouping here: navigation (11), schema (5), routes/policies (2), state (7) ≈ 22, plus 3 service CLI operations (status/health/selftest also live as top-level commands).

Result anatomy: provenance in action #

A real callers --mode all output shape for dynamic PHP:

Text
stated (proven by the graph):
  z_agr_audit_log  ← Workflow.php:210  (edge_uid 3f2a…)
  z_agr_audit_log  ← DocRoute.php:88   (edge_uid 91bc…)
derived (heuristic, separately):
  z_agr_audit_log  ← call_user_func in hooks.php:44  confidence 0.60
  → requires verification via live_read

The two blocks never mix. The takeaway for the agent: stated can be relied on; derived is a list of places to open (live_read) and verify by eye/model.

What operations do NOT do #

  • They do not write or patch code (RAGRAF answers — the agent edits).
  • They do not execute SQL or connect to a DB (schema comes from migrations and read-only information_schema).
  • They do not touch the network (the product's only network traffic is dependency installation and the one-time embedding model download).
  • They do not allow arbitrary graph queries (principle P4 — see problem space).

Limits and output safety #

Every operation carries explicit --limit flags (protecting the agent's context from blowup) and global caps from the corpus config. Answers never contain secret values: secrets_exclude files are not indexed at all, and telemetry stores argument hashes.


Related: CLI reference → · corpus configuration → · reading the envelope in the agent regimen →