Repository navigation
[Test only] #2
Description
| id | swagger linter | tsp lib / migration group | tsp linter PR | PR created time | PR merged time | approved by | new comment after latest commit | Status | notes |
|---|---|---|---|---|---|---|---|---|---|
| 1 | AdditionalPropertiesAndProperties | @azure-tools/typespec-azure-core/bad-record-type | - | - | - | - | - | Done | - |
| 2 | AllProxyResourcesShouldHaveDelete | @azure-tools/typespec-azure-resource-manager/no-resource-delete-operation | - | - | - | - | - | Done | - |
| 3 | AllTrackedResourcesMustHaveDelete | @azure-tools/typespec-azure-resource-manager/no-resource-delete-operation | - | - | - | - | - | Done | - |
| 4 | ApiHost | TypeSpec structural | - | - | - | - | - | Done | - |
| 5 | ApiVersionParameterRequired | @azure-tools/typespec-azure-core/operation-missing-api-version, @azure-tools/typespec-azure-resource-manager/arm-resource-operation | - | - | - | - | - | Done | - |
| 6 | APIVersionPattern | @azure-tools/typespec-azure-resource-manager/arm-resource-invalid-version-format | - | - | - | - | - | Done | - |
| 7 | ArmResourcePropertiesBag | @azure-tools/typespec-azure-resource-manager/arm-resource-duplicate-property | - | - | - | - | - | Done | - |
| 8 | ArrayMustHaveType | TypeSpec structural | - | - | - | - | - | Done | - |
| 9 | ArraySchemaMustHaveItems | TypeSpec structural | - | - | - | - | - | Done | - |
| 10 | AvoidAdditionalProperties | @azure-tools/typespec-azure-resource-manager/arm-no-record | - | - | - | - | - | Done | - |
| 11 | AvoidEmptyResponseSchema | TypeSpec structural | - | - | - | - | - | Done | - |
| 12 | AvoidNestedProperties | TypeSpec structural | - | - | - | - | - | Done | - |
| 13 | BodyTopLevelProperties | @azure-tools/typespec-azure-resource-manager/arm-resource-invalid-envelope-property | - | - | - | - | - | Done | - |
| 14 | ControlCharactersAreNotAllowed | TypeSpec structural | - | - | - | - | - | Done | - |
| 15 | DefinitionsPropertiesNamesCamelCase | @azure-tools/typespec-azure-core/casing-style | - | - | - | - | - | Done | - |
| 16 | DeleteResponseCodes | @azure-tools/typespec-azure-resource-manager/arm-delete-operation-response-codes, @azure-tools/typespec-azure-resource-manager/no-response-body | - | - | - | - | - | Done | - |
| 17 | EnumMustHaveType | TypeSpec structural | - | - | - | - | - | Done | - |
| 18 | EnumMustNotHaveEmptyValue | TypeSpec structural | - | - | - | - | - | Done | - |
| 19 | EnumMustRespectType | TypeSpec structural | - | - | - | - | - | Done | - |
| 20 | EnumUniqueValue | TypeSpec structural | - | - | - | - | - | Done | - |
| 21 | HostParametersValidation | TypeSpec structural | - | - | - | - | - | Done | - |
| 22 | HttpsSupportedScheme | TypeSpec structural | - | - | - | - | - | Done | - |
| 23 | IntegerTypeMustHaveFormat | TypeSpec structural | - | - | - | - | - | Done | - |
| 24 | InvalidVerbUsed | TypeSpec structural | - | - | - | - | - | Done | - |
| 25 | LroLocationHeader | @azure-tools/typespec-azure-resource-manager/lro-location-header | - | - | - | - | - | Done | - |
| 26 | LroPostMustNotUseOriginalUriAsFinalState | TypeSpec structural | - | - | - | - | - | Done | - |
| 27 | LroStatusCodesReturnTypeSchema | TypeSpec structural | - | - | - | - | - | Done | - |
| 28 | MissingTypeObject | TypeSpec structural | - | - | - | - | - | Done | - |
| 29 | NamePropertyDefinitionInParameter | TypeSpec structural | - | - | - | - | - | Done | - |
| 30 | NextLinkPropertyMustExist | TypeSpec structural | - | - | - | - | - | Done | - |
| 31 | NoDuplicatePathsForScopeParameter | TypeSpec structural | - | - | - | - | - | Done | - |
| 32 | NonEmptyClientName | TypeSpec structural | - | - | - | - | - | Done | - |
| 33 | Nullable | @azure-tools/typespec-azure-core/no-nullable | - | - | - | - | - | Done | - |
| 34 | OperationIdRequired | TypeSpec structural | - | - | - | - | - | Done | - |
| 35 | OperationIdSingleUnderscore | TypeSpec structural | - | - | - | - | - | Done | - |
| 36 | OperationsAPIImplementation | @azure-tools/typespec-azure-resource-manager/missing-operations-endpoint | - | - | - | - | - | Done | - |
| 37 | OperationsApiTenantLevelOnly | TypeSpec structural | - | - | - | - | - | Done | - |
| 38 | OperationSummaryOrDescription | @azure-tools/typespec-azure-core/documentation-required | - | - | - | - | - | Done | - |
| 39 | ParameterDescription | @azure-tools/typespec-azure-core/documentation-required | - | - | - | - | - | Done | - |
| 40 | ParameterDescriptionRequired | @azure-tools/typespec-azure-core/documentation-required | - | - | - | - | - | Done | - |
| 41 | ParameterNotDefinedInGlobalParameters | TypeSpec structural | - | - | - | - | - | Done | - |
| 42 | ParameterOrder | TypeSpec structural | - | - | - | - | - | Done | - |
| 43 | ParametersOrder | TypeSpec structural | - | - | - | - | - | Done | - |
| 44 | PatchContentType | TypeSpec structural | - | - | - | - | - | Done | - |
| 45 | PathForResourceAction | TypeSpec structural | - | - | - | - | - | Done | - |
| 46 | PathResourceTypeNameCamelCase | @azure-tools/typespec-azure-resource-manager/arm-resource-path-segment-invalid-chars | - | - | - | - | - | Done | - |
| 47 | PropertiesTypeObjectNoDefinition | @azure-tools/typespec-azure-resource-manager/no-empty-model | - | - | - | - | - | Done | - |
| 48 | PropertyDescription | @azure-tools/typespec-azure-core/documentation-required | - | - | - | - | - | Done | - |
| 49 | ProvisioningStateMustBeReadOnly | @azure-tools/typespec-azure-resource-manager/arm-resource-provisioning-state | - | - | - | - | - | Done | - |
| 50 | ProvisioningStateSpecifiedForLROPatch | TypeSpec structural | - | - | - | - | - | Done | - |
| 51 | ProvisioningStateSpecifiedForLROPut | TypeSpec structural | - | - | - | - | - | Done | - |
| 52 | ProvisioningStateValidation | @azure-tools/typespec-azure-resource-manager/arm-resource-provisioning-state | - | - | - | - | - | Done | - |
| 53 | PutGetPatchResponseSchema | @azure-tools/typespec-azure-resource-manager/arm-resource-operation-response | - | - | - | - | - | Done | - |
| 54 | PutResponseCodes | @azure-tools/typespec-azure-resource-manager/arm-put-operation-response-codes | - | - | - | - | - | Done | - |
| 55 | RequestSchemaForTrackedResourcesMustHaveTags | TypeSpec structural | - | - | - | - | - | Done | - |
| 56 | ResourceNameRestriction | @azure-tools/typespec-azure-resource-manager/arm-resource-name-pattern | - | - | - | - | - | Done | - |
| 57 | ResponseSchemaSpecifiedForSuccessStatusCode | @azure-tools/typespec-azure-resource-manager/no-response-body | - | - | - | - | - | Done | - |
| 58 | SchemaDescriptionOrTitle | @azure-tools/typespec-azure-core/documentation-required | - | - | - | - | - | Done | - |
| 59 | SchemaNamesConvention | @azure-tools/typespec-azure-core/casing-style | - | - | - | - | - | Done | - |
| 60 | SubscriptionIdParameterInOperations | TypeSpec structural | - | - | - | - | - | Done | - |
| 61 | SystemDataDefinitionsCommonTypes | @azure-tools/typespec-azure-resource-manager/arm-resource-invalid-envelope-property | - | - | - | - | - | Done | - |
| 62 | TrackedExtensionResourcesAreNotAllowed | @azure-tools/typespec-azure-resource-manager/arm-resource-invalid-envelope-property | - | - | - | - | - | Done | - |
| 63 | TrackedResourceBeyondsThirdLevel | @azure-tools/typespec-azure-resource-manager/beyond-nesting-levels | - | - | - | - | - | Done | - |
| 64 | UniqueClientParameterName | TypeSpec structural | - | - | - | - | - | Done | - |
| 65 | UniqueModelName | TypeSpec structural | - | - | - | - | - | Done | - |
| 66 | ValidResponseCodeRequired | TypeSpec structural | - | - | - | - | - | Done | - |
| 67 | XmsIdentifierValidation | @azure-tools/typespec-azure-resource-manager/missing-x-ms-identifiers | - | - | - | - | - | Done | - |
| 68 | XMSSecretInResponse | @azure-tools/typespec-azure-resource-manager/secret-prop | - | - | - | - | - | Done | - |
| 69 | EnumInsteadOfBoolean | @azure-tools/typespec-azure-core | 5265 | 2026-08-20 | 2026-08-31 | catalinaperalta | - | Done | - |
| 70 | QueryParametersInCollectionGet | @azure-tools/typespec-azure-resource-manager | 5318 | 2026-08-26 | 2026-09-02 | timotheeguerin | - | Done | - |
| 71 | ValidQueryParametersForPointOperations | @azure-tools/typespec-azure-resource-manager | 5273 | 2026-08-20 | 2026-09-03 | catalinaperalta, timotheeguerin | - | Done | - |
| 72 | ParametersInPointGet | @azure-tools/typespec-azure-resource-manager | 5273 | 2026-08-20 | 2026-09-03 | catalinaperalta, timotheeguerin | - | Done | - |
| 73 | NonApplicationJsonType | @azure-tools/typespec-azure-resource-manager | 5302 | 2026-08-25 | 2026-09-03 | timotheeguerin | - | Done | - |
| 74 | GetCollectionOnlyHasValueAndNextLink | @azure-tools/typespec-azure-resource-manager | 5358 | 2026-09-01 | 2026-09-04 | timotheeguerin | - | Done | - |
| 75 | XmsPageableForListCalls | @azure-tools/typespec-azure-resource-manager | 5379 | 2026-09-02 | 2026-09-07 | timotheeguerin | - | Done | - |
| 76 | ParametersInPost | @azure-tools/typespec-azure-resource-manager | 5281 | 2026-08-24 | 2026-09-09 | catalinaperalta, timotheeguerin | - | Done | - |
| 77 | TenantLevelAPIsNotAllowed | @azure-tools/typespec-azure-resource-manager | 5420 | 2026-09-08 | 2026-09-09 | timotheeguerin | - | Done | - |
| 78 | GetInOperationName | @azure-tools/typespec-client-generator-core | 5364 | 2026-09-01 | 2026-09-15 | timotheeguerin | - | Done | - |
| 79 | PutInOperationName | @azure-tools/typespec-client-generator-core | 5457 | 2026-09-11 | 2026-09-15 | timotheeguerin | - | Done | - |
| 80 | ParametersSchemaAsTypeObject | @azure-tools/typespec-azure-resource-manager | 5361 | 2026-09-01 | 2026-09-18 | timotheeguerin | - | Done | - |
| 81 | GuidUsage | @azure-tools/typespec-azure-resource-manager | 5336 | 2026-08-28 | - | - | No | Done | no need |
| 82 | AvoidAnonymousParameter | @azure-tools/typespec-azure-core, @azure-tools/typespec-azure-resource-manager | 5522 | 2026-09-20 | 2026-10-15 | timotheeguerin | - | Done | - |
| 83 | CollectionObjectPropertiesNaming | @azure-tools/typespec-azure-resource-manager | 5582 | 2026-09-29 | 2026-10-15 | timotheeguerin | - | Done | - |
| 84 | SummaryAndDescriptionMustNotBeSame | @azure-tools/typespec-azure-core | 5507 | 2026-09-17 | 2026-10-16 | timotheeguerin | - | Done | - |
| 85 | SubscriptionsAndResourceGroupCasing | @azure-tools/typespec-azure-resource-manager | 5681 | 2026-10-13 | 2026-10-16 | timotheeguerin | - | Done | - |
| 86 | AllResourcesMustHaveGetOperation | @azure-tools/typespec-azure-resource-manager | 5654 | 2026-10-09 | 2026-10-19 | timotheeguerin | - | Done | - |
| 87 | EvenSegmentedPathForPutOperation | @azure-tools/typespec-azure-resource-manager | 5550 | 2026-09-23 | 2026-10-20 | timotheeguerin | - | Done | - |
| 88 | TagsAreNotAllowedForProxyResources | @azure-tools/typespec-azure-resource-manager | 5502 | 2026-09-17 | 2026-10-21 | markcowl, timotheeguerin | - | Done | - |
| 89 | NoErrorCodeResponses | @azure-tools/typespec-azure-resource-manager | 5556 | 2026-09-23 | 2026-10-21 | timotheeguerin | - | Done | - |
| 90 | GetResponseCodes | @azure-tools/typespec-azure-resource-manager | 5556 | 2026-09-23 | 2026-10-21 | timotheeguerin | - | Done | - |
| 91 | ExtensionResourcePathPattern | @azure-tools/typespec-azure-resource-manager | 5684 | 2026-10-13 | 2026-10-21 | timotheeguerin | - | Done | - |
| 92 | PatchInOperationName | @azure-tools/typespec-client-generator-core | 5673 | 2026-10-12 | 2026-10-22 | timotheeguerin | - | Done | - |
| 93 | DeleteInOperationName | @azure-tools/typespec-client-generator-core | 5673 | 2026-10-12 | 2026-10-22 | timotheeguerin | - | Done | - |
| 94 | LroErrorContent | @azure-tools/typespec-azure-resource-manager | 5451 | 2026-09-11 | 2026-10-29 | markcowl, timotheeguerin | - | Done | - |
| 95 | PostResponseCodes | @azure-tools/typespec-azure-resource-manager | 5638 | 2026-10-08 | 2026-10-29 | timotheeguerin | - | Done | - |
| 96 | XmsExamplesRequired | - | 5398 | - | - | - | - | Hold on | - |
| 97 | LatestVersionOfCommonTypesMustBeUsed | @azure-tools/typespec-azure-resource-manager | 5271 | 2026-08-20 | - | - | No | Doing | - |
| 98 | PatchBodyParametersSchema | @azure-tools/typespec-azure-resource-manager | 5294 | 2026-08-25 | - | - | Yes | Doing | - |
| 99 | UnSupportedPatchProperties | @azure-tools/typespec-azure-resource-manager | 5294 | 2026-08-25 | - | - | Yes | Doing | - |
| 100 | ConsistentResponseSchemaForPut | @azure-tools/typespec-azure-resource-manager | 5423 | 2026-09-08 | - | - | No | Doing | - |
| 101 | ConsistentPatchProperties | @azure-tools/typespec-azure-resource-manager | 5294 | 2026-08-25 | - | - | Yes | Doing | - |
| 102 | PatchPropertiesCorrespondToPutProperties | @azure-tools/typespec-azure-resource-manager | 5481 | 2026-09-15 | - | - | No | Doing | - |
| 103 | PutRequestResponseSchemeArm | @azure-tools/typespec-azure-resource-manager | 5423 | 2026-09-08 | - | - | No | Doing | - |
| 104 | XmsResourceInPutResponse | @azure-tools/typespec-azure-resource-manager | 5423 | 2026-09-08 | - | - | No | Doing | - |
| 105 | RepeatedPathInfo | @azure-tools/typespec-azure-resource-manager | 5526 | 2026-09-21 | - | - | No | Doing | - |
| 106 | AvoidAnonymousTypes | @azure-tools/typespec-azure-core, @azure-tools/typespec-azure-resource-manager | 5551 | 2026-09-23 | - | - | No | Doing | - |
| 107 | OperationIdNounConflictingModelNames | @azure-tools/typespec-client-generator-core | 5591 | 2026-09-29 | - | timotheeguerin | No | Doing | - |
| 108 | LroExtension | @azure-tools/typespec-azure-resource-manager | 5652 | 2026-10-09 | - | - | No | Doing | - |
| 109 | DescriptionMustNotBeNodeName | @azure-tools/typespec-azure-core | 5663 | 2026-10-10 | - | - | No | Doing | - |
| 110 | DescriptiveDescriptionRequired | @azure-tools/typespec-azure-core | 5663 | 2026-10-10 | - | - | No | Doing | - |
| 111 | XMSLongRunningOperationProperty | @azure-tools/typespec-azure-resource-manager | 5652 | 2026-10-09 | - | - | No | Doing | - |
| 112 | ImplementPrivateEndpointAPIs | @azure-tools/typespec-azure-resource-manager | 5766 | 2026-10-19 | - | - | No | Doing | - |
| 113 | DeleteResponseBodyEmpty | @azure-tools/typespec-azure-resource-manager | 5866 | 2026-10-28 | - | timotheeguerin | No | Doing | - |
| 114 | GetOperationMustNotBeLongRunning | @azure-tools/typespec-azure-core, @azure-tools/typespec-azure-resource-manager, @azure-tools/typespec-client-generator-core | 5889 | 2026-10-29 | - | - | No | Doing | - |
| 115 | PathContainsResourceGroup | @azure-tools/typespec-azure-resource-manager | 5859 | 2026-10-28 | - | timotheeguerin | No | Doing | - |
| 116 | SystemDataInPropertiesBag | @azure-tools/typespec-azure-resource-manager | 5892 | 2026-10-29 | - | - | No | Doing | - |
| 117 | ReservedNamesInPropertiesBag | - | - | - | - | - | - | To do | - |
| 118 | AvoidMsdnReferences | C1 - Documentation links | - | - | - | - | - | To do | - |
| 119 | InvalidSkuModel | - | - | - | - | - | - | To do | - |
| 120 | ListInOperationName | - | - | - | - | - | - | To do | - |
| 121 | LocationMustHaveXmsMutability | - | - | - | - | - | - | To do | - |
| 122 | LongRunningOperationsOptionsValidator | - | - | - | - | - | - | To do | - |
| 123 | LroPatch202 | M4 - PATCH response codes | - | - | - | - | - | To do | - |
| 124 | PatchResponseCodes | M4 - PATCH response codes | - | - | - | - | - | To do | - |
| 125 | MissingSegmentsInNestedResourceListOperation | - | - | - | - | - | - | To do | - |
| 126 | MissingXmsErrorResponse | - | - | - | - | - | - | To do | - |
| 127 | MutabilityWithReadOnly | - | - | - | - | - | - | To do | - |
| 128 | NestedResourcesMustHaveListOperation | C6 - Required collections | - | - | - | - | - | To do | - |
| 129 | TopLevelResourcesListByResourceGroup | C6 - Required collections | - | - | - | - | - | To do | - |
| 130 | OperationIdNounVerb | - | - | - | - | - | - | To do | - |
| 131 | OperationsApiResponseSchema | C8 - Canonical operations response | - | - | - | - | - | To do | - |
| 132 | OperationsApiSchemaUsesCommonTypes | C8 - Canonical operations response | - | - | - | - | - | To do | - |
| 133 | PageableRequires200Response | C7 - Pagination | - | - | - | - | - | To do | - |
| 134 | XmsPageableMustHaveCorrespondingResponse | C7 - Pagination | - | - | - | - | - | To do | - |
| 135 | ParameterNotUsingCommonTypes | - | - | - | - | - | - | To do | - |
| 136 | PatchIdentityProperty | C4 - PATCH envelope | - | - | - | - | - | To do | - |
| 137 | PatchSkuProperty | C4 - PATCH envelope | - | - | - | - | - | To do | - |
| 138 | PathContainsResourceType | - | - | - | - | - | - | To do | - |
| 139 | PathForNestedResource | - | - | - | - | - | - | To do | - |
| 140 | PathForTrackedResourceTypes | - | - | - | - | - | - | To do | - |
| 141 | PathResourceProviderNamePascalCase | - | - | - | - | - | - | To do | - |
| 142 | PostOperationIdContainsUrlVerb | - | - | - | - | - | - | To do | - |
| 143 | PreviewVersionOverOneYear | - | - | - | - | - | - | To do | - |
| 144 | PutRequestResponseScheme | - | - | - | - | - | - | To do | - |
| 145 | RequestBodyMustExistForPutPatch | - | - | - | - | - | - | To do | - |
| 146 | ReservedResourceNamesModelAsEnum | - | - | - | - | - | - | To do | - |
| 147 | ResourceHasXMsResourceEnabled | - | - | - | - | - | - | To do | - |
| 148 | TrackedResourcePatchOperation | M5 - Tracked-resource lifecycle | - | - | - | - | - | To do | - |
| 149 | TrackedResourcesMustHavePut | M5 - Tracked-resource lifecycle | - | - | - | - | - | To do | - |
| 150 | ValidFormats | - | - | - | - | - | - | To do | - |
| 151 | XmsPathsMustOverloadPaths | - | - | - | - | - | - | To do | - |
| 152 | docLinkLocale | C1 - Documentation links | - | - | - | - | - | Need investigation | - |
| 153 | TopLevelResourcesListBySubscription | C6 - Required collections | - | - | - | - | - | Need investigation | - |
| 154 | PageableOperation | C7 - Pagination | - | - | - | - | - | Need investigation | - |
| 155 | AzureResourceTagsSchema | - | - | - | - | - | - | Need investigation | - |
| 156 | DefaultErrorResponseSchema | - | - | - | - | - | - | Need investigation | - |
| 157 | DefaultInEnum | - | - | - | - | - | - | Need investigation | - |
| 158 | DeleteMustNotHaveRequestBody | M3 - Request-body prohibition | - | - | - | - | - | Need investigation | - |
| 159 | GetMustNotHaveRequestBody | M3 - Request-body prohibition | - | - | - | - | - | Need investigation | - |
| 160 | DeleteOperationResponses | - | - | - | - | - | - | Need investigation | - |
| 161 | DeprecatedXmsCodeGenerationSetting | M2 - Legacy SDK settings | - | - | - | - | - | Need investigation | - |
| 162 | LicenseHeaderMustNotBeSpecified | M2 - Legacy SDK settings | - | - | - | - | - | Need investigation | - |
| 163 | GetCollectionResponseSchema | - | - | - | - | - | - | Need investigation | - |
| 164 | LroWithOriginalUriAsFinalState | - | - | - | - | - | - | Need investigation | - |
| 165 | MissingDefaultResponse | C5 - Default-error response | - | - | - | - | - | Need investigation | - |
| 166 | RequiredDefaultResponse | C5 - Default-error response | - | - | - | - | - | Need investigation | - |
| 167 | PathContainsSubscriptionId | - | - | - | - | - | - | Need investigation | - |
| 168 | PathResourceProviderMatchNamespace | - | - | - | - | - | - | Need investigation | - |
| 169 | PrivateEndpointResourceSchemaValidation | - | - | - | - | - | - | Need investigation | - |
| 170 | RequiredPropertiesMissingInResourceModel | - | - | - | - | - | - | Need investigation | - |
| 171 | RequiredReadOnlySystemData | - | - | - | - | - | - | Need investigation | - |
| 172 | Rpaas_ResourceProvisioningState | - | - | - | - | - | - | Need investigation | - |
| 173 | SecurityDefinitionsStructure | - | - | - | - | - | - | Need investigation | - |
| 174 | UniqueXmsEnumName | - | - | - | - | - | - | Need investigation | - |
| 175 | UniqueXmsExample | - | - | - | - | - | - | Need investigation | - |
| 176 | XmsClientNameParameter | M1 - Redundant client name | - | - | - | - | - | Need investigation | - |
| 177 | XmsClientNameProperty | M1 - Redundant client name | - | - | - | - | - | Need investigation | - |
| 178 | XmsClientName | M1 - Redundant client name | - | - | - | - | - | Need investigation | - |
| 179 | XmsEnumValidation | - | - | - | - | - | - | Need investigation | - |
| 180 | XmsPageableListByRGAndSubscriptions | - | - | - | - | - | - | Need investigation | - |
| 181 | XmsParameterLocation | - | - | - | - | - | - | Need investigation | - |
Migration groups: Linked labels appear below package/rule information, or alone if unknown. M = merge/subsumption candidate; C = conditional/shared-owner family. Grouping means coordinated work, not accepted coverage, completion, or enablement. See the consolidation analysis and the ordering policy below.
AI update notes
Test tracker destination
This copy records migration data only in msyyc/typespec-azure#2. Keep $repo = 'Azure/typespec-azure' for PR discovery, pinned PRs, changed files, reviews, comments, commits, and PR links. Use $issueRepo = 'msyyc/typespec-azure' and $issueNumber = 2 for tracker reads, concurrency checks, writes, and saved-body verification. Running with -Apply updates this test issue only; it must not update Azure#5274. All discovery, group membership, metadata, protected-row, and notes-preservation rules remain unchanged. The status-first ordering policy below applies to both the table and reusable script.
Keep exactly 181 unique Swagger rules and ten columns. Refresh PR metadata only for rows not already Done or Hold on. Preserve all data cells of those protected rows and every row's existing notes; only position/ID may change. Never derive notes from PR content.
Discovery and consolidation pins
Use titles [Swagger Linter Migration] <SwaggerRuleName> -> <TypeSpecRuleName> (spaces around -> recommended). Search using the original Swagger name, accepting legacy titles too; require whitespace, ->, or end-of-title after the name, and exclude (origin). Do not rename Swagger entries or infer packages from titles.
Consult $pinnedPrs before title discovery. Fetch pinned PRs directly, bypassing title matching, but never bypass protected rows or other validation. The following mappings are authoritative:
| Swagger rules | PR / native owner | Provenance and boundaries |
|---|---|---|
| ConsistentResponseSchemaForPut, PutRequestResponseSchemeArm, XmsResourceInPutResponse | #5423 / put-resource-schema-consistency | Supersedes Azure#5493 and Azure#5503 (closed as superseded). Not enabled yet. Preserve arm-put-operation-response-codes (complete PUT status set) and arm-resource-operation-response (canonical resource across lifecycle operations); intra-PUT consistency cannot replace them. |
| PatchBodyParametersSchema, ConsistentPatchProperties, UnSupportedPatchProperties | #5294 / no-unsafe-patch-body-properties | Azure#5456 and Azure#5384 remain open, proposed for supersession only after coverage acceptance; this mapping neither accepts coverage nor authorizes closure. PatchPropertiesCorrespondToPutProperties (Azure#5481) stays separate. |
| DescriptionMustNotBeNodeName, DescriptiveDescriptionRequired | #5663 / azure-core documentation-required | Absorbs implementation/tests from Azure#5674, closed as superseded. |
| NoErrorCodeResponses, GetResponseCodes | #5556 / ARM use-standard-response-codes | Absorbs implementation/tests from Azure#5585, closed as superseded. |
| LroExtension, XMSLongRunningOperationProperty | #5652 / ARM lro-missing-polling-metadata | Absorbs official policy/unique tests from Azure#5709, closed as superseded. Preserve ARM response-code/header-presence rules. A disabled central entry does not mean universal disablement: ARM library all includes the registered rule. |
| PutInOperationName, PatchInOperationName, DeleteInOperationName | #5673 / TCGC use-correct-verb | Azure#5665 (PATCH) is closed as superseded. Azure#5457 (PUT) genuinely merged: keep that Done row's original PR, merge date, and all cells. Only eligible PATCH/DELETE rows refresh from Azure#5673. |
Do not fall back to superseded PRs or equate closure/supersession with completion. Eligible mapped rows are Doing while their replacement is open and Done only after it merges. Consolidation implies neither CI/review acceptance, equivalent coverage, retirement of existing checks, nor automatic enablement.
Grouping and ordering
Reuse tsp lib / migration group; keep notes rightmost. Infer package information from changed files under packages/typespec-azure-core, packages/typespec-azure-resource-manager, and packages/typespec-client-generator-core, using corresponding @azure-tools/ package names. Preserve existing package/rule information when no PR is found. Append each configured linked group with <br>, or show the group alone when the library is unknown. Never infer a library/native rule from a group label.
$migrationGroups and $reviewedRules define membership/order by Swagger name, never current row ID: 11 groups / 25 rules from M1-M5, C1, C4-C8 in the linked analysis. M means merge/subsumption candidate; C means conditional/shared-owner family, not necessarily one lint. Optional C5 member DefaultErrorResponseSchema stays ungrouped; C2 route helpers and C3 independent naming predicates are not merger groups.
Sort all 181 rules by status first: Done, Hold on, Doing, To do, Need investigation. Each status must form one contiguous block, including all Doing rows regardless of reviewed-rule membership. Within each status, keep other rules first in their existing relative order, followed by reviewed rules in name-keyed group/original order. Group blocks anchor at the earliest original member; preserve original member/ungrouped order within that status. Status takes priority over reviewed sections and group adjacency: split a migration group across status blocks when members have different statuses. Renumber IDs. Preserve group labels during metadata refresh. Future group edits affecting protected cells require explicit user authorization.
Metadata and safety
For valid PRs, fill PR link, creation/merge dates (UTC), libraries, approvals, and status. For open PRs, use each eligible reviewer's latest decisive APPROVED/CHANGES_REQUESTED/DISMISSED review; comments do not revoke approvals. Exclude the author and bots; use real User aliases.
Set new-comment to - when merged. Otherwise compare head commit committer time with top-level and inline comments' created_at and nonempty review summaries' submitted_at; Yes if eligible feedback is later, otherwise No. Check all three API surfaces, not PR updatedAt or gh pr view comments alone.
Read issue JSON via gh api, joining CLI output with newlines before ConvertFrom-Json. Never stringify a multiline body array. Write UTF-8 without BOM. Accept LF/CRLF rows; require 181 unique ten-cell rows, consecutive IDs, preserved protected cells/notes, correct group annotations/layout, complete files, and stable PR snapshots. Abort on ambiguity, incomplete data, or concurrent issue edits; verify the exact saved body. Preserve all non-table content during routine refresh.
Reusable PowerShell update script
Requires PowerShell 7+ and an authenticated GitHub CLI (gh). Save the script below as refresh-arm-linter-issue.ps1. The authenticated account needs issue-edit permission when applying changes.
- Preview without changing the issue:
pwsh -File .\refresh-arm-linter-issue.ps1 - Refresh the issue:
pwsh -File .\refresh-arm-linter-issue.ps1 -Apply
The script sorts every row by status first, keeping all Doing rows together, then applies the name-keyed grouping/order policy within each status (including group annotations alongside inferred packages), preserves all Done and Hold on row data (apart from sorting and renumbering IDs), preserves existing notes for every row, and preserves all content outside the table (including this section). It checks all three feedback surfaces and stops on ambiguous PRs or incomplete data. Dates are UTC. It also recognizes @azure-tools/typespec-client-generator-core when that package contains the implementation. Review the notes before running in case the update policy changes.
# Requires PowerShell 7+ and an authenticated GitHub CLI (gh).
# Preview: pwsh -File .\refresh-arm-linter-issue.ps1
# Update: pwsh -File .\refresh-arm-linter-issue.ps1 -Apply
[CmdletBinding()]
param([switch]$Apply)
$ErrorActionPreference = 'Stop'
$repo = 'Azure/typespec-azure'
$issueRepo = 'msyyc/typespec-azure'
$issueNumber = 2
$expectedRows = 181
$statusOrder = @{ 'Done' = 0; 'Hold on' = 1; 'Doing' = 2; 'To do' = 3; 'Need investigation' = 4 }
$pinnedPrs = @{
'ConsistentResponseSchemaForPut' = 5423
'PutRequestResponseSchemeArm' = 5423
'XmsResourceInPutResponse' = 5423
'PatchBodyParametersSchema' = 5294
'ConsistentPatchProperties' = 5294
'UnSupportedPatchProperties' = 5294
'DescriptionMustNotBeNodeName' = 5663
'DescriptiveDescriptionRequired' = 5663
'NoErrorCodeResponses' = 5556
'GetResponseCodes' = 5556
'LroExtension' = 5652
'XMSLongRunningOperationProperty' = 5652
'PutInOperationName' = 5673
'PatchInOperationName' = 5673
'DeleteInOperationName' = 5673
}
$migrationGroups = @(
@{ Id = 'M1'; Label = 'Redundant client name'; Members = @('XmsClientNameParameter', 'XmsClientNameProperty', 'XmsClientName') }
@{ Id = 'M2'; Label = 'Legacy SDK settings'; Members = @('DeprecatedXmsCodeGenerationSetting', 'LicenseHeaderMustNotBeSpecified') }
@{ Id = 'M3'; Label = 'Request-body prohibition'; Members = @('GetMustNotHaveRequestBody', 'DeleteMustNotHaveRequestBody') }
@{ Id = 'M4'; Label = 'PATCH response codes'; Members = @('PatchResponseCodes', 'LroPatch202') }
@{ Id = 'M5'; Label = 'Tracked-resource lifecycle'; Members = @('TrackedResourcesMustHavePut', 'TrackedResourcePatchOperation') }
@{ Id = 'C1'; Label = 'Documentation links'; Members = @('AvoidMsdnReferences', 'docLinkLocale') }
@{ Id = 'C4'; Label = 'PATCH envelope'; Members = @('PatchIdentityProperty', 'PatchSkuProperty') }
@{ Id = 'C5'; Label = 'Default-error response'; Members = @('RequiredDefaultResponse', 'MissingDefaultResponse') }
@{ Id = 'C6'; Label = 'Required collections'; Members = @('NestedResourcesMustHaveListOperation', 'TopLevelResourcesListByResourceGroup', 'TopLevelResourcesListBySubscription') }
@{ Id = 'C7'; Label = 'Pagination'; Members = @('PageableOperation', 'PageableRequires200Response', 'XmsPageableMustHaveCorrespondingResponse') }
@{ Id = 'C8'; Label = 'Canonical operations response'; Members = @('OperationsApiResponseSchema', 'OperationsApiSchemaUsesCommonTypes') }
)
$reviewedRules = @(
'AvoidMsdnReferences'
'DeleteResponseBodyEmpty'
'GetOperationMustNotBeLongRunning'
'InvalidSkuModel'
'ListInOperationName'
'LocationMustHaveXmsMutability'
'LongRunningOperationsOptionsValidator'
'LroPatch202'
'MissingSegmentsInNestedResourceListOperation'
'MissingXmsErrorResponse'
'MutabilityWithReadOnly'
'NestedResourcesMustHaveListOperation'
'OperationIdNounVerb'
'OperationsApiResponseSchema'
'OperationsApiSchemaUsesCommonTypes'
'PageableRequires200Response'
'ParameterNotUsingCommonTypes'
'PatchIdentityProperty'
'PatchResponseCodes'
'PatchSkuProperty'
'PathContainsResourceGroup'
'PathContainsResourceType'
'PathForNestedResource'
'PathForTrackedResourceTypes'
'PathResourceProviderNamePascalCase'
'PostOperationIdContainsUrlVerb'
'PreviewVersionOverOneYear'
'PutRequestResponseScheme'
'RequestBodyMustExistForPutPatch'
'ReservedResourceNamesModelAsEnum'
'ResourceHasXMsResourceEnabled'
'TopLevelResourcesListByResourceGroup'
'TrackedResourcePatchOperation'
'TrackedResourcesMustHavePut'
'ValidFormats'
'XmsPageableMustHaveCorrespondingResponse'
'XmsPathsMustOverloadPaths'
'AzureResourceTagsSchema'
'DefaultErrorResponseSchema'
'DefaultInEnum'
'DeleteMustNotHaveRequestBody'
'DeleteOperationResponses'
'DeprecatedXmsCodeGenerationSetting'
'docLinkLocale'
'GetCollectionResponseSchema'
'GetMustNotHaveRequestBody'
'LicenseHeaderMustNotBeSpecified'
'LroWithOriginalUriAsFinalState'
'MissingDefaultResponse'
'PageableOperation'
'PathContainsSubscriptionId'
'PathResourceProviderMatchNamespace'
'PrivateEndpointResourceSchemaValidation'
'RequiredDefaultResponse'
'RequiredPropertiesMissingInResourceModel'
'RequiredReadOnlySystemData'
'Rpaas_ResourceProvisioningState'
'SecurityDefinitionsStructure'
'SystemDataInPropertiesBag'
'TopLevelResourcesListBySubscription'
'UniqueXmsEnumName'
'UniqueXmsExample'
'XmsClientNameParameter'
'XmsClientNameProperty'
'XmsEnumValidation'
'XmsPageableListByRGAndSubscriptions'
'XmsParameterLocation'
'XmsClientName'
)
$reviewedRank = @{}
for ($i = 0; $i -lt $reviewedRules.Count; $i++) {
if ($reviewedRank.ContainsKey($reviewedRules[$i])) { throw 'Duplicate reviewed rule.' }
$reviewedRank[$reviewedRules[$i]] = $i
}
$groupByRule = @{}
$groupRank = @{}
foreach ($group in $migrationGroups) {
$anchorRank = ($group.Members | ForEach-Object {
if (-not $reviewedRank.ContainsKey($_)) { throw "Unknown group member: $_" }
$reviewedRank[$_]
} | Measure-Object -Minimum).Minimum
foreach ($rule in $group.Members) {
if ($groupByRule.ContainsKey($rule)) { throw "Duplicate group membership: $rule" }
$groupByRule[$rule] = $group
$groupRank[$rule] = $anchorRank
}
}
function Format-MigrationLibrary([string]$Rule, [string]$Library) {
if (-not $groupByRule.ContainsKey($Rule)) { return $Library }
$group = $groupByRule[$Rule]
$annotation = "[$($group.Id) - $($group.Label)][migration-$($group.Id)]"
if ($Library -ceq $annotation) { return $annotation }
if ($Library.EndsWith("<br>$annotation", [StringComparison]::Ordinal)) { return $Library }
if ($Library -eq '-' -or [string]::IsNullOrWhiteSpace($Library)) { return $annotation }
"$Library<br>$annotation"
}
function Get-OrderedRows([object[]]$Rows) {
$Rows | Sort-Object { $statusOrder[$_.Cells[8]] }, {
if ($reviewedRank.ContainsKey($_.Rule)) { 1 } else { 0 }
}, {
if ($groupRank.ContainsKey($_.Rule)) { $groupRank[$_.Rule] }
elseif ($reviewedRank.ContainsKey($_.Rule)) { $reviewedRank[$_.Rule] }
else { $_.OriginalId }
}, {
if ($reviewedRank.ContainsKey($_.Rule)) { $reviewedRank[$_.Rule] }
else { $_.OriginalId }
}
}
function Assert-MigrationLayout([object[]]$Rows) {
foreach ($rule in $reviewedRules) {
if ($rule -notin $Rows.Rule) { throw "Missing reviewed rule: $rule" }
}
foreach ($row in $Rows) {
if ($row.Cells[2] -cne (Format-MigrationLibrary $row.Rule $row.Cells[2])) {
throw "Missing migration-group annotation: $($row.Rule)"
}
}
for ($i = 1; $i -lt $Rows.Count; $i++) {
if ($statusOrder[$Rows[$i].Cells[8]] -lt $statusOrder[$Rows[$i - 1].Cells[8]]) {
throw 'Statuses must form contiguous blocks: Done, Hold on, Doing, To do, Need investigation.'
}
}
$ordered = @(Get-OrderedRows $Rows)
if (($Rows.Rule -join '|') -cne ($ordered.Rule -join '|')) {
throw 'Incorrect status-first/migration-group ordering.'
}
}
function Get-GitHubJson([string[]]$Arguments) {
$raw = & gh @Arguments
if ($LASTEXITCODE -ne 0) { throw "GitHub command failed: gh $($Arguments -join ' ')" }
($raw -join "`n") | ConvertFrom-Json
}
function Get-Api([string]$Path, [switch]$Paginate) {
if ($Paginate) {
$pages = Get-GitHubJson @('api', $Path, '--paginate', '--slurp')
foreach ($page in $pages) { foreach ($item in $page) { $item } }
} else {
Get-GitHubJson @('api', $Path)
}
}
function Test-EligibleUser($User, [string]$Author) {
$User.type -eq 'User' -and $User.login -ne $Author -and $User.login -notmatch '\[bot\]$'
}
function Get-Rows([string]$Body) {
foreach ($line in ($Body -split "`n")) {
if ($line -notmatch '^\| \d+ \|') { continue }
if ($line -notmatch '^\|(?:[^|\r\n]*\|){10}\r?$') { throw 'Malformed table row.' }
$cells = @($line.Split('|')[1..10] | ForEach-Object { $_.Trim() })
if (-not $statusOrder.ContainsKey($cells[8])) { throw "Unknown status: $($cells[8])" }
$rule = if ($cells[1] -match '^\[([^\]]+)\]') { $Matches[1] } else { $cells[1] }
[pscustomobject]@{ OriginalId = [int]$cells[0]; Rule = $rule; Cells = $cells }
}
}
function Assert-Table([object[]]$Rows) {
if ($Rows.Count -ne $expectedRows -or @($Rows.Rule | Sort-Object -Unique).Count -ne $expectedRows) {
throw "Expected exactly $expectedRows unique rules."
}
for ($i = 0; $i -lt $Rows.Count; $i++) {
if ($Rows[$i].OriginalId -ne $i + 1) { throw 'IDs must be consecutive from 1.' }
}
}
$issue = Get-Api "repos/$issueRepo/issues/$issueNumber"
$originalBody = $issue.body
$rows = @(Get-Rows $originalBody)
Assert-Table $rows
$allPrs = @(Get-GitHubJson @(
'pr', 'list', '--repo', $repo, '--state', 'all',
'--search', '"[Swagger Linter Migration]" in:title',
'--limit', '1000', '--json', 'number,title'
))
if ($allPrs.Count -ge 1000) { throw 'PR search may be truncated; narrow or paginate the search.' }
$candidates = @($allPrs | Where-Object { $_.title -notmatch '\(origin\)' })
$changes = [Collections.Generic.List[object]]::new()
foreach ($row in $rows) {
if ($row.Cells[8] -in @('Done', 'Hold on')) { continue }
$row.Cells[2] = Format-MigrationLibrary $row.Rule $row.Cells[2]
# Match the original Swagger name in legacy titles and OldRule -> new-rule mappings.
$pattern = '^\[Swagger Linter Migration\]\s+' + [regex]::Escape($row.Rule) + '(?=\s|->|$)'
$isPinned = $pinnedPrs.ContainsKey($row.Rule)
if ($isPinned) {
$number = $pinnedPrs[$row.Rule]
} else {
$matching = @($candidates | Where-Object { $_.title -match $pattern })
if ($matching.Count -gt 1) { throw "Multiple matching PRs for $($row.Rule); resolve manually." }
if ($matching.Count -eq 0) {
if ($row.Cells[3] -match '/pull/\d+') {
throw "Existing PR for $($row.Rule) was not found in search; investigate before updating."
}
continue
}
$number = $matching[0].number
}
$pr = Get-Api "repos/$repo/pulls/$number"
if (-not $isPinned -and ($pr.title -notmatch $pattern -or $pr.title -match '\(origin\)')) {
throw "PR #$number title changed."
}
if (-not $pr.merged -and $pr.state -ne 'open') {
throw "PR #$number is closed without merging; resolve its table status manually."
}
$files = @(Get-Api "repos/$repo/pulls/$number/files?per_page=100" -Paginate)
if ($files.Count -ne $pr.changed_files) { throw "Incomplete changed-file list for PR #$number." }
$libs = @(
foreach ($package in @('typespec-azure-core', 'typespec-azure-resource-manager', 'typespec-client-generator-core')) {
if ($files.filename -like "packages/$package/*") { "@azure-tools/$package" }
}
)
if (-not $libs.Count) { throw "Unrecognized library in PR #$number; extend the package mapping." }
$reviews = @(Get-Api "repos/$repo/pulls/$number/reviews?per_page=100" -Paginate)
# A later change request or dismissal supersedes an approval; a comment does not.
$approvals = @($reviews | Where-Object {
(Test-EligibleUser $_.user $pr.user.login) -and
$_.state -in @('APPROVED', 'CHANGES_REQUESTED', 'DISMISSED')
} | Group-Object { $_.user.login } | ForEach-Object {
$last = $_.Group | Sort-Object { [DateTimeOffset]$_.submitted_at }, id | Select-Object -Last 1
if ($last.state -eq 'APPROVED') { $last.user.login }
} | Sort-Object -Unique)
$feedbackFlag = '-'
if (-not $pr.merged) {
$comments = @(Get-Api "repos/$repo/issues/$number/comments?per_page=100" -Paginate)
$inline = @(Get-Api "repos/$repo/pulls/$number/comments?per_page=100" -Paginate)
$head = Get-Api "repos/$repo/commits/$($pr.head.sha)"
$latest = [DateTimeOffset]$head.commit.committer.date
$feedback = @(
@($comments) + @($inline) | Where-Object {
(Test-EligibleUser $_.user $pr.user.login) -and
[DateTimeOffset]$_.created_at -gt $latest
}
$reviews | Where-Object {
(Test-EligibleUser $_.user $pr.user.login) -and
-not [string]::IsNullOrWhiteSpace($_.body) -and
$_.submitted_at -and [DateTimeOffset]$_.submitted_at -gt $latest
}
)
$feedbackFlag = if ($feedback.Count) { 'Yes' } else { 'No' }
}
$fresh = Get-Api "repos/$repo/pulls/$number"
if ($fresh.head.sha -ne $pr.head.sha -or $fresh.state -ne $pr.state -or
$fresh.merged -ne $pr.merged -or $fresh.title -cne $pr.title -or $fresh.body -cne $pr.body) {
throw "PR #$number changed while reading; rerun."
}
$before = $row.Cells[2..9] -join ' | '
$row.Cells[2] = Format-MigrationLibrary $row.Rule ($libs -join ', ')
$row.Cells[3] = "[$number](https://github.com/$repo/pull/$number)"
$row.Cells[4] = ([DateTimeOffset]$pr.created_at).ToString('yyyy-MM-dd')
$row.Cells[5] = if ($pr.merged_at) { ([DateTimeOffset]$pr.merged_at).ToString('yyyy-MM-dd') } else { '-' }
$row.Cells[6] = if ($approvals.Count) { $approvals -join ', ' } else { '-' }
$row.Cells[7] = $feedbackFlag
$row.Cells[8] = if ($pr.merged) { 'Done' } else { 'Doing' }
$after = $row.Cells[2..9] -join ' | '
if ($before -cne $after) {
$changes.Add([pscustomobject]@{ Rule = $row.Rule; Before = $before; After = $after })
}
}
$sorted = @(Get-OrderedRows $rows)
$index = 0
$newLines = foreach ($line in ($originalBody -split "`n")) {
if ($line -match '^\| \d+ \|') {
$sorted[$index].Cells[0] = ($index + 1).ToString()
'| ' + ($sorted[$index].Cells -join ' | ') + ' |'
$index++
} else { $line }
}
$newBody = $newLines -join "`n"
$newRows = @(Get-Rows $newBody)
Assert-Table $newRows
foreach ($old in @(Get-Rows $originalBody)) {
$new = $newRows | Where-Object Rule -eq $old.Rule
if (-not $new) { throw "Lost rule: $($old.Rule)" }
if ($old.Cells[8] -in @('Done', 'Hold on') -and ($old.Cells[1..8] -join '|') -cne ($new.Cells[1..8] -join '|')) {
throw "Modified a protected Done/Hold on row: $($old.Rule)"
}
if ($old.Cells[9] -cne $new.Cells[9]) {
throw "Modified preserved notes: $($old.Rule)"
}
}
Assert-MigrationLayout $newRows
$changes | Format-List
$newRows | Group-Object { $_.Cells[8] } | Select-Object Name, Count | Format-Table
if ($newBody -ceq $originalBody) { Write-Output 'Already up to date; no edit needed.'; return }
if (-not $Apply) { Write-Output 'Preview only. Rerun with -Apply to update the issue.'; return }
$current = Get-Api "repos/$issueRepo/issues/$issueNumber"
if ($current.body -cne $originalBody) { throw 'Issue changed during refresh; rerun to avoid overwriting edits.' }
$tempFile = [IO.Path]::GetTempFileName()
try {
[IO.File]::WriteAllText($tempFile, $newBody, [Text.UTF8Encoding]::new($false))
& gh issue edit $issueNumber --repo $issueRepo --body-file $tempFile
if ($LASTEXITCODE -ne 0) { throw 'Issue update failed.' }
$saved = Get-Api "repos/$issueRepo/issues/$issueNumber"
if ($saved.body -cne $newBody) { throw 'Saved issue differs from proposed body; inspect it before retrying.' }
Assert-Table @(Get-Rows $saved.body)
Assert-MigrationLayout @(Get-Rows $saved.body)
Write-Output "Updated https://github.com/$issueRepo/issues/$issueNumber"
} finally {
Remove-Item -LiteralPath $tempFile
}
Activity