Skip to content

Add standalone symphony-server bin for out-of-process operation - #10

Merged
kriszyp merged 3 commits into
mainfrom
kris/standalone-server
Jun 2, 2026
Merged

Add standalone symphony-server bin for out-of-process operation#10
kriszyp merged 3 commits into
mainfrom
kris/standalone-server

Conversation

@kriszyp

@kriszyp kriszyp commented Jun 1, 2026

Copy link
Copy Markdown
Member

Summary

Adds a symphony-server bin (ts/server.tsdist/server.js) that runs symphony as its own OS process, driven by a JSON config file it watches and hot-reloads. No Rust changes — it reuses the existing napi SymphonyProxy API. Bumps to 0.4.0.

Why

host-manager currently loads symphony in-process, so restarting host-manager takes the edge proxy down with it. This bin lets a supervisor (host-manager — see the paired PR in HarperFast/host-manager) run symphony as a separate, independently-restartable process, and makes the live proxy configuration a readable file.

What it does

  • Reads { version, proxies: [{ listeners, routes }] } — one proxy entry per port-set (the route table is per-proxy). Cert chains are inline PEM; private keys may be referenced by privateKeyFile path, resolved only in the server layer so the napi CertConfig stays inline-only.
  • Watches the config dir; a route change → updateConfig, a listener change → recreate that proxy.
  • Writes status.json ({ pid, version, ports, ... }, atomic temp+rename) for supervisors; SIGHUP reloads, SIGTERM/SIGINT stop gracefully.

Where to look

  • ts/server.ts — the whole bin. Worth a careful read: resolveCert (the file-path cert handling) and the reconcile/portKey matching that decides hot-swap vs. recreate.
  • __test__/server.spec.ts — spawns the real bin and asserts status/version, TLS served with a key loaded by path, and live route reload.

Notes

  • A cross-model review (Codex + Harper-domain) was run; its findings were addressed in-branch (notably making the status write atomic) — nothing left open.
  • Generated by Claude (Opus).

kriszyp and others added 2 commits June 1, 2026 14:52
Ships a config-file-driven Node entrypoint (the `symphony-server` bin) that
runs symphony as its own OS process. It reads a JSON config of per-port
proxies, resolves private keys referenced by file path, hot-reloads routes
when the config file changes, writes a status.json (pid + version) for
supervisors, and stops gracefully on SIGTERM/SIGINT (SIGHUP reloads).

Reuses the existing napi SymphonyProxy API unchanged; the file-path cert form
is resolved only in the server layer so CertConfig stays inline-only. Bumps to
0.4.0.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The status file is rewritten on every config reload; a supervisor polling it
concurrently could read a half-written document and treat symphony as down.
Write via temp + rename so reads always see a complete file.

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

@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 standalone server binary (symphony-server) that runs the symphony proxy as an independent OS process, featuring dynamic configuration hot-reloading, status file writing, and graceful signal handling. It also adds comprehensive integration tests and updates package configurations and documentation. The review feedback highlights critical safety improvements, specifically addressing unsafe non-null assertions on optional certificate configuration fields that could cause runtime errors, and recommending that the file watcher instance be stored, error-handled, and closed properly on shutdown to prevent resource leaks.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread ts/server.ts
Comment thread ts/server.ts
Comment thread ts/server.ts
@kriszyp

kriszyp commented Jun 1, 2026

Copy link
Copy Markdown
Member Author

Heads-up for reviewers: the Harper UDS proxy integration check is red, but it's a pre-existing CI infrastructure failure unrelated to this PR — it fails on `main` and every recent run because that job builds `harper-pro` without checking out its `core` submodule (`error TS2307: Cannot find module '../core/...'`). All platform builds and the unit-test jobs (including the new `server.spec.ts`) pass. No code in this PR touches that path.

— Claude (Opus), on behalf of Kris (AI-generated)

@kriszyp
kriszyp marked this pull request as ready for review June 1, 2026 22:06
- resolveCert/resolveMtls: drop the unsafe non-null assertions; throw a
  descriptive error when neither the inline value nor a file path is provided
  (previously a missing field produced a cryptic path TypeError).
- ServerState: keep the FSWatcher on the instance, register an 'error' listener
  (an fs.watch error would otherwise throw unhandled), and close it in stop().

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@kriszyp
kriszyp merged commit 8f5d804 into main Jun 2, 2026
8 of 10 checks passed
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