Every table on this page is the output of one glia command over examples-glia, a storefront that grew up beside its API: web (Angular), admin (a GraphQL console), api (Go: REST, GraphQL, a WebSocket hub, NATS order events) and contracts (the Solidity escrow orders settle through). Nothing was edited; columns were dropped where a row had many. The raw JSON of every answer sits beside this page in examples/.
The surprise is every place it taught me to hone my skill at chasing the thing perfected in my head. It shows the pile of implementations that are missing. It takes a few repos that were never one thing, links them into one app, and lets an agent run every unit and integration test across all of them, as if they always had been. It caught the storefront reading a field the API never sends, before anyone ran it.
The first two questions on an unknown repo. Services are keyed by project root; each link is one mechanism with the channel it crosses and the resolver's confidence in the pairing.
| from | to | mechanism | channel | confidence |
|---|---|---|---|---|
| web | api | HTTP_CALLS | GET /api/orders | medium |
| web | api | HTTP_CALLS | POST /api/orders | medium |
| web | api | HTTP_CALLS | PATCH /api/orders/${…}/status | medium |
| web | api | WS_CONNECTS | /live/orders | medium |
| web | contracts | RPC_CALLS | abi:ESCROW_ABI.deposit | medium |
| admin | api | HTTP_CALLS | POST /graphql | strong |
| admin | api | GRAPHQL_CALLS | Restock | medium |
| admin | api | GRAPHQL_CALLS | StockList | medium |
| api | contracts | RPC_CALLS | recv:escrow.release | weak |
GET routes left out. The Go call into the contract pairs by a name hint, so it is weak: a rule violation through that edge would be advisory, never blocking.| entry | kind | reach | mechanisms | file:line |
|---|---|---|---|---|
| GET /api/orders @api | ROUTE | 3 | HANDLED_BY, CALLS, USES | handlers/orders.go:26 |
| POST /api/orders @api | ROUTE | 6 | HANDLED_BY, CALLS, USES | handlers/orders.go:28 |
| evm:Escrow.deposit | RPC_PROCEDURE | 2 | HANDLED_BY, EVENT_FLOWS | contracts/Escrow.sol:21 |
| evm:Escrow.release | RPC_PROCEDURE | 2 | HANDLED_BY, EVENT_FLOWS | contracts/Escrow.sol:27 |
| evm:Escrow.seller | RPC_PROCEDURE | 1 | HANDLED_BY | contracts/Escrow.sol:11 |
--features groups them by the feature word trace takes.Order model affect?A seed, a walk over the carry edges, every reached node with its depth. The Go struct and the TypeScript interface form one identity class, so the walk crosses from the API into the storefront without a guess. Then: which tests cover the handler, and what does it write outside the process?
| depth | kind | node | file:line |
|---|---|---|---|
| 1 | METHOD | handlers::orders::Orders::Place | api/internal/handlers/orders.go:45 |
| 1 | METHOD | handlers::orders::Orders::ChangeStatus | api/internal/handlers/orders.go:61 |
| 1 | METHOD | handlers::orders::Orders::List | api/internal/handlers/orders.go:32 |
| 1 | METHOD | handlers::orders::Orders::Get | api/internal/handlers/orders.go:36 |
| 2 | METHOD | store::memory::Memory::Order | api/internal/store/memory.go:31 |
| 2 | METHOD | live::hub::Hub::Broadcast | api/internal/live/hub.go:32 |
| 2 | METHOD | store::memory::Memory::Orders | api/internal/store/memory.go:19 |
| 2 | ROUTE | GET /api/orders @api | api/internal/handlers/orders.go:26 |
| 2 | METHOD | events::publisher::Publisher::OrderPlaced | api/internal/events/publisher.go:22 |
| 2 | ROUTE | GET /api/orders/:id @api | api/internal/handlers/orders.go:27 |
| 2 | METHOD | store::memory::Memory::SaveOrder | api/internal/store/memory.go:38 |
| 2 | ROUTE | POST /api/orders @api | api/internal/handlers/orders.go:28 |
| 2 | STRUCT | models::order::PlaceOrderRequest | api/internal/models/order.go:30 |
glia history sync) the rows reorder by co-change first and the answer gains a files table; this demo repo has one commit, so the structural order stands. Watch the walk.| test | kind | reason | tier | file |
|---|---|---|---|---|
| handlers::orders_test | MODULE | module_tests_edge | heuristic | handlers/orders_test.go:1 |
Place directly, so the method is listed under untested too. With a test-report ingest the rows rank by recent failures.| class | sink | depth | via | tier |
|---|---|---|---|---|
| queue_produce | queue_producer:unresolved:nats | 2 | Place → OrderPlaced (orders.go:56) → publisher.go:24 | derived |
Distinct ranked paths from a seed. A path that leaves the process (a queue, a WebSocket, an external host) ranks first, since that is where a change stops being local. Then the two one-row questions every agent asks: who serves this, and what does this stack frame point at?
| path | depth | edge | to | kind | file:line |
|---|---|---|---|---|---|
| 1 | 1 | handled_by | Orders::Place | METHOD | handlers/orders.go:45 |
| 1 | 2 | calls | Publisher::OrderPlaced | METHOD | events/publisher.go:22 |
| 1 | 3 | uses | queue_producer:unresolved:nats | QUEUE_PRODUCER | events/publisher.go:32 |
| 2 | 2 | calls | handlers::orders::newID | FUNCTION | handlers/orders.go:77 |
| 3 | 2 | calls | Hub::Broadcast | METHOD | live/hub.go:32 |
| 4 | 2 | calls | Memory::SaveOrder | METHOD | store/memory.go:38 |
unresolved:nats tag anchored at its site rather than a guessed topic; gaps lists it below.| route | live | match | handler | file:line |
|---|---|---|---|---|
| POST /api/orders @api | yes | route_prefix | Orders::Place | handlers/orders.go:45 |
| node | kind | score | live | file:line |
|---|---|---|---|---|
| handlers::orders::Orders::Place | METHOD | 0.59 | yes | handlers/orders.go:45 |
resolve takes a signal: a stack trace, a failing test id, a diff, a file:line. find takes a name.No OpenAPI document in this repo. The Go struct's encoding/json names and the TypeScript interface the Angular service reads were paired across the exchange, then compared field by field. The identity report lists every such pairing, and why shows the evidence of one.
| pairing | exchange | field | producer | consumer | rule | breaking |
|---|---|---|---|---|---|---|
| http_model | GET /api/orders response | [].customerName | — | string | json_field_missing | yes |
| http_model | GET /api/orders response | [].customer_name | string | — | json_field_unread | no |
| http_model | GET /api/orders response | [].discountCode | — | string | json_field_optional_absent | no |
| graphql_selection | mutation Restock | selection against schema type Product | identical | no | ||
api/internal/models/order.go:20, the consumer web/src/app/core/models/order.ts:9. The same comparison runs against a git revision in contract-breaks and in the PR report review.| class | rule | members | diverged |
|---|---|---|---|
| Order | http_model | api STRUCT order.go:20 · web INTERFACE order.ts:9 | yes |
| OrderLine | http_model | api STRUCT order.go:14 · web INTERFACE order.ts:3 | no |
| PlaceOrderRequest | http_model | api STRUCT order.go:30 · web INTERFACE NewOrder order.ts:19 | yes |
{ "category": "SAME_AS", "tier": "derived",
"emitter": "resolver:models", "rule": "http_model/diverged",
"basis": "site",
"site": { "file": "web/src/app/core/services/order.service.ts", "line": 15 } }
HttpClient call: the one line that ties the interface to the exchange, and so to the Go struct.Three reports. gaps is what glia could not pair and what looks dead, each row with the overlay section that could repair it. hubs ranks structural load. communities is a Leiden clustering over the carry edges, a heuristic by construction.
| category | node | detail | suggest | tier | file:line |
|---|---|---|---|---|---|
| tag_only_queue | queue_producer:unresolved:nats @api | topic unreadable; owner Publisher::OrderPlaced | constants | wrapper | fact | events/publisher.go:24 |
| dead_symbol | admin::src::inventory::lowStock | no entrypoint reaches it; no incoming call or use | entrypoints | heuristic | admin/src/inventory.ts:5 |
| dead_symbol | admin::src::inventory::restock | no entrypoint reaches it; no incoming call or use | entrypoints | heuristic | admin/src/inventory.ts:10 |
| dead_symbol | api::internal::chain::escrow::Dial | no entrypoint reaches it; no incoming call or use | entrypoints | heuristic | api/internal/chain/escrow.go:18 |
| list | node | label | in | out | authority | file:line |
|---|---|---|---|---|---|---|
| fan-in | models::order::Order | utility | 5 | 0 | 0.75 | models/order.go:20 |
| fan-out | cmd::server::main::main | orchestrator | 0 | 10 | 0.00 | cmd/server/main.go:18 |
main that wires everything up; no cross-service connector above the p99 degree in a repo this small.| id | label | size | cohesion | kinds | top member |
|---|---|---|---|---|---|
| 0 | api | 37 | 0.80 | FUNCTION 11 · MODULE 11 · STRUCT 7 · METHOD 4 | cmd::server::main::main |
Datalog over the built graph, with a prelude of predicates for the code domain. Every row carries a tier and the coverage caveats of what a negation read. Here: every route no handler serves.
| predicate | R | kind | tier | file:line |
|---|---|---|---|---|
| unhandled | GET /boom @api | ROUTE | fact | api/internal/handlers/orders_test.go:17 |
HANDLED_BY, how Go route prefixes fold), so "no handler" is a claim with a stated scope. The same language writes a rule in .glia/overlay.toml that check and review gate on.An empty answer is never silent. It is a fact-tier reason, the nodes it might have meant, and the caveats of every mechanism the question depended on.
{ "absence": { "tier": "FACT", "reason": "unknown_symbol",
"note": "no node has the qname or name `POST /orders` in this graph",
"suggestions": [ "POST /api/orders @api", "endpoint:POST:/api/orders @web" ],
"nodes_searched": 178, "unparsed_files": 0 } }
{ "absence": { "tier": "FACT", "reason": "no_edges",
"note": "no DOCUMENTS edge reaches `api::internal::models::order::Order`",
"mechanisms": [ "DOCUMENTS" ],
"caveats": [ { "edge_category": "DOCUMENTS",
"note": "repo markdown is ingested only from: the well-known files …, a docs/ tree …;
a section DOCUMENTS a symbol only when it names it in a single-backtick span",
"verify": "grep the symbol name across the repo's markdown" } ] } }