fix(cli): callers folds in EXPOSES routes; decompose role-waterfall fixes#398
Merged
HumanBean17 merged 1 commit intoJul 7, 2026
Merged
Conversation
…ixes
Two consumer-reported gaps in the `jrag` CLI, both CLI-layer wiring fixes
over a backend that already had the capability (no ontology bump / re-index).
1. `callers <Controller>` now surfaces the routes its methods EXPOSE.
A controller is an HTTP entry point invoked via EXPOSES, not via in-repo
CALLS edges, so find_callers returned an empty/unhelpful list exactly
when the agent is investigating the controller. The 2-hop
DECLARES->EXPOSES traversal (member_edge_traversal_for) already existed
for inspect/neighbors; callers now folds those routes in as additive
EXPOSES rows alongside any CALLS-in edges ("not only CALLS").
2. `decompose` role-waterfall made adequate in practice:
- Flip `--follow-calls` CLI default to True (it was False, while the
trace_flow backend default is True) so all 3 tiers actually populate
via CALLS top-up instead of looking single-level on codebases wired
via composition. Uses BooleanOptionalAction so --no-follow-calls opts out.
- Rename the misleading `--max-stage` -> `--per-stage-limit`: it caps
symbols per stage, not stage count (the 3 role tiers stay fixed).
- Renderer lists every role in a mixed stage, e.g.
`stage 1 (service, component):` instead of dropping the label on its
busiest stage.
Tests: callers-on-controller e2e (asserts EXPOSES route rows + text);
decompose e2e extended to assert the mixed-role stage header; a synthetic
3-stage renderer test pins the 3rd role tier the bank-chat fixture can't
exercise (it has no REPOSITORY/MAPPER symbols). Docs + shipped mirrors updated.
Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Two consumer-reported gaps in the
jragCLI — both CLI-layer wiring fixes over a backend that already had the capability. No ontology bump, no re-index.1.
callers <Controller>now shows EXPOSES routes, not only CALLSA controller is an HTTP entry point: its handler methods are invoked via
EXPOSES(the framework dispatches the route), not via in-repoCALLSedges. Sofind_callersreturned an empty/unhelpful list exactly when an agent investigates a controller. The 2-hopDECLARES→EXPOSEStraversal (member_edge_traversal_for) already existed forinspect/neighbors;callersnow folds those routes in as additiveEXPOSESrows alongside any CALLS-in edges — the consumer contract: «не только CALLS».Gated on the root being a type Symbol with
DECLARES.EXPOSESout-edges (covers any entry-point holder, not justrole=CONTROLLER).2.
decomposerole-waterfall, made adequate in practiceThe backend (
trace_flow) already runs a real 3-tier role-waterfall (CONTROLLER → SERVICE/COMPONENT → CLIENT/REPOSITORY/MAPPER). It felt broken for three concrete reasons, all fixed:--follow-callsdefault flipped toTrue— the CLI silently overrode the backend'sTruedefault down toFalse, so the waterfall only used structuralINJECTS/EXTENDS/IMPLEMENTSedges and looked single-level on codebases wired via composition. Now usesBooleanOptionalAction, so--no-follow-callsstill opts out.--max-stage→--per-stage-limit— it caps symbols per stage, not stage count (the name read as a stage-count knob, which is the opposite of what agents tuning it for depth expected).stage 1 (service, component):instead of dropping the role label on its busiest stage (the role allow-list is the whole point of a role-waterfall).Tests
test_callers_on_controller_class_surfaces_exposes_routes— e2e:callers <controller>returnsEXPOSESroute rows (kind=route, method+path) + the route renders in text.test_decompose_renders_role_waterfallextended — asserts the mixed-role stage header (stage 1 (...)) renders.test_render_decompose_multistage_waterfall_lists_all_roles— synthetic 3-stage envelope pins the 3rd role tier (stage 2 (repository, client):) the bank-chat fixture can't exercise (it has no REPOSITORY/MAPPER symbols).Out of scope
_FLOW_STAGESbackend redesign if a consumer actually needs it.🤖 Generated with Claude Code