Skip to content

test(floors, ui): one shared floor per ui package population, one catalog entry floor, all at about two thirds - #26576

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-2qb1mr
Oct 27, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-2qb1mr

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Steve · project thread
Fixes #26521

Clause-②: no
Metadata-protocol: none

The ui half of #26444 (the parent stays open for its CLI and baseline halves). No changeset: every edit is to a test, a test helper, a repo-internal gate script under ui/scripts/ or ui/QUICK_REFERENCE.md, none of which any package ships; the PR carries skip-changeset.

维护者速读

Why

#26444's rule: an anti-vacuity floor refuses an empty scan; it is not a census. Floors set at today's measured value red on every legitimate deletion, and #26343 edited five floors to delete one ui package. Each floor now sits at about two thirds of its measurement and is written once per population.

What changes

One floor per ui package population, written once. New ui/scripts/__tests__/helpers/ui-package-population.mjs holds the anti-vacuity floors with the table they were measured from. It is an .mjs module rather than a .ts helper like its neighbours because the two gate scripts import it under plain node. Each floor is about two thirds of the value measured on origin/main 6a7c0fe3 (right after #26483 made @object-ui/app-shell private), the vite-dts-wiring-ratchet precedent:

floor population measured @ 6a7c0fe floor margin
UI_PUBLISHED_PACKAGE_FLOOR published packages (release group) 36 24 12
UI_WORKSPACE_MEMBER_FLOOR manifests under packages/*, apps/*, examples/* 43 28 15
UI_SIDE_EFFECTS_FALSE_FLOOR packages declaring sideEffects: false 11 7 4
UI_SIDE_EFFECTS_ARRAY_FLOOR packages declaring a sideEffects array 17 11 6
UI_TSC_BUILT_PACKAGE_FLOOR tsc-built packages 11 7 4

The card asked for one shared constant; the published-package floor is that constant and every site whose population is the published set or a superset of it reads it. Four sites count genuinely smaller or larger populations (the two sideEffects groups, the tsc-built packages, all workspace members); a 24 there would either red today (11, 17) or sit far under two thirds (43), so each of those has its own floor in the same module, still written once. See open question 1 in the report.

Every site, its measured value and its margin:

site was measured now margin
check-node-esm-load.mjs MIN_PACKAGES 30 36 published floor 24 12
check-published-dist-tooling.mjs MIN_PACKAGES 30 36 published floor 24 12
package-files-exist packages declaring files 38 39 published floor 24 15
package-files-exist files entries 150 153 100 53
package-files-exist packages owing license text 36 36 published floor 24 12
package-files-exist packages declaring exports 36 38 published floor 24 14
package-files-exist exports targets 130 150 100 50
side-effects-declaration-consistency declaring 28 28 false + array floors = 18 10
side-effects-declaration-consistency false 11 11 7 4
side-effects-declaration-consistency array 17 17 11 6
check-dist-completeness tsc-built packages 11 11 7 4
zero-test-member-exclusion-9106 members 40 43 member floor 28 15
zero-test-member-exclusion-9106 members with a test script and files 40 41 member floor 28 13
check-doc-links examples READMEs 3 3 2 1
check-doc-links packages/*/README.md 35 39 published floor 24 15
quick-reference-commands-4149 published under packages/ exact prose 35 published floor 24 (anti-vacuity) 11

The two entry-count floors (files entries, exports targets) and the example-README floor count entries, not packages, so they stay local at two thirds of their own measurement.

ui/QUICK_REFERENCE.md drops its hand-written count. The packages/* row now reads "The published @object-ui/* packages, plus the private ..." and still names the four private packages. Its test no longer requires the row to state N published; it refuses any N published / N packages figure in the row, keeps the anti-vacuity floor under the derived population, and keeps the private-package check (its failure text reworded for a row without a number).

One schema-catalog entry floor, in one place. New ui/examples/schema-catalog/test/catalog-entry-floor.ts exports CATALOG_ENTRY_FLOOR = 288 (432 entries measured, margin 144). It replaces the card's four sites (431 ×3, 423 ×1) and four more spellings of the same population the card did not list (component-fixture-declared-keys.test.ts, allExamples().length > 400 ×3 and entries.length > 400 ×1). The helper lives in the catalog package's own test/ because a test there importing from ui/scripts/ would read outside its package.

Per-type catalog floors in the same four files, fixed in place. The same tests pin per-type censuses at exactly today's count, so deleting one badge or card demo would red them. Same defect class, same files, mechanical two-thirds edit, so they moved in place:

site measured now margin
catalog-authored-key-6805-6806 scroll-area nodes (minNodes) 7 5 2
catalog-authored-key-6805-6806 badge nodes (minNodes) 40 27 13
card-demo-content-6788 cards 93 62 31
card-demo-content-6788 card categories 19 13 6
badge-demo-label-6829 badges 40 27 13
badge-demo-label-6829 badge categories 12 8 4
component-fixture-declared-keys select options 66 44 22
component-fixture-declared-keys option categories 7 5 2
catalog-gallery-render plugin categories 13 9 4

The plugin-category floor counts ui plugin packages with catalog entries, so retiring one plugin package would have redded it.

Forced test edits

  • ui/scripts/__tests__/check-node-esm-load.test.ts "keeps a floor under both legs": it pinned MIN_PACKAGES >= 30, a ninth spelling of the population. It now pins MIN_PACKAGES to the shared floor and keeps > 0.
  • ui/scripts/__tests__/quick-reference-commands-4149.test.ts: rewritten as described above, because the card deletes the prose number it asserted.

Tests

At head 0c64d31a, all under scripts/pm/os-verify-lock.sh:

  • The 14 touched or reading test files (the six ui/scripts/__tests__ sites, check-node-esm-load, check-published-dist-tooling, check-published-tsconfig-tooling-exclude, and the five schema-catalog files): Test Files 14 passed (14), Tests 1143 passed (1143). VERDICT command-exit 0.
  • pnpm --dir ui exec vitest run scripts/ --maxWorkers=2: Test Files 178 passed, 2 skipped (180); Tests 5057 passed, 2 skipped. VERDICT command-exit 0.
  • pnpm --dir ui type-check:scripts (the program holding the new .mjs and every ui/scripts test): VERDICT command-exit 0.
Emptied population: every floor still goes red (31 assertions)

A one-shot mutation, restored from HEAD by a trap and confirmed by an empty git diff HEAD afterwards: at each of the 30 floor sites in the eleven test files the measured population was replaced by 0 (expect.soft(0, "EMPTIED ...")), so every floor is read against an empty population in one run. Result: Test Files 11 failed (11), and 31 assertions red, one per floor (the minNodes loop yields two). Examples from the log:

  • EMPTIED packagesWithFiles.length: expected 0 to be greater than or equal to 24
  • EMPTIED members.length: expected 0 to be greater than or equal to 28
  • EMPTIED published.length: expected 0 to be greater than or equal to 24 (QUICK_REFERENCE)
  • EMPTIED entries.length: expected 0 to be greater than or equal to 288 (×5) and EMPTIED allExamples().length: ... 288 (×3)
  • no plugin categories were derived, so this case would be vacuous: expected 0 to be greater than or equal to 9

The two gate scripts' own collapse refusal (fewer than MIN_PACKAGES published packages found) is covered by the existing check-published-tsconfig-tooling-exclude case that pads a fixture below MIN_PACKAGES and asserts the scan-collapsed finding naming the number; it is green at the new value.

Measurement method

The measured values were read on 6a7c0fe3 by a throwaway mutation that turned each floor into expect.soft(population).toBe(-1) and read the actual values from the failures, restored from HEAD afterwards. MIN_PACKAGES' population was read by calling each script's own discovery (discoverPackages(...).filter(not private) and discoverPublishedPackages): 36 each.

Acceptance notes

  • Deleting one ui package or one catalog entry reds no floor above: every margin is at least 1 (the example-README floor, 3 → 2) and the package floors' margins are at least 4.
  • Left as they are, deliberately. layout-props-conversion.test.tsx: layout nodes 430 (447 measured) has a margin; withClassName 175 (182 measured) says in its own comment it is deliberately tighter after a ruled sweep; the 153 stack-node count is the census of a ruled spacing → gap rename, a transcription pin rather than an anti-vacuity floor (the class ci(gates): retire the transcription pins — tests and gates that hold a hand-typed count or table equal to the tree and red on every unrelated move (parent of eight) #26431 owns). badge-demo-label-6829 CONTAINER_CHILDREN_FLOOR 600 (660 measured) and catalog-authored-key-6805-6806 text-content 600 (659 measured) have margins. Exact toHaveLength pins on fixed demos are not floors.
  • #26365 (plugin-ai retirement) edits the QUICK_REFERENCE count and package-files-exist floors too; whichever lands second merges main. After this PR it needs to touch neither.
  • The new helper sits under ui/scripts/__tests__/helpers/ as the claim's file surface names; the two gate scripts importing from there is the one oddity, and the alternative (a sibling of workspace-root.mjs in ui/scripts/) is open question 2 in the report.

Verification

dispatch-gates: 20 derived, 20 run, 0 NOT MEASURED

node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 0c64d31a derived 20 families; each was run after the last commit with its exit code captured before any pipe:

  • exit 0: check-closing-keyword-parity (and --self-test), check-comment-mask-corpus (18349 files, 0 disagree), check:cross-package-test-inputs, check:dispatcher-error-vocabulary, check:driver-memory-census, check:engine-double-contract, check:gitlink-declared, check:nul-bytes, check:published-files, check:query-options-erasure, check:refd-timer-probe, check:test-source-alias, check:tier-file-adoption, check:type-check-coverage, check:type-check-debt, check:undeclared-dep-imports, check:watch-hint-literal, check:where-matcher, and pnpm --dir ui exec vitest run scripts/ (above).
  • --ran: 20 derived famil(ies) accounted for — 20 run, 0 NOT-MEASURED (a DERIVED zero — all 20 recorded an exit code and none of them is 3).
  • NOT MEASURED: @object-ui/example-schema-catalog type-check on built dependencies. A local tsc -p tsconfig.test.json without the @object-ui/* builds prints 171 errors, all unresolved-module noise from unbuilt packages (81 TS2307, 62 TS2882 and their implicit-any fallout); none names catalog-entry-floor.ts or an edited line. CI Type Check UI is the reading.
  • Every family CI runs is read from this PR's check runs; none was re-run locally to stand in for them.

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic. (not touched)
  • 2. Every name I added uses the casing for its kind.
  • 3. No formatter ran; pnpm lint passes. (lint is CI's run)
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset. (publishes nothing: skip-changeset)
  • 6. packages/spec touched: n/a.
  • 7. No hand edits to content/docs/references/, packages/*/CHANGELOG.md or content/docs/releases/.
  • 8. Title, body and comments are in English.

🤖 Generated with Claude Code

https://claude.ai/code/session_01ADHkmTNh6kDC6Lu2Yr7s5v


Generated by Claude Code

… entry floor in one place, all at about two thirds

The ui published-package count was spelled in about eight places, each floor
sitting at or just under today's measured value, so one package retirement
edited a floor in every file. The floors now live in
ui/scripts/__tests__/helpers/ui-package-population.mjs at about two thirds of
the values measured on 6a7c0fe, read by both gate scripts' MIN_PACKAGES and
by every test site; the schema-catalog entry floor lives in one helper read by
all eight call sites. ui/QUICK_REFERENCE.md drops its hand-written count and
its test now refuses one.

Claude-Session: https://claude.ai/code/session_01ADHkmTNh6kDC6Lu2Yr7s5v
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 27, 2026
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests labels Oct 27, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 · ACCEPT · seat domain:ui#1 · 2026-10-27T08:58Z · #26521

Head 0c64d31a (read from the PR object). Fixes #26521; Part of #26444 (devx seat 2's parent).

  • Shape. 17 files, +220 / −98. Tests, scripts and docs only, so it carries the skip-changeset label and no changeset. New module ui/scripts/__tests__/helpers/ui-package-population.mjs: the one place the ui population floors are written. Every site reads it, including both gates' MIN_PACKAGES.

  • Floors (measured on main 6a7c0fe3, after app-shell went private), each about ⅔ of the measurement.

    Population Measured Floor
    Published 36 24
    Workspace members 43 28
    sideEffects: false 11 7
    sideEffects arrays 17 11
    tsc-built 11 7
    Catalog entries 432 288

    The catalog-entry floor is written once, in ui/examples/schema-catalog/test/catalog-entry-floor.ts, replacing 8 call sites (the 4 the card listed and 4 more above 400). The QUICK_REFERENCE.md prose count is deleted, and its test now refuses one.

  • Not weakened. On an emptied population, all 31 floor assertions go red. Deleting one ui package or one catalog entry reds none.

  • Seat rulings on the open questions.

    • One module with per-population floors: yes.
    • Placement under __tests__/helpers/: kept. The two gate scripts import it at run time under plain node, and the docblock says why. A new top-level ui/scripts/*.mjs would join the gate-script population, so it would be a new script for the script census rather than a helper.
  • Surface deviations (in the report). check-node-esm-load.test.ts was forced, because it pinned MIN_PACKAGES >= 30. component-fixture-declared-keys.test.ts had a per-type census at exactly the measured value; it moved to ⅔ in place, the same class of fix.

  • Governed surface. scripts/pm/check-governed-merges.mjs --pr 26576: not governed.

  • Checks pinned to the head. All check runs completed: 0 failing, 0 pending. The seat's landing script checked this before posting.

  • Evidence (dev). ui scripts/: 178 files green. Gates: 20/20.

  • Serial constraints. refactor(ui)!: retire @object-ui/plugin-ai and its three node types #26365 (plugin-ai retirement, held) also edits these floors and QUICK_REFERENCE.md. If this PR lands first, refactor(ui)!: retire @object-ui/plugin-ai and its three node types #26365 merges main and reads the constant.

Landing: ready + auto-merge through the relay. devx seat 2 is told on merge.

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 size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate tests

Projects

None yet

2 participants