Skip to content

[validation-only] verify loopback-bound PGlite gateway and per-run credentials - #1

Draft
1932819331hy-debug wants to merge 9 commits into
mainfrom
codex/pgstrap-pglite-isolation
Draft

1932819331hy-debug wants to merge 9 commits into
mainfrom
codex/pgstrap-pglite-isolation

Conversation

@1932819331hy-debug

@1932819331hy-debug 1932819331hy-debug commented Oct 19, 2026 •

Copy link
Copy Markdown
Owner

Fork-only validation record for seveibar#100. Do not merge this validation PR.

Summary

New projects initialized with pgstrap init use PGlite for db:generate, so schema generation does not need an external PostgreSQL server. The public generate() default stays unchanged. Connection aliases are scoped to the schema-export child process, preserving the caller environment and isolation between concurrent PGlite and external-database calls.

Security and lifecycle corrections

  • Bind the temporary gateway to 127.0.0.1 and generate a fresh 192-bit password per run.
  • Track owned gateway sockets, stop accepting connections, destroy existing sockets and await server shutdown.
  • Close the temporary PGlite database after both success and failure, including migration and listener-startup failures.
  • Preserve a lone error unchanged; preserve simultaneous generation and cleanup failures together in AggregateError.

The lifecycle defect was reproduced with the real built Node library: generate() returned while the database remained open and an idle gateway connection remained alive. Migration exceptions also left the database open.

PostgreSQL protocol errors

The temporary gateway now asks PGlite to return PostgreSQL ErrorResponse frames. Previously, ordinary SQL failures threw into the adapter's generic fallback and clients received SQLSTATE 123 / "Message code not yet implemented" instead of the original error.

Missing-table, syntax and division-by-zero queries still reject. Their standard SQLSTATE and original messages are preserved, and the connection can recover for subsequent simple and parameterized queries.

Initialization in ES module projects

When the target package declares type: "module", pgstrap init now writes an ES module default export in pgstrap.config.js. Default and explicit CommonJS packages keep CommonJS exports. Existing configuration files are preserved. This fixes a real built-CLI failure where initialization succeeded but the next generate command raised module is not defined.

Configuration paths

The project configuration loader now converts its absolute filesystem path with pathToFileURL(...).href before dynamic import. The real Node CLI previously raised ERR_MODULE_NOT_FOUND for existing configurations under directories containing literal #, ? or %25 because the path was interpreted as URL syntax.

This is the path-import root cause already recorded in issue #8. The regression was reproduced independently on this PR's previous head; no first-discovery or new Windows execution claim is made.

Current validation — 2026-10-19

Published head: dcf621142c5aa028efba4e8ae84e3d2a259d06c1 (parent f4f9818e9a77be1cf3e5a2fde5079596a0eed187).

Check Result
New Node loader regression against the actual predecessor 2 passed, 6 failed: ordinary CJS/ESM paths worked, both module types failed under each special-character directory
Same regression on the final source 8 passed, 16 assertions, with real Node loading a build of the production TypeScript loader
Rebuilt CLI in the 3 previously failing directories 3 passed: each applied a real migration and generated types and table SQL containing the target table
npm run build CJS bundles and TypeScript declarations passed
Biome format check on both changed files; git diff --check Passed
Independent review and published-file verification Approved; both remote blobs exactly match the reviewed/tested source, and the local worktree is clean

The initial eight CLI boundary scenarios also checked space/Unicode paths and custom output directories, repeated initialization preserving existing files/dependencies, missing and malformed configuration, and a real schema-dump child failure followed by successful recovery. Those five unaffected scenarios passed on the predecessor; the three failing path cases were then re-run on the final built CLI. The earlier 18-case full suite below was not re-run for this two-file follow-up.

Local validation used Node 24.19.0 and Bun 1.4.3 with existing locked dependencies. The final CLI bundle has SHA-256 7288c25e540ba9a886352a949cd7f95bf767cc83c4f8b49ea41785d501d0d48e. The new test excludes the ? directory case on Windows because that filename is invalid there; Windows execution remains unverified locally.

Upstream checks for this exact new head require maintainer approval: Build, Bun Test, and Format Check all report action_required. They have not executed and are not passing-test evidence.

Earlier initialization validation — f4f9818

Tested previous head: f4f9818e9a77be1cf3e5a2fde5079596a0eed187.

  • The new real Node configuration regression fails on predecessor 50bc792 for an ES module project, while default and explicit CommonJS cases pass.
  • Complete bun test: 10 outer cases plus 1 gateway, 4 cleanup and 3 concurrency fixture cases all passed — 18 cases and 62 assertions.
  • The built Node 24.19.0 CLI completed initialization and generate --pglite in three fresh projects: default package type, explicit CommonJS and ES module. Every run applied a real SQL migration and produced fresh Zapatos types and table SQL while POSTGRES_URI, PG_URI, DATABASE_URL and DATABASE_URI pointed to an unreachable external endpoint.
  • Independent review confirmed compatibility with the existing dynamic configuration loader and reran the five initialization tests: 5 passed, 11 assertions.
  • npm run build, including declarations: passed.
  • npm run format:check: all 21 files passed; git diff --check passed.
  • The published commit's two changed file blobs match the reviewed and tested source.

Local tests used Bun 1.4.3 with the frozen lockfile. On that recorded head, Build, Bun Test and Format Check require maintainer approval (action_required); they have not executed and are not claimed as passing.

Earlier protocol evidence — 50bc792

The real gateway regression failed on predecessor 3b80946 when an absent table lost its 42P01 response. The fix passed missing-table and parameterized division-by-zero regressions, including recovery and generated output. Independent built-Node validation also checked syntax 42601, division by zero 22012 and successful subsequent queries. The earlier full suite retains the gateway, cleanup and connection-environment isolation regressions.

Earlier integration evidence — 3b80946

The built CLI completed init -> generated db:generate script -> npm run db:generate while POSTGRES_URI, PG_URI, DATABASE_URL and DATABASE_URI pointed to an unreachable external endpoint, producing fresh types and SQL. The lifecycle probe reported databaseClosed=true, gatewayListening=false and remainingConnections=0. The earlier suite continues to cover lifecycle cleanup and combined generation/cleanup failures; this earlier CLI run is identified by its own head.

Fork-only validation PR #1 remains an evidence reference. Implemented and independently reviewed with AI assistance.

@algora-pbc /claim seveibar#2

Track and destroy owned gateway sockets, await server and database cleanup on success and failure, and reject failed listener startup. Preserve original and cleanup errors together. Add real PGlite lifecycle and error-composition regressions.
Ask PGlite to return protocol ErrorResponse frames instead of throwing SQL errors into the generic gateway fallback. Add real simple and extended query regressions covering SQLSTATE, original messages and post-error recovery.
Generate an ES module default export for type:module projects so the built Node CLI can load the initialized configuration. Preserve CommonJS defaults and existing configuration files. Add real Node import regressions for all three project modes.
Encode the project config path with pathToFileURL before dynamic import so literal #, ? and percent characters reach the correct file. Retain CommonJS and ES module loading. Add real Node loader regressions, excluding question-mark paths on Windows where those directory names are invalid.

Related to seveibar#8.
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.

1 participant