Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1501,6 +1501,7 @@ jobs:
node src/bindings/wasix-ts/tools/smoke-node.mjs --runtime node
node src/bindings/wasix-ts/tools/smoke-node.mjs --runtime bun
node src/bindings/wasix-ts/tools/smoke-node.mjs --runtime deno
node src/bindings/wasix-ts/tools/smoke-browser.mjs --postgis-worker
OLIPHAUNT_CI_JOB_TARGETS_JSON='${{ needs.affected.outputs.job_targets }}' OLIPHAUNT_MOON_UPSTREAM=none MOON_CACHE=off .github/scripts/run-planned-moon-job.sh wasix-ts-sdk-package

- name: Upload WASIX TypeScript SDK package artifacts
Expand Down
15 changes: 8 additions & 7 deletions docs/internal/DONE.md
Original file line number Diff line number Diff line change
Expand Up @@ -394,9 +394,9 @@ Implemented coverage:
after the C bridge reports active streaming COPY;
- direct raw protocol streaming is routed through the shared `BackendSession`
framed sender instead of a separate client-only transport path;
- Rust-owned guest bridge allocations are scoped through `pg_free`/`free`, and
debug builds now have a direct raw-protocol stress test proving repeated
bridge round trips keep allocation/free counters balanced;
- the C bridge owns reusable input/output capacity, and the direct raw-protocol
stress test proves repeated bridge round trips remain correct without
per-request guest allocation/free calls;
- direct LISTEN/UNLISTEN quotes channel identifiers and dispatches notifications
by the exact backend channel name, including case-sensitive and quoted names.
- a larger PostgreSQL regression subset now ports the relevant Oliphaunt test
Expand All @@ -422,13 +422,14 @@ Verified ownership boundaries:
state, COPY state, portal cleanup, and longjmp recovery boundaries;
- the WASIX bridge owns only the host ABI that Wasmer/WASIX cannot provide as a
normal OS process boundary: protocol fd transport, locale/identity shims,
single-process shared memory, fail-closed process calls, and explicit
allocation/free ownership.
single-process shared memory, fail-closed process calls, and reusable
guest-owned protocol buffers.

Review conclusions:

- guest-memory ownership is scoped through `GuestAllocator`, `pg_free`/`free`,
and debug allocation/free counters;
- guest-memory ownership is scoped through bridge-owned input/output buffers;
hosts copy requests directly into reserved guest memory and copy each
response once into host-owned storage before the bridge buffer is reset;
- detached protocol stdio fails closed rather than silently accepting bytes;
- COPY state is reported by PostgreSQL through
`pgl_protocol_report_copy_response`; the proxy no longer parses SQL text,
Expand Down
2 changes: 1 addition & 1 deletion docs/internal/PG18_WASIX_PERF_STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ and any accidental parallel worker use fails through the existing error path.
## Release Hygiene

The rebuilt PG18 runtime binary does not contain the old `pgl_*`/`Oliphaunt`
runtime symbol strings when inspected from the packaged `oliphaunt/bin/oliphaunt`
runtime symbol strings when inspected from the packaged `oliphaunt/bin/postgres`
module. The PG18 patch stack and build scripts also keep the new
`oliphaunt_wasix_*` naming.

Expand Down
30 changes: 16 additions & 14 deletions docs/internal/WASIX_PATCH_STACK.md

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions docs/maintainers/assets.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@ per-database skeleton by default. Temporary and template-backed databases use a
cached PGDATA template as a lower filesystem and materialize files into database
storage only when PostgreSQL opens them for mutation.

The runtime tree keeps both `/bin/oliphaunt` and `/bin/postgres`. They are the same
backend module; the `postgres` path exists so upstream `initdb` can discover and
spawn the backend through PostgreSQL's normal `find_other_exec()` path.
The portable artifact installs the backend once under PostgreSQL's conventional
`/bin/postgres` name. Both direct hosts execute that path, and upstream `initdb`
discovers the same regular file through its normal `find_other_exec()` path.
The internal build output and AOT artifact retain the Oliphaunt product identity,
but that branding does not leak into PostgreSQL's installed executable layout.

The cache is content-addressed by the asset manifest and artifact hashes. If an
asset hash does not match the manifest, startup fails instead of using a mixed
Expand Down
2 changes: 1 addition & 1 deletion docs/maintainers/repo-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ synthetic root:
- `src/bindings/wasix-ts` is the public browser, Node, Bun, and Deno binding over the same
portable WASIX runtime. It owns module-Worker and worker-thread orchestration,
archive-to-memory mounts, the patched package-relative Wasmer host, and the
stdio pgwire client. It must not depend on `src/sdks/js`, native runtime
direct guest-memory pgwire client. It must not depend on `src/sdks/js`, native runtime
carriers, Node direct, or the broker. Ordinary opens consume the generated
host-neutral `@oliphaunt/liboliphaunt-wasix` carrier; conditional exports
select the host adapter without changing the public package identity.
Expand Down
24 changes: 19 additions & 5 deletions docs/maintainers/wasix-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,14 +219,28 @@ Rust binding's AOT artifacts and the portable module used by browser direct,
browser worker, and Node/Bun/Deno worker execution all benefit. They are not
host-specific patches.

