Skip to content

RFC: TypeSpec Breaking Change Detection Tool - Design Overview - #4580

Open
markcowl wants to merge 5 commits into
Azure:mainfrom
markcowl:rfc/breaking-changes-overview
Open

RFC: TypeSpec Breaking Change Detection Tool - Design Overview#4580
markcowl wants to merge 5 commits into
Azure:mainfrom
markcowl:rfc/breaking-changes-overview

Conversation

@markcowl

@markcowl markcowl commented Jun 8, 2026

Copy link
Copy Markdown
Member

Summary

Design overview RFC for @azure-tools/typespec-breaking-change, a TypeSpec-native API diff and breaking change detection tool for Azure ARM APIs.

This document covers:

  • Architecture (two-layer: diff engine + policy engine)
  • Comparison phases (Phase A: same-version regression, Phase B: cross-version breaking changes)
  • Rule summary tables (request/response/model breaking changes)
  • Suppression mechanism (two decorators: @approvedBreakingChange, @approvedUnversionedChange)
  • CI integration and output format

Supporting Documents

Additional design detail documents (taxonomy, classification, rules, OAD correlation, validation strategy) are available on the
fc/breaking-changes\ branch
for reference.

@azure-sdk

Copy link
Copy Markdown
Collaborator

No changes needing a change description found.

@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

⚡ Benchmark Results

⚠️ 6 metric(s) regressed above the +5% threshold:

Metric Baseline Current Change
 ↳ linter/@azure-tools/typespec-azure-core/no-header-explode 🔴 26.7ms 🔴 28.3ms +5.7% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-query-explode 🔴 27.8ms 🔴 29.5ms +6.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-agent-base-type-child-resources 🔴 21.0ms 🔴 23.4ms +11.5% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-common-types-version 🟡 12.1ms 🟡 13.1ms +8.3% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-path-casing-conflicts 🟡 17.1ms 🟡 18.2ms +6.8% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/lro-location-header 🟡 19.7ms 🔴 20.7ms +5.2% 🔴
Full details – comparing 61e0327 vs baseline rolling-baseline-4df8556-2398555 (rolling baseline (20 main runs))
Metric Baseline Current Change
total 🔴 1.01s 🔴 1.05s +3.9%
loader 🟡 307.6ms 🟡 321.3ms +4.4%
resolver 🟢 40.5ms 🟢 42.0ms +3.8%
checker 🟡 365.7ms 🟡 380.4ms +4.0%
validation 🟢 85.1ms 🟢 86.7ms +1.9%
 ↳ validation/@azure-tools/typespec-azure-core 🟡 12.6ms 🟡 13.2ms +4.8%
 ↳ validation/@typespec/http 🟡 15.5ms 🟡 16.1ms +3.8%
 ↳ validation/@typespec/rest 🟢 1.6ms 🟢 1.6ms -1.1%
 ↳ validation/@typespec/versioning 🔴 51.4ms 🔴 51.8ms +0.8%
 ↳ validation/compiler 🟢 3.9ms 🟢 3.9ms +1.4%
