Skip to content

Skills optimization flight — skills/objectui: RESTRUCTURE (≈ −21,600 tok of 64,022, −34%) — ~19% of the package is addressed at a contributor to this repo (console-development.md, no-touch-zones.md, half of architecture.md), one rule stated up to four times, 11 vestigial guide frontmatters, and three evals that fail correct answers #7251

Description

@os-litant

Member card of the skills catalog optimization program objectstack-ai/objectstack#14292 (maintainer mandate 2026-09-02, verbatim: 「审核所有的 skills,进行全面的优化。」). Filed by the skills lane seat (session session_01LraLgQVGq8egUwfYZpbYt1). Read-only audit at objectui origin/main 67dadd6. Full findings table = audit record: the dev posts audit/objectui/findings.md (seat scratchpad) verbatim as the first comment at claim time. Published skills/** is a governed surface in this repo (maintainer ruling 批 #7, ui#6866): .md content ⇒ maintainer review, draft PR, human merge.

Audit summary

29 files, 64,022 tokens (guides 45,065 · rules 8,602 · SKILL.md 2,272 · README.md 1,113 · evals 6,079); largest file guides/console-development.md 7,600 tok (11.9%). Enforcement here: exactly one skills gate, check:skills-paths (paths in prose code spans exist on disk — green, 92/93), and nothing else: no token ratchet, no os:check fence gate (grep -rc "os:check" skills/objectui/ = 0), doc-link/component-type/snippet gates all exclude skills/**. Real usage (437 schema-catalog JSONs + apps + examples), true authoring frequencies: text 702, flex 248, stack 153, button 126, card 93, box 84, form 81 … against 230 registered types the package names ~98. Every @object-ui/* import in a TS fence resolves at 67dadd6 (@object-ui/mobile exists). Verdict RESTRUCTURE: ~12,000 tok addressed at a contributor to THIS repo (customer installs have no apps/console/, no packages/components/src/ui/**, no pnpm-workspace.yaml); ~8% in-package duplication; ~5% restating objectstack anchors; 11 vestigial standalone-skill frontmatters; the router (the file's only decision-changing construct) buried under 90 lines of preamble.

Top findings

# id · span proposal Δtok
1 OUI-B-01 · guides/console-development.md:1-510 — addressed at a maintainer of this repo MOVE-TO repo-internal .claude/skills/ (separate commit) −7,600
2 OUI-I-02 · stylesheets ×4 (styling.md:260-316 + page-builder.md:252-304 + project-setup.md:124-164 + SKILL.md:139-140), expression table ×3, data-table trap ×3, columns/2xl ×3 MERGE-INTO the rules/* anchor + pointers −3,850
3 OUI-D-01 · guides/page-builder.md:356-458 — 1 plugin of 19 takes 33% of the guide MOVE-TO packages/plugin-gantt/README.md (separate commit), keep a 10-line minimal −2,075
4 OUI-I-03 · guides/*.md:1-4 ×11 + :8 openers ×12 — vestigial frontmatter no runtime reads DELETE −1,773
5 OUI-B-03 · guides/architecture.md:14-90, 171-189 — monorepo package placement REWRITE-AS-CONSTRUCT, keep :84-89 + :91-126 −1,374
6 OUI-C-01 · app-composition.md:13-110 vs objectstack-ui :857-893, 634-648 — verbatim duplicate DELETE + pointer to objectstack-ui; keep the route table −1,314
7 OUI-C-03 · schema-expressions.md:304-401 — CEL list-view tier owned by objectstack-formula (:309-313 says so) DELETE + pointer −1,139
8 OUI-B-02 · rules/no-touch-zones.md:1-136 + SKILL.md:89-93 — forbids editing a path no customer has MOVE-TO repo-internal (separate commit) −1,030
9 OUI-B-04 · project-setup.md:252-339, 437-444 — workspace/Turbo/vitest guard/vercel DELETE −838
10 OUI-D-03 · console-development.md:117-134 — deleted-symbols table DELETE (inside #1) −741
11 OUI-B-07 · page-builder.md:6-39, 502-530 — preamble + restatement of SKILL.md:131-151 + eval prompts DELETE −647
12 OUI-C-02 · schema-expressions.md:258-302 vs objectstack-data :250-296 — visibleWhen/readonlyWhen/requiredWhen taught twice with divergent spellings DELETE + pointer to objectstack-data −606
13 OUI-B-08 · README.md:45-97 — eval-authoring instructions shipped to every customer session DELETE −602
14 OUI-B-05 · testing.md:10-61 — this repo's vitest projects, coverage thresholds DELETE −551
15 OUI-B-06 · SKILL.md:15-19, 37-39, 49-55 — router buried under positioning/style/doc-driven prose REWRITE-AS-CONSTRUCT + reorder (router first) −259

Correctness (zero delta, HIGH, fix in this flight)

  • OUI-H-01 evals/mobile.json:36-44 requires useSwipe/useLongPress — zero hits repo-wide; the API is useGesture (packages/mobile/src/index.ts:25): the eval fails a correct answer.
  • OUI-H-03 evals/page-builder.json eval 2 requires the literal token props — inverting the package's most-repeated rule (rules/protocol.md:94-147).
  • OUI-H-04 all four app-composition evals require "type": "object" while the guide writes {type:'object', …}.
  • OUI-G-03 schema-expressions.md:649 "a ${...} on title/label/value/description is never evaluated" — false on declaring types (EXPRESSION_BINDABLE_TEXT_KEYS_BY_COMPONENT; pinned in SchemaRenderer.bindableTextKeys.test.tsx) and contradicted by :47.
  • OUI-G-02 page-builder.md:415-416 "gantt field config may also be hoisted to top-level props" — getGanttConfig reads schema.gantt or flat schema.*, never schema.props; the word is node (:427-428 says so).
  • OUI-G-01 ~25 lines of Chinese in page-builder.md / project-setup.md violate the package's own Core Principle 0, incl. a copy-pasteable fence with "label": "状态" (:379).
  • README.md:79 "stays in sync with the packages/ tree" — @object-ui/sdui-parser (14 importers) and @object-ui/react-runtime (5) appear nowhere; architecture.md:36 "@object-ui/data-* … REST, ObjectQL, GraphQL" — only packages/data-objectstack/ exists.

Three funded additions

  1. Layout-primitive table (flex/stack/box/container/grid — type string, key props, when to pick which), +250, paid by OUI-B-03 — the Add automated testing infrastructure and CI/CD workflows #2/Add public roadmap, VitePress documentation site, and GitHub Pages deployment #3/Fix documentation deployment for www.objectui.org #6 most-authored types get zero mentions package-wide.
  2. evals/protocol.json — three prompts on the node-vs-props-vs-properties decision, +450, paid by OUI-B-08 (the eval set covers 11 of 12 guides and 0 of 4 rules files; no token ratchet in this repo, so a new fixture file is allowed here).
  3. (Tooling, separate follow-up card — not this flight) the os:check fence-marker convention + a port of objectstack's check-skill-examples.ts: 123 TypeScript fences are checked by nothing.

Flight scope

IMPLEMENT, split-by-file allowed with a report, as separate commits so the maintainer can drop any one: (a) contributor-only content OUT of the customer bundle — guides/console-development.md and rules/no-touch-zones.md move to a repo-internal skill under .claude/skills/ (new directory, user-invocable: false, a one-line pointer where the router listed them; also governed, same PR), the monorepo halves of architecture.md / project-setup.md / testing.md / README.md:45-97 deleted; (b) the gantt kitchen-sink moved to packages/plugin-gantt/README.md; (c) the four duplicate clusters merged into their rules/* anchor with pointers; (d) the 11 vestigial frontmatters deleted; (e) cross-package duplicates (C-01 → objectstack-ui, C-02 → objectstack-data, C-03 → objectstack-formula) deleted with one-line pointers; (f) the router first in SKILL.md with accurate trigger phrasing for the two under-described guides; (g) every correctness item above; (h) additions 1–2. Update scripts/skills-path-baseline.json only if check:skills-paths demands it.

DEFER: OUI-E-01 (gate port → a follow-up domain:skills card in this repo, filed by the dev as out-of-scope); OUI-A-01/A-02 (cross-repo routing with objectstack-ui → "follow-up" note); OUI-F-03 (@object-ui/runner / collaboration retire-surface → one row each, never the last mention).

Flight constraints (binding)

  • Draft PR(s) against objectui main, first line Fixes #<this card> on the closing one (Part of #<this card> on earlier splits); governed ⇒ stays draft; ⛔ never mark ready; review requests are the seat's step.
  • ⛔ Never edit objectstack files; a missing/weaker anchor there goes in the PR body under "follow-up for ".
  • No token ratchet here — the discipline is the value gate: every ADD paid by a deletion in the same package; report per-file token delta (ceil(utf8 bytes/4)) before/after.
  • Gates: pnpm check:skills-paths, pnpm lint, pnpm type-check (this repo's spelling), the doc gates the changed paths trigger, plus the repo's check:governed-queue-guard --test <paths> (its exit 3 is the governed verdict, not a red); record the head sha. Changeset: objectui has no skip-changeset label — an empty-frontmatter changeset if the repo's rule asks for one on a skills/** change, ⛔ never request a label.
  • PR body: per-item 落点 | before | after keyed by finding id; per-file token delta; moved-file map; needs:contract-review on both carriers (G-02/G-03 are renderer-contract claims).

Refs: objectstack#14292 (anchor) · objectstack#14296 (batch-1 decisions) · objectstack#13658 / #7094 (truth sweep) · #7097 (breakpoint gate candidate).

Activity

  1. self-assigned this
    on Sep 2, 2026
  2. os-litant commented on Sep 2, 2026

    @os-litant
    CollaboratorAuthor

    Claim: PM loop round 4
    Session: session_01LraLgQVGq8egUwfYZpbYt1
    Branch: claude/issue-7251-skills-objectui-optimization
    Worktree: objectui-issue-7251
    Domain: domain:skills
    File surface: skills/objectui/** (published; governed by ruling 批 #7, ui#6866) + a NEW repo-internal skill directory under .claude/skills/ for the contributor-only content moved out of the customer bundle (user-invocable: false; also governed) + packages/plugin-gantt/README.md (the gantt kitchen-sink's new home) + scripts/skills-path-baseline.json only if check:skills-paths demands; ⛔ no objectstack file (a missing or weaker anchor there is a "follow-up for" line in the PR body); ⛔ no other objectui surface
    Container & model: L (29 files, 64,022 tokens; moves across three destinations; three eval corrections; two funded additions), mode:subagent, model: opus — objectui has no dispatch-gates.mjs --tier mandate for skills/**; the content limb applies, compensated by the seat's in-seat review at CONTRACT_REVIEW_TIER
    Clause-②: yes — OUI-G-02 (getGanttConfig reads schema.gantt / flat schema.*, never schema.props) and OUI-G-03 (${...} on title / label / value / description IS evaluated on declaring types via EXPRESSION_BINDABLE_TEXT_KEYS_BY_COMPONENT) are renderer-contract claims ⇒ needs:contract-review on both carriers at PR creation; in-seat review before any human review request
    Serial constraints cleared: no open objectui PR touches skills/objectui/** or .claude/skills/**; cross-package pointers go to objectstack-ui (C-01; its entry file is held by objectstack#14568 but the anchor sections exist on main), objectstack-data (C-02: rules/field-types.md / the *When predicate rows), objectstack-formula (C-03: ## Surfaces that take an Expression, on main and on the delivered #14563 branch); heavy slots: objectstack#14315 i18n + #14316 formula (patch round) + this = 3 ⇒ the cap
    Decision inputs: objectstack#14296 ruled 1A 2A 3A 4A (item 2's stub rule does not apply here — objectui's evals are real fixtures and three of them are corrected, not deleted); objectstack#14568 (split condition) does not bind this repo — objectui has no token ratchet, the discipline is the value gate with per-file deltas reported.

    Landing form: the closing PR opens with Fixes #7251 (the DEFER rows are follow-up cards / notes, not a second round on this card); earlier split PRs, if any, Part of #7251. Governed ⇒ draft; ⛔ never mark ready; objectui has no skip-changeset label — an empty-frontmatter changeset only if the repo's rule asks, ⛔ never request a label.


    Generated by Claude Code

  3. os-litant commented on Sep 2, 2026

    @os-litant
    CollaboratorAuthor

    Dev claim (os-dev seat)

    Session: session_01LraLgQVGq8egUwfYZpbYt1
    Branch: claude/issue-7251-skills-objectui-optimization (pushed empty at base 4704aa4 — write-route probe green)
    Worktree: /home/user/objectui-issue-7251

    File surface I will touch (claim-declared, the serialization list for parallel agents):

    • skills/objectui/** (published, governed — ruling 批 构建一个 **Live Playground (实时演练场)** (用于展示引擎能力) #7, ui#6866)
    • ONE new repo-internal skill directory under .claude/skills/ for the contributor-only content moved out of the customer bundle (user-invocable: false; also governed)
    • packages/plugin-gantt/README.md (new home for the gantt kitchen-sink)
    • scripts/skills-path-baseline.json ONLY if check:skills-paths demands it per its own header
    • no objectstack file; no other objectui surface

    Assignee is the PM's field — not touched.

    Premise check at my base 4704aa4 (audit ref was 67dadd6): git diff --stat 67dadd6 origin/main -- skills/objectui .claude/skills is empty ⇒ the audited surface is byte-identical at my base, so every skills/objectui/** span in the audit record cites correctly here. packages/** citations are re-verified individually at 4704aa4.

    Next comment carries the full audit record verbatim (the finding-by-finding spec).


    Generated by Claude Code

  4. os-litant commented on Sep 2, 2026

    @os-litant
    CollaboratorAuthor

    audit-record — skills/objectui (read-only audit at 67dadd6)

    Verbatim contents of the seat's audit/objectui/findings.md. The GitHub body sanitizer eats
    angle-bracket-shaped fragments, so the three that appear in the source are transliterated.

    Transliteration key (source spelling on the left, as it appears below on the right):

    source written below as
    an HTML comment containing os:check, placed on the line above a fence OSCHECK-MARKER
    packages/ + an angle-bracketed name + /README.md packages/PKGNAME/README.md

    Nothing else is altered. Path/line citations are at 67dadd6; the dev seat verified
    git diff --stat 67dadd6 origin/main -- skills/objectui .claude/skills is empty, so every
    skills/objectui/** span cites identically at the branch base 4704aa4.


    Audit findings — skills/objectui/ (objectui @ origin/main = 67dadd6)

    Read-only audit. Every span cited at the pinned ref. Token unit = ceil(utf8 bytes / 4).

    Package measurement

    Files 29 (1 SKILL.md, 1 README.md, 12 guides, 4 rules, 11 evals)
    Bytes 256,089
    Tokens 64,022 (guides 45,065 · rules 8,602 · SKILL.md 2,272 · README.md 1,113 · evals 6,079)
    Largest file guides/console-development.md — 30,397 B / 7,600 tok (11.9 % of package)
    TypeScript fences 123, of which 0 carry a type-check marker
    JSON/JSONC fences 63
    Registered component types in packages/** 230 (ComponentRegistry.register('…'))
    Types named anywhere in skill text 98 / 230 (loose substring match — real coverage is lower)

    What is enforced in objectui, and what is not

    Gate Scope Covers skills/**?
    scripts/check-skills-paths.mjs + scripts/skills-path-baseline.json (pnpm check:skills-paths, CI .github/workflows/skills-paths.yml:70) in-repo paths stated in backtick code spans in prose (not fences) exist on disk YES — the only skills gate. Green: 92/93 stated path(s) resolve across 18 guide file(s); 1 baselined
    scripts/check-doc-links.mjs SCAN_ROOTS (:583-614) — content/docs, examples, docs, package/app trees, root markdown NO — there is no skills row
    scripts/check-doc-component-types.mjs DOCS_ROOT = 'content/docs'; header states it verbatim: "This gate walks content/docs and nothing else: not skills/**" (:211-213) NO
    scripts/check-doc-snippet-types.mjs DOCS_ROOT = 'content/docs' + PACKAGES_DIR READMEs (:301-302) NO
    scripts/check-doc-fence-languages.mjs content/docs + packages/PKGNAME/README.md (:144-145) NO
    Token ratchet (objectstack scripts/check-skills-token-ratchet.mjs) — DOES NOT EXIST in objectui. package.json has 60+ check:* scripts; none is a skills size/token gate. skills/objectui/ has no ceiling and can grow without paying.
    Example type-check (objectstack packages/spec/scripts/check-skill-examples.ts, marker OSCHECK-MARKER on the line above the fence) — DOES NOT EXIST in objectui. grep -rc "os:check" skills/objectui/ → zero markers; all 123 TypeScript fences are unchecked by anything.

    Net: objectui enforces path existence only. Size, prose-vs-implementation drift, fence compilability and cross-package overlap are all unenforced.

    Structure check on @object-ui/* references (as instructed). Every import { … } from '@object-ui/*' in a TypeScript fence resolves to a real package and a real export at 67dadd6 — verified for app-shell, auth, components (via export * from './ui' / './custom', packages/components/src/index.ts:74-75), core, fields, i18n, mobile, permissions, providers, react, types, layout. @object-ui/mobile (the 2026-08-31 sweep's site) does exist: packages/mobile/package.json, private=no. The remaining guides' package/export references are clean — the residue is elsewhere (OUI-F-02, OUI-H-01).


    Findings

    A — Trigger precision

    id dim file:span evidence proposal Δtok gate ①②③ conf human-floor
    OUI-A-01 A SKILL.md:3 vs /home/user/objectstack/skills/README.md:114 objectui routes outward ("Do NOT use for server-side ObjectStack concerns … those belong to the objectstack-* skills") but nothing routes inward. objectstack's catalog names objectui once, outside the Index and outside "Cross-skill routing": - [\../objectui`](…) — Studio UI (separate repo).` A customer agent on the objectstack bundle authoring a Studio app UI has no route to this package for its core task. ADD one "Cross-skill routing" row in objectstack skills/README.md naming @object-ui/* renderer work — paid by OUI-C-01 in that repo +40 / −1,200 ① yes — decides which package loads ② no ③ construct HIGH yes
    OUI-A-02 A SKILL.md:1-5 vs /home/user/objectstack/skills/*/SKILL.md frontmatters Every objectstack sibling carries license, compatibility: Requires @objectstack/spec 17.x (Zod v4 schemas) and metadata.{author,version,domain,tags}; skills/README.md:71-78 documents these as the shared contract. objectui carries name, description, user-invocable: false — no version pin, though Core Principle 1 (SKILL.md:41-43) makes @objectstack/spec binding and packages/types/package.json:95 pins ^17.0.0. ADD compatibility + metadata; paid by OUI-D-01 +60 ① yes — names the spec major being authored against ② no ③ construct HIGH yes
    OUI-A-03 A guides/*.md:1-4 (11 of 12) 11 guides carry standalone-skill frontmatter (name: objectui-app-composition, description: … Use this skill whenever …); architecture.md carries none. Only SKILL.md's frontmatter is read at load; these 11 are a second, competing router no runtime consults, whose triggers contradict SKILL.md's Quick Reference phrasing (e.g. page-builder.md:3 claims the "migrate handwritten React pages" surface that SKILL.md:113 compresses to "Page building & schema design"). Measured 6,372 B / 1,593 tok. DELETE all 11 blocks −1,593 ① no ② yes ③ n/a HIGH yes
    OUI-A-04 A guides/page-builder.md:250 "see the objectui-schema-expressions skill" — no such skill exists; it is guides/schema-expressions.md in this package. Residue of the pre-consolidation era (README.md:5). check-skills-paths.mjs cannot see it (not a path). REWRITE-AS-CONSTRUCT → [\guides/schema-expressions.md`](./schema-expressions.md)` ±0 ① yes — the pointer currently dead-ends ② no ③ n/a HIGH no

    B — Structure / progressive disclosure (central: 12 guides at full weight)

    id dim file:span evidence proposal Δtok gate ①②③ conf human-floor
    OUI-B-01 B guides/console-development.md:1-510 The largest file (7,600 tok, 11.9 %) is addressed at a maintainer of THIS repo. Its opening: "Use this skill when working on the Console application (apps/console/)" (:8). README.md:13 says the install target is the customer's .claude/skills/objectui/; a customer has no apps/console/, no packages/app-shell/src/views/metadata-admin/registry.ts (:139), and never had the "Retired names" symbols (:117-134). :10-47 is 622 tok of git archaeology over five SHAs correcting an earlier revision of the same note. :44-47 states third parties fork examples/console-starter (~100 LOC) instead. MOVE-TO repo-internal (.claude/skills/, beside the other internal skills) −7,600 ① no ② yes ③ n/a HIGH yes
    OUI-B-02 B rules/no-touch-zones.md:1-136 + SKILL.md:89-93 Whole rules file forbids editing packages/components/src/ui/**/*.tsx because scripts/shadcn-sync.js (:708-716) overwrites them. A customer install has neither path. The four-step wrapper workflow (:623-671) instructs the reader to edit this repo's source. SKILL.md:89-93 restates it as Core Principle 8. Exposes the gate's blind spot: check-skills-paths.mjs passes these paths because it checks existence in this repo — the wrong question for a published package. MOVE-TO repo-internal + DELETE SKILL.md:89-93 −937 −93 = −1,030 ① no ② yes ③ n/a HIGH yes
    OUI-B-03 B guides/architecture.md:14-90, :171-189 "Monorepo Topology" (1,140 tok) decides which package in this monorepo new code belongs in — "Pick a package by role + dependency weight" (:16), "❌ Do NOT create a package for every component" (:75). "AI Workflow Instructions" (:171-189, 234 tok): "On 'Create New Component' … 1. Type Definition: Update @object-ui/types" — a customer cannot. Customer-facing half is :84-89 + :91-126 (238 tok). REWRITE-AS-CONSTRUCT: keep :84-89, :91-126; delete topology tables + AI-workflow. Plugin/platform inventory already exists at guides/project-setup.md:58-100 −1,374 ① no ② yes ③ construct survives HIGH yes
    OUI-B-04 B guides/project-setup.md:252-339, :426-454 "Monorepo structure" (pnpm-workspace.yaml with packages/*, Turbo build order, pnpm --filter, ./scripts/setup.sh) + the 20-line vitest-invocation guard (:306-328) = 778 tok of contributor content; :319-325 is a Chinese console message quoted verbatim. Deployment (:437-444) documents apps/console/vercel.json — this repo's own deploy. DELETE :252-339, :437-444 −838 ① no ② yes ③ n/a HIGH yes
    OUI-B-05 B guides/testing.md:10-61 Pins this repo's CI: vitest.config.mts coverage thresholds (:29-30), the three inline test.projects and the heavyDomTests list (:34-46), vitest.setup.dom.tsx (:48-60). Reusable half starts at :62. DELETE :10-61 −551 ① no ② yes ③ n/a HIGH yes
    OUI-B-06 B SKILL.md:15-33, :37-39, :49-55 vs :105-129 Order buries the router. The only decision-changing construct — the guide table (:105-129, 441 tok) — sits behind 90 lines: "Strategic Positioning" marketing (:15-19, "The only library combining Low-Code speed with Shadcn/Tailwind design quality"), an in-scope list naming packages/ and apps/console (:22-25), Core Principle 0 "English-Only Codebase" (:37-39, a contributor style rule the package itself violates — OUI-G-01), Core Principle 3 "Documentation Driven Development … you MUST update … content/docs/guide/*.md" (:49-55, instructs editing this repo's docs tree). REWRITE-AS-CONSTRUCT: promote :105-129; DELETE :15-19, :37-39, :49-55 −259 + reorder ① yes — routing is the first decision each session ② partly ③ construct HIGH yes
    OUI-B-07 B guides/page-builder.md:6-39, :502-530 317 tok of framing preamble before the first authoring instruction at :42. Tail duplicates SKILL.md: :502-522 restates SKILL.md:131-151 nearly clause-for-clause (292 tok); :524-530 "Example prompts this skill should handle well" (134 tok) is eval material, and evals/page-builder.json exists. DELETE :10-39, :502-530 −647 ① no ② yes ③ n/a HIGH no
    OUI-B-08 B README.md:45-97 "Eval format" (:45-69) + "Maintenance" (:87-97) teach the maintainer how to author eval JSONs and where to add a guide. 602 tok, shipped every customer session. DELETE :45-97 −602 ① no ② yes ③ n/a MED yes
    OUI-B-09 B evals/ (11) vs guides/ (12) README.md:93-94 states the package's own invariant: "New domain area → add a guide … and an eval JSON under evals/ with the same basename." guides/architecture.md has no eval. No rules/* has one. ADD evals/architecture.json or DELETE the invariant sentence (cheaper; consistent with OUI-B-03) −20 ① no ② yes ③ n/a HIGH no
    OUI-B-10 B package-wide No dead links, no orphans. All 16 guides/*+rules/* linked from SKILL.md; all 30 relative links resolve (checked programmatically); router lists all 12 guides. Clean result. — 0 — HIGH no

    C — Cross-package redundancy

    id dim file:span evidence proposal Δtok gate ①②③ conf human-floor
    OUI-C-01 C guides/app-composition.md:13-110 vs /home/user/objectstack/skills/objectstack-ui/SKILL.md:857-893, 634-648 Verbatim duplicate of the anchor. objectui :104-107: "Prefer the object's default view over a pinned viewName; prefer URL filters … over authoring a view for one-off slices; prefer a named view over a page; use a page only for composition a single object view cannot express. Every target appears exactly once." objectstack-ui :889-893: "One-sentence rule: prefer the object's default view over a pinned viewName; prefer URL filters over authoring a view for one-off slices; prefer a named view over a page; use a page only for composition a single object view cannot express. Every target appears exactly once." The nine-member nav-item table (objectui :39-52) is objectstack-ui :636-648; the filters-slice rule (objectui :68-75) is objectstack-ui :870-878; objectstack-ui :858 credits "objectui ADR-0055" as source. A customer authoring *.app.ts loads objectstack-ui. objectui uniquely owns only column 2 of :39-52 — the runtime URL each nav type resolves to (resolveHref, packages/layout/src/NavigationRenderer.tsx). MERGE-INTO objectstack-ui (anchor survives there — it is where the *.app.ts author sits); objectui keeps a ~15-line nav-type→URL route table −1,564 +250 = −1,314 ① no ② yes ③ route table survives HIGH yes
    OUI-C-02 C guides/schema-expressions.md:258-302 vs objectstack-data/SKILL.md:250-296, objectstack-formula/SKILL.md:256-257, 417-421 visibleWhen/readonlyWhen/requiredWhen are fully taught in two objectstack packages, including the protocol-17 conditionalRequired removal that objectui restates at :289-293. Worse than redundant — divergent: objectui teaches the bare string (requiredWhen: "record.status in ['sent','paid']", :271); objectstack-data teaches the canonical tagged template (requiredWhen: P\record.status == 'paid'`, :269`). A customer loading both gets two spellings for one key. MERGE-INTO objectstack-data; objectui keeps 3 lines on the renderer-side fact only (reactive re-evaluation via resolveFieldRuleState, @object-ui/core) −686 +80 = −606 ① no ② yes ③ pointer HIGH yes
    OUI-C-03 C guides/schema-expressions.md:304-401 1,339 tok on the CEL list-view tier — conditional formatting, row-action visible/disabled, SelectOption.visibleWhen, field.dependsOn, options-vs-lookup. All CEL over record.* evaluated by @objectstack/formula (:309-313 says so), i.e. objectstack-formula/-data ground. Renderer-side residue worth keeping is narrow: fail-open vs fail-closed (:300-302, :347-348) and the legacy-shape translation with its one-time deprecation warning (:332-337). MERGE-INTO objectstack-formula; keep ~15 lines −1,339 +200 = −1,139 ① no ② yes ③ construct MED yes
    OUI-C-04 C guides/data-integration.md:66-95 vs objectstack-query QueryParams ($select/$filter/$orderby/$skip/$top/$expand/$search/$count) is objectstack-query's vocabulary. objectui's version adds one thing the anchor cannot: the index signature [key: string]: any (:79) is why an unprefixed limit type-checks and is then dropped (:442). Keep — the $-prefix trap is renderer-side and decision-changing. ADD a one-line "full query semantics → objectstack-query" pointer instead of expanding +15 ① yes (the trap) ② no ③ n/a MED no
    OUI-C-05 C guides/auth-permissions.md:122-251 vs objectstack-data (sharingModel / RLS) @object-ui/permissions is genuinely client-side and distinct from server RLS. But nothing in either package tells an ObjectStack customer which to author, and :193-205 shows the trap: RowLevelPermission.filter is returned verbatim and uninterpolated, so 'ownerId = ${user.id}' reaches the caller as literal text. Two permission models, no routing sentence. ADD one routing sentence at :122; paid by OUI-D-02 +35 ① yes — decides which model to author ② no ③ n/a MED yes

    D — Density

    id dim file:span evidence proposal Δtok gate ①②③ conf human-floor
    OUI-D-01 D guides/page-builder.md:356-458 2,195 tok — one plugin of 19 takes 33 % of the page-builder guide. A 35-line maximal Gantt JSON (:356-391) then four config tables and six prose paragraphs covering resourceView, capacity, autoZoomToFilter, persistLayout, mobileReadOnly, markers, PNG/PDF export, the 定位 locate icon and 闪烁 pulse. Not a canonical example — a feature manual for @object-ui/plugin-gantt. Its three sibling plugins get 4-9 lines each (:313-354). MOVE-TO packages/plugin-gantt/README.md; keep a 10-line minimal gantt node beside kanban/form/grid −2,195 +120 = −2,075 ① no — 19 of 20 readers never author a gantt ② yes ③ minimal example survives HIGH yes
    OUI-D-02 D guides/console-development.md:10-47 622 tok of commit archaeology: five SHAs (c1e105793, 28ffe4033, b279d80d6, cccdf84d7, ff9a0d9e9), a date range, and a paragraph correcting an earlier revision of this same note. :42-43 ("Look in packages/app-shell first. Grep before you assume a path") is the whole actionable content. DELETE :14-39 −500 ① no ② yes ③ n/a HIGH no (subsumed by OUI-B-01)
    OUI-D-03 D guides/console-development.md:117-134 "Retired names — do not import these": 18 rows / 741 tok of symbols deleted from apps/console, each with rationale prose ("Deleted (cccdf84d7, 26 lines)", "195 lines when it landed, 317 when it went", "Worth knowing before deciding that a ROADMAP.md line naming it was invented rather than stale"). A customer never imported any of them. DELETE −741 ① no ② yes ③ n/a HIGH yes (retired semantics)
    OUI-D-04 D SKILL.md:142-151 + guides/page-builder.md:513-522 "Fast Triage Playbook for Ambiguous Requests" — four generic steps and the closer "This keeps momentum while inviting focused user feedback." Generic agent behaviour, stated twice. DELETE both −210 ① no ② yes ③ n/a MED no
    OUI-D-05 D SKILL.md:155 **You are the Architect. Build the Engine.** — persona flourish; the reader builds an app, not the engine. DELETE −15 ① no ② yes ③ n/a HIGH no
    OUI-D-06 D rules/styling.md:112-128 17 lines of "Why" rationale for the colour carve-out ending "Read that rationale as the test." The operative test is already stated at :108-110 ("any inline style that hard-codes a colour such that dark mode renders identically"); :120-123 restates it a third time. DELETE :112-123; keep the scope sentence :125-128 −220 ① no — :108-110 decides every case ② yes ③ the test is the construct MED no

    E — Constructs & examples

    Top-5 real authoring tasks, derived from the corpus (437 JSON schemas under examples/schema-catalog/src/schemas/, apps/console, apps/site) by walking every "type" key — not from any table of contents:

    Rank Real authoring task Evidence ONE canonical copy-pasteable example?
    1 Compose a page from layout + text primitives text ×702, flex ×248, stack ×153, box ×84, container ×15 NO — flex/stack/box/container get 0 mentions package-wide (OUI-F-01)
    2 Build a form form ×81, input ×48, label ×45, select ×24, checkbox ×12, textarea ×9 Partial — object-form node at page-builder.md:333-344; no guide for the form/fields schema itself
    3 Build a card / KPI surface card ×93, statistic ×29, metric-card ×11, metric ×5 YES for card/statistic (page-builder.md:201-223); metric-card unmentioned
    4 Wire a data grid / table grid ×26, data-table ×5, plugin object-grid YES — page-builder.md:313-331, with the field-vs-name construct
    5 Wire a DataSource + provider 36 files importing SchemaRenderer across apps/+examples/ YES — data-integration.md:97-153
    id dim file:span evidence proposal Δtok gate ①②③ conf human-floor
    OUI-E-01 E package-wide (123 fences) Zero OSCHECK-MARKER markers; no check-skill-examples.ts equivalent. check-skills-paths.mjs:120-122 deliberately excludes fences ("A fence is a worked example"), so no gate reads inside a single code block in this package. 123 TypeScript + 63 JSON fences, all unverified. ADD the marker convention + a port of the objectstack gate — highest-leverage structural addition; paid by OUI-B-01 +0 (tooling) ① yes — it is what stops the 121-site sweep recurring ② no ③ construct HIGH yes
    OUI-E-02 E guides/page-builder.md:356-391 The package's largest single example (35 lines) is a kitchen sink: 20 optional keys set at once, so the reader cannot tell which three are required until :393 says so afterwards. Also carries Chinese labels (OUI-G-01). REWRITE-AS-CONSTRUCT: required-three-keys minimal fence (in OUI-D-01) ① yes ② no ③ yes HIGH no
    OUI-E-03 E guides/plugin-development.md:52, 151, 307, 420 vs packages/types/src/plugin-scope.ts:49-54 The guide teaches registration only as ComponentRegistry.register(...). The real plugin-scoped API PluginScope.registerComponent(type, component, meta?) — documented in the implementation's own docblock (plugin-scope.ts:49) — is never mentioned. evals/plugin-development.json requires registerComponent in two of three answers (OUI-H-02), so the package's own eval contradicts its guide. ADD a 4-line registerComponent row; paid by OUI-B-07 +60 ① yes — it is the API a plugin author actually gets ② no ③ construct HIGH no

    F — Gaps vs real usage

    id dim file:span evidence proposal Δtok gate ①②③ conf human-floor
    OUI-F-01 F absent from skills/objectui/** The three most-used layout primitives are undocumented. Across all 437 catalog schemas: flex 248, stack 153, box 84, container 15. All real registered types (packages/components/src/renderers/layout/flex.tsx:14, box.tsx:63, container.tsx:107). Grepping the package for each → 0. SKILL.md:81 names "Grid, Stack, Container" as English nouns in a sentence about columns, never as authorable type strings, and gives no props. A customer authoring a page reaches for flex first; the package is silent. ADD one layout-primitive table (flex/stack/box/container/grid — type, key props, when to pick which); paid by OUI-B-03 or OUI-D-01 +250 ① yes — the #1 authoring decision by volume ② no ③ construct HIGH no
    OUI-F-02 F README.md:81-85, guides/architecture.md:29-71 Two real, used packages absent from every inventory: @object-ui/sdui-parser (14 importing files in apps/+examples/) and @object-ui/react-runtime (5). Neither appears in README.md's "Coverage map" (which claims "The skill stays in sync with the packages/ tree", :79) nor in architecture.md's four package tables. @object-ui/test-support is also absent — correctly, it is private=yes. ADD two rows, or DELETE the "stays in sync" claim +30 or −25 ① marginal ② yes ③ n/a HIGH no
    OUI-F-03 F guides/architecture.md:35, 88; guides/project-setup.md:405-413, 424 Speculative surface. @object-ui/runner has 0 importing files across apps/** and examples/** (grepped @object-ui/runner, excluding node_modules), yet occupies 4 documented positions including a decision-matrix row. Zero usage in examples is evidence, not proof — it is private=no — but a removal candidate under startup focus. @object-ui/collaboration: 3 files, listed in README.md:83, architecture.md:46, project-setup.md:90, with no guide and no example anywhere. RETIRE-SURFACE or compress each to one inventory row −180 ① no ② yes ③ n/a MED yes
    OUI-F-04 F guides/architecture.md:36 "@object-ui/data-* … Connectors for REST, ObjectQL, GraphQL (e.g. @object-ui/data-objectstack)" — the plural family implies siblings. Only packages/data-objectstack/ exists. data-integration.md:359-421 correctly tells the reader to hand-write a RestApiAdapter. REWRITE-AS-CONSTRUCT → name the one package, point at the hand-written-adapter recipe −20 ① yes — stops a search for a package that is not there ② no ③ n/a MED no
    OUI-F-05 F guides/project-setup.md:186-203 CLI table lists 14 commands. Enumerated from packages/cli/src/** .command('…'): add analyze build check create dev doctor generate init lint serve start studio test validate = 15 real; the table's objectui create plugin maps to create. Every documented command resolves. Clean result. — 0 — HIGH no

    G — Consistency

    id dim file:span evidence proposal Δtok gate ①②③ conf human-floor
    OUI-G-01 G guides/page-builder.md:379-381, 401-409, 418-425, 434, 445, 448-450, 452-457; guides/project-setup.md:319-324 The package violates its own Core Principle 0. SKILL.md:37-39: "ALL user-facing text in components, documentation, comments, and UI labels MUST be written in English. Do NOT use Chinese … in … doc files"; README.md:96: "All authored text … must be English-only". CJK byte-range grep: ~25 lines carrying Chinese outside i18n.md (where it is legitimate demo data). In a JSON fence a customer would copy: { "field": "status", "label": "状态" } (page-builder.md:379). In prose: "remove it (移除依赖), or right-click a bar for 添加紧前/添加紧后依赖" (:401-402). In a table cell: "Marks a row view-only / 仅查看" (:424). And a whole quoted console block at project-setup.md:319-324 (vitest 调用被拒绝…正确跑法 —— 一律在【仓库根目录】执行). REWRITE-AS-CONSTRUCT (translate) — most leaves anyway under OUI-D-01 and OUI-B-04 ~−40 ① yes — a copied "label": "状态" ships Chinese into an English app ② partly ③ n/a HIGH yes
    OUI-G-02 G guides/page-builder.md:415-416 vs packages/plugin-gantt/src/ObjectGantt.tsx:508-545 and rules/protocol.md:94-147 "The gantt field config may also be hoisted to top-level props instead of nesting under gantt." Contradicts the package's own central rule — stated four times — that props is never read by a ui:*/page:* renderer. Implementation: ObjectGantt takes schema: ObjectGanttSchema only (:268-288); getGanttConfig reads schema.gantt, else flat keys off schema.* (:526-545); schema.props is never read. The source comment calls that branch "The internal flat form — the ObjectView / ListView flatten product", i.e. not an authoring face. The same guide says "top-level" correctly 12 lines later (:427-428). REWRITE-AS-CONSTRUCT: "…hoisted onto the node (the internal flatten shape — prefer the gantt block)" ±0 ① yes — teaches the one spelling the package elsewhere forbids ② no ③ n/a HIGH yes
    OUI-G-03 G guides/schema-expressions.md:649 vs :47 (same file), rules/protocol.md:22, 65-92, guides/page-builder.md:191, 236-244 Debugging checklist step 1: "A ${...} on title / label / value / description is never evaluated". Contradicted 600 lines earlier in the same file (:47): those four keys are template-evaluated on the declaring types — statistic (label/value/description), card (title/description), button (label) — a closed set read from EXPRESSION_BINDABLE_TEXT_KEYS_BY_COMPONENT in @objectstack/spec/ui, pinned by packages/react/src/__tests__/SchemaRenderer.bindableTextKeys.test.tsx:50-54, 107. An agent debugging with the checklist will "fix" working schemas. REWRITE-AS-CONSTRUCT: "…evaluated only on the declaring types (statistic/card/button), read raw everywhere else" ±0 ① yes — the checklist is the last thing read before acting ② no ③ n/a HIGH yes
    OUI-G-04 G package-wide Brand spelling split: "Object UI" ×62 vs "ObjectUI" ×54. Every rules/*.md and SKILL.md use ObjectUI; every guide frontmatter and most guide prose use Object UI; all 11 eval JSONs use Object UI in prompts. REWRITE-AS-CONSTRUCT: normalise to ObjectUI (the npm / SKILL.md spelling) ±0 ① no ② no ③ n/a HIGH no
    OUI-G-05 G guides/testing.md:363 vs guides/data-integration.md:87 MSW mock returns { records: [...], total: 1 }; the sibling guide states QueryResult.data is "required, and NOT named records". Defensible (raw server envelope ≠ QueryResult) but it is the exact spelling named as the trap, in a fence a reader will copy. REWRITE-AS-CONSTRUCT: rename to data, or annotate // raw server envelope, not QueryResult ±0 ① marginal ② no ③ n/a LOW no
    OUI-G-06 G package-wide Retired-spelling sweep (silently, ignored, dropped, legacy, deprecated, M9, v5.0, OLD, NEW, project-as-workspace): no residue. M9/v5.0/OLD/NEW → zero hits. Every silently/dropped/ignored hit describes real measured runtime behaviour. project here means a customer's code project, not an ObjectStack runtime workspace, so objectstack's environment-not-project convention does not apply. Clean result. — 0 — HIGH no

    H — Evals

    11 files, 6,079 tok, ~3 prompts each. Every must_contain token was cross-checked against (a) its own guide, (b) the whole package, (c) packages/**.

    id dim file:span evidence proposal Δtok gate ①②③ conf human-floor
    OUI-H-01 H evals/mobile.json:36-44 Tests a surface that does not exist, and would FAIL a correct answer. Eval 3 requires must_contain: ["useSwipe", "useLongPress", "@object-ui/mobile"]. grep -rn "useSwipe\b|useLongPress\b" packages/ → zero hits repo-wide. packages/mobile/src/index.ts:22-53 exports useGesture, useSpecGesture, usePullToRefresh, useBreakpoint, useResponsive, useResponsiveConfig, useTouchTarget, MobileProvider, ResponsiveContainer, BREAKPOINTS; guides/mobile.md:34-59 correctly teaches "One hook, useGesture, per gesture" with type: 'swipe-left' / 'long-press'. An answer following the guide fails; an answer inventing two hooks passes. REWRITE-AS-CONSTRUCT: ["useGesture", "swipe-left", "long-press", "@object-ui/mobile"] ±0 ① yes — it grades the package's own correct answer wrong ② no ③ n/a HIGH yes
    OUI-H-02 H evals/plugin-development.json:14, 30; evals/page-builder.json eval 1 Three evals require registerComponent, absent everywhere in the package (guides teach ComponentRegistry.register). It is real (packages/types/src/plugin-scope.ts:54) but untaught — OUI-E-03. Evals 1 and 3 also require FieldWidgetProps, whereas guide and implementation both use FieldWidgetComponentProps (plugin-development.md:240, 268-271); the assertion passes only by accidental substring match on FieldWidgetPropsSchema (:282). REWRITE-AS-CONSTRUCT (align to ComponentRegistry.register + FieldWidgetComponentProps) and ADD the registerComponent API per OUI-E-03 ±0 ① yes ② no ③ n/a HIGH yes
    OUI-H-03 H evals/page-builder.json eval 2 must_contain: ["visible", "props", "admin", "section"]. Requiring the literal token props in a passing answer inverts the package's most-repeated hard rule — "Keys Live on the Node, Not in a props Envelope" (rules/protocol.md:94-147), restated at page-builder.md:87-94, schema-expressions.md:64-74, data-integration.md:263-267. An answer that correctly keeps every key on the node and never writes props fails this eval. (section is also absent from page-builder.md.) REWRITE-AS-CONSTRUCT: drop props from must_contain; move it to must_not_contain ±0 ① yes — trains the grader against the package's central rule ② no ③ n/a HIGH yes
    OUI-H-04 H evals/app-composition.json evals 1-4 All four require the literal JSON-quoted "type": "object". The guide writes the shape as {type:'object', objectName} throughout (app-composition.md:41-44, 56, 61) — single quotes, no space. A correct answer copying the guide's own spelling fails all four. Brittle string matching, not a decision test. REWRITE-AS-CONSTRUCT: assert objectName + navigation + viewName ±0 ① yes ② no ③ n/a HIGH no
    OUI-H-05 H evals/mobile.json:14; evals/project-setup.json eval 3; evals/testing.json eval 2; evals/page-builder.json eval 3 Four more assertions require tokens absent from their own guide: sidebar (0 occurrences in guides/mobile.md), ComponentRegistry (absent from guides/project-setup.md), edit (absent from guides/testing.md), refresh (absent from guides/page-builder.md). Each grades a decision the guide never teaches. REWRITE-AS-CONSTRUCT per row, or drop the token ±0 ① yes ② partly ③ n/a HIGH no
    OUI-H-06 H evals/console-development.json (698 tok) vs guides/console-development.md (7,600 tok) Proportionality: the eval set (6,079 tok) tests 11 of 12 guides and 0 of 4 rules files — including rules/protocol.md, whose props/properties/bindable-keys contract is the package's densest, most error-prone surface and the subject of three separate in-package restatements. ADD evals/protocol.json (~3 prompts, ~450 tok) targeting the node-vs-props decision; paid by OUI-B-08 (−602) +450 ① yes — the decision the package most exists to change ② no ③ construct MED no

    I — Size proportionality

    id dim file:span evidence proposal Δtok gate ①②③ conf human-floor
    OUI-I-01 I package-wide 64,022 tok against 5 distinct high-frequency real authoring tasks (E) and 230 registered types of which ~98 are named at all. ~12,000 tok (19 %) is addressed at a contributor to this repo rather than any customer (OUI-B-01…B-05, B-08); ~5,400 tok (8 %) is in-package duplication (OUI-I-02, I-03); ~3,000 tok (5 %) restates objectstack anchors (OUI-C-01…C-03). Two of four rules/ files are load-bearing (protocol.md, styling.md); one is repo-internal (no-touch-zones.md). No token ratchet exists to have caught any of it. Structural — see verdict ≈ −21,600 (−34 %) per row HIGH yes
    OUI-I-02 I 4 duplication clusters The same rule is stated up to four times. ① Stylesheet imports + @theme/@source split ×4: anchor rules/styling.md:260-316 (685) + guides/page-builder.md:252-304 (646) + guides/project-setup.md:124-164 (474) + SKILL.md:139-140 (199) — and SKILL.md:140 even says "do not keep a second copy of the answer here" while being the second copy. ② Expression-evaluation boundary table ×3: anchor rules/protocol.md:5-43, 94-147 + guides/schema-expressions.md:28-100 (968) + guides/page-builder.md:173-250 (934). ③ data-table / useDataScope reader trap ×3: anchor rules/protocol.md:193-212 (357) + guides/schema-expressions.md:421-451 (307) + guides/data-integration.md:203-231 (323) — the last two share the Ada Lovelace / Grace Hopper fixture verbatim. ④ columns breakpoint object + 2xl dropped ×3: anchor rules/protocol.md:264-296 (352) + SKILL.md:81 (~90) + guides/mobile.md:101-107 (113). MERGE-INTO the rules/* anchor in each cluster; leave a one-line pointer where the guide needs the cue −1,319 −1,902 −630 −203 = −4,054 (+~200 pointers) ≈ −3,850 ① no — the anchor already decides ② yes ③ pointer HIGH yes
    OUI-I-03 I guides/*.md:1-4 ×11, plus :8 openers ×12 Vestigial standalone-skill framing: 11 frontmatter blocks (1,593 tok, OUI-A-03) plus twelve "Use this skill to …" openers (page-builder.md:8, testing.md:8, mobile.md:8, i18n.md:8, plugin-development.md:8, project-setup.md:8, auth-permissions.md:8, console-development.md:8, data-integration.md:8, schema-expressions.md:8, plus page-builder.md:10-32's "When to use this skill"). These are files inside one skill, not skills. DELETE frontmatters; rewrite openers as one-line scope statements −1,593 −180 = −1,773 ① no ② yes ③ n/a HIGH yes

    Incidental falsehoods

    (By-product of this audit. The 2026-08-31 sweep is not being redone.)

    # file:span claim measured truth
    1 guides/page-builder.md:415-416 "The gantt field config may also be hoisted to top-level props instead of nesting under gantt." ObjectGantt accepts schema: ObjectGanttSchema only (packages/plugin-gantt/src/ObjectGantt.tsx:268-288). getGanttConfig (:508-545) reads schema.gantt, else the flat keys off schema.*; schema.props is never read. The flat branch's own comment calls it "The internal flat form — the ObjectView / ListView flatten product". The word is node, not props — and the same guide says so correctly at :427-428.
    2 guides/schema-expressions.md:649 "A ${...} on title / label / value / description is never evaluated" False on the declaring types, and contradicted by :47 of the same file. EXPRESSION_BINDABLE_TEXT_KEYS_BY_COMPONENT (@objectstack/spec/ui) declares statistic → label/value/description, card → title/description, button → label; pinned by packages/react/src/__tests__/SchemaRenderer.bindableTextKeys.test.tsx:50-54, 107.
    3 README.md:79 "The skill stays in sync with the packages/ tree" + a 5-group coverage map @object-ui/sdui-parser and @object-ui/react-runtime are published (private=no) and imported in 14 and 5 files across apps/+examples/; neither appears in the map or anywhere in the package.
    4 guides/architecture.md:36 "@object-ui/data-* … Connectors for REST, ObjectQL, GraphQL" Only packages/data-objectstack/ exists. No data-rest, no data-graphql.
    5 evals/mobile.json:36-44 asserts useSwipe / useLongPress are the mobile gesture API Zero occurrences in packages/**. The API is useGesture with a type discriminator (packages/mobile/src/index.ts:25).

    Generated by Claude Code

  5. os-litant commented on Sep 2, 2026

    @os-litant
    CollaboratorAuthor

    os-dev-report

    {
      "issue": 7251,
      "status": "done",
      "branch": "claude/issue-7251-skills-objectui-optimization",
      "pr": "https://github.com/objectstack-ai/objectui/pull/7370",
      "premise_still_valid": true,
      "summary": "skills/objectui went from 64,023 to 43,679 tokens, -20,344 (-31.8%), 29 files to 27, in 12 commits, one per cluster. IMPLEMENT (a)-(h) all landed: console-development.md and no-touch-zones.md moved to a new .claude/skills/objectui-contributor/ (user-invocable false); the contributor halves of architecture/project-setup/testing/README deleted; the gantt feature manual moved to packages/plugin-gantt/README.md with a minimal node left behind; three of four in-package duplicate clusters merged into their rules/* anchor; 11 vestigial frontmatters (6,372 B, matching the audit exactly) deleted; C-01/C-02/C-03 replaced by pointers to objectstack-ui, -data and -formula anchors verified BY CONTENT on objectstack origin/main; the router promoted to first in SKILL.md; every funded correctness item corrected at source; the layout-primitive table and evals/protocol.json added. ONE finding is premise_false and was reverted, see below. TWO deviations from the audit's proposals were forced by objectui gates the audit did not measure, both declared in the PR body. Assignee untouched; the PM's claim was already on the card.",
      "premise_false": [
        "OUI-I-02 cluster 3 (data-table / useDataScope reader trap, x3) — merged, then REVERTED byte for byte from 96655c5. The two guide spans are not prose duplicates: packages/components/src/__tests__/skill-guide-data-table-binding.test.tsx lifts them off disk at run time, renders the data-table block through the real SchemaRenderer and asserts the four Ada/Grace body cells, and extracts the seven object-* names from the literal sentence 'the plugin packages register (...)' to assert each is registered by exactly one plugin package reading useDataScope(schema.bind) — with an explicit counter-probe against a vacuous pass. The merge turned 5 assertions red. The test's docblock states the intent: 'the guides are executable fixtures ... Keep it that way.' The other three I-02 clusters stand; verified by git grep -ln skills/objectui -- ':!*.md' ':!skills/**' then running every test it names."
      ],
      "deviations": [
        "OUI-A-02 — compatibility carries NO version literal. scripts/__tests__/doc-version-claims.test.ts (covers skills/, objectui#4981; objectstack has no equivalent, which is why the siblings can freeze a number) refused 'Requires @objectstack/spec 17.x (Zod v4 schemas)' and named the remedy: 'Prefer DELETING the literal and pointing at the truth instead'. The field points at the manifests. A KNOWN_CLAIMS entry was rejected — registering an unverifiable claim is what that ratchet exists to stop.",
        "OUI-H-03 — props moved to must_not_contain spelled as the JSON envelope '\"props\": {', not the bare word. A bare props there would fail any answer that NAMES the rule while following it, which is the same defect pointing the other way."
      ],
      "file_surface_supplement": "scripts/__tests__/check-skills-paths.test.ts — outside the dispatch's declared surface, taken under the bounded in-place rule and named with evidence in the PR body. Forced by the ruled move: the checked floor '> 50' cannot survive a scan that legitimately dropped to 27 (it is '> 20' with the arithmetic recorded), and the objectui#3713/#3730 block read the moved guide through repoRoot (ENOENT) and asserted a baseline entry the gate itself demanded be deleted. It landed inside b38ee5e via a stale index entry rather than its own commit; 72f650e carries the rationale rather than rewriting a pushed commit.",
      "tests": "All heavy steps serialized through scripts/pm/os-verify-lock.sh (one queue-timeout exit 99, resumed on the same OS_VERIFY_LOCK_SLOT). Gates run AFTER the final commit, on head 72f650e, exit codes captured before any pipe, verdict lines quoted from the gates themselves: check-skills-paths exit 0 'OK (27/27 stated path(s) resolve across 16 guide file(s))' (was 92/93 across 18 at base); check-doc-links exit 0 'Links are valid across 17 scan roots.'; check-control-bytes exit 0 'OK (scanned 6054 tracked text file(s); skipped 85 binary)'; check-doc-fence-languages exit 0; check-changeset-presence exit 0 'No source or published contract of a released package changed in this range, so no changeset is owed.'; check-shell-escape-residue exit 0; check-governed-queue-guard --self-test exit 0 '132 cases pass'; check-governed-queue-guard --test over all 31 changed paths exit 3 'GOVERNED — 28 of 31 path(s) are on a governed surface' (the correct governed verdict, not a red); pnpm type-check:scripts exit 0, and tsc --listFiles confirms check-skills-paths.test.ts IS in that program, so it is a measurement and not the excluded-tests NOT-MEASURED trap. vitest: scripts set 'Test Files 6 passed (6), Tests 155 passed (155)'; the eight tests that read skills/objectui/** 'Test Files 8 passed (8), Tests 115 passed (115)' — that same set read 5 failed / 110 passed before the cluster-3 revert, and doc-version-claims read 1 failed / 123 passed before the compatibility fix, so both reds were real measurements, not template. No ablation was run: nothing in this diff is a guard whose failure needed proving. pnpm lint NARROWED, declared with all three readings: population from eslint's own config (files ['**/*.{ts,tsx}'] plus the ignore list) makes exactly 1 of the 31 changed paths lintable, the other 30 being .md/.json; --format json reports 1 file, 0 errors, 0 warnings; eslint.config.js sets no parserOptions.project and no projectService, so linting is not type-aware and this diff cannot move any untouched file's verdict. Repo-wide eslint is CI's run.",
      "mcp_calls": "14 — 2 issue comments (claim, audit record) + 3 search_issues (dedupe, each targeted) + 5 issue_write create (follow-up cards) + 1 get_label + 1 create_pull_request + 1 pull_request_read (PR body read-back; the PR page has no SSR payload block, unlike an issue page) + 2 issue_write update (label union writes). This report comment makes 15. Bulk reads went to the zero-quota channels: git for the trees, the issue-page embedded JSON payload for the card body, all comments, and both label compare-read-backs. REST is 403 for this session ('GitHub access is not enabled for this session') and gh is absent, so every write went through MCP — declared channel switch.",
      "open_questions": [],
      "out_of_scope_findings": [
        "filed as #7358: check-skills-paths lost 55 of its 93 assertions (49 + 6) when the two guides left SCAN_ROOT — widen it to cover .claude/skills; the gate was built for console-development.md (#3713/#3730), still 49 coordinates deep and now unguarded",
        "filed as #7359: no gate reads inside a code fence in skills/objectui — 123 TypeScript and 63 JSON fences, zero os:check markers (the flight's DEFER row OUI-E-01)",
        "filed as #7360: six more eval assertions grade tokens their guide never teaches (OUI-H-05) plus OUI-H-02's untaught registerComponent and the FieldWidgetProps substring accident, plus one NOT in the audit — evals/mobile.json eval 2 asserts useOffline while the export is useOfflineSync, passing on the substring",
        "filed as #7361 (finding): container.maxWidth's @default says 'lg' while the renderer applies 'xl', and FlexLayoutProps.align says 'center' while flex.tsx applies 'start' and stack.tsx 'stretch' — an instance of the open #4631, found while writing the layout table from the renderers instead of the types",
        "filed as #7362: content/docs/guide/agent-skills.md still draws both moved files inside the published tree and ci-cd-pipeline.md describes a baseline entry that no longer exists — outside this flight's file surface",
        "follow-up for objectstack-ui (OUI-A-01, no card — objectstack is read-only for this seat): objectui routes outward but nothing routes inward; objectstack's skills/README.md names objectui once, outside its Index and outside Cross-skill routing",
        "follow-up for objectstack-ui / objectstack-data (OUI-C-05, no card, same reason): two permission models, client-side @object-ui/permissions and server RLS, with no sentence anywhere telling a customer which to author; RowLevelPermission.filter is returned verbatim and uninterpolated"
      ]
    }

    Draft PR #7370 is open and stays draft (governed). CI was not waited on, per the standing rule that convergence is the PM's step; gate status at report time is whatever CI reports on 72f650e. Worktree removed without --force.


    Generated by Claude Code

  6. os-litant commented on Sep 2, 2026

    @os-litant
    CollaboratorAuthor

    ACCEPT — PR #7370 @ 72f650e8 (−20,344 tok, −31.8%; 29 → 27 files)

    Session: session_01LraLgQVGq8egUwfYZpbYt1 (skills lane seat)

    Verified against GitHub, not the report:

    Contract review (needs:contract-review, both carriers) — done in-seat at the contract-review tier: PASS. Each claim checked at source on this base, not carried from the audit:

    claim verdict evidence
    OUI-G-02 — the gantt config is read from the node, never hoisted props PASS getGanttConfig reads schema.gantt, else the flat keys off schema.* (packages/plugin-gantt/src/ObjectGantt.tsx:509-513); no .props read in the file
    OUI-G-03 — ${...} on title/label/value/description IS evaluated on declaring types PASS EXPRESSION_BINDABLE_TEXT_KEYS_BY_COMPONENT (@objectstack/spec/ui), pinned by packages/react/src/__tests__/SchemaRenderer.bindableTextKeys.test.tsx (statistic, card, button; negatives text, ui:statistic)
    OUI-H-01 — the gesture API is useGesture PASS packages/mobile/src/index.ts:25; useSwipe / useLongPress have zero hits under packages/
    OUI-F-01 — layout-primitive defaults as the renderers apply them PASS flex row / start / start / gap 2; stack column / stretch / gap 2; grid gap 4; container maxWidth xl; box className verbatim — read from the renderer sources, which is why they differ from the JSDoc (#7361 records the JSDoc side)

    Per the 2026-08-31 ruling, the seat that reviewed strips the label: needs:contract-review removed from this card and from #7370 in the same stroke.

    Also accepted:

    Follow-ups filed unassigned by the dev: #7358 (check-skills-paths coverage after the move), #7359 (no fence gate / os:check port — the DEFER row OUI-E-01), #7360 (six more eval assertions grading untaught tokens + the useOffline substring accident), #7361 (layout @default JSDoc vs renderer), #7362 (content/docs/guide/agent-skills.md and ci-cd-pipeline.md still describe the moved files). Two cross-repo notes (OUI-A-01 inward routing row for objectstack's skills/README.md generator; OUI-C-05 client-permissions vs server-RLS routing sentence, needs both halves) go on the seat ledger in objectstack; they are not this PR's.

    Governed surface (skills/**, .claude/skills/**): the PR stays draft; review requested from os-zhuang and hotlong; landing is the maintainer's. Fixes #7251 closes this card on merge; the seat strips pm:dispatched then.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions