2026-08-29 · Updated 2026-08-29 · 8 min read

What the control plane, Ledger, and Benchmark each own

The citable ownership definition of the YYLO system — which component owns execution and admission, which owns task truth, which owns evaluation evidence — with the boundaries, failure domains, and interfaces between them.

By Juno AI INC · yylo · yylo-ledger · benchmark · system-ownership

Assembling YYLO from its packages installs three programs, and each one answers a question the other two refuse to answer. Which work exists right now, and what may run next? Who dispatches an agent, bounds it, and decides what lands? And when several attempts have run, which of them was actually better? Split those three questions across three independently shipped components and you have the system; hand all three to one component and you have the coupling this decomposition exists to prevent.

This page is the ownership definition of that system: what each component is the sole owner of, what it is structurally barred from, what breaks when it is missing, and how the three talk to each other without merging. Every quoted sentence below is verbatim from committed READMEs — nine sentences from the control plane's, one from the Benchmark's — checked against the package versions this site pins in its generated package facts (verified 2026-08-29). It is deliberately the static half of the picture — the lifecycle guide walks one change station by station through all three; keep that page for the trip and this one for the map.

One definition, three owners

Ownership here means something checkable: a component owns a job when it is the only writer of that job's state and every other component reaches that state through a published interface. Measured that way, the answer leaves no component holding two jobs. The control plane — the yy/yylo CLI — owns execution and admission: it dispatches bounded runs, isolates them, validates them, and merges what passes. YYLO Ledger owns task truth: the durable record of intent, status, dependencies, agent responses, and commit evidence. YYLO Benchmark owns evaluation evidence: immutable plans, isolated attempts, and the retained record of what repeated runs actually proved.

The three ship as three packages on two registries — @yylo/cli 0.2.0 and @yylo/benchmark 0.1.0-rc.7 on npm, yylo-ledger 0.2.0 on PyPI — versioned on their own schedules, because the decomposition is real at the package boundary, not just in the prose. None of the three is embedded in another: the ledger runs with no orchestration at all, the benchmark launches its attempts without entering the task-admission queue, and the control plane, as the next sections show, is structurally forbidden from absorbing either job.

The control plane owns execution and admission

Everything that moves work from *recorded* to *landed* belongs to one component. It starts bounded runs, hands each its own checkout, collects validation, and serializes the actual write into shared history. Its authority map is written down as a lane table in the README: the controller lane is permitted "Kanban/Juno mutation, orchestration, prompts, and durable receipts" and forbidden "Product implementation or integration; implicit ref changes"; a task checkout exists for "Implementation, focused tests, and coherent task commits against the declared base"; the integration owner performs "Reviewed candidate integration under the (Git common directory, full target ref) channel lock and expected-SHA CAS". The rule that makes the table usable is one sentence: "Choose the smallest lane that satisfies the work."

Just as load-bearing is what the controller is not: a code host. "Controller commits never merge or synchronize to product history." — the control plane's own metadata lives beside the work, never inside it, so orchestrating a repository can never become quietly editing that repository. That is the boundary an architect should test first, because it is the one every other property hangs from: with product bytes out of the controller, isolation, validation, and serialized landing all become enforceable instead of aspirational.

What the control plane does not own: the task records it dispatches from (the ledger's), the evaluation of repeated attempts (the benchmark's), and any model or editor of its own — it routes runs to installed agent services and adds the discipline around them. Its failure domain follows: remove it, and the other two components keep working — tasks can still be recorded on the standalone ledger and an agent can be run by hand — but nothing bounds a run, nothing dedicates a checkout, nothing stands between a finished agent session and shared history. The system degrades to well-recorded manual agent use.

The Ledger owns task truth

Task truth is the record of the work, resident in the repository: what was asked, where it stands, what it waits on, what the agent claimed, and which commit carries the result. The ledger is its only writer, and it is a standalone product — a Python package from PyPI whose command surface records and answers. It dispatches nothing: create, mark, ready, get are records and queries, so an agent or a human does the running, and the ledger does the remembering. Completion is the same discipline — the done record carries a commit reference field, and the write is refused when declared blockers are still open; it is a state change on a task, never a merge into code.

That refusal-heavy posture is the point. The ledger's value is that its answers are computed from declared state rather than remembered from conversations, which is exactly what makes them safe to hand to a machine. What it does not own: execution (above), admission (a recorded completion is not a landed change — landing is the control plane's serialized job), and evaluation (which attempt was better is not a task-record question). Its failure domain is the oldest one in coordination: without repository-resident truth, state drifts into chat threads, tickets, and someone's memory — the shared-markdown failure this program's ledger guides dissect — and every concurrent agent inherits a different picture of what is true.

The Benchmark owns evaluation evidence

The benchmark answers the question the other two cannot: across attempts, models, or implementations, what actually performed better on this repository's work? Its package owns validating cases, isolating snapshots, reconciling what really ran, recovering incomplete runs, and reporting from retained evidence — plans are immutable before execution, attempts run isolated, and grading is governed, so a result stays interpretable after the session that produced it has closed.

The boundaries are equally explicit. The benchmark does not own task truth: its README reaches the ledger only "through its public JSON/receipt CLI contract", reading case and plan inputs from the same records everything else reads. It does not own admission: it invokes the control plane to run attempts, but a finished experiment queues nothing — evaluation informs a decision; it is not the decision. And its failure domain is the quietest of the three: remove the benchmark and execution and task truth continue untouched. What is lost is comparability — repeated attempts still happen, but their evidence dies with each session, and next quarter's choice reverts to anecdote.

The seams: delegates that fail closed

Three owners need a connection design that cannot decay into coupling, and the shipped answer is delegation with refusal. The control-plane README binds its side in one sentence: "yy and yylo are equivalent launchers. Their ledger and benchmark subcommands are thin, fail-closed delegates to independently installed yylo-ledger and yylo-benchmark executables." Independence is enforced, not encouraged — "delegates never discover checkout-local or legacy runtimes" — so there is no silent fallback to whatever Python or Node happens to be lying around a checkout. And the contract is byte-level: "Each standalone/delegated help/version pair is byte- and exit-equivalent; arguments, stdin, stdout, stderr, cwd, environment, nonzero exits, and signals are propagated." A script written against one form runs unchanged against the other:

sh
yy ledger --help
yy benchmark --help
yylo-ledger --help
yylo-benchmark --help

The benchmark side mirrors the same shape: its subcommand is a forwarding alias and the standalone executable is the canonical surface, so an evaluation pipeline can target the benchmark directly without the control plane in the loop. Notice what the seams do not contain: no shared database, no embedded interpreter for a sibling package, no component reaching into another's private state. Each seam is a one-way command invocation — one process calls another's CLI and reads its output — which is why the interfaces can be cited, tested, and replaced without renegotiating the system.

Read the system by what fails when

The decomposition is easiest to verify by pulling components out. Remove the control plane: recording survives, agents can still be invoked directly, but bounds, isolation, validation, and serialized landing are gone — nothing stands between a session and shared history. Remove the ledger: execution still runs, but truth leaves the repository, concurrent agents diverge, and every later question about *what happened* becomes archaeology. Remove the benchmark: work flows and lands as before, but comparative evidence evaporates with each session and selection decisions lose their longitudinal ground. No removal reaches another component's records — that compartmentalization is what the ownership boundaries buy.

Cite this page as the system definition with its date attached: every boundary above was read from the committed READMEs and package manifests behind the versions this site pins, on 2026-08-29; the package facts themselves are synchronized from source and rendered on the YYLO project page and its two siblings. The layer-by-layer map of where these components sit in the wider open-source stack has its own survey in this program, and the full auditable architecture has its own page; neither changes what is written here. When a boundary sentence above stops matching its README, the definition is stale — treat that mismatch as the signal to re-derive, not the exception to trust.