pgserve 2.1.2 → 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.
Files changed (227) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/README.md +105 -1
  3. package/bin/autopg-wrapper.cjs +16 -0
  4. package/bin/pgserve-wrapper.cjs +31 -6
  5. package/bin/postgres-server.js +80 -7
  6. package/console/README.md +131 -0
  7. package/console/api.js +173 -0
  8. package/console/app.jsx +483 -0
  9. package/console/colors_and_type.css +227 -0
  10. package/console/components.jsx +167 -0
  11. package/console/console.css +1666 -0
  12. package/console/data.jsx +350 -0
  13. package/console/index.html +31 -0
  14. package/console/screens/databases.jsx +5 -0
  15. package/console/screens/health.jsx +5 -0
  16. package/console/screens/ingress.jsx +5 -0
  17. package/console/screens/optimizer.jsx +5 -0
  18. package/console/screens/rlm-sim.jsx +5 -0
  19. package/console/screens/rlm-trace.jsx +5 -0
  20. package/console/screens/security.jsx +5 -0
  21. package/console/screens/settings.jsx +611 -0
  22. package/console/screens/sql.jsx +5 -0
  23. package/console/screens/sync.jsx +5 -0
  24. package/console/screens/tables.jsx +5 -0
  25. package/console/tweaks-panel.jsx +425 -0
  26. package/package.json +11 -1
  27. package/src/cli-config.cjs +310 -0
  28. package/src/cli-install.cjs +98 -11
  29. package/src/cli-restart.cjs +228 -0
  30. package/src/cli-ui.cjs +580 -0
  31. package/src/cluster.js +43 -38
  32. package/src/postgres.js +141 -19
  33. package/src/settings-loader.cjs +235 -0
  34. package/src/settings-migrate.cjs +212 -0
  35. package/src/settings-pg-args.cjs +146 -0
  36. package/src/settings-schema.cjs +422 -0
  37. package/src/settings-validator.cjs +416 -0
  38. package/src/settings-writer.cjs +288 -0
  39. package/.claude/context/windows-debug.md +0 -119
  40. package/.genie/AGENTS.md +0 -15
  41. package/.genie/agents/README.md +0 -110
  42. package/.genie/agents/analyze.md +0 -176
  43. package/.genie/agents/forge.md +0 -290
  44. package/.genie/agents/garbage-cleaner.md +0 -324
  45. package/.genie/agents/garbage-collector.md +0 -596
  46. package/.genie/agents/github-issue-gc.md +0 -618
  47. package/.genie/agents/review.md +0 -380
  48. package/.genie/agents/semantic-analyzer/find-duplicates.md +0 -90
  49. package/.genie/agents/semantic-analyzer/find-orphans.md +0 -99
  50. package/.genie/agents/semantic-analyzer.md +0 -101
  51. package/.genie/agents/update.md +0 -182
  52. package/.genie/agents/wish.md +0 -357
  53. package/.genie/brainstorms/pgserve-v2/DESIGN.md +0 -174
  54. package/.genie/code/AGENTS.md +0 -694
  55. package/.genie/code/agents/audit/risk.md +0 -173
  56. package/.genie/code/agents/audit/security.md +0 -189
  57. package/.genie/code/agents/audit.md +0 -145
  58. package/.genie/code/agents/challenge.md +0 -230
  59. package/.genie/code/agents/change-reviewer.md +0 -295
  60. package/.genie/code/agents/code-garbage-collector.md +0 -425
  61. package/.genie/code/agents/code-quality.md +0 -410
  62. package/.genie/code/agents/commit-suggester.md +0 -255
  63. package/.genie/code/agents/commit.md +0 -124
  64. package/.genie/code/agents/consensus.md +0 -204
  65. package/.genie/code/agents/daily-standup.md +0 -722
  66. package/.genie/code/agents/docgen.md +0 -48
  67. package/.genie/code/agents/explore.md +0 -79
  68. package/.genie/code/agents/fix.md +0 -100
  69. package/.genie/code/agents/git/commit-advisory.md +0 -219
  70. package/.genie/code/agents/git/workflows/issue.md +0 -244
  71. package/.genie/code/agents/git/workflows/pr.md +0 -179
  72. package/.genie/code/agents/git/workflows/release.md +0 -460
  73. package/.genie/code/agents/git/workflows/report.md +0 -342
  74. package/.genie/code/agents/git.md +0 -432
  75. package/.genie/code/agents/implementor.md +0 -161
  76. package/.genie/code/agents/install.md +0 -515
  77. package/.genie/code/agents/issue-creator.md +0 -344
  78. package/.genie/code/agents/polish.md +0 -116
  79. package/.genie/code/agents/qa.md +0 -653
  80. package/.genie/code/agents/refactor.md +0 -294
  81. package/.genie/code/agents/release.md +0 -1129
  82. package/.genie/code/agents/roadmap.md +0 -885
  83. package/.genie/code/agents/tests.md +0 -557
  84. package/.genie/code/agents/tracer.md +0 -50
  85. package/.genie/code/agents/update/upstream-update.md +0 -85
  86. package/.genie/code/agents/update/versions/generic-update.md +0 -305
  87. package/.genie/code/agents/vibe.md +0 -1317
  88. package/.genie/code/spells/agent-configuration.md +0 -58
  89. package/.genie/code/spells/automated-rc-publishing.md +0 -106
  90. package/.genie/code/spells/branch-tracker-guidance.md +0 -28
  91. package/.genie/code/spells/debug.md +0 -320
  92. package/.genie/code/spells/emoji-naming-convention.md +0 -303
  93. package/.genie/code/spells/evidence-storage.md +0 -26
  94. package/.genie/code/spells/file-naming-rules.md +0 -35
  95. package/.genie/code/spells/forge-code-blueprints.md +0 -195
  96. package/.genie/code/spells/genie-integration.md +0 -153
  97. package/.genie/code/spells/publishing-protocol.md +0 -61
  98. package/.genie/code/spells/team-consultation-protocol.md +0 -284
  99. package/.genie/code/spells/tool-requirements.md +0 -20
  100. package/.genie/code/spells/triad-maintenance-protocol.md +0 -154
  101. package/.genie/code/teams/tech-council/council.md +0 -328
  102. package/.genie/code/teams/tech-council/jt.md +0 -352
  103. package/.genie/code/teams/tech-council/nayr.md +0 -305
  104. package/.genie/code/teams/tech-council/oettam.md +0 -375
  105. package/.genie/neurons/README.md +0 -193
  106. package/.genie/neurons/forge.md +0 -106
  107. package/.genie/neurons/genie.md +0 -63
  108. package/.genie/neurons/review.md +0 -106
  109. package/.genie/neurons/wish.md +0 -104
  110. package/.genie/product/README.md +0 -20
  111. package/.genie/product/cli-automation.md +0 -359
  112. package/.genie/product/environment.md +0 -60
  113. package/.genie/product/mission.md +0 -60
  114. package/.genie/product/roadmap.md +0 -44
  115. package/.genie/product/tech-stack.md +0 -34
  116. package/.genie/product/templates/context-template.md +0 -218
  117. package/.genie/product/templates/qa-done-report-template.md +0 -68
  118. package/.genie/product/templates/review-report-template.md +0 -89
  119. package/.genie/product/templates/wish-template.md +0 -120
  120. package/.genie/scripts/helpers/analyze-commit.js +0 -195
  121. package/.genie/scripts/helpers/bullet-counter.js +0 -194
  122. package/.genie/scripts/helpers/bullet-find.js +0 -289
  123. package/.genie/scripts/helpers/bullet-id.js +0 -244
  124. package/.genie/scripts/helpers/check-secrets.js +0 -237
  125. package/.genie/scripts/helpers/count-tokens.js +0 -200
  126. package/.genie/scripts/helpers/create-frontmatter.js +0 -456
  127. package/.genie/scripts/helpers/detect-markers.js +0 -293
  128. package/.genie/scripts/helpers/detect-todos.js +0 -267
  129. package/.genie/scripts/helpers/detect-unlabeled-blocks.js +0 -135
  130. package/.genie/scripts/helpers/embeddings.js +0 -344
  131. package/.genie/scripts/helpers/find-empty-sections.js +0 -158
  132. package/.genie/scripts/helpers/index.js +0 -319
  133. package/.genie/scripts/helpers/validate-frontmatter.js +0 -578
  134. package/.genie/scripts/helpers/validate-links.js +0 -207
  135. package/.genie/scripts/helpers/validate-paths.js +0 -373
  136. package/.genie/spells/README.md +0 -9
  137. package/.genie/spells/ace-protocol.md +0 -118
  138. package/.genie/spells/ask-one-at-a-time.md +0 -175
  139. package/.genie/spells/backup-analyzer.md +0 -542
  140. package/.genie/spells/blocker.md +0 -12
  141. package/.genie/spells/break-things-move-fast.md +0 -56
  142. package/.genie/spells/context-candidates.md +0 -72
  143. package/.genie/spells/context-critic.md +0 -51
  144. package/.genie/spells/defer-to-expertise.md +0 -278
  145. package/.genie/spells/delegate-dont-do.md +0 -292
  146. package/.genie/spells/error-investigation-protocol.md +0 -328
  147. package/.genie/spells/evidence-based-completion.md +0 -273
  148. package/.genie/spells/experiment.md +0 -65
  149. package/.genie/spells/file-creation-protocol.md +0 -229
  150. package/.genie/spells/forge-integration.md +0 -281
  151. package/.genie/spells/forge-orchestration.md +0 -514
  152. package/.genie/spells/gather-context.md +0 -18
  153. package/.genie/spells/global-health-check.md +0 -34
  154. package/.genie/spells/global-noop-roundtrip.md +0 -25
  155. package/.genie/spells/install-genie.md +0 -1232
  156. package/.genie/spells/install.md +0 -82
  157. package/.genie/spells/investigate-before-commit.md +0 -112
  158. package/.genie/spells/know-yourself.md +0 -288
  159. package/.genie/spells/learn.md +0 -828
  160. package/.genie/spells/mcp-diagnostic-protocol.md +0 -246
  161. package/.genie/spells/mcp-first.md +0 -124
  162. package/.genie/spells/multi-step-execution.md +0 -67
  163. package/.genie/spells/orchestration-boundary-protocol.md +0 -256
  164. package/.genie/spells/orchestrator-not-implementor.md +0 -189
  165. package/.genie/spells/prompt.md +0 -746
  166. package/.genie/spells/reflect.md +0 -404
  167. package/.genie/spells/routing-decision-matrix.md +0 -368
  168. package/.genie/spells/run-in-parallel.md +0 -12
  169. package/.genie/spells/session-state-updater-example.md +0 -196
  170. package/.genie/spells/session-state-updater.md +0 -220
  171. package/.genie/spells/track-long-running-tasks.md +0 -133
  172. package/.genie/spells/troubleshoot-infrastructure.md +0 -176
  173. package/.genie/spells/upgrade-genie.md +0 -415
  174. package/.genie/spells/url-presentation-protocol.md +0 -301
  175. package/.genie/spells/wish-initiation.md +0 -158
  176. package/.genie/spells/wish-issue-linkage.md +0 -410
  177. package/.genie/spells/wish-lifecycle.md +0 -100
  178. package/.genie/state/provider-status.json +0 -3
  179. package/.genie/state/version.json +0 -16
  180. package/.genie/wishes/canonical-pgserve-pm2-supervision/WISH.md +0 -290
  181. package/.genie/wishes/pgserve-v2/BRIEF-from-genie-pgserve.md +0 -99
  182. package/.genie/wishes/pgserve-v2/WISH.md +0 -442
  183. package/.genie/wishes/release-system-genie-pattern/WISH.md +0 -268
  184. package/.genie/wishes/release-system-genie-pattern/validation.md +0 -205
  185. package/.gitguardian.yaml +0 -29
  186. package/.gitguardianignore +0 -16
  187. package/.github/workflows/ci.yml +0 -122
  188. package/.github/workflows/release.yml +0 -289
  189. package/.github/workflows/version.yml +0 -228
  190. package/.husky/pre-commit +0 -2
  191. package/AGENTS.md +0 -433
  192. package/CLAUDE.md +0 -1
  193. package/Makefile +0 -285
  194. package/assets/icon.ico +0 -0
  195. package/bun.lock +0 -435
  196. package/bunfig.toml +0 -28
  197. package/ecosystem.config.cjs +0 -23
  198. package/eslint.config.js +0 -63
  199. package/examples/multi-tenant-demo.js +0 -104
  200. package/install.sh +0 -123
  201. package/knip.json +0 -9
  202. package/scripts/test-bun-self-heal.sh +0 -163
  203. package/scripts/test-npx.sh +0 -60
  204. package/tests/audit.test.js +0 -189
  205. package/tests/backpressure.test.js +0 -167
  206. package/tests/benchmarks/runner.js +0 -1197
  207. package/tests/benchmarks/vector-generator.js +0 -368
  208. package/tests/cli-install.test.js +0 -322
  209. package/tests/control-db.test.js +0 -285
  210. package/tests/daemon-control.test.js +0 -171
  211. package/tests/daemon-fingerprint-integration.test.js +0 -111
  212. package/tests/daemon-pr24-regression.test.js +0 -198
  213. package/tests/fingerprint.test.js +0 -263
  214. package/tests/fixtures/240-orphan-seed.sql +0 -30
  215. package/tests/multi-tenant.test.js +0 -374
  216. package/tests/orphan-cleanup.test.js +0 -390
  217. package/tests/pg-version-regex.test.js +0 -129
  218. package/tests/quick-bench.js +0 -135
  219. package/tests/router-handshake-retry.test.js +0 -119
  220. package/tests/router-handshake-watchdog.test.js +0 -110
  221. package/tests/sdk.test.js +0 -71
  222. package/tests/stale-postmaster-pid.test.js +0 -85
  223. package/tests/stress-test.js +0 -439
  224. package/tests/sync-perf-test.js +0 -150
  225. package/tests/tcp-listen.test.js +0 -368
  226. package/tests/tenancy.test.js +0 -403
  227. 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.