Summary

Implements a pure, algebraic, fully serializable migration system for ZIO Schema 2 as specified in #519. The system represents structural transformations between schema versions as first-class, serializable data.

Architecture

  • DynamicMigration — Untyped, serializable execution engine operating on DynamicValue
  • Migration[A, B] — Typed wrapper with source/target schemas providing A -> toDynamicValue -> DynamicMigration.apply -> fromDynamicValue -> B
  • MigrationAction — Sealed trait ADT with 14 path-based action types via DynamicOptic
  • MigrationBuilder[A, B] — Fluent builder with macro-extracted selector expressions (_.address.street)
  • SchemaShape — Symbolic execution engine for .build() validation at every nesting level
  • MigrationSchemas — Hand-written Schema instances for full serialization of all migration types
  • MigrationMetadata — ID, description, timestamp, author, SHA-256 fingerprint for auditing

Actions (14 types)

Record: AddField, DropField, Rename, TransformValue, Mandate, Optionalize, ChangeType, Join, Split Enum: RenameCase, TransformCase Collection: TransformElements, TransformKeys, TransformValues

Key Design Decisions

  • Reuses SchemaExpr for value-level transformations as specified — no custom expression language
  • Explicit lossiness tracking — every action has lossy: Boolean and reverse: Option[MigrationAction]
  • Security validationDynamicMigration.validate() with configurable limits (maxActions, maxOpticDepth, maxNestingDepth, maxTotalNodes) for untrusted migrations
  • Full DynamicOptic paths in Join/Split (supports nested joins, not just root-level field names)
  • Dual macro implementations — Scala 2 (blackbox.Context) and Scala 3 (scala.quoted) with 11 selector-based builder methods each

Success Criteria Checklist

  • DynamicMigration fully serializable (MigrationSchemas with round-trip tests)
  • Migration[A, B] wraps schemas and actions
  • All actions path-based via DynamicOptic
  • User API uses selector functions (S => A) for optics on old and new types
  • Macro validation in .build()SchemaShape symbolic execution confirms source transforms to target
  • .buildPartial() supported
  • Structural reverse implemented with explicit lossiness
  • Identity & associativity laws hold (tested)
  • Enum rename / transform supported
  • Errors include path information (plus actionIndex, action, cause, actualShape, expectedShape, inputSlice)
  • Comprehensive tests — 182 tests across 7 test files
  • Scala 2.13 and Scala 3.5+ supported

Files (16 new, 5586 lines)

Source (10 files):

  • DynamicMigration.scala — Execution engine with security validation
  • Migration.scala — Typed wrapper with ++, andThen, composeStrict, reverse
  • MigrationAction.scala — 14 sealed action types with reverse/lossy tracking
  • MigrationBuilder.scala — Fluent builder with build(), buildPartial(), dryRun()
  • MigrationError.scala — Rich error type with path and diagnostic context
  • MigrationMetadata.scala — Auditing metadata with SHA-256 fingerprint
  • MigrationSchemas.scala — Self-describing schemas for serialization
  • SchemaShape.scala — Symbolic execution engine for validation
  • MigrationBuilderMacros.scala (scala-2) — Scala 2 selector macros
  • MigrationBuilderMacros.scala (scala-3) — Scala 3 selector macros

Tests (7 files, 182 tests):

  • DynamicMigrationSpec.scala — All action execution, composition, reverse, lossy, validate, explain
  • MigrationBuilderSpec.scala — Builder API, build/buildPartial validation, metadata, dryRun
  • MigrationLawsSpec.scala — Identity, associativity, reverse, composition laws
  • SchemaShapeSpec.scala — Shape extraction, comparison, symbolic action application
  • MigrationCoverageSpec.scala — Branch coverage: ChangeType, TransformCase, collection ops, Join/Split, error paths, serialization round-trips, mixed-action composition
  • MigrationSelectorSpec.scala (Scala 3 only) — Macro selector-to-optic conversion
  • Cross-compilation verified on Scala 2.13.18, 3.3.7 LTS, 3.7.4

Demo

Video walkthrough

/claim #519

Claim

Total prize pool $4,000
Total paid $0
Status Pending
Submitted February 12, 2026
Last updated February 12, 2026

Contributors

CR

CreativeSteward

@AtlasPA

100%

Sponsors

ZI

ZIO

@ZIO

$4,000