feat(register): auto hot-reload service after channel register/deregister

Making a channel registration live no longer depends on an operator/agent
remembering to restart. setup/register.ts and scripts/deregister-room.ts now
call signalEjclawReload() after the DB write, which sends SIGHUP to the running
service's main PID (→ runtimeState.reloadRoomBindings). Best-effort and
injectable-for-tests; no-ops when the service isn't running.

Also document the canonical rule in the committed, agent-loaded platform prompt
(prompts/claude-platform.md): prefer these paths, never fake a restart, verify
via the "Room bindings reloaded" log; a plain in-turn systemctl restart is
forbidden (it kills the agent).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Codex
2026-08-23 19:50:24 +09:00
parent 9020d2c8c5
commit f74536a8b2
5 changed files with 137 additions and 2 deletions

View File

@@ -11,6 +11,7 @@ import { assignRoom, initDatabase } from '../src/db.js';
import { isValidGroupFolder } from '../src/group-folder.js';
import { ensurePairedWorkspaceProvisioned } from '../src/paired-workspace-manager.js';
import { logger } from '../src/logger.js';
import { signalEjclawReload } from '../src/runtime-reload-signal.js';
import { emitStatus } from './status.js';
interface RegisterArgs {
@@ -133,12 +134,17 @@ export async function run(args: string[]): Promise<void> {
});
logger.info({ folder: parsed.folder }, 'Ensured group log directory exists');
// Make the registration live immediately: signal the running service to
// hot-reload its room bindings (no full restart, no operator follow-up).
const reloaded = signalEjclawReload();
emitStatus('REGISTER_CHANNEL', {
JID: parsed.jid,
NAME: parsed.name,
FOLDER: parsed.folder,
CHANNEL: parsed.channel,
STATUS: 'success',
RELOADED: reloaded ? 'yes' : 'no',
LOG: 'logs/setup.log',
});
}