Skip to content

feat(compat): keep parent symbol_removed at breaking severity in detected renames#89

Merged
gjtorikian merged 1 commit into
mainfrom
compat-keep-rename-parent-breaking
May 20, 2026
Merged

feat(compat): keep parent symbol_removed at breaking severity in detected renames#89
gjtorikian merged 1 commit into
mainfrom
compat-keep-rename-parent-breaking

Conversation

@gjtorikian
Copy link
Copy Markdown
Collaborator

Summary

When detectTypeRenames / inferTransitiveTypeRenames / detectEnumRenames matches a removed symbol against a structurally-equivalent (or value-set-equivalent) candidate, stop downgrading the parent symbol_removed to soft-risk. Keep attaching the remediation hint. Child-cascade downgrades in cascadeRenameDowngrades are 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 AuditLogActionJsonAuditLogAction, WebhookEndpointJsonWebhookEndpoint, AuditLogSchemaAuditLogSchemaDto, plus enum modules AuditLogExportJsonState etc. Before this change, those were emitted as soft-risk (hidden from failOn: breaking); after, they report breaking as they should. Verified by re-running oagen compat-diff against 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 three parentRemoval.severity = 'soft-risk' mutations in detectTypeRenames, inferTransitiveTypeRenames, detectEnumRenames. Keep the remediation attachment. Update JSDoc to reflect the new policy.
  • test/compat/rename-detection.test.ts: flip the four parent-severity assertions from soft-risk to breaking. Update two test titles. Cascade-to-children tests are unchanged (and still verify children stay soft-risk).
  • All 1423 tests pass.

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 silently. Either:

  1. Migrate callers to the new symbol name (the intended path — the remediation hint tells you where it moved), or
  2. Approve the intentional rename via compat.allow if breaking is acceptable.

Test plan

  • CI green
  • Spot-check: run oagen compat-diff against a known *Json → bare consolidation and confirm the parent symbol is flagged breaking with a remediation hint.

🤖 Generated with Claude Code

…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>
@gjtorikian gjtorikian changed the title feat(compat)!: keep parent symbol_removed at breaking severity in detected renames feat(compat): keep parent symbol_removed at breaking severity in detected renames May 20, 2026
@gjtorikian gjtorikian merged commit 5c42f96 into main May 20, 2026
6 checks passed
@gjtorikian gjtorikian deleted the compat-keep-rename-parent-breaking branch May 20, 2026 21:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant