Problem / motivation
Capability-routed delegation can only route down. delegate(task="code") resolves to the
cheapest can_delegate backend advertising code, which — on any roster where the free local model
lists code — is always the local model, regardless of how hard the sub-task is.
That is correct and desirable for grunt work, and it is the behavior that makes TangleBrain cheap by
default. It becomes a limitation the moment a coordinator wants to express "this sub-task is hard,
send it somewhere better." Today the only way to say that is to name a backend id explicitly, which
moves the routing decision out of config and into the orchestrator's prompt — the thing capability
routing exists to avoid.
Current behavior
_select_by_capability (tanglebrain/delegate.py:184-212):
candidates = [e for e in roster.delegate_targets() if e.tier in TIER_RANK and task in e.good_at]
return min(candidates, key=lambda e: TIER_RANK[e.tier])
TIER_RANK = {"local": 0, "sub": 1}, so local always wins a tie on capability. api is excluded
outright. The result: capability is a filter, and cost is the only ranking signal.
Proposed behavior
A way for the caller to express a minimum quality bar alongside the capability, so the cheapest
eligible backend is still chosen — just from a smaller eligible set. Rough shape, naming open:
delegate(prompt, task="code", min_tier="sub")
Design questions that need answers before this is buildable:
- Is tier the right axis?
tier currently encodes how it is invoked and paid for
(local / sub / api), not how capable it is. Overloading it to mean quality conflates two
independent things — a strong local model on good hardware may beat a weak subscription CLI. A
separate capability-strength field may be more honest, at the cost of another thing to keep
accurate in config.
- Who decides a sub-task is hard? If the orchestrator asserts
min_tier, the guarantee is only
as good as the model's self-assessment, and the natural failure mode is upward drift — every
sub-task claims to be hard and the cost floor quietly disappears. If config decides, it needs a
signal it does not currently have.
- What happens when nothing meets the floor?
NoDelegateFit already means "handle it yourself,
you are the most capable thing available," which is probably the right answer here too — but that
should be a deliberate decision, not a fallthrough.
Alternatives considered
- Name the target id explicitly. Works today, needs no change, and is the right escape hatch —
but it hardcodes roster ids into orchestrator prompts, so swapping a backend means editing prompts
instead of editing config.
- Reverse the default to most-capable-first. Rejected. It inverts the project's whole premise and
would make spend-avoided collapse silently.
- Let the classifier score sub-tasks. Reuses machinery that already exists
(tanglebrain/classifier.py) and takes the judgment away from the delegating model. Costs a
classifier call per delegated sub-task, which may exceed what it saves on short ones.
Scope notes
- This touches a ratified invariant. "Paid is last resort, never preferred" is documented at
delegate.py:41-44 and enforced by TIER_RANK omitting api. Any floor mechanism must not become
a path to auto-selecting a paid backend — the api exclusion should survive whatever lands here.
Treat that as a constraint on the design, not a detail to settle during implementation.
- Needs new code in
delegate.py and a change to the delegate MCP tool schema.
- Worth building after the coordinator-preference work: the value only shows up once a
designated coordinator is actually fanning work out across a heterogeneous fleet, and real usage
should inform whether the axis is tier, strength, or something else.
Additional context
Third of three gaps found while designing a coordinator-plus-fleet setup. The other two are plumbing;
this one is a genuine design decision, and deliberately filed without a recommended answer.
Problem / motivation
Capability-routed delegation can only route down.
delegate(task="code")resolves to thecheapest
can_delegatebackend advertisingcode, which — on any roster where the free local modellists
code— is always the local model, regardless of how hard the sub-task is.That is correct and desirable for grunt work, and it is the behavior that makes TangleBrain cheap by
default. It becomes a limitation the moment a coordinator wants to express "this sub-task is hard,
send it somewhere better." Today the only way to say that is to name a backend id explicitly, which
moves the routing decision out of config and into the orchestrator's prompt — the thing capability
routing exists to avoid.
Current behavior
_select_by_capability(tanglebrain/delegate.py:184-212):TIER_RANK = {"local": 0, "sub": 1}, solocalalways wins a tie on capability.apiis excludedoutright. The result: capability is a filter, and cost is the only ranking signal.
Proposed behavior
A way for the caller to express a minimum quality bar alongside the capability, so the cheapest
eligible backend is still chosen — just from a smaller eligible set. Rough shape, naming open:
Design questions that need answers before this is buildable:
tiercurrently encodes how it is invoked and paid for(local / sub / api), not how capable it is. Overloading it to mean quality conflates two
independent things — a strong local model on good hardware may beat a weak subscription CLI. A
separate capability-strength field may be more honest, at the cost of another thing to keep
accurate in config.
min_tier, the guarantee is onlyas good as the model's self-assessment, and the natural failure mode is upward drift — every
sub-task claims to be hard and the cost floor quietly disappears. If config decides, it needs a
signal it does not currently have.
NoDelegateFitalready means "handle it yourself,you are the most capable thing available," which is probably the right answer here too — but that
should be a deliberate decision, not a fallthrough.
Alternatives considered
but it hardcodes roster ids into orchestrator prompts, so swapping a backend means editing prompts
instead of editing config.
would make spend-avoided collapse silently.
(
tanglebrain/classifier.py) and takes the judgment away from the delegating model. Costs aclassifier call per delegated sub-task, which may exceed what it saves on short ones.
Scope notes
delegate.py:41-44and enforced byTIER_RANKomittingapi. Any floor mechanism must not becomea path to auto-selecting a paid backend — the
apiexclusion should survive whatever lands here.Treat that as a constraint on the design, not a detail to settle during implementation.
delegate.pyand a change to thedelegateMCP tool schema.designated coordinator is actually fanning work out across a heterogeneous fleet, and real usage
should inform whether the axis is tier, strength, or something else.
Additional context
Third of three gaps found while designing a coordinator-plus-fleet setup. The other two are plumbing;
this one is a genuine design decision, and deliberately filed without a recommended answer.