linter 🟡 215.3ms 🟡 223.3ms +3.7%
 ↳ linter/@azure-tools/typespec-azure-core/auth-required 🟢 0.1ms 🟢 0.1ms +6.1%
 ↳ linter/@azure-tools/typespec-azure-core/bad-record-type 🟢 0.6ms 🟢 0.6ms +0.1%
 ↳ linter/@azure-tools/typespec-azure-core/byos 🟢 8.4ms 🟢 8.6ms +2.8%
 ↳ linter/@azure-tools/typespec-azure-core/casing-style 🟢 1.5ms 🟢 1.5ms +1.0%
 ↳ linter/@azure-tools/typespec-azure-core/composition-over-inheritance 🟢 0.2ms 🟢 0.2ms +1.5%
 ↳ linter/@azure-tools/typespec-azure-core/documentation-required 🟢 1.9ms 🟢 2.0ms +0.9%
 ↳ linter/@azure-tools/typespec-azure-core/friendly-name 🟢 1.4ms 🟢 1.4ms +1.4%
 ↳ linter/@azure-tools/typespec-azure-core/key-visibility-required 🟢 0.4ms 🟢 0.4ms +2.4%
 ↳ linter/@azure-tools/typespec-azure-core/known-encoding 🟢 0.5ms 🟢 0.5ms +3.3%
 ↳ linter/@azure-tools/typespec-azure-core/long-running-polling-operation-required 🟢 0.8ms 🟢 0.8ms -0.2%
 ↳ linter/@azure-tools/typespec-azure-core/no-case-mismatch 🟢 0.7ms 🟢 0.7ms +1.5%
 ↳ linter/@azure-tools/typespec-azure-core/no-closed-literal-union 🟢 1.0ms 🟢 1.0ms -1.5%
 ↳ linter/@azure-tools/typespec-azure-core/no-enum 🟢 0.2ms 🟢 0.3ms +2.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-error-status-codes 🟢 0.3ms 🟢 0.3ms +1.3%
 ↳ linter/@azure-tools/typespec-azure-core/no-explicit-routes-resource-ops 🟢 0.2ms 🟢 0.2ms +3.0%
 ↳ linter/@azure-tools/typespec-azure-core/no-format 🟢 0.8ms 🟢 0.8ms +2.2%
 ↳ linter/@azure-tools/typespec-azure-core/no-generic-numeric 🟢 0.8ms 🟢 0.9ms +2.0%
 ↳ linter/@azure-tools/typespec-azure-core/no-header-explode 🔴 26.7ms 🔴 28.3ms +5.7% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-legacy-usage 🟢 2.1ms 🟢 2.1ms +1.8%
 ↳ linter/@azure-tools/typespec-azure-core/no-multiple-discriminator 🟢 0.2ms 🟢 0.2ms +5.3%
 ↳ linter/@azure-tools/typespec-azure-core/no-nullable 🟢 0.4ms 🟢 0.4ms +3.2%
 ↳ linter/@azure-tools/typespec-azure-core/no-offsetdatetime 🟢 2.0ms 🟢 2.0ms +2.8%
 ↳ linter/@azure-tools/typespec-azure-core/no-openapi 🟢 2.3ms 🟢 2.3ms +0.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-private-usage 🟢 3.2ms 🟢 3.2ms +1.3%
 ↳ linter/@azure-tools/typespec-azure-core/no-query-explode 🔴 27.8ms 🔴 29.5ms +6.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-response-body 🔴 33.4ms 🔴 34.7ms +3.8%
 ↳ linter/@azure-tools/typespec-azure-core/no-rest-library-interfaces 🟢 0.1ms 🟢 0.1ms +4.4%
 ↳ linter/@azure-tools/typespec-azure-core/no-route-parameter-name-mismatch 🟢 7.7ms 🟢 8.0ms +4.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-rpc-path-params 🟢 0.4ms 🟢 0.4ms +3.0%
 ↳ linter/@azure-tools/typespec-azure-core/no-string-discriminator 🟢 0.1ms 🟢 0.1ms +4.0%
 ↳ linter/@azure-tools/typespec-azure-core/no-unknown 🟢 0.4ms 🟢 0.4ms +3.2%
 ↳ linter/@azure-tools/typespec-azure-core/no-unnamed-union 🟢 0.8ms 🟢 0.8ms +0.4%
 ↳ linter/@azure-tools/typespec-azure-core/operation-missing-api-version 🟢 0.4ms 🟢 0.4ms -2.5%
 ↳ linter/@azure-tools/typespec-azure-core/request-body-problem 🟢 0.5ms 🟢 0.5ms +0.6%
 ↳ linter/@azure-tools/typespec-azure-core/require-versioned 🟢 0.1ms 🟢 0.1ms +5.7%
 ↳ linter/@azure-tools/typespec-azure-core/response-schema-problem 🔴 32.6ms 🔴 33.4ms +2.5%
 ↳ linter/@azure-tools/typespec-azure-core/rpc-operation-request-body 🟢 0.7ms 🟢 0.7ms +5.1%
 ↳ linter/@azure-tools/typespec-azure-core/spread-discriminated-model 🟢 0.5ms 🟢 0.5ms +2.9%
 ↳ linter/@azure-tools/typespec-azure-core/use-standard-names 🟢 7.6ms 🟢 7.9ms +5.0%
 ↳ linter/@azure-tools/typespec-azure-core/use-standard-operations 🟢 0.3ms 🟢 0.3ms -0.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-agent-base-type-child-resources 🔴 21.0ms 🔴 23.4ms +11.5% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-agent-base-type-lifecycle-operations 🟢 0.3ms 🟢 0.3ms +5.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-common-types-version 🟡 12.1ms 🟡 13.1ms +8.3% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-no-key 🟢 0.2ms 🟢 0.2ms +2.6%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-usage-discourage 🟢 0.1ms 🟢 0.1ms +6.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-delete-operation-response-codes 🟢 5.0ms 🟢 4.5ms -9.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-feature-file-usage-discourage 🟢 0.1ms 🟢 0.1ms -1.7%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-path-casing-conflicts 🟡 17.1ms 🟡 18.2ms +6.8% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-record 🟢 0.6ms 🟢 0.7ms +2.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-post-operation-response-codes 🟢 1.4ms 🟢 1.5ms +4.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-put-operation-response-codes 🟢 0.2ms 🟢 0.2ms -5.3%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-action-no-segment 🟢 0.4ms 🟢 0.4ms +0.6%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-duplicate-property 🟢 0.4ms 🟢 0.4ms +3.7%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-interface-requires-decorator 🟢 0.1ms 🟢 0.1ms -0.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-action-verb 🟢 0.2ms 🟢 0.2ms +1.9%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-envelope-property 🟢 0.3ms 🟢 0.3ms +2.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-version-format 🟢 0.2ms 🟢 0.2ms -0.3%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-key-invalid-chars 🟢 0.5ms 🟢 0.5ms +4.3%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-name-pattern 🟢 0.1ms 🟢 0.1ms +7.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation 🟢 0.5ms 🟢 0.6ms +1.9%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation-response 🟢 9.0ms 🟢 9.1ms +0.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-patch 🟢 0.8ms 🟢 0.8ms +0.6%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-path-segment-invalid-chars 🟢 0.4ms 🟢 0.4ms +2.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-provisioning-state 🟢 0.4ms 🟢 0.4ms +3.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/beyond-nesting-levels 🟢 0.2ms 🟢 0.2ms +4.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/empty-updateable-properties 🟢 0.4ms 🟢 0.4ms +4.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/improper-subscription-list-operation 🟢 0.1ms 🟢 0.1ms +11.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/lro-location-header 🟡 19.7ms 🔴 20.7ms +5.2% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-operations-endpoint 🟢 0.1ms 🟢 0.1ms +1.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-x-ms-identifiers 🟢 1.0ms 🟢 1.0ms +0.3%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-empty-model 🟢 0.3ms 🟢 0.3ms +3.7%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-override-props 🟢 0.3ms 🟢 0.3ms +2.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-reserved-resource-property 🟢 0.2ms 🟢 0.2ms +1.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-resource-delete-operation 🟢 0.5ms 🟢 0.5ms +4.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-response-body 🔴 29.8ms 🔴 30.9ms +3.6%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/patch-envelope 🟢 0.4ms 🟢 0.4ms +4.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/resource-name 🟢 0.4ms 🟢 0.4ms +1.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/secret-prop 🟢 5.4ms 🟢 5.8ms +7.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/unsupported-type 🟢 0.7ms 🟢 0.7ms +1.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/version-progression 🟢 0.3ms 🟢 0.3ms -2.8%
 ↳ linter/@azure-tools/typespec-client-generator-core/property-name-conflict 🟢 2.3ms 🟢 2.3ms +1.9%
 ↳ linter/@azure-tools/typespec-client-generator-core/require-client-suffix 🟢 1.7ms 🟢 1.7ms +1.8%
