Summary

  • Introduces MigrationError, MigrationAction, and DynamicMigration as the serializable foundation for schema evolution
  • DynamicMigration applies a sequence of path-based MigrationActions to DynamicValue, supporting record ops (add/drop/rename field, mandate, optionalize), enum ops (rename/transform case), collection/map transforms, join/split, and type changes
  • All 13 action types implement structural reverse (action.reverse.reverse == action)
  • Fully serializable — no functions or closures in the untyped core

Files added

File Description
MigrationError.scala Sealed trait + 8 error variants with DynamicOptic path info
MigrationAction.scala Sealed trait + 13 action case classes with reverse
DynamicMigration.scala Serializable migration core: apply, ++, reverse
DynamicMigrationSpec.scala 42 tests covering all actions, laws, and error paths

Laws verified

  • Identity: DynamicMigration.identity.apply(v) == Right(v)
  • Associativity: (m1 ++ m2) ++ m3 == m1 ++ (m2 ++ m3)
  • Structural reverse: m.reverse.reverse == m
  • Best-effort semantic inverse: m.apply(a) == Right(b) ⇒ m.reverse.apply(b) == Right(a)

Test plan

  • 42 new tests pass on Scala 3.3.7 (5,633 total suite: 0 failures)
  • 42 new tests pass on Scala 2.13.18 (5,343 total suite: 0 failures)
  • Cross-compilation succeeds (+schemaJVM/compile)
  • scalafmtCheckAll passes
  • No existing files modified — purely additive, no binary compatibility risk

/attempt #519 issue #519 /claim #519

Claim

Total prize pool $4,000
Total paid $0
Status Pending
Submitted January 30, 2026
Last updated January 30, 2026

Contributors

OR

Orbin Sunny

@orbin123

100%

Sponsors

ZI

ZIO

@ZIO

$4,000