You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Generated doc comments: payload wording on no-content envelopes and adapters #177
No-content (204) operations get payload wording in their generated XML documentation:
The error-path constructor of every envelope says "the payload stays unset behind its guard", including envelopes that have no payload. Example: src/OpenCode.Sdk/Credentials/CredentialActivateResponse.cs:20.
The response adapter says "Maps the declared UTF-8 success body onto the typed envelope", including adapters for operations with no body. Example: CredentialActivateResponseAdapter.
The two other defects this issue first recorded (the article before a vowel; split acronyms and version digits) were fixed by #418. The evidence is in the comments.
Evidence (master 46b65a7e)
tools/OpenCode.Sdk.Tools/Generator/Emission/EnvelopeEmitter.cs:188 emits the payload wording for every envelope.
tools/OpenCode.Sdk.Tools/Generator/Emission/ResponseAdapterEmitter.cs:155 emits the success-body wording for every adapter.
Done when
No-content envelopes and adapters carry no payload or body wording; envelopes and adapters with a payload keep theirs.
Emitter tests pin both cases.
generate --verify is clean, and the regenerated diff touches documentation only.
Owner
The per-operation behaviour epic (#482), which owns EnvelopeEmitter and ResponseAdapterEmitter.
Root causes, located on master a5def42d (a read-only scan, about 78 matches across about 70 generated files):
The article is hard-coded. The fallback doc comments build "a {name}" whatever the name's first sound is:
tools/OpenCode.Sdk.Tools/Generator/Emission/ModelEmitter.cs:64: Represents a {GeneratedDisplayName.Of(model.Name)} value.
HoistedInterfaceEmitter.cs:30: Represents a {plan.Name} value., which is also not passed through GeneratedDisplayName.
StructuralUnionEmitter.cs:77: Represents a {DisplayName(union.Name)} structural union.
StructuralUnionEmitter.cs:197: Creates a {DisplayName(union.Name)} from its {DisplayName(arm.Name)} arm.
UnionEmitter.cs:62: Represents a {GeneratedDisplayName.Of(union.ConceptName)} union.
Acronyms and versions split.GeneratedDisplayName.cs:11 joins CSharpNamePolicy.SplitWords(name) lowercased, so V1 reads as v 1, and acronyms lose their casing.
A fix picks the article in one place (from the display name's first sound, with an exception list for acronyms) and keeps known tokens such as V1 and the brand acronyms whole. Generated output then changes only through generate, after the layout's first slice (#173) moves the emitters.
Re-scoped to item 3 only. Items 1 and 2 are fixed on master (46b65a7e) by #418 (fe05ebff, "generated summaries are grammatical and spell brands right"):
Article:AgentInfo reads "Represents an agent info value." and ExperimentalMigrationV1Status reads "Represents an experimental migration V1 status structural union." No generated /// line in src/OpenCode.Sdk puts "a" before a vowel sound; the one "a" + vowel left is a curated "as a Unix timestamp" (ModelInfoTime.cs:12).
Acronyms and versions:CredentialOAuth reads "Represents a credential OAuth value." No generated summary splits a version into "v 1".
One helper: every emitter that builds a display name calls GeneratedDisplayName (Model, Union, StructuralUnion, HoistedInterface, ExtensibleEnum). StructuralUnionEmitter no longer has its own copy.
Item 3 is still open. The payload wording is emitted unconditionally:
tools/OpenCode.Sdk.Tools/Generator/Emission/EnvelopeEmitter.cs:188: "Initializes an error-path instance; the payload stays unset behind its guard." It appears in all 139 envelopes, including no-content ones such as CredentialActivateResponse (src/OpenCode.Sdk/Credentials/CredentialActivateResponse.cs:20).
tools/OpenCode.Sdk.Tools/Generator/Emission/ResponseAdapterEmitter.cs:155: "Maps the declared UTF-8 success body onto the typed envelope." It also appears on no-content adapters such as CredentialActivateResponseAdapter.
Both emitters belong to the per-operation behaviour epic (#482), which already owns their shared code, so this issue moves under #482.
changed the title [-]Generated doc comments: wrong article, split acronyms, and payload text on no-content responses[/-][+]Generated doc comments: payload wording on no-content envelopes and adapters[/+]on Oct 23, 2026
Activity
Blind-Striker commentedon Oct 14, 2026
Root causes, located on master
a5def42d(a read-only scan, about 78 matches across about 70 generated files):tools/OpenCode.Sdk.Tools/Generator/Emission/ModelEmitter.cs:64:Represents a {GeneratedDisplayName.Of(model.Name)} value.HoistedInterfaceEmitter.cs:30:Represents a {plan.Name} value., which is also not passed throughGeneratedDisplayName.StructuralUnionEmitter.cs:77:Represents a {DisplayName(union.Name)} structural union.StructuralUnionEmitter.cs:197:Creates a {DisplayName(union.Name)} from its {DisplayName(arm.Name)} arm.UnionEmitter.cs:62:Represents a {GeneratedDisplayName.Of(union.ConceptName)} union.GeneratedDisplayName.cs:11joinsCSharpNamePolicy.SplitWords(name)lowercased, soV1reads asv 1, and acronyms lose their casing.A fix picks the article in one place (from the display name's first sound, with an exception list for acronyms) and keeps known tokens such as
V1and the brand acronyms whole. Generated output then changes only throughgenerate, after the layout's first slice (#173) moves the emitters.Blind-Striker commentedon Oct 23, 2026
Re-scoped to item 3 only. Items 1 and 2 are fixed on master (
46b65a7e) by #418 (fe05ebff, "generated summaries are grammatical and spell brands right"):AgentInforeads "Represents an agent info value." andExperimentalMigrationV1Statusreads "Represents an experimental migration V1 status structural union." No generated///line insrc/OpenCode.Sdkputs "a" before a vowel sound; the one "a" + vowel left is a curated "as a Unix timestamp" (ModelInfoTime.cs:12).CredentialOAuthreads "Represents a credential OAuth value." No generated summary splits a version into "v 1".GeneratedDisplayName(Model, Union, StructuralUnion, HoistedInterface, ExtensibleEnum).StructuralUnionEmitterno longer has its own copy.Item 3 is still open. The payload wording is emitted unconditionally:
tools/OpenCode.Sdk.Tools/Generator/Emission/EnvelopeEmitter.cs:188: "Initializes an error-path instance; the payload stays unset behind its guard." It appears in all 139 envelopes, including no-content ones such asCredentialActivateResponse(src/OpenCode.Sdk/Credentials/CredentialActivateResponse.cs:20).tools/OpenCode.Sdk.Tools/Generator/Emission/ResponseAdapterEmitter.cs:155: "Maps the declared UTF-8 success body onto the typed envelope." It also appears on no-content adapters such asCredentialActivateResponseAdapter.Both emitters belong to the per-operation behaviour epic (#482), which already owns their shared code, so this issue moves under #482.
[-]Generated doc comments: wrong article, split acronyms, and payload text on no-content responses[/-][+]Generated doc comments: payload wording on no-content envelopes and adapters[/+]fix(generator): no-content envelopes and adapters stop mentioning a p…