Skip to content

Binder naming-wall gaps: V16, V18, V19, V22 and review riders #27

Open

Description

@Blind-Striker

Source: multi-agent review of PR #26, adversarial verification verdicts (all CONFIRMED, severity 2 or 1, latent: none is reached by the current generation profile). 2026-08-14. M-anchor: M5 (full surface). Do them earlier when a change touches these walls. Riders from the second review (R2-*) and the 1ee8c30 review are in the comments below.

Each item: red-test-first refusal regression in OperationPlanBinderTests / CurationValidatorTests, then the wall.

Original items

  • V16 · A path parameter named path (or query) collides with the locals that RoutesEmitter declares inside query-composing builders (var path, var query) → CS0136. Extend the bind-time reserved-name wall to cover emitted builder locals.
  • V17 · Query-request property names were not checked against compiler-synthesized record members (EqualityContract, …). Closed: ReservedNamePolicy reserves the synthesized record members.
  • V18 · Synthesized {Member}Template route constants are absent from route-member collision validation: Get (builder, emits GetTemplate) plus a sibling GetTemplate → CS0102. Include synthesized names in the collision set.
  • V19 · The payload naming wall (ReservedNamePolicy.PayloadNames) omits the record-reserved name Clone → CS8859. Add it.
  • V22 · schemaAliases: [null] in curation crashes CurationValidator with NullReferenceException instead of a structured fail-closed curation error. Guard null rows across all curation collections.

Riders (details in the comments)

Status 2026-09-27: V16 (RoutesEmitter still declares the path and query locals), V18 and V19 were re-checked on master and are still open.