emit 🔴 6.04s 🔴 6.23s +3.0%
 ↳ emit/@Azure-Tools 🟢 0.0ms 🟢 0.0ms +0.0%
 ↳ emit/@azure-tools/typespec-autorest 🟢 125.4ms 🟢 129.9ms +3.6%
 ↳ emit/@azure-tools/typespec-python 🔴 2.25s 🔴 2.33s +3.2%
 ↳ emit/@typespec 🟢 0.0ms 🟢 0.0ms +0.0%
 ↳ emit/@typespec/http-client-js 🔴 571.9ms 🔴 584.4ms +2.2%
 ↳ emit/@typespec/openapi3 🟢 107.9ms 🟢 110.2ms +2.1%
 ↳ emit/@typespec/openapi3/compute 🟢 93.8ms 🟢 95.6ms +1.9%
 ↳ emit/@typespec/openapi3/write 🟢 13.9ms 🟢 14.3ms +2.8%

Averaged across 3 specs (azure-arm-resource-manager, azure-core-dataplane, azure-full).
Threshold: changes > ±5% are highlighted.
🟢 Fast · 🟡 Moderate (stages >200ms, rules >10ms) · 🔴 Slow (stages >400ms, rules >20ms)

@azure-sdk

azure-sdk commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

You can try these changes here

