Skip to content

[Decision] page requires on the page kinds whose source is never compiled at save (react, full, slotted): refuse it at parse, or keep admitting a key nothing derives? #21459

Description

@objectstack-fleet

Ruled: 5964312254 · letter A · 2026-10-03T01:54Z

Filing gate: ② a maintainer decision, a contract-shape proposal (triage-duties.md: 「needs-user-decision = 设计卡、feature/契约形状提案」). Filed by domain:spec seat 2 (session_01YDt3PzwfrkuFzUBF89WPmM, seat post #18549), from the #20871 dev's measurement 5959538313 (option A) and contract review 5960279457, item ③. The review held that a contract-shape proposal belongs in the decision box, not in chat alone. ⛔ Not a claim. Nothing waits on this card: PR #21451 lands without it.

维护者速读

页面的 requires 字段(页面用到哪些插件)只在 html/jsx 页上有意义:平台保存时编译源码、自动算出并写入,手写的不一致会被拒。在 react、full、slotted 三种页上,平台从不计算它,只有加载时会根据它报一条警告,Studio 保存时还会把它删掉;仓内示例与应用里也没有任何一个页面手写它。A=在这三种页上解析时直接拒收(破坏性收窄,带迁移条目);B=维持现状,照收不管。要不要收窄?(是/否)

Background

Governing text:

  • ADR-0080 §5 [ruled]: "Store { source, compiledTree, requires } — source is truth, tree is derived cache", and "requires is inferred at parse and validated at save and load". That is the JSX-source page kind's stored shape. The ADR does not rule on the other kinds.
  • page.zod.ts, the requires describe (at PR fix(spec,lint): page requires is live — refused at save, reported at load #21451's head): "derived from the source at save — omit it".
  • ADR-0087: the retirement and narrowing mechanism (a semantic entry, FROM/TO in the changeset).
  • check-prior-rulings --terms requires,page requires,sdui manifest,compiled at save,html page named six ADR decisions. Each is a generic match on the word requires, and none rules on a page key.

Protocol declaration: PageSchema.requires: z.array(z.string()).optional() on every kind. Option A changes the protocol, and B does not.

Premises (each with its re-check, measured at origin/main b94a2a7277)

  1. The parse admits requires on every kind, and no refinement ties it to kind.
    • git grep -n "requires: z.array" origin/main -- packages/spec/src/ui/page.zod.ts → :903, 1 hit.
    • git grep -n -E "kind: z.enum" origin/main -- packages/spec/src/ui/page.zod.ts → :839, ['full', 'slotted', 'html', 'react', 'jsx'].
  2. Only html / jsx are compiled at save.
    • git grep -n "COMPILED_PAGE_KINDS" origin/main -- packages/metadata-protocol/src/runtime-authoring-gate.ts → :571 new Set(['html', 'jsx']), and :634, which returns early for any other kind.
  3. No page-level requires is authored in this repo's examples or apps.
    • git grep -n -E "^\s*requires:" origin/main -- examples packages/apps → 3 hits, all stack-level capability lists in objectstack.config.ts, not page bodies.
  4. Studio drops the key on every page save.
    • objectui at the pinned .objectui-sha 89cad75d55: packages/app-shell/src/services/builtinComponents.tsx pageSaveBody deletes requires, registered as fromDraft for type page with no kind gate.
  5. On non-compiled kinds, the only reader is the load report, a warning with the page still served: findPageRequiresAbsentFromManifest (kind-agnostic) via reportPageRequiresAbsentAtLoad, per the measurement 5959538313.

The question

On react, full and slotted pages, the platform never derives requires, Studio never keeps it, and no example writes it. Should the contract go on admitting it there?

Options

What it does What a customer or author sees
A. Refuse at parse on non-compiled kinds PageSchema accepts requires only when kind is html / jsx. A semantic retirement entry (ADR-0087) and a changeset with FROM/TO. A stored non-compiled page that carries the key is converted (the key dropped) or refused at its next save, whichever the entry prescribes. An author or AI that writes requires on a react page gets a loud refusal at save, naming the key and saying it is derived for compiled pages only. No measured author is affected (premise 3).
B. Keep admitting it No change. The ledger row landed by PR #21451 already states the per-kind truth. A requires written on a react page is accepted, only the load-time warning reads it, and Studio drops it on the next save. The author is never told the key does nothing there.

Business meaning:

  • A: a field the platform fills in is accepted only on the page types where the platform fills it in. This is like a calculated column that an import refuses to take a hand-typed value for.
  • B: the form keeps a box nobody reads on three of five page types. Whatever is typed there is silently dropped the next time the page is saved in Studio.

四维分析

os-decision-facets

  • ① 项目长远合理性: A 缩小契约——requires 回到 ADR-0080 定义的「编译页派生字段」本义,一个键只有一种含义;B 保留一个只在两种页上有派生者、其余三种页上无人写也无人真用的方言面,契约增生不减。
  • ② 实际业务拉动: 今天无人撞上——仓内示例与应用零处页面级手写 requires(前提 3),Studio 每次保存都删掉它(前提 4);零拉动按原则默认 remove,而非 declare-and-maintain。
  • ③ 防 AI 犯错: A 让 AI 在非编译页上写 requires 时得到响亮拒绝;B 下 AI 写了也被接受,只得一条加载期警告、随后被 Studio 静默删除——出错时作者看不到,是静默容忍。
  • ④ 创业阶段不扩散: A 删掉一个零消费的声明面,少一项永久义务;B 让每个已声明却无派生者的键继续是永久维护成本。

Prior rulings read: requires,page requires,sdui manifest,compiled at save,html page → 14 hits; ADR-0007 Decision §9, ADR-0055 Decision §3, ADR-0059 Decision §3, ADR-0066 D2, ADR-0088 Decision §1, ADR-0106 D4 (all generic matches on the word requires; the governing text is ADR-0080 §5, read above); thread: none (new card); repo: objectstack-ai/objectstack

推荐:A。 终态句:两年后 requires 应是编译型页面由平台从源码推导出的依赖清单,作者永不手写——如同打包器从 import 推导模块依赖、而不读一份手写依赖表;非编译页不存在这个键。只看①选 A;②③④ 是否翻转:否(②零拉动、③响亮拒绝、④减少义务,均同向)。回退: B(维持现状,PR #21451 落地的账本行已如实写明各页类型的真相)。置信缺口: 仓外(cloud、hotcrm 等姊妹仓)是否有页面手写 requires 未测——本会话组织级代码检索返回 403;A 落地前须由有组织级读权限的席位补测。

After the ruling

  • A: a domain:spec card, filed by the seat that reads the ruling. PageSchema refuses requires unless kind is html / jsx, with the refusal naming the key and the compiled kinds. It carries a semantic retirement entry in the next unreleased step, with its reason and prescription, a changeset with FROM/TO, and the stored-row disposition the entry prescribes. The reconciliation ledger row's per-kind clause shrinks to the compiled kinds. objectui needs no change: Studio already drops the key. Before building, the sister repos' page bodies are measured for a hand-written requires (the confidence gap above).
  • B: this card closes not_planned, citing the ruling. Nothing else changes.

Related

#20871 · PR #21451 · the measurement 5959538313 · seat answer 5959584348 · reviews 5959399303 (FAIL) and 5960279457 (PASS, item ③) · ADR-0080 §5 · ADR-0087.

Dedupe: the 1,000 most recently updated issues and PRs here, open and closed, were listed by REST and grepped for page requires, requires with react page, and requires with non-compiled / slotted. 1 hit: this seat's own post #18549, which names option A as raised. No card proposes narrowing page requires by kind.


Generated by Claude Code

Activity

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