Repository navigation
Description
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
waitingtotask's status. Setting an issue towaitingis refused. - A core status added to
tasklater (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
issueschema declareschanges_requestedandready_to_merge, not task's five. - Resolution. One function in Rust and one in TypeScript build the effective field along the
extendschain. Validation, the property forms,maps_toresolution, 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
issueschema stores only its two statuses; its effective status has all seven, in the order above -
add_field_valueson 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
taskscope still maps (changes_requestedreads asin_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.mdand theissuesheet describe the inherited vocabulary correctly;bun run node-types:checkpasses
Activity
malibio commentedon Oct 12, 2026
Frontend: 5897 passed (325 files)
Inherit a parent's enum values live when a subtype extends the field (c…
Inherit a parent's enum values live when a subtype extends the field (c…