Skip to content

docs(mobile): shrink UNGATED_DOCS by one — the mobile README's 10 blocks compile (#5174 batch 14) - #7975

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-5174-ungated-docs-batch14
Sep 6, 2026
Merged

docs(mobile): shrink UNGATED_DOCS by one — the mobile README's 10 blocks compile (#5174 batch 14)#7975
baozhoutao merged 1 commit into
mainfrom
claude/issue-5174-ungated-docs-batch14

Conversation

@baozhoutao

Copy link
Copy Markdown
Contributor

Part of #5174 — batch 14 of the check-doc-snippet-types ungated-docs ledger burn-down.

packages/mobile/README.md leaves UNGATED_DOCS. All 10 of its ts/tsx blocks now compile --strict against the built dist/*.d.ts. Zero fragment markers written, zero entries added — the ledger hunk is 0 additions / 2 deletions and the whole diff is exactly two files.

reading before after
ledger entries 24 23
covered documents 203 204
of those, holding a ts/tsx block 101 102
covered blocks 635 645
of those, to compile 477 487
declared fragments 158 158
scan-set size 227 227

Fragments unmoved ⇒ every one of the 10 newly covered blocks earned it by compiling. The block count went 9 → 10 because the useGesture / useSpecGesture section now carries one block per hook.

Base for every figure: 859de84a0. Nothing here is inherited from batch 13.

Census, re-taken on this base

Taken with the gate's own exports (UNGATED_DOCS, listDocuments, scanFences), not by eye. Verdict line at the branch point, exit 0:

Scanned 227 document(s): 203 covered (101 of them hold a ts/tsx block), 24 ungated — declared in this script, NOT verified by it.
Covered blocks: 635 — 477 to compile, 158 declared fragment(s).
Semantic phase: 477 of 477 block(s) judged, 0 failed.

24 entries, by ts/tsx block count:

blocks entry takeable?
18 packages/plugin-gantt/README.md no — #7302
11 packages/plugin-chatbot/README.md no — deferred
10 packages/auth/README.md no — held by draft PR #7685
9 packages/mobile/README.md taken this batch
8 packages/i18n/README.md yes
8 packages/plugin-designer/README.md yes
7 collaboration, layout, permissions, plugin-detail, types yes
5 core, plugin-list, react-runtime, root README.md yes
5 packages/plugin-kanban/README.md no — #7302
4 plugin-ai, plugin-charts, plugin-editor, plugin-map, plugin-markdown, providers yes
2 packages/fields/README.md yes
1 packages/plugin-tree/README.md yes

Exclusions re-verified on this base, not inherited:

Decomposition, before any edit

The ledger's reason string was a clue, and it was wrong in two places. Measured at the base by removing the entry in memory (never on disk) and running the gate's own analyze + compileSnippets over the same tree:

ledger reason said measured
19 undefined-name diagnostic(s) 18 TS2304
plus TS1108x2 TS2345x1 TS2353x1 matches
(not mentioned) TS7006 x1 — implicit any on a callback parameter

Total 23 diagnostics across 9 of 9 blocks.

⚠️ The bigger finding is what those 23 numbers HID. Eight of the nine blocks never imported the symbols they called, so every call sat on an any and no argument was ever checked. Once the imports are written, six documented call shapes turn out never to have existed on @object-ui/mobile:

the page taught the package ships
useGesture({ onSwipeLeft, onSwipeRight, onPinch }) UseGestureOptions is { type, onGesture, threshold?, longPressDuration?, enabled? }; the callback-shaped hook is useSpecGesture
useBreakpoint() returning current the field is breakpoint (isAbove / isBelow / width are also returned)
useTouchTarget({ minSize: 44 }) returning targetProps { config?: TouchTargetConfig } returning { style, className }
ResponsiveContainer with mobile / desktop props minBreakpoint / maxBreakpoint / showOn / hideOn / fallback, children required
registerServiceWorker({ cacheStrategy }) ServiceWorkerConfig is { url?, scope?, onSuccess?, onUpdate?, onError? }; caching strategy lives in the generated worker (getServiceWorkerSource)
useResponsive({ mobile, tablet, desktop }) keys are breakpoint names; resolveResponsiveValue walks BREAKPOINT_ORDER only, so the documented call returned undefined at every breakpoint

None of these is a which-side-is-wrong question, so none is refused. For each one the correct spelling already ships and is already exercised elsewhere: useSpecGesture exists precisely to carry per-gesture callbacks, useTouchTarget's own @example in its .d.ts spells style and className, and BREAKPOINTS / BREAKPOINT_ORDER are the only keys the resolver reads. Repairing the page teaches the shipped surface; widening the types to match the prose would have been an unpulled capability expansion, which the startup-stage focus axis rejects by default, and a lenient consumer-side alias, which commandment #0.1 rejects outright.

Coverage limit, measured rather than asserted

ResponsiveValue is T OR a partial record keyed by breakpoint name. The bare-T branch means any object literal type-checks as a responsive value, so wrong breakpoint keys are invisible to this gate on their own. Probe P2b below plants { mobile, tablet, desktop } back into the repaired block with the result no longer rendered, and the gate stays GREEN. What makes P2 red is the repaired block consuming columns at a narrower type — a property of the block this PR writes, not a property of the gate. Stated so the next reader does not credit the gate with catching key validity.

Scope guard

  • The gate file is touched only inside the UNGATED_DOCS object literal, by removal; git diff --numstat reads 0 2. Asserted programmatically, not by eye, by parsing both sides' literal and diffing: base entries: 24 | branch entries: 23, ADDED entries: [], REMOVED entries: ["packages/mobile/README.md"], SURVIVING entries whose reason text changed: [], key order preserved for survivors: true.
  • Strictness proven byte for byte: everything from the Fence scanning banner to end of file is identical on both sides of this diff — sha256 f46b5662ba336f026bca3a0003e0b7979789d48d0291fa5760be7d23c8ed0160 on 859de84a0 and on this branch. ⚠️ Asserted as identity across this diff, never as a constant carried from an earlier batch; it differs from batch 13's value because finding(gate): a blockquoted doc snippet has no reachable fragment-marker escape hatch — population 0 today #7099's blockquote walk landed in between, which is expected.
  • The gate's --build-filter closure grew by exactly one entry, --filter=@object-ui/mobile..., and lost none.
  • Every reader of the edited document was enumerated before choosing the rewrite's shape. git grep -l 'packages/mobile/README.md' -- scripts/ packages/ examples/ apps/ returns the gate itself and scripts/__tests__/doc-version-claims.test.ts, which pins the peer-dependency line. That line is byte-identical in this diff, and probe P5 proves the pin is live rather than assumed.
  • Untouched: packages/auth/README.md, packages/plugin-gantt, packages/plugin-kanban, packages/plugin-chatbot.

Probes — predicted in writing, then observed

Every mutation proven on disk (occurrence count of the removed text and of the injected text, plus a blob hash differing from the HEAD blob); every restore proven (blob equal to the HEAD blob and an empty git diff HEAD); each run under an EXIT INT TERM trap restoring by absolute path from HEAD. No rebuild leg applies: none of these mutations touches a package source, and the built dist the gate resolves against is unchanged throughout.

# mutation predicted observed
P1 minWidth: 44 becomes minWidth: '44' in the repaired useTouchTarget block RED RED[semantic] packages/mobile/README.md:208:15 TS2322: Type 'string' is not assignable to type 'number'., 487 of 487 block(s) judged, 1 failed, exit 1
P2 non-breakpoint keys restored to useResponsive, result still rendered GREEN (the union's bare-T branch swallows it) RED, and for a different reason than predictedTS2322: Type '{ mobile: number; tablet: number; desktop: number; } OPT' is not assignable to type 'ReactNode'. The keys are caught only through the downstream use of the inferred type
P2b same keys, result no longer rendered GREEN GREEN487 of 487 block(s) judged, 0 failed, exit 0. This is the coverage limit above, isolated
P3 README reverted to its base content, ledger removal kept RED with the original diagnostics RED486 of 486 block(s) judged, 9 failed, every base-measured code present (TS2304, TS7006, TS1108, TS2345, TS2353), exit 1
P4 ledger entry restored, repaired README kept (ablation of the removal alone) GREEN, coverage falling back to the base figures GREEN203 covered … 24 ungated, 635 — 477 to compile, 158 declared fragment(s), exit 0. The mutated blob equals the base blob 5024e6bf9, so the ablation reproduced the base gate file byte for byte
P5 peer-dependency line changed to add a caret-17 range RED on the pin that reads the same bytes REDdoc-version-claims.test.ts: `packages/mobile/README.md:23 react: README says "^17.0.0
P6 a fabricated name added to a self-import RED REDcheck-readme-exports: 1 README import name(s) NO package exports, naming packages/mobile/README.md:204 -- import { useTouchTargetSize } from '@object-ui/mobile'

P2 is reported as observed rather than as predicted; the prediction was wrong about the mechanism and P2b was added to isolate what it was actually measuring.

Working tree verified clean after the last probe (git status --porcelain empty).

Gates

All at 50ab43b1b, exit codes captured by redirect before any pipe, each quoted from the gate's own verdict line:

gate exit verdict line
check:doc-snippets 0 Every covered documentation snippet compiles against the built types.
check:doc-fences 0 every TypeScript block in 227 document(s) is fenced ts/tsx/typescript …
check:doc-types 0 Every documented component type is registered.
check:readme-exports 0 OK (43 tracked README(s) … 433 of them self-imports judged (433 real, 0 wrong-path, 0 fabricated) …)
check:control-bytes 0 OK (scanned 6417 tracked text file(s); skipped 85 binary)
check-doc-links.mjs 0 Links are valid across 17 scan roots.
check:doc-example-readers 0 OK 80 documented symbol(s), 3947 call site(s) …
type-check:scripts 0 (silent success)
check-changeset-presence.mjs 0 No source or published contract of a released package changed in this range, so no changeset is owed.
check-governed-queue-guard.mjs --test 0 NOT GOVERNED — 2 path(s) checked against 5 governed surface(s); none matched.

A manual grep -naP over the C0 control-byte set on both changed files returns no hits (exit 1).

⚠️ check:readme-exports first exited 1 with 3 findings, all "its type entry ./dist/index.d.ts is not on disk -- run pnpm build first" for plugin-ai, none naming a file in this diff. That is the gate's own by-design precondition refusal, not a verdict about any document. Building plugin-ai and plugin-tree turned it into a real, green measurement — and check:doc-snippets was re-taken afterwards and read identically (204 covered … 645 — 487 to compile, 158 declared fragment(s), 487 of 487 … 0 failed), so the top-up build moved no figure here.

Vitest from the repository root, --maxWorkers=2, through the shared verify lock: Test Files 15 passed (15) / Tests 591 passed (591), exit 0. The suite union is git grep -l for the gate's file name and for the edited document, unioned — it includes scripts/__tests__/check-doc-snippet-types.test.ts, scripts/__tests__/check-readme-exports.test.ts and scripts/__tests__/doc-version-claims.test.ts, the peer-line pin discussed above.

No changeset is added: the presence gate's verdict is that none is owed, and no skip-changeset label is applied — that label is inert in this repository.

No changeset, no queue actions

This pull request stays draft. It is not flipped ready, auto-merge is not enabled, no label and no assignee is written, and the card stays open — the ledger burn-down continues in later batches.

Follow-up filed, not ridden along

#7974useSpecGesture's own @example passes a scalar swipe.direction where the declared type is an array, and the implementation carries the lenient cast that hides it. Seen while reading @object-ui/mobile's built types for this repair; out of this pull request's two-file surface, so it is filed unassigned and unlabelled for triage. Deduplicated against the round-R44 open-issue snapshot plus one targeted search, with a known-hit control query run in the same session so the empty result is a reading rather than a silent zero.

Next takeable, measured on this branch

After this batch the ledger's largest takeable entries tie at 8 blocks:

entry blocks measured diagnostics
packages/plugin-designer/README.md 8 22 (TS2304x11, TS2339x6, TS1003x1, TS1382x1, TS2741x1, TS2552x1, TS2554x1)
packages/i18n/README.md 8 11 (TS2304x7, TS2559x2, TS2554x2)

Under batch 12's tie-break — larger measured debt wins — that is plugin-designer. Flagged rather than assumed: the tie-break rule reads "ties broken by measured debt" without a direction, and both numbers are given so the next dispatch can price it either way.


Generated by Claude Code

…cks compile

Every ts/tsx block in packages/mobile/README.md now compiles --strict against
the built dist/*.d.ts, so the document leaves the check-doc-snippet-types
coverage ledger (24 entries -> 23).

The page did not merely lack self-contained blocks. Six of its examples taught
call shapes @object-ui/mobile has never exported: useGesture's onSwipeLeft /
onSwipeRight / onPinch (the shipped UseGestureOptions is { type, onGesture };
the callback-shaped hook is useSpecGesture), useBreakpoint's `current` (the
field is `breakpoint`), useTouchTarget's { minSize } -> { targetProps } (the
shipped shape is { config: TouchTargetConfig } -> { style, className }),
ResponsiveContainer's mobile / desktop props (the shipped props are
minBreakpoint / maxBreakpoint / showOn / hideOn), registerServiceWorker's
cacheStrategy (that concept lives in the generated worker), and
useResponsive's { mobile, tablet, desktop } keys, which resolveResponsiveValue
never reads, so the documented call returns undefined at every breakpoint.
Those were invisible to the gate only because the surrounding blocks never
imported the symbols they called.

The gate file is edited only inside the UNGATED_DOCS object literal, by
removal: numstat 0 2.

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 package: mobile 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) 3189.5 KB 3191.4 KB
Main entry chunk (gzip) 143.5 KB 350 KB
Entry file index-BiLRQSYR.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) 510.60KB 116.20KB
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.98KB 10.98KB
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.75KB 3.80KB
plugin-calendar (index.js) 47.87KB 13.31KB
plugin-charts (index.js) 70.92KB 19.75KB
plugin-chatbot (index.js) 196.19KB 46.37KB
plugin-dashboard (index.js) 132.88KB 34.69KB
plugin-designer (index.js) 212.86KB 43.19KB
plugin-detail (index.js) 250.55KB 64.06KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 132.87KB 32.66KB
plugin-gantt (index.js) 167.26KB 41.00KB
plugin-grid (index.js) 209.29KB 56.78KB
plugin-kanban (index.js) 52.71KB 14.55KB
plugin-list (index.js) 113.56KB 27.70KB
plugin-map (index.js) 20.44KB 6.78KB
plugin-markdown (index.js) 13.93KB 4.81KB
plugin-report (index.js) 43.59KB 11.97KB
plugin-timeline (index.js) 30.40KB 8.76KB
plugin-tree (index.js) 9.20KB 3.19KB
plugin-view (index.js) 85.24KB 20.94KB
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

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

Labels

documentation Improvements or additions to documentation package: mobile

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants