Files
platform/todo/infra/opm-officer-s-own-process-manager.md
T

3.5 KiB

id, title, theme, status, created, date_source, order
id title theme status created date_source order
infra/opm-officer-s-own-process-manager OPM — Officer's own process manager, or at least its own PM2 infra open 2026-08-21 stated 0

OPM — Officer's own process manager, or at least its own PM2. Raised 2026-08-21. Taken as: give Officer's processes a manager of their own, named OPM, rather than sharing one daemon with whatever else lives on the host — worth doing for separation of concerns alone, even without any new capability.

The argument is that Officer is now a fleet of processes, not a process. pm2 jlist counts 13 officer entries on officer-dev and 19 on alpha (verified 2026-08-21), and every one of them is a peer of the server rather than a child of it. They are managed today by a generated ecosystem.config.cjs (bun run gen:ecosystem) on a PM2 daemon that belongs to the login user, not to Officer.

What sharing costs, all of it already written down in CLAUDE.md: pm2 restart ecosystem.config.cjs bounces every sidecar including the vault, so the safe habit is --only <name> and the unsafe one looks identical; a pm2 list mixes Officer's processes with other projects' and the rule "nothing here should touch them" is a convention rather than a boundary; and the documented list of entries goes stale every time a sidecar lands, because nothing owns it. Note the foreign-process case is host-dependent — mybiblepal-api and mybiblepal-audio are named in CLAUDE.md as sharing this daemon, and neither is running on officer-dev or alpha today.

Open, and the owner's call: whether OPM is a genuinely new supervisor or PM2 kept underneath with its own daemon, namespace and CLI wrapper — which would buy the separation at a fraction of the cost, since the ecosystem.config.cjs generation, the naming convention and the restart discipline all already exist.


Decided 2026-08-25: it is happening, and it answers the open question above. OPM is a genuinely new supervisor, not PM2-with-a-wrapper — because the next requirement needs something PM2 was never built for: OPM should sit ON the Docker network, so a container-backed dependency never needs a published host port at all.

Verified on this host what that would remove. docker network ls shows dedicated bridge networks already in place (officerdev, services, nginx) — the grouping this asks for exists, containers are just not reached through it. What IS published today, purely so a host process can reach a container, is the thing this closes: officer-postgres is 127.0.0.1:5432->5432, gitea is 127.0.0.1:9004->3000 and 127.0.0.1:10023->22. Every one of those bindings exists for exactly one reason — a process on the host, not in Docker, needs to reach the container — and every one is a port that answers on localhost to anything else running as the same user, not only to Officer.

If OPM itself runs attached to the Docker network (or as a container on it), it reaches officer-postgres:5432 and gitea:3000 by container name, over the network Docker already isolates, and the host-published bindings above stop being necessary for Officer's own processes to work. Whether they can be removed entirely depends on who ELSE reaches them this way — POSTGRES_URL and any migration/backup tooling run from a plain shell would need to move onto the network too, or keep a narrower published port for that one purpose. That accounting is the first real task once this starts, not an assumption to build on.