# spikes/wasm-phase3 — dynamic loader + workspace scaffold Phase 3 combines the Phase 0 dynamic PIC-module loader with the Phase 2 UCEB1 request-context membrane. It is still a spike, not the production wasm worker, but it validates the load-bearing pieces together: 1. build a core WASM reactor that owns memory, allocator, `Request`, `DValue`, UCEB1, and output buffering; 2. build a separate PIC side module with `dylink.0` from a generated-shape UCE page C++ file; 3. parse `dylink.0`, allocate `__memory_base`/`__table_base`, resolve `env.*`, `GOT.mem.*`, and `GOT.func.*` imports against the core/workspace; 4. instantiate the unit, run relocations/constructors, set its Request pointer, call `__uce_render`, and read rendered output from core-owned memory. The fixture intentionally exercises the loader branches that are easiest to accidentally leave dark: non-zero `table_size` / `__table_base`, `GOT.func` resolution (`phase3_core_print`), and deferred self-resolution of unit-owned `GOT.mem` entries. The loader output prints those resolutions before the final pass marker. Its generated-shape expressions call `html_escape(...)` so the side-module import surface includes the first ordinary UCE helper dependency rather than only `types.h`/`DValue`. Run on `k-uce`: ```bash bash spikes/wasm-phase3/build_modules.sh bash spikes/wasm-phase3/build_loader.sh /tmp/uce/wasm-phase3/loader ``` Expected final line: ```text PHASE3 EXIT CRITERION: PASS ``` Files: - `core.cpp` — core/workspace scaffold and UCEB1 membrane decode. - `page.uce` — source page for the generated-shape fixture. - `generated/page.uce.cpp` — checked-in UCE-preprocessor-shaped side-module fixture: `uce_lib.h` include, `__uce_set_current_request`, `__uce_render`, literal markup lowered to `print(R"(...)")`, expression prints wrapped in `html_escape(...)`, callback/lambda/table exercises, and self-GOT data. - `loader.cpp` — dynamic linker/runner adapted from Phase 0. - `hostcalls.syms` — explicit core hostcall allowlist. Still deferred to production Phase 3/4 work: - running the actual UCE preprocessor inside this build script rather than using a checked-in generated-shape fixture; - lazy component/path dispatch for a full site tree; - uce-starter end-to-end under a wasm FastCGI worker; - productionizing the side-module allocator gate as a real `#ifdef` in `types.h` instead of this spike's copied-header text patch; - parser hardening beyond the spike's basic magic/version/bounds/alignment checks, including fuzzing malformed wasm/dylink sections before accepting cache or third-party units; - import-policy hardening beyond this spike's fail-fast resolver; - workspace birth/drop integration with the real server lifecycle, including retaining unaligned allocation pointers needed to unload units or drop a workspace cleanly.