Uh oh!
There was an error while loading. Please reload this page.
skills(ui): optimization flight — date macros/relationships pointed at their anchors, searchableFields and timeSegments cut, dashboards consolidated, retired widget keys removed (net −2,585 tokens) - #14338
Merged
Conversation
…e/drilldown trims, filterBindings + widget options funded
UI-C-01 delete the date-macro + context-token block; keep the heading (two
in-file anchors resolve to it) and point at objectstack-query
rules/filters.md. Two UI-owned rules stay: presentation-scope-not-
security, and AppContextSelector ids never resolving in a filter.
UI-C-02 drop the org-isolation narration; keep the blessed-name pointer at
objectstack-data's hooks reference. `ctx.session.positions` stays in
compact form -- the anchor does not carry it (see PR follow-up list).
UI-D-08 Cube Best Practices -> the two enforced facts.
UI-D-05 delete the renderer note that ends by telling the reader to ignore it.
UI-D-06 delete the v17 `compareTo` removal narration.
UI-B-03 move the dateGranularity bucket table out of `### Drilldown` and under
its own heading (reorder only).
UI-G-02 falsehood 2: the dataset dimension is the DEFAULT; options.dateGranularity
overrides it per widget (dashboard.zod.ts:217-225).
UI-E-02 falsehood 1: delete the retired `actionType`/`actionUrl` pair from the
canonical dashboard widget (dashboard.zod.ts:382-384, retiredKey =
z.never()).
falsehood 4 (found in span, same defect class): `{current_user.id}` ->
`{current_user_id}`; `current_user.id` is the RLS expression root, not
a filter token (spec/src/data/context-tokens.zod.ts:44,49,85).
UI-F-01/F-03 ADD the globalFilters/filterBindings construct (paid by D-05+D-06).
UI-F-02 ADD the five declared widget `options` keys (paid by D-08+D-03-to-come).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1…etired, relationships/conditional-rules pointed at objectstack-data
UI-D-01 keep the two tables and the `userActions: { search: false }` example;
delete the two verbatim `os validate` diagnostics, the empty-array
essay (folded into the row that already existed) and the related-title
prose (reduced to its objectstack-data pointer).
UI-D-02 delete the `timeSegments` block -- self-declared NOT part of
GanttConfigSchema, zero implementation in this repo (every hit is in
objectui plugin-gantt), and 10 of the package's 13 CJK lines.
UI-C-04 the inlineEdit ladder and the modelled grid behaviours point at
objectstack-data rules/relationships.md, which carries them verbatim.
Kept the three UI-authored facts the anchor does NOT carry: the ghost
row, `autofill: false`, and the form's `taxRateField`.
UI-C-03 delete the visibleWhen/readonlyWhen/requiredWhen table; keep the
routing line, the row-by-row inline-grid note and the retired
`conditionalRequired` guard.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1…our highest-traffic examples gated UI-A-01 add `*.page.ts` / `*.report.ts` / `*.dataset.ts` to the trigger list -- `*.page.ts` is the corpus's most-authored kind (29 definitions) and had no filename trigger at all. UI-A-02 falsehood 3: drop "the React renderer implementation (lives in packages/client-react)". That package is React hooks for the client SDK (package.json description; src/index.tsx exports hooks + provider). The renderer is @object-ui/react-runtime, in objectui. UI-A-03 wizards: a stepped form over ONE object is this skill's `formViews` `type: 'wizard'`; only step-branching flows route to automation. UI-D-07 keep the requirement, drop the removal history. UI-D-03 delete the "Why this model" justification. UI-D-04 reduce the metadata-fence rationale to the two facts the table lacks (live-not-a-screenshot; data-not-code). UI-B-06 delete "When to Use This Skill" -- it restated the frontmatter. UI-B-05 the Tailwind rule now states the rule once and points at ADR-0065. UI-G-03 translate the CJK example label. The two remaining CJK lines are non-English USER PHRASINGS the router matches on -- see the PR body. UI-E-03 inline a minimal defineAction so the record-detail page block stands alone (the relative import could never resolve in the gate build dir). UI-E-01 mark four highest-traffic examples `os:check`: structured definePage, the Dashboard literal, defineDataset, the react source tier. Gate: pnpm --filter @objectstack/spec check:skill-examples -- 259 -> 263 marked blocks, "every marked block parsed, so tsc ran the SEMANTIC pass on all of them". Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
…nd the timeSegments deletion
Two mechanical consequences, neither hand-written:
- `content/docs/ai/skills-reference.mdx` — `pnpm --filter @objectstack/spec
gen:skill-docs`. The dispatch predicted `skills/README.md` would be the file
the drift gate demands; it is not. README came back green on its own (it does
not embed the description); the out-of-date artifact is the reference page.
Both are outputs of the one generator the card names.
- `scripts/skill-identifier-liveness-ledger.json` — `node
scripts/check-skill-identifier-liveness.mjs --update`, pruning the now-stale
`dayStart` / `showMidnight` exemptions. Both existed only to excuse the
`timeSegments` block this flight deleted, and each ledger note independently
records that the implementation lives in objectui plugin-gantt -- the same
measurement UI-D-02 rests on. `--update` never ADDS an exemption.
Gates: check:skill-docs 0 (both artifacts ✓); check:skill-identifier-liveness 0
("Leg 1: 498 citations over 48 published files ... 3 ledgered exemptions").
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1…ding
In-seat contract review is right: my UI-D-08 retitle asserted enforcement that
does not exist, which is the same defect class this flight exists to remove.
Re-verified against the source, and the evidence is stronger than the review
cited:
- `granularities: z.array(TimeUpdateInterval).optional()`
(packages/spec/src/data/analytics.zod.ts:147) — optional, and the file
contains ZERO `.refine(` / `superRefine` occurrences, so nothing requires it
on a `time` dimension.
- Cube `sql: z.string().describe('Base SQL statement or Table Name')` (:216).
The describe string itself admits raw SQL; nothing rejects it at parse time,
and no gate script under scripts/ or packages/*/scripts/ references
`cube.sql`.
So there is no gate or schema refinement to cite, and the word is dropped rather
than defended. The two body items are unchanged: they are prescriptions with a
stated mechanism (`cube.sql.trim()` read as the object name), not claims of
enforcement.
Gates at this head: node scripts/check-skills-token-ratchet.mjs exit 0 --
SKILL.md 22856 tokens (ceiling 25445, headroom 2589); pnpm --filter
@objectstack/spec check:skill-examples exit 0 -- "263 prose examples type-check
across 3 surface(s)".
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1os-zhuang
approved these changes
Sep 2, 2026
os-zhuang
marked this pull request as ready for review
September 2, 2026 06:18
os-zhuang
enabled auto-merge
September 2, 2026 06:18
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Sep 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #14298
Governed surface (
skills/**) ⇒ this PR stays draft;needs:contract-reviewis on both carriers because falsehoods 1–2 are contract-semantics corrections. Head sha for every gate figure below:684415c3.Review round 1 — one FAIL, fixed
In-seat contract review flagged the UI-D-08 retitle
### Cube Rules (enforced)as asserting enforcement that does not exist. Correct, and the evidence is stronger than the review cited — re-verified at source:granularities: z.array(TimeUpdateInterval).optional()(packages/spec/src/data/analytics.zod.ts:147), and that file contains zero.refine(/superRefineoccurrences, so nothing requires it on atimedimension.sql: z.string().describe('Base SQL statement or Table Name')(:216) — the describe string itself admits raw SQL; nothing rejects it at parse time, and no gate script underscripts/orpackages/*/scripts/referencescube.sql.There is no gate or schema refinement to cite, so the word is dropped, not defended: the heading is now
### Cube Rules. The two body items are unchanged — they are prescriptions with a stated mechanism (cube.sql.trim()read as the object name), not claims of enforcement. Shipping an unbacked "(enforced)" would have been the same defect class this flight exists to remove.Open questions ruled by the seat: Q1 → C (UI-E-04 deprecated
objectName/viewType, filed by the seat as its own card — nothing done here); Q2 → A (the two CJK trigger phrases stay).Per-file token delta (ratchet convention, ceil(utf8 bytes / 4))
skills/objectstack-ui/SKILL.mdGenerated package members untouched and unchanged:
contracts/react-blocks.contract.json5,352 ·references/react-blocks.md3,153 ·references/_index.md1,205.evals/**untouched (1,102 + 289). The ceiling is left at 25,445: the ratchet header says a ceiling "may be LOWERED by any PR that shrinks its file … always legitimate and encouraged", but the card's flight constraint forbids touching the ratchet script, so the 2,589 tokens of new headroom are deliberately NOT claimed here — a follow-up may lower the row to the measurement.Against the card's target. The card targets ≈ −9,170, of which −5,352 is UI-B-04's duplicated generated JSON — explicitly DEFERRED to #14296 item 3 and not mine. The in-file target was −4,199 prose against +385 of additions; landed −2,585. The gap is itemised below rather than smoothed over: the three funded additions cost +838 against the estimated +385 (the
filterBindingsand widget-optionsconstructs are each roughly double their estimate), and UI-D-01 returned −387 against an estimated −900. Every number below is a measured byte delta.Per-item: 落点 | before | after
Deletions and merges
## Date Macros — Filter Placeholders(whole section +## Context Tokens)### Shift segmentation — timeSegmentsinlineEditladder + line-item grid behaviours### Toolbar Search (searchableFields)options.drillDownrenderer notectxorg-isolation + positions narration## When to Use This SkillcompareToblockquote### Cube Best Practices(5 items)### Cube Rules— see Review round 1metadatafence rationalevisibleWhen/readonlyWhen/requiredWhentableclassNamerestatementdateGranularitybucket table under### DrilldownThe three funded additions
### Dashboard filters — globalFilters + per-widget filterBindings: the broadcast rule,name(defaults tofield; name it for the vocabulary, not the column),scope: 'widget'+targetWidgets, re-target,falseopt-out, the absent-default incl.dateRange.field ?? 'created_at', plus a 2-widget example### Widget options — the five declared keys(dateGranularity/sortBy/sortOrder/limit/stageOrder), with the top-N spelling that had no documented formos:checkmarks on the four highest-traffic examples (+ UI-E-03's inlined action)The three additions cost +838 against −501 of named payers. They are nonetheless fully paid in the same file: the flight's total deletions are −3,423, so SKILL.md ends 2,585 tokens smaller and the ratchet is green with 2,589 tokens of headroom. Flagging the per-item overrun rather than re-cutting the payer list to fit, because the card's funding lines are its ruling and I would rather show them broken than silently re-derive them.
Falsehoods
actionType: 'url', actionUrl: '/objects/opportunity?filter=open'dashboard.zod.ts:382-384retires all three viaretiredKey(...)=z.never(); prescription:309-320"a dashboard widget has NO action button, and never had one".### Server-side date bucketingoptions.dateGranularityoverrides it for that widget only." (dashboard.zod.ts:217-225)packages/client-react, not metadata)"packages/client-reactis "React hooks for ObjectStack Client SDK"; the renderer is@object-ui/react-runtime, in objectui.{current_user.id}{current_user_id}.current_user.idis the RLS expression root, not a filter token —spec/src/data/context-tokens.zod.ts:44,49names this exact near-miss and:85lists the real token. Found inside a span this flight was already rewriting, same defect class as 1–2, mechanically fixed against the spec; taken under the bounded-in-place rule.Also deleted, never ported (card ruling): this package's claim that "unknown placeholders silently pass through as literal strings". It is false and the file contradicted itself 37 lines earlier.
packages/core/src/utils/filter-tokens.ts:378throwsUnknownFilterTokenError, and the module header at:44is titled "An unknown token throws".Deliberate deviations from the routed plan
##heading. The ruling says delete:1659-1768. Two in-file links (:1074,:1507) target#date-macros--filter-placeholders; deleting the heading breaks both, so the heading survives carrying the pointer. Also kept: two rules objectstack-query does not own — a filter token is presentation scope, not security; andAppContextSelectorids resolve in navigationrecordId/paramsonly, never in a filter. Both were their last mention in the package.ctx.session.positionsin compact form. The routed anchor does not carry it (see follow-ups). Kept with the "not an authorization input" guard; the org-isolation half is deleted and pointed.label: '打印总表(A3)'→'Print Summary Sheet (A3)'. The two at:755-756are non-English user phrasings the router matches on; translating a phrase whose only job is to match untranslated input destroys it. Seat ruled A: they stay.Not implemented (and why)
objectName/viewTypespelling. Outside the card's IMPLEMENT verbs, unfunded, and it has a cross-package consequence (three example pages repeat the spelling). Seat ruled C: filed as its own card, which moves the skill and the corpus together.rules/), UI-B-04 (duplicate generated contract), UI-H-01/H-02/H-03 (evals) — deferred by the card to [Decision] Skills optimization program — batch 1 (4 items): new-file ceilings for splits · planned-eval stubs · react-blocks double rendering · published pm-dispatch scope #14296.premise_false
None.
git diff --stat a59f78d origin/main -- skills/objectstack-uiis empty, so every audit span was byte-identical at the branch point. Two PM mechanical assumptions were refined rather than confirmed — below.PM mechanical assumptions — measured
skills/objectstack-ui/**byte-identical betweena59f78dandorigin/main. (origin/mainhad already moved past the dispatch'sd63c8a25to909a4417, which does not touchskills/; the branch is cut from909a4417.)check:skill-docsdoes run in CI and the frontmatter edit does force a regeneration, butskills/README.mdcame back green on its own (✓ skills/README.md) — it does not embed the description. The out-of-date artifact wascontent/docs/ai/skills-reference.mdx. Regenerated with the one generator the card names; the diff is 2 lines, both the frontmatter's own text.tsc; the parse half not measured. Reverse-verified against a committed tree: re-injectingactionType/actionUrlon the widget turnscheck:skill-examplesred with twoerror TS2322: Type 'string' is not assignable to type 'undefined'— one per retired key,z.never()surfacing asundefinedin the input type. Mutation proven on disk before measuring (injected-text grep count 1; blob4a5d1e25→6b5d8296), restore proven the same way (git diff HEADempty, blob back to4a5d1e25, injected count 0) — neither leg read from an editor's exit code. This gate exercisestsconly, so the Zod parse failure is asserted from the schema source, not measured here.defineAction), and thedefineDatasetblock was a fragment — it now importsdefineDataset+type DashboardWidgetand binds the trailing widget literal to a typed const.follow-up for objectstack-query
rules/filters.mdis the anchor and is strong: it already carries the fixed tokens, the parameterised form, both session tokens, both resolvers, the calendar-DAY*_endtrap, and — decisively — "Unknown tokens are rejected, not ignored". These TRUE rows from the deleted objectstack-ui text are not in it and were not ported:{token}and${token}spellings are accepted —spec/src/data/date-macros.zod.ts:200,207andcontext-tokens.zod.ts:101.rules/filters.mdshows only the bare form.{user_id}(a validtitleFormatfield interpolation elsewhere) and{organization_id}(the real column name). Query names{current_user}and{this_quarter_start}only.'user-{current_user_id}'). Query states only the converse;filter-tokens.ts:44states this half directly — "Values that merely CONTAIN braces are left untouched."isDateMacroToken(tok)from@objectstack/spec/dataas the author-time type check.filter-token-unknown, and why it exists: an unresolved token reaches SQL as a literal, matches nothing, and the widget renders0— indistinguishable from a genuine zero.follow-up for objectstack-data
references/data-hooks.mdcarries the org-isolation half completely — UI-C-02's deletion is safely routed there. It does not documentctx.session.positionsat all;:368says only thatctx.sessionhas "No role list —session.roleswas retired in 17.0.0". So the ADR-0090 D3 spelling and the "not an authorization input" guard have no anchor to point at, and a compact form was kept here rather than deleted into a gap.Gates — all 42 families, all at head
684415c30f937dcc, when the changeset wasSKILL.mdalone; the next commit addedcontent/docs/ai/skills-reference.mdxandscripts/skill-identifier-liveness-ledger.json, and I did not re-derive. Re-derived at the current head,node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstacknames 42 — the 26 extra are the docs family the.mdxpulls in. All 42 have now been run; every one of the 26 that had never been run passes. The earlier "16" was wrong and is retracted here rather than quietly overwritten.41 of 42 exit 0. Each exit code captured by redirecting before any pipe. The full list, in the order the harvester prints it:
check-ci-filter-parity·check-cross-package-test-inputs·check-doc-frontmatter·check-doc-route-spelling·check-docs-section-name·check-section-landing-index·check-shard-attestation·check-skills-token-ratchet·doc-formula-expressions·doc-security-posture·check:docs·check:empty-state·check:liveness·check:skill-docs·check:skill-examples·check:strictness-ledger·check:variant-docs·check:yaml-examples·agent-test-spelling·bash32-floor·cli-command-ids·corpus-claim-drift·cross-package-test-inputs·doc-anchors·doc-authoring·docs-audit-scope·docs-redirects·docs-single-h1·entry-guard·merge-driver·parse-guard·pm-governed-merges·pnpm-filter-targets·published-readme-links·react-page-adapter-contract·role-word·skill-compatibility·skill-frame-sync·skill-identifier-liveness·vendor-version-stamps·watch-hint-literal— all exit 0.Named verdict lines for the two the review asked for:
node scripts/check-skills-token-ratchet.mjs→ exit 0, "skills/objectstack-ui/SKILL.mdis 22856 tokens (ceiling 25445; headroom 2589)" · "38 authored bundle file(s) within their ceilings".pnpm --filter @objectstack/spec check:skill-examples→ exit 0, "✅ 263 prose examples type-check across 3 surface(s) — every marked block parsed, so tsc ran the SEMANTIC pass on all of them".The 42nd,
node scripts/check-test-completeness.mjs, exits 3 = NOT MEASURED by its own verdict text ("Nothing was measured… It is not a red, and there is nothing here to fix") — it needs a savedturbo run testlog. Recorded as NOT MEASURED: not a pass, not a red.Heavy runs went through
scripts/pm/os-verify-lock.shwithOS_VERIFY_LOCK_SLOT=issue-14298. Prerequisite builds re-run at this head, not assumed:@objectstack/specand the@objectstack/client-react/@objectstack/clientdependency closure — without the lattercheck:skill-examplesrefuses to run rather than reporting green ("packages/client-react/dist holds no .d.ts declarations… a FALSE GREEN on exactly the change it exists to catch").Repo-wide
pnpm lint(eslint over the whole tree) was NOT run — it is CI's own step, in this derivation's unnarrowable "always runs" tail. A plain omission, not a measured narrowing; I claim none of the three evidence items a narrowing would need.Two consequences outside
SKILL.mdBoth generator/tool output, neither hand-written, each the mechanical consequence of a funded edit:
content/docs/ai/skills-reference.mdx—gen:skill-docs, forced by the frontmatter edit (assumption 2). Notcontent/docs/releases/.scripts/skill-identifier-liveness-ledger.json—check-skill-identifier-liveness.mjs --update, pruningdayStartandshowMidnight. Both existed only to excuse thetimeSegmentsblock this flight deleted, and each ledger note independently records the implementation living in objectuiplugin-gantt— the same measurement UI-D-02 rests on.--updatenever adds an exemption.Changeset
skip-changesetapplies and is on the PR. Checked against the repo's own rule: the exemption means "this PR declares no release of its own", and no package publishesskills/,content/docs/orscripts/. TheCheck Changesetjob reads labels live; the label cannot be applied before the PR exists, so it was applied immediately after creation and read back.🤖 Generated with Claude Code
https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1