Post

That means you can hand it two versions of a schema in any of the languages it supports, and it'll computes the diff, classify whether the change is breaking, and generate a converter that turns old records into new ones.

What's even better is that adding support for a new schema language just involves writing a description of it. Nothing about the underlying engine needs to change.

The generated converter goes both directions. The forward direction turns an old record into a new one; the backward direction converts it back, recovering whatever the forward path dropped (if anything) via a side channel called a complement.

You can also ask what changed without generating a migration. Panproto classifies each diff entry as breaking or non-breaking, using the rules of the specific schema language. This classification can be run from the panproto CLI in CI to gate PRs that touch a schema before they reach review.

Very importantly, migrations are composable. You can chain v1 to v2 to v3 to v4 into a single converter that walks records all the way through. When auto-generation needs help on a particular field, you can drop in a value-level transform written in a small built-in expression language.

Everything above runs on the schema language-general graph. So the same machinery composes lenses across schema language boundaries, like OpenAPI to AsyncAPI or MongoDB to Cassandra.

The system flags what survives cleanly and what loses information when one language has no analogue for a construct in the other.

Source code in any programming language supported by treesitter also parses into the same graph format. So refactoring a Rust codebase and migrating an OpenAPI spec can be viewed as the same operation underneath.

0 reposts0 likes

This setup allows schemas to have a git-style history of their own as part of panproto's VCS. Merges work on schema structure rather than file text, so conflicts hit when two branches edit the same schema file can be surfaced in a legible way.