Skip to content

docs(plugins): bring three documented interface blocks up to their shipped types - #7985

Merged
baozhoutao merged 2 commits into
mainfrom
claude/issue-7302-readme-partial-excerpts-content-half
Sep 6, 2026
Merged

docs(plugins): bring three documented interface blocks up to their shipped types#7985
baozhoutao merged 2 commits into
mainfrom
claude/issue-7302-readme-partial-excerpts-content-half

Conversation

@baozhoutao

@baozhoutao baozhoutao commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Fixes #7302

PARTIAL_EXCERPTS in scripts/check-readme-exports.mjs opened with exactly three entries: objectui#6214 wired the interface pin and was deliberately not allowed to edit README CONTENT, so the drift its first run found was written down there instead of being inherited silently. All three are paid off here.

Ledger before: 3 entries. Ledger after: 0Object.freeze({}), with the docblock kept and extended, because the list must be able to fill again.

Three entries, three dispositions — deliberately not one template

Declaration Disposition Why
packages/plugin-gantt/README.md::GanttTask in-README PARTIAL_MARKER above the fence Genuine excerpt. The paragraph directly below the block already says fields and hasOwnDates are populated by ObjectGantt itself — verified still present on this base. Adding the two keys to the block would contradict that prose.
packages/plugin-kanban/README.md::KanbanColumn block brought up to the shipped declaration Staleness. Nothing on the page says the block is partial.
packages/plugin-kanban/README.md::KanbanCard block brought up to the shipped declaration Same page, same class.

The marker grammar used

One marker silences one TYPE, and it binds to the next fenced block whose opening fence is the first following line that is neither blank nor another marker. Placed at packages/plugin-gantt/README.md:392, immediately above the fence at :393:

readme-exports: partial GanttTask — deliberate excerpt: `fields` and `hasOwnDates` are populated by ObjectGantt itself, as the paragraph below the block says

(spelled without its HTML-comment delimiters here, because a comment-shaped fragment does not survive being written into a GitHub body — see the read-back rule in AGENTS.md. The delimiters are present in the file, and the gate parses it: the run below reports 1 excerpt(s) declared by marker.)

The #6155 impact check (Zone 2 A3) — asked for, and the answer moved a key set

The key sets were re-derived from the gate's own reading of the built tree, not copied from the ledger reasons, exactly as objectui#6155's warning in the ledger asked.

Which declaration @object-ui/plugin-kanban actually exports today: packages/plugin-kanban/src/index.tsx:111 re-exports KanbanCard / KanbanColumn from src/types.ts, and src/types.ts:35 is itself a plain re-export from @object-ui/types. So the shipped declaration is the ONE in packages/types/src/complex.tsKanbanCard at :63, KanbanColumn at :120 — which objectui#7664 made authoritative and which that file's own header pins against re-declaration (one-authority-per-exported-name-6273.test.ts). Of objectui#6155's four disagreeing declarations, this is the one that spells the lane's array cards (objectui#6939 retired items, a spelling with zero read sites) and the card's array badges. Both spellings the README already used are therefore correct against the export; neither was touched. objectui#6155 is not addressed here and remains open.

Where the derived answer disagreed with the ledger's prose: the ledger reason for KanbanColumn recorded ONE omitted key, collapsed. The gate on a built tree reports twocollapsed and color:

partial-ledger  packages/plugin-kanban/README.md:114  interface KanbanColumn  doc 5 key(s) vs own 7 of 7  omitted: collapsed, color

color arrived after that reason was written: objectui#7664 retired it as color?: never, a deliberate tombstone whose own JSDoc gives prong 2 as "keep loud a key the docs taught as working". The README now documents it as such rather than dropping it — which is what the tombstone exists for. The reason string was a derived value, and it was stale; the export won.

Diff, in full

  • packages/plugin-gantt/README.md — one marker line. The block is unchanged.
  • packages/plugin-kanban/README.mdcollapsed?: boolean and color?: never onto KanbanColumn; cardSubtitle?, cardFieldCells?, coverImage? onto KanbanCard, with a one-line comment each in the block's existing trailing-comment style. limit's comment corrected from "Maximum cards allowed" to the WIP-limit wording the shipped JSDoc uses.
  • scripts/check-readme-exports.mjsthe only non-comment change in this file is the ledger literal (three entries becoming {}); verified by filtering the diff. Everything else is docblock: a paragraph recording that empty is a state and not a retirement, and a @type annotation (see below).
  • scripts/__tests__/check-readme-exports.test.ts — see the declared deviation below.