🛝 Playground 🌐 Website

@mikekistler mikekistler left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks awesome!

I left a few comments on things to think about / discuss, but overall this seems well thought out.

Comment thread rfcs/breaking-changes/typespec-breaking-change-design-overview.md Outdated
Comment thread rfcs/breaking-changes/typespec-breaking-change-design-overview.md Outdated
Comment thread rfcs/breaking-changes/typespec-breaking-change-design-overview.md
Comment thread rfcs/breaking-changes/typespec-breaking-change-design-overview.md
Comment thread rfcs/breaking-changes/typespec-breaking-change-design-overview.md
Comment thread rfcs/breaking-changes/typespec-breaking-change-design-overview.md Outdated
Comment thread rfcs/breaking-changes/typespec-breaking-change-design-overview.md
Comment thread rfcs/breaking-changes/typespec-breaking-change-design-overview.md
Comment thread rfcs/breaking-changes/typespec-breaking-change-design-overview.md
Comment thread rfcs/breaking-changes/typespec-breaking-change-design-overview.md
@haolingdong-msft

Copy link
Copy Markdown
Member

Thanks @markcowl for the PR! The design looks awesome. I really love the idea of creating canonicalization on TypeSpec versioning.

Comment thread rfcs/breaking-changes/typespec-breaking-change-design-overview.md
Comment thread rfcs/breaking-changes/typespec-breaking-change-design-overview.md
markcowl and others added 2 commits June 17, 2026 19:03
Design overview for @azure-tools/typespec-breaking-change, a TypeSpec-native
API diff and breaking change detection tool for Azure ARM APIs.

Covers architecture, comparison phases, rule summary tables, suppression
mechanism, CI integration, and output format.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… semantics, and sign-off language

- Add schema/model names to non-goals list
- Phase B now covers new or changed versions (not just new)
- Add type category breakdown for narrowing/widening (scalar, enum, union, array, record, model)
- Add ARM common-types note (compared by underlying schema)
- Clarify CI sign-off refers to breaking change reviewer approval, not general PR approval

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@markcowl
markcowl force-pushed the rfc/breaking-changes-overview branch from 2fc6002 to 61e2666 Compare June 18, 2026 02:04
@microsoft-github-policy-service microsoft-github-policy-service Bot added the stale Mark a PR that hasn't been recently updated and will be closed. label Jul 8, 2026
@microsoft-github-policy-service

Copy link
Copy Markdown

Hi @@markcowl. Your PR has had no update for 14 days and it is marked as a stale PR. If it is not updated within 14 days, the PR will automatically be closed. If you want to refresh the PR, please remove the stale label.

@markcowl
markcowl marked this pull request as ready for review July 14, 2026 02:38
@markcowl
markcowl requested a review from bterlson as a code owner July 14, 2026 02:38
@microsoft-github-policy-service

Copy link
Copy Markdown

Hi @@markcowl. This PR will be closed since it has had no update for 28 days. If this change is still relevant, please reopen the PR.

@markcowl markcowl reopened this Jul 31, 2026
@markcowl
markcowl requested a review from xirzec as a code owner July 31, 2026 19:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stale Mark a PR that hasn't been recently updated and will be closed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants