Research / Agents and LLMs

P63 · full · draft

Models as Placeable, Checked Effects: Route Conditions and a Council That Never Fabricates Consensus

partial full Agents and LLMs

State of the work. Declaration, placement ceiling, answer type, per-member inputs, a self-host port and a partial formal row are on main with test suites; no runtime aggregator exists and nothing has been evaluated on users or benchmarks.

This is a draft, not peer reviewed. Repository references link to revl at commit 45bec431f.

Planned to be combined with P62 (One Type, Three Consumers: A Typed Model Boundary Compiled to Schema, Decode Grammar and Retry Budget) into a single paper.

Pitch

If a model call is a capability-typed crossing that must be placed on a declared role, then, for a component that declares placement, "this confidential input never reaches a cloud model" is a compile-time fact, and a council whose disagreement case has no answer field cannot be made to resolve a split toward allow.

Abstract

Agent systems choose which model answers a request in host configuration, so a checker that reads the program alone cannot say where a confidential value is sent, and "several models agreed" is a convention a caller trusts. We present two checked constructs in revl, a language with a capability-typed effect boundary. First, route model on <action> places an action's model calls on declared roles by the origin class of what the action receives. The block is a permission checked at admission, not a scheduler: a confidential origin routed to an off_device role is refused naming the action, the origin and the role, and the value-level ceiling refuses a confidential value that reaches a model crossing through no on-device arm; the exercised cases include a helper-function seam, and coverage of every path is not claimed. A role may also declare the capabilities a call to it can reach, which enters the attenuation product, so a model is accounted as an authority surrogate rather than as inert. Second, a model council binds role-placed members under an aggregation word from a closed vocabulary. The council's result type has a Split constructor that carries digests of the members' answers and no value of the answer type, so there is no total projection from the result to an answer. Admitting on a tie, counting the floor over responders rather than declared members, a non-total aggregation, and two members on one placement are refused under one guarantee code. We report the rule sets (13 council rules, raised at 22 sites in the checker, and 11 placement declaration rules), the test suites that pin them, and a Lean model of the tie rule. We also state what is not shown: no runtime aggregator exists, on_device is a declared claim, and no user study or benchmark has been run.

Problem and claim

In current agent frameworks and routers the model behind a call is decided by configuration the program cannot see. docs/design/531-model-placement.md:48-75 lists the three questions a checker cannot be asked: whether a confidential input went to a cloud model, whether a component never leaves the device, and which model produced a value. Ensembles have a parallel problem. Self-consistency, judge models and debate return one answer, and the code that consumes it cannot tell a unanimous result from a tie broken by taking the first member.

The claim has two halves, each narrow. (1) Placement of a model call can be a permission that the compiler checks against the origin lattice (docs/design/249-taint-provenance.md, cited from 531), and the check fails closed: an unrouted action in a routed component, a confidential origin with no arm, and an off-device arm all refuse (src/revl/model_route.py:964-1000). (2) For a council, the property "disagreement is never resolved toward allow" can be made a property of the types and of a closed rule vocabulary instead of a review convention: Split carries no T (docs/design/543-model-council.md:156-166), the floor is counted over declared members (543:272-292), and spellings that read as safety features (on_tie allow, quorum answered, aggregate first) parse so the refusal can say why (543 section 8).

The paper does not claim that a council improves answer accuracy, that on_device matches a physical fact, or that any runtime computes an Aggregate. docs/design/543-model-council.md:524-531 says the last one in so many words.

Contributions

  1. route model and model role: a placement permission keyed by the origin lattice, with 11 declaration refusals and one value-side ceiling that uses a single admitting path for a confidential value (docs/design/531-model-placement.md:141-170, 210-250; tests/test_model_placement_512.py, tests/test_model_ceiling_514.py).
  2. A closed sum Answer[T] and Aggregate[T] whose Split and Inquorate constructors carry digests, with a match-exhaustiveness rule, so no total projection to T exists (src/revl/model_answer.py:26-60, 388; docs/design/543-model-council.md:128-190).
  3. A council declaration with 13 rules (raised at 22 sites in model_council.py) that each name a safe-looking spelling, split across two guarantee codes by a one-sentence rule: G-MODEL-PLACE when the subject is a role, G-COUNCIL-SPLIT otherwise (docs/design/557-council-disagreement.md:94-134; src/revl/model_council.py:137-150, 575-600).
  4. Per-member origin ceilings: a council's ceiling for an origin is the join over members that receive it, so a local adversary can read what a cloud proposer cannot (docs/design/543-model-council.md:327-404; src/revl/model_council.py:263).
  5. A model role enters the capability attenuation product through reaches [...] (docs/design/541-model-in-attenuation.md:25-40; tests/test_model_attenuation_519.py).
  6. A Lean model RevL.ModelCouncil.SplitOK bridged to the checker's verdict on the tie rule, and RevL.ModelPlace.PlaceOK for placement, both with a differential corpus (formal/RevL/Theorems/ModelCouncil.lean:16-91 for SplitOK; formal/RevL/Theorems/ModelPlacement.lean:34-108 for PlaceOK; formal/STATUS.md:58-59, 389-394).

