Skip to content

Name union arms from their schema node instead of their position #1409

Open

Description

@bokelley

Taken out of #1392 at review so that PR only contains code the pipeline actually runs. @KonstantinMirin wrote it.

What it is

scripts/union_arm_names.py names a root-level union arm from its schema node instead of its position:

  1. Classify first. An arm that adds no new property is a validation constraint and creates no class. Bare $ref arms and scalar arms also create no class.
  2. Name it using the first of these that is unique among its siblings:
    • the arm's title;
    • the parent name plus the PascalCased discriminator const;
    • the parent name plus the arm's full sorted required set.
  3. Otherwise refuse with UnnameableArmError. It never falls back to a number.

tests/test_union_arm_names.py checks the rule against the pinned bundle. That includes the two response arms it can't name today.

Results on the pinned bundle: 557 root-level non-null arms.

Where the code is

On branch claude/issue-1409-union-arm-naming: #1392's head plus nothing else, before the extraction commit. It came from commits fcbf4229 and 5d705ca8. Those commits touch only scripts/union_arm_names.py and tests/test_union_arm_names.py. The design write-up is the "Union arm names" section of docs/design/type-generation.md on that branch.

What landing it needs

The rule isn't wired in yet. Arms are still named by position in restore_response_variant_aliases (f"{self.base}{index}"), using a hand-written 22-row table and a hardcoded BuildCreativeResponse reordering. Wiring it in is a one-line swap at class_names. The rest is two decisions about the public surface:

Also: test_no_derived_name_is_positional checks the rule against the JSON schemas, not the generated tree. A test that reads the generated classes has to land with the wiring.

Activity

  1. added
    no-triageSkip the Claude triage bot — human or designated agent will handle this issue
    on Oct 6, 2026
  2. added
    claude-triagingTriage routine is actively working on this issue (1-3 min)
    on Oct 6, 2026
  3. bokelley commented on Oct 6, 2026

    @bokelley
    ContributorAuthor

    Triage

    Classification: Codegen enhancement
    Bucket(s): client (eventual wiring touches the public types surface in src/adcp/)
    Status: deferred

    My take: This issue was deliberately extracted from #1392 to keep that PR scoped to code the pipeline actually runs. The naming rule (scripts/union_arm_names.py) and its tests exist on branch claude/issue-1409-union-arm-naming (built on #1392's head), so the natural sequencing is: #1392 merges → this follows. Two open questions noted in the body also need human decisions before the wiring lands: (1) whether to wait for adcontextprotocol/adcp#7913 or deliberately remove the one unnameable arm from the flat surface; (2) how to handle the 38 publicly exported positional names that become a breaking rename — the body suggests a deprecation shim + migration table in a 9.x beta, which requires a versioning decision.

    Blocked-on: #1392 — resurfaces on merge


    Triaged by Claude Code. Session: https://claude.ai/code/session_01Ga2v9ZdA4auwbwZxihBWfF


    Generated by Claude Code

  4. added and removed
    claude-triagingTriage routine is actively working on this issue (1-3 min)
    on Oct 6, 2026
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

    claude-triagedno-triageSkip the Claude triage bot — human or designated agent will handle this issue

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions