What this epic is for
Reduce unnecessary handwritten LRO code by fixing demonstrated gaps in supported generation and runtime behavior. Coordinate the work across TypeSpec, the language emitters, and the SDK repositories.
We are classifying the inventory before selecting implementations. The first pass covers 49 distinct behaviors. It is not a list of 49 confirmed bugs or promised features, and it does not establish complete cross-language parity.
Four-language emitter comparison
Compare Python, Java, TypeScript, and C# independently. Each language below has its own implementation or scenario evidence. SDK customizations are a separate layer of evidence, recorded in the inventory; neither TypeScript behavior nor a shared metadata type establishes another emitter's support.
A comparable example in each language
All four have RPC scenario assertions for the same outcome: input "text" produces a typed result with data == "text data". These are source-reviewed examples, not tests executed in this survey or proof that a production SDK customization can be removed.
| Language |
Example API in its scenario |
Evidence and qualification |
Python (typespec-python) |
begin_long_running_rpc(...).result() |
Python RPC assertions. The polling fixture reinjects the API version; this is not unmodified-runtime proof. |
Java (typespec-java) |
beginLongRunningRpc(...), then getFinalResult() |
Java RPC assertions check both the final result and monitor-body operation ID. The latter is not an immediately available URL-derived ID. |
TypeScript (typespec-ts) |
await client.longRunningRpc(...) |
TypeScript RPC assertions. This establishes the TS example only. |
| C# (generic emitter + Azure extension) |
LongRunningRpcAsync(WaitUntil.Completed, ...) |
Azure C# RPC assertions also cover WaitUntil.Started. These belong to the Azure extension, not generic C# alone. |
What this means for the work items
Python: result extraction, paging, and poller controls
typespec-python delegates to the shared Python emitter with Azure flavor. Its result adapter selects result type and extraction segments separately (L06). Radiology already extracts result; the investigation is about the selected type and generation inputs, not adding extraction from scratch.
The Python generator implements polling=False, caller polling strategies, continuation-token restoration, and a pager starting from the completed response (L17/L18/L23/L24). That is not proof of Translation's separate final listing or custom-token compatibility. Declared terminal-value and arbitrary linked-operation binding support remain unverified.
Java: typed result projection and management LRO+paging
The Azure package uses its declared shared-source revision, not automatically shared main. Its metadata translation distinguishes result from envelope, but carries only the last extraction-property segment and leaves nested extraction as a TODO (L06).
Although the mapper chooses its paging branch first, Azure management handles initial polling inside that branch. The matching generated client and two-page assertions are linked in #5545. This does not establish data-plane Language/Translation parity (L17/L18).
TypeScript: result paths, initial LRO followed by pages, and resumption
The TS result adapter consumes final-result type and segments (L06). The generated paging example awaits an initial poller before ordinary pages (L17/L18); it does not establish a new LRO per page.
Standard scenario assertions cover typed results, progress, and serialize/restore (L24). The runtime bridge does not forward skipFinalGet; reuse the existing L03 issues. Client-side request abort is not service cancellation.
C#: distinguish the generic emitter, Azure extension, and runtime
The requested generic C# front end accepts lro and lropaging metadata; this is not evidence of automatic Azure polling. The Azure extension installs its LRO visitor and uses Azure.Core polling.
That visitor projects a configured result property (L06); arbitrary nested-path traversal is not established. The runtime uses fixed terminal strings, not demonstrated consumption of arbitrary declared values (L01). Azure management separately generates LRO+paging internally by design; public support remains deferred. See #5545. Data-plane paging and service-specific resume parity remain unverified (L17/L18/L24). Checked-in generated C# signature baselines have stub bodies; the implementation and assertions, not those signatures alone, supply the evidence.
Provenance: the four-language sources are independently pinned, not a verified compatible build matrix. Python source/dependency versions agree, not verified package bytes; C# extension dependencies are not the inspected generic SHA. Earlier Go evidence is supplemental. Service compatibility requires separate proof.
Workstreams and next steps
| Workstream |
What we know |
What happens next |
| Final-GET suppression |
The JS runtime option exists; generator integration is already tracked. |
Coordinate TypeScript #4771 and JS #32142. Resolve result/deserialization behavior before removing SDK shims. |
| Result projection and polling correctness |
Radiology has an existing tracker; Java rewrites are cleanup candidates, not three proven bugs; Discovery has two contract investigations. |
Follow the linked tasks. Do not remove customizations until current generation and service contracts are established. |
| Operation IDs, usage, and typed results |
SDKs expose useful metadata and convenience APIs in different ways. Those differences are not automatically generator defects. |
Agree separate client contracts with interested language owners, then file implementation and SDK adoption issues. |
| LRO + paging |
Limited legacy support exists for an initial LRO followed by ordinary pages. Monitor paging, separate final collection calls, and item shaping are different cases. |
Compare each scenario against the existing support decision; do not propose a blanket new paging metamodel. |
| Poller lifecycle and compatibility |
Resume tokens, initial-response results, no-wait behavior, and service cancellation have distinct contracts. |
Preserve existing behavior. Consider small, independently scoped improvements only with an adoption owner. |
| Historical/custom workflows |
Key Vault visibility, Batch state predicates, Load Testing business outcomes, Storage copy, and CCF are not one generic state machine. |
Keep customizations by default. Consider existing client modeling or a small wrapper before new shared support. |
These are navigation groups, not implementation issue boundaries. The expandable inventory below preserves the individual work items and their stable tracking IDs.
Remaining decisions
- Support: Which candidates are gaps in an agreed contract, rather than intentional SDK choices or service exceptions?
- Service parity: Where do generators actually handle the same operation and result/error behavior without customization? Emitter examples are recorded for all four languages; same-service migration parity remains unverified. Unknown does not mean unsupported.
- Ownership: Which repository and language owner should own each investigation or optional improvement?
- Issue scope: Which existing issues can we reuse, and which independent questions need new investigation, implementation, or SDK adoption issues?
Filed and reused issues are linked natively and beside their inventory IDs. Other IDs remain classifications, not implementation commitments; the filing register below records their status.
What stays customized
Keep nonstandard and compatibility-specific behavior unless there is a concrete benefit and an owner-approved replacement. This includes legacy Key Vault workflows, DeviceUpdate/DeviceRegistry compatibility, and service-specific Batch, Load Testing, Storage, and CCF behavior.
For approved exceptions such as Ledger's waitForCommit, prefer existing client.tsp composition or a small convenience wrapper where appropriate. No generic state-machine engine, global fallback flag, or Core/TCGC redesign is a prerequisite.
Progress
Detailed inventory
Open the relevant workstream below. Each entry states its assessment, next action, and service SDK observations. The four-emitter examples above are separate evidence: a generic scenario does not establish service-specific parity. Omitted languages remain unverified, not unsupported. Investigate means the cause or support obligation is unresolved; optional improvement needs owner agreement; keep customization is a deliberate disposition, not unfinished implementation work.
Source links are placed beside each finding. Full evidence notes, repository routing, and migration criteria are available at the end. Findings are based on the recorded source snapshots, not live-service verification.
Protocol wiring and polling correctness - 9 entries
Consume declared terminal values; Security Domain and other annotated status monitors
L01 - Legacy exception; generic defect not established.
The Security Domain spec explicitly calls "Success" a shipped deviation from "Succeeded". Preserve this customization unless exception support is agreed. A separate supported-contract terminal-value defect needs its own reproduction; the annotation alone is not a support obligation.
SDK observations: Python: Handwritten.
Sources: Success already annotated in SDK-pinned spec · current TCGC mapping/terminal translation
Use the declared polling-header/operation source; Admin as a lead
L02 - Needs a supported-contract reproduction before filing.
Compare declared polling metadata with the active generated/runtime path. Admin custom code alone does not establish a supported-contract defect. Keep this separate from final-GET policy.
SDK observations: Python: Handwritten; JavaScript: Handwritten.
Sources: Python final GET/token overrides
Suppress an unsupported final GET; Admin restore, Security Domain
L03 - Existing exception-specific integration work. First-priority investigation.
Reuse TypeScript #4771 and JavaScript #32142. Go restore uses transformed generation plus custom pollers; this is not uncustomized generation. Emitter issue requires internal operation-level config and result/deserialization agreement.
SDK observations: Python: Handwritten; JavaScript: Handwritten.
Sources: existing integration issue · restore final result from monitor
Resolve endpoint-relative polling/final links; DeviceUpdate
L04 - Compatibility exception; optional reachability investigation. Only with an owner-backed adoption case.
Java sampled generated paths already pass an endpoint to stock polling. Verify remaining custom callers before a cleanup issue; absolute-URL guideline and compatibility exception remain distinct.
Sources: Java generated stock strategy with endpoint · maintainer's exception explanation
Invoke a linked polling GET with parameter binding
L05 - No new generic linked-GET feature issue.
Core/TCGC already carry linked operations and parameter mappings. Identify a concrete supported consumer failure before filing; ordinary header-URL polling does not demonstrate explicit parameter binding.
Sources: linked polling/final operations with parameter mapping
Keep final extraction path and result type consistent; Radiology
L06 - Reuse #1167; no duplicate Python issue.
That issue already covers Radiology's path/type mismatch. The checked-in Python callback still projects result into the job type; Java explicitly configures its inference type, and C# provenance does not prove patch-free generation. Reproduce with a pinned current toolchain before assigning a new defect.
SDK observations: Python: Handwritten; Java: Not verified (positive implementation); C#: Not verified (positive implementation).
Sources: generated Python callback · patch
Java Content Understanding generated polling header-name expression
L07 - Verify stale rewrite under Java #50552.
Release-associated helper source already uses getCaseSensitiveName(). The inspected header accessor delegates to toString(), so a key mismatch is not established. Regenerate without this rewrite before removing it.
SDK observations: Java: Rewrite hook present; current behavioral effect unverified.
Sources: Java generated-polling patches
Java Content Understanding generated sync-poller method annotation
L08 - Verify stale rewrite under Java #50552.
The patch removes @Override from sync getResult, not onInitialResponse. The release-associated template already lacks that annotation. Check the resolved runtime and compilation before removing the rewrite.
SDK observations: Java: Rewrite hook present; current behavioral effect unverified.
Sources: Java generated-polling patches
Java Content Understanding generated polling error-message formatting
L09 - Low-priority maintenance under Java #50552.
This patch adds a comma, not a formatting placeholder. Current source already has it and retains duplicate punctuation. Record this rewrite separately within the cleanup task; cosmetic formatting must not block LRO work.
SDK observations: Java: Rewrite hook present; current behavioral effect unverified.
Sources: Java generated-polling patches
Operation metadata and typed SDK results - 7 entries
URI-derived operation ID available after initiation; Document Intelligence/Content Understanding
L10 - Optional SDK API improvement.
Agree extraction/timing/resume and per-language API. JS Document Intelligence intentionally replaced poller ID access with an initial-response helper; JS Content Understanding customizes state plus a deprecated poller property. Do not infer missing parity from API differences. Java's body ID getter does not establish the same source or immediate-availability contract.
SDK observations: Python: Handwritten; C#: Handwritten; JavaScript: Handwritten (Content Understanding); Not verified (Document Intelligence provenance).
Sources: Python URI-derived ID · Document Intelligence intentional ID API change
Expose typed monitor-body usage; Content Understanding
L11 - Optional SDK API improvement.
Python reads latest envelope when done, not necessarily successful; JS captures at result deserialization and exposes state/result. Agree lifecycle rather than assume identical accessor behavior.
SDK observations: Python: Handwritten; C#: Handwritten; JavaScript: Handwritten.
Sources: Python ID/usage/lifecycle · Content Understanding custom ID/usage API
Typed final result / operation identity; App Configuration snapshots
L12 - Optional SDK API improvement.
Java includes explicit polling/final GET; other sampled wrappers use stock paths. Scope the actual API/identity/diagnostic contract, not a presumed protocol gap.
SDK observations: Java: Handwritten; C#: Handwritten; JavaScript: Handwritten.
Sources: C# typed operation wrapper · AppConfig public typed wrapper with stock runtime
Typed final result; DevCenter
L13 - Optional SDK API improvement.
C# result-conversion issue, separate from public signature adaptation L14 and from App Configuration adoption.
SDK observations: C#: Handwritten.
Sources: separate signature and result adaptations
Derive DevCenter path name from model / preserve convenience signature
L14 - Optional client shaping or retained compatibility.
Existing client shaping first; typed LRO result generation alone does not remove this customization.
SDK observations: C#: Handwritten.
Sources: separate signature and result adaptations
Return no monitor as Python upload result; Security Domain
L15 - Keep the existing result contract.
Preserve Python result contract; assess client result shaping only if owner requests removal. Not a new polling protocol.
SDK observations: Python: Handwritten.
Sources: distinct Python behaviors
Preserve DeviceRegistry protocol poller result type for compatibility
L16 - Keep compatibility customization.
Carry-forward BinaryData-versus-Void/public API decision; not equivalent to broken final-result inference.
SDK observations: Java: Patched generation.
Sources: result-type compatibility customization
Paging, aggregate results, and errors - 5 entries
Page results from the completed monitor; TextAnalytics/Conversations
L17 - Shared fixture validation filed as #5545.
Python/TS/Java have matching first-LRO/ordinary-pages ARM examples; C# management intentionally keeps the combined API internal. Validate a pinned matrix, not a presumed skipped-poller bug. Language monitor-result and item-shaping parity remains separate.
SDK observations: Python: Handwritten; Java: Handwritten (TextAnalytics); Not verified (Conversations); C#: Legacy implementation (TextAnalytics); Not verified (Conversations); JavaScript: Legacy implementation (TextAnalytics); Not verified (Conversations).
Sources: Conversations patch · agreed legacy-only support scope
Invoke a separate pageable final operation; Translation
L18 - Investigate an optional client-composition improvement. Optional; requires owner agreement.
SDK chooses document statuses after batch completion. Spec's linked final operation is batch status, not automatically the public pager. Try client composition before a new shared contract. Java returns batch status with document listing separate; that is not the same public result contract.
SDK observations: Python: Handwritten; C#: Handwritten.
Sources: Python final pageable callback · current linked batch status and DELETE cancellation
Aggregate versus flatten action/page items; Language family
L19 - Keep item shaping unless an owner wants a change.
Separate item shape, ordering, and per-item errors from wire paging. One client-shaping decision per public contract; no blanket Conversations parity.
SDK observations: Python: Handwritten; Java: Handwritten (TextAnalytics); C#: Legacy implementation (TextAnalytics); JavaScript: Legacy implementation (TextAnalytics).
Sources: TextAnalytics patch
Return useful document results after failed/canceled batch work; Translation
L20 - Keep the existing business-result contract.
Preserve business-result contract; enum Failed does not alone dictate throwing from result(). Not terminal-list consumption L01.
SDK observations: Python: Handwritten; C#: Handwritten.
Sources: C# failed translation with usable document results
Translation validation-failure error projection
L21 - Keep exceptional error policy; investigate only a concrete defect.
C# also throws for ValidationFailed; exact nested-error shaping parity remains unverified. Separate from ordinary failed-batch document results.
SDK observations: Python: Handwritten; C#: Handwritten (classification); Not verified (innerError parity).
Sources: custom polling/error handling
Poller lifecycle, cancellation, and continuation - 6 entries
Retain initial-response result while monitoring; Security Domain download / Ledger create
L22 - Keep initial-response result retention.
Return initial payload rather than monitor result. Separate result retention from final-GET suppression, terminal literals, transaction identity, and no-wait behavior.
SDK observations: Python: Handwritten.
Sources: distinct Python behaviors · Python ledger patch
Local no-wait / opting out of polling; Security Domain
L23 - Keep client/CLI no-wait behavior.
CLI/client lifecycle behavior, not service cancellation and not a service-schema feature.
SDK observations: Python: Handwritten.
Sources: distinct Python behaviors
Continuation-token representation and rehydration; Admin lead
L24 - Compatibility-sensitive lifecycle investigation, if requested. Only with an owner-backed adoption case.
C# resumes backup from ID, JS restores state by method/path, Go rehydrates handlers. Preserve each contract, not one universal token format.
SDK observations: Python: Handwritten; C#: Handwritten (backup ID); JavaScript: Handwritten.
Sources: Python final GET/token overrides · custom restore/rehydration
Request certificate-operation cancellation
L25 - Keep service-specific cancellation behavior.
Java/JS explicit service cancellation callbacks established; other cells need call-site evidence. Separate from certificate creation policy and local cancellation.
SDK observations: Java: Handwritten; JavaScript: Handwritten.
Sources: certificate monitor/cancel · Java certificate callbacks
Request Translation cancellation
L26 - Keep service-specific cancellation behavior.
Service uses DELETE of a batch and has race/partial-result semantics. A canceled terminal annotation is not a cancel request contract.
SDK observations: Python: Handwritten; C#: Handwritten.
Sources: current linked batch status and DELETE cancellation
Request Load Testing stop/cancellation
L27 - Inventory the service stop operation; do not assume a generator gap. No replacement planned.
Record the actual operation and whether the existing SDK attaches it to a poller; prior service-level cancellation lead is not proof of a missing generator feature.
Sources: current spec contrasts ordinary test-run create/update with standard long-running actions
Historical workflows and compatibility exceptions - 22 entries
Deleted/recovered resource visibility; Key Vault keys/secrets/certs
L28 - Keep the existing visibility workflow.
GET deleted/live resource; 404 is pending. Keys/secrets are two families, with certificates a third; no "4 packages x 4 languages" removal estimate.
SDK observations: Python: Handwritten; Java: Handwritten; C#: Handwritten; JavaScript: Handwritten.
Sources: Python visibility contract
Permission/exception completion policy during Key Vault visibility polling
L29 - Keep operation-specific permission/error handling.
Sampled 403 rules and Java broader exception completion differ. Do not infer identical semantics or generalize 403 as proof of resource existence.
SDK observations: Python: Handwritten; Java: Handwritten; C#: Handwritten; JavaScript: Handwritten.
Sources: C# delete secret · Java exception policy
Pending certificate monitor
L30 - Keep the pending-certificate workflow.
Bespoke creation workflow; status aliases alone do not replace it. Unknown-issuer early exit is separately tracked in L48, not presumed cross-language parity.
SDK observations: Python: Handwritten; Java: Handwritten; C#: Handwritten; JavaScript: Handwritten.
Sources: Python certificate creation
Retrieve certificate after successful creation monitor
L31 - Keep certificate final retrieval.
Separate final retrieval from L30's termination policy if a future replacement is approved.
SDK observations: Python: Handwritten; Java: Handwritten; C#: Handwritten; JavaScript: Handwritten.
Sources: Java certificate callbacks
Finish when a Batch resource leaves a transitional state
L32 - Keep operation-specific Batch predicates.
One operation's predicate at a time; not necessarily a designated success/failure enum. Do not roll all 14 poller classes into one implementation claim.
SDK observations: Python: Handwritten; C#: Handwritten; JavaScript: Handwritten.
Sources: Python predicates
Wait for Batch pool allocation state to become steady
L33 - Keep the pool-state completion policy.
Different property/poll target from job/node state; shared transport does not imply shared result policy.
SDK observations: Python: Handwritten; C#: Handwritten; JavaScript: Handwritten.
Sources: C# resize semantics
Treat Batch polling GET's 404 as completion
L34 - Keep operation-specific disappearance handling.
Different from Key Vault visibility. Preserve whether completion has a value and how non-404 errors propagate.
SDK observations: Python: Handwritten; C#: Handwritten; JavaScript: Handwritten.
Sources: JS custom poller
Load Testing run/profile-run execution completion versus business outcome
L35 - Keep the existing business-result contract.
Python/C#/JS can return failed/canceled run results. Java maps poll states to failed/canceled; runtime return/throw behavior remains untraced. JS profile-run is separate coverage.
SDK observations: Python: Handwritten (run); Java: Handwritten (run); C#: Handwritten (run); JavaScript: Handwritten (run/profile).
Sources: Python execution/validation policies · Java Load Testing policies
Load Testing file-validation completion policy
L36 - Keep the file-validation completion policy.
Separate validation terminal set and GET binding; Java maps failure state, while JS completion returns response even for validation failure. Do not infer identical public outcomes.
SDK observations: Python: Handwritten; Java: Handwritten; JavaScript: Handwritten.
Sources: file validation
Discovery resource provisioningState polling
L37 - Filed contract investigation: specs #46595.
Python/C# share a spec pin declaring a status monitor, but custom code reads resource provisioning state; C# polls the resource directly. Establish actual poll route/body and completion field before blaming an emitter. Keep indexing state separate.
SDK observations: Python: Handwritten; C#: Handwritten.
Sources: Python custom operations
Discovery synchronous initial response handling
L38 - Filed contract investigation: specs #46596.
Both custom pollers complete on missing Operation-Location, more broadly than the HTTP-200 comments. Confirm allowed initial status/header/body combinations and negative cases separately from L37.
SDK observations: Python: Handwritten; C#: Handwritten.
Sources: C# Discovery completion
Discovery delete-until-gone
L39 - Investigate source provenance before considering adoption. Evidence collection only.
Current sampled Python patch does not establish an active custom delete path; test comments mention an old class while supplying stock polling. Do not count stale comments. C# evidence remains separate.
SDK observations: C#: Handwritten.
Sources: Python delete test and stale-comment lead · C# customization directory
Storage copy identity and completion tracking
L40 - Keep the copy tracking/result contract.
Explicit implementations have different final results: Java Void, C# byte count. Identity/error policies must be compared per operation, not merely linked GET status.
SDK observations: Java: Handwritten; C#: Handwritten; JavaScript: Handwritten.
Sources: C# copy operation · Java Storage callbacks
Storage copy progress exposure
L41 - Keep progress API; optional client improvement.
JS progress callback confirmed; other languages' equivalent progress API was not established. Do not equate final byte count with progress reporting.
SDK observations: JavaScript: Handwritten.
Sources: JS copy poller
Storage copy abort/cancellation
L42 - Keep service-specific copy abort behavior.
Java/JS provide abort callbacks. C# copy tracking is not proof of an equivalent poller cancellation API. Separate service abort from local polling stop.
SDK observations: Java: Handwritten; JavaScript: Handwritten.
Sources: Java Storage callbacks · JS copy poller
CCF commit-status polling
L43 - Keep the CCF commit protocol.
Service-specific Ready/Committed terminal policy, not a generic shared-support task. Separate ID mapping (L49), original-response retention (L22), and replication errors (L45).
SDK observations: Python: Handwritten; C#: Handwritten.
Sources: Python ledger patch
CodeTransparency encoding or result representation
L44 - Investigate missing source evidence. Evidence collection only.
The earlier cited C# CreateEntryOperation.cs path does not resolve at its claimed snapshot and was not located by code search. Retract the proven-customization claim until the actual source is found; do not extrapolate Ledger behavior.
CCF replication-lag 404 tolerance
L45 - Keep operation-specific replication-lag handling.
Python and C# have bounded/operation-specific handling; C# gateway/direct policies differ. Neither generic disappearance completion nor Key Vault visibility.
SDK observations: Python: Handwritten; C#: Handwritten.
Sources: C# CCF direct/gateway behavior
Ledger waitForCommit client API split
L46 - Optional client composition for an approved-exception direction. Only with an owner-backed adoption case.
Evaluate separate LRO-like and normal methods using existing client modeling; wrapper is an alternative, not a second mandatory feature. Preserve timeout/recovery limitations.
Sources: review direction: separate client operations or convenience wrapper
Key Vault visibility poller nonblocking result access
L47 - Keep the nonblocking result-access contract.
Python returns retained resource from result() without waiting; wait() drives polling. Preserve this independent API contract if visibility polling is ever replaced.
SDK observations: Python: Handwritten.
Sources: Python nonblocking result contract
Certificate unknown-issuer short circuit
L48 - Keep the issuer-specific early exit.
Python completes immediately for unknown issuer; analogous JS branch was not established. Do not silently copy this rule across language implementations.
SDK observations: Python: Handwritten.
Sources: Python certificate creation
CCF transaction identity mapping
L49 - Keep transaction identity mapping.
Python exposes the response transaction-ID header in its result/commit flow. Different from commit-state polling and returning the original create payload. Any CodeTransparency ID swap needs its own pinned operation evidence.
SDK observations: Python: Handwritten.
Sources: Python ledger patch
Deferred design topics - not implementation prerequisites
| ID |
Classification / disposition |
| D01 |
Canonical terminal-name casing ergonomics: deferred cleanup. Separate compiler recognition from serialized values and runtime comparison. Fix actual supported-contract value bugs under L01 instead. |
| D02 |
Core/TCGC field ownership: Draft PR #5546 keeps protocol facts and required final HTTP steps in Core and moves client-result selection to TCGC. Non-gating, behavior-preserving refactor; not the Radiology fix. |
| D03 |
New generic predicates / 404 state machines / cancellation framework: Deferred shared-support proposal. Recurrence of existing exceptions alone does not authorize a framework. |
| D04 |
Fallback controls: no global flag/decorator committed. Retaining a handwritten implementation is not the same as heuristic runtime fallback. |
Issue filing, repository ownership, and existing links
Filing issues and tracking adoption
2026-09-22 filing pass: reuse exact duplicates, file contract questions as investigations, and treat stale rewrites as maintenance. A filed issue is not a confirmed bug or an assigned owner.
| IDs |
Tracking |
Closeable scope / disposition |
| L03 |
Existing TS #4771 + JS #32142 |
Final-GET configuration and result contract; SDK adoption remains separate. |
| L06 |
Existing #1167 |
Revalidate Radiology result-path/type consistency with current generation. No duplicate Python issue. |
| L07-L09 |
New Java #50552 |
Verify and retire obsolete rewrites in one customization hook; record each rewrite's outcome. Not three demonstrated generator bugs. |
| L37 |
New specs #46595 |
Confirm Discovery's polling route, response shape, and provisioning-completion field. |
| L38 |
New specs #46596 |
Confirm allowed initial responses without Operation-Location, independently of L37. |
| L17 |
New #5545 |
Validate the existing same-fixture ARM comparison; Java preserves initial polling, and C# management's internal-only API is intentional. No emitter bug alleged. |
| L18 |
Not filed |
Separate final collection call/client composition; not interchangeable with L17. Requires an agreed result contract. |
| L01, L02, L04, L05 |
Not filed |
Legacy support decision or concrete supported reproduction still needed. No generic terminal-state/linked-GET expansion is implied. |
| L10-L14 |
Not filed |
Independent ID, usage, and convenience-API decisions require interested owners before implementation. |
| L15-L16, L19-L36, L39-L49 |
Per-entry dispositions below |
Preserve accepted behavior; pursue optional improvements or unresolved provenance only with the stated evidence/owner gates. These ranges are navigation, not combined issue scopes. |
Dependency order: support/contract decision -> reproduction -> necessary shared/spec/runtime change -> emitter change -> SDK adoption -> exact workaround removal. Skip unnecessary layers. Optional work needs owner interest; generic nonstandard implementation is not committed.
Cross-repository ownership map
| Alias |
Repository / responsibility |
| typespec-azure |
Azure/typespec-azure: Azure.Core, TCGC, typespec-python, typespec-java, typespec-ts, and cross-language scenarios |
| microsoft/typespec |
microsoft/typespec: shared http-client-python, http-client-java, http-client-js, http-client-csharp infrastructure; route only after tracing whether the shared or Azure layer is responsible |
| REST API specs |
Azure/azure-rest-api-specs: wire spec correction and service-specific client.tsp composition |
| Python SDK |
Azure/azure-sdk-for-python: Python runtime, public SDK behavior, regeneration and patch removal |
| Java SDK |
Azure/azure-sdk-for-java: Java runtime, SDK customization and adoption |
| C# SDK |
Azure/azure-sdk-for-net: Azure C# emitter under eng/packages/http-client-csharp, runtime and SDK adoption; shared-base defects may belong in microsoft/typespec |
| JavaScript SDK |
Azure/azure-sdk-for-js: JavaScript SDK runtime, SDK customization and adoption |
| Go SDK |
Azure/azure-sdk-for-go: Go runtime, SDK customization and adoption |
These are repository routes, not assigned owners. In particular, emitter changes do not automatically belong in the language SDK repo: the Azure Python package consumes the shared Python emitter; the generic C# emitter is in microsoft/typespec; Azure-specific C# generation has a separate layer in azure-sdk-for-net. Pin the actual generator package/version used by the SDK before filing.
Linking and tracking convention
Keep #5432 as the parent. Link each child natively and beside its L/D ID; children link back and name dependencies. Reuse existing issues. Track classification, owner review, filing, implementation, and SDK adoption separately, alongside accepted/deferred/needs-evidence dispositions. See the filing register for new and reused children; remaining inventory entries are not automatically work commitments.
Related support and integration issues
Support policy, evidence standards, and migration safeguards
Use the applicable Azure REST API guidelines and explicit support decisions, including legacy-only LRO+paging. Service-exception approval is distinct from emitter support; an initial LRO followed by ordinary pages does not imply per-page LRO support.
| Assessment |
Action |
| Supported-contract bug |
Reproduce and fix; remove the workaround after SDK adoption. |
| Optional SDK improvement |
Agree the client contract and owner; prefer existing modeling/runtime facilities. |
| Keep customization |
Preserve historical/compatibility behavior unless an approved replacement pays off. |
| Deferred shared support |
Require a sponsor, bounded semantics, benefit, compatibility and support review. |
| Investigate |
Resolve the missing evidence without promising a feature. |
Compare like with like: same service operation, API version, request/result/error semantics, and intended public API. Generic fixture examples do not establish patch-free service parity; working handwritten code does not establish spec correctness. A confirmed bug does not require two languages to reproduce it. Track technical layer, spec confidence, and delivery status separately.
One leaf issue, one outcome: name its owner/repo, L/D ID, source and package versions, support basis, expected behavior, non-goals, dependencies, and closure criterion. Investigations close with evidence and a disposition. Implementations and SDK adoption are tracked separately.
Before removing a customization: cover relevant initial/poll/final requests, synchronous responses, success/failure/canceled/unknown states, eventual consistency, paging laziness, metadata timing, and token compatibility. Preserve public APIs unless change is approved. A regeneration diff alone is insufficient.
Measure outcomes: count reproduced defects fixed and active workarounds removed, separately from accepted, optional, deferred, and unknown cases. Reclassification is not implementation progress; equivalent semantics do not require identical APIs.
Reduce undeclared protocol inference, not necessary response inspection. No global fallback flag, generic state-machine framework, or wholesale Core/TCGC rewrite is a prerequisite.
Full source notes and research limitations
Source snapshots and limitations
Sources below are pinned where practical. Earlier 2026-09-15 source snapshots remain valid observations of those revisions, not claims that a current emitter is still broken. The 2026-09-21 follow-up adds source review, not live-service verification. Attach spec/emitter/runtime versions to each child before treating it as reproducible.
What this epic is for
Reduce unnecessary handwritten LRO code by fixing demonstrated gaps in supported generation and runtime behavior. Coordinate the work across TypeSpec, the language emitters, and the SDK repositories.
We are classifying the inventory before selecting implementations. The first pass covers 49 distinct behaviors. It is not a list of 49 confirmed bugs or promised features, and it does not establish complete cross-language parity.
Four-language emitter comparison
Compare Python, Java, TypeScript, and C# independently. Each language below has its own implementation or scenario evidence. SDK customizations are a separate layer of evidence, recorded in the inventory; neither TypeScript behavior nor a shared metadata type establishes another emitter's support.
A comparable example in each language
All four have RPC scenario assertions for the same outcome: input
"text"produces a typed result withdata == "text data". These are source-reviewed examples, not tests executed in this survey or proof that a production SDK customization can be removed.typespec-python)begin_long_running_rpc(...).result()typespec-java)beginLongRunningRpc(...), thengetFinalResult()typespec-ts)await client.longRunningRpc(...)LongRunningRpcAsync(WaitUntil.Completed, ...)WaitUntil.Started. These belong to the Azure extension, not generic C# alone.What this means for the work items
Python: result extraction, paging, and poller controls
typespec-pythondelegates to the shared Python emitter with Azure flavor. Its result adapter selects result type and extraction segments separately (L06). Radiology already extractsresult; the investigation is about the selected type and generation inputs, not adding extraction from scratch.The Python generator implements
polling=False, caller polling strategies, continuation-token restoration, and a pager starting from the completed response (L17/L18/L23/L24). That is not proof of Translation's separate final listing or custom-token compatibility. Declared terminal-value and arbitrary linked-operation binding support remain unverified.Java: typed result projection and management LRO+paging
The Azure package uses its declared shared-source revision, not automatically shared main. Its metadata translation distinguishes result from envelope, but carries only the last extraction-property segment and leaves nested extraction as a TODO (L06).
Although the mapper chooses its paging branch first, Azure management handles initial polling inside that branch. The matching generated client and two-page assertions are linked in #5545. This does not establish data-plane Language/Translation parity (L17/L18).
TypeScript: result paths, initial LRO followed by pages, and resumption
The TS result adapter consumes final-result type and segments (L06). The generated paging example awaits an initial poller before ordinary pages (L17/L18); it does not establish a new LRO per page.
Standard scenario assertions cover typed results, progress, and serialize/restore (L24). The runtime bridge does not forward
skipFinalGet; reuse the existing L03 issues. Client-side request abort is not service cancellation.C#: distinguish the generic emitter, Azure extension, and runtime
The requested generic C# front end accepts
lroandlropagingmetadata; this is not evidence of automatic Azure polling. The Azure extension installs its LRO visitor and uses Azure.Core polling.That visitor projects a configured result property (L06); arbitrary nested-path traversal is not established. The runtime uses fixed terminal strings, not demonstrated consumption of arbitrary declared values (L01). Azure management separately generates LRO+paging internally by design; public support remains deferred. See #5545. Data-plane paging and service-specific resume parity remain unverified (L17/L18/L24). Checked-in generated C# signature baselines have stub bodies; the implementation and assertions, not those signatures alone, supply the evidence.
Provenance: the four-language sources are independently pinned, not a verified compatible build matrix. Python source/dependency versions agree, not verified package bytes; C# extension dependencies are not the inspected generic SHA. Earlier Go evidence is supplemental. Service compatibility requires separate proof.
Workstreams and next steps
These are navigation groups, not implementation issue boundaries. The expandable inventory below preserves the individual work items and their stable tracking IDs.
Remaining decisions
Filed and reused issues are linked natively and beside their inventory IDs. Other IDs remain classifications, not implementation commitments; the filing register below records their status.
What stays customized
Keep nonstandard and compatibility-specific behavior unless there is a concrete benefit and an owner-approved replacement. This includes legacy Key Vault workflows, DeviceUpdate/DeviceRegistry compatibility, and service-specific Batch, Load Testing, Storage, and CCF behavior.
For approved exceptions such as Ledger's
waitForCommit, prefer existingclient.tspcomposition or a small convenience wrapper where appropriate. No generic state-machine engine, global fallback flag, or Core/TCGC redesign is a prerequisite.Progress
Detailed inventory
Open the relevant workstream below. Each entry states its assessment, next action, and service SDK observations. The four-emitter examples above are separate evidence: a generic scenario does not establish service-specific parity. Omitted languages remain unverified, not unsupported. Investigate means the cause or support obligation is unresolved; optional improvement needs owner agreement; keep customization is a deliberate disposition, not unfinished implementation work.
Source links are placed beside each finding. Full evidence notes, repository routing, and migration criteria are available at the end. Findings are based on the recorded source snapshots, not live-service verification.
Protocol wiring and polling correctness - 9 entries
Consume declared terminal values; Security Domain and other annotated status monitors
L01 - Legacy exception; generic defect not established.
The Security Domain spec explicitly calls
"Success"a shipped deviation from"Succeeded". Preserve this customization unless exception support is agreed. A separate supported-contract terminal-value defect needs its own reproduction; the annotation alone is not a support obligation.SDK observations: Python: Handwritten.
Sources:
Successalready annotated in SDK-pinned spec · current TCGC mapping/terminal translationUse the declared polling-header/operation source; Admin as a lead
L02 - Needs a supported-contract reproduction before filing.
Compare declared polling metadata with the active generated/runtime path. Admin custom code alone does not establish a supported-contract defect. Keep this separate from final-GET policy.
SDK observations: Python: Handwritten; JavaScript: Handwritten.
Sources: Python final GET/token overrides
Suppress an unsupported final GET; Admin restore, Security Domain
L03 - Existing exception-specific integration work. First-priority investigation.
Reuse TypeScript #4771 and JavaScript #32142. Go restore uses transformed generation plus custom pollers; this is not uncustomized generation. Emitter issue requires internal operation-level config and result/deserialization agreement.
SDK observations: Python: Handwritten; JavaScript: Handwritten.
Sources: existing integration issue · restore final result from monitor
Resolve endpoint-relative polling/final links; DeviceUpdate
L04 - Compatibility exception; optional reachability investigation. Only with an owner-backed adoption case.
Java sampled generated paths already pass an endpoint to stock polling. Verify remaining custom callers before a cleanup issue; absolute-URL guideline and compatibility exception remain distinct.
Sources: Java generated stock strategy with endpoint · maintainer's exception explanation
Invoke a linked polling GET with parameter binding
L05 - No new generic linked-GET feature issue.
Core/TCGC already carry linked operations and parameter mappings. Identify a concrete supported consumer failure before filing; ordinary header-URL polling does not demonstrate explicit parameter binding.
Sources: linked polling/final operations with parameter mapping
Keep final extraction path and result type consistent; Radiology
L06 - Reuse #1167; no duplicate Python issue.
That issue already covers Radiology's path/type mismatch. The checked-in Python callback still projects
resultinto the job type; Java explicitly configures its inference type, and C# provenance does not prove patch-free generation. Reproduce with a pinned current toolchain before assigning a new defect.SDK observations: Python: Handwritten; Java: Not verified (positive implementation); C#: Not verified (positive implementation).
Sources: generated Python callback · patch
Java Content Understanding generated polling header-name expression
L07 - Verify stale rewrite under Java #50552.
Release-associated helper source already uses
getCaseSensitiveName(). The inspected header accessor delegates totoString(), so a key mismatch is not established. Regenerate without this rewrite before removing it.SDK observations: Java: Rewrite hook present; current behavioral effect unverified.
Sources: Java generated-polling patches
Java Content Understanding generated sync-poller method annotation
L08 - Verify stale rewrite under Java #50552.
The patch removes
@Overridefrom syncgetResult, notonInitialResponse. The release-associated template already lacks that annotation. Check the resolved runtime and compilation before removing the rewrite.SDK observations: Java: Rewrite hook present; current behavioral effect unverified.
Sources: Java generated-polling patches
Java Content Understanding generated polling error-message formatting
L09 - Low-priority maintenance under Java #50552.
This patch adds a comma, not a formatting placeholder. Current source already has it and retains duplicate punctuation. Record this rewrite separately within the cleanup task; cosmetic formatting must not block LRO work.
SDK observations: Java: Rewrite hook present; current behavioral effect unverified.
Sources: Java generated-polling patches
Operation metadata and typed SDK results - 7 entries
URI-derived operation ID available after initiation; Document Intelligence/Content Understanding
L10 - Optional SDK API improvement.
Agree extraction/timing/resume and per-language API. JS Document Intelligence intentionally replaced poller ID access with an initial-response helper; JS Content Understanding customizes state plus a deprecated poller property. Do not infer missing parity from API differences. Java's body ID getter does not establish the same source or immediate-availability contract.
SDK observations: Python: Handwritten; C#: Handwritten; JavaScript: Handwritten (Content Understanding); Not verified (Document Intelligence provenance).
Sources: Python URI-derived ID · Document Intelligence intentional ID API change
Expose typed monitor-body
usage; Content UnderstandingL11 - Optional SDK API improvement.
Python reads latest envelope when done, not necessarily successful; JS captures at result deserialization and exposes state/result. Agree lifecycle rather than assume identical accessor behavior.
SDK observations: Python: Handwritten; C#: Handwritten; JavaScript: Handwritten.
Sources: Python ID/usage/lifecycle · Content Understanding custom ID/usage API
Typed final result / operation identity; App Configuration snapshots
L12 - Optional SDK API improvement.
Java includes explicit polling/final GET; other sampled wrappers use stock paths. Scope the actual API/identity/diagnostic contract, not a presumed protocol gap.
SDK observations: Java: Handwritten; C#: Handwritten; JavaScript: Handwritten.
Sources: C# typed operation wrapper · AppConfig public typed wrapper with stock runtime
Typed final result; DevCenter
L13 - Optional SDK API improvement.
C# result-conversion issue, separate from public signature adaptation L14 and from App Configuration adoption.
SDK observations: C#: Handwritten.
Sources: separate signature and result adaptations
Derive DevCenter path name from model / preserve convenience signature
L14 - Optional client shaping or retained compatibility.
Existing client shaping first; typed LRO result generation alone does not remove this customization.
SDK observations: C#: Handwritten.
Sources: separate signature and result adaptations
Return no monitor as Python upload result; Security Domain
L15 - Keep the existing result contract.
Preserve Python result contract; assess client result shaping only if owner requests removal. Not a new polling protocol.
SDK observations: Python: Handwritten.
Sources: distinct Python behaviors
Preserve DeviceRegistry protocol poller result type for compatibility
L16 - Keep compatibility customization.
Carry-forward BinaryData-versus-Void/public API decision; not equivalent to broken final-result inference.
SDK observations: Java: Patched generation.
Sources: result-type compatibility customization
Paging, aggregate results, and errors - 5 entries
Page results from the completed monitor; TextAnalytics/Conversations
L17 - Shared fixture validation filed as #5545.
Python/TS/Java have matching first-LRO/ordinary-pages ARM examples; C# management intentionally keeps the combined API internal. Validate a pinned matrix, not a presumed skipped-poller bug. Language monitor-result and item-shaping parity remains separate.
SDK observations: Python: Handwritten; Java: Handwritten (TextAnalytics); Not verified (Conversations); C#: Legacy implementation (TextAnalytics); Not verified (Conversations); JavaScript: Legacy implementation (TextAnalytics); Not verified (Conversations).
Sources: Conversations patch · agreed legacy-only support scope
Invoke a separate pageable final operation; Translation
L18 - Investigate an optional client-composition improvement. Optional; requires owner agreement.
SDK chooses document statuses after batch completion. Spec's linked final operation is batch status, not automatically the public pager. Try client composition before a new shared contract. Java returns batch status with document listing separate; that is not the same public result contract.
SDK observations: Python: Handwritten; C#: Handwritten.
Sources: Python final pageable callback · current linked batch status and DELETE cancellation
Aggregate versus flatten action/page items; Language family
L19 - Keep item shaping unless an owner wants a change.
Separate item shape, ordering, and per-item errors from wire paging. One client-shaping decision per public contract; no blanket Conversations parity.
SDK observations: Python: Handwritten; Java: Handwritten (TextAnalytics); C#: Legacy implementation (TextAnalytics); JavaScript: Legacy implementation (TextAnalytics).
Sources: TextAnalytics patch
Return useful document results after failed/canceled batch work; Translation
L20 - Keep the existing business-result contract.
Preserve business-result contract; enum
Faileddoes not alone dictate throwing fromresult(). Not terminal-list consumption L01.SDK observations: Python: Handwritten; C#: Handwritten.
Sources: C# failed translation with usable document results
Translation validation-failure error projection
L21 - Keep exceptional error policy; investigate only a concrete defect.
C# also throws for ValidationFailed; exact nested-error shaping parity remains unverified. Separate from ordinary failed-batch document results.
SDK observations: Python: Handwritten; C#: Handwritten (classification); Not verified (innerError parity).
Sources: custom polling/error handling
Poller lifecycle, cancellation, and continuation - 6 entries
Retain initial-response result while monitoring; Security Domain download / Ledger create
L22 - Keep initial-response result retention.
Return initial payload rather than monitor result. Separate result retention from final-GET suppression, terminal literals, transaction identity, and no-wait behavior.
SDK observations: Python: Handwritten.
Sources: distinct Python behaviors · Python ledger patch
Local no-wait / opting out of polling; Security Domain
L23 - Keep client/CLI no-wait behavior.
CLI/client lifecycle behavior, not service cancellation and not a service-schema feature.
SDK observations: Python: Handwritten.
Sources: distinct Python behaviors
Continuation-token representation and rehydration; Admin lead
L24 - Compatibility-sensitive lifecycle investigation, if requested. Only with an owner-backed adoption case.
C# resumes backup from ID, JS restores state by method/path, Go rehydrates handlers. Preserve each contract, not one universal token format.
SDK observations: Python: Handwritten; C#: Handwritten (backup ID); JavaScript: Handwritten.
Sources: Python final GET/token overrides · custom restore/rehydration
Request certificate-operation cancellation
L25 - Keep service-specific cancellation behavior.
Java/JS explicit service cancellation callbacks established; other cells need call-site evidence. Separate from certificate creation policy and local cancellation.
SDK observations: Java: Handwritten; JavaScript: Handwritten.
Sources: certificate monitor/cancel · Java certificate callbacks
Request Translation cancellation
L26 - Keep service-specific cancellation behavior.
Service uses DELETE of a batch and has race/partial-result semantics. A canceled terminal annotation is not a cancel request contract.
SDK observations: Python: Handwritten; C#: Handwritten.
Sources: current linked batch status and DELETE cancellation
Request Load Testing stop/cancellation
L27 - Inventory the service stop operation; do not assume a generator gap. No replacement planned.
Record the actual operation and whether the existing SDK attaches it to a poller; prior service-level cancellation lead is not proof of a missing generator feature.
Sources: current spec contrasts ordinary test-run create/update with standard long-running actions
Historical workflows and compatibility exceptions - 22 entries
Deleted/recovered resource visibility; Key Vault keys/secrets/certs
L28 - Keep the existing visibility workflow.
GET deleted/live resource; 404 is pending. Keys/secrets are two families, with certificates a third; no "4 packages x 4 languages" removal estimate.
SDK observations: Python: Handwritten; Java: Handwritten; C#: Handwritten; JavaScript: Handwritten.
Sources: Python visibility contract
Permission/exception completion policy during Key Vault visibility polling
L29 - Keep operation-specific permission/error handling.
Sampled 403 rules and Java broader exception completion differ. Do not infer identical semantics or generalize 403 as proof of resource existence.
SDK observations: Python: Handwritten; Java: Handwritten; C#: Handwritten; JavaScript: Handwritten.
Sources: C# delete secret · Java exception policy
Pending certificate monitor
L30 - Keep the pending-certificate workflow.
Bespoke creation workflow; status aliases alone do not replace it. Unknown-issuer early exit is separately tracked in L48, not presumed cross-language parity.
SDK observations: Python: Handwritten; Java: Handwritten; C#: Handwritten; JavaScript: Handwritten.
Sources: Python certificate creation
Retrieve certificate after successful creation monitor
L31 - Keep certificate final retrieval.
Separate final retrieval from L30's termination policy if a future replacement is approved.
SDK observations: Python: Handwritten; Java: Handwritten; C#: Handwritten; JavaScript: Handwritten.
Sources: Java certificate callbacks
Finish when a Batch resource leaves a transitional state
L32 - Keep operation-specific Batch predicates.
One operation's predicate at a time; not necessarily a designated success/failure enum. Do not roll all 14 poller classes into one implementation claim.
SDK observations: Python: Handwritten; C#: Handwritten; JavaScript: Handwritten.
Sources: Python predicates
Wait for Batch pool allocation state to become steady
L33 - Keep the pool-state completion policy.
Different property/poll target from job/node state; shared transport does not imply shared result policy.
SDK observations: Python: Handwritten; C#: Handwritten; JavaScript: Handwritten.
Sources: C# resize semantics
Treat Batch polling GET's 404 as completion
L34 - Keep operation-specific disappearance handling.
Different from Key Vault visibility. Preserve whether completion has a value and how non-404 errors propagate.
SDK observations: Python: Handwritten; C#: Handwritten; JavaScript: Handwritten.
Sources: JS custom poller
Load Testing run/profile-run execution completion versus business outcome
L35 - Keep the existing business-result contract.
Python/C#/JS can return failed/canceled run results. Java maps poll states to failed/canceled; runtime return/throw behavior remains untraced. JS profile-run is separate coverage.
SDK observations: Python: Handwritten (run); Java: Handwritten (run); C#: Handwritten (run); JavaScript: Handwritten (run/profile).
Sources: Python execution/validation policies · Java Load Testing policies
Load Testing file-validation completion policy
L36 - Keep the file-validation completion policy.
Separate validation terminal set and GET binding; Java maps failure state, while JS completion returns response even for validation failure. Do not infer identical public outcomes.
SDK observations: Python: Handwritten; Java: Handwritten; JavaScript: Handwritten.
Sources: file validation
Discovery resource
provisioningStatepollingL37 - Filed contract investigation: specs #46595.
Python/C# share a spec pin declaring a status monitor, but custom code reads resource provisioning state; C# polls the resource directly. Establish actual poll route/body and completion field before blaming an emitter. Keep indexing state separate.
SDK observations: Python: Handwritten; C#: Handwritten.
Sources: Python custom operations
Discovery synchronous initial response handling
L38 - Filed contract investigation: specs #46596.
Both custom pollers complete on missing Operation-Location, more broadly than the HTTP-200 comments. Confirm allowed initial status/header/body combinations and negative cases separately from L37.
SDK observations: Python: Handwritten; C#: Handwritten.
Sources: C# Discovery completion
Discovery delete-until-gone
L39 - Investigate source provenance before considering adoption. Evidence collection only.
Current sampled Python patch does not establish an active custom delete path; test comments mention an old class while supplying stock polling. Do not count stale comments. C# evidence remains separate.
SDK observations: C#: Handwritten.
Sources: Python delete test and stale-comment lead · C# customization directory
Storage copy identity and completion tracking
L40 - Keep the copy tracking/result contract.
Explicit implementations have different final results: Java Void, C# byte count. Identity/error policies must be compared per operation, not merely linked GET status.
SDK observations: Java: Handwritten; C#: Handwritten; JavaScript: Handwritten.
Sources: C# copy operation · Java Storage callbacks
Storage copy progress exposure
L41 - Keep progress API; optional client improvement.
JS progress callback confirmed; other languages' equivalent progress API was not established. Do not equate final byte count with progress reporting.
SDK observations: JavaScript: Handwritten.
Sources: JS copy poller
Storage copy abort/cancellation
L42 - Keep service-specific copy abort behavior.
Java/JS provide abort callbacks. C# copy tracking is not proof of an equivalent poller cancellation API. Separate service abort from local polling stop.
SDK observations: Java: Handwritten; JavaScript: Handwritten.
Sources: Java Storage callbacks · JS copy poller
CCF commit-status polling
L43 - Keep the CCF commit protocol.
Service-specific Ready/Committed terminal policy, not a generic shared-support task. Separate ID mapping (L49), original-response retention (L22), and replication errors (L45).
SDK observations: Python: Handwritten; C#: Handwritten.
Sources: Python ledger patch
CodeTransparency encoding or result representation
L44 - Investigate missing source evidence. Evidence collection only.
The earlier cited C#
CreateEntryOperation.cspath does not resolve at its claimed snapshot and was not located by code search. Retract the proven-customization claim until the actual source is found; do not extrapolate Ledger behavior.CCF replication-lag 404 tolerance
L45 - Keep operation-specific replication-lag handling.
Python and C# have bounded/operation-specific handling; C# gateway/direct policies differ. Neither generic disappearance completion nor Key Vault visibility.
SDK observations: Python: Handwritten; C#: Handwritten.
Sources: C# CCF direct/gateway behavior
Ledger
waitForCommitclient API splitL46 - Optional client composition for an approved-exception direction. Only with an owner-backed adoption case.
Evaluate separate LRO-like and normal methods using existing client modeling; wrapper is an alternative, not a second mandatory feature. Preserve timeout/recovery limitations.
Sources: review direction: separate client operations or convenience wrapper
Key Vault visibility poller nonblocking result access
L47 - Keep the nonblocking result-access contract.
Python returns retained resource from
result()without waiting;wait()drives polling. Preserve this independent API contract if visibility polling is ever replaced.SDK observations: Python: Handwritten.
Sources: Python nonblocking result contract
Certificate unknown-issuer short circuit
L48 - Keep the issuer-specific early exit.
Python completes immediately for unknown issuer; analogous JS branch was not established. Do not silently copy this rule across language implementations.
SDK observations: Python: Handwritten.
Sources: Python certificate creation
CCF transaction identity mapping
L49 - Keep transaction identity mapping.
Python exposes the response transaction-ID header in its result/commit flow. Different from commit-state polling and returning the original create payload. Any CodeTransparency ID swap needs its own pinned operation evidence.
SDK observations: Python: Handwritten.
Sources: Python ledger patch
Deferred design topics - not implementation prerequisites
Issue filing, repository ownership, and existing links
Filing issues and tracking adoption
2026-09-22 filing pass: reuse exact duplicates, file contract questions as investigations, and treat stale rewrites as maintenance. A filed issue is not a confirmed bug or an assigned owner.
Dependency order: support/contract decision -> reproduction -> necessary shared/spec/runtime change -> emitter change -> SDK adoption -> exact workaround removal. Skip unnecessary layers. Optional work needs owner interest; generic nonstandard implementation is not committed.
Cross-repository ownership map
typespec-python,typespec-java,typespec-ts, and cross-language scenarioshttp-client-python,http-client-java,http-client-js,http-client-csharpinfrastructure; route only after tracing whether the shared or Azure layer is responsibleclient.tspcompositioneng/packages/http-client-csharp, runtime and SDK adoption; shared-base defects may belong in microsoft/typespecThese are repository routes, not assigned owners. In particular, emitter changes do not automatically belong in the language SDK repo: the Azure Python package consumes the shared Python emitter; the generic C# emitter is in microsoft/typespec; Azure-specific C# generation has a separate layer in azure-sdk-for-net. Pin the actual generator package/version used by the SDK before filing.
Linking and tracking convention
Keep #5432 as the parent. Link each child natively and beside its L/D ID; children link back and name dependencies. Reuse existing issues. Track classification, owner review, filing, implementation, and SDK adoption separately, alongside accepted/deferred/needs-evidence dispositions. See the filing register for new and reused children; remaining inventory entries are not automatically work commitments.
Related support and integration issues
Support policy, evidence standards, and migration safeguards
Use the applicable Azure REST API guidelines and explicit support decisions, including legacy-only LRO+paging. Service-exception approval is distinct from emitter support; an initial LRO followed by ordinary pages does not imply per-page LRO support.
Compare like with like: same service operation, API version, request/result/error semantics, and intended public API. Generic fixture examples do not establish patch-free service parity; working handwritten code does not establish spec correctness. A confirmed bug does not require two languages to reproduce it. Track technical layer, spec confidence, and delivery status separately.
One leaf issue, one outcome: name its owner/repo, L/D ID, source and package versions, support basis, expected behavior, non-goals, dependencies, and closure criterion. Investigations close with evidence and a disposition. Implementations and SDK adoption are tracked separately.
Before removing a customization: cover relevant initial/poll/final requests, synchronous responses, success/failure/canceled/unknown states, eventual consistency, paging laziness, metadata timing, and token compatibility. Preserve public APIs unless change is approved. A regeneration diff alone is insufficient.
Measure outcomes: count reproduced defects fixed and active workarounds removed, separately from accepted, optional, deferred, and unknown cases. Reclassification is not implementation progress; equivalent semantics do not require identical APIs.
Reduce undeclared protocol inference, not necessary response inspection. No global fallback flag, generic state-machine framework, or wholesale Core/TCGC rewrite is a prerequisite.
Full source notes and research limitations
Source snapshots and limitations
Sources below are pinned where practical. Earlier 2026-09-15 source snapshots remain valid observations of those revisions, not claims that a current emitter is still broken. The 2026-09-21 follow-up adds source review, not live-service verification. Attach spec/emitter/runtime versions to each child before treating it as reproducible.
Successalready annotated in SDK-pinned spec.6b1d50b: Content Understanding custom ID/usage API; Document Intelligence intentional ID API change; Load Testing profile-run result; file validation; certificate monitor/cancel; AppConfig compatibility wrapper.843a26a: Admin generator transform installs custom handlers; restore final result from monitor; custom restore/rehydration; AppConfig public typed wrapper with stock runtime.