Merge nucleic/ivory-jade-ibis-gv6u into dev

This commit is contained in:
2026-08-02 21:40:32 -07:00
parent 57b52b4ec6
commit 531e9ba301
2 changed files with 157 additions and 83 deletions
+64 -57
View File
@@ -79,12 +79,14 @@ public struct RoutingNote: Sendable, Equatable {
/// Purpose × level concrete (model, effort). The routing knowledge is a hand-encoded
/// matrix grounded in July-2026 model research (see the plan's research table and the
/// per-cell comments): Opus 5 peaks at *medium* effort on routine coding and never exceeds
/// `high`; GPT-5.6 Sol owns the backend lane at high+; Fable 5 appears only at Deep/Max on
/// the lanes that genuinely reward long-horizon reasoning; Haiku/Luna only where a light
/// model can't hurt. Every cell carries a Claude-lane and a GPT-lane candidate so a
/// single-provider user always resolves; `IntelligenceRoutingTests` enforces the
/// invariants (tier monotonicity, per-model caps, valid efforts for every connected set).
/// per-cell comments): Opus 5 carries the heavy Claude lane and is allowed past `high` only
/// at the top of the two rows that reward it (`debugging`/`review` at Max); GPT-5.6 Sol owns
/// the backend lane at high+; Fable 5 is now reserved for the two long-horizon Max cells
/// (`planning`, `refactor`); Luna only where a light model can't hurt. Nearly every cell
/// carries a Claude-lane and a GPT-lane candidate so a single-provider user resolves inside
/// its own row `frontendImpl`/`balanced` is the one deliberate exception, and falls back
/// to the row's Light GPT candidate. `IntelligenceRoutingTests` enforces the invariants
/// (tier monotonicity, per-model caps, valid efforts for every connected set).
public enum IntelligenceRouter {
/// One ranked routing option: a SKU, its effort, and whether a ChatGPT Pro account
/// upgrades the effort to Sol's `ultra` mode at Max level.
@@ -267,84 +269,89 @@ public enum IntelligenceRouter {
/// inline where a cell is deliberately *not* the obvious escalation.
static let matrix: [PromptPurpose: [IntelligenceLevel: [Candidate]]] = [
.planning: [
.quick: [.init("claude-sonnet-5", "medium"), .init("gpt-5.6-terra", "medium")],
.light: [.init("claude-opus-5", "medium"), .init("gpt-5.6-terra", "high")],
.quick: [.init("gpt-5.6-terra", "medium"), .init("claude-sonnet-5", "medium")],
.light: [.init("claude-sonnet-5", "medium"), .init("gpt-5.6-terra", "high")],
.balanced: [.init("claude-opus-5", "high"), .init("gpt-5.6-sol", "high")],
.deep: [.init("claude-fable-5", "high"), .init("gpt-5.6-sol", "xhigh")],
// Fable is the long-horizon planning specialist; max effort is reserved for it.
.deep: [.init("claude-opus-5", "high"), .init("gpt-5.6-sol", "xhigh")],
// The preferred lane here is the long-horizon specialist; max effort is reserved for it.
.max: [.init("claude-fable-5", "max"), .init("gpt-5.6-sol", "xhigh", ultraEligible: true)],
],
.backendImpl: [
.quick: [.init("claude-sonnet-5", "low"), .init("gpt-5.6-luna", "medium")],
.light: [.init("claude-sonnet-5", "medium"), .init("gpt-5.6-terra", "medium")],
// Sol leads the backend lane from Balanced up it rewards high+ effort on
// implementation where Opus 5 would already be past its medium-effort peak.
.quick: [.init("gpt-5.6-luna", "low"), .init("claude-sonnet-5", "medium")],
.light: [.init("gpt-5.6-terra", "medium"), .init("claude-sonnet-5", "medium")],
// Lane preference flips from Balanced up: the preferred model rewards high+ effort on
// implementation, where the secondary would already be past its medium-effort peak.
.balanced: [.init("gpt-5.6-sol", "high"), .init("claude-opus-5", "medium")],
.deep: [.init("gpt-5.6-sol", "xhigh"), .init("claude-fable-5", "high")],
.max: [.init("gpt-5.6-sol", "xhigh", ultraEligible: true), .init("claude-fable-5", "high")],
.deep: [.init("gpt-5.6-sol", "xhigh"), .init("claude-opus-5", "high")],
.max: [.init("gpt-5.6-sol", "xhigh", ultraEligible: true), .init("claude-opus-5", "high")],
],
.frontendImpl: [
.quick: [.init("claude-sonnet-5", "low"), .init("gpt-5.6-luna", "medium")],
.light: [.init("claude-sonnet-5", "medium"), .init("gpt-5.6-terra", "medium")],
// Opus 5 is the consensus UI pick at medium, its measured peak for routine work.
.balanced: [.init("claude-opus-5", "medium"), .init("gpt-5.6-terra", "high")],
.quick: [.init("gpt-5.6-luna", "low"), .init("claude-sonnet-5", "medium")],
.light: [.init("gpt-5.6-terra", "medium"), .init("claude-sonnet-5", "medium")],
// The one deliberately single-lane cell: routine UI work sits on the Claude lane at
// both ranks (Sonnet at its peak, Opus behind it), because neither GPT-lane model
// is worth the swap here. A Codex-only account falls back to this row's Light
// candidate see `everyCellCoversBothLanes`, which allowlists exactly this cell.
.balanced: [.init("claude-sonnet-5", "medium"), .init("claude-opus-5", "high")],
.deep: [.init("claude-opus-5", "high"), .init("gpt-5.6-sol", "high")],
.max: [.init("claude-fable-5", "high"), .init("gpt-5.6-sol", "xhigh")],
.max: [.init("claude-opus-5", "high"), .init("gpt-5.6-sol", "xhigh")],
],
.quickFix: [
.quick: [.init("gpt-5.6-luna", "low"), .init("claude-sonnet-5", "low")],
.light: [.init("claude-sonnet-5", "low"), .init("gpt-5.6-luna", "medium")],
.balanced: [.init("claude-sonnet-5", "medium"), .init("gpt-5.6-terra", "medium")],
// Deep tops out at Opus·medium (its measured peak) a "deep" quick fix wants
.light: [.init("gpt-5.6-luna", "low"), .init("claude-sonnet-5", "medium")],
.balanced: [.init("gpt-5.6-terra", "medium"), .init("claude-sonnet-5", "medium")],
// Deep tops out at the preferred model's measured peak effort a "deep" quick fix wants
// care, not scope; and it keeps this row within one cost tier of the heavy rows
// a borderline classification could have landed on (the drift invariant).
.deep: [.init("claude-opus-5", "medium"), .init("gpt-5.6-terra", "high")],
// Even "Max" on a quick fix stops at Opus·medium more model would only invite
// out-of-scope refactors (the measured Opus-past-medium failure mode).
.max: [.init("claude-opus-5", "medium"), .init("gpt-5.6-sol", "high")],
.deep: [.init("claude-sonnet-5", "medium"), .init("gpt-5.6-terra", "high")],
// Even "Max" on a quick fix stops at that same peak more model would only invite
// out-of-scope refactors (the measured past-peak failure mode).
.max: [.init("claude-sonnet-5", "medium"), .init("gpt-5.6-terra", "high")],
],
.refactor: [
.quick: [.init("claude-sonnet-5", "low"), .init("gpt-5.6-luna", "medium")],
.quick: [.init("gpt-5.6-terra", "low"), .init("claude-sonnet-5", "medium")],
.light: [.init("claude-sonnet-5", "medium"), .init("gpt-5.6-terra", "medium")],
.balanced: [.init("claude-sonnet-5", "high"), .init("gpt-5.6-terra", "high")],
.balanced: [.init("claude-opus-5", "high"), .init("gpt-5.6-sol", "high")],
.deep: [.init("claude-opus-5", "medium"), .init("gpt-5.6-sol", "high")],
.max: [.init("claude-fable-5", "high"), .init("gpt-5.6-sol", "xhigh")],
],
.debugging: [
.quick: [.init("claude-sonnet-5", "medium"), .init("gpt-5.6-terra", "medium")],
.light: [.init("claude-sonnet-5", "high"), .init("gpt-5.6-terra", "high")],
.quick: [.init("gpt-5.6-terra", "medium"), .init("claude-sonnet-5", "medium")],
.light: [.init("claude-opus-5", "high"), .init("gpt-5.6-sol", "high")],
.balanced: [.init("claude-opus-5", "high"), .init("gpt-5.6-sol", "high")],
.deep: [.init("claude-fable-5", "high"), .init("gpt-5.6-sol", "xhigh")],
// Root-causing gnarly failures is the other lane that genuinely rewards Fable max.
.max: [.init("claude-fable-5", "max"), .init("gpt-5.6-sol", "xhigh", ultraEligible: true)],
.deep: [.init("claude-opus-5", "high"), .init("gpt-5.6-sol", "xhigh")],
// Root-causing gnarly failures is one of the two rows where Opus earns effort past
// its routine-coding peak `max` here, `xhigh` on Review's top cell.
.max: [.init("claude-opus-5", "max"), .init("gpt-5.6-sol", "xhigh", ultraEligible: true)],
],
.review: [
.quick: [.init("claude-haiku-4-5", "low"), .init("gpt-5.6-luna", "low")],
.light: [.init("claude-sonnet-5", "low"), .init("gpt-5.6-terra", "medium")],
.quick: [.init("gpt-5.6-luna", "low"), .init("claude-sonnet-5", "low")],
.light: [.init("gpt-5.6-terra", "low"), .init("claude-sonnet-5", "medium")],
.balanced: [.init("gpt-5.6-sol", "medium"), .init("claude-opus-5", "high")],
.deep: [.init("gpt-5.6-sol", "high"), .init("claude-opus-5", "high")],
.max: [.init("gpt-5.6-sol", "high"), .init("claude-opus-5", "xhigh")],
],
.writing: [
.quick: [.init("gpt-5.6-luna", "low"), .init("claude-sonnet-5", "low")],
.light: [.init("gpt-5.6-terra", "low"), .init("claude-sonnet-5", "medium")],
// Off the bargain tier from Balanced up: prose prompts routinely border on
// backend/docs mixes, so the row stays within one cost tier of the implementation
// rows a borderline classification could have meant (the drift invariant) and
// serious writing genuinely reads better off a heavier model, held at its
// routine-work peak effort rather than pushed higher.
.balanced: [.init("claude-opus-5", "medium"), .init("gpt-5.6-terra", "medium")],
.deep: [.init("claude-opus-5", "medium"), .init("gpt-5.6-sol", "high")],
.max: [.init("claude-opus-5", "medium"), .init("gpt-5.6-sol", "high")],
],
// The conservative row every failed classification lands on: mid-tier at every stop,
// so "we couldn't tell" can never mean the specialist at max or a light model on a hard task.
.general: [
.quick: [.init("gpt-5.6-luna", "low"), .init("claude-sonnet-5", "medium")],
.light: [.init("gpt-5.6-terra", "medium"), .init("claude-sonnet-5", "medium")],
.balanced: [.init("claude-sonnet-5", "medium"), .init("gpt-5.6-terra", "high")],
.deep: [.init("claude-opus-5", "high"), .init("gpt-5.6-sol", "high")],
.max: [.init("claude-opus-5", "high"), .init("gpt-5.6-sol", "xhigh")],
],
.writing: [
.quick: [.init("claude-haiku-4-5", "low"), .init("gpt-5.6-luna", "low")],
.light: [.init("claude-sonnet-5", "low"), .init("gpt-5.6-luna", "medium")],
// Sonnet/Terra (not the bargain tier) from Balanced up: prose prompts routinely
// border on backend/docs mixes, so the row stays within one cost tier of the
// implementation rows a borderline classification could have meant (the drift
// invariant) and serious writing genuinely reads better off the mid tier.
.balanced: [.init("claude-sonnet-5", "medium"), .init("gpt-5.6-terra", "medium")],
.deep: [.init("claude-opus-5", "medium"), .init("gpt-5.6-terra", "high")],
.max: [.init("claude-opus-5", "medium"), .init("gpt-5.6-terra", "high")],
],
// The conservative row every failed classification lands on: mid-tier at every stop,
// so "we couldn't tell" can never mean Fable-at-max or Haiku-on-a-hard-task.
.general: [
.quick: [.init("claude-sonnet-5", "low"), .init("gpt-5.6-luna", "medium")],
.light: [.init("claude-sonnet-5", "medium"), .init("gpt-5.6-terra", "medium")],
.balanced: [.init("claude-opus-5", "medium"), .init("gpt-5.6-terra", "high")],
.deep: [.init("claude-opus-5", "high"), .init("gpt-5.6-sol", "high")],
.max: [.init("claude-fable-5", "high"), .init("gpt-5.6-sol", "xhigh")],
],
]
/// Every SKU the matrix can produce. Kept derived from the matrix so quota-family
@@ -6,11 +6,14 @@ import Testing
/// Locks the Intelligence router's research-derived invariants: every purpose × level cell
/// resolves to a real, supported (model, effort) for every connected-provider combination;
/// cost never decreases as the slider rises; and the per-model rules the July-2026 research
/// established (Opus 5 never above `high`, Fable only at Deep/Max, Haiku only on the light
/// review/writing rows, `max` effort reserved for Fable's planning/debugging cells, `ultra`
/// only for a Pro account at Max on Sol) hold for the whole matrix so a future matrix edit
/// can't silently reintroduce the misrouting failure modes the slider exists to prevent.
/// cost never decreases as the slider rises; and the per-model rules hold for the whole
/// matrix (Opus 5 past `high` only on the two documented top cells, Fable only on the two
/// long-horizon Max cells, Haiku never off the light review/writing rows, `max` effort only
/// at the top of Planning/Debugging, `ultra` only for a Pro account at Max on Sol) so a
/// future matrix edit can't silently reintroduce the misrouting failure modes the slider
/// exists to prevent. Where the current matrix takes a deliberate exception to a rule, the
/// exception is an explicit allowlist here rather than a loosened bound, so anything *else*
/// drifting the same way still fails.
@Suite struct IntelligenceRoutingTests {
private let allLevels = IntelligenceLevel.allCases
private let allPurposes = PromptPurpose.allCases
@@ -21,15 +24,48 @@ import Testing
// MARK: Matrix shape
/// Cells that deliberately rank two models from the SAME lane. A single-provider user
/// still resolves `rankedCandidates` walks the lower levels of the same purpose but
/// they resolve out of a neighbouring cell rather than this one, so each exception is
/// listed explicitly and checked below.
private let singleLaneCells: [(purpose: PromptPurpose, level: IntelligenceLevel, lane: BackendID)] = [
(.frontendImpl, .balanced, .claudeCode),
]
@Test func everyCellCoversBothLanes() {
for purpose in allPurposes {
for level in allLevels {
let cell = IntelligenceRouter.matrix[purpose]?[level]
#expect(cell != nil, "missing cell \(purpose)/\(level)")
let backends = Set((cell ?? []).compactMap { BackendID.forModel($0.sku) })
guard
let exception = singleLaneCells.first(
where: { $0.purpose == purpose && $0.level == level })
else {
#expect(
backends.isSuperset(of: [.claudeCode, .codex]),
"\(purpose)/\(level) must offer a Claude and a GPT lane")
continue
}
#expect(
backends == [exception.lane],
"\(purpose)/\(level) is allowlisted as \(exception.lane)-only; it now spans \(backends)")
}
}
}
/// The promise the allowlist above must not break: even on a single-lane cell, a user
/// connected to only the *other* provider still gets a route on their own lane.
@Test func singleLaneCellsStillResolveOnTheMissingLane() {
for exception in singleLaneCells {
for lane in [BackendID.claudeCode, .codex] where lane != exception.lane {
let resolution = IntelligenceRouter.route(
purpose: exception.purpose, level: exception.level,
connected: [lane], fallback: fallback)
#expect(
BackendID.forModel(resolution.model) == lane,
"\(exception.purpose)/\(exception.level) left \(lane) without a route")
#expect(resolution.isAvailable)
}
}
}
@@ -95,30 +131,40 @@ import Testing
// MARK: Research-derived per-model rules
@Test func opusNeverExceedsHighEffort() {
/// Opus stays at or below `high` its measured peak band for routine work everywhere
/// except the top of the two rows that genuinely reward more thinking. Those two cells
/// are named, so a third one can't appear without this test failing.
@Test func opusExceedsHighOnlyOnTheDocumentedTopCells() {
let allowed: [PromptPurpose: String] = [.debugging: "max", .review: "xhigh"]
for (purpose, row) in IntelligenceRouter.matrix {
for (level, cell) in row {
for candidate in cell where candidate.sku.hasPrefix("claude-opus") {
if ["low", "medium", "high"].contains(candidate.effort) { continue }
#expect(
["low", "medium", "high"].contains(candidate.effort),
level == .max && allowed[purpose] == candidate.effort,
"\(purpose)/\(level): Opus past its measured peak (\(candidate.effort))")
}
}
}
}
@Test func fableOnlyAtDeepAndMax() {
/// Fable is the long-horizon specialist and now appears on exactly two cells the Max
/// stop of the two rows whose whole point at that level is unbounded reasoning depth.
@Test func fableOnlyOnThePlanningAndRefactorMaxCells() {
let allowed: Set<PromptPurpose> = [.planning, .refactor]
for (purpose, row) in IntelligenceRouter.matrix {
for (level, cell) in row {
for candidate in cell where candidate.sku.hasPrefix("claude-fable") {
#expect(
level >= .deep,
"\(purpose)/\(level): Fable on a low tier overpays for routine work")
level == .max && allowed.contains(purpose),
"\(purpose)/\(level): Fable off its two specialist cells overpays")
}
}
}
}
/// Haiku is currently unused by the matrix; this stays as a forward guard so a future
/// edit can't put it anywhere it couldn't carry the work.
@Test func haikuOnlyOnLightReviewAndWritingCells() {
for (purpose, row) in IntelligenceRouter.matrix {
for (level, cell) in row {
@@ -131,13 +177,19 @@ import Testing
}
}
@Test func maxEffortReservedForFablePlanningAndDebugging() {
/// `max` effort is the top of the ladder and stays at the top of the two rows that earn
/// it: Planning (on the specialist) and Debugging (on Opus).
@Test func maxEffortReservedForTheTopOfPlanningAndDebugging() {
let allowed: [PromptPurpose: String] = [
.planning: "claude-fable-5", .debugging: "claude-opus-5",
]
for (purpose, row) in IntelligenceRouter.matrix {
for (level, cell) in row {
for candidate in cell where candidate.effort == "max" {
#expect(candidate.sku.hasPrefix("claude-fable"))
#expect([PromptPurpose.planning, .debugging].contains(purpose))
#expect(level == .max, "\(purpose)/\(level)")
#expect(
allowed[purpose] == candidate.sku,
"\(purpose)/\(level): \(candidate.sku) can't carry max effort")
}
}
}
@@ -285,7 +337,7 @@ import Testing
#expect(limits.contains(model: "claude-fable-5"))
#expect(!limits.contains(model: "claude-opus-5"))
let resolution = IntelligenceRouter.route(
purpose: .planning, level: .deep,
purpose: .planning, level: .max,
connected: [.claudeCode, .codex], limits: limits,
fallback: fallback)
#expect(resolution.model == "gpt-5.6-sol")
@@ -343,12 +395,12 @@ import Testing
}
@Test func specialistPerformanceWinsDespiteLowProviderCapacity() {
// Deep planning is a deliberately decisive Fable cell. Even a large quota imbalance
// Max planning is a deliberately decisive Fable cell. Even a large quota imbalance
// must not turn the capacity signal into a quality downgrade.
let limits = IntelligenceRouter.Limits(
providerUtilization: [.claudeCode: 95, .codex: 0])
let resolution = IntelligenceRouter.route(
purpose: .planning, level: .deep,
purpose: .planning, level: .max,
connected: [.claudeCode, .codex], limits: limits,
fallback: fallback)
@@ -401,22 +453,24 @@ import Testing
// MARK: Mixed-intent blend
/// Light is the stop where Writing and Debugging still sit a tier apart on the Claude
/// lane (Balanced puts both on the same tier, so it exercises the no-raise branch).
@Test func mixedIntentRaisesPrimaryToSecondaryCostFloor() {
let primary = IntelligenceRouter.route(
purpose: .writing, level: .balanced, connected: [.claudeCode],
purpose: .writing, level: .light, connected: [.claudeCode],
fallback: fallback)
let secondary = IntelligenceRouter.route(
purpose: .debugging, level: .balanced, connected: [.claudeCode],
purpose: .debugging, level: .light, connected: [.claudeCode],
fallback: fallback)
let mixed = IntelligenceRouter.routeMixed(
primary: .writing, secondary: .debugging, level: .balanced,
primary: .writing, secondary: .debugging, level: .light,
connected: [.claudeCode], fallback: fallback)
#expect(IntelligenceRouter.costTier(of: primary.model) == 1)
#expect(IntelligenceRouter.costTier(of: secondary.model) == 2)
#expect(IntelligenceRouter.costTier(of: mixed.model) == 2)
#expect(mixed.purpose == .writing)
#expect(mixed.level == .balanced)
#expect(mixed.level == .light)
#expect(mixed.reason.contains("\(PromptPurpose.writing.displayName) + \(PromptPurpose.debugging.displayName)"))
#expect(mixed.reason.contains("secondary intent's cost tier"))
}
@@ -454,10 +508,22 @@ import Testing
// MARK: Misroute damage bound
/// Purpose pairs allowed to drift two tiers instead of one. `quickFix` is now capped at
/// the mid tier at *every* level deliberately, so a "quick fix" can never turn into a
/// scope-expanding refactor while Debugging and Refactor climb to the top of their
/// rows. That makes a quickFixheavy misclassification a two-tier move by construction.
/// It is an allowlist rather than a loosened bound so every other pair still gets the
/// one-tier guarantee.
private let twoTierDriftPairs: [Set<PromptPurpose>] = [
[.quickFix, .debugging],
[.quickFix, .refactor],
]
/// The binding accuracy invariant: even when the heuristic classifier mislabels a
/// fixture, routing its *predicted* purpose lands within one cost tier of routing the
/// *true* purpose, at every level and in every lane so a misclassification can never
/// cause the 12× overpay (or a hard task on a toy model) the feature exists to prevent.
/// *true* purpose (two for the documented pairs above), at every level and in every
/// lane so a misclassification can never cause the 12× overpay (or a hard task on a
/// toy model) the feature exists to prevent.
@Test func fixtureMisroutesStayWithinOneCostTier() throws {
for fixture in try PurposeFixtures.load() {
let predicted = HeuristicPurposeClassifier.classify(fixture.prompt).purpose
@@ -475,11 +541,12 @@ import Testing
let drift = abs(
IntelligenceRouter.costTier(of: routedPredicted.model)
- IntelligenceRouter.costTier(of: routedTruth.model))
let bound = twoTierDriftPairs.contains([predicted, truth]) ? 2 : 1
#expect(
drift <= 1,
drift <= bound,
"""
"\(fixture.prompt)": predicted \(predicted) vs true \(truth) drifts \
\(drift) tiers at \(level) with \(connected)
\(drift) tiers at \(level) with \(connected) (bound \(bound))
""")
}
}