Dev.to AI 🤖 Ai 👁 0 📖 1 min read

Diffing OpenAPI specs taught me that 'no LLM' is a feature, not a limitation

I built a changelog generator because I got tired of release notes where an LLM invented a breaking change that didn't exist. You feed it two OpenAPI specs — base and new — and it returns a structured diff of operations,

I built a changelog generator because I got tired of release notes where an LLM invented a breaking change that didn't exist. You feed it two OpenAPI specs — base and new — and it returns a structured diff of operations, schemas, parameters, and response codes. Deterministic: same input, same output, every time.

The gotcha I hit early was spec ordering. Key order in YAML/JSON objects isn't semantic, but a naive text diff treats it as signal. Two specs that were semantically identical produced a thousand-line "changelog." I had to normalize by parsing into a canonical form — sort keys, resolve $ref pointers to their target paths, compare schemas structurally instead of textually. After that, false positives dropped to zero across a test corpus of 200 spec pairs.

The other failure was $ref cycles. Recursive data models (a tree node containing children of the same type) blew up naive resolvers with stack overflows. The fix was tracking visited (ref, path) pairs during traversal so cycles terminate instead of recursing forever.

Agents consume the output directly: machine-readable JSON for automation, human-readable Markdown for release notes. No "this might break" hedges. If it's in the diff, it changed; if it didn't change, it isn't mentioned.

I ended up packaging it as https://x402.freeq.one/tools/changelog_openapi.html

📰 Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.