This is the record of an abcd-managed repository

abcdBetav0.16.2 · 2026-11-06

Development record

abcd proposes the model each agent deserves, and facilitates it where it can

intentplannedminorstandaloneitd-2609170822093401

Press Release

abcd now ships its own proposal for which model tier each of its agents deserves, shows it, applies it once the operator accepts it, and makes a best effort to satisfy it — a local or cloud provider where one is configured and reachable, the harness otherwise, always. Today the oracle backend is one repo-wide value that nothing reads, and every delegated step reaches whatever model the harness picks at whatever it costs. The proposal is a table with one row per agent: a tier from a small closed set (local, economy, frontier, host-decides) that survives model churn, and a fan-out bound that may tighten the ceiling the agent's own trust contract declares but never raise it. Nothing is applied until it is accepted: the install step renders the proposal and writes it, on consent, as the machine's table under ~/.abcd.noindex/; a repository may commit its own rows at .abcd/config/oracle-routing.json, and a repo row wins over a machine row, which wins over the bundled proposal. Above all three sits a manual override for one invocation — --route <agent>=<tier>[@<connection>], repeatable, on every delegating verb — so an autonomous experiment can run the same agent across backends and configurations and read the outcome from receipts that name the override verbatim. A provider's sampling settings — temperature, seed, and whatever else that provider accepts — default on the connection, and a row or a --route may override them for one agent or one run; a setting a provider does not accept is refused by that provider's adapter, never dropped. At run time abcd resolves the winning row against the connections configured on the machine: a configured provider that is reachable and can serve the tier is used directly; otherwise the step goes to the harness with the tier named in its request, one line on stderr says so before the step runs, and the receipt records the tier asked, the connection tried, the connection used and the model the host or provider reported. A machine with nothing accepted behaves exactly as today. The proposal is the surface a later learner updates from measurements across repositories; this intent ships the best guess and the machinery that carries it.

"The release gate's semantic review and the cold reading's four positions were reaching the same model at the same price, and I could not say which steps I had actually read the output of," said Maya, AI/agent researcher. "abcd's proposal already had the split right — the verdicts I read at frontier, the rest at economy — and once I pointed it at the local server the economy rows ran there without my touching a row. The receipt shows me what ran next to what was asked." Dave, security engineer, put it more simply: "The row says local, and if the local server is down the receipt says the step went to the cloud instead. I would rather know than guess."

Why This Matters

Graduated from iss-2609170818061083. The host-delegated oracle (adr-25) made model access the host's problem, which was right, but it left abcd with no way to express which model an agent deserves or how much parallel work it may spawn, and the repo-wide oracle.backend the install step writes is read by no verb. Cost is undifferentiated: every delegated step is paid for as if it carried a verdict somebody reads. Privacy is undifferentiated: a step over sensitive material is routed like one over a public brief, so an operator with a local provider has no switch that sends the sensitive passes there. Fan-out is unbounded by anything the record can see.

The operator should not have to write this table from nothing. Which agents carry judgement a human reads and which are plumbing is a property of the agents, not of the repository, so abcd can propose the split and be right for most operators; what a machine can reach is a property of the machine, so the proposal is resolved against configured connections at run time rather than written into rows. Acceptance is the opt-in that adr-25 asks for: a configured provider and an accepted table are the operator's two acts, and after them abcd routes without asking. The host still owns model choice, credentials and execution on the harness leg, which is why this refines adr-25 rather than reversing it; on a provider leg abcd owns the connection, and that adapter's own intent (itd-2609081951381895) records what that means.

Two intents share the seam. The enforced half — every ingested payload must name its model and its agent count — is itd-2609180517121254, which this one builds on: the routing table is what those fields are checked against. Learned routing (itd-17) refines this: the proposal is the floor a learner adjusts from measurements across repositories, and the invocation-time override is how those measurements are taken — the same agent run under several routes, each receipt naming the route that governed it.

