Repository navigation
Expand file tree
/
Copy path.image-size-baseline.json
More file actions
35 lines (35 loc) · 17.3 KB
/
Copy path.image-size-baseline.json
File metadata and controls
35 lines (35 loc) · 17.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
{
"note": "Ceiling for the published image (#2132). Compressed bytes - what crosses the wire on a pull. MEASURED IN CI (ubuntu-latest, docker-build-smoke.yml), because that is the environment that gates. NEVER lower this to match a laptop - and the reason is now PROVEN, not assumed (#2134): the number depends on the DAEMON'S IMAGE STORE. The same published artifact (ghcr.io/astrapi69/adaptive-learner:2.8.2, amd64) measured 125606171 bytes on a runner (classic graphdriver, overlay2) and 112828486 bytes on a containerd-image-store machine - 12.78 MB apart, same command, same bytes of content. docker save emits already-compressed blobs under the containerd store and raw layer tars under the classic graphdriver, and gzip -1 packs the latter far worse. Base-image and apt drift were the ORIGINAL guess here and are ruled out: the local base image was digest-identical to the current one (docker pull -> 0 byte delta).",
"compressed_bytes": 129808688,
"measured_in": "ci/ubuntu-24.04",
"_runner_pin_3732": "Pinned 2026-10-12 (#3732): the amd64 ceiling is measured on ubuntu-24.04 in docker-build-smoke.yml, the amd64 leg of publish-image.yml and the amd64 branch of image-size-measure.yml, no longer on ubuntu-latest, which moves to 26.04 from 2026-10-19. The runner's image store alone moves the reading by 12.8 MB for identical content (#2134), so a runner-image change must be a deliberate re-anchor (#3733), never a silent one. arm64 has been pinned to ubuntu-24.04-arm from the start.",
"_tightening": "Tightening stays MANUAL (#2140): the gate offers headroom above the jitter tolerance but never applies it. This ceiling is a CI measurement; a local run lowering it would pin the project to one machine's IMAGE STORE, which is worth ~12.8 MB (#2134, proven by measuring the same published image on both stores - run 30638091353).",
"_raise_2575": "Raised 125668464 -> 126148228 (#2575, docker-build-smoke.yml run 31693708819): eruda, the ?debug=1-gated on-device debugging console, ships in frontend `dependencies` because it must be fetchable on the deployed build, not just local dev - its chunk is excluded from the PWA precache (globIgnores) but still ships as a static asset in the image's frontend/dist. Deliberate --allow-raise, CI-measured, not a local reading.",
"per_arch": {
"amd64": 129808688,
"arm64": 128422931
},
"_per_arch_note": "Per-architecture ceilings (#2147) - two published architectures are two environments (#2136 point 5), so neither may borrow the other's number. amd64 carries the CI measurement from docker-build-smoke.yml. arm64 was seeded from image-size-measure.yml run 30532123506 (native ubuntu-24.04-arm, gzip -1, after the #2163 runs-on fix; the workflow reports and a human enters, per #2140).",
"_measurement_paths": "Seeding measures a locally built+loaded image; enforcement measures one pulled from a registry. Verified 2026-07-29 that both paths mean the same number: the same image measured locally and after a push/pull round-trip through a throwaway registry:2 differed by 14 bytes of 112325662 (0.000%) - three orders of magnitude inside the 2 MB rebuild-jitter tolerance. So a ceiling seeded from a measurement run is valid against the published artifact. Re-verify if the packaging changes (a different registry, a different image store, or zstd-compressed layers).",
"_tolerance_note": "Tolerance is +/-500000 bytes around each ceiling (raised from 200000, #2926): ~10.5x the measured rebuild jitter (47651 bytes between identical-content builds), still 4x tighter than the previously-rejected 2MB (which let a real 66106-byte regression pass unnoticed, #2135). Above ceiling+tolerance fails (growth); below ceiling-tolerance fails too (an unexpected shrink is a finding, #2135 both directions). Ceilings re-anchored to the v2.8.0 PUBLISHED per-arch measurements (run 30548288561) so the next growth is measured from what users actually pull.",
"_lower_2610": "Lowered amd64 126148228 -> 125781551 (#2610, docker-build-smoke.yml run 31874060583): eruda no longer ships in the production image (dev-only build flag), reversing the _raise_2575 raise. CI-measured on this PR's build, not a local reading. arm64 stays at 124288511: no fresh native-arm measurement exists for the eruda-less image (seeding is manual via image-size-measure.yml, #2140), and the expected eruda-less arm64 size (~124.4 MB, published v2.12.0 124808422 minus the ~0.37 MB eruda shed) sits within the +/-200000 tolerance of the existing ceiling - the next publish run measures it for real; re-anchor then if it drifts.",
"_raise_2625": "Raised amd64 125781551 -> 126388990 (#2625, docker-build-smoke run on chore/2625-fastapi-141): fastapi 0.136->0.141 + starlette 1.3->1.6 and their transitives across backend + all plugins. Deliberate --allow-raise semantics, CI-measured on this PR's build, not a local reading. arm64 expected to grow by the same dep set - re-measure via image-size-measure.yml before the next publish (#2140 flow).",
"_arm64_reseed_2625": "arm64 124288511 -> 125547583 (#2625): seeded from image-size-measure.yml run 31889612661 (native ubuntu-24.04-arm, MEASURED line), the #2140 flow - the workflow reports, this entry is the human step. Covers the eruda removal (#2610) minus the fastapi-0.141 growth in one re-anchor; the next publish run verifies against it.",
"_raise_2650": "Raised amd64 126388990 -> 126946549 (#2650, docker-build-smoke run 32023108450 on chore/2650-anthropic-sdk-122): anthropic SDK 0.55 -> 0.122 (+ new transitive docstring-parser) in the ai-anthropic plugin, installed into the backend image via the combined lock. Deliberate --allow-raise semantics, CI-measured on this PR's build, not a local reading. arm64 expected to grow by the same pure-python dep set - re-measure via image-size-measure.yml (#2140 flow) and re-anchor.",
"_arm64_reseed_2650": "arm64 125547583 -> 126095576 (#2650): seeded from image-size-measure.yml run 32023355109 (native ubuntu-24.04-arm, MEASURED line), the #2140 flow - the workflow reports, this entry is the human step. Same anthropic-0.122 dep growth as the amd64 raise (_raise_2650); the next publish run verifies against it.",
"_arm64_lower_2748": "Lowered arm64 126095576 -> 125675448 (#2748, publish run 32840213174): first PUBLISH-run measurement of the arm64 artifact after two estimate-based reseeds (_lower_2610 expected-value, _arm64_reseed_2650 measure-run) - the 420,128-byte delta is the accumulated estimate error surfacing, not a regression; amd64 passed within tolerance on the same run. CI-measured in the ENFORCEMENT environment itself (the publish run's arm64 verify job), not a local reading. Deliberate lower per the shrink-direction rule (#2135 both directions, #2140 human-entered).",
"_raise_2855": "Raised amd64 126946549 -> 130386089 (PR #2855, docker-build-smoke run 33561294148 on claude/iphone-focus-navigation-debug-a7txf8 with develop merged in): accumulated develop feature growth since _raise_2650 - 49 commits whose PRs never tripped the path-filtered gate (speech-recording + audio exercise renderers #2840/#2841/#2846, preset avatar gallery #2851, Spielmodus + Lernfunke mascot #2845/#2852, DiagnosticsPanel #2782/#2789, i18n batches across 11 catalogs, sync-table surface #2827; 447 files, ~17.7k insertions, no single binary asset). First PR to touch a Docker input since then measures the sum. Deliberate --allow-raise semantics, CI-measured on this PR's build, not a local reading. arm64 expected to have grown by the same frontend/backend content - re-measure via image-size-measure.yml (#2140 flow) and re-anchor before the next publish.",
"_raise_2922": "Raised amd64 130386089 -> 130610330 (PR #2922, docker-build-smoke run 33840644938, top-level `compressed_bytes` corrected in a follow-up commit - the PR gate step calls verify_image_size.py without --arch and reads the top-level field, not per_arch; an initial per_arch-only edit left the gate reading the stale ceiling): dependabot backend-minor-patch group - pydantic 2.13.4 -> 2.13.5, platformdirs 4.11.4 -> 4.11.5, cryptography 50.0.0 -> 50.0.1, all main-group deps installed into the prod image (`poetry install --only main`). ruff and datamodel-code-generator in the same group are dev-only and excluded from the image; not the cause. Deliberate --allow-raise, CI-measured on this PR's build, not a local reading. arm64 expected to grow by the same pure-python/compiled-wheel delta - re-measure via image-size-measure.yml (#2140 flow) and re-anchor before the next publish.",
"_raise_2923": "Raised amd64 130610330 -> 130624726 (PR #2923, docker-build-smoke run 33840436317, rebased onto #2922 after it merged first the same day): dependabot frontend-minor-patch group, 36 updates - no single package identified as the driver (routine minor/patch bumps across the frontend dependency tree, bun.lock churn, incl. happy-dom 20.11.6 -> 20.12.0). Both compressed_bytes (top-level, read by the docker-build-smoke PR gate step which calls verify_image_size.py without --arch) and per_arch.amd64 set together from the same CI measurement, per the #2922 lesson same-day: the gate step reads the top-level field, per_arch alone is not enough. A deliberate buffer above this measurement was tried and reverted - the gate fails BOTH directions (#2135), so any ceiling meaningfully above the true measurement trips the shrink check on the very next PR instead of the growth check; there is no slack to bank, see _tightening. Deliberate --allow-raise, CI-measured on this PRs build, not a local reading. arm64 expected to grow by the same frontend asset delta - re-measure via image-size-measure.yml (#2140 flow) and re-anchor before the next publish.",
"_arm64_reanchor_2933": "arm64 125675448 -> 129754458 (publish-image.yml run 33864600131, the v2.14.0 release publish, ENFORCEMENT-environment measurement - the publish run own arm64 verify step, not a separate image-size-measure.yml seed): accumulated develop growth since the last re-anchor (#2748) never re-measured because every intermediate raise in this release cycle (#2922, #2923, #2926) only touched amd64 (the PR-gate architecture); arm64 has no PR-time gate, only this publish-time one, so it drifted silently until publish caught it - exactly the re-anchor-before-next-publish gap the prior notes flagged. Deliberate, CI-measured in the real enforcement environment.",
"_arm64_reanchor_3156": "arm64 129754458 -> 132819562 (publish-image.yml run 35199359621, the v2.15.0 release publish, ENFORCEMENT-environment measurement from its own arm64 verify step, the #2933 flow): arm64 has no PR-time gate, so growth since the v2.14.0 re-anchor accumulated unmeasured - learn-content-engine 0.23 -> 0.26, the v2.15.0 features and the #3144 dependency sweep. Deliberate, CI-measured in the real enforcement environment.",
"_raise_3111": "Raised amd64 130624726 -> 133474152 (PR #3111, docker-build-smoke run 34990848751 / job 104454794593): the learn-content-engine pin bump 0.23.0 -> 0.24.1 (#3108) is the ONLY dependency that moved - bun.lock diffed to exactly one changed line, no other package added, removed or bumped, so the whole +2849426 bytes is attributable to that single package. Two engine minor releases' worth of accumulated code (QTI import/export, stable-id minting/coverage tooling, migrate.js, the variables/declared-extensions/content-domains/release-parity modules) ships in the frontend bundle the app imports runtime parse/validate/migrate functions from, not just types. Both compressed_bytes (top-level, read by the docker-build-smoke PR gate step which calls verify_image_size.py without --arch) and per_arch.amd64 set together from the same CI measurement, per the #2922/#2923 lesson. Deliberate --allow-raise, CI-measured on this PR's build, not a local reading. arm64 expected to grow by the same engine-bundle delta - re-measure via image-size-measure.yml (#2140 flow) and re-anchor before the next publish.",
"_backmerge_provisional": "This back-merge (main -> develop, restoring the #334/#2182 Gitflow contract after #3111/#3112/#3115 landed directly on main) combines two independently-measured trees: main's amd64=133474152 (_raise_3111, the engine-pin bump) and develop's arm64=129754458 (_arm64_reanchor_2933, accumulated develop-only growth since the last common ancestor). Neither parent's ceiling reflects the ACTUAL merged tree per the 'ratchet baseline is itself a measurement' lesson (lessons/ci-gates.md) - this pairing is a provisional maximum-of-both starting point, not a CI measurement of this PR's build. docker-build-smoke.yml on this back-merge PR is the authoritative re-measurement; if it reports outside tolerance, follow it with a same-pattern _raise_NNNN/_lower_NNNN entry rather than trusting this note's numbers.",
"_lower_3187": "Lowered amd64 133474152 -> 128208956 (#3187, docker-build-smoke.yml run 35825277337 on PR #3184; the weekly develop run 35588595999 on 2026-09-21 already measured 128181637). No image input changed between the 133.9 MB runs of 2026-09-17 and the 128.2 MB runs (no Dockerfile/compose/lock/package diff, no package left the lock); the shrink is build-environment drift (base-image digest, apt, runner tar/gzip), the downward twin of #2134. CI-measured number entered by hand via --size-bytes; arm64 untouched until image-size-measure.yml reports again.",
"_arm64_lower_3159": "Lowered arm64 132819562 -> 126825345 (#3159, the first weekly publish-image DRY RUN on develop, run 36610482730, its own native ubuntu-24.04-arm verify job measuring the locally built+loaded image, the path _measurement_paths verified equal to a pull within 14 bytes). The 5994217-byte shrink is the arm64 twin of _lower_3187: the amd64 reading in the same run sat within tolerance of its already-lowered ceiling (128208956), and the arm64 ceiling still carried the v2.15.0 publish measurement from 2026-09-17, before the build-environment drift (base-image digest, apt, runner tar/gzip) that took 5.3 MB off amd64 with no image input changed. Nothing left the image: develop since v2.15.0 only ADDED (engine 0.26 -> 0.34, the #3169 runner refactors). CI-measured number entered by hand via --size-bytes; the next dry run or publish verifies against it.",
"_raise_3541": "Raised amd64 128208956 -> 131515115 (#3541, 2026-10-02; back-merge PR of release/2.16.0, docker-build-smoke job 110767361155): accumulated develop growth since the 2026-09-23 measurement (_lower_3187) - learn-content-engine 0.26 -> 0.36 across several re-pins (#3238, #3529, #3532; the app imports the engine's runtime parse/validate/rules modules, not just types) plus the v2.16.0 frontend work (error surfaces, tutor-chat error states, exercise-editor engine check, footer status). The first PR to touch a Docker input since then measures the sum. Deliberate --allow-raise, CI-measured on this PR's build, not a local reading. arm64 untouched: re-measure via the publish run's arm64 verify step (#2933 flow).",
"_raise_arm64_3545": "Raised arm64 126825345 -> 130466477 (#3545, 2026-10-02; publish-image.yml run 37024516951, the v2.16.0 release publish, ENFORCEMENT-environment measurement from its own native arm64 verify step, the #2933 flow): the arm64 twin of _raise_3541. Same cause - learn-content-engine 0.26 -> 0.36 across several re-pins (#3238, #3529, #3532; the app imports the engine's runtime parse/validate/rules modules) plus the v2.16.0 frontend work - accumulated unmeasured because arm64 has no PR-time gate. 3641132 bytes over the ceiling lowered by #3159 on 2026-09-29. Deliberate, CI-measured in the real enforcement environment, not a local reading.",
"_lower_3187b": "Lowered amd64 131515115 -> 128394208 (#3187 recurrence, docker-build-smoke.yml run 37630917754, 2026-10-07). Last green: develop schedule run 37306889521 on 2026-10-05; first red: 2026-10-06 12:23Z on the i18n-only branch of #3576, whose merge base is that green commit, so no image input changed. python:3.12-slim (final stage) was republished on Docker Hub 2026-10-06 11:07Z (digest sha256:05cda9777409..., the one the red runs resolve). Build-environment drift, same class as _lower_3187; CI-measured number entered by hand via --size-bytes; arm64 untouched until its own measurement reports.",
"_raise_3550": "Raised amd64 128394208 -> 129808688 (#3550, docker-build-smoke run 37741416045 on PR #3669, 2026-10-08): SQLAlchemy 2.0.54 -> 2.1.4 with the asyncio extra. 2.1 no longer pulls greenlet by default; app/database.py builds an async engine, so the backend declares sqlalchemy[asyncio] and greenlet stays. Develop without the bump measured 128397334 in the same hour (run 37742069911, PR #3670), so the bump accounts for +1411354 bytes. #3540 measured about +0.73 MB for 2.1.1 WITHOUT greenlet; the difference is greenlet, which the async engine needs. Deliberate --allow-raise, CI-measured; arm64 untouched until its own measurement reports.",
"_arm64_lower_3730": "Lowered arm64 130466477 -> 128422931 (#3730, 2026-10-12; the weekly publish-image dry run on develop d90859726, run 38248071878, its own native ubuntu-24.04-arm verify job 114812000659 - the ENFORCEMENT environment, entered by hand via --size-bytes, not a local reading; the branch dispatch run 38254524031, job 114835062917, measured 128418627, 4304 bytes of jitter apart). The arm64 twin of _lower_3187b plus _raise_3550: python:3.12-slim was republished on 2026-10-06 and took 3.12 MB off amd64 with no image input changed, then SQLAlchemy 2.1 with greenlet added 1.41 MB; both notes left arm64 untouched until its own measurement reported. Expected arm64 delta about -3.1 + 1.4 = -1.7 MB, measured -2.04 MB. Nothing left the image. From now on the gate prints its reading as a ::notice annotation, readable over the API."
}