8000 feat(engine)!: ship one native reylo binary per platform by colinhacks · Pull Request #152 · colinhacks/reylo · GitHub
[go: up one dir, main page]

Skip to content < 8000 div data-target="react-partial.reactRoot">

feat(engine)!: ship one native reylo binary per platform - #152

Merged
colinhacks merged 6 commits into
mainfrom
engine-binary
Nov 2, 2026
Merged

colinhacks merged 6 commits into
mainfrom
engine-binary

Conversation

@colinhacks
@colinhacks colinhacks commented Nov 2, 2026 •
Copy link
Copy Markdown
Owner

Reylo's engine becomes one native program, the reylo binary, built for eight platforms and installed through reylo's optional dependencies, in place of the four WebAssembly components committed under packages/.

What changes

Area Change
Engine engine/cli (crate reylo) serves each database's engine as reylo engine <database>, the JSON-lines protocol engine/native speaks, or reylo engine <database> call for one request; reylo --version prints reylo's version, which the Cargo workspace now carries ([workspace.package]) and the ping reports.
Loader src/engine.ts runs the binary as a long-lived child per database (the ping, the lexer, DuckDB's replay) and one child per connection, held only while a request waits so a build still exits. src/native.ts finds it: REYLO_ENGINE_PATH, else the platform package reylo's install holds, else a checkout's target/release or target/debug. src/component.ts, src/engine-worker.ts, src/engine-package.ts and tests/fingerprint.test.ts are gone; src/tooling-loader.ts loads the build-time half.
Packaging dist/reylo lists @reylosql/engine-<platform> for darwin-arm64, darwin-x64, linux-x64, linux-x64-musl, linux-arm64, linux-arm64-musl, win32-x64 and win32-arm64 as optional dependencies at its exact version (npm/platforms.json), and no longer has the @reylosql/<database> peers. scripts/build.ts writes dist/engine-<platform> and refuses a binary whose header names another platform, or a version that differs from package.json's. packages/ is deleted: no engine is committed.
Platforms binaries.yml builds the binary for each of the eight platforms on its own runner, Linux on glibc in a pinned manylinux_2_28 container so that it starts on glibc 2.28 (build-binary.sh refuses a newer symbol), packs the nine packages, and on each platform installs reylo from a registry of its own into a fresh project (.github/scripts/install-check.ts): npm must bring that platform's engine alone, which types a query with reylo generate, runs it under the preload, and reads Postgres statements nested to the engine's bound. Linux on glibc runs it in Debian 11, AlmaLinux 8 and Amazon Linux 2023, on musl in Alpine, macOS on Intel on an Intel runner. It runs on pull requests that change the binary or its packaging, and within each release, which now calls it for its build.
CI test.yml: a binary job builds the binary once and hands it to the loader's tests; a playground job builds the docs site's WebAssembly playground engine on a pull request that changes Postgres's engine or anything shared, so a broken wasm32-wasip2 build fails before a release does. release.yml: the binary is built on each platform's own runner (.github/scripts/build-binary.sh, which checks --version and a ping on all four databases), the eight platform packages are staged before reylo, and the GitHub release carries the binaries, the playground engine and SHA256SUMS.
Docs site The playground's engine is fetched from the GitHub release of the site's version (site/scripts/playground-engine.ts, checked against SHA256SUMS), or from a checkout's own engine/build.sh output, instead of from packages/postgres.
TLS With sslrootcert=system, a chain the operating system refuses is checked against the roots NODE_EXTRA_CA_CERTS names, as Node checks it; the WebAssembly engine already did.
Native builds Every native build's bundled SQLite has the math, percentile and geopoly functions (.cargo/config.toml), and a SQLite file another engine holds locked (Turso's) is read through a copy instead of waiting. The WebAssembly engines already behaved this way.
Docs Setup says reylo brings its engine and names the eight platforms; examples, labs, README.md, AGENTS.md and engine/README.md follow.

Upgrading

   "dependencies": {
     "reylo": "^0.7.0"
   },
   "devDependencies": {
-    "@reylosql/postgres": "^0.6.0",
     "typescript": "beta"
   }

A production install that runs the reylo/register preload needs the engine: keep reylo a dependency, and install without --omit=optional.

Time to the first analysis

macOS arm64, three runs each, from importing src/engine.ts to the first analyze("select 1 as x"):

