Skip to main content
Version: 0.1.0-alpha.5 (alpha)

Angular renderer qualification observation

Recorded 2026-09-15 for Phase 3 #224, based on development e9ac2b970e9f02c92ef45013ddacc44120d98a23 plus the qualification sources retained with this report. This finite feasibility check is not a production benchmark, security certification or completed node renderer adapter. The recipe and profile describe reproduction and scope.

Native SSR and browser hydration​

Node 24.19.0 built actual Angular 22.1.6 full-AOT server/browser bundles on Windows. Wasmtime 47.0.4 executed the component in an x86_64 Linux Docker container limited to 2 CPUs and 2 GiB. The native host/Cranelift were debug builds; generated guest code used Cranelift speed. The component was 23,773,029 bytes with no imports.

ObservationResult
Cold native compilation, one debug-host sample197,067.648 ms
Fresh-Store SSR: Alice, Bob, Alice14.593 / 13.053 / 12.769 ms
Store setup for those samples6.531 / 0.224 / 0.182 ms
Guest instruction fuel55,321,659 / 54,736,023 / 55,321,659
Observed linear memory per normal render21,233,664 bytes
Alice HTML / Bob HTML476 / 443 bytes, with hydration metadata
Reused-instance negative controlModule counter 1 then 2; fresh Stores always 1
Store ownership after destructionZero after every success/failure
Actual native HTML in Chrome 152.0.7977.84Original heading DOM reused; escaped input preserved; Angular signal click works; no page errors

These are individual observations, not medians or an LSF request budget. They exclude admission, HTTP ingress, providers, delivery, competing workloads and production native-cache behavior. Linear memory is not total activation cost, process RSS or a density measurement. Compilation is outside invocation limits.

Failure and recovery​

Every failure is followed by successful Angular SSR with a fresh module counter. Fuel, epoch, allocation and result-lifting checks require their actual cause, not merely any failed call. The ticker is stopped and joined on exit.

ProbeActual outcome
1 MiB instantiation limitMemory limiter denied; owner released
CPU loop, 100,000 fuelOutOfFuel, 0.761 ms
CPU loop / Promise storm, 25 epochsInterrupt, 28.220 / 28.807 ms
Retained 4 MiB arraysMemory growth denied; peak 264,306,688 bytes below the 256 MiB ceiling; 164.043 ms
JavaScript exceptionTrapped; fresh SSR succeeded
256 KiB result, instruction fuel remainingActual hostcall-fuel allocation rejection at 128 KiB; 342.458 ms
Positive-delay timer / intervalTrapped as unsupported
257th timer / 4097th explicit microtask callbackTrapped at cumulative limits

The output probe has a separate very large finite instruction-fuel allowance and a 5000-epoch deadline, so an earlier CPU trap cannot masquerade as allocation containment. Store-owner counters do not establish OS page reclamation or compiler/whole-process memory containment.

Alternative Node host and compiler limitations​

The same bundle ran in one supervised Node child slot on Windows. Render samples were 20.409/15.023 ms in one retained process and 22.877/13.321 ms in a fresh one. The module counter was 1 then 2 in each process. Complete child lifetimes were 274.175/170.662 ms. A CPU-loop child was killed/reaped after 275.218 ms for a 250 ms parent timer. Peak owned children was one and final ownership was zero.

Despite --max-old-space-size=32, the memory probe allocated and filled a 67,108,864-byte ArrayBuffer, with 119,369,728-byte reported RSS. No hostile-code OS containment was implemented for this candidate; it is not selected. Its Windows timings cannot establish a speed comparison against Linux Wasmtime.

A minimal direct async WIT export failed in ComponentizeJS 0.22.0's splicer with not yet implemented / RuntimeError: unreachable before Angular execution. The private synchronous proof drains JavaScript promises. #233 still owns the public async adapter and executable composition evidence.

Two additional builds with identical recorded profile, lock, embedding, server and client digests produced different component bytes. Byte-for-byte component reproducibility failed; the underlying cause was not established. #234 must make it reproducible or explicitly report the limitation and reject a reproducibility claim. Actual bytes continue to determine immutable package identity. Do not normalize or substitute artifacts to match an earlier receipt.

IdentitySHA-256
Native-tested component036678e89f3872d562cf521c686fda369d06cb33b0be52f1b94cccc516ac99b4
Profilef3f6e8c02eef8cf49643f318f0cd970738b815d4e545071d7efd97b3782400b2
Locked npm inputf3195990ed231efddcd792e735493ea0d75d9845beb3cbe54e06fd95a595f757
StarlingMonkey embeddingb45eb4dda2fed0eaecd4e5581fb26a99e642d001dbf82f3698aba27564a78ea1
Server bundle60a147f076d2944ff8c5a34588bb48302fdcb1b7af4258797437e4063d35413f
Client bundled777fdd194e801b948ef23aab283ff513f48ca2117237adb321337302d34837c
Repeated build A, 23,773,476 bytes752139a1ce25d1c3ea5d287665bec0bd8917d116e6958088164b06491474e148
Repeated build B, 23,773,496 bytese6bcc9f73836e0ee2d181bc4fc01d74cbafdc5a0a042a2af699d5fda11c7a392

The repeated-build artifacts are distinct from the native-tested artifact. CI builds, hashes and tests its own artifact from the PR checkout. Git retains this compact observation and source, not generated Wasm, bundles or timing archives.