Invoice
followed by object identity from the call that built it to the call that charged it.
Status
This tool is planned and does not run today. The local tools answer from recorded files
on your machine, where there is no Cypher engine, and the hosted graph is not open yet.
ra cypher is registered so that ra tools lists it, and running it reports the same status. The
rest of this page describes the design.
The problem
Each tool on this site answers one question, and some questions have no tool. Suppose
Billing::Gateway#charge started timing out last week, and you want to know which checkout paths
pass it an invoice that was built without a rate table. In the example app
Billing::Checkout#complete builds one on the fly:
invoice = order.invoice || Invoice.new(account: order.account, number: order.number, issued_on: Date.current)
what_calls gives you the callers of charge, and how_it_got_here gives you the chains that
reach it. The question also needs those chains joined to how the argument was built, filtered to the
last seven days and grouped by entry point, which neither tool does. The alternatives are to export
the recording and write a script, or to query the graph.
The design
In the hosted graph every recorded call would be a node and an edge. This is the question above in Cypher:
MATCH (entry:EntryPoint)-[:ROOT_OF]->(:Call)-[:CALLS*]->(charge:Call {method: 'Billing::Gateway#charge'})
MATCH (charge)-[:ARG]->(invoice:Object {class: 'Invoice'})
MATCH (built:Call {method: 'Invoice.new'})-[:RETURNED]->(invoice)
WHERE charge.deployed_at > datetime() - duration('P7D')
AND NOT (built)-[:ARG {name: 'rate_table'}]->()
RETURN entry.identity AS entry_point, count(*) AS calls
ORDER BY calls DESC
The schema is the same structure the other tools read from the recording today:
Callnodes, one per recorded call, with the method, the file and line, and the deploy.CALLSedges from a call to the calls it made, in order.Objectnodes for the receivers, arguments and return values, labelled by class and joined by object identity, so a value can be followed from the call that built it to every call it reached.EntryPointnodes for the spec example, request or job that started each call tree.
Over MCP your agent would write the query, run it and read the rows back.
Reading the result
- Queries would be read-only and would not change the graph.
- A query that walks every path in a busy app will be slow, so queries would run with a time limit. A query you run often is a candidate for a tool of its own.
Every tool reads the same recording. What gets recorded and how far to trust an answer are on the questions page.
Related tools
coupling_map
Coupling measured from app runs. Which modules and namespaces of your app call each other, and how many times, counted from recorded app runs.
See more →what_calls
The callers of a method. Every caller of a method in the recorded runs, with the file and line of each call and how often it was made, including calls made through public_send. what_it_calls lists the methods it calls.
See more →where_nil_comes_from
Where nil comes from. The methods that returned nil and the arguments that received nil in recorded runs, logged as NilClass and tied to the errors that followed, including nil returns that a declared return type rules out.
See more →