// Agent profile admission: the parent-side decision of whether a Fresh // request satisfies the built-in subagent type rules. A Direct self-spawn is // rejected; tool presentation remains outside this module. See CONTEXT.md // "Agent profile admission". import { BUILTIN_SUBAGENT_TYPES } from "./launch-policy.ts"; /** Decision for a spawn request against the Direct self-spawn rule. */ export type SelfSpawnDecision = | { allowed: true } | { blocked: true; hasAlternative: boolean }; export interface AgentProfileAdmission { classifySelfSpawn(currentAgent: string, requestedAgent: string): SelfSpawnDecision; } export function createAgentProfileAdmission(): AgentProfileAdmission { return { classifySelfSpawn(currentAgent: string, requestedAgent: string): SelfSpawnDecision { // Only a non-empty, matching request is a Direct self-spawn. Anything // else — including an unset parent or child identity — is allowed and // left to ordinary launch validation. const current = currentAgent.trim(); const requested = requestedAgent.trim(); if (!current || !requested || requested !== current) { return { allowed: true }; } // With a fixed catalog there is always exactly one other type; an // unknown current identity also leaves both types available. const hasAlternative = BUILTIN_SUBAGENT_TYPES.some((type) => type.name !== current); return { blocked: true, hasAlternative }; }, }; }