You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add @azure-tools/typespec-client-generator-core/no-operation-group-name-conflict as a small, declaration-based naming guideline. An interface or namespace containing operations should not have the same effective name as a model, scalar, enum or union declared alongside it.
The rule ID, diagnostic identity and disabled-by-default client SDK ruleset registration are unchanged. This is a native guideline, not a claim of Swagger equivalence or a prediction of every generated SDK layout.
Latest review changes
This revision addresses Timothee's three design comments:
Revert the public metadata-scope feature: remove createTCGCContext's proposed scope option, the proposed TCGCContext.scope property, the public AllScopes export, associated default-lookup changes, API-specific tests and feature change entry. Existing emitter-scoped context behavior is restored exactly to main.
Follow the existing name-validation pattern: compare declared namespace members using the existing naming helpers and reuse getDefinedLanguageScopes from validations/types.ts. There is no client hierarchy construction or SDK package/type classification.
Remove model-tree expansion: remove operation reachability, recursive model/base/discriminator traversal, union-owner classification and the second classification context. Tests now specify the smaller declaration policy rather than perpetuating the superseded client-graph contract.
The follow-up cleanup in 801c00043 keeps one representative scoped-name collision, removes redundant unused/model-tree fixtures while retaining direct namespace boundaries, and shortens the guide examples to the conflicting names and rename. No production behavior, public APIs or enablement changed.
Current native contract
For each declared namespace:
Collect names of its directly declared models, scalars, enums and unions, including unused declarations.
Compare them with interfaces containing operations and child namespaces containing directly declared operations.
Use complete, case-sensitive names, honoring existing @clientName lookup in common and explicitly configured language scopes, common-name fallback, negated scopes and friendly names.
Compare both sides in the same scope; do not combine an override from one language with a name from another.
Report once per conflicting group, at its authored interface or namespace, even if several operations or naming scopes match.
Check nested namespaces independently. Do not flatten types or groups across namespace boundaries or follow referenced types into other namespaces.
Do not inspect model properties, base models, discriminator alternatives or operation input/output reachability.
Do not interpret @client or @clientLocation as synthesized group names. Root operations, empty containers and virtual groups do not create extra checks.
Only a normal, non-mutating TCGC context is used for existing naming helpers, following the package's other naming rules. No new context API or public export is needed.
These are intentional policy changes from the previous implementation: unused local declarations now participate, cross-namespace reachable types do not, and explicit language-name collisions are checked. The authored guide, generated rule listings and feature change entry describe this policy.
Examples
An interface renamed to a model's name is flagged:
Naming the interface Widgets without that override is valid. Focused incorrect/correct excerpts are in the authored rule guide.
Tests and validation
Validation for the published cleanup at 801c000433b9eecd2e90926d56d0576f65323791:
22 canonical rule cases passed: authored interface/namespace targets, all four declaration kinds (including unused declarations), exact case/full names, common/scoped precedence, cross-language isolation, fallback/negation, per-group deduplication, friendly names and direct namespace/client-graph boundaries remain covered.
TCGC production tsc -p tsconfig.build.json --noEmit passed. Production rule code and shared APIs/utilities were not changed.
Repository pnpm format, pnpm lint and git diff --check passed. Existing per-package unreleased entries remain sufficient; no redundant review-history changeset was added.
Documentation regeneration passed with existing signature-tag/missing-documentation warnings unrelated to this rule. Generated rule pages are ignored build output, regenerated from the committed authored guide.
The actual final published incorrect/correct excerpts were validated once with explicit public HTTP/TCGC imports and usings in a service namespace: exactly one expected warning at WidgetOperations, versus zero diagnostics. These are contextual excerpts, not standalone specifications. This one-time receipt is not continuous Markdown coverage; no bespoke parser or documentation-testing system remains in the repository.
The earlier full-suite, ruleset/build and test-project typecheck observations belong to the preceding revision; those broader checks were not rerun for this bounded test/documentation cleanup. No new full-suite or all-tests typecheck success is claimed.
The public-entry-point dependency-isolation guard remains unchanged and continues to verify that AllScopes is not exported publicly. Rule ID, registration and disabled-by-default ruleset behavior are unchanged.
That rule compares the segment before the first underscore in serialized operation IDs with Swagger definition names. This native rule instead compares declared group/type names; it does not reconstruct emitted operation IDs, naming transformations or schema inlining.
The earlier development source was #5589, reviewed at 85e2dce677b4733e2e47c28c06300051cea14fcd. Its migration report and historical corpus counts describe the previous graph-based implementation, not acceptance evidence or equivalence for this revision.
The previous promotion's source-fidelity and graph-policy claims are superseded by this explicitly requested review redesign. No development-source branch, ARM dependency, dependency manifest, rule ID or ruleset enablement was changed. Bespoke Markdown tests removed in the previous review cleanup remain removed; a standard documentation-testing framework is separate work.
Add the no-operation-group-name-conflict lint rule to warn when an interface or,> namespace containing operations has the same name as a type declared in its parent,> namespace. Check common and language-specific names without constructing SDK clients.
✅ No notable package size changes compared to the base branch.
14 package(s) with no notable change
Package
Packed (base → head)
Δ Packed
Unpacked (base → head)
Δ Unpacked
@azure-tools/typespec-client-generator-core
249.80 KB → 249.98 KB
+183 B (+0.1%)
1.33 MB → 1.33 MB
+1.02 KB (+0.1%)
@azure-tools/typespec-azure-rulesets
6.00 KB → 6.03 KB
+24 B (+0.4%)
35.20 KB → 35.41 KB
+214 B (+0.6%)
@azure-tools/azure-http-specs
143.53 KB → 143.53 KB
—
1.20 MB → 1.20 MB
—
@azure-tools/typespec-autorest
87.87 KB → 87.87 KB
—
424.17 KB → 424.17 KB
—
@azure-tools/typespec-autorest-canonical
7.42 KB → 7.42 KB
—
26.00 KB → 26.00 KB
—
@azure-tools/typespec-azure-core
136.55 KB → 136.55 KB
—
733.30 KB → 733.30 KB
—
@azure-tools/typespec-azure-examples
80.15 KB → 80.15 KB
—
383.36 KB → 383.36 KB
—
@azure-tools/typespec-azure-portal-core
36.26 KB → 36.26 KB
—
242.62 KB → 242.62 KB
—
@azure-tools/typespec-azure-resource-manager
192.89 KB → 192.89 KB
—
1.15 MB → 1.15 MB
—
@azure-tools/typespec-go
264.28 KB → 264.28 KB
—
1.35 MB → 1.35 MB
—
@azure-tools/typespec-java
20.22 MB → 20.22 MB
—
22.52 MB → 22.52 MB
—
@azure-tools/typespec-metadata
15.88 KB → 15.88 KB
—
62.08 KB → 62.08 KB
—
@azure-tools/typespec-python
42.58 KB → 42.58 KB
—
166.02 KB → 166.02 KB
—
@azure-tools/typespec-ts
550.66 KB → 550.66 KB
—
2.75 MB → 2.75 MB
—
Packed = gzipped .tgz published to npm. Unpacked = total extracted size. 🆕 added, 🗑️ removed. Packages from the core/ submodule are not included. 🔴 grew · 🟢 shrank — only changes of at least 512 B and 0.5% are marked.
The scalar branch stops here without traversing type.baseScalar. TCGC preserves named custom-scalar inheritance through SdkBuiltInType.baseType (src/types.ts:291-294), so a body of scalar Alias extends Widget with operation group Widget reaches both SDK names but this rule records only Alias and misses the conflict. Repair the pinned source to traverse the base-scalar chain, add a regression, and then refresh this promotion.
The reason will be displayed to describe this comment to others. Learn more.
Simplified in fd5ec39b2. The rule now checks operation-group names against type names declared in the same namespace, reusing getDefinedLanguageScopes and getLibraryName from the existing naming validation. It no longer builds SDK clients or walks their operation-group hierarchy.
I think we should just update the validator to include that. What we really want is to make sure there is not conflicting top level types in the generated sdk
The reason will be displayed to describe this comment to others. Learn more.
Thanks, the name checks do overlap. I tried the validator consolidation, but it changes compatibility: validateClientNames produces compile-blocking duplicate-client-name errors, which cannot be mitigated with #suppress like lint warnings. Existing specs with these collisions would stop compiling, and renaming declarations may also change shipped SDK APIs.
I've reverted that consolidation in d862761 and restored the previous validator behavior. The separate lint rule remains disabled by default and, when enabled, reports a suppressible warning. This keeps the migration opt-in rather than imposing new validation errors on existing specs. Consolidation would need a separate compatibility/rollout plan, not just adding interfaces to the validator's comparisons.
Operation group NetworkSecurityPerimeterConfigurations is renamed to NetworkSecurityPerimeterConfiguration, matching the model name.
Currently compiles; consolidation introduces two blocking errors.
.NET 1.7.0, released June 2, 2026, explicitly migrated to TypeSpec generation.
These names are compatibility-sensitive, not just new naming choices. Changing @clientName to satisfy the validator can rename generated public APIs and break consumers of already-released SDKs. We cannot treat renaming as a safe, routine fix; it would require checking the generated API impact and preserving compatibility.
The reason will be displayed to describe this comment to others. Learn more.
I don't get the 2 examples you have have the conflict and used clientName to fix it which reinforce the case that this should not be allowed. Is there any cases where we'd have to suppress that rule?
Retain literal rule fixtures and package-isolation regressions. Published examples were independently executed and recorded as one-time session evidence; no continuous Markdown coverage is claimed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace client-graph reachability with namespace declaration checks and reuse existing scoped naming validation. Remove the proposed public metadata-scope API and update the policy, docs, and regressions.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary
- Treat a lint brief/PR description as the proposal under review, not a
reason to reject clear requests to simplify, revert, or consolidate it.
- Compare existing native mechanisms first; distinguish native
requirements and released compatibility from legacy parity and
complexity introduced by the proposal.
- Delete framework-only suppression/enablement tests without replacement
while retaining concrete rule-owned interactions, authored-node
deduplication, and meaningful regression preconditions.
- Remove bespoke per-rule Markdown parsers instead of moving them into
another suite. Validate published snippets through existing shared
tooling or recorded one-time execution, without claiming continuous
coverage from a one-time receipt.
- Keep actual policy/authorization gates, source immutability, required
validation, and released compatibility intact. Track replies separately
from satisfaction of review concerns.
## Evidence and rationale
This skill-only change follows a retrospective of recorded migration
feedback, not a new live-head review or a change to the underlying rule
PRs.
- [#5591 simplification
direction](#5591 (comment)),
[client-setup
question](#5591 (comment)),
and [model-tree
question](#5591 (comment)):
demonstrating differences from the current design does not independently
establish that its architecture is required.
- [#5551 consolidation
direction](#5551 (comment)):
assess extending the existing native rule and analyze actual
enablement/suppression consequences separately.
- Explicit requests for another maintainer's input, such as
[#5526](#5526 (comment))
and
[#5673](#5673 (comment)),
remain distinct decision dependencies.
The validation skill already discouraged framework-only unit tests, but
evidence-preservation wording could encourage relocating them. Promotion
still explicitly accommodated per-rule Markdown extraction. These
instructions now agree on removing unnecessary infrastructure without
discarding rule-owned behavior or honest published-example evidence.
## Scope
Only five existing skill Markdown files change: discovery,
implementation, validation, development, and promotion. No production
rules, package tests, dependencies, submodules, generated artifacts,
release entries, or CI configuration change. Two custom review/fix
skills stored outside this repository were updated locally in the same
task; they are not included in this PR.
Base: `feature/lintdiff-migration-new`, as explicitly requested.
## Validation
- Existing Prettier 3.9.5: focused Markdown format/check for the changed
files.
- `git diff --check`.
- Checked 78 concrete local Markdown references and heading anchors
across the five changed repository skills; template URL placeholders
were excluded.
- Reviewed the complete task diff and reconciled development/promotion
references with the shared validation guidance.
The root Prettier configuration could not load the unbuilt `core`
TypeSpec plugin. Formatting therefore used the existing Prettier
Markdown parser with the root style options and no custom plugins; no
dependency installation, submodule initialization, or build was
performed for this documentation-only change. Package/source lint and
test suites are not applicable under the skill-only
lightweight-validation policy. Normal CI is left enabled.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary
Update five lint development/promotion skills to prevent the recurring
review feedback in the supplied 58-comment retrospective across 17
migration PRs. Target `feature/lintdiff-migration-new`, the branch
current when this work was requested.
| Review theme | Comments | Prevention |
| --- | ---: | --- |
| Redundant internal change entries | 28 | Inspect and reuse task-owned
unreleased feature/fix coverage before creating entries; preserve
genuinely needed coverage for other packages. |
| Multiple behavior suites for one public rule | 14 | Extend the
canonical suite, found by its imported rule object even when its
historical filename differs from the public name. |
| Repetitive test headings | 13 | Use file-scope cases or meaningful
scenario groups, preserving scoped setup rather than repeating the
rule/filename. |
| Private fixture APIs | 2 | Use supported public imports/decorators;
redesign or remove artificial private-only cases without changing
production scope. |
| Bespoke Markdown parser | 1 | Enforce the existing prohibition without
relocating the parser or losing distinct semantic/example evidence. |
These are five recurring lessons, not 58 independent design judgments:
55 comments explicitly disclose Copilot generation, and three have no
automation disclosure. Original report IDs 37-39 on #5591 and #5654
remain outside the selection.
## Changes
- `typespec-lint-validate`: define canonical suite ownership and
meaningful grouping; clarify genuine public-entry/package tests versus
duplicate rule execution under import guards; require public fixture
APIs.
- `typespec-lint-implement`: centralize unreleased change-entry
reconciliation and include the shared test policies in
implementation/final review.
- `lintdiff-rule-promote`: replace unconditional creation of a test
file/change entry with discovery and reuse; reconcile
acceptance-evidence and review instructions with the shared policies.
- `develop-lintdiff-rule`: reference the shared policies during test
planning and independent review; preserve migration/corpus requirements.
- `create-linter-rule`: apply the same guidance to scaffold cleanup,
existing-rule extensions, public fixtures, and changelog coverage.
## Evidence and boundaries
- [Changelog guidance, report
22](#5502 (comment))
- [Private APIs, report
23](#5502 (comment))
- [One behavior suite per rule, report
36](#5556 (comment))
- [Historical canonical filename, report
48](#5663 (comment))
- [Isolation-suite duplication, report
53](#5665 (comment))
- [Meaningful scenario grouping, report
55](#5673 (comment))
- [Markdown parser removal, report
33](#5551 (comment))
Keep independent utility tests, genuine package/registration evidence,
rule-owned diagnostic regressions, and actual published-example
validation. Keep separate rulesets-package internal coverage when
needed; do not delete all internal entries. Existing production
semantics, audience/enablement, source immutability, parity evidence,
and required validation remain unchanged.
Skills only: no generator, rule implementation/test, package,
dependency, release entry, or CI changes. The scaffolder's redundant
wrapper is explicitly handled by cleanup guidance; changing the
generator is a separate follow-up.
## Validation
- Scoped Prettier write/check on the five changed Markdown files, using
the repository's scalar formatting settings without optional plugins
because the configured TypeSpec plugin has no built output. No
dependencies or submodules were initialized for this documentation
update.
- Relative Markdown file/heading reference checks and full five-file
diff review.
- `git diff --check` and explicit staged-file scope verification.
No package builds, corpus runs, docs regeneration, or repository-wide
formatting/source linting are needed for this Markdown-only change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ation"
This reverts commit be52108.
Retain opt-in, suppressible lint warnings rather than introducing mandatory validator errors that can break compilation of existing specifications.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Yuchao Yan (msyyc)
changed the title
[Swagger Linter Migration] OperationIdNounConflictingModelNames -> existing client-name validation
[Swagger Linter Migration] OperationIdNounConflictingModelNames -> no-operation-group-name-conflict
Oct 19, 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
int:azure-specsRun integration tests against azure-rest-api-specslib:tcgcIssues for @azure-tools/typespec-client-generator-core librarylinterIssues related to linter rulesmeta:websiteTypeSpec.io updates
4 participants
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
Add
@azure-tools/typespec-client-generator-core/no-operation-group-name-conflictas a small, declaration-based naming guideline. An interface or namespace containing operations should not have the same effective name as a model, scalar, enum or union declared alongside it.The rule ID, diagnostic identity and disabled-by-default client SDK ruleset registration are unchanged. This is a native guideline, not a claim of Swagger equivalence or a prediction of every generated SDK layout.
Latest review changes
This revision addresses Timothee's three design comments:
createTCGCContext's proposedscopeoption, the proposedTCGCContext.scopeproperty, the publicAllScopesexport, associated default-lookup changes, API-specific tests and feature change entry. Existing emitter-scoped context behavior is restored exactly to main.getDefinedLanguageScopesfromvalidations/types.ts. There is no client hierarchy construction or SDK package/type classification.The follow-up cleanup in 801c00043 keeps one representative scoped-name collision, removes redundant unused/model-tree fixtures while retaining direct namespace boundaries, and shortens the guide examples to the conflicting names and rename. No production behavior, public APIs or enablement changed.
Current native contract
For each declared namespace:
@clientNamelookup in common and explicitly configured language scopes, common-name fallback, negated scopes and friendly names.@clientor@clientLocationas synthesized group names. Root operations, empty containers and virtual groups do not create extra checks.Only a normal, non-mutating TCGC context is used for existing naming helpers, following the package's other naming rules. No new context API or public export is needed.
These are intentional policy changes from the previous implementation: unused local declarations now participate, cross-namespace reachable types do not, and explicit language-name collisions are checked. The authored guide, generated rule listings and feature change entry describe this policy.
Examples
An interface renamed to a model's name is flagged:
Naming the interface
Widgetswithout that override is valid. Focused incorrect/correct excerpts are in the authored rule guide.Tests and validation
Validation for the published cleanup at
801c000433b9eecd2e90926d56d0576f65323791:tsc -p tsconfig.build.json --noEmitpassed. Production rule code and shared APIs/utilities were not changed.pnpm format,pnpm lintandgit diff --checkpassed. Existing per-package unreleased entries remain sufficient; no redundant review-history changeset was added.WidgetOperations, versus zero diagnostics. These are contextual excerpts, not standalone specifications. This one-time receipt is not continuous Markdown coverage; no bespoke parser or documentation-testing system remains in the repository.The public-entry-point dependency-isolation guard remains unchanged and continues to verify that
AllScopesis not exported publicly. Rule ID, registration and disabled-by-default ruleset behavior are unchanged.Migration provenance and limits
Original Swagger rule:
That rule compares the segment before the first underscore in serialized operation IDs with Swagger definition names. This native rule instead compares declared group/type names; it does not reconstruct emitted operation IDs, naming transformations or schema inlining.
The earlier development source was #5589, reviewed at
85e2dce677b4733e2e47c28c06300051cea14fcd. Its migration report and historical corpus counts describe the previous graph-based implementation, not acceptance evidence or equivalence for this revision.The previous promotion's source-fidelity and graph-policy claims are superseded by this explicitly requested review redesign. No development-source branch, ARM dependency, dependency manifest, rule ID or ruleset enablement was changed. Bespoke Markdown tests removed in the previous review cleanup remain removed; a standard documentation-testing framework is separate work.