tell an existing commander how to reach its owner

the voice-memos commander was asked for a notification and reached for its
harness's own push tool — a different channel, which refuses to interrupt a
live terminal. it did that because nothing had told it Officer has a route
of its own. that rule is the harness's; the platform's route has none, and
had already pushed to a phone twice with the owner sitting at the terminal.

so the notify part is its own section now, appendable on its own, and the
backfill lands it on a commander that already has a credential — which is
every commander that predates this, i.e. the ones that need it.

the backfill also stopped being all-or-nothing. it skipped everything after
the credential check, so a commander with an officer.env could never
receive anything added later. each section is now appended independently,
keyed on a marker the section itself contains.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Officer-Session: 656f5c85-e49a-4f1f-b9f3-042a04b4d043
This commit is contained in:
2026-08-24 15:31:37 +00:00
co-authored by Claude Opus 5
parent 2d5e9835f5
commit 40a03d987f
2 changed files with 48 additions and 17 deletions
+33 -17
View File
@@ -21,7 +21,7 @@ import { readFileSync, existsSync, appendFileSync, chmodSync } from 'node:fs';
import { join } from 'node:path';
import { getUsers, listCommandHqSessions } from 'officerdb';
import { writeCommanderCredential, commanderEnvPath } from '../src/servers/api/command-hq/credential';
import { credentialSection } from '../src/servers/api/command-hq/directory';
import { credentialSection, notifySection } from '../src/servers/api/command-hq/directory';
import { getCommanderDir } from '../src/servers/data-path';
import { lookupOsUser } from '../src/servers/os-user';
@@ -64,26 +64,42 @@ for (const row of rows) {
continue;
}
const envPath = commanderEnvPath(row.email, row.dirName);
if (existsSync(envPath)) {
console.log(`ok ${label} — already has a credential`);
continue;
}
const { path } = await writeCommanderCredential({ userId: row.userId, email: row.email, dirName: row.dirName });
chmodSync(path, 0o600);
await giveToAccount(row.osUser, path);
// Appended only when it is not already described. A commander whose CLAUDE.md was hand-edited to
// mention its credential must not end up with the section twice.
const claudeMd = join(dir, 'CLAUDE.md');
const existing = existsSync(claudeMd) ? readFileSync(claudeMd, 'utf8') : '';
if (!existing.includes('officer.env')) {
appendFileSync(claudeMd, `\n${credentialSection(path).join('\n')}`);
/**
* Append a section only when it is not already described.
*
* The marker is a string the section itself contains, so a commander whose CLAUDE.md was hand-edited to
* describe the same thing does not end up with it twice.
*/
const appendIfMissing = async (marker: string, lines: string[]): Promise<boolean> => {
const existing = existsSync(claudeMd) ? readFileSync(claudeMd, 'utf8') : '';
if (existing.includes(marker)) return false;
appendFileSync(claudeMd, `\n${lines.join('\n')}`);
await giveToAccount(row.osUser, claudeMd);
return true;
};
const envPath = commanderEnvPath(row.email, row.dirName);
if (!existsSync(envPath)) {
const { path } = await writeCommanderCredential({ userId: row.userId, email: row.email, dirName: row.dirName });
chmodSync(path, 0o600);
await giveToAccount(row.osUser, path);
await appendIfMissing('officer.env', credentialSection(path));
console.log(`MINT ${label} — ${path}`);
} else {
console.log(`ok ${label} — already has a credential`);
}
console.log(`MINT ${label} — ${path}`);
/*
Separately, because it arrived later and the commanders that need it most already have a credential.
Without it a commander does not know Officer HAS a notification route, so it reaches for whatever its
harness offers — a different channel, with its own rules about when it may interrupt.
*/
if (await appendIfMissing('/api/notify/_officer/notify', notifySection())) {
console.log(`NOTIFY ${label} — told how to reach the owner`);
}
}
process.exit(0);