feat(migration): auto-migration rename detection#2112
Merged
Conversation
Design for closing item 6 (migration rename detection) from docs/wheels-vs-frameworks.md "Where Wheels Trails". Covers explicit hints, heuristic suggestions (normalized-token + Levenshtein), CLI command, MCP integration, testing strategy, and documentation updates. Targets v4.0. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
21-task TDD implementation plan for auto-migration rename detection. Covers RenameDetector engine, AutoMigrator integration, CLI command, MCP handler, and documentation. Targets v4.0. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Duplicate() is a deep copy in CFML; the prior comment said shallow. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds `case "diff":` to the CLI bridge switch statement in cli.cfm. Wraps AutoMigrator.diff() and diffAll() with URL parameter parsing for hints, threshold, write, and name options. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Downstream consumers (CLI and MCP) need the exception type to distinguish error classes (InvalidRenameHint vs RenameHintTypeMismatch etc). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Matches the convention used by all other dbmigrate CLI commands (info, latest, up, down, exec, reset, etc) for CI/scripting use. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Matches the encoding pattern used for every other parameter. Low-risk but defense-in-depth. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The MCP spec defines diffAll input hints as model-keyed:
{"User": {"renames": {...}}, "Post": {...}}
But AutoMigrator.diffAll reads options.hints, so the MCP handler
must wrap model-keyed hints in {hints: ...} before forwarding to
the CLI bridge. Single-model path already uses the flat
{renames: {...}} shape that diff() reads directly.
Without this fix, MCP diffAll with hints silently ran the heuristic
without applying the hints.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This was referenced May 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes item 6 ("Migration rename detection") from
docs/wheels-vs-frameworks.md"Where Wheels Trails" list — promoting it to "Where Wheels Leads" as item 16.AutoMigrator.diff()now detects column renames via two complementary mechanisms:options.renames = {"oldCol": "newCol"}is authoritative. Invalid hints raise typed exceptions (Wheels.InvalidRenameHint,Wheels.RenameHintTypeMismatch,Wheels.DuplicateRenameHint).full_name↔fullName); everything else surfaces assuggestedRenamesrequiring explicit confirmation. Ambiguity is pre-counted across the full candidate pool before greedy assignment, so ambiguous score-1.0 pairs are correctly demoted to suggestions rather than silently applied.What's included
vendor/wheels/migrator/RenameDetector.cfc(pure logic, no DB/model deps, 275 lines, 39 unit specs)diff(modelName, options)anddiffAll(options)accept hints and threshold;generateMigrationCFC()emitsrenameColumn()inup()(first) and reversedrenameColumn()indown()(last). Backward compatible — zero breaking changes.wheels dbmigrate diff [modelName]command with--rename=OLD:NEW,--threshold,--write,--nameflags. FordiffAll, use--rename=User.old_col:newCol.wheels_migrate(action="diff")handler; returns full JSON envelope withrenameColumns,suggestedRenames,addColumns,removeColumns,changeColumns.wheels-vs-frameworks.md, newdbmigrate-diff.mdCLI reference, auto-migration sections inmigrations.mdCLI guide and the migrations tutorialREADME.md,CLAUDE.mdquick reference.Spec & plan
docs/superpowers/specs/2026-04-15-auto-migration-rename-detection-design.mddocs/superpowers/plans/2026-04-15-auto-migration-rename-detection.mdStats
Intentional behavioral change
A model rename that previously produced
removeColumn+addColumn(with data loss) will now producerenameColumnwhen the heuristic confirms it at score 1.0 unambiguously (e.g., case/underscore variants of the same tokens). This is the desired fix; noted here so anyone regenerating migrations is aware.Test Plan
command=difffor both single-model and diffAll)wheels_migrate action="diff")success: trueconfirms code loads and executes on Adobe flavorgraphqlclientpackage gap that blocks the suite runner. Not introduced by this branch. Recommend fixing that container setup separately and then running:docker compose up -d adobe2025 && curl -s "http://localhost:62025/wheels/core/tests?db=sqlite&format=json&directory=wheels.tests.specs.migrator"migratetool's declared argument list only listsaction; diff-specific params (modelName,hints,heuristicThreshold,write) are not in the schema. They work because we dispatch internally, but AI agents can't discover them from tool introspection. Fast-follow PR suggested.🤖 Generated with Claude Code