Skip to content

ci: bound the seven remaining cache saves so bookkeeping cannot void a verdict - #7269

Merged
yinlianghui merged 6 commits into
mainfrom
claude/issue-7048-bound-cache-saves
Sep 2, 2026
Merged

yinlianghui merged 6 commits into
mainfrom
claude/issue-7048-bound-cache-saves

Conversation

@yinlianghui

Copy link
Copy Markdown
Collaborator

Fixes #7048

Every remaining combined actions/cache@v6 use in this repository is split into actions/cache/restore@v6 (in place, unbounded) plus a trailing actions/cache/save@v6 carrying timeout-minutes and continue-on-error: true. Seven sites across five workflows — which, as the card's correction comment recorded, was the repository's default spelling for caching, not an edge case on one job.

The mechanism is #6577's, pinned by PR #7047 and not re-argued here: the combined action declares main: dist/restore/index.js plus post: dist/save/index.js, so its save is a step the runner generates at job end and no workflow syntax attaches timeout-minutes or continue-on-error to it. An upload stall therefore runs the job into its ceiling, the job goes cancelled, and the merge queue cannot tell cancelled from failure. The ordering sentence is carried verbatim into all seven comments: the verdict is recorded by the checking steps; everything after them is bookkeeping, and bookkeeping must never discard an answer the gate already produced.

⛔ No job's timeout-minutes is raised, and none is added. ⛔ No verdict-bearing step is touched.

Population — re-derived, not inherited

Enumeration and content read from the same source (git ls-tree -r, then git show) at adbda1bed:

