Repository navigation
XML docs: the long tail of placeholder summaries on public generated members #478
Description
Priority: high. The maintainer decides at the end of the 1.0 road whether the long tail blocks 1.0.0 or ships after it.
What
IntelliSense is the documentation surface consumers read most, and in the public members it is still mostly empty. In the shipped lib/net10.0 XML of the 2.0.32 nightly, 2,668 of 4,307 public T:/P: entries (62%) are placeholders such as "Gets the X value." or "Represents a X value." The counting method differs from the preview.10 round's (55%), so read the trend loosely. The gap is real either way.
This issue owns the long tail: every public generated member whose summary still says nothing beyond its name, after the work that already landed.
What already landed (not this issue)
- Generated summaries are grammatical, and a guard caps the placeholder ratio ([GEN-E6] generated summaries: grammatical articles, whole brand spellings, digits on their word #418, [GEN-E6] a guard keeps generated summaries free of grammar defects and caps the placeholder ratio #435).
- Every curated description cites the upstream declaration it states, proven against the pinned tree ([GEN-E6] every curated description cites the upstream declaration it states, proven against the pinned tree (PR 2a) #445).
- Curated interface documentation reaches its implementing members through
inheritdoc([GEN-E6] curated interface documentation reaches its implementing members; 26 moved rows return narrowed (PR 2b) #455). - Upstream schema descriptions are carried through where upstream has them (XML docs: carry upstream schema descriptions through instead of placeholder summaries #269, closed).
So the remaining placeholders are mostly members upstream itself does not describe in the pinned OpenAPI document.
Why it matters (evidence)
In the internal developer-experience round on the 2.0.32 nightly (2026-10-18, 12 apps built from the public docs alone on Windows, Linux and macOS), the thin XML was the weakest surface:
- Builders reached for reflection over public signatures to learn what a member holds (apps 04, 05, 06, 07 and 08).
- Union members carry no CLR type and no nullability in their docs:
IFormField.Key, the config-source unions and the nestedBranchshapes. - Timestamp members state no unit or type (tracked separately in XML docs: timestamp members don't state their unit or type #303).
- The answer shape for a question form (
FormValue,FormStringField) was found only by reflection or trial.
Scope
Every public type and member in OpenCodeDotNet.Sdk and OpenCodeDotNet.Sdk.Extensions whose shipped XML summary is a placeholder.
Not in scope:
- Internal members in the shipped XML, which is Packages: strip internal members from the shipped XML documentation #286.
- Timestamp units, which is XML docs: timestamp members don't state their unit or type #303. This issue reuses XML docs: timestamp members don't state their unit or type #303's rule once it lands.
Proposed approach
These steps are ordered; each one shrinks the ratio guard's ceiling (#435), which only falls.
- Inventory. Classify every placeholder by kind: event payload, request model, response model, union arm, enum literal, options, error. For each, record whether upstream describes it anywhere at the pin: OpenAPI, the schema package, the Effect source, or TypeScript doc comments. This is a committed, generated report, not a hand list.
- Carry through what upstream has. Where upstream describes a member outside the OpenAPI document (schema package, source comments), cite it the same way [GEN-E6] every curated description cites the upstream declaration it states, proven against the pinned tree (PR 2a) #445 does.
- Mechanical facts the generator already knows. Every union arm names its CLR type, and every optional or nullable member says when it is absent. Ranges and formats the contract declares are stated. Enum literals state their wire value. These come from the binding model, not from prose.
- Members consumers demonstrably touch. The members the developer-experience rounds and the guides use get hand-written summaries, each citing the upstream declaration or behaviour it states (the [GEN-E6] every curated description cites the upstream declaration it states, proven against the pinned tree (PR 2a) #445 rule).
- The rest of the tail. Hand-written summaries in batches by family, under the same citation rule. A batch that cannot cite upstream for a statement leaves the statement out rather than guessing.
- Upstream proposal. Propose to upstream that its schemas carry descriptions for the members we had to describe by hand, so a later pin refresh carries them through and our curation shrinks.
Acceptance
- The placeholder ratio guard's ceiling is at the agreed target. The target is set after step 1's inventory, with the maintainer.
- No public union arm and no optional member lacks a statement of its CLR type or its absence.
- Every hand-written summary cites the upstream declaration it states, and the existing guard enforces it.
- The inventory report is regenerated by the generator and checked in CI, so a pin refresh shows new placeholders as a diff.
Source: internal developer-experience evaluation of the 2.0.32 nightly, 2026-10-18 (finding D32-8), and of 0.9.0-preview.10, 2026-10-14 (finding DX-4).
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsQueue
Activity