pgserve 2.1.3 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +86 -0
- package/README.md +105 -1
- package/bin/autopg-wrapper.cjs +16 -0
- package/bin/pgserve-wrapper.cjs +31 -6
- package/bin/postgres-server.js +56 -0
- package/console/README.md +131 -0
- package/console/api.js +173 -0
- package/console/app.jsx +483 -0
- package/console/colors_and_type.css +227 -0
- package/console/components.jsx +167 -0
- package/console/console.css +1666 -0
- package/console/data.jsx +350 -0
- package/console/index.html +31 -0
- package/console/screens/databases.jsx +5 -0
- package/console/screens/health.jsx +5 -0
- package/console/screens/ingress.jsx +5 -0
- package/console/screens/optimizer.jsx +5 -0
- package/console/screens/rlm-sim.jsx +5 -0
- package/console/screens/rlm-trace.jsx +5 -0
- package/console/screens/security.jsx +5 -0
- package/console/screens/settings.jsx +611 -0
- package/console/screens/sql.jsx +5 -0
- package/console/screens/sync.jsx +5 -0
- package/console/screens/tables.jsx +5 -0
- package/console/tweaks-panel.jsx +425 -0
- package/package.json +11 -1
- package/src/cli-config.cjs +310 -0
- package/src/cli-install.cjs +98 -11
- package/src/cli-restart.cjs +228 -0
- package/src/cli-ui.cjs +580 -0
- package/src/cluster.js +43 -38
- package/src/postgres.js +141 -19
- package/src/settings-loader.cjs +235 -0
- package/src/settings-migrate.cjs +212 -0
- package/src/settings-pg-args.cjs +146 -0
- package/src/settings-schema.cjs +422 -0
- package/src/settings-validator.cjs +416 -0
- package/src/settings-writer.cjs +288 -0
- package/.claude/context/windows-debug.md +0 -119
- package/.genie/AGENTS.md +0 -15
- package/.genie/agents/README.md +0 -110
- package/.genie/agents/analyze.md +0 -176
- package/.genie/agents/forge.md +0 -290
- package/.genie/agents/garbage-cleaner.md +0 -324
- package/.genie/agents/garbage-collector.md +0 -596
- package/.genie/agents/github-issue-gc.md +0 -618
- package/.genie/agents/review.md +0 -380
- package/.genie/agents/semantic-analyzer/find-duplicates.md +0 -90
- package/.genie/agents/semantic-analyzer/find-orphans.md +0 -99
- package/.genie/agents/semantic-analyzer.md +0 -101
- package/.genie/agents/update.md +0 -182
- package/.genie/agents/wish.md +0 -357
- package/.genie/brainstorms/pgserve-v2/DESIGN.md +0 -174
- package/.genie/code/AGENTS.md +0 -694
- package/.genie/code/agents/audit/risk.md +0 -173
- package/.genie/code/agents/audit/security.md +0 -189
- package/.genie/code/agents/audit.md +0 -145
- package/.genie/code/agents/challenge.md +0 -230
- package/.genie/code/agents/change-reviewer.md +0 -295
- package/.genie/code/agents/code-garbage-collector.md +0 -425
- package/.genie/code/agents/code-quality.md +0 -410
- package/.genie/code/agents/commit-suggester.md +0 -255
- package/.genie/code/agents/commit.md +0 -124
- package/.genie/code/agents/consensus.md +0 -204
- package/.genie/code/agents/daily-standup.md +0 -722
- package/.genie/code/agents/docgen.md +0 -48
- package/.genie/code/agents/explore.md +0 -79
- package/.genie/code/agents/fix.md +0 -100
- package/.genie/code/agents/git/commit-advisory.md +0 -219
- package/.genie/code/agents/git/workflows/issue.md +0 -244
- package/.genie/code/agents/git/workflows/pr.md +0 -179
- package/.genie/code/agents/git/workflows/release.md +0 -460
- package/.genie/code/agents/git/workflows/report.md +0 -342
- package/.genie/code/agents/git.md +0 -432
- package/.genie/code/agents/implementor.md +0 -161
- package/.genie/code/agents/install.md +0 -515
- package/.genie/code/agents/issue-creator.md +0 -344
- package/.genie/code/agents/polish.md +0 -116
- package/.genie/code/agents/qa.md +0 -653
- package/.genie/code/agents/refactor.md +0 -294
- package/.genie/code/agents/release.md +0 -1129
- package/.genie/code/agents/roadmap.md +0 -885
- package/.genie/code/agents/tests.md +0 -557
- package/.genie/code/agents/tracer.md +0 -50
- package/.genie/code/agents/update/upstream-update.md +0 -85
- package/.genie/code/agents/update/versions/generic-update.md +0 -305
- package/.genie/code/agents/vibe.md +0 -1317
- package/.genie/code/spells/agent-configuration.md +0 -58
- package/.genie/code/spells/automated-rc-publishing.md +0 -106
- package/.genie/code/spells/branch-tracker-guidance.md +0 -28
- package/.genie/code/spells/debug.md +0 -320
- package/.genie/code/spells/emoji-naming-convention.md +0 -303
- package/.genie/code/spells/evidence-storage.md +0 -26
- package/.genie/code/spells/file-naming-rules.md +0 -35
- package/.genie/code/spells/forge-code-blueprints.md +0 -195
- package/.genie/code/spells/genie-integration.md +0 -153
- package/.genie/code/spells/publishing-protocol.md +0 -61
- package/.genie/code/spells/team-consultation-protocol.md +0 -284
- package/.genie/code/spells/tool-requirements.md +0 -20
- package/.genie/code/spells/triad-maintenance-protocol.md +0 -154
- package/.genie/code/teams/tech-council/council.md +0 -328
- package/.genie/code/teams/tech-council/jt.md +0 -352
- package/.genie/code/teams/tech-council/nayr.md +0 -305
- package/.genie/code/teams/tech-council/oettam.md +0 -375
- package/.genie/neurons/README.md +0 -193
- package/.genie/neurons/forge.md +0 -106
- package/.genie/neurons/genie.md +0 -63
- package/.genie/neurons/review.md +0 -106
- package/.genie/neurons/wish.md +0 -104
- package/.genie/product/README.md +0 -20
- package/.genie/product/cli-automation.md +0 -359
- package/.genie/product/environment.md +0 -60
- package/.genie/product/mission.md +0 -60
- package/.genie/product/roadmap.md +0 -44
- package/.genie/product/tech-stack.md +0 -34
- package/.genie/product/templates/context-template.md +0 -218
- package/.genie/product/templates/qa-done-report-template.md +0 -68
- package/.genie/product/templates/review-report-template.md +0 -89
- package/.genie/product/templates/wish-template.md +0 -120
- package/.genie/scripts/helpers/analyze-commit.js +0 -195
- package/.genie/scripts/helpers/bullet-counter.js +0 -194
- package/.genie/scripts/helpers/bullet-find.js +0 -289
- package/.genie/scripts/helpers/bullet-id.js +0 -244
- package/.genie/scripts/helpers/check-secrets.js +0 -237
- package/.genie/scripts/helpers/count-tokens.js +0 -200
- package/.genie/scripts/helpers/create-frontmatter.js +0 -456
- package/.genie/scripts/helpers/detect-markers.js +0 -293
- package/.genie/scripts/helpers/detect-todos.js +0 -267
- package/.genie/scripts/helpers/detect-unlabeled-blocks.js +0 -135
- package/.genie/scripts/helpers/embeddings.js +0 -344
- package/.genie/scripts/helpers/find-empty-sections.js +0 -158
- package/.genie/scripts/helpers/index.js +0 -319
- package/.genie/scripts/helpers/validate-frontmatter.js +0 -578
- package/.genie/scripts/helpers/validate-links.js +0 -207
- package/.genie/scripts/helpers/validate-paths.js +0 -373
- package/.genie/spells/README.md +0 -9
- package/.genie/spells/ace-protocol.md +0 -118
- package/.genie/spells/ask-one-at-a-time.md +0 -175
- package/.genie/spells/backup-analyzer.md +0 -542
- package/.genie/spells/blocker.md +0 -12
- package/.genie/spells/break-things-move-fast.md +0 -56
- package/.genie/spells/context-candidates.md +0 -72
- package/.genie/spells/context-critic.md +0 -51
- package/.genie/spells/defer-to-expertise.md +0 -278
- package/.genie/spells/delegate-dont-do.md +0 -292
- package/.genie/spells/error-investigation-protocol.md +0 -328
- package/.genie/spells/evidence-based-completion.md +0 -273
- package/.genie/spells/experiment.md +0 -65
- package/.genie/spells/file-creation-protocol.md +0 -229
- package/.genie/spells/forge-integration.md +0 -281
- package/.genie/spells/forge-orchestration.md +0 -514
- package/.genie/spells/gather-context.md +0 -18
- package/.genie/spells/global-health-check.md +0 -34
- package/.genie/spells/global-noop-roundtrip.md +0 -25
- package/.genie/spells/install-genie.md +0 -1232
- package/.genie/spells/install.md +0 -82
- package/.genie/spells/investigate-before-commit.md +0 -112
- package/.genie/spells/know-yourself.md +0 -288
- package/.genie/spells/learn.md +0 -828
- package/.genie/spells/mcp-diagnostic-protocol.md +0 -246
- package/.genie/spells/mcp-first.md +0 -124
- package/.genie/spells/multi-step-execution.md +0 -67
- package/.genie/spells/orchestration-boundary-protocol.md +0 -256
- package/.genie/spells/orchestrator-not-implementor.md +0 -189
- package/.genie/spells/prompt.md +0 -746
- package/.genie/spells/reflect.md +0 -404
- package/.genie/spells/routing-decision-matrix.md +0 -368
- package/.genie/spells/run-in-parallel.md +0 -12
- package/.genie/spells/session-state-updater-example.md +0 -196
- package/.genie/spells/session-state-updater.md +0 -220
- package/.genie/spells/track-long-running-tasks.md +0 -133
- package/.genie/spells/troubleshoot-infrastructure.md +0 -176
- package/.genie/spells/upgrade-genie.md +0 -415
- package/.genie/spells/url-presentation-protocol.md +0 -301
- package/.genie/spells/wish-initiation.md +0 -158
- package/.genie/spells/wish-issue-linkage.md +0 -410
- package/.genie/spells/wish-lifecycle.md +0 -100
- package/.genie/state/provider-status.json +0 -3
- package/.genie/state/version.json +0 -16
- package/.genie/wishes/canonical-pgserve-pm2-supervision/WISH.md +0 -290
- package/.genie/wishes/pgserve-v2/BRIEF-from-genie-pgserve.md +0 -99
- package/.genie/wishes/pgserve-v2/WISH.md +0 -442
- package/.genie/wishes/release-system-genie-pattern/WISH.md +0 -268
- package/.genie/wishes/release-system-genie-pattern/validation.md +0 -205
- package/.gitguardian.yaml +0 -29
- package/.gitguardianignore +0 -16
- package/.github/workflows/ci.yml +0 -122
- package/.github/workflows/release.yml +0 -289
- package/.github/workflows/version.yml +0 -228
- package/.husky/pre-commit +0 -2
- package/AGENTS.md +0 -433
- package/CLAUDE.md +0 -1
- package/Makefile +0 -285
- package/assets/icon.ico +0 -0
- package/bun.lock +0 -435
- package/bunfig.toml +0 -28
- package/ecosystem.config.cjs +0 -23
- package/eslint.config.js +0 -63
- package/examples/multi-tenant-demo.js +0 -104
- package/install.sh +0 -123
- package/knip.json +0 -9
- package/scripts/test-bun-self-heal.sh +0 -163
- package/scripts/test-npx.sh +0 -60
- package/tests/audit.test.js +0 -189
- package/tests/backpressure.test.js +0 -167
- package/tests/benchmarks/runner.js +0 -1197
- package/tests/benchmarks/vector-generator.js +0 -368
- package/tests/cli-install.test.js +0 -322
- package/tests/control-db.test.js +0 -285
- package/tests/daemon-args.test.js +0 -86
- package/tests/daemon-control.test.js +0 -171
- package/tests/daemon-fingerprint-integration.test.js +0 -111
- package/tests/daemon-pr24-regression.test.js +0 -198
- package/tests/fingerprint.test.js +0 -263
- package/tests/fixtures/240-orphan-seed.sql +0 -30
- package/tests/multi-tenant.test.js +0 -374
- package/tests/orphan-cleanup.test.js +0 -390
- package/tests/pg-version-regex.test.js +0 -129
- package/tests/quick-bench.js +0 -135
- package/tests/router-handshake-retry.test.js +0 -119
- package/tests/router-handshake-watchdog.test.js +0 -110
- package/tests/sdk.test.js +0 -71
- package/tests/stale-postmaster-pid.test.js +0 -85
- package/tests/stress-test.js +0 -439
- package/tests/sync-perf-test.js +0 -150
- package/tests/tcp-listen.test.js +0 -368
- package/tests/tenancy.test.js +0 -403
- package/tests/wrapper-supervision.test.js +0 -107
|
@@ -1,290 +0,0 @@
|
|
|
1
|
-
# Wish: Canonical pgserve + PM2 supervision across genie/omni/pgserve
|
|
2
|
-
|
|
3
|
-
| Field | Value |
|
|
4
|
-
|-------|-------|
|
|
5
|
-
| **Status** | DRAFT |
|
|
6
|
-
| **Slug** | `canonical-pgserve-pm2-supervision` |
|
|
7
|
-
| **Date** | 2026-04-30 |
|
|
8
|
-
| **Author** | genie-configure |
|
|
9
|
-
| **Appetite** | medium-large |
|
|
10
|
-
| **Repos touched** | `namastexlabs/pgserve`, `automagik-dev/omni`, `automagik-dev/genie`, `namastexlabs/genie-configure` (brain only) |
|
|
11
|
-
| **Design** | _No brainstorm — direct wish from operational pain (live debugging session 2026-04-30)_ |
|
|
12
|
-
|
|
13
|
-
## Summary
|
|
14
|
-
|
|
15
|
-
Canonicalize **pgserve as the single, central, pm2-supervised database server** that every service in the stack connects to. Make `genie serve` and `omni-api`/`omni-nats` peer-equal pm2 services that boot under the same hardening, register via their own `*-install` commands, and consume pgserve through its CLI.
|
|
16
|
-
|
|
17
|
-
**End-state pm2 list:**
|
|
18
|
-
|
|
19
|
-
```
|
|
20
|
-
┌──────────────────────────────────────────┐
|
|
21
|
-
│ pm2 supervisor │
|
|
22
|
-
├──────────────────────────────────────────┤
|
|
23
|
-
│ 1. pgserve ← NEW (canonical PG) │
|
|
24
|
-
│ 2. omni-api ← existing, reconfig │
|
|
25
|
-
│ 3. omni-nats ← existing │
|
|
26
|
-
│ 4. genie-serve ← NEW │
|
|
27
|
-
│ │
|
|
28
|
-
│ + pm2-logrotate (module, already there) │
|
|
29
|
-
└──────────────────────────────────────────┘
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## Trigger
|
|
33
|
-
|
|
34
|
-
Live debugging session, 2026-04-30:
|
|
35
|
-
|
|
36
|
-
1. WhatsApp DM lands at omni-api ✅
|
|
37
|
-
2. omni dispatches to NATS ✅
|
|
38
|
-
3. **bridge silently dropped — `genie serve` was running in a foreground bash on `/dev/pts/24` and died when the shell closed** ❌
|
|
39
|
-
4. Operator (Felipe) sent multiple test messages; nothing came back. Recovery required SSH into the server, kill the orphan, re-launch `genie serve` manually.
|
|
40
|
-
|
|
41
|
-
Earlier in the same session: omni-api was hardened with pm2 + log rotation as part of `omni-lifecycle-hardening` (archived wish). Genie was supposed to follow but never did. The asymmetry is the root cause of every "the bridge is gone again" incident.
|
|
42
|
-
|
|
43
|
-
Same session also revealed: **multiple pgserve instances running in parallel** (3 distinct postgres-server.js processes, each on a different port). Every service that wants Postgres spins its own embedded pgserve. No single source of truth for connection strings; data dirs scattered across `~/.omni/data/pgserve/`, `~/.genie/data/pgserve/`, and `/dev/shm/pgserve-*`.
|
|
44
|
-
|
|
45
|
-
## Scope
|
|
46
|
-
|
|
47
|
-
### IN
|
|
48
|
-
|
|
49
|
-
1. **pgserve gets `install` + `serve` commands.** New subcommands in the pgserve CLI:
|
|
50
|
-
- `pgserve install` — idempotent pm2 registration with hardened defaults (mirror omni's `PM2_HARDENED_DEFAULTS`); creates `~/.pgserve/config.json` with canonical port + data dir.
|
|
51
|
-
- `pgserve serve` — long-lived process pm2 invokes (currently `bin/pgserve-wrapper.cjs daemon`, just renamed for clarity).
|
|
52
|
-
- `pgserve status` / `pgserve url` / `pgserve port` — discovery API for downstream installers.
|
|
53
|
-
- `pgserve uninstall` — `pm2 delete pgserve` + leave data dir intact.
|
|
54
|
-
|
|
55
|
-
2. **Hardened pm2 defaults shared.** Extract `PM2_HARDENED_DEFAULTS` and `buildPm2StartArgs` from `omni/packages/cli/src/pm2.ts` into a small shared shape every installer copies. Constants stay duplicated across repos (avoids a new shared package), but the values are pinned in this wish:
|
|
56
|
-
```
|
|
57
|
-
maxRestarts: 10
|
|
58
|
-
restartDelayMs: 5000
|
|
59
|
-
maxMemoryRestart: 2G (api/serve), 1G (nats)
|
|
60
|
-
killTimeoutMs: 20000
|
|
61
|
-
logDateFormat: YYYY-MM-DD HH:mm:ss.SSS
|
|
62
|
-
logs: ~/.<service>/logs/<name>-{out,error}.log
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
3. **`genie install` (NEW).** Mirror of `omni install`:
|
|
66
|
-
- Calls `pgserve install` first (no-op when already registered).
|
|
67
|
-
- Reads `pgserve url` to get the canonical connection string.
|
|
68
|
-
- Registers `genie-serve` under pm2 with hardened defaults.
|
|
69
|
-
- Writes `~/.genie/config.json` with `databaseUrl: <pgserve url>`.
|
|
70
|
-
- Idempotent; safe to re-run.
|
|
71
|
-
- Adds `--non-interactive` for CI/install.sh.
|
|
72
|
-
|
|
73
|
-
4. **`omni install` reconfigured.** Stops embedding pgserve inside `omni-api`'s lifecycle:
|
|
74
|
-
- Calls `pgserve install` first.
|
|
75
|
-
- Migration: pg_dump from current `~/.omni/data/pgserve/` → restore into canonical pgserve. Stop and pm2-delete the embedded pgserve.
|
|
76
|
-
- Update `omni-api`'s `DATABASE_URL` env to point at canonical pgserve.
|
|
77
|
-
- Existing `omni doctor` already audits this; extend it to check connection-string-points-at-canonical-pgserve.
|
|
78
|
-
|
|
79
|
-
5. **`install.sh` updates.** Both repos' bootstrap scripts route through the new pattern:
|
|
80
|
-
- `omni/install.sh`: install pgserve@latest globally → `pgserve install` → `omni install`.
|
|
81
|
-
- `genie/install.sh`: install pgserve@latest globally → `pgserve install` → `genie install`.
|
|
82
|
-
|
|
83
|
-
6. **Brain documentation.** Add to genie-configure's brain:
|
|
84
|
-
- `Configuration & Routing/canonical-pgserve-pm2.md` — architecture map: 4 pm2 services, pgserve as central PG, install ordering.
|
|
85
|
-
- `Runbooks/recover-pm2-stack.md` — how to diagnose / restart any of the 4 services; `pm2 resurrect` after reboot.
|
|
86
|
-
- `_decisions/2026-04-30-canonical-pgserve.md` — ADR documenting why one pgserve instead of N embedded.
|
|
87
|
-
|
|
88
|
-
### OUT
|
|
89
|
-
|
|
90
|
-
- **No replacement of pgserve with vanilla postgres.** pgserve stays; we only canonicalize how it's deployed.
|
|
91
|
-
- **No port migration tooling for third-party consumers.** If someone else's app talks to omni's old pgserve port directly, they update on their own.
|
|
92
|
-
- **No automatic uninstall of legacy embedded pgserve data dirs.** Migration copies forward; the old data stays on disk until operator removes it (avoids accidental data loss).
|
|
93
|
-
- **No multi-host pgserve cluster.** Single host only. Multi-host pgserve is a separate, much larger wish.
|
|
94
|
-
- **No systemd / launchd path.** pm2 is the single supervisor for this iteration. Aegis-runtime wish covers a future systemd-user variant.
|
|
95
|
-
|
|
96
|
-
## Decisions
|
|
97
|
-
|
|
98
|
-
| # | Decision | Rationale |
|
|
99
|
-
|---|---|---|
|
|
100
|
-
| 1 | pgserve owns the install + serve subcommands | Other services should NOT know how to register pgserve under pm2 — that's pgserve's responsibility. Same pattern as omni owning omni-api/nats. |
|
|
101
|
-
| 2 | Idempotent `*-install` everywhere | Every installer can be re-run without harm. Re-running `pgserve install` after it's already registered exits 0 with "already installed." Same for `omni install` and `genie install`. |
|
|
102
|
-
| 3 | Cross-repo install dependency: pgserve → omni & genie | omni and genie shell out to `pgserve install` first. They DON'T re-implement pgserve registration. Tighter coupling, but simpler than a shared package, and avoids "two installers disagree on hardening defaults." |
|
|
103
|
-
| 4 | `--interpreter none` for pm2 launches | Both genie and omni binaries use `#!/usr/bin/env bun` shebangs. `--interpreter bun` triggers pm2's ESM/require crash on top-level await. Shebang resolution side-steps the issue. **Empirically validated 2026-04-30** during the manual genie-serve pm2 registration. |
|
|
104
|
-
| 5 | `genie serve start --headless --no-tui --no-interactive` for pm2 | TUI requires a real terminal; pm2 child has no tty. Headless + no-tui matches omni-api's mode. **Empirically validated 2026-04-30.** |
|
|
105
|
-
| 6 | Migration via pg_dump + restore (not file-level copy) | Data file format is sensitive to PG version; pg_dump is portable. Even with same pgserve version, dump+restore is the safe path. |
|
|
106
|
-
| 7 | Single config file per service, no shared "canonical config" file | `pgserve install` writes `~/.pgserve/config.json`; consumers read it via `pgserve url`. We don't introduce a `~/.canonical/` directory or similar. The CLI is the contract. |
|
|
107
|
-
| 8 | pm2-logrotate stays as a module, not a pm2 service | It's a pm2 module by design; `omni install` already configures it. `pgserve install` reuses the same pm2-logrotate (no duplicate setup). |
|
|
108
|
-
|
|
109
|
-
## Success Criteria
|
|
110
|
-
|
|
111
|
-
- [ ] `pgserve install` registers `pgserve` as a pm2 service with hardened defaults; idempotent on second invocation.
|
|
112
|
-
- [ ] `pgserve url` returns a valid connection string that other tools can use without pgserve being CLI-imported.
|
|
113
|
-
- [ ] `omni install` on a clean machine results in: `pgserve` + `omni-api` + `omni-nats` all under pm2 with green status.
|
|
114
|
-
- [ ] `genie install` on a clean machine results in: `pgserve` + `genie-serve` all under pm2 with green status.
|
|
115
|
-
- [ ] On a machine where both omni and genie are installed, exactly **4 pm2 services** are present (pgserve, omni-api, omni-nats, genie-serve), pgserve is shared, and both `omni doctor` and `genie doctor` are green.
|
|
116
|
-
- [ ] On reboot, `pm2 resurrect` brings all 4 services back online with correct env.
|
|
117
|
-
- [ ] Existing omni installs migrate without data loss: pre-migration `omni events list` content matches post-migration content.
|
|
118
|
-
- [ ] `genie serve` running under pm2 survives shell closure (the bug that triggered this wish stays fixed forever).
|
|
119
|
-
- [ ] `omni doctor` and `genie doctor` both gain a check: "process is registered under pm2 with hardened defaults" (yes/no with one-line remediation if no).
|
|
120
|
-
- [ ] Brain entries (architecture map, runbook, ADR) merged in genie-configure.
|
|
121
|
-
|
|
122
|
-
## Execution Strategy
|
|
123
|
-
|
|
124
|
-
Wave-based; each wave can ship independently. Three repos, four PRs total.
|
|
125
|
-
|
|
126
|
-
### Wave 1 — `pgserve` foundation (BLOCKS waves 2 & 3)
|
|
127
|
-
|
|
128
|
-
**Goal:** pgserve owns its pm2 lifecycle.
|
|
129
|
-
|
|
130
|
-
- Group 1.1 — `pgserve install` + `pgserve serve` + `pgserve status` + `pgserve url` + `pgserve port`. Add `--non-interactive` for CI/install.sh. New file: `src/commands/install.ts` (mirror omni's structure).
|
|
131
|
-
- Group 1.2 — Tests: install idempotency, status reflects pm2 state, url/port match what install registered.
|
|
132
|
-
- Group 1.3 — README: document the 4 new subcommands.
|
|
133
|
-
|
|
134
|
-
**Validation:**
|
|
135
|
-
```bash
|
|
136
|
-
bunx pgserve install # green; pm2 list shows `pgserve`
|
|
137
|
-
bunx pgserve install # exits 0, "already installed"
|
|
138
|
-
bunx pgserve url # postgres://localhost:8432/postgres
|
|
139
|
-
bunx pgserve status --json # { name: "pgserve", status: "online", port: 8432, dataDir: "..." }
|
|
140
|
-
pm2 list | grep pgserve # online, max-restarts=10, etc.
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
**PR:** `namastexlabs/pgserve#???` — `feat(cli): pgserve install + pm2 supervision`.
|
|
144
|
-
|
|
145
|
-
### Wave 2 — `genie install` (depends on Wave 1)
|
|
146
|
-
|
|
147
|
-
**Goal:** Genie has parity with omni — `genie install` registers `genie-serve` under pm2 by calling `pgserve install` first.
|
|
148
|
-
|
|
149
|
-
- Group 2.1 — New `genie install` command in `src/genie-commands/install.ts`. Calls `pgserve install`, then `pm2 start` for genie-serve with the hardened args validated in this server's manual test (`--interpreter none` + `serve start --headless --no-tui --no-interactive`).
|
|
150
|
-
- Group 2.2 — Update `genie serve start` to detect when genie-serve is already pm2-supervised: print "Already managed by pm2; use `pm2 restart genie-serve`" and exit. Avoid the multi-instance lockfile dance.
|
|
151
|
-
- Group 2.3 — `genie doctor` adds `pm2-supervision` check.
|
|
152
|
-
- Group 2.4 — Tests for install command (with PM2 stubbed).
|
|
153
|
-
- Group 2.5 — `install.sh` updated to call `pgserve install` then `genie install`.
|
|
154
|
-
|
|
155
|
-
**Validation:**
|
|
156
|
-
```bash
|
|
157
|
-
genie install # green
|
|
158
|
-
pm2 list # includes pgserve + genie-serve
|
|
159
|
-
genie doctor # all green
|
|
160
|
-
genie serve stop && genie install # idempotent
|
|
161
|
-
# kill the shell that ran install — bridge stays alive (the original incident's reproduction)
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
**PR:** `automagik-dev/genie#???` — `feat(cli): genie install + pm2 supervision`.
|
|
165
|
-
|
|
166
|
-
### Wave 3 — `omni install` reconfig (depends on Wave 1)
|
|
167
|
-
|
|
168
|
-
**Goal:** Omni's installer routes through canonical pgserve instead of the embedded one.
|
|
169
|
-
|
|
170
|
-
- Group 3.1 — `omni install` calls `pgserve install` before `omni-api` registration.
|
|
171
|
-
- Group 3.2 — Migration handler: detect existing `~/.omni/data/pgserve/` running under omni-api → pg_dump → restore into canonical pgserve → update omni-api `DATABASE_URL` env → delete embedded pgserve from pm2 → preserve old data dir on disk (operator can `rm -rf` later when satisfied).
|
|
172
|
-
- Group 3.3 — `omni doctor` adds `connection-string-canonical` check.
|
|
173
|
-
- Group 3.4 — Tests for migration path (start with embedded, run install, verify omni-api connects to canonical).
|
|
174
|
-
- Group 3.5 — `install.sh` updated to call `pgserve install` first.
|
|
175
|
-
|
|
176
|
-
**Validation:**
|
|
177
|
-
```bash
|
|
178
|
-
# Fresh machine
|
|
179
|
-
omni install
|
|
180
|
-
pm2 list # pgserve + omni-api + omni-nats
|
|
181
|
-
omni doctor # all green; connection-string-canonical=ok
|
|
182
|
-
|
|
183
|
-
# Existing machine (with embedded pgserve)
|
|
184
|
-
omni install # detects legacy, runs migration
|
|
185
|
-
omni events list --limit 100 # data preserved post-migration
|
|
186
|
-
pm2 list # pgserve + omni-api + omni-nats (no embedded pgserve)
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
**PR:** `automagik-dev/omni#???` — `feat(install): canonical pgserve + migration from embedded`.
|
|
190
|
-
|
|
191
|
-
### Wave 4 — Brain ingestion (depends on Waves 1–3 merging)
|
|
192
|
-
|
|
193
|
-
**Goal:** Document the canonical layout so future agents inheriting any of these servers know the pattern by reading a single file.
|
|
194
|
-
|
|
195
|
-
- Group 4.1 — `brain/Configuration & Routing/canonical-pgserve-pm2.md`: architecture map; 4-service ascii diagram; pgserve discovery via `pgserve url`; install ordering.
|
|
196
|
-
- Group 4.2 — `brain/Runbooks/recover-pm2-stack.md`: diagnose/restart any of the 4 services; `pm2 resurrect` after reboot; rollback to embedded pgserve (if migration goes wrong).
|
|
197
|
-
- Group 4.3 — `brain/_decisions/2026-04-30-canonical-pgserve.md`: ADR; alternatives considered (vanilla postgres, systemd-user, embedded-everywhere); consequences.
|
|
198
|
-
|
|
199
|
-
**PR:** `namastexlabs/genie-configure#???` — `chore(brain): canonical pgserve + pm2 supervision`.
|
|
200
|
-
|
|
201
|
-
## Dependencies
|
|
202
|
-
|
|
203
|
-
```
|
|
204
|
-
Wave 1 (pgserve) ──┬──→ Wave 2 (genie)
|
|
205
|
-
├──→ Wave 3 (omni)
|
|
206
|
-
└──→ Wave 4 (brain — also depends on Wave 2 & 3)
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
Cross-wish: closes the operator-lockout footgun the canonical-genie-omni-wiring + omni-host-fingerprint-trust wishes paved over with workarounds. Doesn't conflict with `aegis-runtime` (separate daemon, separate supervisor).
|
|
210
|
-
|
|
211
|
-
## QA Criteria
|
|
212
|
-
|
|
213
|
-
- [ ] On a fresh Ubuntu 24 box: `curl … omni/install.sh | bash` results in 3 pm2 services (pgserve + omni-api + omni-nats), green doctor.
|
|
214
|
-
- [ ] On the same box: `curl … genie/install.sh | bash` adds genie-serve = 4 pm2 services. pgserve shared.
|
|
215
|
-
- [ ] Reboot the box: `pm2 resurrect` brings all 4 back; both doctors green; bridge subscribes to NATS without manual intervention.
|
|
216
|
-
- [ ] Kill any one of the 4 services with SIGKILL: pm2 restarts it within 5 s; doctor goes red briefly then green.
|
|
217
|
-
- [ ] On a machine with the OLD embedded pgserve setup: `omni install` (post-Wave-3) migrates without data loss.
|
|
218
|
-
- [ ] `pgserve install` followed by `pgserve install --rotate-port 8433` correctly re-registers pgserve on the new port and updates omni-api/genie-serve env (or refuses cleanly if they're using the old port).
|
|
219
|
-
- [ ] `omni-host-fingerprint-trust` pipeline (the wish that closed two days before this one) keeps working — instances flagged `requireGenieSignature: true` still get gated correctly post-migration.
|
|
220
|
-
|
|
221
|
-
## Assumptions / Risks
|
|
222
|
-
|
|
223
|
-
| # | Item | Risk | Mitigation |
|
|
224
|
-
|---|---|---|---|
|
|
225
|
-
| 1 | pgserve repo accepts the new install/serve subcommands | Low — author is in the same org | If rejected, fall back to having omni and genie register pgserve directly (loses the "owned by pgserve" property but still gets us to 4 services). |
|
|
226
|
-
| 2 | Migration from embedded pgserve preserves all data | Medium — pg_dump on a live system + connection-string switch is non-trivial | Stage in Wave 3 with `--dry-run` first; document rollback. Take filesystem snapshot before running on production. |
|
|
227
|
-
| 3 | pm2 ESM/await crash with bun on future bun versions | Low | `--interpreter none` is robust; documented Decision 4. |
|
|
228
|
-
| 4 | Operators who customized their existing pgserve port will be confused | Medium | `omni doctor` and `genie doctor` add explicit "this service points at non-canonical pgserve" check with override flag. |
|
|
229
|
-
| 5 | NATS port also needs canonicalization (similar split-brain risk) | Out of scope for this wish | Park as a follow-up wish if it becomes a problem. omni-nats is single-instance today via pm2 so no urgency. |
|
|
230
|
-
| 6 | genie-configure (this brain) is not in the cycle | None | Wave 4 lands the docs in this repo only; no source code changes here. |
|
|
231
|
-
|
|
232
|
-
## Files to Create / Modify
|
|
233
|
-
|
|
234
|
-
### `namastexlabs/pgserve` (Wave 1)
|
|
235
|
-
- `src/commands/install.ts` (new)
|
|
236
|
-
- `src/commands/serve.ts` (new — likely a thin wrapper around the existing wrapper)
|
|
237
|
-
- `src/commands/status.ts`, `src/commands/url.ts`, `src/commands/port.ts` (new)
|
|
238
|
-
- `src/lib/pm2-args.ts` (new — shared pm2 launch builder, mirror of omni's)
|
|
239
|
-
- `bin/pgserve-wrapper.cjs` (modify — add subcommand routing)
|
|
240
|
-
- `__tests__/install.test.ts`, `__tests__/url.test.ts` (new)
|
|
241
|
-
- `README.md` (modify)
|
|
242
|
-
|
|
243
|
-
### `automagik-dev/genie` (Wave 2)
|
|
244
|
-
- `src/genie-commands/install.ts` (new)
|
|
245
|
-
- `src/genie-commands/doctor.ts` (modify — add pm2-supervision check)
|
|
246
|
-
- `src/term-commands/serve.ts` (modify — detect pm2 supervision, defer)
|
|
247
|
-
- `install.sh` (modify — route through `pgserve install` + `genie install`)
|
|
248
|
-
- `src/lib/pm2-args.ts` (new — copy from this wish's spec)
|
|
249
|
-
- Tests for install + doctor changes.
|
|
250
|
-
|
|
251
|
-
### `automagik-dev/omni` (Wave 3)
|
|
252
|
-
- `packages/cli/src/commands/install.ts` (modify — call `pgserve install` first; remove embedded pgserve registration)
|
|
253
|
-
- `packages/cli/src/lib/migrate-from-embedded-pgserve.ts` (new)
|
|
254
|
-
- `packages/cli/src/commands/doctor.ts` (modify — add canonical-connection-string check)
|
|
255
|
-
- `install.sh` (modify — `pgserve install` step)
|
|
256
|
-
- Tests for migration path.
|
|
257
|
-
|
|
258
|
-
### `namastexlabs/genie-configure` (Wave 4)
|
|
259
|
-
- `brain/Configuration & Routing/canonical-pgserve-pm2.md` (new)
|
|
260
|
-
- `brain/Runbooks/recover-pm2-stack.md` (new)
|
|
261
|
-
- `brain/_decisions/2026-04-30-canonical-pgserve.md` (new)
|
|
262
|
-
|
|
263
|
-
## Validated Beachhead (already shipped manually)
|
|
264
|
-
|
|
265
|
-
The genie-serve part is **already running under pm2** on this server as of 2026-04-30 16:08 UTC. Manual command used:
|
|
266
|
-
|
|
267
|
-
```bash
|
|
268
|
-
pm2 start /home/genie/.bun/bin/genie \
|
|
269
|
-
--name genie-serve \
|
|
270
|
-
--interpreter none \
|
|
271
|
-
--max-restarts 10 \
|
|
272
|
-
--restart-delay 5000 \
|
|
273
|
-
--max-memory-restart 2G \
|
|
274
|
-
--kill-timeout 20000 \
|
|
275
|
-
--log-date-format 'YYYY-MM-DD HH:mm:ss.SSS' \
|
|
276
|
-
--output ~/.genie/logs/genie-serve-out.log \
|
|
277
|
-
--error ~/.genie/logs/genie-serve-error.log \
|
|
278
|
-
-- serve start --headless --no-tui --no-interactive
|
|
279
|
-
|
|
280
|
-
pm2 save
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
Wave 2 codifies this exact invocation as `genie install`. The args are pinned in Decisions 4 & 5.
|
|
284
|
-
|
|
285
|
-
## See also
|
|
286
|
-
|
|
287
|
-
- `omni-lifecycle-hardening` (archived) — established the omni-api pm2 hardening pattern this wish extends.
|
|
288
|
-
- `aegis-runtime` (draft) — different daemon, different supervisor (launchd/systemd-user), no conflict.
|
|
289
|
-
- `invincible-genie` (draft) — orthogonal: that wish is about `genie serve` self-healing; this wish is about `genie serve` being supervised in the first place. Both can ship independently.
|
|
290
|
-
- `pgserve-proxy-resilience` — sets up pgserve to exit cleanly when its child dies (so a supervisor can restart it). This wish is the supervisor side of that contract.
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
# Brief from genie-pgserve (parent agent)
|
|
2
|
-
|
|
3
|
-
Read this AFTER WISH.md. Critical operational context that supersedes parts of the wish.
|
|
4
|
-
|
|
5
|
-
## CRITICAL — genie wish-parser regression is active
|
|
6
|
-
|
|
7
|
-
Your CLI version is **4.260426.4**. Both `genie work pgserve-v2` and `genie wish status pgserve-v2` will fail with:
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
❌ Group "N" depends on non-existent group "pgserve-v2#M"
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
**Do not interpret that error as a wish problem.** The wish is well-formed.
|
|
14
|
-
|
|
15
|
-
**Root cause** (already debugged):
|
|
16
|
-
- `automagik-dev/genie` `src/term-commands/dispatch.ts:189-197` — `parseWishGroups` stores group names as bare ids (`"1"`, `"2"`) but does NOT strip the `<slug>#` prefix from depends-on entries.
|
|
17
|
-
- Then `src/lib/wish-state.ts:240` — `validateGroupRefs` does `groupNames.has("pgserve-v2#1")` against `{"0".."8"}` and throws.
|
|
18
|
-
- Affects EVERY wish using the canonical `<slug>#<n>` depends-on form, including the shipped reference `release-system-genie-pattern`.
|
|
19
|
-
|
|
20
|
-
**GH issue filed**: https://github.com/automagik-dev/genie/issues/1406
|
|
21
|
-
**Fix-wish draft**: `/home/genie/workspace/agents/genie-pgserve/brain/_decisions/genie-parser-fix-wish-draft.md`
|
|
22
|
-
|
|
23
|
-
## Workaround you must use
|
|
24
|
-
|
|
25
|
-
Bypass `genie work` orchestration. Dispatch each group manually:
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
genie spawn engineer # or reviewer / fix / qa
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
Then `genie send` a curated prompt to the spawned engineer with this structure (per the /work skill's Context Curation rules — DO NOT just say "read WISH.md"):
|
|
32
|
-
|
|
33
|
-
```
|
|
34
|
-
Execute Group N of wish "pgserve-v2".
|
|
35
|
-
|
|
36
|
-
Goal: <one sentence from WISH.md>
|
|
37
|
-
|
|
38
|
-
Deliverables:
|
|
39
|
-
1. <copy from WISH.md>
|
|
40
|
-
2. <copy from WISH.md>
|
|
41
|
-
|
|
42
|
-
Acceptance Criteria:
|
|
43
|
-
- [ ] <copy from WISH.md>
|
|
44
|
-
- [ ] <copy from WISH.md>
|
|
45
|
-
|
|
46
|
-
Validation:
|
|
47
|
-
<copy the bash block from WISH.md>
|
|
48
|
-
|
|
49
|
-
Depends-on: <human-resolved — group N from this wish, already complete>
|
|
50
|
-
|
|
51
|
-
Repo: /home/genie/workspace/repos/pgserve
|
|
52
|
-
Branch: pgserve-v2 (from wish/pgserve-v2)
|
|
53
|
-
Worktree: /home/genie/.genie/worktrees/pgserve/pgserve-v2
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
Track group state via your own scratchpad in this worktree (e.g. `STATUS.md` next to this brief). Mark groups done as engineers report PASS.
|
|
57
|
-
|
|
58
|
-
## Execution order — start parallel waves NOW
|
|
59
|
-
|
|
60
|
-
| Wave | Groups | When |
|
|
61
|
-
|------|--------|------|
|
|
62
|
-
| **0** | Group 0 (dogfooder twin) | Spawn now, runs continuously |
|
|
63
|
-
| **1** | Group 1 (control DB + audit infra) | Sequential foundation, spawn now in parallel with Group 0 |
|
|
64
|
-
| **2** | Group 2 (daemon) ‖ Group 3 (fingerprint) | After Group 1 ships |
|
|
65
|
-
| **3** | Group 4 (per-fp DB enforcement) | After Wave 2 ships |
|
|
66
|
-
| **4** | Group 5 (lifecycle/GC) ‖ Group 6 (--listen TCP) | After Group 4 ships |
|
|
67
|
-
| **5** | Group 7 (genie consumer migration) | After Wave 4 ships |
|
|
68
|
-
| **6** | Group 8 (release prep, ship 2.0.0) | After Group 7 ships |
|
|
69
|
-
|
|
70
|
-
## Important consumer-repo correction
|
|
71
|
-
|
|
72
|
-
The canary consumer for Group 7 / Group 0 dogfooder is **`automagik-dev/genie`**, cloned at **`/home/genie/workspace/repos/genie`**. NOT `automagik-genie` (no such repo). NOT `namastexlabs/genie`. The wish has been corrected but your initial mental model may have absorbed the earlier wrong name from the genie team-lead system prompt. Verify with `git -C /home/genie/workspace/repos/genie remote -v` before any consumer-side work.
|
|
73
|
-
|
|
74
|
-
## Felipe's standing constraints
|
|
75
|
-
|
|
76
|
-
From `agents/genie-pgserve/AGENTS.md`:
|
|
77
|
-
- **Don't restart the running pgserve daemon** at PID 160588 (orphaned but Felipe is using it for the email brain).
|
|
78
|
-
- **Don't drop any `brain_*` databases** without Felipe's explicit OK.
|
|
79
|
-
- **Don't merge PR #16** in `namastexlabs/pgserve` — it's superseded by this wish (delete schema/role machinery, use database-per-fingerprint).
|
|
80
|
-
- **Don't propose substituting pgserve with vanilla Postgres** — pgserve IS the answer.
|
|
81
|
-
- **Don't spawn pgserve daemons for testing** — use ephemeral test instances per the wish's test fixtures, never daemon mode in tests.
|
|
82
|
-
|
|
83
|
-
## Reporting back
|
|
84
|
-
|
|
85
|
-
Cross-team scope is locked one-way (you → me, not me → you). Report status, blockers, completions to me via:
|
|
86
|
-
|
|
87
|
-
```bash
|
|
88
|
-
genie send '<msg>' --to genie-pgserve --bridge
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
I will relay any course-correction signals from Felipe back to you via this BRIEF file (I'll append a `## Update <timestamp>` section). Re-read this file at the start of each wave.
|
|
92
|
-
|
|
93
|
-
## Felipe's non-negotiable for this wish
|
|
94
|
-
|
|
95
|
-
- 1.2.0 is the last non-breaking version on the v1 line; lock it.
|
|
96
|
-
- 2.0.0 is THIS wish's target — single breaking cut, not staged.
|
|
97
|
-
- The 5 non-genie consumers (brain, omni, rlmx, hapvida-eugenia, email) MUST be advised to pin `pgserve@^1.x` before 2.0.0 ships. Group 8's release prep includes that advisory; do not skip it.
|
|
98
|
-
|
|
99
|
-
Good hunting.
|