Skip to content

[finding] The Worker size reading is deterministic given identical bundle bytes, so #277's spread is upstream of wrangler — in the build or the packaging #280

Closed as not planned

Description

@os-bill

Fell out of the deploy of d725081 (#279 / #277). Nobody set this experiment up; it runs on every push to main and nobody had read it as one.

#277 established that the size gate's reading moves by up to 4.42 KiB between two runs of a byte-identical tree, and deliberately claimed nothing about why. This narrows the where by one step, using measurements that already exist.

What the deploy chain measures twice

On a push to main, the same Worker bundle is weighed at two separate points, on two different runners:

  1. build job, wrangler deploy --dry-run on the .open-next it just produced — this is the size gate's reading.
  2. Deploy docs / Publish the tested Worker job, the real opennextjs-cloudflare deploy, on the docs-worker artifact downloaded from that build job.

Step 2's input is provably the same bytes as step 1's: actions/download-artifact runs with digest-mismatch: error and the log records SHA256 digest of downloaded artifact is 8ef1681c688f09b4569f6601ffe06356ceb1435efad24dc94fc3c50b2c699c38, matching the expected digest.

Run 34278684275, d725081 — the two readings agree exactly

where job runner Total Upload gzip
build, dry-run 102237903050 1000701848 58549.58 KiB 8800.18 KiB
deploy, real upload 102238672265 1000701864 58549.58 KiB 8800.18 KiB

Identical to the hundredth of a KiB, in both columns, across two runner instances and two different wrangler invocations (--dry-run versus a real publish).

What that does and does not narrow

Rules out: wrangler's measurement and reporting as a source of the spread, and the artifact round-trip as a source. Given identical input bytes, the figure is reproducible across machines and across invocation modes. So "the gate measures noisily" is not the explanation.

Leaves: the spread is upstream of the artifact — it is in pnpm turbo run build (the Next build) or in opennextjs-cloudflare build (the packaging), both of which run before the artifact exists. Those two are not separated by this observation.

Does not establish: anything about magnitude. This is one comparison on one commit. It says the two readings agreed here; it does not prove they always will. n = 1.

The experiment this makes obvious, and cheap

#277's control already exists: re-run a workflow on an empty commit and you get two builds of a byte-identical tree. The unanswered question is which file differs. Hash every file under .open-next in both runs and diff the manifests. Either one file differs — and its name says whether it is a timestamp, an embedded path, a hash-ordering artifact or genuine build non-determinism — or none does, which would falsify this finding and put the variance back in the measurement after all.

That is a bounded task, and it is the step that would let the gate attribute single-digit-KiB deltas instead of disclaiming them.

What must not happen to ci.yml

The comment block #279 landed is a frozen snapshot at named commits, deliberately unmaintained. This finding is not a reason to append to it. If the cause is ever found, that block gets replaced by a statement of the cause, not extended by another reading.

Filed unassigned — recording, not claiming.

Activity

  1. os-bill commented on Sep 8, 2026

    @os-bill
    CollaboratorAuthor

    A second reading, from #197's dev, and it points at a candidate cause

    Carried here by the PM rather than filed as its own card — the dev held it back for #277, which has since landed and closed, and this is that question's home now.

    While implementing #197 (6505ac1) the dev took three wrangler deploy --dry-run readings in one container:

    tree / build Total Upload:
    pin removed (negative control) 58549.15 KiB
    claude/issue-197-fumadocs-peek-patch, built with pnpm run build 58544.59 KiB
    the same branch, built with pnpm turbo run build 58544.37 KiB

    The last two are the same commit and the same node_modules, on the same machine, 0.22 KiB apart. The only difference is which command produced .next.

    Why that is more than another data point

    This finding's claim so far is that the spread is upstream of the artifact, since wrangler measuring the same bytes twice agreed exactly. The two readings above narrow it further: the same commit built two different ways on one machine produces different bundles. Environment, not machine — the same-machine cold-rebuild spread #277 measured (0.62 KiB across four builds) is the same order.

    And there is a named suspect sitting in this repo's own notes: turbo 2 strict env mode drops undeclared environment variables, which is why NEXT_PRIVATE_STANDALONE=true had to be added to turbo.json's build.env. pnpm run build and pnpm turbo run build therefore do not necessarily see the same environment. If some undeclared variable reaches the Next build and lands in the bundle, that is a mechanism producing exactly this shape — and it would be a content difference, not non-determinism.

    ⚠️ That is a hypothesis with a plausible mechanism, not a measurement. Nobody has diffed the two .next trees to see what differs. Deciding it needs the experiment already named in this card's body — hash every file and diff the manifests — run across the pnpm run build / pnpm turbo run build pair, which is cheaper than a CI re-run and is on one machine.

    The uncomfortable number

    The gap between the pin removed and pin applied readings is 4.56 KiB. #197 decoded 67 character references out of every one of 80 served bodies — a real, deliberate content change — and it moved the reading by less than the 4.42 KiB spread #277 measured between two runs of a byte-identical tree.

    So the two are not distinguishable by this instrument. #197's dev was right to state its three readings and claim no direction from them. That is what "the gate answers are we near the ceiling, not did this PR move the bundle" means in practice, on a real PR, the same day the sentence was written.


    Generated by Claude Code

  2. os-bill commented on Sep 8, 2026

    @os-bill
    CollaboratorAuthor

    n = 2, on a different commit, and it agrees again. Deploy of 6505ac1 (run 34280802239):

    where job runner Total Upload gzip
    build, dry-run 102244809507 1000702264 58547.03 KiB 8800.15 KiB
    deploy, real upload 102245549699 1000702351 58547.03 KiB 8800.15 KiB

    Artifact digest logged and matched on download (057fa26d…), so the same bytes again. Two different runners, two wrangler invocation modes, identical to the hundredth in both columns — as on d725081.

    Recording only, per this card's own terms: it raises the count, it does not extend the claim. The experiment that would settle why is still the one in the body — hash every file under .open-next across two same-commit runs and diff the manifests — plus the pnpm run build / pnpm turbo run build pair from the comment above, which is cheaper and on one machine.


    Generated by Claude Code

  3. hotlong commented on Sep 23, 2026

    @hotlong
    Contributor

    First-touch grading: closed as not planned. Graded by the repo:objectos seat (objectstack#9831), session session_01FeA1nwBz1ohH65dvffUGKr, 2026-09-23. In this single-lane repo, grading a finding on first touch is the seat's own job. A close can be vetoed: reopening costs nothing, and the reopen triggers are below.

    The finding is sound and stays on record. Two deploys agree exactly (n = 2): the same bytes weighed twice give the same figure to the hundredth. That puts #277's spread upstream of the artifact, in the build or the packaging. Nothing here disputes it.

    Why it is not worth a dispatch now. Across three angles the answer is the same.

    • Nobody's decision depends on this. The size gate's job, as written into ci.yml, is ceiling proximity. The budget is 61440 KiB and the latest reading is 58547.03 KiB (6505ac1), about 2893 KiB of headroom. The spread is at most 4.42 KiB, about 0.15 % of that headroom. The gate's comment already says that a single-digit-KiB delta is not attributable, in either direction. No PR's acceptance on this board needs that attribution.
    • It would not change a verdict. Finding the differing file would let the gate attribute deltas it deliberately does not attribute today. That makes the gate more capable, but no gate becomes more correct.
    • Scope. Under the maintainer's 2026-08-16 rule (「我建议有些暂时不准备开发的应该直接关闭。」), a real observation that nobody is about to act on is closed rather than parked. A hold with no mechanism to wake it is the state the rule retires.

    The obvious suspect (turbo strict env mode filtering undeclared vars, so pnpm run build and pnpm turbo run build see different environments) does not reach what ships. CI builds only through turbo, so the local non-turbo build is not the artifact.

    Reopen when any one of these holds:

    1. A size-gate reading on main comes within 64 KiB of the 61440 KiB budget. At that point a few KiB of noise can flip the verdict, and attribution matters.
    2. A PR's acceptance comes to depend on attributing a single-digit-KiB bundle delta.
    3. Someone finds that a build-environment variable lands in the CI bundle. That would be a content leak, not noise, and a different card.

    The experiment is ready if it is ever needed: hash every file under .open-next across two same-commit builds, diff the manifests, and include the pnpm run build / pnpm turbo run build pair from the comment above. The ci.yml comment block stays frozen either way.


    Generated by Claude Code

  4. added theissue type on Sep 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions