diff --git a/eng/scripts/doc-updater/knowledge/azure-resource-manager.md b/eng/scripts/doc-updater/knowledge/azure-resource-manager.md index efd085f3f1..e62d44a1c9 100644 --- a/eng/scripts/doc-updater/knowledge/azure-resource-manager.md +++ b/eng/scripts/doc-updater/knowledge/azure-resource-manager.md @@ -124,3 +124,17 @@ The library provides an experimental **Agent** base type in `lib/base-types/agen - How-to guide added: `website/src/content/docs/docs/howtos/ARM/agent-base-type.mdx`. - The ARM howtos sidebar is auto-generated from the directory (`current-sidebar.ts` → `autogenerate` on `howtos`), so new how-to files need no manual sidebar registration. - Reference docs (`reference/*.md`) for these lib additions were already regenerated in-commit; no `regen-docs` diff was needed for this batch. + +## Rule Renames (use-* rules) + +The `core-operations` rule was renamed to `use-interface`. Two rules were added: `use-api-version` and `use-operation-decorator`. When auditing docs, ensure no reference to the old `core-operations` name remains and that every rule slug matches a registered rule name. + +## Rule Reference Link Slugs + +Rule reference links in the how-to guides point to `docs/libraries/azure-resource-manager/rules//`, where `` must exactly match the **registered** rule name (including any `arm-`/`arm-resource-` prefix). A common defect is link text using the correct prefixed name while the URL slug drops the prefix (e.g. text `arm-put-operation-response-codes` but URL `rules/put-operation-response-codes)`), producing dead links. `rpc-guidelines-coverage.md` had several of these. Note that some links in these files point to rules owned by other libraries (e.g. `key-visibility-required`, `no-enum`, `non-breaking-versioning`, `operation-missing-api-version`) — those are intentionally un-prefixed. + +## Relationship & BillingData (Experimental) + +- `Relationship` (`lib/base-types/relationship.tsp`, namespace `Azure.ResourceManager.BaseTypes.Relationships`) is an `ExtensionResource` that applies `@azureBaseType(#{ baseType: BaseType.Relationship, version: ... })` automatically. `RelationshipProperties` carries `baseTypes`, `sourceId`/`sourceTenant`, `targetId`/`targetTenant`, `provisioningState`. New rule: `use-relationship-required-properties`. +- `BillingData` (`lib/common-types/billing-data.tsp`, `@added(Versions.v6)`) is a common-type model for resource billing metadata. +- Both are experimental; do not add new getstarted content for them. Reference docs are auto-generated. diff --git a/eng/scripts/doc-updater/knowledge/azure-resource-manager.meta.json b/eng/scripts/doc-updater/knowledge/azure-resource-manager.meta.json index be9d317972..ab3443eeef 100644 --- a/eng/scripts/doc-updater/knowledge/azure-resource-manager.meta.json +++ b/eng/scripts/doc-updater/knowledge/azure-resource-manager.meta.json @@ -1,6 +1,6 @@ { - "lastCommit": "5036a37233b303fd4c59afc2c6c8ffc6d6194e3a", - "lastUpdated": "2026-07-20T10:23:17.492Z", + "lastCommit": "9d5bfaac699cff4defc27914130a65d4bb851390", + "lastUpdated": "2026-08-24T10:12:06.217Z", "analyzedPaths": [ "packages/typespec-azure-resource-manager/src", "packages/typespec-azure-resource-manager/lib", diff --git a/website/src/content/docs/docs/howtos/ARM/rpc-guidelines-coverage.md b/website/src/content/docs/docs/howtos/ARM/rpc-guidelines-coverage.md index 93794e8446..1071308d27 100644 --- a/website/src/content/docs/docs/howtos/ARM/rpc-guidelines-coverage.md +++ b/website/src/content/docs/docs/howtos/ARM/rpc-guidelines-coverage.md @@ -26,36 +26,36 @@ This page maps each RPC guideline to the TypeSpec linting rules that cover or pa The following table lists each ARM RPC rule by its rule number and maps it to the TypeSpec linting rules that provide coverage. For **🔶 partially covered** rules, the **Notes** column describes what is and is not covered, and **service owners are responsible for verifying the uncovered aspects** — specific suggestions are provided where possible. -| RPC Rule | Description | Coverage | TypeSpec Rule(s) | Notes | -| -------- | ----------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| RPC003 | Tracked resource types must support move | ❌ 🏗️ | — | Resource move is configured in the ARM manifest, not in the TypeSpec API specification. **Service owners** must configure resource move support in the ARM manifest. | -| RPC004 | URI must follow ARM standard guidelines (well-formed GET/PUT/DELETE URI tuples) | 🔧 | `arm/arm-resource-path-segment-invalid-chars`, `arm/arm-resource-key-invalid-chars` | Enforced by TypeSpec ARM resource templates (`TrackedResource`, `ProxyResource`) which generate correct URI structures. Path character rules provide additional validation. | -| RPC005 | Provisioning state semantics must be followed (terminal/non-terminal states) | 🔶 🔄 | `arm/arm-resource-provisioning-state` | The rule checks that `provisioningState` is an open union containing the correct terminal states (Succeeded, Failed, Canceled). Runtime behavior (transitioning states on PUT/PATCH/DELETE) cannot be linted. **Service owners** must verify correct provisioning state transitions through integration tests covering resource lifecycle (create, update, delete). | -| RPC006 | Tracked resource types must support GET, PUT, PATCH, DELETE & LIST | 🔶 🟣 | `arm/use-operation-decorator`, `arm/no-resource-delete-operation` | `use-operation-decorator` validates operations use the correct decorator for the HTTP verb. `no-resource-delete-operation` checks resources with createOrUpdate also have delete. **Gap**: No single rule validates the complete set of required operations (GET, PUT, PATCH, DELETE, ListByRG, ListBySub) for tracked resources — a linting rule could and should be added. **Service owners** should verify the complete operation set through API design review until such a rule exists. | -| RPC007 | Resource types must support PATCH for Tags | ✅ | `arm/arm-resource-patch`, `arm/patch-envelope` | `arm-resource-patch` checks that if a resource has `tags`, PATCH includes it. `patch-envelope` validates PATCH includes envelope properties (identity, managedBy, plan, sku, tags). | -| RPC008 | PUT, GET, PATCH & LIST must return the same resource schema | ✅ | `arm/arm-resource-operation-response` | Directly implements RPC 008 — validates that PUT, GET, PATCH, and LIST operations all return the same resource schema. | -| RPC009 | Use PUT for replace, PATCH for partial update (JSON merge-patch) | 🔧 | — | Enforced by ARM TypeSpec operation templates: `ResourceCreateOrUpdate` for PUT and `ResourceUpdate` for PATCH generate the correct patterns. | -| RPC010 | Use PUT or PATCH to update a resource, not POST | ❌ 📐 🟣 | — | No rule prevents using POST for what should be a resource update. `arm/arm-resource-invalid-action-verb` ensures actions use POST/GET verbs but does not check intent. **Service owners** must verify through API design review that POST is not used for operations that semantically perform a full resource update. | -| RPC011.a | PUT on parent must not implicitly create tracked child resources | ❌ 📐 🟣 | — | No rule detects implicit child resource creation in PUT request bodies. **Service owners** must review PUT request schemas during API design review to ensure tracked child resources are not implicitly created. | -| RPC011.b | PUT on parent should avoid implicitly creating proxy child resources | ❌ 📐 🟣 | — | Same gap as RPC011.a. This rule is still being refined. **Service owners** should review PUT request schemas for implicit proxy child creation. | -| RPC012 | Secret property semantics (no secrets in GET/PUT/PATCH responses, use POST list\* action) | 🔶 📐 🔄 | [`arm/secret-prop`](/docs/libraries/azure-resource-manager/rules/secret-prop) | Checks properties with sensitive names (password, key, token, etc.) are marked `@secret`. **Service owners** must additionally verify that: (1) secrets are omitted from GET/PUT/PATCH responses (runtime integration tests), and (2) secret retrieval is only via POST `list*` actions (API design review). | -| RPC013 | Resource must define a property bag; should include provisioningState | ✅ | `arm/arm-resource-provisioning-state`, `arm/arm-resource-invalid-envelope-property` | `arm-resource-provisioning-state` checks for a properly configured `provisioningState`. `arm-resource-invalid-envelope-property` ensures RP-specific properties are inside the `properties` bag. ARM base types enforce the property bag structure. | -| RPC014 | POST action must operate on single resource | 🔶 📐 | `arm/arm-resource-invalid-action-verb` | Validates that actions use POST or GET verbs. **Service owners** must verify through API design review that POST actions target individual resource instances, not collections. | -| RPC015 | PUT APIs that only return 200 (should also support 201/202 for creation) | ✅ | [`arm/arm-put-operation-response-codes`](/docs/libraries/azure-resource-manager/rules/put-operation-response-codes) | Validates that PUT operations have the appropriate status codes including 201 for creation. | -| RPC016 | Responses must include id, name, type; RP content inside properties | ✅ | `arm/arm-resource-invalid-envelope-property`, `arm/arm-resource-operation-response` | `arm-resource-invalid-envelope-property` validates envelope properties come from Azure.ResourceManager namespace. ARM base types enforce id, name, type. `arm-resource-operation-response` ensures consistent schema across operations. | -| RPC019 | No resources of other types in response (RBAC violation / info leak) | ❌ 📐 🟣 | — | No rule detects when a response includes full content of resources of different types. **Service owners** must review response schemas during API design review to ensure responses do not embed full representations of other resource types, which could create RBAC bypass or information leakage. Related to ARG001. | -| RPC020 | Circular dependencies between resources (read-only back-references) | ❌ 📐 | — | No rule detects writable circular references between resources. **Service owners** must review resource relationships during API design review to ensure circular dependencies use `readOnly` back-references, so ARM template dependency ordering can be resolved. | -| RPC021 | operationResults must be a top-level resource type | ❌ 🏗️ | — | `/operationResults` API placement is an ARM platform pattern, not described in TypeSpec resource provider specs. **Service owners** must configure this through the ARM platform. | -| RPC022 | Identifiers for operationResults must be unique (use GUIDs, not hashes) | ❌ 🏗️ | — | Identifier generation strategy is a runtime implementation concern internal to ARM. **Service owners** must ensure their implementation uses GUIDs for operation result identifiers. | -| RPC023 | DELETE should always be honored (never reject DELETE on bad state) | ❌ 🔄 | — | Whether DELETE is accepted regardless of resource state is a runtime implementation concern. **Service owners** must verify through runtime tests that DELETE is never rejected due to resource state. | -| RPC024 | Prefer header-based async timeout over manifest-based | ❌ 🏗️ | — | Async timeout configuration is in the ARM manifest, not in the TypeSpec API specification. **Service owners** must configure this in the ARM manifest. | -| RPC025 | 201 is the recommended async pattern (201 + provisioningState + Azure-AsyncOperation) | 🔶 🔄 | [`arm/arm-put-operation-response-codes`](/docs/libraries/azure-resource-manager/rules/put-operation-response-codes), [`arm/lro-location-header`](/docs/libraries/azure-resource-manager/rules/lro-location-header), `arm/retry-after` | PUT response codes, LRO Location header, and Retry-After are checked. **Service owners** must verify through integration tests that their preferred async pattern follows the 201 + provisioningState + Azure-AsyncOperation recommendation, as no rule specifically enforces this preference over alternatives. | -| RPC026 | Resource provider must implement subscription lifecycle contract | ❌ 🏗️ | — | Subscription lifecycle (register/unregister) is an internal ARM contract, not part of the customer-facing TypeSpec spec. POST `/register` in operations API is covered by `arm/missing-operations-endpoint`. **Service owners** must implement the subscription lifecycle contract as specified by the ARM platform. | -| RPC027 | SystemData support (createdBy, createdAt, etc.) | 🔧 | — | Enforced by ARM TypeSpec base types — `TrackedResource` and `ProxyResource` automatically include `systemData` in the resource model. | -| RPC028 | Async operation tracking URI must follow ARM guidelines | 🔶 🔄 | [`arm/lro-location-header`](/docs/libraries/azure-resource-manager/rules/lro-location-header) | Validates 202 responses include a Location header. **Service owners** must verify through integration tests that the Location URI format follows ARM guidelines and points to the ARM front door, as the specific URI format is not validated. | -| RPC029 | FQDNs must use auto-generated domain name labels (prevent subdomain takeover) | ❌ 🔄 | — | Domain label generation strategy is a runtime implementation concern. **Service owners** must verify through runtime testing that FQDNs use the AzureDNS Deterministic Names library to prevent subdomain takeover. | -| RPC030 | Avoid excessive resource type nesting (max 3 levels for tracked) | ✅ | `arm/beyond-nesting-levels` | Ensures tracked resources use 3 or fewer levels of nesting. | -| RPC031 | Unsupported query parameters (sub, subId, subscription, subscriptionId) | ❌ 🏗️ | — | ARM proxy behavior for query parameters is handled by the ARM platform. **Service owners** do not need to take action — this is enforced by the ARM front door. | +| RPC Rule | Description | Coverage | TypeSpec Rule(s) | Notes | +| -------- | ----------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| RPC003 | Tracked resource types must support move | ❌ 🏗️ | — | Resource move is configured in the ARM manifest, not in the TypeSpec API specification. **Service owners** must configure resource move support in the ARM manifest. | +| RPC004 | URI must follow ARM standard guidelines (well-formed GET/PUT/DELETE URI tuples) | 🔧 | `arm/arm-resource-path-segment-invalid-chars`, `arm/arm-resource-key-invalid-chars` | Enforced by TypeSpec ARM resource templates (`TrackedResource`, `ProxyResource`) which generate correct URI structures. Path character rules provide additional validation. | +| RPC005 | Provisioning state semantics must be followed (terminal/non-terminal states) | 🔶 🔄 | `arm/arm-resource-provisioning-state` | The rule checks that `provisioningState` is an open union containing the correct terminal states (Succeeded, Failed, Canceled). Runtime behavior (transitioning states on PUT/PATCH/DELETE) cannot be linted. **Service owners** must verify correct provisioning state transitions through integration tests covering resource lifecycle (create, update, delete). | +| RPC006 | Tracked resource types must support GET, PUT, PATCH, DELETE & LIST | 🔶 🟣 | `arm/use-operation-decorator`, `arm/no-resource-delete-operation` | `use-operation-decorator` validates operations use the correct decorator for the HTTP verb. `no-resource-delete-operation` checks resources with createOrUpdate also have delete. **Gap**: No single rule validates the complete set of required operations (GET, PUT, PATCH, DELETE, ListByRG, ListBySub) for tracked resources — a linting rule could and should be added. **Service owners** should verify the complete operation set through API design review until such a rule exists. | +| RPC007 | Resource types must support PATCH for Tags | ✅ | `arm/arm-resource-patch`, `arm/patch-envelope` | `arm-resource-patch` checks that if a resource has `tags`, PATCH includes it. `patch-envelope` validates PATCH includes envelope properties (identity, managedBy, plan, sku, tags). | +| RPC008 | PUT, GET, PATCH & LIST must return the same resource schema | ✅ | `arm/arm-resource-operation-response` | Directly implements RPC 008 — validates that PUT, GET, PATCH, and LIST operations all return the same resource schema. | +| RPC009 | Use PUT for replace, PATCH for partial update (JSON merge-patch) | 🔧 | — | Enforced by ARM TypeSpec operation templates: `ResourceCreateOrUpdate` for PUT and `ResourceUpdate` for PATCH generate the correct patterns. | +| RPC010 | Use PUT or PATCH to update a resource, not POST | ❌ 📐 🟣 | — | No rule prevents using POST for what should be a resource update. `arm/arm-resource-invalid-action-verb` ensures actions use POST/GET verbs but does not check intent. **Service owners** must verify through API design review that POST is not used for operations that semantically perform a full resource update. | +| RPC011.a | PUT on parent must not implicitly create tracked child resources | ❌ 📐 🟣 | — | No rule detects implicit child resource creation in PUT request bodies. **Service owners** must review PUT request schemas during API design review to ensure tracked child resources are not implicitly created. | +| RPC011.b | PUT on parent should avoid implicitly creating proxy child resources | ❌ 📐 🟣 | — | Same gap as RPC011.a. This rule is still being refined. **Service owners** should review PUT request schemas for implicit proxy child creation. | +| RPC012 | Secret property semantics (no secrets in GET/PUT/PATCH responses, use POST list\* action) | 🔶 📐 🔄 | [`arm/secret-prop`](/docs/libraries/azure-resource-manager/rules/secret-prop) | Checks properties with sensitive names (password, key, token, etc.) are marked `@secret`. **Service owners** must additionally verify that: (1) secrets are omitted from GET/PUT/PATCH responses (runtime integration tests), and (2) secret retrieval is only via POST `list*` actions (API design review). | +| RPC013 | Resource must define a property bag; should include provisioningState | ✅ | `arm/arm-resource-provisioning-state`, `arm/arm-resource-invalid-envelope-property` | `arm-resource-provisioning-state` checks for a properly configured `provisioningState`. `arm-resource-invalid-envelope-property` ensures RP-specific properties are inside the `properties` bag. ARM base types enforce the property bag structure. | +| RPC014 | POST action must operate on single resource | 🔶 📐 | `arm/arm-resource-invalid-action-verb` | Validates that actions use POST or GET verbs. **Service owners** must verify through API design review that POST actions target individual resource instances, not collections. | +| RPC015 | PUT APIs that only return 200 (should also support 201/202 for creation) | ✅ | [`arm/arm-put-operation-response-codes`](/docs/libraries/azure-resource-manager/rules/arm-put-operation-response-codes) | Validates that PUT operations have the appropriate status codes including 201 for creation. | +| RPC016 | Responses must include id, name, type; RP content inside properties | ✅ | `arm/arm-resource-invalid-envelope-property`, `arm/arm-resource-operation-response` | `arm-resource-invalid-envelope-property` validates envelope properties come from Azure.ResourceManager namespace. ARM base types enforce id, name, type. `arm-resource-operation-response` ensures consistent schema across operations. | +| RPC019 | No resources of other types in response (RBAC violation / info leak) | ❌ 📐 🟣 | — | No rule detects when a response includes full content of resources of different types. **Service owners** must review response schemas during API design review to ensure responses do not embed full representations of other resource types, which could create RBAC bypass or information leakage. Related to ARG001. | +| RPC020 | Circular dependencies between resources (read-only back-references) | ❌ 📐 | — | No rule detects writable circular references between resources. **Service owners** must review resource relationships during API design review to ensure circular dependencies use `readOnly` back-references, so ARM template dependency ordering can be resolved. | +| RPC021 | operationResults must be a top-level resource type | ❌ 🏗️ | — | `/operationResults` API placement is an ARM platform pattern, not described in TypeSpec resource provider specs. **Service owners** must configure this through the ARM platform. | +| RPC022 | Identifiers for operationResults must be unique (use GUIDs, not hashes) | ❌ 🏗️ | — | Identifier generation strategy is a runtime implementation concern internal to ARM. **Service owners** must ensure their implementation uses GUIDs for operation result identifiers. | +| RPC023 | DELETE should always be honored (never reject DELETE on bad state) | ❌ 🔄 | — | Whether DELETE is accepted regardless of resource state is a runtime implementation concern. **Service owners** must verify through runtime tests that DELETE is never rejected due to resource state. | +| RPC024 | Prefer header-based async timeout over manifest-based | ❌ 🏗️ | — | Async timeout configuration is in the ARM manifest, not in the TypeSpec API specification. **Service owners** must configure this in the ARM manifest. | +| RPC025 | 201 is the recommended async pattern (201 + provisioningState + Azure-AsyncOperation) | 🔶 🔄 | [`arm/arm-put-operation-response-codes`](/docs/libraries/azure-resource-manager/rules/arm-put-operation-response-codes), [`arm/lro-location-header`](/docs/libraries/azure-resource-manager/rules/lro-location-header), `arm/retry-after` | PUT response codes, LRO Location header, and Retry-After are checked. **Service owners** must verify through integration tests that their preferred async pattern follows the 201 + provisioningState + Azure-AsyncOperation recommendation, as no rule specifically enforces this preference over alternatives. | +| RPC026 | Resource provider must implement subscription lifecycle contract | ❌ 🏗️ | — | Subscription lifecycle (register/unregister) is an internal ARM contract, not part of the customer-facing TypeSpec spec. POST `/register` in operations API is covered by `arm/missing-operations-endpoint`. **Service owners** must implement the subscription lifecycle contract as specified by the ARM platform. | +| RPC027 | SystemData support (createdBy, createdAt, etc.) | 🔧 | — | Enforced by ARM TypeSpec base types — `TrackedResource` and `ProxyResource` automatically include `systemData` in the resource model. | +| RPC028 | Async operation tracking URI must follow ARM guidelines | 🔶 🔄 | [`arm/lro-location-header`](/docs/libraries/azure-resource-manager/rules/lro-location-header) | Validates 202 responses include a Location header. **Service owners** must verify through integration tests that the Location URI format follows ARM guidelines and points to the ARM front door, as the specific URI format is not validated. | +| RPC029 | FQDNs must use auto-generated domain name labels (prevent subdomain takeover) | ❌ 🔄 | — | Domain label generation strategy is a runtime implementation concern. **Service owners** must verify through runtime testing that FQDNs use the AzureDNS Deterministic Names library to prevent subdomain takeover. | +| RPC030 | Avoid excessive resource type nesting (max 3 levels for tracked) | ✅ | `arm/beyond-nesting-levels` | Ensures tracked resources use 3 or fewer levels of nesting. | +| RPC031 | Unsupported query parameters (sub, subId, subscription, subscriptionId) | ❌ 🏗️ | — | ARM proxy behavior for query parameters is handled by the ARM platform. **Service owners** do not need to take action — this is enforced by the ARM front door. | ### RPC Rules Coverage Summary @@ -84,14 +84,14 @@ The following sections provide a more detailed breakdown of coverage organized b ## Section 2: ARM Resource Model Rules -| RPC Guideline | RPC ID(s) | Coverage | TypeSpec Rule(s) | Notes | -| ------------------------------------------------------------ | --------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| 2.1 PUT response must be an ARM Resource | RPC-Put-V1-12 | ✅ | `arm/arm-resource-operation-response`, [`arm/arm-put-operation-response-codes`](/docs/libraries/azure-resource-manager/rules/put-operation-response-codes) | RPC 008 validates PUT/GET/PATCH/LIST return the same resource schema. PUT response codes are also validated. ARM base types ensure `x-ms-azure-resource` is set. | -| 2.2 Tracked resources must have all required operations | RPC-Get-V1-01, RPC-Put-V1-01, RPC-Patch-V1-03, RPC-Delete-V1-01 | 🔶 🟣 | `arm/use-operation-decorator`, [`arm/no-resource-delete-operation`](/docs/libraries/azure-resource-manager/rules/no-resource-delete-operation) | `use-operation-decorator` validates operations use the correct decorator for the HTTP verb. `no-resource-delete-operation` checks that resources with createOrUpdate also have delete. **Gap**: No single rule validates the complete operation set (GET, PUT, PATCH, DELETE, ListByRG, ListBySub) for tracked resources — a linting rule could and should be added. **Service owners** should verify the complete operation set through API design review until such a rule exists. | -| 2.3 Nested resources must have List under parent | — | ❌ 🟣 | — | **Gap**: No rule validates that nested resources define a List operation under their parent — a linting rule could and should be added. **Service owners** must verify this during API design review until such a rule exists. | -| 2.3 Nesting depth limit | — | ✅ | `arm/beyond-nesting-levels` | Ensures tracked resources use 3 or fewer nesting levels. | -| 2.3 No embedded nested resources in parent GET | ARG001 | ❌ 📐 | — | No rule prevents embedding child resources inline in parent GET response. **Service owners** must verify during API design review that parent GET responses do not embed full child resources. See also Section 10.1. | -| 2.4 Resource references use fully qualified ARM resource IDs | — | 🔧 📐 | — | TypeSpec provides the `armResourceIdentifier` scalar in `Azure.Core` for this purpose, which enforces the `arm-id` format and allows specifying allowed resource types and scopes. However, no linting rule can reliably detect that a plain `string` property is _intended_ to hold a resource reference — that requires domain knowledge. **Service owners** must use `armResourceIdentifier` for properties that reference other ARM resources and verify this through API design review. See [ARM Resource Types](./resource-type.md). | +| RPC Guideline | RPC ID(s) | Coverage | TypeSpec Rule(s) | Notes | +| ------------------------------------------------------------ | --------------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| 2.1 PUT response must be an ARM Resource | RPC-Put-V1-12 | ✅ | `arm/arm-resource-operation-response`, [`arm/arm-put-operation-response-codes`](/docs/libraries/azure-resource-manager/rules/arm-put-operation-response-codes) | RPC 008 validates PUT/GET/PATCH/LIST return the same resource schema. PUT response codes are also validated. ARM base types ensure `x-ms-azure-resource` is set. | +| 2.2 Tracked resources must have all required operations | RPC-Get-V1-01, RPC-Put-V1-01, RPC-Patch-V1-03, RPC-Delete-V1-01 | 🔶 🟣 | `arm/use-operation-decorator`, [`arm/no-resource-delete-operation`](/docs/libraries/azure-resource-manager/rules/no-resource-delete-operation) | `use-operation-decorator` validates operations use the correct decorator for the HTTP verb. `no-resource-delete-operation` checks that resources with createOrUpdate also have delete. **Gap**: No single rule validates the complete operation set (GET, PUT, PATCH, DELETE, ListByRG, ListBySub) for tracked resources — a linting rule could and should be added. **Service owners** should verify the complete operation set through API design review until such a rule exists. | +| 2.3 Nested resources must have List under parent | — | ❌ 🟣 | — | **Gap**: No rule validates that nested resources define a List operation under their parent — a linting rule could and should be added. **Service owners** must verify this during API design review until such a rule exists. | +| 2.3 Nesting depth limit | — | ✅ | `arm/beyond-nesting-levels` | Ensures tracked resources use 3 or fewer nesting levels. | +| 2.3 No embedded nested resources in parent GET | ARG001 | ❌ 📐 | — | No rule prevents embedding child resources inline in parent GET response. **Service owners** must verify during API design review that parent GET responses do not embed full child resources. See also Section 10.1. | +| 2.4 Resource references use fully qualified ARM resource IDs | — | 🔧 📐 | — | TypeSpec provides the `armResourceIdentifier` scalar in `Azure.Core` for this purpose, which enforces the `arm-id` format and allows specifying allowed resource types and scopes. However, no linting rule can reliably detect that a plain `string` property is _intended_ to hold a resource reference — that requires domain knowledge. **Service owners** must use `armResourceIdentifier` for properties that reference other ARM resources and verify this through API design review. See [ARM Resource Types](./resource-type.md). | ## Section 3: PUT Operation Rules @@ -112,10 +112,10 @@ The following sections provide a more detailed breakdown of coverage organized b ## Section 5: DELETE Operation Rules -| RPC Guideline | RPC ID(s) | Coverage | TypeSpec Rule(s) | Notes | -| ------------------------------------------------------------ | --------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | -| 5.1 DELETE response codes (200, 204, default; 202 for async) | RPC-Delete-V1-01, RPC-Async-V1-09 | ✅ | [`arm/arm-delete-operation-response-codes`](/docs/libraries/azure-resource-manager/rules/delete-operation-response-codes) | Validates correct status codes for both sync and async DELETE operations. | -| 5.2 DELETE must not have a request body | — | 🔧 | — | Enforced by ARM TypeSpec operation templates which do not include a body parameter for DELETE. | +| RPC Guideline | RPC ID(s) | Coverage | TypeSpec Rule(s) | Notes | +| ------------------------------------------------------------ | --------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | +| 5.1 DELETE response codes (200, 204, default; 202 for async) | RPC-Delete-V1-01, RPC-Async-V1-09 | ✅ | [`arm/arm-delete-operation-response-codes`](/docs/libraries/azure-resource-manager/rules/arm-delete-operation-response-codes) | Validates correct status codes for both sync and async DELETE operations. | +| 5.2 DELETE must not have a request body | — | 🔧 | — | Enforced by ARM TypeSpec operation templates which do not include a body parameter for DELETE. | ## Section 6: Long-Running Operations (LRO) @@ -170,28 +170,28 @@ The following sections provide a more detailed breakdown of coverage organized b ## Section 12: POST Actions -| RPC Guideline | RPC ID(s) | Coverage | TypeSpec Rule(s) | Notes | -| -------------------------------------------- | --------- | -------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| 12.1 POST actions must use POST or GET verbs | — | ✅ | [`arm/arm-resource-invalid-action-verb`](/docs/libraries/azure-resource-manager/rules/arm-resource-invalid-action-verb) | Validates that action operations use only POST or GET HTTP verbs. | -| 12.1 POST response codes | — | ✅ | [`arm/arm-post-operation-response-codes`](/docs/libraries/azure-resource-manager/rules/post-operation-response-codes) | Validates correct status codes for POST operations. | -| 12.2 POST to create resources | — | ❌ 📐 | — | POST creation is not allowed for ARM services. This constraint is not detectable by examining the API description alone. **Service owners** must verify through API design review that POST is not used for resource creation in ARM resource provider APIs. | +| RPC Guideline | RPC ID(s) | Coverage | TypeSpec Rule(s) | Notes | +| -------------------------------------------- | --------- | -------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| 12.1 POST actions must use POST or GET verbs | — | ✅ | [`arm/arm-resource-invalid-action-verb`](/docs/libraries/azure-resource-manager/rules/arm-resource-invalid-action-verb) | Validates that action operations use only POST or GET HTTP verbs. | +| 12.1 POST response codes | — | ✅ | [`arm/arm-post-operation-response-codes`](/docs/libraries/azure-resource-manager/rules/arm-post-operation-response-codes) | Validates correct status codes for POST operations. | +| 12.2 POST to create resources | — | ❌ 📐 | — | POST creation is not allowed for ARM services. This constraint is not detectable by examining the API description alone. **Service owners** must verify through API design review that POST is not used for resource creation in ARM resource provider APIs. | ## Additional ARM TypeSpec Rules The following TypeSpec linting rules enforce ARM conventions that are not explicitly called out as individual RPC guidelines but support overall ARM compliance: -| TypeSpec Rule | Description | -| ------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | -| `arm/arm-common-types-version` | Requires specifying the ARM common-types version using `@armCommonTypesVersion`. | -| [`arm/arm-no-record`](/docs/libraries/azure-resource-manager/rules/arm-no-record) | Prevents use of `Record` types for ARM resources, which produce `additionalProperties` in OpenAPI. | -| `arm/arm-resource-duplicate-property` | Warns about duplicate properties in resource definitions. | -| `arm/arm-resource-interface-requires-decorator` | Requires `@armResourceOperations` decorator on resource interfaces. | -| [`arm/arm-resource-name-pattern`](/docs/libraries/azure-resource-manager/rules/resource-name-pattern) | Requires a `pattern` restriction on resource name parameters. | -| `arm/improper-subscription-list-operation` | Ensures tenant and extension resources don't define list-by-subscription operations. | -| [`arm/missing-x-ms-identifiers`](/docs/libraries/azure-resource-manager/rules/missing-x-ms-identifiers) | Requires array properties to describe identifying properties with `x-ms-identifiers`. | -| [`arm/no-empty-model`](/docs/libraries/azure-resource-manager/rules/no-empty-model) | Prevents ARM properties with `type: object` that don't reference a model definition. | -| [`arm/no-override-props`](/docs/libraries/azure-resource-manager/rules/no-override-props) | Disallows redefining properties already defined in a base type. | -| [`arm/unsupported-type`](/docs/libraries/azure-resource-manager/rules/unsupported-type) | Checks for unsupported ARM types. | +| TypeSpec Rule | Description | +| --------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | +| `arm/arm-common-types-version` | Requires specifying the ARM common-types version using `@armCommonTypesVersion`. | +| [`arm/arm-no-record`](/docs/libraries/azure-resource-manager/rules/arm-no-record) | Prevents use of `Record` types for ARM resources, which produce `additionalProperties` in OpenAPI. | +| `arm/arm-resource-duplicate-property` | Warns about duplicate properties in resource definitions. | +| `arm/arm-resource-interface-requires-decorator` | Requires `@armResourceOperations` decorator on resource interfaces. | +| [`arm/arm-resource-name-pattern`](/docs/libraries/azure-resource-manager/rules/arm-resource-name-pattern) | Requires a `pattern` restriction on resource name parameters. | +| `arm/improper-subscription-list-operation` | Ensures tenant and extension resources don't define list-by-subscription operations. | +| [`arm/missing-x-ms-identifiers`](/docs/libraries/azure-resource-manager/rules/missing-x-ms-identifiers) | Requires array properties to describe identifying properties with `x-ms-identifiers`. | +| [`arm/no-empty-model`](/docs/libraries/azure-resource-manager/rules/no-empty-model) | Prevents ARM properties with `type: object` that don't reference a model definition. | +| [`arm/no-override-props`](/docs/libraries/azure-resource-manager/rules/no-override-props) | Disallows redefining properties already defined in a base type. | +| [`arm/unsupported-type`](/docs/libraries/azure-resource-manager/rules/unsupported-type) | Checks for unsupported ARM types. | ## Rules Not Enforceable Through Linting — Service Owner Responsibility