fix(kiota): document patches, Accept normalisation, expansion-gated read — the three live-run #3 failures - #109
Merged
Merged
Conversation
…ion, expansion-gated read The three live acceptance failures each exposed a place the generated document was allowed to overrule observed reality, and each fix moves the authority back to the evidence. sdk generate gains document patches: curated RFC 6902 corrections under openapi/<provider>/patches/, each carrying a justification naming its evidence, applied to a copy of the snapshot -- whose bytes and checksum never change -- before kiota reads it. Application walks the YAML node tree rather than a decoded map because document order is load-bearing: kiota names colliding anonymous schemas by encounter order, and an early JSON re-encode that sorted the keys re-awoke exactly the nondeterminism this work went on to fix. A patched generation rewrites only the lock's descriptionLocation, pointing it back at the pinned snapshot; -check applies the same patches, so the committed tree stays provable. An add that finds its value already present refuses as stale, which is how a patch announces the vendor has fixed the document. Two patches ship. The first adds "none" to Alerts_API_RepeatType: the recordings show the API accepting and echoing it, the published enum omits it, and a closed kiota enumeration made the value unrepresentable -- refused on write, silently dropped on read. The second collapses Endpoint_Agents_API_AgentTransfer's single-member anonymous allOf, the true root of the agents.go/proxies.go naming flip the excludes only appeared to cure; with the member named by its component, five consecutive drift checks pass where roughly one in five used to fail. The pilot client gains an Accept-normalising middleware: an operation whose specification declares only error media types gets Accept: application/problem+json alone from kiota, and the ThousandEyes API answers that header with 406 before reading the request -- the credential delete, live. The header is widened to admit the API's real success forms, and a wire test pins it beside the gzip one. endpoint_label's read chain now passes a request configuration asking for expand=filters, which the blueprint's own probe note has always said the read must do; the port had flattened every trailing argument to nil, so each read-after-write returned a label without filters and the state promptly contradicted the plan. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Aug 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
go | Acceptance tests (kiota)run #3 failed on 4 of 10 packages (credential resource + ephemeral, alert_suppression_window, endpoint_label; everything else passed live). All three root causes are places the published document was allowed to overrule observed reality. Each fix moves authority back to the evidence.1. Document patches (new
sdk generatecapability)repeat.type = "none"failed with "not a member of models.Alerts_API_RepeatType". The recordings prove the API accepts and echoes"type": "none"; the published enum omits it; a closed Kiota enum therefore made the value unrepresentable in both directions — refused on write, and (proven offline) silently dropped on read.Per the decision to fix this systemically:
sdk generatenow applies document patches — curated RFC 6902 corrections underopenapi/<provider>/patches/*.patch.json, each with a mandatoryjustificationnaming its evidence — to a copy of the snapshot (whose bytes and checksum never change) before kiota reads it. Key properties:-checkapplies the same patches, so drift checking still holds the committed tree to the pinned inputs. The lock'sdescriptionLocationis rewritten (one field, byte-targeted) back to the snapshot; onlydescriptionHashchanges, deterministically.addthat finds its value already present refuses as stale — the prompt to delete the patch when the vendor fixes the document.Documented in
docs/cli.md(drift-tested) and the glossary (named document patch — this repo reserves "spec" for the provider spec).Two patches ship:
Alerts_API_RepeatTypegains"none"(recording-justified). The suppression-window blueprint needed no change — the existing enum converters simply start working.Endpoint_Agents_API_AgentTransfer's single-member anonymousallOfis collapsed into the plain object it definitionally is. This was the true root cause of the agents.go/proxies.go naming flip — the path excludes added in feat(kiota): parity foundations — every block kind fluent, full-spec SDK, single-nested rendering #107 only appeared to cure it (~1-in-5 failure surfaced again during this work). With the member named by its component, five consecutivesdk generate -checkruns pass.2. Accept normalisation (credential 406)
The credentials DELETE declares only error media types, so kiota emits
Accept: application/problem+jsonalone — and ThousandEyes answers that with a bare 406 before considering the request. A small middleware in the hand-owned pilot client widens such degenerate Accept headers to admit the API's real success forms; a wire test pins it beside the gzip regression test from #106.3. Expansion-gated read (endpoint_label filters null after apply)
The blueprint's own probe note has always said filters are "only returned when the read asks for expand=filters" — resty's read passes
WithQueryParam("expand","filters"), but the port flattened every fluent trailing argument tonil, soreadAfterWritereturned a label without filters and state contradicted the plan. The read chain's trailing argument is now a real request configuration (QueryParameters.Expand = [filters]) — pure blueprint data through the existing chain-argument import machinery; no emitter change needed.Verification
bindings check;probe verify7/7 resources; provider drift 0 on both pilots; root + kiota pilot suites 0 failures; docs drift test green."none"deserialization, DELETE Accept header).After merge: dispatch
go | Acceptance tests (kiota)for live confirmation, then the tests wave (PR 3 of the parity plan) proceeds.🤖 Generated with Claude Code