What's In Scope

  • The bundled proposal: one row per agent, tier and fan-out bound, shipped with the binary.
  • Rendering the proposal and writing it only on consent, at machine level (~/.abcd.noindex/) and, offered separately, at repository level (.abcd/config/oracle-routing.json); repo over machine over bundled.
  • Run-time resolution of the winning row against the machine's configured connections: provider where reachable and able to serve the tier, harness otherwise, the fallback announced on stderr and recorded on the receipt.
  • The closed tier vocabulary and the host-decides floor.
  • The request block carrying the tier and bound on the harness leg; the receipt carrying tier asked, connection tried, connection used and model reported.
  • An orphan row reported by name when a table is read.
  • The invocation-time override, --route <agent>=<tier>[@<connection>], repeatable, on every delegating verb: it wins over every layer for that run alone, and the receipt records it as an override so a measurement run is never mistaken for accepted routing.
  • Provider settings carried on a route: a connection's defaults, overridden per row and per --route, passed through to the provider and recorded on the receipt as sent.

What's Out of Scope

  • Requiring and refusing on the payload's model and agents_used fields — itd-2609180517121254.
  • The provider adapters themselves, how a connection is configured and probed, and which settings each provider accepts — itd-2609081951381895 and iss-2609081951416843; this intent resolves against whatever connections they establish and hands settings through, and the adapter refuses one its provider does not accept.
  • Updating the proposal from measurements — itd-17.
  • Enforcing a fan-out bound at ingest; here a row carries the number and the request block states it.
  • A lint rule over the tables; run-time reporting is the gate here.

Mechanism

  • We expect a routing row to change which model a harness-run step uses because the harness already exposes model selection to a sub-agent request, so a plainly stated tier in the request block is enough; shown wrong if receipts show the host ignoring the tier on a material share of runs.
  • We expect cost to fall without judgement suffering because the steps whose output a human reads are a small minority of delegated steps, so tiering the rest down changes nothing a person acts on; shown wrong if economy-tier outputs fail the ingesting verbs' schema gates or the audit verdicts drift.