Two things the dispatch did not predict — both declared

1. The gate's own suite has a non-vacuity guard on the ledger, and it fired. expect(ledgered.length, 'the ledger is empty, so this case asserts nothing').toBeGreaterThan(0) went red the moment the ledger emptied. It was right to: the per-ENTRY leg of that case does stop asserting. But the case does not go vacuous with it — judgeable becomes the empty set, so the equality below it then reads "NO declaration in this tree reds as a stale omission with the ledger off", which reds on the next README that drifts. So the guard is replaced by the empty state asserted as a fact, with a comment saying that an entry arriving flips that line, and that the per-entry property never depended on the repository carrying an entry — it is pinned on the fixture tree in the same file (the LEDGER suppresses the omission it records, the LEDGER does NOT suppress a fabricated key either, and the two stale-entry cases), which carries an entry by construction.

⚠️ This file is outside the file surface the claim comment declared (which named only the two READMEs and the gate script). It is not a gate LOGIC change — the judgement code is byte-identical — but it is a fourth file, and the card's own done criterion requires the self-test to pass, so it could not be avoided. Flagged rather than absorbed.

2. pnpm type-check:scripts failed TS18046 on the empty ledger. Object.freeze({}) infers Readonly of the empty object type, so Object.entries hands the test suite unknown values and the case that reads each reason stops compiling. Fixed with a @type {Readonly<Record<string, string>>} JSDoc annotation on the export — the same spelling, and the same reason, as check-doc-snippet-types.mjs's UNGATED_DOCS. It is a comment, so it changes no runtime byte.

Probes — every mutation proven on disk, every restore proven

Run on the COMMITTED tree, one script with trap ... EXIT INT TERM and absolute paths. Each mutation is proven by comparing git hash-object against the path's HEAD blob (an empty or equal hash aborts loudly), and each restore by git checkout HEAD -- path followed by an empty git diff HEAD.

Probe Mutation On-disk proof Gate result Restore
A — ablation: is it the CONTENT fix that greens the gate, or the ledger deletion? kanban README reverted to the base blob, ledger left empty 5d17050c vs HEAD 97296226; anchor counts collapsed=0, coverImage=0 exit 12 documented type(s) are behind the shipped declaration: KanbanColumn omits collapsed, color; KanbanCard omits cardSubtitle, cardFieldCells, coverImage git diff HEAD EMPTY
B — the marker's stale direction the two keys added to the Gantt block, marker kept 8e2a2736 vs HEAD 17b504eb; injected anchor hasOwnDates=1, marker still 1 exit 11 partial-excerpt marker(s) declare nothing: GanttTask declares an excerpt that omits nothing any more -- delete the marker git diff HEAD EMPTY
Cfabricated-key positive control a made-up key planted in the KanbanCard block 9e149d23 vs HEAD 97296226; anchor count 1 exit 11 documented type(s) declare a key the shipped type does NOT have: documents totallyMadeUpKey, not on the shipped type git diff HEAD EMPTY

B is the one that earns the marker route: the marker is checked, so it cannot outlive the fact it declares.

Verification — at 09f1d4856, on a BUILT tree

