Skip to content

fix(cli): callers folds in EXPOSES routes; decompose role-waterfall fixes#398

Merged
HumanBean17 merged 1 commit into
masterfrom
fix/jrag-callers-exposes-and-decompose-waterfall
Jul 7, 2026
Merged

fix(cli): callers folds in EXPOSES routes; decompose role-waterfall fixes#398
HumanBean17 merged 1 commit into
masterfrom
fix/jrag-callers-exposes-and-decompose-waterfall

Conversation

@HumanBean17

Copy link
Copy Markdown
Owner

What

Two consumer-reported gaps in the jrag CLI — 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 CALLS

A controller is an HTTP entry point: its handler methods are invoked via EXPOSES (the framework dispatches the route), not via in-repo CALLS edges. So find_callers returned an empty/unhelpful list exactly when an agent investigates a 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 — the consumer contract: «не только CALLS».

$ jrag callers ChatIngressController
root: ChatIngressController @chat-core  role=CONTROLLER  symbol_kind=class
  POST /api/v1/chat/events @chat-core

Gated on the root being a type Symbol with DECLARES.EXPOSES out-edges (covers any entry-point holder, not just role=CONTROLLER).

2. decompose role-waterfall, made adequate in practice

The 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-calls default flipped to True — the CLI silently overrode the backend's True default down to False, so the waterfall only used structural INJECTS/EXTENDS/IMPLEMENTS edges and looked single-level on codebases wired via composition. Now uses BooleanOptionalAction, so --no-follow-calls still opts out.
  • Renamed --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).
  • Renderer lists every role in a mixed stagestage 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).
stage 0 (seed):
  ChatIngressController @chat-core  role=CONTROLLER
stage 1 (component, service):
  SlaService @chat-core  role=SERVICE
  ClientMessageProcessor @chat-core  role=COMPONENT
  ...

Tests

  • test_callers_on_controller_class_surfaces_exposes_routes — e2e: callers <controller> returns EXPOSES route rows (kind=route, method+path) + the route renders in text.
  • test_decompose_renders_role_waterfall extended — 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).
  • Full suite: 1138 passed, 14 skipped. Ruff: zero new errors (3 pre-existing on master, untouched).

Out of scope

  • A 4th+ role tier (Facade/Dao layers) — the 3 tiers stay fixed; that's a _FLOW_STAGES backend redesign if a consumer actually needs it.

🤖 Generated with Claude Code

…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>
@HumanBean17 HumanBean17 merged commit 0a019c4 into master Jul 7, 2026
3 checks passed
@HumanBean17 HumanBean17 deleted the fix/jrag-callers-exposes-and-decompose-waterfall branch July 7, 2026 06:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant