Skip to content

feat: route the drain's eligibility judgement through a decision adapter, with shadow pairs a lab harvests - #1245

Queued
REPPL wants to merge 20 commits into
mainfrom
build/run-2610290450515187-lane-1
Queued

REPPL wants to merge 20 commits into
mainfrom
build/run-2610290450515187-lane-1

Conversation

@REPPL

@REPPL REPPL commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator

This lands the first part of the decision adapter intent.

A small model can now answer one of abcd's closed-option judgements beside the host, or in its place, with a value and a probability.

What a person sees

  • One interface for typed judgements. Each judgement type in the registry (twelve) is a question with closed options: choose, score, or yes/no. The host or a decision adapter answers it with a value and a probability. Embark's lesson ranking is among the registered types.

  • A route per type, in three modes. A type's route is set under oracle.judgements.<type>:

    • host is the default.
    • shadow:<provider>/<model> keeps the host's answer and records the adapter's answer beside it.
    • The bare <provider>/<model> hands the decision to the adapter.

    A repository's .abcd/config.json may keep a type on the host or put it in shadow. Only the person's own ~/.abcd.noindex/config.json turns a type on, and a repository's turned-on route is skipped with a diagnostic. Every route, shadow included, passes the provider's model list and the denylist before any call.

  • The drain's eligibility judgement goes through it.

    • On the host, the drain behaves as before.
    • In shadow, the host's answer stands, and the pair (both answers, the probability and a state hash) is appended to pairs.jsonl in the newest lab home. Nothing is written in the repository.
    • A state larger than the model's window is recorded as a skipped pair.
    • Turned on, the adapter's answer goes through the same checks as the host's answer, and the drain's record names the route. An adapter that cannot answer leaves the host's request standing, and a fallback receipt is kept. The adapter is asked at most once per request.
  • abcd lab harvest reports agreement per type. It gives pairs, compared, agreed and skipped counts, a rate, and four probability bands, plus the line a research note carries to turn a type on. It reads the pairs a line at a time, so a large file does not stop the harvest.

  • abcd ahoy connect for a keyless provider offers a judgement type the shadow: spelling in either file, and says the bare spelling turns a type on only from the person's own machine file. ahoy --providers spells a shadow route with its prefix.

Not in this change

  • Embark's lesson ranking is registered but not yet routed through the adapter. It stays in scope as a real judgement and is the intent's next step. So the spec stays open, the intent stays planned, and this change carries no Delivers:.
  • The other judgement types are made in host command pages that hand nothing back to the binary. They stay on the host whatever their route says until their steps call the router. The pages say so.

Checks

  • Each mode is driven through a real drain move with a fake adapter, and each new test was watched fail first.
  • The harvest reads a pairs file past the 4 MiB document bound.
  • make preflight passed on the head, 6d1e887.
  • The build loop's review rounds passed: in the last round every reviewer said ship, and the audit judged no criterion not met.

Resolves: iss-2610262037348735
Refs: itd-2609221009495079
Refs: iss-2610262033055327

Assisted-by: Claude:claude-opus-5-5

REPPL added 20 commits October 29, 2026 04:57
The packages line carried prose (the OpenAI-compatible client adapter,
callers across capture, intent, memory and lint), which a reservation
would take literally. It now names the paths the build changes.

Refs: iss-2610241549334990
Assisted-by: Claude:claude-opus-5-5
oracle.judgements.<type> now takes host, shadow:<provider>/<model> or
<provider>/<model>. A shadow route passes the same skips, allowlist and
denylist as one turned on, when the configuration is read and before any
call; host keeps the type on the host and points it nowhere.

Assisted-by: Claude:claude-opus-5-5
… agreement

A shadow pair (host answer, adapter answer, probability, state hash and
size) is appended to pairs.jsonl in the newest lab home of the
repository's lane, never in the repository. lab harvest reads it back as
agreement per judgement type with counts, skips and four probability
bands, plus the line a research note carries naming the lab home and the
count. The lab chapter now describes the computed section.

Resolves: iss-2610262037348735
Assisted-by: Claude:claude-opus-5-5
…adapter

The judge package is the decision adapter's interface: a typed
question (choose, score, yes/no) over a state, answered with a value
and a probability. The host and the API adapter both implement it, and
a router switches each judgement type by configuration alone: host;
shadow, where the host decides and the pair is recorded in the newest
lab home, skipped with its size when the state exceeds the window; or
on, where the adapter decides and an adapter that cannot answer falls
back to the host with a receipt. The allowlist is judged when the
configuration is read, before any call.

Assisted-by: Claude:claude-opus-5-5
…ent types

The embark page ranks retrospective lessons by term overlap against the
new voyage's brief, a deterministic computation with no host answer to
pair, so it cannot run in shadow or be turned over. The intent's two
lists no longer name it and the judge registry never held it. Recorded
as facilitator-on-delegation: a factual correction to the intent's
scope, accepted by the run's coordinator.

Resolves: iss-2610262033055327
Assisted-by: Claude:claude-opus-5-5
…t agreement

The configuration chapter gives oracle.judgements' three modes, the
judgement type registry and the drain's eligibility-residual routes; the
adapters chapter gains the decision adapter; the lab command page says
what the harvest's agreement carries and that turning a type on is the
user's decision.

Assisted-by: Claude:claude-opus-5-5
No judgement step calls the router yet: the drain's call is a later
change and the other types' judgements are made in command pages. The
configuration and adapters chapters now say so instead of describing the
drain's routes as running.