Activity

  1. Blind-Striker commented on Aug 15, 2026

    @Blind-Striker
    CollaboratorAuthor

    The second verified review of PR #26 adds five wall gaps to this issue's scope (all latent — none triggered by the pinned spec; each would surface as a compile error or silent misnaming in committed generated output instead of the contracted bind-time refusal):

    • R2-8 — verb fallback is silent. A KnownVerbSegments miss (only create/get/list today) falls back to HTTP-method-prefixed names with no diagnostic and no curation lever; the pinned pending queue already holds POST verb-final operations (v2.session.fork, v2.session.compact, v2.mcp.connect, v2.generate.text) that would bind cleanly to PostForkAsync-style names. Either the verb list grows deliberately per batch with a loud miss, or curation gains a method-name hook.
    • R2-9 — Pluralize misses -o endings. o-final words fall through to naive +s (Echos), contradicting the method's own refuse-on--es contract; add -o to the refusal list.
    • R2-10 — property names have no reserved-member wall. Model properties (SchemaPlanBinder) and query-record properties consult no reserved list beyond duplicates, so wire clone/equalityContract emits CS8859/CS0102 records. (The envelope-payload Clone gap was already V19 here.)
    • R2-11 — internal spine names are unwalled. ReservedSpineTypeNames lists public spine types only, while generated clients reference Pipeline/MockSeam/OpenCodeJsonContext unqualified under both usings — a model with one of those names goes CS0104-ambiguous. Path parameters named path/query (route-builder locals) and {X}Template route members were already V16/V18 here.
    • R2-12 — body-root claim can silently retype a shared component (PLAUSIBLE). The {Subject}{Verb}Request ownership claim renames the root for the whole selected closure without checking whether the root is also referenced as a nested model type elsewhere; if it is, that property's public type silently becomes {X}Request. The claim should refuse (or copy) when the root has non-body references.

    Trigger for the whole set: any breadth batch admitting one of these shapes fires the gap immediately; the walls are a hard gate before M5's full-surface profile. R2-8 is the most likely to fire first — the very next batch that selects a POST verb-final operation.

  2. Blind-Striker commented on Aug 17, 2026

    @Blind-Striker
    CollaboratorAuthor

    The 1ee8c30 review adds confirmed naming/curation riders to this existing wall batch.

    • Merged body/query collision: SpecBinder.AttachRequestQueryProperties appends query members without comparing them to body member names. A body and query both mapping to Location emit duplicate members instead of a located refusal.
    • Synthesized names: validate generated carrier names, route Template members, client backing members, and C# keywords for path parameters against the complete emitted symbol set. This extends the existing V16-V19/C20 family.
    • Duplicate/dormant curation: duplicate JSON dictionary keys are last-wins before validation; envelope payload rows for stream/204 shapes can pass but never be consumed.
    • Additive inline-union naming: common-prefix naming can rename an existing interface when a new branch has a different prefix. Require stable curation or refuse the evolution.
    • Current duplicate schemas: Session.Inbox.UserPayload1 equals Session.Inbox.UserPayload, and Session.Inbox.SyntheticPayload1 equals Session.Inbox.SyntheticPayload; validated alias rows should remove unstable numeric suffixes before packaging.
    • Brand/action trigger: v2.integration.oauth.connect currently derives Oauth without a brand-spelling mechanism. v2.event.subscribe is tracked separately because it blocks M3 Arc 3b.

    Triggers: current Inbox aliases in M3; operation/action/brand and remaining walls on first occurrence, no later than M5 full-surface acceptance.

  3. Blind-Striker commented on Aug 18, 2026

    @Blind-Striker
    CollaboratorAuthor

    Completed the current M3 alias subset in 7123627, and only that subset: Session.Inbox.SyntheticPayload1 -> Session.Inbox.SyntheticPayload and Session.Inbox.UserPayload1 -> Session.Inbox.UserPayload. Both rows pass the existing structural-equivalence wall against the pinned OpenAPI. Generator-owned regeneration renamed the two model files, updated both inbox item owners, serializer registry, generated manifest, and the reviewed PublicApi baseline. No wire shape or runtime behavior changed. Fresh-context review reported no findings. All six local gates passed with 1,240 tests, 0 failed, 0 skipped. Hosted CI run 32128587050 is green on Linux, Windows, and macOS after a diagnostic rerun of one unrelated Microsoft.OpenApi RegexMatchTimeoutException on the first Windows attempt: https://github.com/Blind-Striker/opencode-sdk-dotnet/actions/runs/32128587050. Keeping #27 open for its remaining first-occurrence/M5 naming and collision walls.

  4. changed the title [-]M5: binder naming-wall gaps — reserved locals, record members, route Template members, Clone, null curation rows (V16-V19 V22)[/-] [+]M5: binder naming-wall gaps — remaining: reserved locals (V16), route Template members (V18), Clone (V19), null curation rows (V22)[/+] on Sep 14, 2026
  5. Blind-Striker commented on Sep 14, 2026

    @Blind-Striker
    CollaboratorAuthor

    Status 2026-09-14: V17 is closed (ReservedNamePolicy reserves the compiler-synthesized record members such as EqualityContract). V16, V18, V19 and V22 remain latent walls; the ordinal-fragment naming fix that shipped with v2.0.2 (CSharpNamePolicy.ToPascalCaseFragment) is adjacent but does not cover them. Each item stays red-test-first: refusal regression in OperationPlanBinderTests/CurationValidatorTests, then the wall.

  6. changed the title [-]M5: binder naming-wall gaps — remaining: reserved locals (V16), route Template members (V18), Clone (V19), null curation rows (V22)[/-] [+]M5: binder naming-wall gaps — V16, V18, V19, V22 and review riders[/+] on Sep 27, 2026
  7. added this to the 1.1 milestone on Oct 14, 2026
  8. changed the title [-]M5: binder naming-wall gaps — V16, V18, V19, V22 and review riders[/-] [+]Binder naming-wall gaps: V16, V18, V19, V22 and review riders[/+] on Oct 14, 2026
  9. Blind-Striker commented on Oct 14, 2026

    @Blind-Striker
    CollaboratorAuthor

    Milestone 1.1; the retired M-series anchor in the body no longer applies. Two rows moved to milestone 1.0, because after 1.0 they would let an upstream refresh change public types or names silently:

    The remaining rows (V16, V18, V19, V22, the merged body/query collision, duplicate and dormant curation, R2-9, R2-10, R2-11) are trigger-based: each lands red-test-first when a refresh first meets its shape.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-agentSpecified enough that the work is mechanical

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions