MarkUs: Framework Maintenance

PR #7675 — Migrating deprecated Rack status symbols across the codebase.


Context

Rack 3.0 deprecated several HTTP status symbols, including renaming :payload_too_large to :content_too_large to align with RFC 9110 terminology. MarkUs, running on Rails with Rack as its HTTP interface layer, used the deprecated symbols in ~40 files across controllers, tests, and middleware.

Framework deprecation migrations are unglamorous but essential: deprecated symbols become removed symbols in the next major version, turning warnings into runtime errors. Deferring the migration creates compounding technical debt as the affected surface area grows.


Approach

Codebase-wide changes require systematic execution to avoid introducing inconsistencies:

  1. Audit. grep -rn :payload_too_large to find all occurrences. Map each to its context: controller responses, test assertions, middleware error handling.

  2. Verify semantics. Confirm that :content_too_large maps to the same HTTP status code (413). Rack’s symbol-to-status mapping is defined in Rack::Utils::SYMBOL_TO_STATUS_CODE; both the old and new symbol map to 413 during the deprecation period.

  3. Replace. Consistent find-and-replace across all files. For symbols used in string interpolation or metaprogramming, verify that the replacement doesn’t break dynamic dispatch.

  4. Test. Run the full test suite. Deprecation-related changes should produce zero functional diff; any test failure indicates a semantic mismatch, not expected behavioral change.

  5. Changelog. Document the migration following MarkUs’s changelog conventions, linking to the upstream Rack changelog entry.


Technical Principle

Track upstream deprecation cycles proactively. Rails, Rack, and Ruby follow semantic versioning with deprecation warnings in minor versions and removals in major versions. A codebase that stays current with deprecations can upgrade major versions incrementally. A codebase that defers migrations faces a compounding wall of breaking changes at upgrade time.

The cost of this PR was ~2 hours of systematic replacement. The cost of deferring would be a blocked Rack upgrade affecting the entire deployment pipeline.