CodeRadius LogoCodeRadius Docs

Grounding & Trust Tiers

How CodeRadius tells you where every fact in the graph came from, what supports it, and how much to trust it. Covers the dashboard quality dot, the cr review pending triage workflow, and the diagnostic filters.

Grounding & Trust Tiers

Every node and every edge inferred by CodeRadius carries a grounding stamp answering three questions:

  • Source: who or what produced the fact (a deterministic AST walk, an LLM call, a customer-declared override).
  • Evidence: what supports it (which extractors fired, which heuristic fallbacks ran, which welders merged predecessors).
  • Quality: how much you should trust it (categorical tier: Verified, Strong, Probable, Weak, Guess).

The grounding system replaces the older "confidence percentage" model. Floats compound badly across pipeline hops, and a 0.8 from an AST extractor and a 0.8 from an LLM are not the same kind of 0.8. The categorical model surfaces why an entity is trusted (or not) without forcing operators to mentally translate probability scores.


The 5 Trust Tiers

Every inferred entity (MessageChannel, DataContainer, APIEndpoint, etc.) is stamped with one of five tiers. On the dashboard, the tier is shown as a small colored dot.

DotLabelMeaning
● greenVerifiedDirect evidence in source or contract (a decorator, an OpenAPI spec, a declared catalog entry). The strongest tier.
● light greenStrongMultiple extractors agree. Composite of static analysis + LLM confirmation.
● amberProbableSingle signal, plausible. Typically an LLM extraction that passed sanitizer guards.
● orangeWeakInferred from indirect evidence. The engine had to guess.
● redGuessNo direct evidence; surfaced only when the engine had to invent something. Treat with skepticism.

The dot color is the visual language; the label appears in the inspect drawer and the popover. Hover the dot anywhere to see the descriptive tagline.


Where You See It

Dashboard

Graph cards (the radial blast-radius view): each inferred node has a small colored dot in its bottom-right corner. Cluster supernodes show the worst quality among their members ("at least one node in this cluster is speculative").

Inspect drawer (click any node): the Grounding section reads as one line:

GROUNDING
● Verified   Static code analysis

Hover the dot for the tagline ("Direct evidence in source or contract"). Hover the source label for the longer explanation of how that extractor works.

Popover (single-click any node): same composed line in the status row.

Suppressed on structural entities

The dot is hidden by default on structural labels (Repository, Service, SourceFile, Function, Class, ...) because they are uniformly Verified by definition: they're direct AST artefacts. Showing the dot on every file and function would drown out the decision-relevant tiers on inferred entities.


The 7 Source Types

The dot tells you how much to trust; the source label tells you how the fact was established. The dashboard shows the source as a muted label next to the dot ("Static code analysis", "LLM inference", etc.).

Internal idLabelHow to read it
astStatic code analysisParsed directly from source (decorator, function signature, deterministic config walk).
heuristicNaming heuristicPattern matched (file naming, symbol convention). The weakest static signal.
llmLLM inferenceExtracted by a language model from code semantics.
compositeCross-verifiedMultiple extractors independently agreed.
declaredDeclared in catalogAsserted by coderadius.yaml or a service catalog entry.
infraInfrastructure matchConfirmed by a live infrastructure snapshot (RabbitMQ admin, K8s, Terraform).
runtimeRuntime traceObserved in production traffic (OTel span).

Operator Workflows

See the trust distribution after every sync

Every cr analyze code run prints a grounding breakdown at the end:

Grounding distribution
  MessageChannel  3 exact, 1 high, 1 medium, 0 low, 0 speculative
  DataContainer   7 exact, 4 high, 2 medium, 1 low, 0 speculative   needs-review: 1
  APIEndpoint    27 exact, 0 high, 0 medium, 0 low, 0 speculative

A needs-review count > 0 means the engine has flagged entities for human triage (see cr review pending below).

Triage flagged entities

cr review pending
cr review pending --label MessageChannel
cr review pending --quality-at-least medium --source llm

Lists every node with needsReview = true, grouped by label. Flags entities the engine wants a human to adjudicate (ambiguous welds, weak LLM-only signals with no static cross-check, sanitizer fallbacks that fired on already-shaky source).

