Skip to content

Commit ad0a800

Browse files
docs(vrs): measure cross-platform evaluation determinism
CMP-A03 (evaluation is reproducible) said it must be tested rather than assumed. Tested. A representative plan's canonical serialization is byte-identical across x86_64-linux, aarch64-linux, and aarch64-darwin — hash 5160e9b3 on all three. The property several requirements rest on is now measured, not inferred. Method: identity is the hash of the evaluated value and transpilation does not enter it, so the only platform-variable component is the JS engine. QuickJS-ng's standalone qjs is in nixpkgs, so the engine was exercised directly via `nix shell nixpkgs#quickjs-ng` on all three arches without building the pipeline. Honest surprise, recorded in the experiment: the transcendental Math functions matched on Apple libm too, so the predicted glibc-vs-Apple divergence did not reproduce for these inputs on 0.14.0. That does not refute the primary sources (input- and version-specific) and does not prove transcendentals agree in general — but it does show the Math lock is insurance, not a demonstrated-necessary fix. Plan identity is safe because plans do no such arithmetic at all, not because the lock catches a divergence about to corrupt a hash. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QzRc44KbA3wfYYKFF9UDMa agent-session-id: cdf2c185-eeb3-4a4d-8ce0-52885f145cac agent-tool: Claude Code agent-tool-version: 2.1.215 agent-model: claude-opus-4-8 agent-runtime-profile: /nix/store/acr8a3l2v366jgmwiq8xdrhgz1py0db5-coding-agent-runtime-profile/share/coding-agents/profile.json agent-skills-manifest: /nix/store/sj1v5j91h8v8d1w9lca4040302lwrd6v-agent-skills-corpus/share/agent-skills/manifest.json tooling-profile: dotfiles@unknown-dirty
1 parent 43c5f09 commit ad0a800

2 files changed

Lines changed: 88 additions & 1 deletion

File tree

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Cross-platform evaluation determinism
2+
3+
Date: 2026-07-25
4+
5+
Validates the property that a plan's identity is the same on every platform —
6+
the basis for "same source produces the same version everywhere", which several
7+
requirements rest on and which had been an inference rather than a measurement.
8+
9+
## Hypothesis
10+
11+
Evaluating a plan produces byte-identical output on x86_64-linux,
12+
aarch64-linux, and aarch64-darwin, because a plan is pure data construction and
13+
the only platform-variable surface identified in earlier research —
14+
libc-delegated transcendental Math — is not reached by a plan and is removed
15+
from the evaluation global regardless.
16+
17+
## Method
18+
19+
Plan identity is the hash of the evaluated value's canonical serialization, and
20+
transpilation does not enter identity (0011 Amendment 1), so the only
21+
platform-variable component is the JavaScript engine. The engine is QuickJS-ng
22+
(0011), whose standalone interpreter `qjs` is in nixpkgs, so the engine could be
23+
exercised directly without building the full pipeline.
24+
25+
A probe constructed a representative evaluated plan — nested objects and arrays,
26+
Unicode and combining-character strings, integer and non-integer arithmetic, and
27+
integer-like object keys to exercise the key-ordering rule — and printed its
28+
canonical serialization. As a negative control it also printed the transcendental
29+
Math functions the design removes from the global, to see whether they were in
30+
fact a source of cross-platform divergence.
31+
32+
The identical probe ran under `nix shell nixpkgs#quickjs-ng -c qjs` on three
33+
machines spanning both dimensions that could matter, architecture and libc:
34+
35+
| Machine | Platform |
36+
| --- | --- |
37+
| local | x86_64-linux (glibc) |
38+
| dev4 | aarch64-linux (glibc) |
39+
| mbp2025 | aarch64-darwin (Apple libm) |
40+
41+
The serialized-plan line was hashed on each and compared.
42+
43+
## Result
44+
45+
The canonical plan serialization was **byte-identical on all three platforms**
46+
(SHA-256 `5160e9b3…`). The hypothesis holds: a plan's identity does not depend on
47+
the platform it is evaluated on.
48+
49+
The negative control was more interesting than expected. Every transcendental —
50+
`sin`, `cos`, `exp`, `log`, `pow`, `tanh` — was **also identical across all
51+
three**, including on Apple libm. The predicted glibc-vs-Apple-libm divergence
52+
did not manifest for these inputs on QuickJS-ng 0.14.0.
53+
54+
## Interpretation
55+
56+
The load-bearing conclusion is unaffected and now measured rather than assumed:
57+
plan identity is platform-independent, because a plan constructs data and touches
58+
none of the platform-variable surface.
59+
60+
The control result is a genuine discrepancy with the earlier research, which read
61+
QuickJS-ng master delegating every transcendental straight to libc and cited
62+
1-ULP glibc/Apple disagreements. Two readings are consistent with both: the
63+
disagreements are input-specific and these inputs happen to agree, or 0.14.0
64+
differs from the master source that was read. This experiment does not
65+
distinguish them, and does **not** establish that transcendentals agree across
66+
platforms in general — only that they did here.
67+
68+
The Math lock therefore stands as insurance rather than a demonstrated-necessary
69+
fix: primary sources still show some inputs diverge, a plan has no reason to call
70+
these functions, and removing them costs three lines. What this experiment
71+
establishes is that the lock is not load-bearing for plan identity — identity is
72+
safe because plans do not do arithmetic of this kind at all, not because the lock
73+
catches a divergence that was about to corrupt a hash.
74+
75+
## Threats to validity
76+
77+
- One probe, one set of Math inputs. A wider input sweep could still surface the
78+
predicted transcendental divergence; this experiment did not attempt one,
79+
because transcendentals are outside what a plan evaluates.
80+
- `qjs` is the standalone interpreter, not the embedded `rquickjs` the tool will
81+
use. They share the QuickJS-ng core, so engine-level number and string
82+
behaviour is the same, but the embedding has not itself been run cross-platform.
83+
- Darwin coverage is aarch64 only; no x86_64-darwin was tested, and none is in
84+
the fleet.

context/requirements.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ for one layer:
2828
result on every machine and across engine versions. Agreement about what a
2929
Plan says — its Steps, their identities, their acceptance — rests on this, so
3030
it must be tested rather than assumed, and any widening of what evaluation can
31-
reach is a change to this assumption.
31+
reach is a change to this assumption. Measured across x86_64-linux,
32+
aarch64-linux, and aarch64-darwin: a plan's canonical serialization is
33+
byte-identical on all three
34+
([experiment](./.experiments/2026-07-25-cross-platform-evaluation-determinism.md)).
3235

3336
## Acceptable Tradeoffs
3437

0 commit comments

Comments
 (0)