{"version":3,"file":"subagent-registry.d.ts","sourceRoot":"","sources":["../../src/core/subagent-registry.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Canonical subagent registry and policy boundary.\n *\n * Agent Markdown files are user-facing configuration. They are not the\n * authority for role, model, tools, effects, budgets, or output contracts.\n * The registry is rebuilt from immutable definitions on every load; callers\n * may cache diagnostics, but a cache can never create authority.\n */\n\nexport const ANALYTICAL_PROVIDER = \"openrouter\" as const;\nexport const ANALYTICAL_MODEL = \"deepseek/deepseek-v4-flash-latest\" as const;\nexport const WORKER_PROVIDER = \"openrouter\" as const;\nexport const WORKER_MODEL = \"openai/gpt-5.6-luna\" as const;\n\nexport type SubagentRole =\n\t| \"exploration\"\n\t| \"investigation\"\n\t| \"planning\"\n\t| \"implementation\"\n\t| \"review\"\n\t| \"security\"\n\t| \"research\"\n\t| \"testing\";\nexport type SubagentExecutionMode = \"observe\" | \"plan\" | \"execute\";\nexport type ModelResolutionPolicy = \"strict\" | \"configured_fallback\";\n\nexport interface SubagentBudget {\n\tmaxModelTurns?: number;\n\tmaxToolCalls?: number;\n\tmaxWallTimeMs?: number;\n\tmaxInputTokens?: number;\n\tmaxOutputTokens?: number;\n\tmaxCostUsd?: number;\n\tmaxAffectedFiles?: number;\n}\n\nexport interface SubagentDefinition {\n\tname: string;\n\taliases: string[];\n\tversion: number;\n\tdescription: string;\n\trole: SubagentRole;\n\tprovider: string;\n\tmodel: string;\n\tmodelResolutionPolicy: ModelResolutionPolicy;\n\texecutionMode: SubagentExecutionMode;\n\tallowedTools: string[];\n\tdeniedTools: string[];\n\tdeniedEffects: string[];\n\trequiredCapabilities: string[];\n\tbudget: SubagentBudget;\n\tconcurrency: { parallelSafe: boolean; maximumInstances: number };\n\trecursion: { maySpawnSubagents: boolean; maximumDepth: number };\n\tinputSchema: string;\n\toutputSchema: string;\n\tfallbackAgents: string[];\n\tresultCompression?: { enabled: boolean; maximumCharacters?: number };\n\t/** Workspace retrieval policy (1.7.0). */\n\tretrieval?: SubagentRetrievalPolicy;\n}\n\n/**\n * Retrieval permissions and budget for a subagent. Child permission is always\n * the intersection of parent authorization, policy, agent, skill and retrieval\n * policy; retrieval can never expand workspace scope.\n */\nexport interface SubagentRetrievalPolicy {\n\tallowed: boolean;\n\tmode: \"lexical\" | \"hybrid\" | \"semantic\";\n\tmaxResults: number;\n\tmaxContextTokens: number;\n\trevalidateBeforeMutation: boolean;\n}\n\nexport const DEFAULT_RETRIEVAL_POLICY: SubagentRetrievalPolicy = {\n\tallowed: false,\n\tmode: \"hybrid\",\n\tmaxResults: 20,\n\tmaxContextTokens: 2048,\n\trevalidateBeforeMutation: false,\n};\n\n/** Resolve the retrieval policy declared by a built-in subagent, if any. */\nexport function subagentRetrievalPolicy(name: string): SubagentRetrievalPolicy | undefined {\n\tconst def = BUILTIN_SUBAGENT_DEFINITIONS.find((d) => d.name === name || d.aliases.includes(name));\n\treturn def?.retrieval;\n}\n\nexport interface SubagentModelResolution {\n\tagent: string;\n\tconfiguredProvider: string;\n\tconfiguredModel: string;\n\tresolvedProvider: string;\n\tresolvedModel: string;\n\tresolutionKind: \"exact\" | \"provider_alias\" | \"configured_fallback\";\n\treasonCode: string;\n\trecordedAt: string;\n}\n\nexport type SubagentResolutionErrorCode =\n\t| \"SUBAGENT_NOT_REGISTERED\"\n\t| \"SUBAGENT_ALIAS_AMBIGUOUS\"\n\t| \"SUBAGENT_DISABLED\"\n\t| \"SUBAGENT_MODEL_UNAVAILABLE\"\n\t| \"SUBAGENT_PERMISSION_CONFLICT\"\n\t| \"SUBAGENT_OUTPUT_SCHEMA_INVALID\";\n\nexport interface SubagentResolutionError {\n\tcode: SubagentResolutionErrorCode;\n\trequestedAgent: string;\n\treferencingSkill?: string;\n\tavailableAgents: string[];\n\tcompatibleAgents?: string[];\n\tautomaticFallbackAttempted: false;\n}\n\nexport interface RegistryDiagnostic {\n\tcode: string;\n\tmessage: string;\n\tagent?: string;\n\tpath?: string;\n}\n\nexport interface SkillDependencyDiagnostic {\n\tcode: \"SKILL_DEPENDENCY_INVALID\";\n\tskillName: string;\n\tskillSource: string;\n\tmissingAgent?: string;\n\tinvalidFallback?: string;\n\tinvalidModel?: string;\n\tpermissionConflict?: string;\n\tschemaError?: string;\n\trecommendedRemediation: string;\n}\n\nexport interface ResolvedSubagent {\n\tdefinition: SubagentDefinition;\n\tmodel: SubagentModelResolution;\n}\n\nconst OBSERVE_TOOLS = [\n\t\"read\",\n\t\"grep\",\n\t\"find\",\n\t\"ls\",\n\t\"bash\",\n\t\"workspace_search\",\n\t\"workspace_search_lexical\",\n\t\"workspace_search_symbols\",\n\t\"workspace_retrieval_status\",\n\t\"workspace_search_semantic\",\n];\nconst BUILDER_TOOLS = [\n\t\"read\",\n\t\"grep\",\n\t\"find\",\n\t\"ls\",\n\t\"edit\",\n\t\"write\",\n\t\"bash\",\n\t\"workspace_search\",\n\t\"workspace_search_lexical\",\n\t\"workspace_search_symbols\",\n];\nconst WORKER_TOOLS = [\n\t\"read\",\n\t\"grep\",\n\t\"find\",\n\t\"ls\",\n\t\"edit\",\n\t\"write\",\n\t\"bash\",\n\t\"powershell\",\n\t\"workspace_search\",\n\t\"workspace_search_lexical\",\n\t\"workspace_search_symbols\",\n];\nconst OBSERVE_EFFECTS = [\"writesWorkspace\", \"mutatesGit\", \"publishes\", \"terminatesProcesses\", \"spawnsSubagents\"];\nconst PLAN_EFFECTS = [\"writesWorkspace\", \"mutatesGit\", \"publishes\", \"terminatesProcesses\", \"spawnsSubagents\"];\nconst EXECUTE_EFFECTS = [\"publishes\", \"mutatesReleaseTags\", \"merges\", \"spawnsSubagents\"];\n\nfunction analytical(\n\tname: string,\n\tdescription: string,\n\trole: SubagentRole,\n\toutputSchema: string,\n\toptions: Partial<SubagentDefinition> = {},\n): SubagentDefinition {\n\treturn {\n\t\tname,\n\t\taliases: [],\n\t\tversion: 1,\n\t\tdescription,\n\t\trole,\n\t\tprovider: ANALYTICAL_PROVIDER,\n\t\tmodel: ANALYTICAL_MODEL,\n\t\tmodelResolutionPolicy: \"strict\",\n\t\texecutionMode: \"observe\",\n\t\tallowedTools: OBSERVE_TOOLS,\n\t\tdeniedTools: [\"edit\", \"write\", \"publish\", \"merge\"],\n\t\tdeniedEffects: OBSERVE_EFFECTS,\n\t\trequiredCapabilities: [],\n\t\tbudget: { maxModelTurns: 8, maxToolCalls: 32, maxWallTimeMs: 120_000, maxOutputTokens: 4_000 },\n\t\tconcurrency: { parallelSafe: true, maximumInstances: 2 },\n\t\trecursion: { maySpawnSubagents: false, maximumDepth: 0 },\n\t\tinputSchema: \"subagent-context-packet-v1\",\n\t\toutputSchema,\n\t\tfallbackAgents: [],\n\t\tresultCompression: { enabled: true, maximumCharacters: 8_000 },\n\t\t...options,\n\t};\n}\n\nexport const BUILTIN_SUBAGENT_DEFINITIONS: readonly SubagentDefinition[] = [\n\tanalytical(\"librarian\", \"Find documented, historical, and release facts.\", \"research\", \"librarian-result-v1\", {\n\t\tretrieval: {\n\t\t\tallowed: true,\n\t\t\tmode: \"lexical\",\n\t\t\tmaxResults: 20,\n\t\t\tmaxContextTokens: 2048,\n\t\t\trevalidateBeforeMutation: false,\n\t\t},\n\t}),\n\tanalytical(\n\t\t\"pentester\",\n\t\t\"Run bounded authorized adversarial tests against existing defenses.\",\n\t\t\"testing\",\n\t\t\"pentest-result-v1\",\n\t\t{\n\t\t\tretrieval: {\n\t\t\t\tallowed: true,\n\t\t\t\tmode: \"hybrid\",\n\t\t\t\tmaxResults: 25,\n\t\t\t\tmaxContextTokens: 2048,\n\t\t\t\trevalidateBeforeMutation: false,\n\t\t\t},\n\t\t},\n\t),\n\tanalytical(\"planner\", \"Turn evidence into a bounded implementation plan.\", \"planning\", \"planner-result-v1\", {\n\t\texecutionMode: \"plan\",\n\t\tretrieval: {\n\t\t\tallowed: true,\n\t\t\tmode: \"hybrid\",\n\t\t\tmaxResults: 20,\n\t\t\tmaxContextTokens: 2048,\n\t\t\trevalidateBeforeMutation: false,\n\t\t},\n\t}),\n\tanalytical(\n\t\t\"reviewer\",\n\t\t\"Perform a broad read-only review against objective and acceptance criteria.\",\n\t\t\"review\",\n\t\t\"review-result-v1\",\n\t\t{\n\t\t\tretrieval: {\n\t\t\t\tallowed: true,\n\t\t\t\tmode: \"hybrid\",\n\t\t\t\tmaxResults: 25,\n\t\t\t\tmaxContextTokens: 2048,\n\t\t\t\trevalidateBeforeMutation: false,\n\t\t\t},\n\t\t},\n\t),\n\tanalytical(\n\t\t\"scout\",\n\t\t\"Perform fast, shallow repository orientation and locate probable symbols.\",\n\t\t\"exploration\",\n\t\t\"scout-result-v1\",\n\t\t{\n\t\t\tretrieval: {\n\t\t\t\tallowed: true,\n\t\t\t\tmode: \"lexical\",\n\t\t\t\tmaxResults: 15,\n\t\t\t\tmaxContextTokens: 1024,\n\t\t\t\trevalidateBeforeMutation: false,\n\t\t\t},\n\t\t},\n\t),\n\tanalytical(\n\t\t\"security\",\n\t\t\"Review trust boundaries, authorization, secrets, and unsafe defaults.\",\n\t\t\"security\",\n\t\t\"security-result-v1\",\n\t\t{\n\t\t\tretrieval: {\n\t\t\t\tallowed: true,\n\t\t\t\tmode: \"hybrid\",\n\t\t\t\tmaxResults: 25,\n\t\t\t\tmaxContextTokens: 2048,\n\t\t\t\trevalidateBeforeMutation: false,\n\t\t\t},\n\t\t},\n\t),\n\t{\n\t\tname: \"worker\",\n\t\taliases: [],\n\t\tversion: 1,\n\t\tdescription: \"Implement one authorized bounded task using policy, transactions, checkpoints, and validation.\",\n\t\trole: \"implementation\",\n\t\tprovider: WORKER_PROVIDER,\n\t\tmodel: WORKER_MODEL,\n\t\tmodelResolutionPolicy: \"strict\",\n\t\texecutionMode: \"execute\",\n\t\tallowedTools: WORKER_TOOLS,\n\t\tdeniedTools: [\"publish\", \"merge\", \"git_push\", \"npm_publish\"],\n\t\tdeniedEffects: [\"publishes\", \"merges\", \"mutatesReleaseTags\", \"scopeExpansion\"],\n\t\trequiredCapabilities: [\"workspace-lease\", \"checkpoint\", \"transaction\", \"rollback\"],\n\t\tretrieval: {\n\t\t\tallowed: true,\n\t\t\tmode: \"hybrid\",\n\t\t\tmaxResults: 30,\n\t\t\tmaxContextTokens: 2048,\n\t\t\trevalidateBeforeMutation: true,\n\t\t},\n\t\tbudget: { maxModelTurns: 20, maxToolCalls: 80, maxWallTimeMs: 600_000, maxOutputTokens: 8_000 },\n\t\tconcurrency: { parallelSafe: false, maximumInstances: 1 },\n\t\trecursion: { maySpawnSubagents: false, maximumDepth: 0 },\n\t\tinputSchema: \"subagent-context-packet-v1\",\n\t\toutputSchema: \"worker-result-v1\",\n\t\tfallbackAgents: [],\n\t},\n\tanalytical(\n\t\t\"cavecrew-investigator\",\n\t\t\"Deeply trace one concrete code or runtime flow without mutation.\",\n\t\t\"investigation\",\n\t\t\"cavecrew-investigation-result-v1\",\n\t\t{\n\t\t\taliases: [\"cavecrew-investigate\"],\n\t\t\tretrieval: {\n\t\t\t\tallowed: true,\n\t\t\t\tmode: \"hybrid\",\n\t\t\t\tmaxResults: 40,\n\t\t\t\tmaxContextTokens: 3072,\n\t\t\t\trevalidateBeforeMutation: false,\n\t\t\t},\n\t\t\tbudget: { maxModelTurns: 12, maxToolCalls: 48, maxWallTimeMs: 180_000, maxOutputTokens: 5_000 },\n\t\t},\n\t),\n\t{\n\t\t...analytical(\n\t\t\t\"cavecrew-reviewer\",\n\t\t\t\"Compactly review a narrowly bounded diff without mutation.\",\n\t\t\t\"review\",\n\t\t\t\"cavecrew-review-result-v1\",\n\t\t\t{\n\t\t\t\taliases: [\"cavecrew-review\"],\n\t\t\t\tretrieval: {\n\t\t\t\t\tallowed: true,\n\t\t\t\t\tmode: \"hybrid\",\n\t\t\t\t\tmaxResults: 25,\n\t\t\t\t\tmaxContextTokens: 2048,\n\t\t\t\t\trevalidateBeforeMutation: false,\n\t\t\t\t},\n\t\t\t},\n\t\t),\n\t},\n\t{\n\t\tname: \"cavecrew-builder\",\n\t\taliases: [\"cavecrew-build\"],\n\t\tversion: 1,\n\t\tdescription: \"Apply one narrowly bounded one- or two-file change as a restricted worker specialization.\",\n\t\trole: \"implementation\",\n\t\tprovider: WORKER_PROVIDER,\n\t\tmodel: WORKER_MODEL,\n\t\tmodelResolutionPolicy: \"strict\",\n\t\texecutionMode: \"execute\",\n\t\tallowedTools: BUILDER_TOOLS,\n\t\tdeniedTools: [\"publish\", \"merge\", \"git_push\", \"npm_publish\", \"subagent\"],\n\t\tdeniedEffects: [\"publishes\", \"merges\", \"mutatesReleaseTags\", \"scopeExpansion\", \"externalWrites\"],\n\t\trequiredCapabilities: [\"workspace-lease\", \"checkpoint\", \"transaction\", \"rollback\"],\n\t\tretrieval: {\n\t\t\tallowed: true,\n\t\t\tmode: \"hybrid\",\n\t\t\tmaxResults: 30,\n\t\t\tmaxContextTokens: 2048,\n\t\t\trevalidateBeforeMutation: true,\n\t\t},\n\t\tbudget: {\n\t\t\tmaxModelTurns: 12,\n\t\t\tmaxToolCalls: 40,\n\t\t\tmaxWallTimeMs: 300_000,\n\t\t\tmaxOutputTokens: 5_000,\n\t\t\tmaxAffectedFiles: 2,\n\t\t},\n\t\tconcurrency: { parallelSafe: false, maximumInstances: 1 },\n\t\trecursion: { maySpawnSubagents: false, maximumDepth: 0 },\n\t\tinputSchema: \"subagent-context-packet-v1\",\n\t\toutputSchema: \"cavecrew-build-result-v1\",\n\t\tfallbackAgents: [\"worker\"],\n\t},\n] as const;\n\nconst REQUIRED_SCHEMA_FIELDS: Record<string, readonly string[]> = {\n\t\"cavecrew-investigation-result-v1\": [\n\t\t\"objective\",\n\t\t\"summary\",\n\t\t\"flow\",\n\t\t\"rootCauses\",\n\t\t\"relevantFiles\",\n\t\t\"unknowns\",\n\t\t\"recommendedNextAgent\",\n\t],\n\t\"cavecrew-build-result-v1\": [\n\t\t\"objective\",\n\t\t\"status\",\n\t\t\"filesChanged\",\n\t\t\"validations\",\n\t\t\"rollbackState\",\n\t\t\"remainingRisks\",\n\t],\n\t\"cavecrew-review-result-v1\": [\"verdict\", \"findings\", \"missingTests\", \"acceptanceGaps\"],\n\t\"planner-result-v1\": [\"scope\", \"nonGoals\", \"implementationSteps\", \"risks\", \"tests\", \"acceptanceCriteria\"],\n\t\"scout-result-v1\": [\"candidateLocations\", \"relevantSymbols\", \"confidence\", \"recommendedNextRole\"],\n\t\"worker-result-v1\": [\"status\", \"filesChanged\", \"validations\"],\n};\n\nfunction validateModelReference(provider: string, model: string): string | null {\n\tif (!provider || !/^[a-z0-9-]+$/u.test(provider)) return \"INVALID_PROVIDER\";\n\tif (!model || model.startsWith(\"~\") || /[\\s;|&`$]/u.test(model)) return \"INVALID_MODEL_REFERENCE\";\n\tif (!/^[a-zA-Z0-9._:/-]+$/u.test(model)) return \"INVALID_MODEL_REFERENCE\";\n\treturn null;\n}\n\nfunction cloneDefinition(definition: SubagentDefinition): SubagentDefinition {\n\treturn {\n\t\t...definition,\n\t\taliases: [...definition.aliases],\n\t\tallowedTools: [...definition.allowedTools],\n\t\tdeniedTools: [...definition.deniedTools],\n\t\tdeniedEffects: [...definition.deniedEffects],\n\t\trequiredCapabilities: [...definition.requiredCapabilities],\n\t\tbudget: { ...definition.budget },\n\t\tconcurrency: { ...definition.concurrency },\n\t\trecursion: { ...definition.recursion },\n\t\tfallbackAgents: [...definition.fallbackAgents],\n\t\tresultCompression: definition.resultCompression ? { ...definition.resultCompression } : undefined,\n\t};\n}\n\nexport class SubagentRegistry {\n\tprivate readonly definitions: Map<string, SubagentDefinition>;\n\tprivate readonly aliases: Map<string, string>;\n\tprivate readonly diagnostics: RegistryDiagnostic[];\n\n\tprivate constructor(definitions: readonly SubagentDefinition[], diagnostics: RegistryDiagnostic[]) {\n\t\tthis.definitions = new Map();\n\t\tthis.aliases = new Map();\n\t\tthis.diagnostics = [...diagnostics];\n\t\tfor (const definition of definitions) this.definitions.set(definition.name, cloneDefinition(definition));\n\t\tfor (const definition of definitions)\n\t\t\tfor (const alias of definition.aliases) this.aliases.set(alias, definition.name);\n\t}\n\n\tstatic create(definitions: readonly SubagentDefinition[] = BUILTIN_SUBAGENT_DEFINITIONS): SubagentRegistry {\n\t\tconst diagnostics: RegistryDiagnostic[] = [];\n\t\tconst names = new Set<string>();\n\t\tconst aliases = new Map<string, string>();\n\t\tfor (const definition of definitions) {\n\t\t\tif (names.has(definition.name))\n\t\t\t\tdiagnostics.push({\n\t\t\t\t\tcode: \"DUPLICATE_CANONICAL_NAME\",\n\t\t\t\t\tmessage: `Duplicate agent ${definition.name}`,\n\t\t\t\t\tagent: definition.name,\n\t\t\t\t});\n\t\t\tnames.add(definition.name);\n\t\t\tif (validateModelReference(definition.provider, definition.model))\n\t\t\t\tdiagnostics.push({\n\t\t\t\t\tcode: \"INVALID_MODEL\",\n\t\t\t\t\tmessage: `Invalid model policy for ${definition.name}`,\n\t\t\t\t\tagent: definition.name,\n\t\t\t\t});\n\t\t\tif (\n\t\t\t\tdefinition.executionMode === \"observe\" &&\n\t\t\t\tdefinition.allowedTools.some((tool) => [\"edit\", \"write\", \"publish\", \"merge\"].includes(tool))\n\t\t\t)\n\t\t\t\tdiagnostics.push({\n\t\t\t\t\tcode: \"OBSERVE_MUTATION_TOOL\",\n\t\t\t\t\tmessage: `Observe agent ${definition.name} declares mutation tool`,\n\t\t\t\t\tagent: definition.name,\n\t\t\t\t});\n\t\t\tif (definition.concurrency.maximumInstances < 1 || definition.recursion.maximumDepth < 0)\n\t\t\t\tdiagnostics.push({\n\t\t\t\t\tcode: \"INVALID_LIMIT\",\n\t\t\t\t\tmessage: `Invalid limits for ${definition.name}`,\n\t\t\t\t\tagent: definition.name,\n\t\t\t\t});\n\t\t\tfor (const alias of definition.aliases) {\n\t\t\t\tconst prior = aliases.get(alias);\n\t\t\t\tif (prior && prior !== definition.name)\n\t\t\t\t\tdiagnostics.push({\n\t\t\t\t\t\tcode: \"DUPLICATE_ALIAS\",\n\t\t\t\t\t\tmessage: `Alias ${alias} is ambiguous`,\n\t\t\t\t\t\tagent: definition.name,\n\t\t\t\t\t});\n\t\t\t\taliases.set(alias, definition.name);\n\t\t\t}\n\t\t}\n\t\tfor (const definition of definitions) {\n\t\t\tfor (const fallback of definition.fallbackAgents) {\n\t\t\t\tif (!names.has(fallback)) {\n\t\t\t\t\tdiagnostics.push({\n\t\t\t\t\t\tcode: \"INVALID_FALLBACK\",\n\t\t\t\t\t\tmessage: `${definition.name} references unknown fallback ${fallback}`,\n\t\t\t\t\t\tagent: definition.name,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor (const definition of definitions) {\n\t\t\tconst visiting = new Set<string>();\n\t\t\tconst walk = (name: string): void => {\n\t\t\t\tif (visiting.has(name)) {\n\t\t\t\t\tdiagnostics.push({\n\t\t\t\t\t\tcode: \"FALLBACK_CYCLE\",\n\t\t\t\t\t\tmessage: `Fallback cycle includes ${name}`,\n\t\t\t\t\t\tagent: definition.name,\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tvisiting.add(name);\n\t\t\t\tconst next = definitions.find((candidate) => candidate.name === name);\n\t\t\t\tfor (const fallback of next?.fallbackAgents ?? []) walk(fallback);\n\t\t\t\tvisiting.delete(name);\n\t\t\t};\n\t\t\twalk(definition.name);\n\t\t}\n\t\treturn new SubagentRegistry(\n\t\t\t[...definitions].sort((left, right) => left.name.localeCompare(right.name)),\n\t\t\tdiagnostics,\n\t\t);\n\t}\n\n\tlist(): SubagentDefinition[] {\n\t\treturn [...this.definitions.values()].map(cloneDefinition).sort((a, b) => a.name.localeCompare(b.name));\n\t}\n\taliasesList(): Array<{ alias: string; name: string }> {\n\t\treturn [...this.aliases.entries()]\n\t\t\t.map(([alias, name]) => ({ alias, name }))\n\t\t\t.sort((a, b) => a.alias.localeCompare(b.alias));\n\t}\n\tdiagnosticsList(): RegistryDiagnostic[] {\n\t\treturn [...this.diagnostics];\n\t}\n\tvalidate(): { valid: boolean; diagnostics: RegistryDiagnostic[] } {\n\t\treturn { valid: this.diagnostics.length === 0, diagnostics: this.diagnosticsList() };\n\t}\n\n\tresolve(\n\t\trequestedAgent: string,\n\t\toptions: { referencingSkill?: string; availableModels?: readonly string[] } = {},\n\t): ResolvedSubagent | SubagentResolutionError {\n\t\tconst canonicalName = this.definitions.has(requestedAgent) ? requestedAgent : this.aliases.get(requestedAgent);\n\t\tif (!canonicalName)\n\t\t\treturn {\n\t\t\t\tcode: \"SUBAGENT_NOT_REGISTERED\",\n\t\t\t\trequestedAgent,\n\t\t\t\treferencingSkill: options.referencingSkill,\n\t\t\t\tavailableAgents: this.list().map((definition) => definition.name),\n\t\t\t\tautomaticFallbackAttempted: false,\n\t\t\t};\n\t\tconst definition = this.definitions.get(canonicalName);\n\t\tif (!definition)\n\t\t\treturn {\n\t\t\t\tcode: \"SUBAGENT_NOT_REGISTERED\",\n\t\t\t\trequestedAgent,\n\t\t\t\treferencingSkill: options.referencingSkill,\n\t\t\t\tavailableAgents: this.list().map((item) => item.name),\n\t\t\t\tautomaticFallbackAttempted: false,\n\t\t\t};\n\t\tconst model = resolveSubagentModel(definition, options.availableModels);\n\t\tif (!model.ok)\n\t\t\treturn {\n\t\t\t\t...model.error,\n\t\t\t\trequestedAgent,\n\t\t\t\treferencingSkill: options.referencingSkill,\n\t\t\t\tavailableAgents: this.list().map((item) => item.name),\n\t\t\t\tautomaticFallbackAttempted: false,\n\t\t\t};\n\t\treturn { definition, model: model.value };\n\t}\n}\n\nexport function resolveSubagentModel(\n\tdefinition: SubagentDefinition,\n\tavailableModels?: readonly string[],\n): { ok: true; value: SubagentModelResolution } | { ok: false; error: SubagentResolutionError } {\n\tconst configuredModel = definition.model.startsWith(\"~\") ? definition.model.slice(1) : definition.model;\n\tconst invalid = validateModelReference(definition.provider, configuredModel);\n\tif (invalid)\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SUBAGENT_MODEL_UNAVAILABLE\",\n\t\t\t\trequestedAgent: definition.name,\n\t\t\t\tavailableAgents: [],\n\t\t\t\tautomaticFallbackAttempted: false,\n\t\t\t},\n\t\t};\n\tconst exactReference = `${definition.provider}/${configuredModel}`;\n\tif (\n\t\tavailableModels &&\n\t\tavailableModels.length > 0 &&\n\t\t!availableModels.includes(configuredModel) &&\n\t\t!availableModels.includes(exactReference)\n\t) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SUBAGENT_MODEL_UNAVAILABLE\",\n\t\t\t\trequestedAgent: definition.name,\n\t\t\t\tavailableAgents: [...availableModels],\n\t\t\t\tautomaticFallbackAttempted: false,\n\t\t\t},\n\t\t};\n\t}\n\treturn {\n\t\tok: true,\n\t\tvalue: {\n\t\t\tagent: definition.name,\n\t\t\tconfiguredProvider: definition.provider,\n\t\t\tconfiguredModel: definition.model,\n\t\t\tresolvedProvider: definition.provider,\n\t\t\tresolvedModel: configuredModel,\n\t\t\tresolutionKind: definition.model.startsWith(\"~\") ? \"provider_alias\" : \"exact\",\n\t\t\treasonCode: definition.model.startsWith(\"~\") ? \"PROFILE_MARKER_STRIPPED\" : \"CONFIGURED_EXACT_REFERENCE\",\n\t\t\trecordedAt: new Date().toISOString(),\n\t\t},\n\t};\n}\n\nexport function validateSubagentOutput(\n\tschema: string,\n\toutput: unknown,\n): { valid: true; value: Record<string, unknown> } | { valid: false; error: SubagentResolutionError } {\n\tif (!REQUIRED_SCHEMA_FIELDS[schema] || typeof output !== \"object\" || output === null || Array.isArray(output))\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SUBAGENT_OUTPUT_SCHEMA_INVALID\",\n\t\t\t\trequestedAgent: \"unknown\",\n\t\t\t\tavailableAgents: [],\n\t\t\t\tautomaticFallbackAttempted: false,\n\t\t\t},\n\t\t};\n\tconst object = output as Record<string, unknown>;\n\tif (REQUIRED_SCHEMA_FIELDS[schema].some((field) => !(field in object)))\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\terror: {\n\t\t\t\tcode: \"SUBAGENT_OUTPUT_SCHEMA_INVALID\",\n\t\t\t\trequestedAgent: \"unknown\",\n\t\t\t\tavailableAgents: [],\n\t\t\t\tautomaticFallbackAttempted: false,\n\t\t\t},\n\t\t};\n\treturn { valid: true, value: object };\n}\n\nexport function validateSkillAgentReferences(\n\tskillName: string,\n\tskillSource: string,\n\tcontent: string,\n\tregistry: SubagentRegistry = SubagentRegistry.create(),\n): SkillDependencyDiagnostic[] {\n\tconst names = [\n\t\t...content.matchAll(/(?:cavecrew-[a-z0-9-]+|librarian|pentester|planner|reviewer|scout|security|worker)/gu),\n\t].map((match) => match[0]);\n\tconst diagnostics: SkillDependencyDiagnostic[] = [];\n\tfor (const name of [...new Set(names)]) {\n\t\tconst result = registry.resolve(name, { referencingSkill: skillName });\n\t\tif (\"code\" in result)\n\t\t\tdiagnostics.push({\n\t\t\t\tcode: \"SKILL_DEPENDENCY_INVALID\",\n\t\t\t\tskillName,\n\t\t\t\tskillSource,\n\t\t\t\tmissingAgent: name,\n\t\t\t\trecommendedRemediation: `Register or repair the exact agent reference ${name} before activating ${skillName}.`,\n\t\t\t});\n\t}\n\treturn diagnostics;\n}\n\nexport function getCanonicalSubagentRegistry(): SubagentRegistry {\n\treturn SubagentRegistry.create();\n}\nexport function assertCanonicalProductionAgents(agentNames: readonly string[]): void {\n\tconst known = new Set(\n\t\tgetCanonicalSubagentRegistry()\n\t\t\t.list()\n\t\t\t.map((definition) => definition.name),\n\t);\n\tconst unknown = agentNames.filter((name) => !known.has(name));\n\tif (unknown.length > 0) throw new Error(`PRODUCTION_AGENT_OUTSIDE_CANONICAL_REGISTRY: ${unknown.join(\", \")}`);\n}\n\nexport const SUBAGENT_POLICY_EFFECTS = {\n\tobserve: [...OBSERVE_EFFECTS],\n\tplan: [...PLAN_EFFECTS],\n\texecute: [...EXECUTE_EFFECTS],\n} as const;\n"]}