Filters narrow the result:

  • --label <name>: restrict to a single inferred label (MessageChannel, DataContainer, ...).
  • --quality-at-least <tier>: keep only entities whose quality is at least the given tier (exact ≥ high ≥ medium ≥ low ≥ speculative).
  • --source <s>: keep only entities whose grounding source matches. Repeat the flag for multiple sources.

Nothing in the database is changed by these commands; they are read-only triage views.

Filter coverage diagnostics

The diagnostic dump accepts the same filter vocabulary:

bun run scripts/diag-graph-coverage.ts --quality-at-least high
bun run scripts/diag-graph-coverage.ts --source ast
bun run scripts/diag-graph-coverage.ts --repo my-repo --source llm

Useful queries:

  • "Show me only the entities I should trust"--quality-at-least high.
  • "Show me what the LLM inferred (so I can sanity-check it)"--source llm.
  • "Show me what came from the AST (the deterministic, high-trust baseline)"--source ast.

The output dumps every inferred node label (DataContainer, MessageChannel, APIEndpoint, Datastore, ExternalAPI) with its grounding columns alongside the existing discriminators.


What Drives the Tier?

The engine assigns quality categorically based on which pipeline path produced the fact. The matrix:

If the fact came fromSourceQuality
Pure AST extraction (provider, decorator, deterministic walk)astVerified
Static analyzer + registry hitcompositeStrong
LLM extraction with full static context in the promptcompositeStrong
LLM extraction with weak static contextllmProbable
LLM extraction surviving only sanitizer guards by exclusionllmWeak
Sanitizer applied a fallback (env-stem normalize, name promotion)(upstream)demoted one tier
Welder merged two predecessorscompositemin(predecessors)
coderadius.yaml declareddeclaredVerified
Infrastructure snapshot matchinfraVerified
Runtime trace matchruntimeVerified

Cross-source composite promotion is capped at Strong: Verified is reserved for single-source ground truth (pure AST, declared, infra, runtime). The cap prevents the engine from claiming the strongest tier just because two unrelated signals agreed.


Inspecting an Entity's Evidence

The Inspect Drawer (open by clicking any node) shows the full grounding block. The descriptive tooltip on the dot lists:

  • The tagline for the tier ("Direct evidence in source or contract").
  • The source's detail line ("Parsed directly from source: decorator, function signature, AST walk").
  • The extractor identities that contributed (symfony-messenger-php@v1, unified-analyzer@v1, ...). Each is versioned so a prompt or regex change produces a new identity, leaving stale entries queryable.

If the entity was welded from multiple predecessors, the evidence block will list the merged URNs. If a sanitizer transform fired, the applied fallback is listed (e.g. env-var-stem-normalize means the engine canonicalized acme.inventory{envSuffix}.X.Y to acme.inventory.X.Y).


FAQ

Why categorical and not a percentage?

Because a 0.8 from an AST extractor and a 0.8 from an LLM mean different things, and multiplying them along path computations produces silently-wrong math. The categorical tiers are explicit assignments per pipeline path, not derived statistics.

Can I override the tier on a specific entity?

Yes, via coderadius.yaml declaration. An entity asserted in the catalog gets source: declared, quality: Verified and overrides whatever the engine inferred.

Why is everything in my graph "Verified"?

You probably just opened the dashboard on a fresh sync of well-typed code (OpenAPI specs, decorators, AmqpConfig YAML). That's the happy path. The decision-relevant tiers (Probable, Weak, Guess) appear when the engine had to infer from ambiguous code.

Why is everything "Probable"?

The codebase exposes weak static signals (no decorators, no config files, no contracts), so the LLM is doing most of the inference. Consider declaring the canonical entities in coderadius.yaml to promote them to Verified.

The needs-review count is large. What now?

Run cr review pending to see the flagged entities and their grounding. The most common causes:

  1. The engine welded an ambiguous match.
  2. An LLM-inferred entity has no static cross-check.
  3. The defensive untagged@v1 default fired: grep evidence_extractors CONTAINS 'untagged@v1' to find them; a mutation was invoked without a grounding argument.

In all cases, you can either accept the engine's inference (no action), refine the source code so the static extractor catches it, or declare the entity in coderadius.yaml to promote it.

On this page