Serialize to canonical pretty JSON: every object key is emitted in
alphabetical order and the graph nodes / edges arrays are sorted by a
stable key (id for nodes; from, to, kind for edges). This makes the
output byte-stable for unchanged input — re-running the analysis never
reorders keys (e.g. from HashMap iteration order) or array entries.