feat(compat): keep parent symbol_removed at breaking severity in detected renames#89
Merged
Merged
Conversation
…ected renames Previously, when `detectTypeRenames` / `inferTransitiveTypeRenames` / `detectEnumRenames` matched a removed symbol against a structurally-equivalent (or value-set-equivalent) candidate, the parent `symbol_removed` was downgraded to `soft-risk`. The rationale was that consumer code accessing fields *through a value* of the renamed type would keep working. That rationale holds for cascaded child removals — and those are still downgraded — but it does not hold for the parent itself. Callers who reference the removed symbol *by name* (Sorbet annotations, `is_a?` checks, pattern matches, deserialization targets, type-class lookups) fail at runtime because the symbol is gone. Concretely: in workos-ruby PR #489 the spec consolidates `AuditLogActionJson` → `AuditLogAction`, `WebhookEndpointJson` → `WebhookEndpoint`, etc. These suffix-renames were emitted as `soft-risk`, hiding what is a real breaking change for any caller referencing the old constant. The fix: stop mutating `parentRemoval.severity` in all three rename detectors. Keep attaching the `remediation` string so reviewers / users see where the symbol moved. The child-cascade downgrades in `cascadeRenameDowngrades` are unchanged — field/method access through the new type still works. BREAKING CHANGE: rename-detected parent type/enum removals now report `breaking` instead of `soft-risk`. Consumers running `oagen verify` with `failOn: breaking` (the default) may see new failures for renames that previously passed. Approve intentional renames via `compat.allow` to suppress, or migrate callers to the new symbol name. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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
When
detectTypeRenames/inferTransitiveTypeRenames/detectEnumRenamesmatches a removed symbol against a structurally-equivalent (or value-set-equivalent) candidate, stop downgrading the parentsymbol_removedtosoft-risk. Keep attaching theremediationhint. Child-cascade downgrades incascadeRenameDowngradesare unchanged.Why
The old rationale (consumer code accessing fields through a value of the renamed type keeps working) holds for cascaded child removals, but not for the parent itself. Callers who reference the removed symbol by name — Sorbet annotations,
is_a?checks, pattern matches, deserialization targets, type-class lookups — fail at runtime because the symbol is gone.Concretely: in workos-ruby#489 the spec consolidates
AuditLogActionJson→AuditLogAction,WebhookEndpointJson→WebhookEndpoint,AuditLogSchema→AuditLogSchemaDto, plus enum modulesAuditLogExportJsonStateetc. Before this change, those were emitted assoft-risk(hidden fromfailOn: breaking); after, they reportbreakingas they should. Verified by re-runningoagen compat-diffagainst PR #489's base→head: 11 → 17 breaking rows, +6 covering exactly the *Json/Dto parent symbols.What changes
src/compat/differ.ts: remove the threeparentRemoval.severity = 'soft-risk'mutations indetectTypeRenames,inferTransitiveTypeRenames,detectEnumRenames. Keep theremediationattachment. Update JSDoc to reflect the new policy.test/compat/rename-detection.test.ts: flip the four parent-severity assertions fromsoft-risktobreaking. Update two test titles. Cascade-to-children tests are unchanged (and still verify children staysoft-risk).Breaking change
Rename-detected parent type/enum removals now report
breakinginstead ofsoft-risk. Consumers runningoagen verifywithfailOn: breaking(the default) may see new failures for renames that previously passed silently. Either:remediationhint tells you where it moved), orcompat.allowif breaking is acceptable.Test plan
oagen compat-diffagainst a known *Json → bare consolidation and confirm the parent symbol is flagged breaking with a remediation hint.🤖 Generated with Claude Code