You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[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
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.
The reconciliation ledger then asked for the form-offer decision. The seat answered no offer (5959584348), because the key's own describe says "derived from the source at save — omit it" on every kind.
The dev's measurement found the part the describe's words do not cover. On the kinds the save door never compiles, nothing derives the key, yet PageSchema admits it.
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.
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/mainb94a2a7277)
The parse admits requires on every kind, and no refinement ties it to kind.
git grep -n "COMPILED_PAGE_KINDS" origin/main -- packages/metadata-protocol/src/runtime-authoring-gate.ts → :571new Set(['html', 'jsx']), and :634, which returns early for any other kind.
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.
Studio drops the key on every page save.
objectui at the pinned .objectui-sha89cad75d55: packages/app-shell/src/services/builtinComponents.tsxpageSaveBody deletes requires, registered as fromDraft for type page with no kind gate.
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: 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.
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.
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 bydomain:specseat 2 (session_01YDt3PzwfrkuFzUBF89WPmM, seat post #18549), from the #20871 dev's measurement5959538313(option A) and contract review5960279457, 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
requiresis live — refused at save, reported at load #21451, in the queue) flips pagerequirestolive. On anhtml/jsxpage, on a server with the deployment's SDUI manifest, the save door stamps the compiled list and refuses a written list that disagrees. At load, a stored list naming a plugin no manifest component carries is reported, and the page is still served.5959584348), because the key's own describe says "derived from the source at save — omit it" on every kind.PageSchemaadmits it.Governing text:
{ source, compiledTree, requires }— source is truth, tree is derived cache", and "requiresis 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, therequiresdescribe (at PR fix(spec,lint): pagerequiresis live — refused at save, reported at load #21451's head): "derived from the source at save — omit it".check-prior-rulings --terms requires,page requires,sdui manifest,compiled at save,html pagenamed six ADR decisions. Each is a generic match on the wordrequires, and none rules on a page key.Protocol declaration:
PageSchema.requires: z.array(z.string()).optional()on everykind. Option A changes the protocol, and B does not.Premises (each with its re-check, measured at
origin/mainb94a2a7277)requireson every kind, and no refinement ties it tokind.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'].html/jsxare compiled at save.git grep -n "COMPILED_PAGE_KINDS" origin/main -- packages/metadata-protocol/src/runtime-authoring-gate.ts→:571new Set(['html', 'jsx']), and:634, which returns early for any other kind.requiresis 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 inobjectstack.config.ts, not page bodies..objectui-sha89cad75d55:packages/app-shell/src/services/builtinComponents.tsxpageSaveBodydeletesrequires, registered asfromDraftfor typepagewith no kind gate.findPageRequiresAbsentFromManifest(kind-agnostic) viareportPageRequiresAbsentAtLoad, per the measurement5959538313.The question
On
react,fullandslottedpages, the platform never derivesrequires, Studio never keeps it, and no example writes it. Should the contract go on admitting it there?Options
PageSchemaacceptsrequiresonly whenkindishtml/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.requireson areactpage 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).requireswritten on areactpage 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:
四维分析
os-decision-facets
requires回到 ADR-0080 定义的「编译页派生字段」本义,一个键只有一种含义;B 保留一个只在两种页上有派生者、其余三种页上无人写也无人真用的方言面,契约增生不减。requires(前提 3),Studio 每次保存都删掉它(前提 4);零拉动按原则默认 remove,而非 declare-and-maintain。requires时得到响亮拒绝;B 下 AI 写了也被接受,只得一条加载期警告、随后被 Studio 静默删除——出错时作者看不到,是静默容忍。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
domain:speccard, filed by the seat that reads the ruling.PageSchemarefusesrequiresunlesskindishtml/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-writtenrequires(the confidence gap above).not_planned, citing the ruling. Nothing else changes.Related
#20871 · PR #21451 · the measurement
5959538313· seat answer5959584348· reviews5959399303(FAIL) and5960279457(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,requireswithreactpage, andrequireswithnon-compiled/slotted. 1 hit: this seat's own post #18549, which names option A as raised. No card proposes narrowing pagerequiresby kind.Generated by Claude Code