Skip to content

feat(cutover#g19): autopg serve dual-transport + runtime.json discovery (WIP — tests pending)#80

Merged
namastex888 merged 3 commits into
mainfrom
feat/cutover-g19-dual-transport
May 8, 2026
Merged

feat(cutover#g19): autopg serve dual-transport + runtime.json discovery (WIP — tests pending)#80
namastex888 merged 3 commits into
mainfrom
feat/cutover-g19-dual-transport

Conversation

@namastex888

Copy link
Copy Markdown
Contributor

Mid-work checkpoint for cutover G19 (NEW group, was NOT-STARTED per audit). Engineer disbanded before final validation; preserves 5 files (+875/-25) for future engineer to finish.

What landed

  • src/lib/runtime-json.js (NEW) — runtime discovery file writer/reader at <socketDir>/runtime.json
  • bin/postgres-server.js — postmaster writes runtime.json after greet, cleans on SIGTERM, leaves on crash
  • src/cli-install.cjs — discovery primitives (port/url/status) read runtime.json first, fall back to ~/.autopg/admin.json and pm2-process inspection
  • tests/cli/serve.test.js (NEW) — dual-transport + runtime.json shape tests
  • tests/lib/runtime-json.test.js (NEW) — writer/reader unit tests

Cohort contract

Critical separation maintained:

  • <socketDir>/runtime.json = live discovery ({ socketDir, port, pid, autopgPid, schemaVersion }), ephemeral
  • ~/.autopg/admin.json = supervisor config ({ supervisor, socketDir, port, installedAt }), persistent
  • runtime.json does NOT carry supervisor field — that's admin.json territory

NOT shipped

  • Tests not yet validated end-to-end
  • G19 acceptance criteria sweep against actual postmaster startup

Holding for engineer to finish before merge.

…ry (mid-work checkpoint)

Engineer disbanded mid-work; this commit preserves the in-progress state.

What landed:
- src/lib/runtime-json.js (NEW): runtime discovery file writer/reader at <socketDir>/runtime.json
- bin/postgres-server.js: postmaster invocation writes runtime.json after greet, cleans on SIGTERM
- src/cli-install.cjs: discovery primitives (port/url/status) read runtime.json first, fall back to admin.json
- tests/cli/serve.test.js (NEW): dual-transport + runtime.json shape tests
- tests/lib/runtime-json.test.js (NEW): writer/reader unit tests

NOT shipped — completion check pending; tests not yet validated end-to-end.
Future engineer must run full validation against G19 acceptance criteria.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 8, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@namastex888 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 46 minutes and 2 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 97dae2f4-1568-448e-aa77-309c964b0e03

📥 Commits

Reviewing files that changed from the base of the PR and between d8cad08 and 116f68e.

📒 Files selected for processing (5)
  • bin/postgres-server.js
  • src/cli-install.cjs
  • src/lib/runtime-json.js
  • tests/cli/serve.test.js
  • tests/lib/runtime-json.test.js
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/cutover-g19-dual-transport

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces a runtime discovery layer for pgserve by implementing a runtime.json file. This file is managed by the postmaster to provide real-time socket and PID information, complementing the existing static configuration files through a fallback chain (runtime.json -> admin.json -> config.json). The CLI commands for status, url, and port have been updated to use this discovery mechanism. Feedback identifies a critical issue in the new integration tests where an undefined variable TEST_PORT is used, which will cause test failures. Additionally, there are recommendations to address code duplication regarding socket directory resolution and process liveness checks to improve maintainability.

Comment thread tests/cli/serve.test.js Outdated
}
});

function spawnPostmaster({ port = TEST_PORT, extraArgs = [] } = {}) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The variable TEST_PORT is used as a default parameter here and throughout the file (e.g., lines 179, 193, 201, 221, 241, 266), but it is never defined. This will cause the tests to fail with a ReferenceError. Based on the constants defined at the top of the file, you likely intended to use PORT_BIND, PORT_RUNTIME, PORT_SIGTERM, and PORT_SIGKILL in their respective test cases to avoid port collisions.

Comment thread src/cli-install.cjs
Comment on lines +221 to +228
function resolveCanonicalSocketDir() {
// Mirror src/lib/socket-dir.js#resolveSocketDir — pure function, no fs
// touch. Inlined here so the sync discovery layer doesn't need a top-
// level await on the ESM module.
const xdg = process.env.XDG_RUNTIME_DIR;
const base = xdg && xdg.length > 0 ? xdg : '/tmp';
return path.join(base, 'pgserve');
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

This function duplicates the logic found in src/lib/socket-dir.js#resolveSocketDir. While the comment explains that inlining it avoids an async dependency in the synchronous discovery layer, it introduces a maintenance risk. If the canonical socket directory resolution logic changes, it must be updated in both places. Consider if this logic can be moved to a shared CommonJS-compatible utility or if the discovery layer can be made asynchronous to leverage the existing ESM module.

Comment thread src/cli-install.cjs
Comment on lines +230 to +238
function isLivePid(pid) {
if (!Number.isInteger(pid) || pid < 1) return false;
try {
process.kill(pid, 0);
return true;
} catch (err) {
return err && err.code === 'EPERM';
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The isLivePid function duplicates the logic of isLiveRuntime in src/lib/runtime-json.js. To improve maintainability and ensure consistency across the codebase, consider centralizing this process liveness check logic.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7e180f189a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/cli/serve.test.js Outdated
}
});

function spawnPostmaster({ port = TEST_PORT, extraArgs = [] } = {}) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Replace undefined TEST_PORT constant in serve tests

The new serve.test.js suite references TEST_PORT, but that identifier is never declared (only PORT_BIND, PORT_RUNTIME, PORT_SIGTERM, and PORT_SIGKILL exist), so calling spawnPostmaster() triggers a ReferenceError from the default parameter and all tests that call waitForReady(TEST_PORT) will also fail immediately. This makes the added test coverage non-runnable in CI until the constant usage is corrected.

Useful? React with 👍 / 👎.

Comment thread src/cli-install.cjs Outdated
Comment on lines +267 to +270
if (runtime) {
composedSocketDir = runtime.socketDir ?? socketDir;
composedPort = runtime.port ?? null;
} else if (admin && Number.isInteger(admin.port)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Ignore invalid runtime.json before applying discovery precedence

In readDiscovery(), any parsed object from runtime.json is treated as authoritative, even if it lacks a valid port, so a malformed-but-JSON object (for example {}) causes composedPort to become null and prevents fallback to admin.json/config.json. In that state, cmdUrl and cmdPort report not installed despite valid persisted configuration, so discovery should only prefer runtime records after validating required fields.

Useful? React with 👍 / 👎.

namastex888 and others added 2 commits May 8, 2026 15:17
…_BIND

CI on PR #80 was red with ReferenceError: TEST_PORT is not defined across
all 4 serve.test.js test cases. The constant was referenced but never
declared.

Fix: each test now owns its own port (PORT_BIND) to avoid TIME_WAIT
collision between consecutive runs; spawnPostmaster() throws if port not
provided.

Local validation: 3/4 pass (1 fails on env port collision unrelated to
this fix). CI on a fresh runner should be all green.

Engineer left this change uncommitted in the worktree; this commit
captures + pushes so CI can pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
PR #80 P2 from chatgpt-codex bot review:
readDiscovery() previously treated ANY parsed runtime.json as authoritative
even if it lacked a valid port or socketDir. A malformed-but-JSON file would
hide later admin.json + config fallbacks because composedPort stayed null
while the precedence chain stopped early. Discovery primitives (port/url/
status) would then return null/undefined and downstream consumers would
fail with confusing 'no port available' errors.

Fix: gate the runtime-takes-precedence path on Number.isInteger(runtime.port)
&& non-empty runtime.socketDir. Mirrors the existing admin / config branch
guards. Malformed runtime.json now falls through to admin.json which falls
through to config — the correct precedence.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@namastex888 namastex888 merged commit c007364 into main May 8, 2026
9 checks passed
@namastex888 namastex888 deleted the feat/cutover-g19-dual-transport branch May 10, 2026 02:44
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