An unbuilt tree reports every declaration unjudgeable-type and SUSPENDS the shrink-only rule, so it is a precondition and not a red. Measured both ways here: before building, 426 self-import(s) could not be judged and 3 not judged; the build (turbo run build --filter=./packages/*, through the shared verify lock) reported VERDICT command-exit 0, Tasks: 39 successful, 39 total.

  • pnpm check:readme-exportsexit 0, ✅ check-readme-exports: OK (... 58 key(s) compared both ways (0 fabricated, 0 stale omission(s); 1 excerpt(s) declared by marker, 0 by ledger, 0 not judged ...)). Baseline before the change on the same built tree: 53 key(s) ... 0 by marker, 3 by ledger.
  • Done criterion, the gate's own API: scan(repoRoot, { excerpts: {} }) returns findings: 0 vacuous: 0 with PARTIAL_EXCERPTS keys: [].
  • --list now reports partial-marker on GanttTask and matches doc 7 key(s) vs own 7 of 7 on both kanban declarations.
  • Gate suite + README readers + both plugin packages: pnpm exec vitest run packages/plugin-gantt/ packages/plugin-kanban/ scripts/__tests__/check-readme-exports.test.ts scripts/__tests__/check-unreferenced-sources.test.tsTest Files 88 passed (88), Tests 728 passed (728), lock VERDICT command-exit 0. The reader sweep (git grep -l for both README paths over scripts/ packages/ examples/ apps/) names packages/plugin-gantt/src/readme-navigation-example.test.ts, scripts/__tests__/check-readme-exports.test.ts and scripts/check-doc-snippet-types.mjs; all three are covered above.
  • pnpm check:doc-snippets — exit 0, Semantic phase: 477 of 477 block(s) judged, 0 failed. Both READMEs are on that gate's UNGATED_DOCS ledger (gantt: 9 parse + 12 undefined-name; kanban: 6 parse), so their fences are NOT compiled; the ledger's counts are prose and are not re-derived, so these edits cannot move that verdict.
  • pnpm check:doc-fences exit 0 · check-doc-links exit 0 · pnpm check:control-bytes exit 0 (6421 tracked text file(s)) · pnpm check:doc-types exit 0 · pnpm check:doc-example-readers exit 0 · check-unreferenced-sources exit 0 · pnpm lint:coverage exit 0 (46/46 packages) · pnpm check:governed-queue-guard exit 0 (132 cases pass).
  • pnpm type-check:scripts — exit 0.
  • node scripts/check-changeset-presence.mjs — exit 0, verdict quoted literally: ✅ No source or published contract of a released package changed in this range, so no changeset is owed. (0 of them published source of a package the release covers).
  • node scripts/check-governed-queue-guard.mjs --test over all four changed paths — ✅ NOT GOVERNED — 4 path(s) checked against 5 governed surface(s); none matched.
  • Control-byte self-scan beyond the gate: grep -naP for the control range over all four files → no hits.
  • Lint, as a declared narrowing (three readings, so this is a measurement and not a skipped run): ① the population comes from eslint's own config — eslint.config.js's files globs are **/*.{ts,tsx} and narrower, with no markdown processor, so the two READMEs and the .mjs are outside eslint's population entirely and the linted half of this diff is one file; ② --format json counted files linted: 2, errors: 0, warnings: 0; ③ invariance — the config declares no project / projectService, so type-aware linting is off and this diff cannot move the verdict on any untouched file. The repo-wide eslint . --no-inline-config run belongs to CI.

Out of scope, filed

#7984 — the same README's badges element documents 2 of the shipped 4 members (colorClass / colorStyle are missing). It sits inside a nested object literal, which this gate compares in neither direction by design, and the page's fences are not compiled either. Not touched here.

Patch round (R45) — Test (shard 2/4) was red at 09f1d485, and the fix is test-side

Test (shard 2/4) (run 34014605149, job 101436113831) failed at the previous head with two assertions in scripts/__tests__/check-readme-exports.test.ts, the file this PR already edits:

FAIL  the PARTIAL_EXCERPTS ledger ... > hides ONLY omissions, at every declaration the tree can judge — in ANY build state
      expect(off.census.excerptsNotJudged).toBe(0)     // :1020 — received 1

FAIL  repo state — assertions that hold in EVERY build state > finds no fabricated or wrong-path import where it can judge, and never passes silently where it cannot
      expect(result.census.excerptsNotJudged, "the ledger's suspension count is not the number of entries whose own package is unbuilt (none)").toBe(suspendable.length)   // :1084 — received 1
      build state: census.packagesUnbuilt = 36 of 40 packages

Why it was green here and red there

The test shards run pnpm install then pnpm test and never build, so CI judges an unbuilt tree — packages/plugin-gantt among the 36 unbuilt packages. On an unbuilt package every declaration comes back unjudgeable-type, and the gate then suspends the shrink-only rule for whatever declared that declaration an excerpt, counting it in census.excerptsNotJudged. It counts both mechanisms there, deliberately and in one sentence of its own header: "BOTH suppress stale-omission ... both are counted as not judged in the census".

The two assertions derived their expected value from the ledger onlyObject.keys(PARTIAL_EXCERPTS) filtered by build state. That was complete while every excerpt in the tree was a ledger entry. This PR moved GanttTask to the in-README PARTIAL_MARKER (the disposition the ledger's own reason prescribed), which produced a marker-declared excerpt on an unbuilt package — a count neither assertion modelled: expected 0, gate reported 1. Verification for R44 ran on a BUILT tree, which is exactly the state in which this cannot fire.

Which side owns the count

The test. The gate's behaviour is the one its header specifies, and the census already attributes the suspension correctly — so nothing in scripts/check-readme-exports.mjs changed in this round. No judgement byte and no census byte moves. The whole patch is one file.

suspendedExcerpts(result, excerpts?) returns the declared excerpts whose OWN package is unbuilt, under the same per-package rule the rest of these cases use since objectui#7460:

  • ledger half — from the exported PARTIAL_EXCERPTS literal, as before;
  • marker half — by re-reading each README of an unbuilt package through the gate's own exported grammar (extractCodeBlocks + findPartialMarkers), keyed fence::Name per README exactly as the gate keys its excerptFor map.

Derived from the README bytes, never read back off the counter under test, so both assertions still cross-check the gate against something that is not the gate's own count. The marker half deliberately does not re-parse the block to confirm the named type is declared inside it: a bound marker whose fence declares no such type is reported stale-partial-marker in every build state, and the same case asserts there are none of those.

The property both assertions exist for is kept and extended, not relaxed: an unbuilt package must be REPORTED and never silently skipped, and a new line now asserts that for the marker route too — every marker-declared excerpt on an unbuilt package must carry its own unjudgeable-type finding, the requirement the ledger half has always had. The :1020 line is likewise no longer a hard-coded 0: excerpts: {} turns the ledger off and the ledger is the only half it can turn off, so that line was quietly asserting "this repository declares no excerpt by marker" under a title about the ledger.

Verdict lines — both build states

state command verdict
UNBUILT, before the fix (reproduction; 0 of 40 dist/ present) pnpm exec vitest run scripts/__tests__/check-readme-exports.test.ts exit 1Tests 2 failed | 85 passed (87), byte-identical to the CI signature at :1020 and :1084
UNBUILT, after the fix same command exit 0Test Files 1 passed (1), Tests 87 passed (87)
BUILT (turbo run build --filter=./packages/* --concurrency=2Tasks: 39 successful, 39 total), after the fix same command exit 0Tests 87 passed (87)
BUILT, the gate itself pnpm check:readme-exports exit 0check-readme-exports: OK (... 58 key(s) compared both ways (0 fabricated, 0 stale omission(s); 1 excerpt(s) declared by marker, 0 by ledger, 0 not judged ...))

Ablation

On the committed tree, unbuilt, one script with trap ... EXIT INT TERM and absolute paths: the test-side change alone reverted to the pre-fix blob (git checkout 09f1d485 -- scripts/__tests__/check-readme-exports.test.ts).

  • mutation proven on disk: blob ddae340e vs HEAD e64cd41b; anchor suspendedExcerpts count 0 after the revert, the old expect(off.census.excerptsNotJudged).toBe(0); line back at count 1;
  • result: exit 1, Tests 2 failed | 85 passed (87) — the same two assertions, the predicted direction (turns red);
  • restore: git checkout HEAD -- path, blob back to e64cd41b, git diff HEAD on that path empty and git status --porcelain empty.

Gates, at b520274

pnpm type-check:scripts exit 0 · node scripts/check-governed-queue-guard.mjs --test over all four changed paths — NOT GOVERNED — 4 path(s) checked against 5 governed surface(s); none matched · node scripts/check-changeset-presence.mjs exit 0, No source or published contract of a released package changed in this range, so no changeset is owed · pnpm check:control-bytes exit 0 (scanned 6421 tracked text file(s)) plus a grep -naP self-scan of the changed file, no hits · pnpm check:unreferenced-sources exit 0.

Readers of the changed file (git grep -l over scripts/ packages/ .github/, unpiped, exit 0): .github/workflows/readme-exports.yml, which names it in prose as the pin that fails if a paths filter is ever added to that workflow — no code reads it. Readers of the module it imports: scripts/__tests__/check-unreferenced-sources.test.ts (run: Tests 25 passed (25)), plus prose references in scripts/check-unreferenced-sources.mjs, scripts/check-doc-snippet-types.mjs and .github/workflows/ci.yml.

Lint, as a declared narrowing with its three readings: ① the changed file is a .ts and therefore inside eslint's own population (files globs **/*.{ts,tsx}); ② --format json counted files linted: 1, errors: 0, warnings: 0; ③ invariance — the config declares no project / projectService, so type-aware linting is off and this diff cannot move the verdict on any untouched file. The repo-wide run belongs to CI.

One deviation from the dispatch's wording: it asked for the build to go through "the repo's shared verify lock". There is no such entry point in this repository (no scripts/pm/os-verify-lock.sh, nothing in AGENTS.md); the build was run in the foreground at --concurrency=2 as written.


Generated by Claude Code


Generated by Claude Code

…ipped types

`PARTIAL_EXCERPTS` in `scripts/check-readme-exports.mjs` opened with three
entries, each recording drift objectui#6214 was not allowed to fix in the
gate's own PR. All three are paid off here and the ledger is now empty.

The three are NOT one fix:

- `packages/plugin-gantt/README.md::GanttTask` is a genuine excerpt -- the
  paragraph directly below the block already says `fields` and `hasOwnDates`
  are populated by `ObjectGantt` itself. It moves to the in-README
  `PARTIAL_MARKER` above the fence, which is the declaration that means
  "deliberate"; adding the two keys to the block would contradict that prose.
- `packages/plugin-kanban/README.md::KanbanColumn` and `::KanbanCard` are
  staleness, so the blocks are brought up to the shipped declarations. The
  key sets are re-derived from what `@object-ui/plugin-kanban` actually
  exports on a built tree, not copied from the ledger reasons: the column is
  two keys behind (`collapsed` and the `color` tombstone), not the one the
  ledger recorded.

The ledger's own test case is updated with it. Its non-vacuity guard
(`expect(ledgered.length).toBeGreaterThan(0)`) went red on the empty ledger,
correctly: the per-ENTRY leg stops asserting. The case does not go vacuous --
`judgeable` becomes the empty set and the equality then reads "no declaration
in this tree reds as a stale omission with the ledger off" -- so the guard is
replaced by the empty state asserted as a fact, and the per-entry property
stays pinned on the fixture tree, which carries an entry by construction.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013uAaxiwgYDybsTNV9xwa1M
@github-actions github-actions Bot added documentation Improvements or additions to documentation plugin plugin: kanban tests labels Sep 6, 2026
@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 50 chunks) 3185.9 KB 3191.4 KB
Main entry chunk (gzip) 143.5 KB 350 KB
Entry file index-8xzvN5SF.js
Status PASS

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


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 15.67KB 5.75KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 5.13KB 2.35KB
collaboration (CommentThread.js) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 497.06KB 113.79KB
core (index.js) 6.96KB 2.79KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 182.08KB 50.62KB
fields (index.js) 242.44KB 61.25KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 4.28KB 1.75KB
i18n (index.js) 3.65KB 1.47KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 26.89KB 9.04KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.84KB 10.94KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 4.39KB 1.66KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 11.71KB 4.29KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 5.12KB 1.74KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 15.16KB 3.68KB
plugin-calendar (index.js) 47.35KB 13.21KB
plugin-charts (index.js) 70.31KB 19.62KB
plugin-chatbot (index.js) 193.53KB 46.05KB
plugin-dashboard (index.js) 131.41KB 34.43KB
plugin-designer (index.js) 211.51KB 43.01KB
plugin-detail (index.js) 247.59KB 63.48KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 131.01KB 32.32KB
plugin-gantt (index.js) 167.16KB 40.99KB
plugin-grid (index.js) 208.56KB 56.63KB
plugin-kanban (index.js) 52.30KB 14.49KB
plugin-list (index.js) 113.24KB 27.66KB
plugin-map (index.js) 20.35KB 6.77KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.42KB 11.92KB
plugin-timeline (index.js) 29.95KB 8.67KB
plugin-tree (index.js) 9.16KB 3.18KB
plugin-view (index.js) 84.33KB 20.75KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 81.07KB 26.86KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 2.32KB 1.24KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 5.41KB 2.34KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 4.93KB 2.24KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 20.57KB 5.88KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 10.35KB 3.60KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.74KB 1.41KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

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

…n expectation

`Test (shard 2/4)` went red at head 09f1d48 with two assertions in this file
expecting 0 and receiving 1. CI's shards run `pnpm install` then `pnpm test`
and never build, so the tree they judge is unbuilt -- and an unbuilt tree is
the only state in which this can fire. The PR's own verification ran on a
built tree, where it cannot.

The gate counts BOTH excerpt mechanisms in one census counter, deliberately
and in one sentence of its header: a declaration that comes back
`unjudgeable-type` suspends the shrink-only rule for its ledger entry AND for
its in-README `PARTIAL_MARKER`, and "both are counted as `not judged` in the
census". The two assertions derived their expected value from the LEDGER
alone -- `Object.keys(PARTIAL_EXCERPTS)` filtered by build state -- which was
complete only while every excerpt in the tree was a ledger entry. Moving
`GanttTask` to the marker, which is the disposition a genuine excerpt is meant
to end at, produced a count neither assertion modelled.

So the expectation is widened to the population the counter actually counts,
under the same per-PACKAGE rule: `suspendedExcerpts()` returns the ledger
entries and the bound markers whose OWN package is unbuilt. The gate is
unchanged -- no judgement byte and no census byte moves.

Derived from the READMEs, not from the counter under test: the ledger half
from the exported literal, the marker half by re-reading each README of an
unbuilt package through the gate's own exported grammar
(`extractCodeBlocks` + `findPartialMarkers`, keyed `<fence>::<Name>` per
README exactly as the gate keys `excerptFor`). It does not re-parse the block
to confirm the named type is declared inside it, because a bound marker whose
fence declares no such type is reported `stale-partial-marker` in every build
state and the same case asserts there are none.

The property both assertions exist for is kept and extended, not relaxed: an
unbuilt package is still REPORTED and never silently skipped, and a new line
asserts that for the marker route too -- every marker-declared excerpt on an
unbuilt package must carry its own `unjudgeable-type` finding, the same
requirement the ledger half has always had.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MM7kaS4dPpYHV5BsMyu4tQ
@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 50 chunks) 3185.9 KB 3191.4 KB
Main entry chunk (gzip) 143.5 KB 350 KB
Entry file index-8xzvN5SF.js
Status PASS

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


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 15.67KB 5.75KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 5.13KB 2.35KB
collaboration (CommentThread.js) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 497.06KB 113.79KB
core (index.js) 6.96KB 2.79KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 182.08KB 50.62KB
fields (index.js) 242.44KB 61.25KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 4.28KB 1.75KB
i18n (index.js) 3.65KB 1.47KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 26.89KB 9.04KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.84KB 10.94KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 4.39KB 1.66KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 11.71KB 4.29KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 5.12KB 1.74KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 15.16KB 3.68KB
plugin-calendar (index.js) 47.35KB 13.21KB
plugin-charts (index.js) 70.31KB 19.62KB
plugin-chatbot (index.js) 193.53KB 46.05KB
plugin-dashboard (index.js) 131.41KB 34.43KB
plugin-designer (index.js) 211.51KB 43.01KB
plugin-detail (index.js) 247.59KB 63.48KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 131.01KB 32.32KB
plugin-gantt (index.js) 167.16KB 40.99KB
plugin-grid (index.js) 208.56KB 56.63KB
plugin-kanban (index.js) 52.30KB 14.49KB
plugin-list (index.js) 113.24KB 27.66KB
plugin-map (index.js) 20.35KB 6.77KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.42KB 11.92KB
plugin-timeline (index.js) 29.95KB 8.67KB
plugin-tree (index.js) 9.16KB 3.18KB
plugin-view (index.js) 84.33KB 20.75KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 81.07KB 26.86KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 2.32KB 1.24KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 5.41KB 2.34KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 4.93KB 2.24KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 20.57KB 5.88KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 10.35KB 3.60KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.74KB 1.41KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

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

Copy link
Copy Markdown
Contributor Author

Standing down on Live E2E (informational) — red on the base branch too, not this PR's. domain:devx @ objectui execution seat, PM session session_01MM7kaS4dPpYHV5BsMyu4tQ, R45, 2026-09-06T07:05Z.

Proceeding: arming auto-merge (ACCEPT 5557561871 on #7302) and reading added_to_merge_queue as the receipt.


Generated by Claude Code

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 plugin: kanban plugin tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

finding(docs): three documented interface blocks are behind their shipped types — the PARTIAL_EXCERPTS ledger #6214 opened with

2 participants