refactor: drop legacy env alias reads

This commit is contained in:
ejclaw
2026-04-10 21:37:20 +09:00
parent 644b38f2f6
commit 312d19c0d1
4 changed files with 61 additions and 66 deletions

View File

@@ -225,24 +225,11 @@ describe('DiscordChannel', () => {
}); });
describe('channel registration', () => { describe('channel registration', () => {
it('warns when only legacy owner token names are configured', () => { it('warns when the canonical owner token is not configured', () => {
const ownerFactory = registeredChannelFactories.get('discord'); const ownerFactory = registeredChannelFactories.get('discord');
vi.mocked(getEnv).mockImplementation((key: string) => {
if (key === 'DISCORD_BOT_TOKEN') return 'legacy-owner-token';
return undefined;
});
expect(ownerFactory).toBeTypeOf('function'); expect(ownerFactory).toBeTypeOf('function');
expect(ownerFactory?.(createTestOpts() as any)).toBeNull(); expect(ownerFactory?.(createTestOpts() as any)).toBeNull();
expect(logger.warn).toHaveBeenCalledWith(
{
role: 'owner',
canonicalKey: 'DISCORD_OWNER_BOT_TOKEN',
legacyKeys: ['DISCORD_BOT_TOKEN'],
},
'Discord: legacy bot token names detected; rename them to canonical role-based names',
);
expect(logger.warn).toHaveBeenCalledWith( expect(logger.warn).toHaveBeenCalledWith(
'Discord: DISCORD_OWNER_BOT_TOKEN not set', 'Discord: DISCORD_OWNER_BOT_TOKEN not set',
); );

View File

@@ -30,38 +30,6 @@ const DISCORD_ARBITER_CHANNEL = 'discord-arbiter';
const DISCORD_OWNER_TOKEN_KEY = 'DISCORD_OWNER_BOT_TOKEN'; const DISCORD_OWNER_TOKEN_KEY = 'DISCORD_OWNER_BOT_TOKEN';
const DISCORD_REVIEWER_TOKEN_KEY = 'DISCORD_REVIEWER_BOT_TOKEN'; const DISCORD_REVIEWER_TOKEN_KEY = 'DISCORD_REVIEWER_BOT_TOKEN';
const DISCORD_ARBITER_TOKEN_KEY = 'DISCORD_ARBITER_BOT_TOKEN'; const DISCORD_ARBITER_TOKEN_KEY = 'DISCORD_ARBITER_BOT_TOKEN';
const DISCORD_OWNER_LEGACY_TOKEN_KEYS = [
'DISCORD_BOT_TOKEN',
'DISCORD_CLAUDE_BOT_TOKEN',
];
const DISCORD_REVIEWER_LEGACY_TOKEN_KEYS = [
'DISCORD_CODEX_BOT_TOKEN',
'DISCORD_CODEX_MAIN_BOT_TOKEN',
];
const DISCORD_ARBITER_LEGACY_TOKEN_KEYS = [
'DISCORD_REVIEW_BOT_TOKEN',
'DISCORD_CODEX_REVIEW_BOT_TOKEN',
];
function warnIfLegacyDiscordTokenConfigured(
canonicalKey: string,
legacyKeys: string[],
role: 'owner' | 'reviewer' | 'arbiter',
): void {
if (getEnv(canonicalKey)) return;
const configuredLegacyKeys = legacyKeys.filter((key) => !!getEnv(key));
if (configuredLegacyKeys.length === 0) return;
logger.warn(
{
role,
canonicalKey,
legacyKeys: configuredLegacyKeys,
},
'Discord: legacy bot token names detected; rename them to canonical role-based names',
);
}
/** /**
* Download a Discord attachment to local disk. * Download a Discord attachment to local disk.
@@ -835,11 +803,6 @@ export class DiscordChannel implements Channel {
} }
registerChannel(DISCORD_OWNER_CHANNEL, (opts: ChannelOpts) => { registerChannel(DISCORD_OWNER_CHANNEL, (opts: ChannelOpts) => {
warnIfLegacyDiscordTokenConfigured(
DISCORD_OWNER_TOKEN_KEY,
DISCORD_OWNER_LEGACY_TOKEN_KEYS,
'owner',
);
const token = getEnv(DISCORD_OWNER_TOKEN_KEY) || ''; const token = getEnv(DISCORD_OWNER_TOKEN_KEY) || '';
if (!token) { if (!token) {
logger.warn('Discord: DISCORD_OWNER_BOT_TOKEN not set'); logger.warn('Discord: DISCORD_OWNER_BOT_TOKEN not set');
@@ -849,11 +812,6 @@ registerChannel(DISCORD_OWNER_CHANNEL, (opts: ChannelOpts) => {
}); });
registerChannel(DISCORD_REVIEWER_CHANNEL, (opts: ChannelOpts) => { registerChannel(DISCORD_REVIEWER_CHANNEL, (opts: ChannelOpts) => {
warnIfLegacyDiscordTokenConfigured(
DISCORD_REVIEWER_TOKEN_KEY,
DISCORD_REVIEWER_LEGACY_TOKEN_KEYS,
'reviewer',
);
const ownerToken = getEnv(DISCORD_OWNER_TOKEN_KEY) || ''; const ownerToken = getEnv(DISCORD_OWNER_TOKEN_KEY) || '';
const token = getEnv(DISCORD_REVIEWER_TOKEN_KEY) || ''; const token = getEnv(DISCORD_REVIEWER_TOKEN_KEY) || '';
if (!token) return null; if (!token) return null;
@@ -874,11 +832,6 @@ registerChannel(DISCORD_REVIEWER_CHANNEL, (opts: ChannelOpts) => {
}); });
registerChannel(DISCORD_ARBITER_CHANNEL, (opts: ChannelOpts) => { registerChannel(DISCORD_ARBITER_CHANNEL, (opts: ChannelOpts) => {
warnIfLegacyDiscordTokenConfigured(
DISCORD_ARBITER_TOKEN_KEY,
DISCORD_ARBITER_LEGACY_TOKEN_KEYS,
'arbiter',
);
const ownerToken = getEnv(DISCORD_OWNER_TOKEN_KEY) || ''; const ownerToken = getEnv(DISCORD_OWNER_TOKEN_KEY) || '';
const reviewerToken = getEnv(DISCORD_REVIEWER_TOKEN_KEY) || ''; const reviewerToken = getEnv(DISCORD_REVIEWER_TOKEN_KEY) || '';
const token = getEnv(DISCORD_ARBITER_TOKEN_KEY) || ''; const token = getEnv(DISCORD_ARBITER_TOKEN_KEY) || '';

View File

@@ -23,6 +23,13 @@ describe('config/env loading', () => {
delete process.env.CODEX_MODEL; delete process.env.CODEX_MODEL;
delete process.env.STATUS_CHANNEL_ID; delete process.env.STATUS_CHANNEL_ID;
delete process.env.TZ; delete process.env.TZ;
delete process.env.DISCORD_BOT_TOKEN;
delete process.env.DISCORD_CLAUDE_BOT_TOKEN;
delete process.env.DISCORD_CODEX_BOT_TOKEN;
delete process.env.DISCORD_CODEX_MAIN_BOT_TOKEN;
delete process.env.DISCORD_REVIEW_BOT_TOKEN;
delete process.env.DISCORD_CODEX_REVIEW_BOT_TOKEN;
delete process.env.SESSION_COMMAND_USER_IDS;
vi.resetModules(); vi.resetModules();
}); });
@@ -94,4 +101,24 @@ describe('config/env loading', () => {
expect(config.STATUS_CHANNEL_ID).toBe('status-room'); expect(config.STATUS_CHANNEL_ID).toBe('status-room');
expect(config.TIMEZONE).toBe('UTC'); expect(config.TIMEZONE).toBe('UTC');
}); });
it('fails fast when a legacy Discord token alias is configured', async () => {
process.env.DISCORD_BOT_TOKEN = 'legacy-owner-token';
const { loadConfig } = await import('./config/load-config.js');
expect(() => loadConfig()).toThrow(
/Legacy env aliases are no longer supported; rename them to canonical keys \(DISCORD_BOT_TOKEN -> DISCORD_OWNER_BOT_TOKEN\)/,
);
});
it('fails fast when SESSION_COMMAND_USER_IDS is configured', async () => {
process.env.SESSION_COMMAND_USER_IDS = 'alice,bob';
const { loadConfig } = await import('./config/load-config.js');
expect(() => loadConfig()).toThrow(
/Legacy env aliases are no longer supported; rename them to canonical keys \(SESSION_COMMAND_USER_IDS -> SESSION_COMMAND_ALLOWED_SENDERS\)/,
);
});
}); });

View File

@@ -7,6 +7,16 @@ import { getEnv } from '../env.js';
import type { AppConfig, RoleModelConfig } from './schema.js'; import type { AppConfig, RoleModelConfig } from './schema.js';
const LEGACY_ENV_ALIAS_MAP = {
DISCORD_BOT_TOKEN: 'DISCORD_OWNER_BOT_TOKEN',
DISCORD_CLAUDE_BOT_TOKEN: 'DISCORD_OWNER_BOT_TOKEN',
DISCORD_CODEX_BOT_TOKEN: 'DISCORD_REVIEWER_BOT_TOKEN',
DISCORD_CODEX_MAIN_BOT_TOKEN: 'DISCORD_REVIEWER_BOT_TOKEN',
DISCORD_REVIEW_BOT_TOKEN: 'DISCORD_ARBITER_BOT_TOKEN',
DISCORD_CODEX_REVIEW_BOT_TOKEN: 'DISCORD_ARBITER_BOT_TOKEN',
SESSION_COMMAND_USER_IDS: 'SESSION_COMMAND_ALLOWED_SENDERS',
} as const;
function readText(key: string): string | undefined { function readText(key: string): string | undefined {
return getEnv(key); return getEnv(key);
} }
@@ -100,7 +110,29 @@ function normalizeServiceId(
return serviceId === 'codex' ? codexMainServiceId : serviceId; return serviceId === 'codex' ? codexMainServiceId : serviceId;
} }
function assertNoLegacyEnvAliasesConfigured(): void {
const configuredAliases = Object.entries(LEGACY_ENV_ALIAS_MAP).filter(
([legacyKey]) => {
const value = getEnv(legacyKey);
return value != null && value !== '';
},
);
if (configuredAliases.length === 0) {
return;
}
const aliasList = configuredAliases
.map(([legacyKey, canonicalKey]) => `${legacyKey} -> ${canonicalKey}`)
.join(', ');
throw new Error(
`Legacy env aliases are no longer supported; rename them to canonical keys (${aliasList})`,
);
}
export function loadConfig(): AppConfig { export function loadConfig(): AppConfig {
assertNoLegacyEnvAliasesConfigured();
const assistantName = readText('ASSISTANT_NAME') ?? 'Andy'; const assistantName = readText('ASSISTANT_NAME') ?? 'Andy';
const assistantSlug = assistantName.trim().toLowerCase(); const assistantSlug = assistantName.trim().toLowerCase();
@@ -217,11 +249,7 @@ export function loadConfig(): AppConfig {
}, },
sessionCommands: { sessionCommands: {
allowedSenders: new Set( allowedSenders: new Set(
( (readText('SESSION_COMMAND_ALLOWED_SENDERS') ?? '')
readText('SESSION_COMMAND_ALLOWED_SENDERS') ??
readText('SESSION_COMMAND_USER_IDS') ??
''
)
.split(',') .split(',')
.map((value) => value.trim()) .map((value) => value.trim())
.filter(Boolean), .filter(Boolean),