Save the current implementation and README, status, and known-issue documentation at the user-requested stop. No completed release or deployment is claimed. Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: GPT-6 Codex <noreply@openai.com>
Fixed Javy/Wasm runtime adapter — not qualified
This new module is a standalone runtime plugin. It does not import QQQ, modify the existing TypeScript compiler or change qbit-scripting-worker/1. No product provider may advertise it as qualified until the exact built artifact and complete host lifecycle pass the required tests.
Dependency and build boundary
Javy CLI release9.1.0 corresponds to public runtime crate javy8.1.0, using rquickjs0.12.0 (tagged Cargo.toml). This module uses those public crates directly. It requires no Javy CLI, Wizer or author snapshot. Runtime::new constructs a new QuickJS runtime during each invocation. The external host caches the common compiled Wasm code; publication caches contain only private bytecode and immutable identity metadata.
Rust1.97.1 is pinned. Direct dependencies are exact-version pins in Cargo.toml. Root resolved the 73-package Cargo.lock (SHA256 F077884125E23E5989D158FE6FE86DF9009F5842076609CEDF2DA6F4951021A1); the rquickjs facade is0.12.0 and its compatible core/sys dependencies resolve to0.12.2. Root owns public tool acquisition, Linux/WASI SDK/libclang setup and actual Wasm execution. Building rquickjs requires its documented C/WASI compiler and bindgen prerequisites; do not silently substitute an engine or crate version.
Planned root commands after the pinned environment is ready:
cargo generate-lockfile
cargo fmt --check
cargo test --locked --test trusted_contract
cargo clippy --all-targets --locked -- -D warnings
cargo build --locked --release --target wasm32-wasip1
The native tests execute only fixed trusted fixtures. Native tests cannot qualify Wasm import capabilities, fuel, actual fresh Store state or host cancellation. A subsequent exact-Wasm run must verify those independently. The common Wasm plugin must be instantiated with no WASI preopens, no inherited environment/stdin credentials, no network capability, bounded linear memory/fuel and an outer deadline. Native tests are not permission to run author submissions.
Private supervisor ABI
Extism export run() -> i32 reads and writes one UTF-8 JSON frame through the ordinary Extism input/output ABI. Exactly one call is permitted per Wasm instance; the host must free that Plugin/Store before reporting RETIRED. Return zero means a private result was produced; a nonzero return is a refusal/trap with no successful result.
Prepare input (cold path):
{"operation":"prepare","runtimeSha256":"<actual fixed Wasm SHA>","artifactSha256":"<existing artifact SHA>","bundle":"<exact qqq-esm/1 artifact string>"}
Prepare returns profile, runtimeSha256, artifactSha256, entryPoint, sorted modules[{path,bytecode,sha256}] and preparedSha256. Bytecode is canonical standard base64; the prepared hash is domain-separated and length-framed across all immutable fields. This digest proves consistency, not authorization: the supervisor must verify the actual loaded runtime binary and original publication, and retain the resulting bytecode itself. Never accept arbitrary client-supplied bytecode merely because its self-declared hashes match. QuickJS's public Module::load is an unsafe bytecode reader; only the trusted compiler's exact output is an allowed input, inside the Wasm boundary.
Run input (hot path):
{"operation":"run","runtimeSha256":"<actual fixed Wasm SHA>","preparedSha256":"<trusted cached identity>","prepared":{},"request":{}}
prepared is the complete cached prepare result. request is the existing execute object without bundle, matching the persistent transport's INVOKE shape; it retains digest, .ts entrypoint, request ID, event/payload, fresh opaque capability token and limits. Run output is {message,guestWallMillis}. message has the existing executeResult fields but deliberately omits usage. The supervisor adds authoritative CPU/wall usage before forwarding the unchanged WorkerProtocol result. Guest wall time is diagnostic, not CPU accounting or a trusted enforcement signal.
Imported application function: extism:host/user::qqq_broker(i64 requestOffset) -> i64 responseOffset. Offsets refer to Extism-owned memory, not host pointers. Input is existing bounded broker JSON; output must be a newly allocated existing brokerResult JSON block. The plugin copies and frees both allocations; returning the request allocation itself is refused. The supervisor callback runs synchronously on the active invocation thread and supplies current authority from that invocation only. It must validate frames and enforce its own I/O deadline. Zero offset is refusal. No callback, token or actor is retained in compiled code/cache.
Semantic/resource contract
Preparation verifies the existing emitted artifact hash, validates the closed path/module set and calls Javy compile_to_bytecode, which declares/writes modules without evaluation. Execution installs a restricted relative resolver and loads those exact modules. It awaits module evaluation and exported main until actually settled; pending with no work, detached rejection, job failure and bounded job exhaustion are failures. It does not use default Javy invoke's pending-Promise success behavior.
The trusted SDK factory captures its primitives before author evaluation, returns a frozen Promise-based qqq.query and preserves one-pending-call and call-count constraints. The opaque token remains in the native broker closure, not a guest global. Broker denial and author errors produce generic host-owned error text. Output is a bounded JSON object.
QuickJS heap is capped by the requested memory limit, stack at256KiB; wall checks and engine interrupt cover interpretation. A fixed10,000 pending-job-turn ceiling is an additional explicit runtime profile bound. Extism/Wasmtime must separately enforce linear-memory/fuel, and the supervisor must enforce actual CPU and whole-operation wall limits including initialization and broker waits. Fuel does not meter native host callback work. One Engine slot has one active invocation; ambiguous cancellation retires the slot rather than reusing it speculatively.
The few unsafe blocks are narrowly documented public FFI/bytecode boundaries, required by the chosen APIs. There is no engine fork, reflection or raw host-pointer access. This is an explicit scoped exception to the personal default of forbidding unsafe Rust; it does not permit unchecked external bytecode.
Current evidence
Twelve fixed trusted native tests pass with cargo +1.97.1 test --offline --locked --test trusted_contract, including fresh state/time/random, relative imports/live bindings/TLA, awaited broker, Unicode source above1MiB UTF-8, pending/error refusal and attributed-import rejection. cargo-native-serialization-red.log preserves the demonstrated toJSON detached-rejection bug; cargo-native-serialization-verification.log records all12 passing after adding the final bounded job/rejection check after serialization. No Wasm execution, performance or hostile-code qualification has passed for this module yet. The earlier Extism JS-PDK runtime-floor experiment is not evidence for this implementation. Exact-Wasm proof must include these semantics, one-call-per-instance refusal, and actual fuel/memory/deadline/cancel retirement behavior.
Pinned bytecode import-attribute compatibility
The resolved rquickjs-sys0.12.2 quickjs/quickjs.c has SHA256 CE9A95D3C011F255C1FACB7D4361C71209E71BA58D84ACD3281A755D0686A285. JS_WriteModule at38038–38042 writes requested module names without attributes. JS_ReadModule at39124–39142 allocates zeroed entries and passes their attribute value to the import resolver without initializing it to JS_UNDEFINED. The public rquickjs wrapper therefore supplies Some with a non-object value for ordinary bytecode imports; enumerating it throws. The initial native test and reduced relative-import fixture both failed on this path.
load_bytecode uses a runtime-local RAII BytecodePhase to ignore that placeholder only during synchronous loading of exact supervisor-owned bytecode. Nested loads restore the prior phase; evaluation occurs outside it. Source compilation rejects actual attributes for every module, including unused files, before producing a prepared result. Dynamic imports remain subject to the normal attribute check; regression tests prove attributed dynamic imports fail after nested loading while ordinary dynamic imports succeed. There is no engine modification, global flag, guest-visible toggle or acceptance of client-supplied bytecode. This workaround remains tied to the pinned dependency behavior and needs re-review on an engine upgrade.