Assisted-by: Claude:claude-opus-5-5
The drain's judgement over a remedy is the typed judgement
eligibility-residual: no, user-visible or trust-rule. shadowDrainJudgement
records the adapter's answer beside a taken judgement when the type is
in shadow; decideDrainJudgement asks the adapter when it is turned on,
takes its answer as a routed judge's under the same disposition rules
with the route naming the adapter and model, and returns a fallback
receipt, the host's request standing, when it cannot answer. The call
from the drain's move is left for a change that holds drain.go.

Assisted-by: Claude:claude-opus-5-5
The reach audit refuses an exported core function no production code
outside its package calls: render, known and types are unexported, the
router's constructor is newRouter with NewForTest as the loop tests'
seam, and the unused Routes method is gone. The tests build the abcd
home's paths through abcdhome.Display instead of spelling the folder.

Assisted-by: Claude:claude-opus-5-5
…s judgement types"

This reverts commit 966013a.

The product thinker has ruled that embark's lesson ranking stays in the
decision adapter's scope. It becomes a judgement routed through the
adapter's one interface, replacing today's term-overlap ordering, rather
than a computation left outside the adapter. The facilitator-on-delegation
decision recorded in the reverted commit, which dropped the ranking as a
factual correction, is withdrawn. The intent's two lists name the ranking
again, and iss-2610262033055327 returns to open/. It now stands for the
work of turning the ranking into that judgement.

Refs: iss-2610262033055327
Assisted-by: Claude:claude-opus-5-5
…t type

Under the product thinker's ruling, embark's lesson ranking is a
judgement routed through the adapter in place of its term-overlap
ordering, so embark-lesson-ranking joins the closed registry and the
configuration chapter's list. The embark verb does not call the router
yet; until it does, the ranking stays as it is.

Refs: iss-2610262033055327
Assisted-by: Claude:claude-opus-5-5
A bare <provider>/<model> under oracle.judgements hands the type's decision
to the decision adapter. That is now honoured only from the person's own
configuration, the machine's ~/.abcd.noindex/config.json, the same layers a
role handed to a runner is read from. The same route in a repository's
.abcd/config.json is skipped with one diagnostic, and the machine's own
route to the type applies in its own mode, or the host when the machine sets
none, so a repository's route never turns the machine's shadow into on. A
repository may still keep a type on the host or run it in shadow, where the
host still decides.

The refusal of a malformed judgement route in the machine's file now quotes
the value as the file spells it, shadow: prefix included, and names the
three forms a judgement route takes.

The configuration and adapters briefs state the rule.

Assisted-by: Claude:claude-opus-5-5
…board

The text form of abcd ahoy --providers printed every judgement route as a
bare <provider>/<model>, so a shadow route read like one that turns the type
on. It now prints the route as the configuration spells it. The --json form
already carried the mode.

Assisted-by: Claude:claude-opus-5-5
A judgement type whose shadow pairs were all skipped has no rate. The
harvest's text output printed it as 0%; it now prints n/a, as harvest.md
does.

Assisted-by: Claude:claude-opus-5-5
The lab command page and the lab brief described shadow mode as recording
pairs today. No step calls the decision adapter's router yet, so every type
stays on the host and no pair is kept until that call is added; both pages
now say so, as the configuration brief already did.

Assisted-by: Claude:claude-opus-5-5
After connecting a provider that takes no key, ahoy connect suggested
pointing a judgement type at it with the bare <provider>/<model> in the
repository's .abcd/config.json or the machine's file. A judgement type is
turned on only from the person's own configuration, so the bare spelling in
the repository's file is skipped. The advice now names both files for a
role, offers a judgement type the shadow:<provider>/<model> spelling, which
either file honours, and says the bare spelling turns the type on only from
~/.abcd.noindex/config.json. A provider holding a key keeps its one line
naming the machine's file.

Assisted-by: Claude:claude-opus-5-5
The ahoy page lists why a route is reported as oracle_api.route_skipped.
It now also names a repository's judgement route that turns a type on,
which only ~/.abcd.noindex/config.json may set; the machine's route to the
type, or the host, applies in its place.

Assisted-by: Claude:claude-opus-5-5
The harvest read pairs.jsonl whole under the 4 MiB bound every lab
document read takes, while shadow pairs are appended to it without
one, so a busy lab's harvest failed outright once the file passed the
bound. It now reads the file a line at a time, each line bounded as a
recorded pair is, so every pair is counted however long the lab ran; a
line longer than a pair may be is counted as one that did not parse and
the read goes on past it. The file is still read only as a regular file
in the lab home, never through a link.

Assisted-by: Claude:claude-opus-5-5
The drain's judgement before a lane opens is the judgement type
eligibility-residual, and the drain's move now asks the router for it.

On the host, the default, the move is as it was. In shadow, once the
host's or the routed judge's answer is taken, the adapter is asked the
same question over the same record and the pair is recorded in the
newest lab home; a state over the adapter's window is recorded as
skipped with its size. Shadow decides nothing, and its call is bounded
by its own short timeout. Turned on (only from the person's own
configuration), the adapter is asked once the host's request is written,
before any runner the judge is routed to; its answer is taken as a
routed judge's is, and the drain's record names the route
decision-adapter <provider>/<model>. An adapter that cannot answer
leaves the host's request standing with a fallback receipt in the
drain's state, and the request is marked as asked, so the polls that
follow while it stands ask the adapter nothing again. A drain stopped
while the adapter is asked refuses the move and records no fallback.

Assisted-by: Claude:claude-opus-5-5
The lab page, the lab and configuration chapters, the adapters chapter
and the package map said no step calls the router yet. The drain's
judgement before a lane opens now does, in each mode; every other
judgement type still stays on the host whatever its route says.

Assisted-by: Claude:claude-opus-5-5
@REPPL
REPPL enabled auto-merge October 30, 2026 03:48
@REPPL
REPPL added this pull request to the merge queue Oct 30, 2026
Any commits made after this event will not be merged.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant