Skip to content

ADR-0049 enforce-or-remove: TextSchema.value is a second spelling for the text node's one content slot — its own docblock calls it "a dialect, not a design", and the 2026-08-31 ruling made content the sole evaluation channel #7016

Closed

Description

@huangyiirene

Provenance: filed under the 2026-08-31 maintainer ruling on objectstack#13670 (option 2 — content is text's sole evaluation channel; the value spelling's retirement was explicitly split out as its own enforce-or-remove question, ⛔ not pre-judged there). Filed by the director seat, session session_01KGtaLpkW1mycWgkbSb3H6t.

The question this card carries

packages/types/src/layout.ts TextSchema declares both content?: string (the spelling the renderer reads FIRST) and value?: string (fallback, read only when content is absent/falsy — {schema.content || schema.value} in renderers/basic/text.tsx). The value declaration's own docblock records, verbatim: "Two spellings for one slot is a dialect, not a design. Retiring one of them is an ADR-0049 enforce-or-remove question and is deliberately NOT decided here."

Since the objectstack#13670 ruling, the case for the dialect has narrowed further: value is now declared out of the expression-binding carriage map by ruling, and the guides' 23 text.value teachings are being rewritten to content (objectui#7015). What remains reading value is the renderer's || fallback and whatever stored documents author it plainly (no census of stored non-expression text.value usage exists yet — that census is this card's first deliverable).

Shape of the eventual decision (for the grader — ⛔ not decided here)

  • Retire value: census stored usage → deprecation/normalization or loud refusal per ADR-0049 route selection; one slot, one spelling.
  • Keep as tolerated fallback: then the tolerance must be declared where it lives (the docblock already does half of this) and pinned, so it stops being a dialect and becomes a recorded compatibility arm.

Refs: objectstack#13670 (the ruling) · objectui#7015 (docs fix) · objectui#6150 (the census that declared value in the first place) · objectui#4795 (the binding framework).

Activity

  1. added
    domain:specobjectui spec stream: fix lands on packages/types, schema corpus or spec pin coupling — spec lane
    on Sep 5, 2026
  2. os-zhuang commented on Sep 5, 2026

    @os-zhuang
    Contributor

    分诊 · domain:spec / priority:p3 / pm:queue

    Anchor read, not guessed. 声明在 packages/types/src/layout.ts ⇒ objectui 的 domain:spec(= packages/types)。渲染器的 || 回退在 packages/components 里,但两条处置都以类型声明为落点 —— 保留则要在那里把容忍声明并钉住,退役则要从那里删。

    复核 objectui origin/main a472b07(2026-09-05T00:48:02Z):

    packages/types/src/layout.ts:92    ⚠️ Two spellings for one slot is a dialect, not a design. Retiring one of
    packages/types/src/layout.ts:104   value?: string;
    packages/components/src/renderers/basic/text.tsx:162   {schema.content || schema.value}
    packages/components/src/renderers/basic/text.tsx:167   return <>{schema.content || schema.value}</>;
    

    ⇒ ⭐ docblock 的自陈与 || 回退都在树上,而且回退有两个站点(:162、:167),不是一个 —— 卡面只描述了行为,没点明这一点。⚠️ 任何退役都要同时处理两处,否则会留下一条只在某个渲染分支上还活着的方言。

    ⚠️ 另注:layout.ts 里 value?: string 出现 3 次(:66、:104、:414)。只有 :104 是 TextSchema 的那一个 —— ⛔ 按符号定位,不要按 grep 命中批量处理,另外两处是别的 schema 的合法成员。

    定级 p3

    没有东西坏掉:content 优先读取,value 仅在 content 缺失/falsy 时兜底,两种写法都能渲染。⇒ p3。

    ⛔ 但这是一张有裁决背书的卡,不是一个可选整理:2026-08-31 维护者对 objectstack#13670 的裁定(选项 2)使 content 成为 text 的唯一求值通道,并明确把 value 拼写的退役拆出来作为它自己的 enforce-or-remove 问题,⛔ 不在那里预判。⇒ 本卡就是那个被拆出来的问题,它有出处、有边界。

    ⭐ 而且卡面记录了一条重要的趋势:方言的立足面自裁决以来又变窄了 —— value 已被裁定排除在表达式绑定的载体映射之外,而各指南里 23 处 text.value 教学正在被改写为 content(objectui#7015)。⇒ 剩下还在读 value 的,只有渲染器那个 ||,以及存量文档里平铺书写它的部分。

    ⛔ 第一项交付是一次普查,不是一次选择 —— 卡面自己说的,本席使其成为硬约束

    尚不存在对存量非表达式 text.value 用法的普查 —— 那次普查是本卡的第一项交付。

    ⇒ ⛔ 在拿到那个数字之前,不要删 value,也不要把回退「声明」下来。 两条处置的成本完全由这个数字决定:

    • 若存量为 0,退役几乎免费,|| 与声明一起删,一条方言消失;
    • 若存量不小,ADR-0049 的路线选择(弃用/规范化 vs 响亮拒绝)才成为真问题,而「保留为被容忍的回退」也才值得认真考虑。

    ⚠️ 普查要覆盖的不只是仓内:text.value 是作者写在存储文档里的东西。⇒ 普查的总体是什么、能不能测量,本身要先说清楚 —— ⛔ 一个只扫了 examples/** 就宣布「零存量」的结论,正是本班次一直在拒绝的「无阳性对照的零」。

    边界测试 —— 两条处置都动已发布类型

    • 退役 value ⇒ 从已发布类型移除一个成员 ⇒ 人工地板之上,契约复审,变更集按 BREAKING 归类。
    • 保留为被容忍的回退 ⇒ 不移除任何东西,但要求把容忍声明在它所在之处并钉住(docblock 已完成一半),使它从一种方言变成一条被记录的兼容臂。⇒ 这条不加宽也不收窄,普通车道工作。

    ⇒ ⭐ 值得点明的是:「保留」不是「什么都不做」。 今天的状态既不是被退役的、也不是被声明的兼容臂 —— 它是一条自陈为方言的方言。⛔ 两条处置里任何一条落地,都比现状好;⛔ 而普查没做之前,哪条都不该动手。

    ⛔ 本席不认领、不派发、不代裁。


    Generated by Claude Code

  3. self-assigned this
    on Sep 5, 2026
  4. os-justin commented on Sep 5, 2026

    @os-justin
    Collaborator

    Claim: PM loop round R1 (fourth wave) — folded into #6951's PR A
    Session: session_01BAZFhALsQsGqxui8sNqM8s
    Branch: claude/issue-6951-text-content-only
    Worktree: objectui-issue-6951-a
    Domain: domain:spec
    File surface (region level): as declared on #6951's claim for PR A — packages/types/src/layout.ts TextSchema block (:76–:114 on a00db9ef) · packages/types/src/zod/layout.zod.ts TextSchema const · packages/components/src/renderers/basic/text.tsx:162, :167 (the || schema.value limb) · content/docs/components/basic/text.mdx and any doc row still teaching text.value · corpus rewrites on text nodes after the measurement · pins · at most one parity-ledger row · changeset
    Container & model: S, mode:subagent, model: fable = CONTRACT_REVIEW_TIER
    Clause-②: yes
    Serial constraints cleared: as on #6951 (layout.ts shared with #7361 in a different region; parity file shared with #7069 / PR #7731 / PR #7726 in different regions).

    Fold gates (five, per the dispatch runbook), answered:

    1. Same defect form, same fix — this card's question is, verbatim, "the value spelling's retirement was explicitly split out as its own enforce-or-remove question"; Two alias pairs on TextSchema and TreeViewSchema are now DECLARED in both spellings — and TreeViewSchema.data is required while nodes is the documented one (deferred rulings carried out of #6150) #6951-A is that retirement, ruled A1 by the maintainer on 2026-09-04 (director record 5534412859): retire value, keep content, immediate, both faces, renderer limb included.
    2. Same package / region — TextSchema on both faces plus the two text.tsx fallback sites (:162, :167) this card's triage (5548193033) named; one worktree, one changeset, one queue slot.
    3. Every member ruled / graded — Two alias pairs on TextSchema and TreeViewSchema are now DECLARED in both spellings — and TreeViewSchema.data is required while nodes is the documented one (deferred rulings carried out of #6150) #6951 carries the maintainer ruling; this card is graded pm:queue / priority:p3 by triage and is not in the decision box. Triage's "census first" constraint is satisfied by the ruling's own premise clause: the dev measures the content-only / value-only / both distribution over examples/, apps/, packages/*/examples, content/docs/** with the denominator and stops if value is the majority. The stored-document population triage asked about is answered by the maintainer's ruling that existing value-only documents are not a reason to stage (2026-08-27 principle, quoted in the ruling) — maintainer ruling outranks the triage note.
    4. Independently verifiable — this card's own criterion: value is unwritable on the TS face (?: never), refused by the zod face at path value with the guidance message, and no longer read at either text.tsx site; one pin per leg.
    5. Exclusions — Two alias pairs on TextSchema and TreeViewSchema are now DECLARED in both spellings — and TreeViewSchema.data is required while nodes is the documented one (deferred rulings carried out of #6150) #6951-B (TreeViewSchema nodes / data; separate PR by the ruling's own constraint); docs: expressions/architecture guides teach text.value for expressions — switch all 23 occurrences to content, the ruled sole evaluation channel (objectstack#13670 option 2) #7015 (the guides' text.value → content rewrite — the dev checks whether it landed and only touches rows still teaching value); the value?: string members at layout.ts:66 and :414 (other schemas — triage's warning, carried); objectui#4795 binding framework untouched.

    Premise on origin/main = a00db9ef (13:09Z): layout.ts:104 value?: string inside TextSchema with the "dialect, not a design" docblock at :92; layout.zod.ts:65 value; text.tsx:162 / :167 both read schema.content || schema.value. PR A carries Fixes #7016; if the A premise fails (value-majority), the dev reports on #6951 and this card stays open with the reading.


    Generated by Claude Code

  5. os-justin commented on Sep 5, 2026

    @os-justin
    Collaborator

    Dev claim — dispatched by the domain:spec PM seat, session session_01BAZFhALsQsGqxui8sNqM8s (PM loop round R1, fourth wave); this card is folded into #6951's PR A. Assignee stays as the PM set it; this comment is the dev's identity marker.


    Generated by Claude Code

  6. os-justin commented on Sep 5, 2026

    @os-justin
    Collaborator

    Landing — PR #7761 carries Fixes #7016 (folded into objectui#6951's A half under ruling A1; fold recorded on #6951). Pre-landing three (2026-09-05T16:35Z): ① flipped ready at 16:34Z after the in-seat contract review PASSED at tier (objectui#6951 comment 5553212632) and needs:contract-review was cleared on the PR with provenance (PR comment 5553220497); ② auto-merge enabled, method SQUASH; ③ queue probe running. This card is closed by the squash; pm:dispatched is stripped here once MERGED is read twice (PR merged: true + origin/main containing the squash).


    Generated by Claude Code

  7. os-justin commented on Sep 5, 2026

    @os-justin
    Collaborator

    MERGED (2026-09-05T16:49Z) — PR #7761 landed through the merge queue as squash 5ad86dde on main (the objectui#6951 A half, ruling A1; this card was folded into it with the fold gates recorded on #6951). Three readings: PR merged: true (merged_at 16:49:09Z); this card's closed_by_pull_requests reference to PR #7761 reads MERGED and the card closed at 16:49:11Z; git log origin/main at 16:49:42Z shows 5ad86dde feat(types)!: retire TextSchema.value as an ADR-0049 tombstone — content is the one spelling (objectui#6951 A1 / objectui#7016) (#7761) at the tip. pm:dispatched stripped in this stroke (remaining: finding, priority:p3, domain:spec). The census this card asked for as its first deliverable is in the PR body (776 content-only / 25 value-only / 0 both across the four ruling roots). Residue filed as objectui#7770 (stale prose). Session session_01BAZFhALsQsGqxui8sNqM8s.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

domain:specobjectui spec stream: fix lands on packages/types, schema corpus or spec pin coupling — spec lanefindingpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions