From 4e0a065f0e26a8a11c12961026e5759abec1ae4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Fri, 28 Aug 2026 23:02:52 +0100 Subject: [PATCH] a host can drop a core sidecar it does not use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `OFFICER_DISABLED_SIDECARS` in .env, comma separated, filtered out of the generated ecosystem file. core processes are a fixed array because the platform's own features depend on them. that is still true — what is not true is that every host runs every feature. fofos is a 1.9 GB machine serving a website, and officer-opencode sat on it costing 456 MB for a harness nobody there uses. it froze hard twice today, and the tell is what is MISSING from the journal: no OOM kill, no panic, no shutdown — the log simply stops mid-session and resumes at the manual reboot. that is memory exhaustion with no headroom left to kill anything cleanly, on a box with 1.9 GB and a 2 GB swapfile that was already 440 MB into swap one minute after boot. .env rather than a database setting, and that is the load-bearing part: this file is regenerated during a plugin install, so a host that dropped a process needs it to stay dropped across one. per-host is also exactly the scope of the decision. not validated. naming `officer` or `officer-pty` will break that host, and which processes are safe to drop depends on what the host is for — which this script cannot know and should not guess. Co-Authored-By: Claude Opus 5 Officer-Session: 656f5c85-e49a-4f1f-b9f3-042a04b4d043 --- scripts/gen-ecosystem.ts | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/scripts/gen-ecosystem.ts b/scripts/gen-ecosystem.ts index 03beb2cd..dee2eeab 100644 --- a/scripts/gen-ecosystem.ts +++ b/scripts/gen-ecosystem.ts @@ -60,9 +60,34 @@ function coreProcesses(): Pm2App[] { const [name, script, args] = line.split('|'); if (!name || !script) return fail(`unreadable CORE_PROCESSES entry: "${line}"`); return { name, script, args, cwd: PLATFORM_DIR, watch: false }; - }); + }) + .filter((app) => !DISABLED.has(app.name)); } +/* + Core processes this host does not want, from `OFFICER_DISABLED_SIDECARS` in `.env`. + + A core process is core because the platform's own features depend on it — which is why the list is a + fixed array and not a setting. But "the platform depends on it" is not "every host runs it": fofos is a + 1.9 GB machine serving a website, and `officer-opencode` sat there costing 456 MB of that for a harness + nobody on it uses. It froze hard twice, with no OOM line in the journal — which is what memory + exhaustion looks like when there is not enough headroom left to kill something cleanly. + + Deliberately NOT a database setting. This file is regenerated during a plugin install, so a host that + has dropped a process needs it to stay dropped across one. `.env` is read at generation time and is + per-host, which is exactly the scope of the decision. + + Naming something the platform genuinely needs will break that host — `officer` itself, or + `officer-pty` if anyone uses a terminal. Not validated, because which processes are safe to drop + depends on what the host is for, and this script cannot know that. +*/ +const DISABLED = new Set( + (process.env.OFFICER_DISABLED_SIDECARS ?? '') + .split(',') + .map((entry) => entry.trim()) + .filter(Boolean), +); + /** Installed AND enabled AND actually ships a sidecar — all three, or it gets no entry. */ async function pluginEntries(): Promise { const [installs, { plugins }] = await Promise.all([listPluginInstalls(), discoverPlugins()]);