Evidence on main

Claimpath:line or testStatusNote
model role NAME on_device/off_device and route model on <action> { origin -> role }docs/design/531-model-placement.md:76-117; tests/test_model_placement_512.py (19 test functions; doc says 19 tests)shippedContextual identifiers, no lexer change
Confidential origin routed to an off_device role refused naming action, origin, roledocs/design/531-model-placement.md:174-208; tests/test_model_ceiling_514.py:117-140shipped
Value-side ceiling, one admitting path, verdicts unrouted/unplaced/off_devicesrc/revl/model_route.py:964-1000; docs/design/531-model-placement.md:210-250shippedFires only for confidential; secret is judged elsewhere (531:273-281)
Ceiling survives a helper-fn seamdocs/design/531-model-placement.md:282-288 (models_at)shipped531:628-648 (section 10) says what is not verified and what is exercised, and claims no completeness
Placement is a permission, no IRdocs/design/531-model-placement.md:299; tests/test_1311_model_routes_not_in_ir.pyshipped
Council declaration, 13 rules (22 raise sites in model_council.py)src/revl/model_council.py:137-150, 575-600; docs/design/543-model-council.md:437-480; tests/test_model_council_516.py (77 test functions)shippedThe doc later says 17 refusals are ported to the gate (543:758-768, 556)
Split carries no answer; digests onlysrc/revl/model_answer.py:26-60; docs/design/543-model-council.md:156-166shipped (types)
Match must name Split and Inquoratesrc/revl/model_answer.py:388; docs/design/543-model-council.md:713-735shippedMeasured on a commit hash in the doc: 1 of 6 programs admits, 5 refused
Floor counted over declared memberstests/test_model_council_516.py:422-433 (floor == 3, == 2)shipped (static value)The number is computed; nothing asks members at run time
G-COUNCIL-SPLIT code, fix line, tier-matrix rowdocs/design/557-council-disagreement.md:41-60, 262-318; tests/test_council_disagreement_1190.py (31 test functions)shipped
Per-member reads <origin>, per-origin ceilingdocs/design/543-model-council.md:327-404; src/revl/model_council.py:263shipped
Self-host port of council refusalsdocs/design/556-model-council-selfhost.md; docs/design/543-model-council.md:758-768shipped
Formal: tie rule SplitOK, placement PlaceOKformal/RevL/Theorems/ModelCouncil.lean:16-91 (SplitOK); formal/RevL/Theorems/ModelPlacement.lean:34-108 (PlaceOK); tests/test_formal_council_split_1811.py (11 test functions); tests/test_formal_model_place_1811.py (10); formal/STATUS.md:58-59partialSTATUS says the row is deliberately silent on the other council refusals and on the value-level ceiling
Model role in attenuation productdocs/design/541-model-in-attenuation.md:25-40; tests/test_model_attenuation_519.py (19); src/revl/lower.py:9176-9198shippedSlice status in 541 is mixed ("slice 5 is partial")
A runtime that asks members and computes an Aggregatedocs/design/543-model-council.md:524-531not presentStated as a non-goal

Numbers that exist

Paper outline

  1. Introduction: model choice is invisible to checkers; consensus is a convention.
  2. Background: revl capability boundary, origin lattice, residence bit.
  3. Placement: model role, route model, the permission vs. scheduler argument, 11 refusals, fail-closed verdicts.
  4. The value ceiling: one admitting path, helper seam, why secret is not judged here.
  5. The council: Answer/Aggregate, Split without a payload of type T, digests, floor over declared, abstain vs block, Inquorate vs Split.
  6. Per-member inputs and the ceiling join; role reach in attenuation.
  7. Refusing safe-looking spellings: the 13 rows and the two-code rule.
  8. Evaluation: rule suites, non-vacuity runs, differential corpus, Lean model, plus a corpus study and runtime experiments still to be done.
  9. Related work and limits.

Threats to validity and limits

Fact-check

Claims in this draft were checked against revl main at commit 45bec431f: 24 checked, 6 corrected.

Cite this draft

@misc{revlp63,
  author       = {Thomas Moussajee},
  title        = {Models as Placeable, Checked Effects: Route Conditions and a Council That Never Fabricates Consensus},
  year         = {2026},
  howpublished = {\url{https://inso1337.github.io/revl/research/P63.html}},
  note         = {Research draft, not peer reviewed. Written against revl commit 45bec431f. Licensed CC BY 4.0.}
}

Text licensed CC BY 4.0, author Thomas Moussajee.

← All research drafts