The 2026-09-08 ruling on objectui#8426 (director seat, decision batch #86, maintainer reply 「继续决策」)
has three parts. Two have landed — objectui#9229 added the approval envelope additively, and
objectui#8426's PR objectui#10017 builds the discriminated parts and lifts approval. The third is
unlanded and has no carrier until this card:
the authoring state union sheds the three runtime-only approval states, so a schema-authored
invocation cannot claim approval-requested without an envelope.
Filed by the domain:ui#2 execution seat (session_018HrVaotisyhgmot9o2MLRq) at 2026-09-19T11:43Z, from objectui#8426's hand-back. ⛔ This seat
does not grade or route.
Why it was not done in either predecessor, and both refusals were right
- objectui#9229 left it deliberately, and its own doc says so: 「objectui#8426's narrowing of the
state union above, deliberately NOT done here」. That card's half was additive.
- objectui#8426 could not: the union lives in
@object-ui/types, which its dispatch fenced OUT
with 「if you find it incomplete, report; ⛔ do not extend it here」. The dev reported rather than
picking a side, which is what the fence is for.
⇒ the ruling ships in two halves plus a residual, and this card is the residual.
Why it is its own card rather than a tail
It is a published authoring-contract change: the union has a Zod mirror and a parity test, so it
carries its own review surface and its own changeset semantics. Landing it inside a renderer PR would
have made that PR's diff span a contract package — the one thing the fence exists to stop.
The cost of leaving it, measured
The parts builder currently needs a runtime branch for an approval state with no envelope — a
shape the narrowing would delete by construction. ⭐ That branch is cheap, tested, and audible (it
warns the producer by name), so nothing is lost by sequencing; but it is dead weight that exists only
because the authoring face still admits a claim the runtime cannot back.
What a taker should do
- Narrow
ChatToolInvocation's authoring state union in @object-ui/types to shed the three
runtime-only approval states, with the Zod mirror and the parity test moving together.
- Then delete the un-backed-approval branch in
packages/plugin-chatbot's parts builder and its
test, because the narrowing makes the shape unconstructible.
- ⚠️ Check whether this is breaking for external authors and grade the changeset accordingly — the
repo's policy on a narrowing of a published input is the deciding input, ⛔ not this seat's guess.
- ⛔ Do not re-litigate the ruling. It is quoted above; this card executes its third clause.
Related
objectui#8426 → PR objectui#10017 (the builder half, landing) · objectui#9229 (the additive half,
landed) · objectui#9232 and objectui#9233 (both open, both untouched by objectui#10017 and both on
this same message path) · objectui#10019 (two stale enumerations this family's diff created).
Dedupe words: ChatToolInvocation state union narrowing · approval-requested without envelope ·
chat tool invocation authoring state · decision batch 86 residual clause ·
plugin-chatbot un-backed approval branch
⛔ Attribution corrected 2026-09-19T12:08Z: this card was filed without a session id, which the half-state patrol's H64 row named — a seat artefact whose author GitHub records only as a token (os-tesla), and the token records the token, ⛔ not the seat. The writing session is session_018HrVaotisyhgmot9o2MLRq, seat domain:ui#2 at objectstack-ai/objectui. ⛔ Nothing else in this card changed.
Generated by Claude Code
The 2026-09-08 ruling on objectui#8426 (director seat, decision batch #86, maintainer reply 「继续决策」)
has three parts. Two have landed — objectui#9229 added the
approvalenvelope additively, andobjectui#8426's PR objectui#10017 builds the discriminated parts and lifts
approval. The third isunlanded and has no carrier until this card:
Filed by the
domain:ui#2execution seat (session_018HrVaotisyhgmot9o2MLRq) at 2026-09-19T11:43Z, from objectui#8426's hand-back. ⛔ This seatdoes not grade or route.
Why it was not done in either predecessor, and both refusals were right
stateunion above, deliberately NOT done here」. That card's half was additive.@object-ui/types, which its dispatch fenced OUTwith 「if you find it incomplete, report; ⛔ do not extend it here」. The dev reported rather than
picking a side, which is what the fence is for.
⇒ the ruling ships in two halves plus a residual, and this card is the residual.
Why it is its own card rather than a tail
It is a published authoring-contract change: the union has a Zod mirror and a parity test, so it
carries its own review surface and its own changeset semantics. Landing it inside a renderer PR would
have made that PR's diff span a contract package — the one thing the fence exists to stop.
The cost of leaving it, measured
The parts builder currently needs a runtime branch for an approval state with no envelope — a
shape the narrowing would delete by construction. ⭐ That branch is cheap, tested, and audible (it
warns the producer by name), so nothing is lost by sequencing; but it is dead weight that exists only
because the authoring face still admits a claim the runtime cannot back.
What a taker should do
ChatToolInvocation's authoringstateunion in@object-ui/typesto shed the threeruntime-only approval states, with the Zod mirror and the parity test moving together.
packages/plugin-chatbot's parts builder and itstest, because the narrowing makes the shape unconstructible.
repo's policy on a narrowing of a published input is the deciding input, ⛔ not this seat's guess.
Related
objectui#8426 → PR objectui#10017 (the builder half, landing) · objectui#9229 (the additive half,
landed) · objectui#9232 and objectui#9233 (both open, both untouched by objectui#10017 and both on
this same message path) · objectui#10019 (two stale enumerations this family's diff created).
Dedupe words:
ChatToolInvocation state union narrowing·approval-requested without envelope·chat tool invocation authoring state·decision batch 86 residual clause·plugin-chatbot un-backed approval branch⛔ Attribution corrected 2026-09-19T12:08Z: this card was filed without a session id, which the half-state patrol's H64 row named — a seat artefact whose author GitHub records only as a token (
os-tesla), and the token records the token, ⛔ not the seat. The writing session issession_018HrVaotisyhgmot9o2MLRq, seatdomain:ui#2at objectstack-ai/objectui. ⛔ Nothing else in this card changed.Generated by Claude Code