Scope Conditions

  • Providers the operator configured at machine level: abcd never reaches a connection nobody set up, and a step on a machine with no provider runs through the harness whatever the row says.
  • Single-operator repositories: one person or one small team accepts the tables, and no claim is made about a table contested across many contributors.
  • Hosts that report the model used: on the harness leg the self-report is the only evidence, and a host that cannot name its model cannot be checked, so rows for it are advice with a receipt that says so.
  • Escalation applies to tier-routed reviewers only: the agent that writes each fix round has no level row and never escalates (Decision 6, the product thinker's ruling of 2026-10-23).

Decisions

Ruled by the product thinker on 2026-09-22, after the research pass on model routing:

  1. Escalation inside a lane is a rule, not a router. A lane starts at its role's tier; on a failed fix round the next round runs one tier up, and the switch is recorded as a fact in the state file with the round and the gate output that caused it.
  2. A route through a provider adapter must be on that provider's allowlist (adr-2609221009491186); the tier proposes only routes the resolver admits.
  3. No learned per-request router (itd-17 superseded by itd-2609221009495079).

Settled by the technical facilitator on the product thinker's delegation, relayed by the coordinator on 2026-10-22, each from this intent's own What's Out of Scope:

  1. A row's fan-out bound is carried, not enforced, until the payload names the agents it used. Out of Scope lists "Enforcing a fan-out bound at ingest; here a row carries the number and the request block states it". No verb reads the bound before itd-2609180517121254 gives the payload agents_used; resolution clamps it to the ceiling (internal/core/oracle/resolve.go) and the request block states it, as today.
  2. The proposal is held to the agent roster at run time and by a test, not by a lint rule. Out of Scope lists "A lint rule over the tables; run-time reporting is the gate here". An orphan row is reported at run time as a diagnostic (internal/core/oracle/store.go), and TestProposalNamesEveryAgentInTheRosterAndNoOther keeps the bundled proposal and agents/ in step both ways.

Ruled by the product thinker on 2026-10-23, relayed by the coordinator:

  1. Escalation covers tier-routed reviewers only. The agent that writes each fix round has no level row in the routing tables and never moves up a tier, and accepted tables are not offered a new row. A failed round's next round asks one tier up for each reviewer whose route resolves from a tier; a route that names no tier (a runner route, the reviewer route, a pointed role, host-decides, the fix agent) is recorded with the gate output and does not move. The scope condition saying so was stamped by abcd intent plan, which here carries the product thinker's direct answer of 2026-10-23, relayed by the coordinator, and changes nothing else on the intent.

Acceptance Criteria

  • Given a machine with no accepted table and a repository with no routing file, when any delegating step runs, then it runs through the harness at host-decides under the agent contract's own fan-out ceiling, and no provider is contacted.
  • Given the install step on a machine with no accepted table, when it runs, then it says abcd's proposal in counts (how many agents, how many at each tier, their fan-out bounds) and where every row can be read once accepted, and writes the table, one row per agent with tier and fan-out bound, under ~/.abcd.noindex/ only on consent; a repository-level file is offered separately and written only on consent.
  • Given an accepted row for an agent naming a tier, and a configured provider on this machine that is reachable and can serve that tier, when a step dispatching that agent runs, then abcd routes the step to that provider directly.
  • Given an accepted row for an agent, and no configured provider that is reachable and can serve its tier, when a step dispatching that agent runs, then the step goes to the harness with the tier and bound named in its request block, one line on stderr names the fallback and its reason before the step runs, and the receipt records the tier asked, the connection tried, and the connection used.
  • Given a step's payload is ingested, when the receipt is written, then it carries the tier requested, the connection used and the model reported, side by side, verbatim.
  • Given a repository file and a machine file that disagree on an agent, when a step dispatching that agent runs, then the repository row is the one resolved, and the bare abcd board shows all three layers for that agent with the winning row marked.
  • Given --route <agent>=<tier>[@<connection>] on a delegating verb, when a step dispatching that agent runs, then the flag's row is the one resolved regardless of the accepted tables, a second --route for a different agent applies alongside it, and the receipt records the route as an invocation override, verbatim; a --route naming an agent the verb does not dispatch, or a connection that is not configured, is refused before the step runs.
  • Given a connection carrying default provider settings, a row that overrides some of them, and a --route that overrides others, when a step resolves to that connection, then the settings sent are the connection's defaults with the row's overrides applied and then the flag's, and the receipt records the settings as sent; a setting the provider's adapter does not accept is refused before the step runs, never dropped.
  • Given a table carrying a row for a name that is not an agent in the roster, when the table is read, then the orphan row is reported by name on stderr and the remaining rows still apply.
  • Given a lane whose fix round failed, when the next round starts, then it runs one tier up from the role's tier and the state file records the round, the gate output and the switch.
  • Given a proposed route through a provider adapter, when the tier proposes it, then it is one the provider's allowlist admits, or the proposal names the refusal instead.

SOTA

Surveyed on 2026-10-23; sources, evidence tiers and the local fit risks are in the models, prompts and measurement SOTA note, which reuses the Jev and model-routing pass and the model-matrix note for everything the decisions already rest on.

  • The harness leg works as the Mechanism claims. The host's sub-agent docs resolve a model in a fixed order: per-invocation parameter, then the definition's model frontmatter (inherit means the main model), then a CLAUDE_CODE_SUBAGENT_MODEL default, then the main conversation's model; effort is settable on the same two surfaces (Claude Code sub-agents documentation).
  • A host force switch can override a row silently. CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1 makes the environment value beat both the frontmatter and the per-invocation parameter, and a mod's spawn hook can replace the parameter; CLAUDE_CODE_EFFORT_LEVEL in the environment likewise beats both the definition's and the per-invocation effort. The receipt's "model reported" beside "tier asked" is the only check (the third scope condition), and a mismatch that matches the force variable should be named as such.
  • Two-model cascades pay; deeper ones rarely do. Two-model cascades gained 2.1–8.2 points over single-model selection; allowing more than two models did not improve mean accuracy in 118 of 135 comparisons (at most +0.43 points); depth beyond two helped only when the deferral signal reflected whether the current model was wrong rather than difficulty shared across models (Bouchard, arXiv 2605.06350, 2026). Whether a failed fix round is a current-model-error signal or a shared-difficulty signal decides whether a second step pays; it is a plausible instance of the first, not a tested one, and the paper studies single-query cascades, not fix loops. Decision 1's one-tier-per-failed-round rule is consistent with this, and the matrix run is where a second step is tested.
  • Router benchmarking exists (RouterArena, arXiv 2510.00202), and nothing in it reopens decision 3.
  • Served versus asked stays as the matrix note has it: the receipt carries the served model, provider and fallback attempts where the source exposes them.

Path 2, as planned: a native table resolved onto the host's per-invocation model and effort parameters on the harness leg and onto a connection on the provider leg; the request-block mapping is the seam. No dependency. The independent fit-challenge is still owed before the build, and the questions below are kept for it.

Questions this pass raised for the fit-challenge before the build. They are kept here, not under Open Questions, so they do not hold a build the record already rules ready:

  • Whether a receipt whose reported model contradicts the tier asked, on a host where the force variable is set, is recorded as a host override by name, so a measurement run never mistakes a forced model for the row's.

Open Questions

  • Whether a fan-out bound on a row is read by any verb before itd-2609180517121254 gives the payload an agents_used field, or only carried in the request block until then.
    • Resolved: carried in the request block until then (Decision 4).
  • How the bundled proposal is versioned against the agent roster: an agent added without a row, or a row for an agent since removed, must be a lint finding on the payload rather than a run-time surprise.
    • Resolved: run-time reporting and the roster test are the gate, not a lint rule (Decision 5).
  • built on by itd-2610161733316518 (one feature built across a model matrix): Routes each copy through the per-invocation override, extended to name a runner and its model.

Audit Notes

  • 2026-10-03 — Acceptance criterion 2 says the proposal in counts rather than one row per agent. The product thinker ruled on 2026-10-03, answering "setup offers a plan giving each of abcd's 16 helpers a model level; with all listed it cannot fit" (options: counts only, split into parts, let it scroll, decide later), verbatim: "Show counts only". The written table is unchanged; only the question's text is (iss-2610031236155833).
  • 2026-10-02 — Declared mutual pair with itd-2609081951381895 (the technical facilitator's ruling CY2 of 2026-10-02, verbatim: "SAME, DECLARED PAIRS — each direction names the piece it needs"). itd-2609081951381895's builds_on itd-2609170822093401 needs the routing seam: the per-agent route and the invocation-time --route override that point a role or a judgement type at <provider>/<model>, the only ways a provider is reached (the adapter's decision 9). itd-2609170822093401's builds_on itd-2609081951381895 needs the provider connections its winning rows are resolved against, and the adapter's refusal of a setting its provider does not accept (its out-of-scope list names the adapter for both). Both edges stand. The record has no field record-lint's edge_cycle rule reads as a declared pair, so the linter still reports the cycle at warn until it does (iss-2610020836255174). Each piece is read from the two records' own scope, criteria and decisions; the ruling names none. Recorded by lane rd2 of autonomous run A.

Linkage note (2026-09-30)

builds_on named itd-2 (in-session subagent dispatch), which is superseded by itd-2609201916056194. The edge is dropped rather than relinked: itd-2's supersession hands the repo-wide oracle backend it keyed on to this record, and itd-2609201916056194 declares builds_on this record, so the relinked edge would run against the dependency the successor already states and close a cycle.

Grounds

  • pursued: flexibility first — each delegated step routed to the model it deserves, with privacy as an option (a local model where the material must not leave the machine) and cost as the essential lever: abcd proposes the split between judgement-bearing and plumbing steps, the operator accepts it once, and abcd facilitates it where a configured provider can serve the tier, the harness always the fallback; sub-agent fan-out declared and bounded per agent, because unbounded fan-out is where cost and unpredictability come from. Shown wrong if the locally-routed or bounded steps start failing the binary's schema gates or their verdicts drift from the frontier-routed ones, if accepted tables diverge widely from the proposal, or if bounded runs cost the same and vary as much as unbounded ones.

Frontmatter

iditd-2609170822093401
typeintent
lifecycleplanned
kindstandalone
severityminor

References4

Referenced by25

mentions17