Nobody staffs a control room by staring at a screen for eight hours. Instruments watch, thresholds are agreed in advance, and an alarm summons a human who arrives with authority and context.
You approve a module β what you want, in your own words, with criteria anyone can observe. Agents write the specs and the code. Deterministic gates and a different vendor's model produce the evidence. Your default state is not involved. When something needs you, your phone says which rule broke, why in one sentence, and what your two or three options cost.
An empty queue is the success state. The app tells you to close it.
There is no usable release yet. The repository contains the architecture, the roadmap, the governance setup, a build skeleton, and a working implementation of the verification system itself. Phase P1 is where the orchestrator begins.
| What | State |
|---|---|
| Architecture, protocol, threat model, decisions | β
docs/ |
| Verification gates β modes, guards, evidence artifact, canaries | β
Working β go run ./scripts/gate verify |
| Repo scaffolding, CI, licence automation | β In place |
| Orchestrator, relay, mobile app | π§ Not started β P1βP4 |
The gates are not a demo. This repository is built with them (ADR-011).
We used to spend hours at a computer writing code. Now we spend hours at a computer watching something else write it. The clock did not move; the agency did.
Both ends of the current spectrum are wrong. The developer stays at the centre of the work because something has to ship β that does not scale past one person's day. The product owner hands everything to the agent and looks only at the output β that has no way of finding out whether the output is right.
And the reason nobody can safely stop watching is that the agent's own "done" is not checkable. A coding agent finishes a feature and reports success. Everything is green. But green means "it followed the rules" β not "it did the right thing."
This was measured, not assumed. A project one model declared complete was put through a verification pass driven by a different model against its spec. That pass found missing translations, tests that were never written, a coverage regression, and real bugs.
The primitive unit is not a message and not a feature. It is a module.
| Layer | Written in | Who | You see it |
|---|---|---|---|
| Module | Business language. Criteria anyone can observe. | You | βͺ always |
| Spec | Technical language. SPEC-β¦ ids, invariants. |
Agents | β only when it matters |
| Feature + invariant | Code citing a SPEC-β¦ id |
Agents | never |
| Code | β | Agents | never |
A module says "a dealer with insufficient balance cannot transact and understands why." It may not name an endpoint, a table or a class β that is a spec, one layer down, and writing it at module level destroys the oracle.
This is where your judgement actually works. Asked to ratify an idempotency invariant, you take it on trust. Asked whether a dealer should see their own balance, you know instantly.
βͺ YOU approve a module βββ criteria Β· scope: included / excluded
βΌ
M1 every spec must name the criterion it serves ββ and stay in scope
βΌ
β spec β auto-ratified unless HIGH risk, a new rule, or M1 red
βΌ (and if it reaches you, it says why)
T1 cheap model implements βββ T0 lint/types, instant, no tokens
βΌ
T2 a DIFFERENT model tries to break it ββ same model = gate void
βΌ
T3 arbiter, only on contradiction
βΌ
M2 is any criterion served by NO spec? ββββ blocks β‘ while red
βΌ
β‘ YOU observe the criteria, one at a time. Half-ticked won't close.
Each role runs a real, existing agent β Qwen Code, Kimi Code, OpenCode β over the Agent Client Protocol. We implement no agent, no model router, no provider integration (ADR-014). Each uses your account under its own identity. Keys never reach us.
Every gate runs against a selective regression cache, and git commit invalidates nothing β committing does not change what a gate read.
Every spec ratified. Every gate green. The code entirely correct. And a part of what you actually asked for was never built β because nobody ever wrote a spec for it.
No other gate can see this, because every other gate compares code against a spec, and here the defect is the missing spec. M2 compares the specs against your module's criteria and names the one nothing serves (ADR-019). The check that binds is set arithmetic, not model judgement β a judged gate here may raise a finding, never clear one (ADR-023).
Said honestly: this relocates the blind spot rather than removing it. Nothing is the oracle of the module itself, so a requirement you never turned into a criterion is still invisible. What changes is the price β a missing criterion costs a conversation at βͺ; a missing spec costs a rebuild. The verifier is pointed at the module draft to push on that, and it is pressure, not proof (ADR-026).
While M2 is red, β‘ cannot start. Interface-testing a knowingly incomplete product is not a test.
And you may lower a criterion to clear it β sometimes the goal really was too ambitious. But never in one tap. The module returns to draft, you write why, and it comes back through βͺ. Lowering a target to turn red green is the human-hand version of the thing the loop is forbidden to do, and a phone queue between meetings is the most dangerous place in the product for it.
Raw gate output is unreadable on a train. So the orchestrator does not send it. It sends a decision:
Violated: the same transaction can never be charged twice Why: the second call with the same
session_idissues a second receipt. Options: β atomic lock β ~15 min, no schema change Β· β‘ relax the spec β touches the module boundary, reopens βͺ Β· β’ leave it to me β stays queued, I'll look at my desk.
That translation is the product's real engineering work (ADR-021). It happens in the orchestrator, not the app.
| Tier | Job | Model |
|---|---|---|
| M | Intent gates β reading meaning | Expensive |
| T0 | Format, lint, types | None. Deterministic, free |
| T1 | Producer | Cheapest capable, flat-rate subscription |
| T2 | Adversarial verifier | Never the same model as T1 |
| T3 | Arbiter, on contradiction only | Expensive, rare |
| T4 | Weekly sweep β CVEs, dead code | Cheap, off by default |
Cross-verification costs 2β3Γ the tokens of a single pass. One price tier everywhere fails both ways: expensive everywhere is unaffordable; cheap everywhere puts the weakest judgement exactly where your decision rests on it.
And T2 may never be T1. Configure them the same and the gate is void and the ladder halts β it does not quietly pass. A model grading its own work is the failure this product exists to correct; showing a green badge for it would be worse than running nothing (ADR-022).
The cheap end of the market is therefore not a positioning choice. It is what makes the technique exist at all.
The honest output of cross-verification is sometimes "our own model got this wrong."
Vendors ship model pickers and steer you toward their own β one gives a 1.5Γ quota bonus for using its first-party client. Only a party that sells no model can credibly arbitrate between models.
Reference design: design/mobile-v2.html β open it in a browser.
| Tab | What it holds | Empty means |
|---|---|---|
| Queue | Pending βͺ, β , β‘ and arbitrations β nothing else | β "Nothing is waiting for you." And it says you can close the app β with a timestamp proving it still knows. |
| Modules | Per project: modules, complete, scope gaps, awaiting approval β and which criterion is met by which spec | Nothing in flight |
| Settings | Agent assignment, loop method, auto-approval conditions, budget, visibility, interrupt counter | β |
"One module has a scope gap" is a number almost nothing can produce, because it needs an oracle β a statement of intent above the spec layer. A chat log is not one. A ratified module with observable criteria is.
Chat is not removed, and it is not a tab. It is a context-aware command bar at the bottom of every screen, and it is asynchronous β you send and you leave; it answers "sent, you can go." Input is conversation; output is structure: a module draft, a spec card, an optioned decision. Never a wall of text.
Every element has to pass one test: does seeing this change the decision I am about to make?
Failing it: the token counter, the agent's reasoning stream, the diff by default, the live log. Each is engaging; none changes an answer.
Two exceptions, and no more. Budget β it decides whether to let the loop keep grinding. And the heartbeat β because a dead orchestrator and a quiet one render the same empty screen, and an app still reporting "2 modules running" nine hours after the process died is a lie shaped like good news. Stale silence becomes the alarm itself (ADR-024).
Nothing is hidden. The full reasoning trace and the raw agent conversation are available in their entirety, without restriction, one tap away, freely opened and freely closed. The objection was to making them the centre β never to their existence (P11).
Not time in the app. Time away from the desk. The interrupt counter ships as a feature: interrupts per module, auto-approval ratio, hours spent elsewhere. Above roughly eight interrupts per module, the product tells you what that means β the modules are too large, or the criteria too vague.
The system cannot earn the right to interrupt before it has earned the right to correctly not interrupt.
- Not another coding agent. Use the ones you already have. We orchestrate them.
- Not a chat client for your agent. Several of those exist. This is the opposite bet.
- Not a terminal mirror. Interactive TUIs are out of scope β
sshandtmuxalready do that well. - Not a model provider. Your keys, your subscriptions, your bill β paid directly to your provider.
- Not a cloud runner. Our server is a control-channel relay. It never proxies a model call.
- Not project management with dates. No Gantt, no burndown, no estimates in time. The only budget is a count of decisions.
One requirement worth knowing: the orchestrator runs on your machine, so that machine must be on. If it is not, the app shows the last known state and says so β it will not silently spin. For always-on use, run it on a machine that is always up (headless deployment).
Everything crossing the relay is end-to-end encrypted; it handles ciphertext and routing metadata only (ADR-004). In Settings, provider keys read "on device" β that line is a commitment, not a preference, and there is no UI path that could make it false. Self-hosting removes us from the picture entirely.
Any ACP agent can fill any role. Provider-agnostic agents such as OpenCode reach dozens of models on their own β including providers that ship no CLI.
| Agent | Models | Licence |
|---|---|---|
| Qwen Code | Qwen | Apache-2.0 |
| Kimi Code | Kimi / Moonshot | Apache-2.0 |
| OpenCode | provider-agnostic β GLM, DeepSeek, MiniMax, β¦ | Open source |
A direct pay-as-you-go path against any OpenAI-compatible endpoint remains available as a fallback (ADR-012).
No release yet. What works today:
git clone https://github.com/burakhalefoglu/RemLinkAgent.git
cd RemLinkAgent
make cli && make server # β ./bin/rla, ./bin/rla-server
make verify # the verification system, running on itself
make canary # proves each gate still detects breakagemake help lists every target. Windows without GNU make: .\scripts\make.ps1 <target>.
Prerequisites and setup: CONTRIBUTING.md.
| Phase | Scope | State |
|---|---|---|
| P0 | Scaffolding, CI, verification gates, ACP spike | π§ In progress |
| P1 | Orchestrator: ACP client, role assignment, coder β gates β reviewer handoff | π Next |
| P2 | Relay: WSS, pairing, E2E, JetStream sync, push | π |
| P3 | Mobile: spec ratification, evidence review, approvals | π |
| P4 | Signed binaries, store submission, launch | π |
| M1 | Managed cloud and a team tier β self-host stays free and complete | π |
| X | Voice, smartwatches, deeper verification tiers | π |
Detail and the assumptions behind the estimates: roadmap.md.
| Component | Licence |
|---|---|
Orchestrator + relay (cmd/, internal/, deploy/, scripts/) |
AGPL-3.0-or-later |
Mobile client (mobile/) |
Apache-2.0 |
The split is deliberate β GPL-family terms conflict with App Store distribution (ADR-002). Contributions require a CLA (why).
Early, and the architecture is still soft in places. Start with CONTRIBUTING.md, then development-loop.md β this repository is built with the method it ships.
Security issues: do not open a public issue β see SECURITY.md.
"Everything is green" means it follows the rules. It does not mean it does the right thing.