Use the standard SQL WITH RECURSIVE form against the lineage table:
WITH RECURSIVE chain(did, parent, depth) AS (
SELECT did, parent, 0
FROM lineage
WHERE did = 'did:oas:l1fe:agent:web-research@3.4.0'
UNION ALL
SELECT l.did, l.parent, chain.depth + 1
FROM lineage l, chain
WHERE l.did = chain.parent AND chain.depth < 16
)
SELECT * FROM chain ORDER BY depth;
Or use the LINEAGE() function
SELECT *
FROM LINEAGE('did:oas:l1fe:agent:web-research@3.4.0', 16);
The function returns (did, parent, depth, signed_at) rows ordered by
ascending depth. Equivalent to the CTE above, but shorter.
Bound the depth
Always bound recursion. depth < 16 is a reasonable default; chains
deeper than ~10 are extremely rare in practice.