Currently all codegen targets (Swift, TypeScript, wire) independently walk raw facet Shapes to generate encode/decode logic. This means each target independently re-derives decisions like is_bytes, named vs anonymous types, transparent aliases, etc.
extract_schemas already makes these decisions correctly and produces a clean, language-agnostic Schema representation. That's the single source of truth — it's already what gets serialized to CBOR and sent over the wire for schema compatibility checking.
The codegen should consume Schema nodes instead of Shape nodes. The flow should be:
facet Shape → extract_schemas → Schema → all targets
Benefits:
is_bytes, variant classification, struct/enum recognition etc. are decided once, correctly, in one place — not duplicated and potentially inconsistently across every target
- Codegen and runtime schema compatibility checking are provably describing the same type system and cannot drift apart
- Codegen logic becomes simpler —
Schema is a clean tagged union with no ShapeKind::Pointer, ShapeKind::TupleStruct, transparent aliases, or other reflection artifacts to handle
- Adding a new language target just means consuming
Schema, not understanding facet internals
Currently all codegen targets (Swift, TypeScript, wire) independently walk raw
facetShapes to generate encode/decode logic. This means each target independently re-derives decisions likeis_bytes, named vs anonymous types, transparent aliases, etc.extract_schemasalready makes these decisions correctly and produces a clean, language-agnosticSchemarepresentation. That's the single source of truth — it's already what gets serialized to CBOR and sent over the wire for schema compatibility checking.The codegen should consume
Schemanodes instead ofShapenodes. The flow should be:Benefits:
is_bytes, variant classification, struct/enum recognition etc. are decided once, correctly, in one place — not duplicated and potentially inconsistently across every targetSchemais a clean tagged union with noShapeKind::Pointer,ShapeKind::TupleStruct, transparent aliases, or other reflection artifacts to handleSchema, not understandingfacetinternals