before after
workflow files enumerated 31 31
combined actions/cache@v6 sites 7 0
split-form restore/save lines 2 (the PR #7047 site) 16 (8 sites)
control: uses: actions/ lines across those files 88 95 (+7, one per split)

The seven sites, each with its own bound

⭐ The card fences copying PR #7047's timeout-minutes: 5 across. Every number below is derived from that site's own measurement; the four .turbo/cache sites landing on 5 is a result of their own arithmetic, not a copy — each comment carries its own working.

workflow:line (at adbda1bed) cache content job ceiling measured healthy save bound live run on this PR
ci.yml:1146 — e2e Playwright browsers, ~269 MB 30 min not directly observable (saves only after a version bump; post = 0s on every sampled run). Restores of the same archive: 3s (jobs 100096569775, 100094597323), 5s in live-e2e.yml 8 min ✅ yes
ci.yml:1311 — docs .turbo/cache 15 min 5s (Post Turbo Cache, job 100094597253) 5 min ⚠️ partial — steps skip on a PR without apps/site//content/ changes; the job's real run is the merge_group build
lint.yml:244 .turbo/cache none (360 default) 6s (job 100097466846) 5 min ✅ yes
live-e2e.yml:98 live backend fixture 40 min 8s (job 100097466897 — a real save; the restore missed) 5 min ✅ yes
live-e2e.yml:163 Playwright browsers, ~269 MB 40 min as ci.yml:1146; restore 5s here 8 min ✅ yes
performance-budget.yml:138 .turbo/cache none (360 default) 1s (job 100096569559) 5 min ✅ yes (self-included in its own paths:)
changeset-release.yml:576 .turbo/cache none (360 default) ⚠️ not observable at this site — see below 5 min ⛔ no (push to main / schedule only)

Bound arithmetic, stated so it is checkable

  • Playwright (8 min). Restores of that exact 269 MB archive measured 3s/3s/5s on this runner class ⇒ the cache service moves it at ~54–90 MB/s downward. Taking a deliberately pessimistic 20x penalty for the upload direction on the slowest observed restore gives ~1m40s for an honest save; 8 minutes is ~4.8x that and demands only 0.56 MB/s sustained to finish. Ceiling check: 8 × 2 = 16 ≤ 30 (and ≤ 40).
  • .turbo/cache (5 min). Same cache, four independent same-day measurements: 1s, 2s, 5s, 6s. 5 minutes is 50x the slowest and 300x the fastest. Ceiling check where one exists: 5 × 2 = 10 ≤ 15.
  • live-e2e.yml has two caches under one ceiling, so what matters is the sum: 5 + 8 = 13 min against a verdict path measured at 2m25s end to end — both bookkeeping halves stalling at once still cannot reach 40.

⚠️ Where the derivation is weaker, said plainly rather than dressed up

changeset-release.yml is the only site with no same-site save measurement. Its release job runs on push to main only when the version is not yet on npm, and on the 6-hourly schedule the primary key is an exact hit — the sampled scheduled run's Post Turbo Cache measured 0s with its restore at 4s (job 99021319583, 2026-08-29). Its bound is therefore derived from the same cache at four sibling sites. It is included rather than left out because the diff there is strictly the cache step plus its comment, the save is appended after publish, after the post-version tree validation and after the refresh, and it carries continue-on-error: true — so nothing the release lane does can be affected by it. The workflow still parses (below). If a directly measured save of that site ever lands outside the 1–6s range, the comment says to re-derive rather than defend the number.

No verdict-bearing step changed — comparison parser output

PR #7047's approach, re-implemented over all five files: parse both revisions with a real YAML parser and compare, per job, every command-bearing (run:) step plus each job's timeout-minutes.

compared .github/workflows/ci.yml: 7 job(s), 50 command-bearing step(s); ceilings: changeset-check=10, type-check=20, test=20, test-coverage=40, coverage-report=20, e2e=30, docs=15
compared .github/workflows/lint.yml: 1 job(s), 11 command-bearing step(s); ceilings: lint=none
compared .github/workflows/live-e2e.yml: 1 job(s), 10 command-bearing step(s); ceilings: live-e2e=40
compared .github/workflows/performance-budget.yml: 1 job(s), 10 command-bearing step(s); ceilings: bundle-analysis=none
compared .github/workflows/changeset-release.yml: 2 job(s), 12 command-bearing step(s); ceilings: lane=none, release=none

TOTAL COMPARED: 12 jobs, 93 command-bearing steps across 5 files

RESULT: no command-bearing step and no job ceiling differs between the two revisions.

CONTROL (BASE vs BASE with one `run:` body mutated — "node scripts/check-changeset-fixed.mjs"):
  - ci.yml[CONTROL] :: job changeset-check: command step GONE or CHANGED: Verify all packages are in changeset fixed group
  - ci.yml[CONTROL] :: job changeset-check: command step NEW or CHANGED: Verify all packages are in changeset fixed group
CONTROL PASSED: the comparator does notice a changed command step, so the RESULT above is non-vacuous.

⭐ The control earned its keep, and the way it did is worth recording. Its first spelling appended # CONTROL-MUTATION to a run: line — YAML reads that as a trailing comment, the parsed scalar never changed, and the control came back clean while the comparator was working perfectly. Exactly the class of trap PR #7047 recorded for its own ablation anchor, caught here only because the control was asserted rather than assumed. The mutation now changes the scalar itself.

Ablation — 21 of them, each proven on disk and each restore proven by blob hash

Three mutations × seven sites, run against the pin: fold the split back, drop continue-on-error, hoist the save above the checking steps. 21 red, 0 green. Every mutation is confirmed on disk before the reading is trusted, anchored on the YAML key at its exact indent — never the phrase, because continue-on-error: true also appears in the comments this change adds (the trap #7047 recorded, inherited deliberately). Every restore is proven by comparing git hash-object against the file's HEAD blob, with an empty hash read as failure.

mutation on-disk proof assertion that caught it
fold split back uses: actions/cache@v6 +1, restore@v6 −1, save@v6 −1 caches through the split form only — never the combined action
drop continue-on-error exact-indent key −1 bounds every save, and lets none of them speak for the code
hoist above checks ⭐ counts are +0 by construction for a move, so this leg measures position instead: save line 260 → last run: 193 before (after: true) vs save 153 → last run: 204 after (after: false) runs every save AFTER its job's last command step

Sample restore proof: restored; blob fed6ab4ad671edbce5d5d271c35f61474cc09c68 == HEAD fed6ab4ad671edbce5d5d271c35f61474cc09c68. Final line: all 5 touched workflow files match their HEAD blobs.

Gates — all run at the final commit 4c67aeddb, verdict lines quoted

gate verdict line
changeset presence ✅ No source or published contract of a released package changed in this range, so no changeset is owed. (6 files changed, 0 published source) — none owed
check:control-bytes ✅ check-control-bytes: OK (scanned 6002 tracked text file(s); skipped 85 binary).
check:shell-escape-residue ✅ check-shell-escape-residue: OK (4/4 root(s) resolved … 205 file(s) and 1318 fenced block(s) examined) — its roots are AGENTS/CLAUDE/skills/content, so it does not scan workflows
check:governed-queue-guard OK check-governed-queue-guard self-test: 132 cases pass; and for this diff's paths: ✅ NOT GOVERNED — 6 path(s) checked against 5 governed surface(s); none matched.
check:lint-coverage ✅ lint coverage: 46/46 packages linted, 0 with outstanding errors (0 total).
YAML parse, all workflows parsed 31 workflow file(s), 39 job(s) total, 0 problem(s) — this is the "changeset-release.yml still parses" evidence; actionlint is neither installed in this container nor referenced anywhere in the repo (git grep actionlint exits 1)
scripts/ vitest suite (every test that reads these workflow files) Test Files 94 passed (94) / Tests 2625 passed (2625)
turbo-cache-save-bound + workflow-cache-save-bound Test Files 2 passed (2) / Tests 14 passed (14)
type-check:scripts exit 0, and --listFiles confirms the new test file is in the program (1 occurrence; #7047's pin as positive control, also 1) — so this is a measurement, not a vacuous pass
eslint root scope in full: 226 files, 0 errors, 29 pre-existing warnings, exit 0, my file present in eslint's own resolved population

Declared narrowing: pnpm lint (turbo run lint, 46 packages) was not run locally. Evidence the narrowing excludes nothing: (1) population read from eslint's own resolution, not a guess — 226 files in the root scope, 46/46 packages reported by check-lint-coverage.mjs; (2) file count read from --format json; (3) eslint.config.js declares no project/projectService/parserOptions (grep exits 1), so it is not type-aware and this diff cannot move any untouched file's verdict — and the diff contains zero files under packages/, apps/ or examples/, so the package farm has no changed input at all. CI runs the farm regardless.

Deviation from the declared file surface — one file, declared not hidden

The card fenced the file surface to the five workflow files. This PR adds one more: scripts/__tests__/workflow-cache-save-bound.test.ts.

The reason is the card's own requirement. "Prove each pin has teeth by ablation" is unanswerable without something that can go red — and reverting any of these seven splits is invisible: the cache still works, every run still passes, and the next transient stall ejects the next green pull request. PR #7047 shipped its split with a pin beside it for exactly this reason and said so in its own body. Without this file the ablation section above would read "21 mutations applied, nothing noticed."

It is a second file rather than an edit to turbo-cache-save-bound.test.ts because the two have different subjects: that one is about one incident and is sized against type-check's numbers; this one is about the population, and asserts its non-vacuity on the population axis — which is precisely the axis that failed when this card was first filed 3.5x low, and which a probe-side control structurally cannot catch.

Live-run coverage on this PR

ci.yml, lint.yml and live-e2e.yml are pull_request-triggered and performance-budget.yml lists its own file in its paths:, so six of the seven sites get a live run on this PR. Two caveats stated rather than glossed: ci.yml's docs job skips its steps on a PR with no apps/site//content/ change, so that site's live proof arrives at the merge_group build; and changeset-release.yml runs only on push to main and on its schedule, so that site gets no live run before merge — the YAML parse and the pin are its whole local evidence.

Not claimed

🤖 Generated with Claude Code

https://claude.ai/code/session_01BGMDbrVa8JjZcCQ7DWYH1b


Generated by Claude Code

Two of the seven combined `actions/cache@v6` uses objectui#7048 measured live
in this file, split per PR #7047's route: `actions/cache/restore@v6` in place
and unbounded, `actions/cache/save@v6` last, bounded and `continue-on-error`.
The save phase of the combined action is a step the runner generates at job end
and no workflow key reaches it, so an upload stall runs the job into its ceiling
and reports `cancelled` — which the merge queue cannot tell from `failure`.

Each bound is derived from that site's own measurement, never inherited:

  - `e2e` / Playwright browsers (~269 MB), ceiling 30 min -> 8 minutes.
    A save is only observable after a version bump, so the bound is sized off
    measured restores of the same archive (3s here on jobs 100096569775 and
    100094597323, 5s in live-e2e.yml job 100097466897) with a deliberately
    pessimistic 20x upload penalty: ~1m40s honest save, bound 4.8x that,
    demanding 0.56 MB/s sustained. 8 x 2 = 16 <= 30.
  - `docs` / `.turbo/cache`, ceiling 15 min -> 5 minutes. This job's own save
    measured 5s on job 100094597253 (a merge_group build, where these steps
    actually run). 5 min is 60x that; 5 x 2 = 10 <= 15.

No job's `timeout-minutes` moves and no command-bearing step changes: all 7
jobs and 50 command steps of this file compare byte-equal against
adbda1b, with a control proving the comparator non-vacuous.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BGMDbrVa8JjZcCQ7DWYH1b
Same split as ci.yml's: restore in place and unbounded, save last with
`timeout-minutes: 5` and `continue-on-error: true`.

Bound derived here, not inherited from PR #7047 — landing on the same number is
a result: this job's own save of `.turbo/cache` measured 6s on 2026-09-02
(`Post Turbo Cache`, job 100097466846) against a 5m14s job, so 5 minutes is 50x
the measured save.

`Lint` is a required context on `pull_request` and `merge_group`, and this job
declares NO `timeout-minutes` — its ceiling is GitHub's 360-minute default, so
an unbounded stalled save could hold the shared serial queue for six hours
before reporting `cancelled`. Adding a ceiling is deliberately NOT done here:
it would change what this gate rejects. The bound is on the bookkeeping step
alone.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BGMDbrVa8JjZcCQ7DWYH1b
This job has two combined `actions/cache@v6` uses; both are split. The saves go
last, ordered Playwright-then-fixture so the observed post-phase order is
preserved (post steps run in reverse registration order — job 100097466897).

Bounds derived per cache:

  - Playwright browsers (~269 MB) -> 8 minutes, from measured restores of the
    same archive (5s here, 3s in ci.yml) plus a pessimistic 20x upload penalty.
  - live backend fixture -> 5 minutes. This site's save measured 8s on
    2026-09-02 (job 100097466897) — a real save, not a skip: the restore missed,
    which is why `Start ObjectStack backend` did the full clone and install.

Both bounds share one 40-minute ceiling, so what matters is their sum:
5 + 8 = 13 minutes against a verdict path measured at 2m25s end to end, so even
both bookkeeping halves stalling at once cannot reach the ceiling.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BGMDbrVa8JjZcCQ7DWYH1b
Same split; `timeout-minutes: 5`, `continue-on-error: true`, save placed last —
after the budget verdict and after the comment that reports it, which is where
the generated post phase already ran.

Bound derived from this site: this job's own save of `.turbo/cache` measured 1s
on 2026-09-02 (`Post Turbo Cache`, job 100096569559) against a 4m07s job, so
5 minutes is 300x it. That is the same RATIO PR #7047 sized its bound at,
arrived at from this job's own number rather than copied from that one.

`Bundle Analysis` is a required context (objectui#6245) and this job declares no
`timeout-minutes`, so its ceiling is the 360-minute default — the bound is the
only thing that stops a stalled save holding a required check open for hours.
Adding a ceiling would change what the gate rejects and is deliberately not done.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BGMDbrVa8JjZcCQ7DWYH1b
The release lane, treated with extra care: the diff is strictly the cache step
and its comment, the save is appended LAST — after publish, after the
post-version tree validation and after the refresh — and no step above it is
touched. Publishing cannot be affected by a step that runs after all of it and
carries `continue-on-error: true`.

The derivation here is weaker than at the other six sites and the comment says
so rather than dressing it up. A same-SITE save was not observable in the
sampled runs: this job runs on `push` to `main` only when the version is not
yet on npm, and on the 6-hourly `schedule` the primary key is an exact hit — the
sampled scheduled run's `Post Turbo Cache` measured 0s with its restore at 4s
(job 99021319583, 2026-08-29). The bound is therefore derived from the SAME
CACHE at four sibling sites, whose saves measured 1s, 2s, 5s and 6s on
2026-09-02 (jobs 100096569559, 100096569872, 100094597253, 100097466846);
5 minutes is 50x the slowest of those.

This job declares no `timeout-minutes` either, so its ceiling is the 360-minute
default. Adding one is NOT attempted: the release act must never be truncated by
a clock.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BGMDbrVa8JjZcCQ7DWYH1b
Reverting any of the seven splits is invisible — the cache still works, every
run still passes, and the next transient stall ejects the next green pull
request. PR #7047 shipped a pin for exactly that reason; this one generalises it
from the one incident site to the population, because the population is what
this card found: seven more combined uses across five workflows, the
repository's default spelling for caching.

Enumerates every workflow file and requires of every `actions/cache/save`:
`timeout-minutes` present, `continue-on-error: true`, placed after its job's
last command step, same path and key as a matching restore with an `id`, and
guarded on that restore's `cache-hit`. Where a job declares a ceiling, the SUM
of its save bounds x 2 must fit inside it — the generalisation of #7047's
invariant to a job with more than one cache.

Non-vacuity is asserted on the axis that actually failed when this card was
filed: the POPULATION, not the probe. A control on a probe cannot catch a scope
inherited from someone else's narrative, which is how the first count came in
3.5x low.

Deliberately not asserted: that restore halves are bounded (a restore stall
fails before any verdict exists, which is honest), and any specific bound
value — each site's number is derived from that site's own measurement and lives
in the comment beside it.

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

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 48 chunks) 3160.2 KB 3191.4 KB
Main entry chunk (gzip) 142.6 KB 350 KB
Entry file index-BOEfHVe7.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.33KB 5.59KB
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) 514.46KB 117.29KB
core (index.js) 5.55KB 2.23KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 178.20KB 49.60KB
fields (index.js) 244.25KB 61.73KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
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.44KB 1.39KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 26.89KB 9.04KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 33.40KB 8.71KB
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.55KB 0.62KB
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 (useResponsiveConfig.js) 1.37KB 0.63KB
mobile (useSpecGesture.js) 4.32KB 1.64KB
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) 46.92KB 12.93KB
plugin-charts (index.js) 70.02KB 19.44KB
plugin-chatbot (index.js) 190.53KB 45.18KB
plugin-dashboard (index.js) 132.63KB 34.56KB
plugin-designer (index.js) 212.87KB 43.19KB
plugin-detail (index.js) 250.65KB 63.91KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 132.78KB 32.58KB
plugin-gantt (index.js) 166.77KB 40.76KB
plugin-grid (index.js) 208.88KB 56.59KB
plugin-kanban (index.js) 53.21KB 14.66KB
plugin-list (index.js) 113.51KB 27.67KB
plugin-map (index.js) 20.20KB 6.66KB
plugin-markdown (index.js) 13.72KB 4.69KB
plugin-report (index.js) 43.51KB 11.94KB
plugin-timeline (index.js) 29.34KB 8.47KB
plugin-tree (index.js) 8.98KB 3.08KB
plugin-view (index.js) 85.90KB 21.12KB
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) 3.11KB 1.48KB
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 0.99KB
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 (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.72KB 2.24KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 2.59KB 1.31KB
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 (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) 3.40KB 1.71KB
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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ci] SEVEN more combined actions/cache saves carry the unbounded-save exposure #6577 measured — across five workflows, not just ci.yml

2 participants