Implements a pure, algebraic migration system for ZIO Schema that represents
structural transformations between schema versions as first-class, serializable data. Unlike traditional migration approaches, this system uses no functions, closures, or reflection - migrations are pure ADTs that can be stored, inspected, and applied dynamically.

Key Features

  • Pure Data Migrations: All migrations are represented as case classes with no closures
  • Fully Serializable: DynamicMigration can be stored in registries, databases, or files
  • Compile-Time Validation: MigrationBuilder.withFieldTracking ensures all
    fields are handled
  • Bidirectional: Every migration has a structural reverse
  • Path-Based Actions: All operations specify location via DynamicOptic
  • Introspectable: Migration logic can be inspected, transformed, and optimized

API Overview

// Build a type-safe migration
val migration = MigrationBuilder.withFieldTracking[PersonV1, PersonV2]
.renameField(select(_.name), select(_.fullName))
.keepField(select(_.age))
.addField(select(_.country), "US")
.build // Only compiles when all fields are handled
// Apply migration
migration.apply(v1) // Right(PersonV2(...))
// Reverse migration
migration.reverse.apply(v2) // Right(PersonV1(...))

Migration Actions Category: Record Actions: AddField, DropField, Rename, TransformValue, Mandate, Optionalize,
ChangeType ──────────────────────────────────────── Category: Enum Actions: RenameCase, TransformCase ──────────────────────────────────────── Category: Collection Actions: TransformElements, TransformKeys, TransformValues Files Added

  • Core Types: MigrationError, MigrationAction, DynamicMigration, Migration,
    SchemaFields, FieldSelector, Resolved, PrimitiveConversions
  • Type-Level: FieldSet (Scala 2 & 3)
  • Macros: SelectorMacros, SchemaFieldsMacros, MigrationBuilderMacros (Scala 2 &
  • Builder: MigrationBuilder (Scala 2 & 3)
  • Documentation: docs/reference/migration.md

Design Decisions

  1. Non-inline builder methods: Only select() and withFieldTracking are inline
    macros. All builder methods are regular methods with type parameters, ensuring builders work correctly when stored in vals.
  2. Two-layer architecture:
  • DynamicMigration - Untyped, fully serializable core
  • Migration[A, B] - Typed wrapper with schemas
  1. Resolved expressions: Pure data representations of value computations
    (Literal, Identity, FieldAccess, Convert, Concat, etc.)

Test Coverage

1000+ tests across 24 spec files covering:

  • Core migration operations
  • Builder API and field tracking
  • All migration action types
  • Bidirectional migrations
  • Error handling and diagnostics
  • Algebraic properties (identity, associativity)
  • Edge cases and boundaries
  • Property-based tests

fixes #519 /claim #519

Claim

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

Contributors

AQ

Aqil Ahmad

@Aqil-Ahmad

100%

Sponsors

ZI

ZIO

@ZIO

$4,000