# Path IDs

Every request records the path it took through your app: the route,
each action and query, and each branch taken inside them. The compiler
knows every possible path, so a path can be named by a number rather
than described. You write nothing for this.

## `path`

`path` is a number that decodes against that build's graph. It uses
Ball–Larus path numbering, which gives each path without loops through a
callable its own small integer, at little cost to record.
`jadpo path <build> <path>` draws the route from the number alone, with
no recorded data.

## `path_key`

`path_key` is a hash of the stable identities on the path
([Stable identity](stable-identity.md)), so the
same path can be compared across builds: "p95 of this path since
Tuesday's deploy". An edit inside a declaration changes its key, which
is right, because the path changed.

## Loops and recursion

A `for` body records which inner paths ran, not how many times. A
recursive call records the path of its first entry.

## Where path IDs go

Both go on the root span and on every failure and fault event. A path ID
says which way a request went, not how long it took or what it carried.
Timings, the request and the response come from the trace
([The request timeline in `jadpo dev`](the-request-timeline-in-jadpo-dev.md)).

Two failures at the same line reached from different routes keep
different paths. A path also shows the branches that ran and finished
before the failure, which a stack no longer holds.

Path IDs need the compiler's graph to hold the control flow inside each
callable. Each body's ways are numbered today, and the differential run
compares the paths each test's bodies took
([How it is built](https://github.com/jadpo-dev/jadpo/blob/main/docs/compiler-runtime.md)), but no request carries a
`path` or a `path_key` yet ([What is built](built-in-services-built.md)).