Transport remains host-specific. PostgreSQL patch 0039 adds an opt-in stdio
pgwire entry point to the shared guest, but only browser-worker execution sets
`OLIPHAUNT_WASIX_STDIO_PGWIRE=1`. Rust, browser-direct, and Node/Bun/Deno hosts pump the
existing lifecycle exports instead. The patches under
Transport remains host-specific. Current TypeScript placements, including the
dedicated browser worker, use the direct guest-memory PGWire driver; worker
execution isolates its synchronous guest calls from the browser main thread.
PostgreSQL patch 0039 declares the hybrid transport ABI used only when the Rust
proxy enters COPY streaming; it does not add a process-level stdio entry point.
Rust pumps the existing lifecycle exports through its native Wasmer host. The patches under
`src/bindings/wasix-ts/host` adapt the pinned Wasmer JS 6.1/WASIX 0.601 host;
they do not belong in the Rust host, which uses the coherent Wasmer
that host binds the explicitly single-backend guest clock directly to imported
memory. Its direct PGWire driver also moves
request bytes straight from JavaScript into guest memory and returns one owned
JavaScript response, avoiding intermediate copies without exposing a view that
PostgreSQL could later mutate. Direct-session stderr is retained only as a
bounded 16 KiB diagnostic tail and attached on lifecycle failure. These host
adaptations do not belong in the Rust host,
which uses the coherent Wasmer
7.2.1/WASIX 0.702.1 family. Native runtimes keep PostgreSQL's normal concurrent
atomics and their own transport rather than inheriting either WASIX contract.
Wasmer 7.2.1 explicitly disables WebAssembly exception-handling tests on
Windows, so the Rust MSVC host retains PostgreSQL's top-level process-exit
recovery boundary. Nested `PG_TRY`/`PG_CATCH` qualification applies to the
other Rust hosts and the JavaScript host; Windows still proves top-level error
recovery but does not claim nested Wasm-EH support.

## Wasmer compatibility

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,6 @@ impl WasixBackendSession {
&self.postgres_config
}

#[cfg(debug_assertions)]
pub(crate) fn guest_bridge_allocation_counts(&self) -> (u64, u64) {
self.pg.guest_bridge_allocation_counts()
}

pub(crate) fn send_buffered(
&mut self,
message: &[u8],
Expand Down Expand Up @@ -366,11 +361,6 @@ impl BackendSession {
self.0.postgres_config()
}

#[cfg(debug_assertions)]
pub(crate) fn guest_bridge_allocation_counts(&self) -> (u64, u64) {
self.0.guest_bridge_allocation_counts()
}

pub(crate) fn send_buffered(
&mut self,
message: &[u8],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ impl RootPrepareOptions {

impl RuntimeLayout {
pub(crate) fn module_path(&self) -> PathBuf {
self.module_root.join("bin/oliphaunt")
self.module_root.join("bin/postgres")
}

pub(crate) fn uses_shared_overlay(&self) -> bool {
Expand Down Expand Up @@ -364,8 +364,8 @@ fn locate_runtime_module(paths: &OliphauntPaths) -> Option<(PathBuf, PathBuf)> {
if !oliphaunt_dir.exists() {
return None;
}
let oliphaunt_bin_dir = oliphaunt_dir.join("bin");
let module = oliphaunt_bin_dir.join("oliphaunt");
let bin_dir = oliphaunt_dir.join("bin");
let module = bin_dir.join("postgres");
if !module.exists() {
return None;
}
Expand All @@ -384,7 +384,7 @@ fn locate_runtime_module(paths: &OliphauntPaths) -> Option<(PathBuf, PathBuf)> {
{
return None;
}
Some((module, oliphaunt_bin_dir))
Some((module, bin_dir))
}

fn ensure_full_runtime(paths: &OliphauntPaths) -> Result<bool> {
Expand Down Expand Up @@ -1309,7 +1309,7 @@ fn sha256_hex(bytes: &[u8]) -> String {

pub(crate) fn preload_runtime_module() -> Result<()> {
let cached_runtime = runtime_cache()?;
let module_path = cached_runtime.runtime_root.join("bin/oliphaunt");
let module_path = cached_runtime.runtime_root.join("bin/postgres");
PostgresMod::preload_module(&module_path)
}

Expand Down Expand Up @@ -1914,9 +1914,9 @@ mod tests {
.context("memory runtime should have an immutable shared root")?;
assert!(
shared_root
.metadata(Path::new("/bin/oliphaunt"))
.metadata(Path::new("/bin/postgres"))
.is_ok_and(|metadata| metadata.is_file()),
"memory runtime is missing /bin/oliphaunt"
"memory runtime is missing /bin/postgres"
);
let filesystem = prepared
.outcome
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -424,13 +424,6 @@ impl Oliphaunt {
self.backend.runtime_storage()
}

/// Return debug-build bridge allocation/free counters for ownership tests.
#[doc(hidden)]
#[cfg(debug_assertions)]
pub fn guest_bridge_allocation_counts(&self) -> (u64, u64) {
self.backend.guest_bridge_allocation_counts()
}

/// Back up the physical database state to a gzipped tar archive.
///
/// The archive is intended to be loaded back into oliphaunt-wasix/Oliphaunt with
Expand Down
Loading
Loading