Skip to content

[Swagger Linter Migration] PatchBodyParametersSchema (origin) - #5209

Draft
Yuchao Yan (msyyc) wants to merge 6 commits into
feature/lintdiff-migration-newfrom
feature/lintdiff-patch-body-parameters-schema
Draft

[Swagger Linter Migration] PatchBodyParametersSchema (origin)#5209
Yuchao Yan (msyyc) wants to merge 6 commits into
feature/lintdiff-migration-newfrom
feature/lintdiff-patch-body-parameters-schema

Conversation

@msyyc

@msyyc Yuchao Yan (msyyc) commented Aug 12, 2026

Copy link
Copy Markdown
Member

Summary

This PR closes two known semantic gaps in the native TypeSpec migration of PatchBodyParametersSchema: it detects create-only PATCH properties and mirrors the Swagger validator's top-level identity exemption. The rule remains classified as partial because corpus-level one-sided projects still require project-specific explanation; raw diagnostic counts are not expected to match because Swagger reports emitted OpenAPI occurrences while TypeSpec reports semantic source properties.

Original Swagger linter

Rule: PatchBodyParametersSchema (source, RPC-Patch-V1-10)

For every property reachable from a Swagger 2.0 PATCH body schema, the original rule checks that:

  • the property is not listed in its containing schema's required array;
  • the property does not define a default value;
  • the property's x-ms-mutability is not exactly ["create"].

It deliberately skips a case-insensitive top-level property named identity, including that property's descendants.

How the Swagger linter works

The Spectral ruleset selects resolved body parameters under $.paths.*.patch.parameters. Its custom function obtains the body schema's properties and required-property list, checks each property, and recursively enters nested object schemas. For nested findings, it advances the JSON path through schema.properties.<property>; diagnostics target the containing schema rather than the individual property node.

The implementation has two important comparison caveats:

  • It tests properties[prop].default by truthiness, so emitted defaults such as false, 0, and "" are not reported even though the guideline forbids defaults.
  • It operates on emitted Swagger occurrences. Reused semantic properties can therefore produce multiple diagnostics across paths or files, while source properties that project away or become optional in the selected API version may produce none.

Those behaviors explain count differences and are not copied merely to force numerical parity.

How the migrated TypeSpec linter works

The TypeSpec rule visits operations in ARM provider namespaces, resolves each HTTP operation with getHttpOperation, and processes only PATCH operations with model request bodies. It recursively walks authored and inherited ModelProperty values, preserves derived overrides, and tracks visited models to avoid cycles.

For each property it reports:

  • a required-property diagnostic when ModelProperty.optional is false;
  • a default diagnostic whenever defaultValue is present, including falsy defaults;
  • a create-only diagnostic when getVisibilityForClass against getLifecycleVisibilityEnum contains exactly Lifecycle.Create.

The rule skips top-level identity before checking or recursing, matching the Swagger exception. Diagnostics target the authored ModelProperty and include its full nested property path, giving users a stable source location instead of an emitted schema location.

This PR adds focused fixtures for default-valued and create-only properties, retains the required-property fixture, and adds a compliant top-level identity regression. For example, @visibility(Lifecycle.Create) createOnly?: string now matches Swagger's emitted x-ms-mutability: ["create"], while required descendants beneath top-level identity remain clean on both sides.

Migration evidence

See PatchBodyParametersSchema migration evidence for focused fixture results, the pinned full-corpus run, project overlap and complete one-sided project lists, compile failures, selected-version/source-to-emission analysis, review decisions, and remaining uncertainty.

The latest full run covered 462 successfully compiled projects: the validator fired in 93 projects, TypeSpec in 123, with 89 overlapping, four validator-only, and 34 TypeSpec-only projects. The identity exemption removed prior TypeSpec-only identity.type cases including DataFactory, ElasticSan, HealthcareApis, Monitor ScheduledQueryRuleApi, and SAP Virtual Instance. The rule remains partial until the residual project-level gaps are fully reconciled.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7054e94e-5ed2-43ae-9bca-490a4203c0a7

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Improves PatchBodyParametersSchema parity with the Swagger validator.

Changes:

  • Detects create-only PATCH properties.
  • Broadens the top-level identity exemption.
  • Adds fixtures, snapshots, and migration evidence.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/typespec-lintdiff/src/rules/patch-body-parameters-schema.ts Implements create-only detection and identity skipping.
packages/typespec-lintdiff/test/fixtures/PatchBodyParametersSchema/rule.md Documents covered behavior and fixtures.
packages/typespec-lintdiff/test/fixtures/PatchBodyParametersSchema/migration.md Records corpus and migration evidence.
.../default-patch-property/main.tsp Defines the default-value fixture.
.../default-patch-property/expect.json Marks the fixture as violating.
.../default-patch-property/output.json Captures emitted Swagger.
.../default-patch-property/tsp-diagnostics.json Captures TypeSpec diagnostics.
.../default-patch-property/validator-diagnostics.json Captures validator diagnostics.
.../create-only-patch-property/main.tsp Defines the create-only fixture.
.../create-only-patch-property/expect.json Marks the fixture as violating.
.../create-only-patch-property/output.json Captures emitted Swagger.
.../create-only-patch-property/tsp-diagnostics.json Captures TypeSpec diagnostics.
.../create-only-patch-property/validator-diagnostics.json Captures validator diagnostics.
.../top-level-identity-compliant/main.tsp Defines the identity exemption fixture.
.../top-level-identity-compliant/expect.json Records compliant expectations and noise.
.../top-level-identity-compliant/output.json Captures emitted Swagger.
.../top-level-identity-compliant/tsp-diagnostics.json Captures ambient TypeSpec diagnostics.
.../top-level-identity-compliant/validator-diagnostics.json Confirms no validator diagnostic.
Suppressed comments (1)

packages/typespec-lintdiff/src/rules/patch-body-parameters-schema.ts:80

  • This exception checks the TypeSpec source name, but the Swagger rule checks the emitted JSON property name. Because AutoRest emits model keys via resolveEncodedName(..., "application/json"), a top-level customIdentity encoded as identity will still be reported here even though Swagger skips it, while a source identity encoded to another name is incorrectly skipped. Base this check on the resolved JSON name (and add a focused encoded-name fixture) to preserve parity.
    if (isTopLevelIdentityProperty(propertyPath)) {

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/typespec-lintdiff/src/rules/patch-body-parameters-schema.ts Outdated
@msyyc
Yuchao Yan (msyyc) marked this pull request as draft August 12, 2026 06:59
Yuchao Yan (msyyc) and others added 5 commits August 14, 2026 15:18
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 7054e94e-5ed2-43ae-9bca-490a4203c0a7
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 7054e94e-5ed2-43ae-9bca-490a4203c0a7
@msyyc Yuchao Yan (msyyc) changed the title Improve PatchBodyParametersSchema lint parity [Swagger Linter Migration] PatchBodyParametersSchema (origin) Aug 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants