Skip to main content
Six questions come up often enough to name. Each one is answered by reading a different part of the same data.

Debugging

Open the trace of the request that failed and walk it. The errored step names its exception class, and the steps around it carry the inputs they were given and the outputs they returned. A step that succeeded and returned nothing useful is as informative as the step that raised. The execution graph walks one rejected request from its trace body down to the values on its root.

Coding

Before changing a function, ask what called it. The function index holds observed caller and callee pairs per service and function name, kept for 90 days, so it outlives the traces they were derived from. Any marked function that ran has a row. The lists are observed, which is the whole claim: they name what was recorded calling that function, never everything that can.

Verification

After a change ships, read real executions of the function it touched and compare their inputs and outputs with what you expected. Reading a function’s examples returns up to five of them, as previews or as full values, each carrying the status of the attempt it names. Nothing here diffs two deployments for you. What it gives you is concrete behaviour from production to compare against, for the cases a test suite does not cover because nobody thought of them.

Performance

Inside one trace, every completed attempt carries its start as an offset from the trace’s start and its own duration, both in microseconds, so the time that went missing is attributable to a step rather than to a service. Read one trace’s steps in duration order and the slow one is named. Timings stay per request: the function index carries counts and instants, not durations, so there is no aggregate timing anywhere to read.

Understanding

A trace shows the path a request actually took, which is a different thing from the paths the code allows. Read a few traces of the same entry point and the common shape appears; the function index ranks functions by how often they were observed running, which answers how often a path runs rather than whether it can. That count counts steps once each rather than records, so a record delivered twice does not inflate it, and a slow path does not outrank a frequent one.

Testing

Test inputs are the one thing captured values hand over directly. A function’s examples carry the arguments real callers passed it, so a regression test starts from a value that occurred rather than one you invented.

For an AI agent

An AI agent reads all six answers from the same data through the MCP server’s tools, in the same order a person would: find the request, read its shape, then fetch only the values it needs. Debugging with an agent walks one rejected request through those tools, with the token cost of each call.