/**
 * @internal
 * config/guard.mjs — gate .aperant/config.json writes behind a whitelist (R13).
 *
 * Today the only callers that legitimately write config.json are `init`
 * (fresh install) and `setup` (`/apt:setup` customization). Every other
 * subsystem reads config.json. Installing the rail now lets us catch it the
 * moment a new code path tries to mutate config without registering as a
 * sanctioned writer — the duplicate-edit race observed alongside the C29
 * leak (worktree and main repo both flipping worktree_per_task concurrently)
 * is exactly the failure mode this guard blocks.
 *
 * The APT_CONFIG_WRITER_OVERRIDE env var lets tests drive the guard without
 * taking on the whitelist surface. It is NOT documented in the CLI help.
 */

/** @internal */
export const ALLOWED_CONFIG_WRITERS = new Set(['init', 'setup'])

/**
 * Throw if `callerId` is not an approved config writer. Accepts the env
 * override for test harnesses that need to exercise the write path without
 * impersonating one of the sanctioned callers.
 *
 * @internal
 */
export function assertConfigWriteAllowed(callerId) {
	const override = process.env.APT_CONFIG_WRITER_OVERRIDE
	if (override && override === callerId) return
	if (override && override === '*') return
	if (!ALLOWED_CONFIG_WRITERS.has(callerId)) {
		const err = new Error(
			`config-write-forbidden: '${callerId}' is not an approved writer for .aperant/config.json. Allowed: ${[...ALLOWED_CONFIG_WRITERS].join(', ')}`,
		)
		err.code = 'config-write-forbidden'
		err.caller = callerId
		throw err
	}
}
