-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrouting.yaml
More file actions
228 lines (221 loc) · 13.6 KB
/
Copy pathrouting.yaml
File metadata and controls
228 lines (221 loc) · 13.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# Eidolons Routing Data — machine-readable cortex
# ────────────────────────────────────────────────
# Single source of truth for `eidolons run` — the mechanical routing kernel.
# This file makes the EIDOLONS.md descriptor table + dispatch protocol
# DETERMINISTIC: the kernel reads these fields and table-matches, rather than a
# host LLM interpreting prose. Mirrors EIDOLONS.md §"Roster Index" and
# §"Dispatch Protocol"; `eidolons doctor --deep` is the planned drift gate.
#
# Schema: ../schemas/routing.schema.json
# Sibling to roster/index.yaml (the member registry) and roster/mcps.yaml.
#
# Invariant I-C6: same prompt + same context + same routing data ⇒ same routing.
# Invariant I-C2: this is DATA. The kernel interprets it; there is no eval.
#
# Model tiers: the SOLE tier source is this file (single source of truth).
# Vendor model strings live ONLY in roster/model-profiles.yaml (PD #162).
# Tier ladder: light < standard < deep.
routing_version: "1.1"
updated_at: "2026-07-05T20:45Z"
# ─── Gate thresholds (Dispatch Protocol Step 2 / TRANCE Step 4) ─────────────────
thresholds:
tau_standard: 0.6 # min top-score to dispatch a single Eidolon (OQ-2)
tau_trance: 0.8 # min score that, WITH a stakes flag, may escalate tier
chain_floor: 0.6 # min score for a second Eidolon to co-trigger a chain
max_reroutes: 2 # OQ-6 reroute cap (anti ping-pong)
max_parallel: 5 # TRANCE cost ceiling C1
surface_files: 25 # large-surface complexity flag (C5)
surface_modules: 5
# ─── TRANCE model-tier split (EIDOLONS.md §TRANCE) ───────────────────────────
# lead_tier / workers_tier are vendor-neutral tier words (light|standard|deep).
# Computed artifact data — replaces the EIDOLONS.md §TRANCE prose "model-tier
# upgrade (lead=deep, workers=light)". The kernel surfaces model_tier_lead /
# model_tier_workers on the artifact only when tier == "trance" (fail-open:
# absent block → fields omitted, not defaulted).
trance:
lead_tier: deep
workers_tier: light
# ─── Class-level tier defaults ───────────────────────────────────────────────
# Used by the model resolver when a given Eidolon has no per-id suggested_tier.
# 'default' applies to unknown / future capability classes.
classes:
default:
suggested_tier: standard
# ─── Per-Eidolon routing descriptors (mirror EIDOLONS.md trigger/refuses) ───────
# suggested_tier: vendor-neutral tier (light|standard|deep). The active profile
# in roster/model-profiles.yaml maps tier → concrete model string.
# score = (# distinct trigger phrases matched in the prompt). Refusal is checked
# against refuse_verbs.
eidolons:
atlas:
capability_class: scout
suggested_tier: standard
trigger_verbs: ["map", "trace", "find where", "who calls", "call graph", "list entrypoints", "entrypoints", "audit", "explore", "where is", "scout", "understand the codebase", "make sense of"]
refuse_verbs: ["implement", "fix", "edit", "write", "commit", "deploy", "migrate", "refactor", "patch"]
downstream: ["ramza", "vivi", "idg"]
ramza:
capability_class: planner
suggested_tier: deep
default_for_class: planner # Stage 3b — the default planner seat (measurement-validated:
# pre-registered A/B non-inferior 6/6 vs spectra 6/6, holdout-consistent,
# 0 MUST failures over 24 cells, 2026-07-05). Mechanized gates
# (right-size, rubric, EARS lint, SHA-256 freeze, drift, maker≠checker).
fallback: spectra # declared conservative peer for the host-tier fallthrough gate
# (routing.yaml is DATA; I-C2 — the kernel interprets, no eval)
trigger_verbs: ["spec", "plan", "decompose", "clarify requirements", "given/when/then", "decision-ready", "design", "requirements", "scope the work"]
refuse_verbs: ["implement code", "modify files", "write the code"]
downstream: ["vivi", "idg"]
spectra:
capability_class: planner
suggested_tier: deep
# conservative prose-methodology fallback; opt-in (`eidolons add spectra`);
# named dispatch still routes to it (the +0.5 name bonus). RAMZA holds the
# default planner seat via default_for_class above.
trigger_verbs: ["spec", "plan", "decompose", "clarify requirements", "given/when/then", "decision-ready", "design", "requirements", "scope the work"]
refuse_verbs: ["implement code", "modify files", "write the code"]
downstream: ["apivr", "idg"]
vivi:
capability_class: coder
suggested_tier: standard
loop_native: true # drives `eidolons sandbox loop`; host-adaptive shape
# (iterate on thinking hosts / fanout on standard hosts)
default_for_class: coder # Stage 3b — the default coder seat (measurement-validated:
# fanout pass^2 1.00 vs APIVR-Δ 0.67, weak-host adversarial suite)
degraded_mode: fanout # loop-shape on weak/undeclared hosts (replaces the
# prose-only "degrade to APIVR-Δ")
fallback: apivr # declared conservative peer for the S1.7 host-tier
# fallthrough gate (routing.yaml is DATA; I-C2)
trigger_verbs: ["implement", "build", "fix", "extend", "wire up", "make tests pass", "add a", "add the", "patch", "code"]
refuse_verbs: ["design from scratch", "novel architecture", "greenfield"]
downstream: ["idg"]
apivr:
capability_class: coder
suggested_tier: standard
loop_native: false # conservative non-loop fallback; opt-in (`eidolons add apivr`);
# named dispatch still routes to it (the +0.5 name bonus)
trigger_verbs: ["implement", "build", "fix", "extend", "wire up", "make tests pass", "add a", "add the", "patch", "code"]
refuse_verbs: ["design from scratch", "novel architecture", "greenfield"]
downstream: ["idg"]
idg:
capability_class: scriber
suggested_tier: light
trigger_verbs: ["document", "adr", "runbook", "chronicle", "synthesize", "record decisions", "write the docs", "changelog narrative"]
refuse_verbs: ["explore repo", "find calls", "retrieve", "analyze code"]
downstream: []
forge:
capability_class: reasoner
suggested_tier: deep
degraded_mode: sample-select # N-sample deliberation + rubric-agreement selection
# on weak hosts (sampling replaces unreliable
# single-trace self-correction)
trigger_verbs: ["trade-off", "tradeoff", "which approach", "should we", "ambiguous", "counterfactual", "deliberate", "x or y", "decide between"]
refuse_verbs: ["implement", "retrieve", "synthesize prose"]
downstream: []
vigil:
capability_class: debugger
suggested_tier: deep
trigger_verbs: ["root cause", "flaky", "heisenbug", "regression after", "post-mortem", "postmortem", "why does this fail", "why does it fail"]
refuse_verbs: ["build new feature", "plan from scratch"]
downstream: []
kupo:
capability_class: executor
suggested_tier: light
# NARROW by design: only clearly-localized micro-task verbs, so the router never
# poaches APIVR-Δ/Vivi coding work. Kupo is orchestrator-dispatched (subagents cannot
# spawn subagents); the localized_micro_task signal boosts Kupo over the coder when
# a fix-family verb co-occurs with a localized-task marker (+0.15 → 0.95 > 0.8).
escalation: # verifier-failed micro-task escalates once to the coder;
on_fail: reroute # the kernel only SURFACES this data in the artifact —
reroute_to: vivi # execution belongs to the orchestrator/sandbox.
max_escalations: 1
trigger_verbs: ["rename symbol", "import fix", "fix the import", "path fix", "bump lockfile", "pin dependency", "pin the version", "autofix lint", "format fix", "one-line fix", "single-line edit", "update fixture", "update snapshot", "grep-replace", "search-replace", "config key edit", "fix the typo", "fix the path"]
refuse_verbs: ["design", "cross-cutting refactor", "refactor across", "plan", "novel architecture", "greenfield", "open-ended", "loop-native campaign", "implement feature"]
downstream: []
gilgamesh:
capability_class: generalist
suggested_tier: standard
# ESL change generalist-eidolon (R-004/R-005/R-019): NO positive
# trigger_verbs by design — a fallthrough-only worker that MUST never
# enter Step-1 classification or outrank a specialist scoring >= tau.
# It is dispatched solely via Dispatch Protocol Step-2(a) (S6=no
# specialist >= tau, S7=no chain, then the presence-based S1..S5
# predicate over closed lexicons — methodology/cortex/dispatch-predicate.md).
# Even a NAMED mention ("Gilgamesh, ...") only earns the +0.5 name bonus
# on a raw=0 base (score 0.5 < tau_standard 0.6), so it still cannot
# win Step-1 through this kernel — a second, independent guarantee of
# R-019 beyond the empty trigger_verbs array.
trigger_verbs: []
# refuse_verbs tile the specialist space (one representative phrase per
# routed capability class) + deploy/migrate (irreversible-without-checker,
# R-009 sandbox-first/PROPOSE-only) + routing/spawning (HC8 — worker,
# never router) + underspecified/ambiguous scope (R-020 — still clarify).
refuse_verbs: ["design", "design from scratch", "novel architecture", "spec", "plan", "decompose", "map the codebase", "trace calls", "audit read-only", "document", "runbook", "chronicle", "trade-off", "which approach", "deliberate", "root cause", "flaky", "heisenbug", "rename symbol", "lockfile bump", "deploy", "migrate", "route to another eidolon", "spawn subagents", "underspecified", "ambiguous scope"]
downstream: []
# ─── Confidence signals (Dispatch Protocol §"Confidence Signals") ───────────────
# Applied additively to the matched Eidolon's score. `stakes: true` marks a
# signal as a TRANCE stakes-flag contributor (does not by itself escalate tier).
# Boosts are in score-space (added to base; final compared uncapped, displayed
# capped at 1.0). stack_trace / prior_apivr_failure are DECISIVE (≥ tau_standard
# alone and dominate a competing 'fix' verb) to honour V9/V5, which the cortex
# prose under-weights at +0.3.
signals:
- id: stack_trace
match: ["stack trace", "traceback", "panic", "segfault", "still failing", "after retry", "fails after"]
boost: { vigil: 0.9 }
note: "stack trace / repeat failure → VIGIL fast-path (V9)"
- id: prior_apivr_failure
match: ["tried to fix", "already tried", "reflect exhausted", "still broken after"]
boost: { vigil: 0.95 }
note: "prior failed APIVR-Δ attempt → VIGIL (V5)"
- id: greenfield
match: ["greenfield", "from scratch", "brand new project", "novel architecture"]
boost: { vivi: -0.4, apivr: -0.4 }
note: "the coder class refuses greenfield (Vivi and APIVR-Δ alike)"
- id: no_spec_yet
match: ["don't have a spec", "no spec yet", "i don't know the call graph", "not sure what to build"]
boost: { ramza: 0.2 }
- id: large_surface
match: ["entire monorepo", "whole codebase", "all modules", "across all"]
boost: { atlas: 0.2 }
stakes: true
note: "large surface → ATLAS-TRANCE candidate (V2)"
- id: localized_micro_task
# Kupo-vs-coder tiebreak (executor precedence). The `fix`-family verbs
# (fix the import / one-line fix / fix the typo) tie Kupo with Vivi/APIVR-Δ
# at 0.8 because the coder matches the bare word `fix`. When a LOCALIZED
# micro-task marker co-occurs, prefer the executor: boost Kupo by +0.15
# (0.8 -> 0.95, clears the coder's 0.8) while staying below the +0.5
# name bonus, so "Vivi, fix the import" still routes to Vivi.
# Pure DATA (I-C2): the kernel sums this boost; there is no eval.
match: ["import", "lockfile", "lint autofix", "typo", "rename", "one-line", "single-line", "fixture", "snapshot", "dependency pin", "pin the version", "grep-replace", "search-replace", "path fix", "config key"]
boost: { kupo: 0.15 }
note: "localized micro-task marker → prefer the executor over the coder (Kupo-vs-Vivi tiebreak)"
# ─── Chain templates (EIDOLONS.md §"Chain Templates") ───────────────────────────
# Selected when ≥2 capability classes co-trigger. `requires_classes` lists the
# capability classes whose presence selects this template; the kernel picks the
# most specific (longest requires_classes) matching template.
chains:
- name: plan-before-build
steps: ["atlas", "ramza", "vivi", "idg"]
requires_classes: ["scout", "planner", "coder"]
when: "Unfamiliar code + multi-component change"
- name: decide-then-implement
steps: ["forge", "ramza", "vivi"]
requires_classes: ["reasoner", "coder"]
when: "Should we use X or Y, then build it"
- name: audit-without-touching
steps: ["atlas", "idg"]
requires_classes: ["scout", "scriber"]
when: "Audit/explain/review with no write intent"
- name: ship-fast
steps: ["ramza", "vivi"]
requires_classes: ["planner", "coder"]
when: "Known terrain, scoped feature"
- name: forensic-then-fix
steps: ["vigil", "vivi"]
requires_classes: ["debugger", "coder"]
when: "Bug with reproduction + verified patch"
- name: scout-then-spec
steps: ["atlas", "ramza"]
requires_classes: ["scout", "planner"]
when: "Discovery + spec verbs co-occur (V3)"