Skip to content

docs: taught action:* nodes move their executor keys into the spec properties bag (objectui#11183) - #11317

Merged
os-warren merged 4 commits into
mainfrom
claude/issue-11183-action-node-properties-bag
Oct 1, 2026
Merged

os-warren merged 4 commits into
mainfrom
claude/issue-11183-action-node-properties-bag

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #11183
Clause-②: no

Every taught action:* node under AGENTS.md, skills/objectui/** and content/docs/guide/** now writes the block's props in the spec's properties bag, as the @objectstack/spec ComponentPropsMap row declares them, instead of flat on the node. Triage's ruling on the objectui#10872 fork, carried by the card: A, the properties bag is the contract. The spec's PageComponentSchema is .strict() (ADR-0089 D3a) and refuses a node-level actionType / target as mis-layered; objectui's StrictAnyComponentSchema refuses the same two keys. The runtime reads both spellings through the SchemaRenderer properties hoist, so only documents and their pins change — ⛔ no runtime or validator code in this diff.

Order: this PR lands BEFORE PR objectui#11069 (objectui#5250, objectui validate onto the strict face). objectui#5250 carries Blocked-by: #11183; PR objectui#11069 touches content/docs/guide/layout.md and schema-rendering.md in other sections than the ones edited here (its layout.md hunk is the label / text paragraph under the page-buttons passage; its schema-rendering.md hunk is the three validation doors), so it merges main after this lands with no textual overlap.

Governed surface: AGENTS.md, skills/objectui/SKILL.md, skills/objectui/guides/page-builder.md, skills/objectui/rules/protocol.md (node scripts/check-governed-queue-guard.mjs --test answers exit 3, GOVERNED). This PR stays draft until an APPROVED review by os-zhuang or hotlong; the claiming seat lands it. Cross-lane surface (content/docs/**, packages/** pins), declared on the claim comment of the card.

维护者速读(草稿)

改了什么。 文档与测试,零运行时代码。我们教给作者(和 AI)的 action:button 示例,把 actionType / target 这类执行器键从节点顶层挪进了 properties 包里 —— 共 11 个节点、10 个文件(受管面 4 个:AGENTS.md 第 #4 条、skills/objectui/SKILL.md、guides/page-builder.md、rules/protocol.md;非受管 6 个:content/docs/guide/ 下 4 篇指南、content/docs/plugins/plugin-detail.mdx、随同的两条 pin 测试)。同一家族的两处 rider 一并处理:plugin-detail 指南里的 record:activity 示例(limit / showCompleted 进包),以及 page-builder 技能里的 object-form 表单示例(objectui#11291 落地后 objectui validate 已按名拒绝扁平写法)。另附一个空 frontmatter 的 changeset(声明不发版)。

为什么改。 spec 的 PageComponentSchema 是 .strict() 的(ADR-0089 D3a),节点顶层出现 actionType / target 会被当作错层键直接拒绝;objectui 自己的严格校验面 StrictAnyComponentSchema 同样拒绝这两个键。PR objectui#11069 正要把 objectui validate 切到这个严格面,届时受管规程文件里的标准示例就会变成校验器拒收的节点,而 agent 会照抄示例。裁决是「教的内容向 spec 靠」,不是反过来给 objectui 开一条 spec 拒绝的扁平通道。实测:12 个被改示例在改前全部被两个严格面拒绝,改后在宽容面、严格面、spec 三面全部通过(见下方 census)。

风险与代价(含回滚)。 运行时无变化:SchemaRenderer 把 properties 整包提升到节点上再交给渲染器,两种拼写渲染结果相同;guide-layout-page-buttons-7926 这条真实渲染 pin 读的就是 layout 指南里被改的那段 JSON,改后 Edit / Delete 两个按钮照常画出。代价是示例各长了 2–5 行。回滚:revert 本 PR 即可,没有任何生成物、锁文件或发布物需要同步;但回滚后 objectui#11069 不能先落地,否则规程示例会被校验器拒收。

席位意见。(留空)

你要做的。 作为受管面 PR,需要你(os-zhuang / hotlong)在本 PR 上留一条 APPROVED review;之后由认领席翻 ready 并入合并队列,⛔ 本 PR 不自行 ready、不自行入队。请顺手确认 AGENTS.md #4 的新措辞(「props 住在 properties 包里,⛔ 不写在节点顶层」)是你希望 agent 读到的规则。

Census (the gate the card asks for)

Instrument: for every "type": "action:button|icon|group|menu" node under content/docs/**, skills/**, AGENTS.md, README.md (grep -rnE '"type":\s*"action:(button|icon|group|menu)"' content/docs skills AGENTS.md README.md), the keys written at the node's own level — actionType, target, endpoint, method, name, icon, variant, params, label — before the next node or the closing brace.

reading action nodes nodes with a flat row key
base caa0cd392 (objectui origin/main at cut) 11 11
this branch f580661 11 0

Per site (base → branch), by heading, all in one commit each:

file site moved into properties
AGENTS.md #4 example (one-line node) label, actionType, target
skills/objectui/SKILL.md "4. The action system" label, actionType, target
skills/objectui/rules/protocol.md "Rule: Actions Are Node Types, Not An Event Bag" (the node example only; the 「Readers only.」 paragraph is #11009's and is untouched) label, actionType, target
skills/objectui/guides/page-builder.md "5. Use action data" label, actionType, target
skills/objectui/guides/page-builder.md "Form plugin example" (object-form rider) objectName, mode, fields
content/docs/guide/quick-start.md "Add Actions" label, actionType, target
content/docs/guide/record-edit-modes.md "Triggering the routes from JSON", three nodes label, icon, actionType, and the already-bagged params stays in the same bag
content/docs/guide/schema-rendering.md "Reference actions in schemas" name, label, actionType, endpoint, method
content/docs/guide/layout.md "Detail Page with Actions", two nodes name, label, variant, icon, actionType
content/docs/plugins/plugin-detail.mdx "The record:activity block" (record:activity rider) limit, showCompleted

Each edited fence judged on three faces (a probe run from packages/types against the source zod/index.zod.ts and the installed @objectstack/spec 17.5.0): at base, every one of the 12 is refused by StrictAnyComponentSchema and by the spec's PageComponentSchema with exactly the flat keys named above (the object-form one is refused on the tolerant face too, by name, since objectui#11291); on this branch all 12 pass tolerant, strict and spec. The prose beside each fence moved with it: the sentence "the node's own keys carry that executor's arguments" now reads "the row's other keys" / "the bag's other keys", and each site says why the flat spelling is refused.

skills/** line readings (the governed-surface reading, lines; no token meter exists for this surface — check:skill-eval-tokens meters eval must_contain tokens, not file length): SKILL.md 137 → 142, guides/page-builder.md 346 → 353, rules/protocol.md 364 → 370; bundle skills/objectui/**/*.md 4782 → 4800; all SKILL.md files 137 → 142. The whole increase is the bag's two wrapper lines per fence plus the one-sentence refusal note; nothing was re-wrapped.

Pins moved

  • packages/types/src/__tests__/held-public-block-arms-10872.test.ts (reads the quick-start's "Add Actions" fence): the taught node now validates AS WRITTEN on both faces and on the spec's PageComponentSchema; the pre-move flat spelling is DERIVED from the taught node (bag hoisted flat) and pinned as refused by exactly actionType and target on both strict faces while the tolerant face still keeps it — so the reading of the refusal stays live and moves with the page.
  • packages/cli/src/__tests__/registered-types-validate-ratchet-10859.test.ts (same fence, through objectui validate): lit control that the extracted node is in the bag spelling; the row still passes the tolerant face validate runs today and will pass the strict one PR objectui#11069 wires. ⛔ Its header and refusedAtType helper — the lines PR objectui#11069 edits — are untouched here.
  • Reverse leg, run with the pins committed: git checkout BASE -- content/docs/guide/quick-start.md ⇒ 4 red (reads the taught node … bag spelling, strict face: the taught node AS WRITTEN … validates, the spec's own PageComponentSchema accepts the taught node as written, the ratchet's validates a page with the taught action:button node), 60 green; git checkout HEAD -- … restored, git diff HEAD empty, git hash-object of the page equals its HEAD blob ca70f902fc5c….

Gates run locally (head f580661; exit codes read before any pipe)

Derived from .github/workflows/*.yml on origin/main (41 files, the same count the working tree lists): my diff touches **/*.md, content/**, .changeset/** AND two packages/*/src/__tests__/*.test.ts, so the Decide whether this change needs a full run step in lint.yml / ci.yml answers should_run=true, every always-on doc gate fires, and changeset-guard.yml fires on the .changeset/** path.

gate (workflow) command exit
Skills Paths node scripts/check-skills-paths.mjs 0
Skill Examples node scripts/check-skill-examples.mjs --self-test · node scripts/check-skill-examples.mjs (both after the scoped build its --build-filter names, 30 tasks; before the build both answer exit 2 = could not run, not a verdict) 0 (60 cases) · 0
Skill Eval Tokens node scripts/check-skill-eval-tokens.mjs --self-test · node scripts/check-skill-eval-tokens.mjs 0 · 0
Line Citation Gate node scripts/check-new-cross-file-line-citations.mjs 0 (0 new citations)
Control Bytes node scripts/check-control-bytes.mjs 0
Doc Fence Languages · Doc Example Ids · Doc Component Types the three node scripts/check-doc-*.mjs 0 · 0 · 0
Doc Snippet Types node scripts/check-doc-snippet-types.mjs (after the full build pnpm turbo run build --filter='!@object-ui/site', 43 tasks) 0
Changeset Presence · Changeset Guard node scripts/check-changeset-presence.mjs · node scripts/check-changeset-no-major.mjs · check-changeset-claims · check-pending-changeset-literals 0 · 0 · 0 · 0
README Exports node scripts/check-readme-exports.mjs (after the full build) 0
Docs Links · Docs Route Eager Closure · Action Ref Convention · Shell Escape Residue · Inert vi.mock Specifiers · Pre-Install Import Graph each node scripts/check-*.mjs 0 each
node scripts/check-comment-mask-corpus.mjs · node scripts/markdown-test-inputs.mjs --audit 0 · 0 (107 candidate test files adjudicated, 78 entries present)
Governed Surface Guard node scripts/check-governed-queue-guard.mjs --test AGENTS.md skills/objectui/SKILL.md skills/objectui/guides/page-builder.md skills/objectui/rules/protocol.md 3 = GOVERNED, by design
Lint (lint.yml roster) pnpm lint --concurrency=2 (47 tasks, 0 errors) · node scripts/check-vi-mock-override-shape.mjs · node scripts/check-test-path-roots.mjs · pnpm --filter '@object-ui/cli...' build · pnpm check 0 · 0 · 0 · 0 · 0
CI (ci.yml) — the affected tests pnpm exec vitest run on the two moved pins + guide-layout-page-buttons-7926 (3 files, 71 tests) · the other eight ledgered readers of the edited docs (8 files, 87 tests) · the root scripts/ suite (177 files, 5371 tests, 2 skipped) 0 · 0 · 0
type-check of what I edited tsc -p packages/types/tsconfig.test.json · tsc --noEmit in packages/cli · eslint on the two test files 0 · 0 · 0

Not run locally, declared to CI: the full pnpm test shards (ci.yml), Live E2E, Spec Main Shape Gate (it builds @objectstack/spec from objectstack main on the runner), Bundle Analysis. Heavy steps ran under /home/user/objectstack/scripts/pm/os-verify-lock.sh (three locked runs: the scoped build 234 s held, the scripts suite + lint, the full build + two gates after a 452 s queue wait).

Acceptance notes

  • packages/plugin-detail/README.md — the items half of the record:activity rider is NOT moved, by measurement. ComponentPropsMap['record:activity'] on the installed spec has no items key (its keys: aria, enableMentions, enableReactions, enableThreading, filterMode, limit, showCommentInput, showCompleted, showFilterToggle, showSubscriptionToggle, types, unifiedTimeline), and both objectui faces refuse properties.items by name, so the bag spelling would turn a working example into a refused one. The README's example is TSX code composing a DetailViewSchema whose Activity tab hands the block a host-supplied feed — record-activity.tsx reads schema.items as the first of its three feed sources — the same runtime-slot shape as record:history's entries. Left as is; reported in the dev report for the domain:ui lane to rule on whether items wants a named RUNTIME SLOT refusal on the authoring faces.
  • Out of the roots, same family: packages/app-shell/README.md teaches two flat action:button nodes (navigate_create / navigate_edit, under "The handler name goes in actionType"), the twin of the record-edit-modes.md passage moved here. Outside the claimed surface; in the dev report as a finding, not edited.
  • Different family, noted: content/docs/api/schema-reference.md "ActionSchema" teaches "type": "action" nodes with actionType: "ajax" and an api key — a vocabulary schema-rendering.md itself says no action renderer forwards. Not an action:* public block; not edited.
  • Zone 2 item 4 of the dispatch assumed check:skill-eval-tokens meters skill-file length; it meters eval must_contain tokens against the bundle (its header's "THE ORACLE" section). No length ceiling gate exists for skills/** in this tree; the line readings above are reported in its place.
  • objectui#11198 (guides/app-composition.md nav label) does not ride this PR; that file is untouched.

Session: session_01KTZmMfzVzjNvyaLyQ8mHvg (PM loop round 11, claim comment 5923347428).


Generated by Claude Code

claude added 2 commits October 1, 2026 02:33
…uilder object-form move their props into the spec's properties bag

The spec's PageComponentSchema is .strict() (ADR-0089 D3a) and refuses a flat
actionType / target on a component node; objectui's strict authoring face
refuses the same keys. Every taught action:button node under AGENTS.md,
skills/objectui and content/docs/guide now writes the block's props in the
properties bag, as the ComponentPropsMap row declares them. Same move for the
record:activity example in plugin-detail.mdx (limit / showCompleted) and the
page-builder "Form plugin example" (object-form, refused flat by name since
objectui#11291). The runtime reads both spellings through the SchemaRenderer
properties hoist, so only documents change.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KTZmMfzVzjNvyaLyQ8mHvg
… node in the properties bag, with a derived flat control

held-public-block-arms-10872: the taught node now validates AS WRITTEN on both
faces and on the spec's PageComponentSchema; the pre-move flat spelling is
derived from the taught node (bag hoisted flat) and pinned as refused by
exactly actionType and target on both strict faces, while the tolerant face
still keeps it. registered-types-validate-ratchet-10859: lit control that the
extracted node is in the bag spelling. Empty-frontmatter changeset: docs and
pins only, nothing released.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KTZmMfzVzjNvyaLyQ8mHvg
@github-actions github-actions Bot added documentation Improvements or additions to documentation package: types tests package: cli labels Oct 1, 2026
@github-actions

github-actions Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

changeset-claim-re-read

⚠️ 15 pending changeset(s) describe a file this change touches

Their bodies publish verbatim into the CHANGELOG at the next release, so this is a request to re-read them against your diff — addressed here because you are the one seat that can answer it without re-deriving anything.

⛔ Nothing here blocks, and nothing here is a verdict on your change. This gate exits 0, is not a required context, and judges name resolution, never meaning: it asked whether a pending body names a file you touched. "Is this sentence still true?" is the one question it will not answer, and the one you are being asked to answer.

.changeset/10106-settled-schema-equal-payload.md

  • names AGENTS.md → AGENTS.md — edited by this change

    The hook refetches getObjectSchema whenever the adapter identity changes, and every consumer its doc comment instructs — ObjectGantt, ObjectCalendar, ObjectView, ObjectTimeline, ObjectGallery — keys its record fetch on the returned def, which is what AGENTS.md §5 commandment [WIP] Enhance every detail of the designer #10 tells a consumer to do (key on the payload, never on a memo identity). The producer half of that same sentence is what this fixes: a byte-identical answer arriving as a fresh object re-fired every one of those fetches, and the duplicate query carried the same $expand set as the one before it. Measured first-hand on ObjectGantt with an instrumented adapter, with a control swap in the same command; the counts, and the control that makes them a discrimination rather than a counting artefact, are asserted by packages/react/src/hooks/__tests__/useSettledSchema.equalPayload-10106.test.tsx (objectui#10106).

.changeset/4795-bindable-text-keys.md

  • names skills/objectui/rules/protocol.md → skills/objectui/rules/protocol.md — edited by this change

    Published authoring guidance updated to match: skills/objectui/rules/protocol.md (new "Bindable Text Keys" rule), plus the page-builder, schema-expressions and data-integration guides, which taught the now-retired "never evaluated" statement and its host-pre-resolution workaround.

.changeset/5674-retire-plugin-component-input.md

  • names AGENTS.md → AGENTS.md — edited by this change

    Why now, and why a minor rather than waiting further. The deprecation window exists to warn a consumer outside this repository, unmeasurable from here, before a published export disappears. That window has already been spent — stage 1 shipped and the warning has been live. The follow-up card that was meant to gate stage 2 on "a release actually shipping the deprecation" was later closed as a duplicate into a release-batch tracking card that itself no longer exists (answers 404), so the gate had no carrier left to clear. Execution ruling 2026-09-27 (triage, carrying the maintainer's 「同意」) deletes now rather than block indefinitely on a dead gate; the sibling objectstack repository's docs/NORTH-STAR.md 〈阶段姿态〉 already makes immediate retirement (no alias, no window) the default disposition for a zero-consumer published name. Removing a published export is minor, not patch — this repo's own breaking changes never declare major (see AGENTS.md's version-alignment policy).

.changeset/6357-basechema-bind-declaration.md

  • names AGENTS.md → AGENTS.md — edited by this change

    bind was read by ten production sites and declared by no schema shape. It resolved as any through BaseSchema's index signature and rode .passthrough() on the validator, while three separate documents taught it as an authorable key of every node: this repo's own AGENTS.md §4 ("Every node in the UI tree follows this shape (@object-ui/types)"), the published agent-facing skills/objectui/rules/protocol.md ("Every UI component node MUST follow this shape"), and content/docs/fields/grid.mdx. So the agent-facing protocol told authors to write a key the published types did not know existed.

  • names skills/objectui/rules/protocol.md → skills/objectui/rules/protocol.md — edited by this change

    bind was read by ten production sites and declared by no schema shape. It resolved as any through BaseSchema's index signature and rode .passthrough() on the validator, while three separate documents taught it as an authorable key of every node: this repo's own AGENTS.md §4 ("Every node in the UI tree follows this shape (@object-ui/types)"), the published agent-facing skills/objectui/rules/protocol.md ("Every UI component node MUST follow this shape"), and content/docs/fields/grid.mdx. So the agent-facing protocol told authors to write a key the published types did not know existed.

.changeset/6475-gantt-block-face-declared.md

  • names skills/objectui/guides/page-builder.md → skills/objectui/guides/page-builder.md — edited by this change

    Maintainer ruling, objectui#6475 (2026-08-27), Option A — enforce as-is, immediately, no warning window (the startup-stage no-gradualism rule, objectstack#12668: transitions do not get phased windows without named external-user evidence, and none exists here). A census of every gantt block reachable through ObjectGanttSchema in this repository — the examples/schema-catalog fixtures, content/docs/plugins/plugin-gantt.mdx, and the published skills/objectui/guides/page-builder.md guide — found zero blocks missing the trio.

.changeset/6505-predicate-valued-gate-rules.md

  • names AGENTS.md → AGENTS.md — edited by this change

    The accept set widens to what the protocol already declares and the runtime already accepts, not beyond it. AGENTS.md §4 declares both keys as expressions, SchemaRenderer evaluates them through hasDeclaredPredicate + evaluateCondition, @objectstack/spec normalizes every authored predicate into a { dialect, source } envelope, and the objectui#3862 / objectui#3955 rulings are entirely about which expression spellings count as declared. This table was the one place in the repo that disagreed, so this restores declared = enforced rather than changing a contract.

.changeset/6575-data-table-bind-diagnostic.md

  • names skills/objectui/rules/protocol.md → skills/objectui/rules/protocol.md — edited by this change

    The platform was already paying for this in teaching rather than in diagnostics: skills/objectui/rules/protocol.md documents the pothole verbatim and a pin test locks the behaviour. The warning now also reaches the console, where the author who did not read the docs is standing:

.changeset/6665-data-table-non-array-data-diagnostic.md

  • names skills/objectui/rules/protocol.md → skills/objectui/rules/protocol.md — edited by this change

    The spelling that opened the card is a ${...} expression string, and it is a defect rather than a design because the SAME expression is evaluated one key over. Re-measured on merge-base 5967be095 through the real SchemaRenderer (the table was previously quoted from skills/objectui/rules/protocol.md as a measurement on f1c27f037 and had not been re-run); all four legs reproduced, and they are now pinned as tests rather than prose:

.changeset/6872-app-shell-branding-title-jsdoc.md

  • names content/docs/guide/layout.md → content/docs/guide/layout.md — edited by this change

    Correct the AppShellBranding.title doc comment. It read "Page title suffix (sets document.title)" while useAppShellBranding assigns document.title = title wholesale — nothing is appended; the caller composes the whole string (the console passes "App label — Product name"). That comment ships in dist/index.d.ts and is the only description a consumer sees on editor hover, so a reader who followed it passed a suffix-only fragment and got a truncated title with no error. The comment now carries the same wording as content/docs/layout/app-shell.mdx, and agrees with the AppShellProps tables in the package README and content/docs/guide/layout.md. No runtime behaviour changes; the wholesale assignment and the four-surface agreement are now pinned by tests.

.changeset/7122-spec-17-3-0-parity-reconciliation.md

  • names AGENTS.md → AGENTS.md — edited by this change

    Two breaking consequences for a consumer that names the type directly. (1) It no longer declares editMode; the key is now carried by the spec's ServiceObject, so ObjectSchemaMetadata still has it, but code written against the extension type ALONE loses it. (2) interface → type alias also ends declaration merging: a consumer that reopened declare module '@object-ui/types' { interface ObjectSchemaClientExtensions { … } } to add its own client-side member no longer compiles, because an alias cannot be reopened. minor rather than major per AGENTS.md's version-alignment rule — objectui's own breaking changes are graded minor with the semantics stated in the body, since any major in the fixed group would push all 39 packages off @objectstack's major.

.changeset/7714-lookup-draft-stays-client-side.md

  • names AGENTS.md → AGENTS.md — edited by this change

    minor rather than major per AGENTS.md: objectui's major tracks @objectstack's, so objectui's own breaking changes ship as minor with the breaking semantics stated.

.changeset/7926-page-node-refuses-actions.md

  • names content/docs/guide/layout.md → content/docs/guide/layout.md — edited by this change

    Scope. One key, by name; the node is NOT strict. A census over this tree read 91 authored page-tagged objects with a blind-spot reading of 8 unreadable sites, and found only actions (3 sites, all in content/docs/guide/layout.md) and breadcrumbs (1 site, its own question, untouched) surviving passthrough on a real page node — every other undeclared key belongs to a different declaration that merely spells type: 'page'. PageNodeSchema still passes unknown renderer props through.

.changeset/8284-content-channel-per-component.md

  • names content/docs/guide/schema-rendering.md → content/docs/guide/schema-rendering.md — edited by this change

    Migration. Nothing that renders today stops rendering: a document authoring the channel its renderer reads is unchanged, and a document authoring the other one rendered an empty element before and is now refused instead. The repo-wide census found five documents in this state — packages/react/README.md, content/docs/guide/expressions.md, two blocks in content/docs/guide/schema-rendering.md and packages/components/TESTING.md — every one of them a form or container authoring body; all five are corrected in this change. If your own metadata authors the refused channel on one of these twelve node types, the component was already drawing nothing there; rename the key to the one in the table.

.changeset/8871-page-node-refuses-breadcrumbs.md

  • names content/docs/guide/layout.md → content/docs/guide/layout.md — edited by this change

    Three author sites, all teaching passages in content/docs/guide/layout.md, and that count corrects the actions refusal's "1 site": its census reads every git-tracked JSON file, every json fence in .md/.mdx, and every TS/TSX object literal via the TypeScript AST (PR fix(types,docs): refuse actions by name on the page node, teach the shape that draws (objectui#7926) #8870), and it undercounted for two different reasons. The Schema API block declared breadcrumbs?: ArrayANGLE-BRACKETS({ label, href }) outright and its literal does carry type: 'page', but that literal sits inside a markdown typescript fence — a fence language the census's json-fence reader never visits, so it was never read at all. Best Practices §2 authored it on a fragment inside a json fence the census does read, but that fragment never writes type, so a page-tagged filter correctly excluded it. No example app, catalog fixture, template or customer document writes the key, so the refusal strands no authored document in this tree.

.changeset/9308-data-root-unbound-from-adapter.md

  • names content/docs/guide/schema-rendering.md → content/docs/guide/schema-rendering.md — edited by this change

    The Data Context passages of content/docs/guide/schema-rendering.md and packages/react/README.md teach the scope channel accordingly.

Read the paragraph, not the line: both false halves of the objectui#8617 claim sat in one paragraph, and correcting either alone would have left it asserting the same wrong thing.

If a claim did go false, correct the body. That is precedented and prose-only, frontmatter untouched; check-changeset-overwrite.mjs will report the correction as its own case 2 ("correcting a declaration on purpose … legitimate"), which is the intended shape — one gate asks for the read, the other records the write.

Not covered, stated so nobody reads this as more: a born-false claim that spells no line address at all (objectui#9495 coordinated one by ORDINAL — "a grep finds that member first" — and deciding that means reading what the sentence means), a claim spelled as a symbol or a package rather than a backticked file name, and a file named ambiguously.

Angle-bracketed names in the quoted prose above are rewritten as ANGLE-BRACKETS(name): GitHub deletes tag-shaped fragments from a stored body, and a quote that silently loses the identifier it is about is worse than a visible repair.

Compared the checked-out tree with 2124d0411 (merge-base with origin/main): 11 file(s) changed outside .changeset/, read against 1910 pending declaration(s) that publish a body (2524 pending in total). · run

@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 330 chunks) 3585.7 KB 3607.4 KB
Main entry chunk (gzip) 150.4 KB 350 KB
Entry file index-C1QQgozJ.js —
Status PASS —

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.88KB 6.25KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.11KB 3.87KB
auth (ActiveOrganizationStorage.js) 27.95KB 10.04KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.22KB 10.61KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.17KB 5.40KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.72KB 2.24KB
auth (SocialSignInButtons.js) 9.70KB 3.93KB
auth (UserMenu.js) 3.39KB 1.21KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.70KB 10.94KB
auth (createAuthenticatedFetch.js) 8.54KB 3.46KB
auth (index.js) 3.63KB 1.64KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 27.13KB 7.95KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 571.60KB 136.88KB
core (index.js) 10.00KB 3.96KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 229.96KB 63.80KB
fields (index.js) 261.05KB 66.23KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 2.59KB 1.22KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.24KB 2.27KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 39.40KB 12.91KB
i18n (translateFn.js) 0.20KB 0.18KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 34.49KB 9.23KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 40.95KB 11.48KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 6.62KB 2.45KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 5.52KB 2.10KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.86KB 5.00KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.52KB 2.26KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.33KB 3.07KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 16.01KB 3.93KB
plugin-calendar (index.js) 52.90KB 15.35KB
plugin-charts (index.js) 84.09KB 22.93KB
plugin-chatbot (index.js) 198.22KB 46.97KB
plugin-dashboard (index.js) 139.34KB 37.30KB
plugin-designer (index.js) 216.45KB 44.60KB
plugin-detail (index.js) 244.79KB 64.47KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 173.70KB 44.63KB
plugin-gantt (index.js) 173.03KB 43.07KB
plugin-grid (index.js) 231.61KB 63.61KB
plugin-kanban (index.js) 49.32KB 15.48KB
plugin-list (index.js) 116.63KB 28.97KB
plugin-map (index.js) 23.54KB 7.83KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 44.04KB 12.21KB
plugin-timeline (index.js) 33.05KB 9.67KB
plugin-tree (index.js) 11.20KB 3.89KB
plugin-view (index.js) 90.32KB 22.76KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.81KB 3.58KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 119.55KB 39.23KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.50KB 2.06KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.50KB 1.99KB
sdui-parser (codegen.js) 9.45KB 3.76KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 6.06KB 2.68KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.84KB 1.90KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 21.42KB 7.05KB
types (ai.js) 4.39KB 2.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 4.12KB 1.61KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 3.19KB 1.62KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.26KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 5.00KB 2.39KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 2.52KB 1.31KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 4.99KB 1.96KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 21.59KB 7.71KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: f580661be67d78ef4a8120029c510ff898b547b9
Local-runs: none

Head resolved from GET pulls/11317 → head.sha f580661be67d78ef4a8120029c510ff898b547b9 on claude/issue-11183-action-node-properties-bag; merge-base with main is caa0cd39277a1ff20cf9ee53a11626a5a3335770 (the dev's base_sha). main is 5 commits past it (cd5b19a7e7, mergeable_state: behind); none of the 91 files those commits touch is one of this PR's 12. The API diff is byte-identical to the seat's pr.diff; the net diff head-vs-merge-base has the same 12-file numstat (+162 −79). Two commits, both authored Claude.

Check-runs on the head (read three times, last at 2026-10-01T03:13Z): 43 runs — 40 success, 3 skipped (Test (coverage), Test (coverage shard ${{ matrix.shard }}/4), dependabot), 0 failure, 0 in_progress. The first read (≈03:04Z) had 11 in_progress — Lint, Type Check, Spec Main Shape Gate, Test (shard 1/8) … Test (shard 8/8) — every one of them converged to success by the last read, and the Test rollup appeared as success. Required set per scripts/check-required-check-set.mjs: pinned Type Check (success); watched Lint, Build & E2E, Test, Build Docs, Changeset Declaration, Spec Main Shape Gate (all success). Governed Surface Queue Guard success is the pull_request leg, which exits 0 by design on a governed draft — it is not a NOT-GOVERNED reading. 0 reviews on the PR; it is draft, as a governed-surface PR must be.

Rulings taken as input: the card body's ruling A (the properties bag is the contract; ADR-0089 D3a), rider 5916799642 (record:activity limit / showCompleted / items), rider 5922065881 (object-form), the claim 5923347428 (declared surface) and the dev's os-dev-report 5923856769.

① Derived judgments

(a) Every edited fence, on three faces. 11 action:button nodes under the roots at the head (AGENTS.md #4 ×1; skills/objectui/SKILL.md "4. The action system" ×1; guides/page-builder.md "5. Use action data" ×1; rules/protocol.md "Rule: Actions Are Node Types, Not An Event Bag" ×1; content/docs/guide/quick-start.md "Add Actions" ×1; record-edit-modes.md "Triggering the routes from JSON" ×3; schema-rendering.md "Reference actions in schemas" ×1; layout.md "Detail Page with Actions" ×2) — the dev's count of 11 is right, and at the head each node's own level carries exactly type and properties. Faces read, not run:

  • Spec — PageComponentSchema lives at objectstack origin/main packages/spec/src/ui/page.zod.ts (⚠️ the brief's path page.ts does not exist; the card's page.test.ts does, with the describe ADR-0089 D3a — strict page component schema (loud mis-layered keys)). It is strictObject with node-level type, id, label (I18nLabelSchema), properties (z.record(z.string(), z.unknown()), optional, default {}), events, style, className, responsiveStyles, visibleWhen / visibility, dataSource, aria. So on the spec face every bagged node is accepted (the bag is an open record there), and flat actionType, target, name, icon, variant, endpoint, method, params are unrecognized_keys. label is the one bagged key the spec would ALSO accept flat — see (b).
  • objectui tolerant (safeValidateSchema → AnyComponentSchema) — ActionButtonBlockSchema = BaseSchema.extend({ type, ...NODE_ENVELOPE, properties: propsBag('action:button', stripImportedDefaults(SpecActionButtonPropsSchema)), onSuccess: aliasKeyRefusal(…) }); the bag is the spec row by reference. The spec row (ActionButtonPropsSchema, strictObject) declares every key the diff bagged: name, label, icon, actionType, variant (enum of the Button primitive's default | destructive | outline | secondary | ghost | link plus primary — layout.md's default and destructive are members), params (z.unknown()), target, endpoint, method. Accepted.
  • objectui strict (StrictAnyComponentSchema, derived with catchall: z.never() on every reachable object) — node level holds only type + properties, both declared; accepted.
  • Riders: record:activity bag { "limit": 20, "showCompleted": false } — both are RecordActivityProps members (limit int positive, showCompleted boolean; defaults stripped at the import boundary); the enclosing page:tabs → properties.items[].children nesting is the objectui#11223 walk and is unchanged. object-form bag { objectName, mode: "edit", fields: [ {…} ] } — ObjectFormPropsSchema declares objectName (optional string), mode (create | edit | view), fields (z.array(z.unknown())). Accepted on all three.
  • Machine confirmation exists for ONE of the 12 fences: the two moved pins (now green in the Test shards) parse the quick-start fence and assert it validates tolerant + strict + spec. The other 11 rest on the schema reading above — the Skill Example Check only JSON-parses a marked fence (its header: "a json / jsonc block must parse"), and Doc Snippet Type Check compiles ts fences; neither judges a JSON node against a face.

(b) The prose beside the nodes. Every refusal sentence names its refuser; none says objectui validate refuses a flat action:* today — correct, because packages/cli/src/commands/validate.ts at the head still calls safeValidateSchema (the tolerant face), and PR objectui#11069 is what moves it. Precise sentences: AGENTS.md #4 ("the spec's PageComponentSchema is .strict() (ADR-0089 D3a) and refuses a node-level actionType / target as mis-layered, and objectui's strict authoring face refuses the same two keys"), SKILL.md, rules/protocol.md and quick-start.md ("Written flat on the node, actionType and target are refused by the spec's strict page component") — all name exactly the two keys and the two refusers. The one sentence that claims objectui validate refuses something today is the page-builder object-form line ("objectui validate refuses the flat spelling by name") — TRUE at the head: ObjectFormBlockSchema spreads OBJECT_FORM_FLAT_PROP_REFUSALS ("One by-name refusal per member of the spec's object-form row"), which sits on the arm the tolerant face runs, so validate refuses it today without #11069. ⚠️ Precision wobble, not a defect: layout.md ("Its props — actionType and the rest of the block's row — go in the node's properties bag … the spec's strict page component refuses them written flat") and schema-rendering.md ("the block's props go in its properties bag … the spec's strict page component refuses them written flat") sweep label into "them", but label is a declared node-level key on the spec's page component (and on objectui's BaseSchema), so a flat label is kept, not refused. The instruction (write the bag) is right either way; only the breadth of the refusal claim overshoots. The PR body's census paragraph has the same overshoot ("refused … with exactly the flat keys named above"): name is a BaseSchema key (kept by objectui's strict face, refused by the spec) and label is kept by both. Exactness holds only for the quick-start-shaped node, which is the one the pin asserts.

(c) AGENTS.md #4. "The block's props live in the node's properties bag, which is the spec's ComponentPropsMap row for it" — true of the validator (propsBag('action:button', …) IS ComponentPropsMap['action:button'] by reference). "The runtime reads both spellings through the SchemaRenderer properties hoist" — true: HOIST_PROTECTED_KEYS = new Set(['type', 'id']) is the whole exclusion list ("Keys the properties hoist deliberately refuses to copy onto the node"), every other properties.* is copied onto the node, flat keys are already there, and action-button.tsx reads schema.actionType, schema.label, schema.target, schema.name, schema.icon, schema.variant post-hoist. The guide-layout-page-buttons-7926 pin (real renderers on the edited layout.md passage, asserting the Edit / Delete buttons draw) is green in the shards. As an instruction it is complete: what to write (the bag), what is refused (flat actionType / target), by whom (spec strict + objectui strict), and that render cost is nil. It does not claim validate refuses today, so it stays true across #11069.

(d) Riders. plugin-detail.mdx: limit and showCompleted are ComponentPropsMap['record:activity'] keys (row members read from the spec source: types, filterMode, showFilterToggle, limit, showCompleted, unifiedTimeline, showCommentInput, enableMentions, enableReactions, enableThreading, showSubscriptionToggle, aria — the dev's list of 12, exactly). page-builder.md object-form: PR objectui#11291 is e3782d26ec on main ("an authored object-form takes its props in the spec's properties bag; the flat spelling is refused by name"); at the head the arm carries OBJECT_FORM_FLAT_PROP_REFUSALS for every row member (flat refused by name on both faces) and properties: propsBag('object-form', …) (bag accepted). Rider premise holds; execution matches.

(e) The measured NON-edit of packages/plugin-detail/README.md. Verified: items is not a RecordActivityProps member; the row is strictObject, so properties.items is unrecognized_keys on the tolerant face (the bag is judged by the row when present) and on the strict face alike; record-activity.tsx documents "Three sources, in precedence order: 1. items on the node — a host that already owns the feed passes it in, exactly as record:history takes entries" and reads Array.isArray(schema.items) ? schema.items : Array.isArray(bag.items) ? bag.items : …; the README's example is a ```tsx fence composing a DetailViewSchema in code (`type: 'record:activity', items: activityData`) and its prose says "The feed arrives as `items`, not `data`". Leaving it is RIGHT: moving `items` into the bag would turn a working host composition into a node both authoring faces refuse. The out-of-scope finding is a real class-c defect for `domain:ui` to carry, with one correction: `record:history`'s `entries` is NOT a named runtime-slot refusal either — `RecordHistoryBlockSchema` declares `type`, the envelope, `properties`, `body`, `children` and nothing called `entries` — so the asymmetry the dev drew against `entries` does not exist; the asymmetry is against `action:button`'s `onClick` (a `handlerKeyRefusal`). Both feed-slot keys are in the same unnamed state.

(f) The two pins. held-public-block-arms-10872.test.ts: the control is flattened(taughtActionButton()) — const { properties, ...rest } = node; return { ...rest, ...properties } — derived from the parsed fence, not a literal; the derived flat node is asserted refused by StrictAnyComponentSchema and by PageComponentSchema with refusedKeys(...).sort() equal to ['actionType', 'target'], and kept by safeValidateSchema; the taught node AS WRITTEN is asserted green on FACES (tolerant + strict), in a page and alone, and on PageComponentSchema. registered-types-validate-ratchet-10859.test.ts: lit control taught.properties?.actionType === 'url' and not.toHaveProperty('actionType'), then validate on the page expecting "Schema is valid" / exit 0 — the tolerant face it runs today; the header and refusedAtType (the lines #11069 edits) are untouched, as claimed. Reverse-leg consistency: with the quick-start flat, bag.actionType dereferences undefined (non-vacuity row red), the strict AS WRITTEN row goes red while its tolerant twin stays green, the spec row goes red, and the ratchet's properties?.actionType control goes red — 4 red / 60 green is exactly what the assertions produce. Both files are ledgered readers in scripts/markdown-test-inputs.mjs (reads: [... 'content/docs/guide/quick-start.md']).

(g) PR objectui#11069 overlap. Read its diff: on layout.md it edits only the label / text paragraph under the page-buttons passage ("objectui validate refuses it by name, but nothing on the render path does"); this PR edits the "Detail Page with Actions" fence and the onClick paragraph after it — disjoint. On schema-rendering.md #11069 edits doors 2 and 3 of "Validation happens at three doors" (naming StrictAnyComponentSchema.safeParse as the parse validate runs); this PR edits "Reference actions in schemas" — disjoint, and nothing here says validate runs the tolerant face in a doc. On the ratchet test #11069 edits the header, the import, refusedAtType and the chart control; this PR edits only the validates a page with the taught action:button node body. No overlap, no contradiction; the one line #11069 will have to revisit is the PRE-EXISTING test title "passes the tolerant face objectui validate runs", which this PR did not touch.

(h) Scope fences. rules/protocol.md: one hunk only; the paragraph beginning "Readers only. list and tree-view…" is byte-identical between main and the head (#11009's). guides/app-composition.md: not in the 12 files (#11198).

(i) Census. Re-ran the instrument at the head: 11 hits under the roots, every node's own level is type + properties (0 flat row keys); at main the same 11 nodes carry flat keys. Outside the roots: packages/app-shell/README.md — two action:button nodes with flat actionType (navigate_create / navigate_edit, under "The handler name goes in actionType") — outside the claimed surface, as the dev says; no other action:* node in packages/*/README.md, apps, examples or docs. See ③ for the wider-family remainder the rider asked about.

(j) Rule #11. PR body, changeset and every added diff line scanned for path:line and #L forms: none. Line Citation Gate success (its ENFORCEMENT is 'report-only', so green there means 0 new, not "blocking passed").

(k) Added lines on skills/objectui/**. Counts verified against the blobs: SKILL.md 137→142, guides/page-builder.md 346→353, rules/protocol.md 364→370, bundle 4782→4800. Per file: the fence gains 2 wrapper lines (the example IS the rule); the prose gains one rule sentence — "Its props go in the node's properties bag" / "never flat on the node" / "⛔ Not flat on the node" — and one justification clause — "the spec's strict page component refuses a node-level actionType / target as mis-layered (ADR-0089 D3a), and so does objectui's strict authoring face". The justification is commentary an authoring agent does not need to act and it is now spelled four times (three skills files + AGENTS.md); protocol.md's parenthetical "(the spec's row for the block, hoisted onto the node by SchemaRenderer as the rule above describes)" restates its own table row ("hoisted onto the node (type / id excepted)") and "Rule: Keys Live on the Node". The page-builder object-form line ("objectui validate refuses the flat spelling by name") IS a rule an agent needs. Tax: roughly one line of commentary per governed file; tolerable, trimmable later, not a defect.

② Semver level

Docs, two test files, one changeset. packages/types and packages/cli files[] are both ["dist", "README.md", "CHANGELOG.md", "LICENSE"]; the test files sit under src/__tests__, which packages/types' tsconfig excludes by directory ("Tooling is excluded by DIRECTORY, not just by file NAME", enforced by check:published-tsconfig-exclude) and which packages/cli's tsup entry never names; Test (dist pins) is success. Nothing published changes. The empty-frontmatter changeset is required and right: check-changeset-presence.mjs fires on any fixed-group package's src/** and its header says "An EMPTY frontmatter counts"; AGENTS.md calls that form "合法的一等通过写法". ⚠️ Brief premise corrected: a skip-changeset label object DOES exist among objectui's 98 labels, but it is a phantom — scripts/__tests__/ci-cd-pipeline-doc.test.ts pins "never wires the phantom skip-changeset label into a workflow or a gate" and no script or workflow reads it — so the empty changeset remains the only first-class form. Changeset body: no model id, no line address. Clause-②: no is right: no file under packages/types/src/zod, strict-authoring-face.ts or packages/cli/src/commands is in the diff, and the moved pin's CONTROL asserts the tolerant face still keeps the flat node — no accept/reject behaviour moved.

③ Boundary flags

  1. README non-edit — answered in ①(e): right call; the out-of-scope finding carries to domain:ui with the entries correction (both record:activity items and record:history entries are host feed slots refused unnamed on the strict face).
  2. check:skill-eval-tokens misreading in the dispatch — the dev is right. The script's header: "Every must_contain token of every" bundle's "evals/*.json must be something the skill bundle actually TEACHES"; exit 1 is "a token no guide teaches". It is not a length meter, and no script under scripts/ bounds skills/** length. What that means for the line readings: they are unbounded self-reports (verified here against the blobs), and Skill Eval Token Check success says only that the re-worded prose dropped no taught token.
  3. Three locked builds — three gates (check-skill-examples, check-doc-snippet-types, check-readme-exports) need dist, so the dev built under os-verify-lock. Process cost, no rule breached; the same three gates are success on the head and nothing in this record rests on the local runs.
  4. Model-free trailers — both commits (deaf475…, f580661…) end with the Co-authored-by: Claude trailer (the noreply@anthropic.com address) and Claude-Session: https://claude.ai/code/session_01KTZmMfzVzjNvyaLyQ8mHvg; no model identifier in either, nor in the PR title/body, the changeset or any edited doc — AGENTS.md's quoted "Commit message:" rule, with the harness reminder yielding to it, as that rule says.
  5. mcp_calls: 0 / api_writes: 2 — consistent with the threads: the PR is authored by objectstack-fleet[bot] (the dispatch pr_create); the card has exactly one dev comment (the os-dev-report); the PR thread holds only the changeset-claim-re-read and Console Performance Budget bot comments; 0 reviews; the four labels (documentation, package: types, package: cli, tests) all have .github/labeler.yml entries; assignees empty. mcp_calls: 0 is not independently observable; nothing contradicts it.
  6. Escalation — rider 5916799642's widening ask is only part-executed. The rider asked the claim "to widen both to every public-block example under the same roots". The claim fixed the surface to the named sites (action:* + plugin-detail.mdx + plugin-detail/README.md + page-builder.md's object-form), so the dev breached nothing — but two same-family nodes remain under the roots and are in nobody's out_of_scope_findings: content/docs/guide/slotted-pages.md writes a record:related_list with flat objectName, relationshipField, columns (row members of RecordRelatedListProps: objectName, relationshipField, relationshipValueField, columns, sort) plus actions, which is not a row member at all; content/docs/api/schema-reference.md writes the same node flat inside a blockquote (objectName, relationshipField, title, columns). RecordRelatedListBlockSchema is bagged (propsBag('record:related_list', …)), so both are refused by the strict face and by the spec's page component exactly as the action:* nodes were. Carry to domain:ui (objectui#10872 family) or a follow-up to this card; not this PR.
  7. Brief premise corrections (for the seat's own record): the spec file is packages/spec/src/ui/page.zod.ts, not page.ts; objectui's skip-changeset label exists but is wired to nothing (see ②).
  8. Branch state — mergeable_state: behind (5 main commits, none on these 12 files); the queue rebases, no action for the dev.
  9. Note for the seat, outside the dev's deliverable: the claim comment 5923347428 on the card names a model (model: fable, claude-fable-5-1); the AGENTS.md trailer rule's "no model identifier lands in … a comment" is the seat's own exposure there, not this PR's.

Governed-surface posture is correct: draft, awaiting an APPROVED review from os-zhuang / hotlong; the claiming seat lands it; this record is not that approval.

Implemented-by: claude/issue-11183-action-node-properties-bag
Reviewed-by: session_01KTZmMfzVzjNvyaLyQ8mHvg

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读

改了什么:把教给 AI 的 11 处 action:* 节点范例(AGENTS.md 第 4 条、skills/objectui 三个文件、content/docs/guide 四个文件)的执行键(actionType、target 等)从节点平铺挪进 spec 的 properties 袋;顺带两条同族:plugin-detail.mdx 的 record:activity 行键、page-builder.md 的 object-form 范例。两枚读这些文档的 pin 测试随之改为袋拼法,并带派生的平铺对照。

为什么改:分诊对 #10872 的裁决 A——properties 袋是契约(ADR-0089 D3a),spec 的严格 page component 拒绝平铺。PR #11069 即将把 objectui validate 换到严格面;若本 PR 不先落地,技能里的范例就会被校验器拒绝。运行时两种拼法都经 SchemaRenderer 提升读到,所以只动文档。

风险与代价(含回滚):不改运行时、不改校验器,空 changeset 不发包;复审(契约复审档,记录 5924066480)逐个范例在三张面上核过。回滚 = revert。留给后续的:layout.md/schema-rendering.md 里「平铺一律被拒」措辞略宽(label 平铺其实被接受),搭下次改那段的 PR;plugin-detail/README.md 的 items 是宿主运行时槽,经实测不动;根之外还剩三处同族平铺范例 + 两个未具名的宿主槽,已立 #11321 交分诊。

席位意见:建议批准,并先于 PR #11069 合入。

你要做的:在本 PR 上留一条 APPROVED review(os-zhuang 或 hotlong);之后由本席翻 ready、挂 auto-merge 入队。


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review October 1, 2026 05:34
@os-zhuang
os-zhuang added this pull request to the merge queue Oct 1, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 1, 2026
@os-warren
os-warren enabled auto-merge October 1, 2026 05:48
@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 330 chunks) 3585.7 KB 3607.4 KB
Main entry chunk (gzip) 150.4 KB 350 KB
Entry file index-Dx92d-uf.js —
Status PASS —

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.88KB 6.25KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.11KB 3.87KB
auth (ActiveOrganizationStorage.js) 27.95KB 10.04KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.22KB 10.61KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.17KB 5.40KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.72KB 2.24KB
auth (SocialSignInButtons.js) 9.70KB 3.93KB
auth (UserMenu.js) 3.39KB 1.21KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.70KB 10.94KB
auth (createAuthenticatedFetch.js) 8.54KB 3.46KB
auth (index.js) 3.63KB 1.64KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 27.13KB 7.95KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 571.28KB 136.83KB
core (index.js) 10.00KB 3.96KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 229.96KB 63.80KB
fields (index.js) 261.05KB 66.23KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 2.59KB 1.22KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.24KB 2.27KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 39.40KB 12.91KB
i18n (translateFn.js) 0.20KB 0.18KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 34.49KB 9.23KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 40.95KB 11.48KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 6.62KB 2.45KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 5.52KB 2.10KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.86KB 5.00KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.52KB 2.26KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.33KB 3.07KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 16.01KB 3.93KB
plugin-calendar (index.js) 52.98KB 15.39KB
plugin-charts (index.js) 84.09KB 22.93KB
plugin-chatbot (index.js) 198.22KB 46.97KB
plugin-dashboard (index.js) 139.34KB 37.30KB
plugin-designer (index.js) 216.45KB 44.60KB
plugin-detail (index.js) 244.79KB 64.47KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 173.70KB 44.63KB
plugin-gantt (index.js) 173.11KB 43.10KB
plugin-grid (index.js) 231.53KB 63.58KB
plugin-kanban (index.js) 49.32KB 15.48KB
plugin-list (index.js) 116.63KB 28.97KB
plugin-map (index.js) 23.54KB 7.83KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 44.04KB 12.21KB
plugin-timeline (index.js) 33.91KB 10.00KB
plugin-tree (index.js) 11.20KB 3.89KB
plugin-view (index.js) 90.32KB 22.76KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.81KB 3.58KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 119.55KB 39.23KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.50KB 2.06KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.50KB 1.99KB
sdui-parser (codegen.js) 9.45KB 3.76KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 6.06KB 2.68KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.84KB 1.90KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 21.42KB 7.05KB
types (ai.js) 4.39KB 2.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 4.12KB 1.61KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 3.19KB 1.62KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.26KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 5.00KB 2.39KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 2.52KB 1.31KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 4.99KB 1.96KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 21.59KB 7.71KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Red check on this PR, read by the skills seat (session_01KTZmMfzVzjNvyaLyQ8mHvg) on the maintainer's word 「11317 红了」, 2026-10-01T07:41Z.

What is red. Spec Main Shape Gate on head 39d7744a8 (the merge of main into this branch after the queue removed it at 05:46Z), run 36821538165, compiled against @objectstack/spec built from objectstack-ai/objectstack at 94608a7d72ec. Its annotations name five objectui files: packages/runner/src/LayoutRenderer.tsx (a retired-key tsc error, the "[REMOVED] Key retired: run os validate for its migration" shape objectstack#21023 introduced) and four type-twin pins under packages/types/src/__tests__ (twins-spec-by-reference-9736, record-details-top-level-9040, dashboard-aria-retired-contract-twins, chartconfig-aria-retired-4044 — true not assignable to false and the converse).

Why it is not this PR's. None of those five files is in this PR's diff (12 files: docs, AGENTS.md, skills/objectui/**, two other pins — held-public-block-arms-10872 and registered-types-validate-ratchet-10859 — and an empty changeset; the diff touches no .ts outside those two tests and no runner code). The gate compiles the whole repository against objectstack's moving main; the failing twins pin spec shapes objectstack moved that morning. The same gate passed on every objectui head it ran on from 06:45Z onward (pull_request and merge_group runs alike), compiled against a later objectstack main — so the 05:48Z reading is a transient of objectstack main at 94608a7d, not a defect this diff introduced.

What the seat does. One re-run of the failed job now, as the confirmation the rule allows. Green ⇒ auto-merge (armed 05:48Z) takes the PR back into the queue on its own; the seat clears needs-user-decision (os-zhuang's APPROVED review is on record). Red again with the same signature ⇒ objectui main is behind objectstack main's spec and that is a domain:spec / domain:devx card on objectui, never a push on this PR.


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Second reading, skills seat (session_01KTZmMfzVzjNvyaLyQ8mHvg), 2026-10-01T07:58Z — correcting the note above.

The re-run of Spec Main Shape Gate on 39d7744a8 reds again with the same five files, now compiled against objectstack at 12fbb2fac8ee, so it is not a transient of objectstack main. The cause is this branch's base: objectui main carries the fix — 47e3ce00, "fix(types,runner): the retired-key pins and the runner sidebar compile against both the pinned spec and objectstack main (objectui#11330)" (PR #11343) — which touches exactly packages/runner/src/LayoutRenderer.tsx and the four packages/types twin pins, and it landed after this branch's merge-base 5262f7dd3. Every other objectui head the gate ran on since 06:45Z includes it and is green.

Act: main merged into the branch through the update-branch route (a merge commit, zero file writes by the seat) → head 31d85dc96. This PR's own diff is unchanged (12 files). The gate re-runs on the new head; auto-merge stays armed and os-zhuang's APPROVED review stands, so a green run takes the PR back into the queue on its own.


Generated by Claude Code

@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 330 chunks) 3552.7 KB 3574.6 KB
Main entry chunk (gzip) 150.4 KB 350 KB
Entry file index-DcOQ2GGR.js —
Status PASS —

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.88KB 6.25KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.11KB 3.87KB
auth (ActiveOrganizationStorage.js) 27.95KB 10.04KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.22KB 10.61KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.17KB 5.40KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.72KB 2.24KB
auth (SocialSignInButtons.js) 9.70KB 3.93KB
auth (UserMenu.js) 3.39KB 1.21KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.70KB 10.94KB
auth (createAuthenticatedFetch.js) 8.54KB 3.46KB
auth (index.js) 3.63KB 1.64KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 27.13KB 7.95KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 571.28KB 136.83KB
core (index.js) 10.00KB 3.96KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 229.96KB 63.80KB
fields (index.js) 261.05KB 66.23KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 2.59KB 1.22KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.24KB 2.27KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 39.40KB 12.91KB
i18n (translateFn.js) 0.20KB 0.18KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 34.49KB 9.23KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 40.55KB 11.41KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 6.62KB 2.45KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 5.52KB 2.10KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.86KB 5.00KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.52KB 2.26KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.33KB 3.07KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 16.01KB 3.93KB
plugin-calendar (index.js) 53.15KB 15.45KB
plugin-charts (index.js) 84.07KB 22.93KB
plugin-chatbot (index.js) 198.22KB 46.97KB
plugin-dashboard (index.js) 139.34KB 37.30KB
plugin-designer (index.js) 216.54KB 44.64KB
plugin-detail (index.js) 245.45KB 64.47KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 173.25KB 44.58KB
plugin-gantt (index.js) 173.11KB 43.10KB
plugin-grid (index.js) 231.53KB 63.58KB
plugin-kanban (index.js) 49.49KB 15.54KB
plugin-list (index.js) 116.63KB 28.97KB
plugin-map (index.js) 23.54KB 7.83KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 44.04KB 12.21KB
plugin-timeline (index.js) 33.91KB 10.00KB
plugin-tree (index.js) 11.20KB 3.89KB
plugin-view (index.js) 90.32KB 22.76KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.81KB 3.58KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 119.55KB 39.23KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.50KB 2.06KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.50KB 1.99KB
sdui-parser (codegen.js) 9.45KB 3.76KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 6.06KB 2.68KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.84KB 1.90KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 21.42KB 7.05KB
types (ai.js) 4.39KB 2.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 4.12KB 1.61KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 3.19KB 1.62KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.26KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 5.00KB 2.39KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 2.52KB 1.31KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 4.99KB 1.96KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 21.59KB 7.71KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@os-warren
os-warren added this pull request to the merge queue Oct 1, 2026
Merged via the queue into main with commit b387d5e Oct 1, 2026
44 checks passed
@os-warren
os-warren deleted the claude/issue-11183-action-node-properties-bag branch October 1, 2026 08:27
os-litant pushed a commit that referenced this pull request Oct 1, 2026
…jectui#11168 slice 3, round 3, third merge)

origin/main advanced to 5638529 while the round-3 gates ran: #11317
(docs), #11352 (types, fields) and #11350 (plugin-grid, core). No
conflict. #11352 also edits packages/types objectql.ts, objectql.zod.ts
and zod-mirror-parity.test.ts, which this branch edits too; it
auto-merged, and the gates are re-run at this head. The guard is
untouched by this merge, so its census still reads as at 2817b5f:
objectui#11168 5, unjudgedBlocks 2, refusedArms 0.

Claude-Session: https://claude.ai/code/session_01VhxTqosz7wn54ahqyxgERT
Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation package: cli package: types tests

Projects

None yet

3 participants