Skip to content

A subtype that extends an inherited enum must keep inheriting its parent's values #3749

Closed

Description

@malibio

Problem

A type that adds values to an enum it inherits stops receiving its parent's later values.

ADR-078 says an extending schema inherits its parent's vocabulary live: a value added to the parent later "is reflected the next time an extending schema's effective fields are resolved". The code does not do this once the subtype has added a value of its own. extend_inherited_field (packages/core/src/schema/mod.rs) copies the parent's whole field onto the subtype and appends to the copy. The subtype then holds a frozen list.

Since ADR-098, every database ships with issue, whose status is seeded as such a copy. So:

  • A team adds waiting to task's status. Setting an issue to waiting is refused.
  • A core status added to task later (ADR-098 names "waiting on a person" as one "which an issue inherits") would need a second edit to the issue's list.
  • The same holds for any user type that added a value to an inherited enum.

Change

A type that extends an inherited enum stores only the values it adds. The field's values are resolved as the ancestors' current values plus each extending type's own, wherever they are read.

  • Stored shape. The extending schema's declaration of the field lists its added values only. The seeded issue schema declares changes_requested and ready_to_merge, not task's five.
  • Resolution. One function in Rust and one in TypeScript build the effective field along the extends chain. Validation, the property forms, maps_to resolution, boards, tables, the agent's status tool and the entity-type prompt blocks read through it.
  • Order. An added value sits after the value it maps to, so an issue's statuses read open, in progress, changes requested, in review, ready to merge, done, cancelled.
  • Collisions. Adding a value to a field is refused when a type that extends it already added a value of that name, and the error names that type.
  • Storage of a node's value is unchanged. The field is still stored in the bucket of the nearest type that declares it.
  • No migration: the stored schema shape changes, so existing databases are reset.

Not in scope

A larger alternative is to keep the field's value in the base type's bucket and have the subtype only widen the vocabulary, which is closer to ADR-078's wording that the field "remains a field of the base". It would remove the special handling a moved bucket needs (the started-at stamp, rebucketing on a type change, a write that names the field in two buckets). It reworks node storage, the typed IssueNode conversions and the status index, so it is a separate decision and not part of this fix.

Acceptance criteria

  • A value added to task's status after the fact can be set on an issue, and on a node of a user type that extended the status
  • The seeded issue schema stores only its two statuses; its effective status has all seven, in the order above
  • add_field_values on an inherited field stores only the added values on the extending schema
  • Adding a value to a parent that a descendant already added is refused, naming the descendant
  • A status read at task scope still maps (changes_requested reads as in_progress); a value inherited from the parent reads as itself
  • The app's status menu, board columns and table cells for an issue show the parent's later values
  • The test that pinned the frozen list asserts the opposite
  • node-types.md and the issue sheet describe the inherited vocabulary correctly; bun run node-types:check passes

Activity

  1. assigned and unassigned on Oct 12, 2026
  2. malibio commented on Oct 12, 2026

    @malibio
    CollaboratorAuthor

    Frontend: 5897 passed (325 files)

  3. self-assigned this
    on Oct 12, 2026
  4. added a commit that references this issue on Oct 12, 2026
    1726454
  5. added a commit that references this issue on Oct 12, 2026
    c9098d4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions