{"version":3,"file":"baseline.d.ts","sourceRoot":"","sources":["../../../src/core/routing/baseline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAMtH;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,YAAY,EA6ExC,CAAC;AAEF,MAAM,WAAW,cAAc;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,sBAAsB,CAAC;IAClC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,wEAAwE;AACxE,wBAAgB,cAAc,CAAC,QAAQ,EAAE,0BAA0B,GAAG,cAAc,CA4CnF;AAkBD,wBAAgB,gBAAgB,CAAC,CAAC,EAAE;IACnC,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;CACxB,GAAG,MAAM,CAET","sourcesContent":["/**\n * Deterministic baseline policy.\n *\n * The baseline must function with no historical evaluations, no live providers,\n * no model-based routing, and no network access. It is a canonical, rule-based,\n * deterministic mapping from the feature vector to a recommended candidate.\n *\n * Rules carry explicit IDs and deterministic precedence. The baseline remains\n * available during evaluation-store failure and is fully replayable.\n */\n\nimport type { BaselineRule, ExecutionTopology, OrchestrationCandidate, OrchestrationFeatureVector } from \"./types.js\";\n\nconst DEFAULT_PROVIDER = \"fixture\";\nconst DEFAULT_MODEL = \"fixture/deterministic\";\nconst _DEFAULT_THINKING = \"off\";\n\n/**\n * Deterministic baseline rules, ordered by precedence (lower runs first).\n * Each rule matches on a subset of feature fields.\n */\nexport const BASELINE_RULES: BaselineRule[] = [\n\t{\n\t\truleId: \"baseline-release\",\n\t\tdescription: \"Release task: planner + builder + reviewer topology, release budget, hybrid retrieval.\",\n\t\tprecedence: 1,\n\t\tmatch: { requiresRelease: true },\n\t\tresult: {\n\t\t\texecutionTopology: \"cavecrew\",\n\t\t\tretrievalPolicy: \"hybrid\",\n\t\t\tbudgetClass: \"release\",\n\t\t\tproviderProfile: DEFAULT_PROVIDER,\n\t\t\tconfiguredModel: DEFAULT_MODEL,\n\t\t\tthinkingLevel: \"high\",\n\t\t\treasonCodes: [\"baseline:release_task\"],\n\t\t},\n\t},\n\t{\n\t\truleId: \"baseline-high-risk-mutation\",\n\t\tdescription:\n\t\t\t\"High-risk multi-file mutation: single agent plus reviewer or Cavecrew builder, large bounded budget.\",\n\t\tprecedence: 2,\n\t\tmatch: { minComplexity: 0.55, requiresMutation: true },\n\t\tresult: {\n\t\t\texecutionTopology: \"single_agent_with_reviewer\",\n\t\t\tretrievalPolicy: \"hybrid\",\n\t\t\tbudgetClass: \"large\",\n\t\t\tproviderProfile: DEFAULT_PROVIDER,\n\t\t\tconfiguredModel: DEFAULT_MODEL,\n\t\t\tthinkingLevel: \"high\",\n\t\t\treasonCodes: [\"baseline:high_risk_mutation\"],\n\t\t},\n\t},\n\t{\n\t\truleId: \"baseline-bounded-implementation\",\n\t\tdescription: \"Bounded implementation: single worker, hybrid retrieval, standard budget.\",\n\t\tprecedence: 3,\n\t\tmatch: { requiresMutation: true, minComplexity: 0.1 },\n\t\tresult: {\n\t\t\texecutionTopology: \"single_agent\",\n\t\t\tretrievalPolicy: \"hybrid\",\n\t\t\tbudgetClass: \"standard\",\n\t\t\tproviderProfile: DEFAULT_PROVIDER,\n\t\t\tconfiguredModel: DEFAULT_MODEL,\n\t\t\tthinkingLevel: \"high\",\n\t\t\treasonCodes: [\"baseline:bounded_implementation\"],\n\t\t},\n\t},\n\t{\n\t\truleId: \"baseline-small-exact-lookup\",\n\t\tdescription: \"Small exact read-only query: single analytical agent, lexical retrieval, small budget.\",\n\t\tprecedence: 4,\n\t\tmatch: { requiresMutation: false, minComplexity: 0.05 },\n\t\tresult: {\n\t\t\texecutionTopology: \"single_agent\",\n\t\t\tretrievalPolicy: \"lexical\",\n\t\t\tbudgetClass: \"small\",\n\t\t\tproviderProfile: DEFAULT_PROVIDER,\n\t\t\tconfiguredModel: DEFAULT_MODEL,\n\t\t\tthinkingLevel: \"off\",\n\t\t\treasonCodes: [\"baseline:small_exact_lookup\"],\n\t\t},\n\t},\n\t{\n\t\truleId: \"baseline-default\",\n\t\tdescription: \"Default fallback: single analytical agent, hybrid retrieval, standard budget.\",\n\t\tprecedence: 99,\n\t\tmatch: {},\n\t\tresult: {\n\t\t\texecutionTopology: \"single_agent\",\n\t\t\tretrievalPolicy: \"hybrid\",\n\t\t\tbudgetClass: \"standard\",\n\t\t\tproviderProfile: DEFAULT_PROVIDER,\n\t\t\tconfiguredModel: DEFAULT_MODEL,\n\t\t\tthinkingLevel: \"high\",\n\t\t\treasonCodes: [\"baseline:default\"],\n\t\t},\n\t},\n];\n\nexport interface BaselineResult {\n\truleId: string;\n\tcandidate: OrchestrationCandidate;\n\treasonCodes: string[];\n\tprecedence: number;\n}\n\n/** Select the deterministic baseline candidate for a feature vector. */\nexport function baselineSelect(features: OrchestrationFeatureVector): BaselineResult {\n\tconst sorted = [...BASELINE_RULES].sort((a, b) => a.precedence - b.precedence);\n\tfor (const rule of sorted) {\n\t\tif (matchesRule(rule, features)) {\n\t\t\tconst r = rule.result;\n\t\t\tconst candidate: OrchestrationCandidate = {\n\t\t\t\tcandidateId: buildCandidateId(r),\n\t\t\t\tproviderProfile: r.providerProfile,\n\t\t\t\tconfiguredModel: r.configuredModel,\n\t\t\t\tthinkingLevel: r.thinkingLevel,\n\t\t\t\texecutionTopology: r.executionTopology,\n\t\t\t\tskillIds: [],\n\t\t\t\tsubagentDefinitions:\n\t\t\t\t\tr.executionTopology === \"single_agent_with_reviewer\"\n\t\t\t\t\t\t? [\"reviewer\"]\n\t\t\t\t\t\t: r.executionTopology === \"cavecrew\"\n\t\t\t\t\t\t\t? [\"investigator\", \"planner\", \"builder\", \"reviewer\"]\n\t\t\t\t\t\t\t: [],\n\t\t\t\tretrievalPolicy: r.retrievalPolicy,\n\t\t\t\tbudgetClass: r.budgetClass,\n\t\t\t\tfallbackPolicy: \"validated_policy\",\n\t\t\t};\n\t\t\treturn { ruleId: rule.ruleId, candidate, reasonCodes: r.reasonCodes, precedence: rule.precedence };\n\t\t}\n\t}\n\t// Unreachable since baseline-default always matches.\n\tconst fallback = BASELINE_RULES[BASELINE_RULES.length - 1];\n\tconst r = fallback.result;\n\treturn {\n\t\truleId: fallback.ruleId,\n\t\tcandidate: {\n\t\t\tcandidateId: buildCandidateId(r),\n\t\t\tproviderProfile: r.providerProfile,\n\t\t\tconfiguredModel: r.configuredModel,\n\t\t\texecutionTopology: r.executionTopology,\n\t\t\tskillIds: [],\n\t\t\tsubagentDefinitions: [],\n\t\t\tretrievalPolicy: r.retrievalPolicy,\n\t\t\tbudgetClass: r.budgetClass,\n\t\t\tfallbackPolicy: \"validated_policy\",\n\t\t},\n\t\treasonCodes: r.reasonCodes,\n\t\tprecedence: fallback.precedence,\n\t};\n}\n\nfunction matchesRule(rule: BaselineRule, features: OrchestrationFeatureVector): boolean {\n\tconst m = rule.match;\n\tif (m.taskCategory !== undefined && m.taskCategory !== features.taskCategory) return false;\n\tif (m.minComplexity !== undefined && features.taskComplexity < m.minComplexity) return false;\n\tif (m.requiresMutation !== undefined && m.requiresMutation !== features.requiresMutation) return false;\n\tif (m.requiresRelease !== undefined && m.requiresRelease !== features.requiresRelease) return false;\n\tif (\n\t\tm.requiresCrossPlatformValidation !== undefined &&\n\t\tm.requiresCrossPlatformValidation !== features.requiresCrossPlatformValidation\n\t)\n\t\treturn false;\n\tif (m.requiresExternalResearch !== undefined && m.requiresExternalResearch !== features.requiresExternalResearch)\n\t\treturn false;\n\treturn true;\n}\n\nexport function buildCandidateId(r: {\n\texecutionTopology: ExecutionTopology;\n\tretrievalPolicy: string;\n\tbudgetClass: string;\n\tproviderProfile: string;\n\tconfiguredModel: string;\n}): string {\n\treturn `c-${r.providerProfile.replace(/[^a-z0-9]/gi, \"-\")}-${r.configuredModel.replace(/[^a-z0-9]/gi, \"-\")}-${r.executionTopology}-${r.retrievalPolicy}-${r.budgetClass}`;\n}\n"]}