Database WebAssembly component Native binary
Postgres 230–274 ms 64–69 ms
MySQL 210–240 ms 47–56 ms
SQLite (:memory:) 184–234 ms 43–49 ms

Verified

On every platform, by binaries.yml on e11b136: all eight binaries built, and each installed, typed and ran a query. On Windows x64, by windows.yml run by hand on this branch: the loader's tests, the type check through every form a Windows path takes, Postgres's TLS files and NODE_EXTRA_CA_CERTS, MySQL over a named pipe, and the Node example. The Windows job now finds the runner's MySQL wherever its image version puts it; main's Windows job had been failing since the image moved it.

On macOS arm64:

  • nub run typecheck; nub run test with Postgres 18 and MySQL 8.4, none skipped.
  • cargo build --workspace --all-targets with no warning; cargo test of every crate; the oracle with --strict-coverage (DuckDB's cases with --features duckdb) and SQLite's own test suite replayed against the engine.
  • nub run build (dist/reylo and dist/engine-darwin-arm64), the docs site's build, the playground engine's WebAssembly build and its ping, ten labs and all ten examples, each on the built packages.
  • actionlint and shellcheck on the changed workflows and scripts.

Until a release carries the playground asset, Vercel's preview builds of main cannot fetch the playground engine; reylo.dev serves the release branch and is unaffected.

The engine is the reylo binary (engine/cli), which reylo installs as one
of eight @reylosql/engine-<platform> optional dependencies; the four
WebAssembly components and the @reylosql/<database> peers are gone.
Copilot AI balanced review requested due to automatic review settings November 2, 2026 07:49
@vercel
vercel Bot commented Nov 2, 2026 •
Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
reylo Error Error Nov 2, 2026 8:56pm UTC

Request Review

Copilot AI left a comment
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The SQLite fallback can produce inconsistent snapshots and expose database contents, while CLI tests omit the engine path required for subprocesses to run in clean CI environments.

4 open issues
11 files not reviewed
  • examples/bun/pnpm-lock.yaml: Generated file
  • examples/cloudflare-workers/pnpm-lock.yaml: Generated file
  • examples/esbuild/pnpm-lock.yaml: Generated file
  • examples/jest/pnpm-lock.yaml: Generated file
  • examples/nextjs/pnpm-lock.yaml: Generated file
  • examples/node/pnpm-lock.yaml: Generated file
  • examples/nub/pnpm-lock.yaml: Generated file
  • examples/rspack/pnpm-lock.yaml: Generated file
  • examples/vite/pnpm-lock.yaml: Generated file
  • examples/webpack/pnpm-lock.yaml: Generated file
  • pnpm-lock.yaml: Generated file
What changed in this PR

This breaking change moves Reylo’s SQL analysis from per-database WebAssembly packages to one native executable per platform, while retaining WebAssembly for the docs playground.

Changes:

  • Introduces the native engine CLI, platform discovery, and updated loader integration.
  • Adds platform-specific builds and release assets, including a separately distributed playground engine.
  • Updates tests, SQLite behavior, documentation, and examples for the new installation model.
< 8000 td>Updates installation and engine explanations.
File Description
tsconfig.build.json Includes build-time tooling and the D1 proxy.
tests/​unterminated.test.ts Removes database-engine package links.
tests/​project.test.ts Uses platform-independent engine lookup.
tests/​project-file-module.test.ts Removes the SQLite engine link.
tests/​lex.test.ts Checks asynchronous and one-shot engine lexing.
tests/​jest.test.ts Removes the SQLite engine link.
tests/​fingerprint.test.ts Removes committed-component fingerprint checks.
tests/​engines.test.ts Tests native discovery, validation, and connection lifecycle.
tests/​depth.test.ts Adapts depth checks to native execution.
tests/​definition.test.ts Removes the SQLite engine link.
tests/​connect.test.ts Adapts connection tests to native paths and execution.
tests/​comments.test.ts Removes database-engine package links.
tests/​cli.test.ts Updates stderr expectations and engine comments.
tests/​catalog-queries.test.ts Uses simplified engine lookup.
tests/​analyze.test.ts Adapts offline dialect assumptions to cached entries.
src/​webpack.ts Loads tooling through the new loader.
src/​vite.ts Loads tooling through the new loader.
src/​tooling.ts Updates tooling ownership and its type import.
src/​tooling-loader.ts Adds lazy loading of local build-time tooling.
src/​register-worker.ts Uses the new tooling loader.
src/​project.ts Infers offline dialects from cached entries.
src/​play.ts Awaits session lexing.
src/​native.ts Finds the platform package or configured executable.
src/​mapper.ts Uses local build-time tooling.
src/​mapper-server.ts Updates engine lookup and awaits lexing.
src/​loader.ts Awaits fallback parameter lexing.
src/​host-url.ts Resolves certificate paths without WASI mapping.
src/​esbuild.ts Uses the new tooling loader.
src/​engine-worker.ts Removes the WebAssembly connection worker.
src/​engine-package.ts Removes per-database tooling discovery.
src/​engine-core.ts Supports asynchronous replay requests.
src/​duckdb.ts Updates the engine architecture comment.
src/​connection.ts Updates the explanation of shared error identities.
src/​component.ts Removes the Node-side WASI host.
src/​commands.ts Updates the tooling ownership comment.
src/​cli.ts Loads commands through the new tooling loader.
src/​analyze.ts Updates engine lookup, fingerprints, and asynchronous lexing.
site/​scripts/​playground-engine.ts Retrieves and verifies the playground engine.
site/​scripts/​capture-types.ts Awaits session lexing during capture.
site/​package.json Prepares the playground engine before dev and build.
site/​lib/​root-modules.d.ts Removes the obsolete root shim declaration.
site/​lib/​live/​worker.ts Loads WebAssembly assets from .playground.
site/​lib/​live/​plugin.ts Uses the new playground engine directory.
site/​lib/​live/​play-data.ts Reads playground assets from their new directory.
site/​lib/​live/​engine.ts Imports the prepared playground component.
site/​lib/​live/​engine-dir.ts Defines the playground asset directory.
site/​content/​sections/​01-setup.mdx Documents native requirements and installation.
site/​content/​docs/​sqlite.mdx Removes the separate engine-package reference.
site/​content/​docs/​postgres.mdx Removes the separate engine-package reference.
site/​content/​docs/​mysql.mdx Removes the separate engine-package reference.
site/​.gitignore Ignores prepared playground assets.
README.md Simplifies installation instructions.
pnpm-lock.yaml Removes old engine links and the direct shim dependency.
packages/​sqlite/​tooling.ts Removes the SQLite tooling re-export.
packages/​sqlite/​README.md Removes obsolete SQLite package documentation.
packages/​sqlite/​package.json Removes the SQLite engine package manifest.
packages/​postgres/​tooling.ts Removes the Postgres tooling re-export.
packages/​postgres/​README.md Removes obsolete Postgres package documentation.
packages/​postgres/​package.json Removes the Postgres engine package manifest.
packages/​mysql/​tooling.ts Removes the MySQL tooling re-export.
packages/​mysql/​README.md Removes obsolete MySQL package documentation.
packages/​mysql/​package.json Removes the MySQL engine package manifest.
packages/​duckdb/​tooling.ts Removes the DuckDB tooling re-export.
packages/​duckdb/​README.md Removes obsolete DuckDB package documentation.
packages/​duckdb/​package.json Removes the DuckDB engine package manifest.
package.json Removes per-database engine dependencies and peers.
oracle/​cases/​sqlite_functions/​unchecked.txt Records unavailable sqlite_offset cases.
oracle/​cases/​sqlite_functions/​offset_missing.sql Adds an unavailable-function projection case.
oracle/​cases/​sqlite_functions/​offset_missing_in_where.sql Adds an unavailable-function filter case.
oracle/​cases/​sqlite_functions/​math.sql Covers enabled SQLite math functions.
oracle/​cases/​sqlite_functions/​math_in_where.sql Covers math functions in filters.
oracle/​cases/​sqlite_functions/​expected.txt Updates SQLite function expectations.
npm/​platforms.json Defines eight platform targets and runners.
npm/​engine/​README.md Adds platform-package documentation.
lab/​nextjs/​tsconfig.json Raises the compilation target to ES2020.
lab/​nextjs/​README.md Documents native engine setup.
lab/​jest/​README.md Documents native engine setup.
lab/​bundlers/​README.md Documents checkout binary discovery.
examples/​webpack/​README.md
examples/​webpack/​pnpm-lock.yaml Removes the MySQL engine link.
examples/​webpack/​package.json Removes the MySQL engine dependency.
examples/​vite/​README.md Updates installation and engine explanations.
examples/​vite/​pnpm-lock.yaml Removes the Postgres engine link.
examples/​vite/​package.json Removes the Postgres engine dependency.
examples/​rspack/​README.md Updates installation and engine explanations.
examples/​rspack/​pnpm-lock.yaml Removes the Postgres engine link.
examples/​rspack/​package.json Removes the Postgres engine dependency.
examples/​README.md Explains building and linking native platform packages.
examples/​nub/​README.md Updates installation and engine explanations.
examples/​nub/​pnpm-lock.yaml Removes the SQLite engine link.
examples/​nub/​package.json Removes the SQLite engine dependency.
examples/​node/​README.md Updates installation and engine explanations.
examples/​node/​pnpm-lock.yaml Removes the Postgres engine link.
examples/​node/​package.json Removes the Postgres engine dependency.
examples/​nextjs/​README.md Updates installation and engine explanations.
examples/​nextjs/​pnpm-lock.yaml Removes the Postgres engine link.
examples/​nextjs/​package.json Removes the Postgres engine dependency.
examples/​jest/​README.md Updates installation and engine explanations.
examples/​jest/​pnpm-lock.yaml Removes the SQLite engine link.
examples/​jest/​package.json Removes the SQLite engine dependency.
examples/​esbuild/​README.md Updates installation and bundle explanations.
examples/​esbuild/​pnpm-lock.yaml Removes the Postgres engine link.
examples/​esbuild/​package.json Removes the Postgres engine dependency.
examples/​cloudflare-workers/​README.md Updates installation and engine explanations.
examples/​cloudflare-workers/​pnpm-lock.yaml Removes the SQLite engine link.
examples/​cloudflare-workers/​package.json Removes the SQLite engine dependency.
examples/​bun/​README.md Updates installation and engine explanations.
examples/​bun/​pnpm-lock.yaml Removes the SQLite engine link.
examples/​bun/​package.json Removes the SQLite engine dependency.
engine/​wasip2/​src/​lib.rs Updates the WebAssembly host documentation.
engine/​wasip2/​Cargo.toml Documents the component’s playground role.
engine/​wasip2/​Cargo.lock Updates the core crate version.
engine/​README.md Documents native architecture and build commands.
engine/​native/​src/​sqlite.rs Adds a copy fallback for locked databases.
engine/​native/​src/​lib.rs Exposes serving with an explicit one-shot mode.
engine/​core/​Cargo.toml Inherits the workspace version.
engine/​cli/​src/​main.rs Adds database dispatch and version commands.
engine/​cli/​Cargo.toml Defines the native executable crate.
engine/​build.sh Builds WebAssembly only for the playground.
Cargo.toml Registers the CLI and shared version.
Cargo.lock Records the CLI and updated core version.
.github/​workflows/​windows.yml Builds and supplies the Windows executable.
.github/​workflows/​test.yml Adds native binary and playground build jobs.
.github/​workflows/​release.yml Builds, stages, and releases platform assets.
.github/​scripts/​windows-check.ts Removes per-database package dependencies.
.github/​scripts/​npm-stage-publish.sh Updates platform-package comments.
.github/​scripts/​build-playground.sh Builds and archives the playground component.
.github/​scripts/​build-binary.sh Builds and smoke-checks platform executables.
.cargo/​config.toml Enables additional bundled SQLite functions.

Review effort: Balanced

Comment thread engine/native/src/sqlite.rs Outdated
Comment on lines +142 to +145
let dir = std::env::temp_dir().join(format!("reylo-sqlite-{}-{:016x}", std::process::id(), hasher.finish()));
let copy = dir.join("db");
let failed = |e: std::io::Error| rusqlite::Error::SqliteFailure(rusqlite::ffi::Error::new(rusqlite::ffi::SQLITE_CANTOPEN), Some(format!("cannot copy the database the app holds: {e}")));
std::fs::create_dir_all(&dir).map_err(failed)?;
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: the copies now go in a directory the program creates itself, refusing one that already exists, so no directory or link someone else put there is written through. It is owner-only on Unix, belongs to the connection, and is removed when the connection closes or the engine exits. A Rust test covers the copy, its mode and its removal.

Comment thread engine/native/src/sqlite.rs Outdated
Comment on lines +149 to +152
std::fs::copy(path, &copy).map_err(failed)?;
let wal = format!("{path}-wal");
if std::path::Path::new(&wal).exists() {
std::fs::copy(&wal, dir.join("db-wal")).map_err(failed)?;
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: the log is copied after the file, and the snapshot is kept only when the log's header (its checkpoint sequence and salts) is the same before the file's copy, in the copy and after it. A checkpoint that restarted the log in between retakes both. A checkpoint that only writes the file is safe, since the log still holds every page it wrote.

Comment thread tests/cli.test.ts Outdated
Comment on lines 184 to 185
// The engine is the preload's worker's child, whose stderr is the program's own.
const r = spawnSync(process.execPath, ["--import", pathToFileURL(REGISTER).href, "main.ts"], { cwd: root, encoding: "utf8", env: { PATH: process.env.PATH, DATABASE_URL: "file:./app.db" } });
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right: CI names the binary only in REYLO_ENGINE_PATH. The three spawns now pass it through when it is set; the run with no URL still leaves DATABASE_URL out.

Comment thread engine/native/src/sqlite.rs Outdated
Comment on lines +142 to +145
let dir = std::env::temp_dir().join(format!("reylo-sqlite-{}-{:016x}", std::process::id(), hasher.finish()));
let copy = dir.join("db");
let failed = |e: std::io::Error| rusqlite::Error::SqliteFailure(rusqlite::ffi::Error::new(rusqlite::ffi::SQLITE_CANTOPEN), Some(format!("cannot copy the database the app holds: {e}")));
std::fs::create_dir_all(&dir).map_err(failed)?;
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: the copies now go in a directory the program creates itself, refusing one that already exists, so no directory or link someone else put there is written through. It is owner-only on Unix, belongs to the connection, and is removed when the connection closes or the engine exits. A Rust test covers the copy, its mode and its removal.

@pullfrog pullfrog Bot left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No critical issues — three rough edges inline, and a few stale references below.

Reviewed changes

I reviewed the whole PR: the engine moves from four committed WebAssembly components to one native reylo binary, published as one npm package per platform.

  • Native binary: engine/cli serves reylo engine <database> [call] over engine/native's JSON-lines protocol. reylo --version and the ping report the Cargo workspace's version, which must equal package.json's.
  • Loader host: src/engine.ts runs one long-lived child per database and one child per connection. The children are unreferenced, and a timer keeps the process alive while a request waits. Sync config goes through spawnSync. src/native.ts finds the binary: REYLO_ENGINE_PATH, then the platform package, then a checkout's target/.
  • Build-time half: src/tooling-loader.ts replaces src/engine-package.ts. dist/reylo now ships the tsc-compiled tooling.js graph. I checked it: it has no bare imports and no top-level await, so require still loads it.
  • No URL, no engine package: where no URL names the dialect, it now comes from the dialect recorded in the .reylo/queries entries.
  • Packaging: scripts/build.ts writes dist/engine-<platform> and lists all eight packages as optionalDependencies. It checks each binary's ELF, Mach-O or PE header against its package's os/cpu/libc. It links the host's engine into dist/reylo/node_modules.
  • SQLite natively: .cargo/config.toml enables the math, percentile and geopoly functions for every native build, and the oracle case is updated to match. A file another process holds locked (Turso) is read through a temp copy.
  • CI and release: test.yml gets a binary job feeding REYLO_ENGINE_PATH and a playground wasm job. release.yml builds the binary on each platform's own runner, stages eight platform packages before reylo, and attaches tarballs, the playground engine and SHA256SUMS to the GitHub release before it moves release.
  • Docs site: the playground engine comes from site/.playground/, filled by site/scripts/playground-engine.ts from the checkout's build or the release asset, after a hash check.

ℹ️ Stale references to the per-database packages, and a scope gap for .cargo/

Several files outside the diff still describe the removed @reylosql/<database> packages. One new file is also not covered by CI's scope. These lines aren't in the diff, so they're listed here.

Technical details
# Stale engine-package references and CI scope

## Affected sites
- `engine/postgres/src/lib.rs:8`, `engine/mysql/src/lib.rs:7`, `engine/sqlite/src/lib.rs:7`: crate docs say the WebAssembly component "the package `@reylosql/<db>` carries".
- `engine/native/src/bin/reylo-{postgres,mysql,sqlite,duckdb}.rs:1`: "`@reylosql/<db>`'s engine as a native program". Nothing ships these per-database binaries any more; `reylo engine <db>` replaces them.
- `Cargo.toml:5`: "`reylo-engine-native`, the program each database's WebAssembly component is built from". `Cargo.toml:39-41` still describes "the engine's components".
- `.github/workflows/test.yml:63` (the `everything` regex in `scope`): `.cargo/` is not listed. A PR that changes `.cargo/config.toml` changes the SQLite every native build compiles, yet it would run neither the engine's tests nor the oracle.

## Required outcome
- Comments describe the `reylo` binary and the platform packages.
- A change under `.cargo/` runs every engine check.

## Open questions for the human
- Should the `reylo-<db>` bins in `engine/native/Cargo.toml` stay, for example for the oracle or ad hoc use, or go?

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using claude-opus-5-5 | 𝕏

Comment thread engine/native/src/sqlite.rs Resolved
Comment thread .github/scripts/windows-check.ts Resolved
Comment thread src/native.ts Resolved
Pass REYLO_ENGINE_PATH to the CLI tests' children, keep a held SQLite
file's copies in a private directory removed with its connection, check
a stale binary against its sources' fingerprint, and load wasi-sdk's own
libclang and clang for the playground's bindings.
@colinhacks
Copy link
Copy Markdown
Owner Author

On the review's list: the crate docs, the per-database programs' docs and the workspace comment now describe the reylo binary, and .cargo/ now runs every engine check. The reylo-<database> programs in engine/native stay for now; removing them is a change of its own.

@pullfrog pullfrog Bot left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

The Windows check now crashes on its first run() call, before it checks anything. Because the windows job is skipped on pull requests, this shows up only after the merge, on the push to main.

Reviewed changes

I reviewed a99f766, which answers the initial review and makes the playground build on Linux.

  • SQLite copies of a held file: the copies now go in a directory that Copies::create makes itself. It refuses a path that already exists, is 0o700 on Unix, and is removed on Drop when the connection closes. open_copy now copies the WAL after the file and retries when the log's header changed in between. A Rust test covers the copy, its mode and its removal.
  • Stale-binary guard: tests/fingerprint.test.ts is back. It hashes engine/core and each database crate's sources and compares the result with the fingerprint the binary's ping reports.
  • Engine lookup in CI: windows-check.ts removes REYLO_ENGINE_PATH from its children's environment, so dist/reylo has to find the engine through the platform-package junction. tests/cli.test.ts now passes REYLO_ENGINE_PATH through to its children.
  • CI scope: the everything regex in test.yml's scope now includes .cargo/.
  • Playground on Linux: engine/build.sh points bindgen at wasi-sdk's own libclang and clang.
  • Stale references: the doc comments in the engine crates, the reylo-<db> bins, Cargo.toml and engine/README.md now describe the reylo binary.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using claude-opus-5-5 | 𝕏

Comment thread .github/scripts/windows-check.ts Resolved
binaries.yml builds the eight binaries (release.yml now calls it), then
installs reylo from them on each platform and types and runs a query.
The glibc builds run in manylinux_2_28. Also: copy a held file's journal
and reuse its copy, settle an id-less answer, and word comments without
unreleased products.
@pullfrog pullfrog Bot left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No critical issues. One minor suggestion inline, on the new SQLite copy cache.

Reviewed changes

I reviewed 859e4ca, which installs and runs each platform's binary on that platform and builds the Linux binaries for glibc 2.28.

  • binaries.yml: added a workflow that release.yml calls as its build job and that also runs on pull requests touching the binary. It builds each platform's binary, packs all nine packages, then installs and runs them on each platform. Linux runs in several images: Debian 11, AlmaLinux 8, Amazon Linux 2 10BC8 023 and Alpine.
  • install-check.ts and with-node.sh: added a check that publishes the packed packages to a local Verdaccio registry. It installs reylo in a fresh project, confirms npm brought only this platform's engine, runs reylo generate and the preload on SQLite, and checks Postgres's nesting depth limit against the installed binary.
  • glibc 2.28: linux-gnu is now built in pinned manylinux_2_28 containers, and build-binary.sh fails if the binary needs a glibc symbol newer than 2.28. The SQLite flags now come only from .cargo/config.toml.
  • SQLite copy of a held file: the copy now includes the rollback journal as well as the WAL. It is reused while the file and its logs keep the same size and modification time. A new test covers rolling back a hot journal.
  • Loader: scripts/build.ts checks that PLATFORM_PACKAGES matches npm/platforms.json and requires the built tooling.js. Channel matches an answer with no id to the oldest pending request (the engine answers in order). The checkout fallback picks the newer of target/release and target/debug.
  • windows-check.ts: environment is now declared before the first run(), which fixes the module-scope TDZ crash.
  • Engine docs: the comments in engine/core and engine/postgres no longer mention Reylo Framework or the reylo extension; they now say "a host" and "a server-side extension".

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using claude-opus-5-5 | 𝕏

Comment thread engine/native/src/sqlite.rs Resolved
A file written within the last second may be written again in the same
clock tick with the same size, so its copy is not reused. Also: find the
Windows runner's MySQL wherever its version put it, and leave the install
check's files to the runner where Windows still holds them.
@pullfrog pullfrog Bot left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found. The racy-stamp concern on the SQLite copy cache is addressed.

Reviewed changes

I reviewed 5ced853, which keeps a held SQLite file's copy only after the file has settled, and fixes two things in Windows CI.

  • SQLite copy cache: open_copy now reads now before it takes the stamp. It keeps the stamp only when every file in it was last modified at least a second before now, which is git's rule for a racy index entry. A same-size write in the same clock tick therefore forces a fresh copy. If any file has no modification time, the copy is never kept, which is the safe default. The journal test now covers both a fresh write (copy not kept) and a settled one (copy kept and reused).
  • Windows MySQL: windows.yml now finds mysqld.exe under whatever versioned directory the runner image has, instead of the hard-coded MySQL Server 8.0 path. If it finds no server, the step fails and lists what is there. AGENTS.md no longer pins the version.
  • Install check cleanup: install-check.ts now ignores an error from rmSync in its finally block. On Windows, the engine's child processes still hold their files open until the process exits.

Pullfrog  | View workflow run | Using claude-opus-5-5 | 𝕏

The native engine checked sslrootcert=system against the operating
system's store alone. A chain it refuses is now checked as Node checks
one, against the roots NODE_EXTRA_CA_CERTS names.
@pullfrog pullfrog Bot left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No critical issues. One minor edge case inline, in the new handling of NODE_EXTRA_CA_CERTS.

Reviewed changes

I reviewed 1ccbe22. It makes the native engine trust the roots named by NODE_EXTRA_CA_CERTS as well as the operating system's store.

  • OrExtra verifier: when no root file is named, the native engine still checks the chain with the operating system first. If the system refuses it, the engine checks the chain again with webpki against the extra roots. When that check finds no extra root either (UnknownIssuer), the user sees the system's original error, so a chain to a public CA reports the same failure as before. Both verifiers use the same ring provider, so sending the handshake-signature checks to extra makes no difference.
  • extra_roots(): one helper now reads the extra roots for both the native engine and the WebAssembly engine. The WebAssembly engine still adds them on top of webpki-roots. The loader already passes this variable to the engine, resolved to an absolute path (engineEnv in src/engine.ts).

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using claude-opus-5-5 | 𝕏

Comment thread engine/native/src/tls.rs Resolved
@pullfrog pullfrog Bot left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found. The empty NODE_EXTRA_CA_CERTS store case is handled.

Reviewed changes

I reviewed e11b136, which keeps the system's roots when NODE_EXTRA_CA_CERTS holds no usable root.

  • Empty extra-roots store: in engine/native/src/tls.rs, if none of the file's certificates could be added to the RootCertStore, the native verifier is now the operating system's verifier alone. It no longer builds a WebPkiServerVerifier over an empty store, which returned NoRootAnchors and made every connection fail. This matches Node, which warns about such a file and continues without it.

Pullfrog  | View workflow run | Using claude-opus-5-5 | 𝕏

@colinhacks
colinhacks merged commit d6e0258 into main Nov 2, 2026
33 of 34 checks passed
@colinhacks
colinhacks deleted the engine-binary branch November 2, 2026 21:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

0