Add ADR-001: rein harness family, and first workplan
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Establishes glas-harness as the framework routing between concrete
harness backends ("reins"): rein-aharness (renamed from agent-harness)
and the newly chartered rein-openweights. GLAS-WP-0001 defines the
harness contract, rein registry, and a minimal gateway proving parity
against rein-aharness.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
tegwick 2026-07-26 12:29:02 +02:00
parent e64ddad637
commit c2a788aed9
2 changed files with 198 additions and 0 deletions

View file

@ -0,0 +1,93 @@
# ADR-001: The "rein" harness family, routed by glas-harness
- Status: accepted
- Date: 2026-07-26
- Deciders: Bernd Worsch
## Context
Two harness efforts existed in parallel with no relationship documented
between them:
- **agent-harness** — a working v0.1 runtime, deployed on Railiance,
driving Claude Code CLI sessions for one tenant (`binky-control`). Its
only isolation is a `--allowedTools` allow-list string plus cwd-pinning;
it has no OS-level sandbox and no awareness of glas-harness or
sand-boxer.
- **glas-harness** — a charter-only meta-framework (`INTENT.md` plus a CI
smoke stub) that names sand-boxer as its sandbox provider but has no
gateway, session loop, or tool dispatch implemented yet.
Neither repo referenced the other. Left alone, this heads toward "two
harnesses that both think they're the runtime," with no shared contract
and duplicated wiring to `kaizen-agentic`, `activity-core`, and
`llm-connect`.
Separately: every current agent-facing harness in the ecosystem (Claude
Code, Grok's CLI, GPT/Codex's CLI) is a **frontier-model-vendor harness**
— it only drives that vendor's own model. There is no harness in the
ecosystem today that can run a current open-weight model (via OpenRouter)
through an equivalent agentic tool-use loop.
## Decision
1. **glas-harness is the framework.** It owns the harness *contract*
(session lifecycle, tool dispatch, actor attribution, sandbox
consumption via sand-boxer) and routes between pluggable, concrete
harness backends — mirroring how sand-boxer owns a sandbox contract
and routes between pluggable extensions (`ext.compose-ssh`,
`ext.vm-packer`, `ext.e2b`, ...).
2. **Concrete harness backends are called "reins."** The name mirrors
"rails" (operations models for running workloads): different reins
suit different circumstances, and more can be added without changing
the framework. Each rein is its own repo, prefixed `rein-*`.
3. **`agent-harness` is renamed `rein-aharness`** and becomes the first
rein: the Claude-Code-CLI-driven harness for governed, unattended/
scheduled tenant work (its existing `binky-control` role is unchanged).
Repo and Forgejo remote already renamed
(`coulomb/rein-aharness.git`); local directory, git remote, and
self-referencing docs (`README.md`, `INTENT.md`, `pyproject.toml`
project name) are updated as part of this ADR landing. The CLI command
name, Python package name, and deploy artifacts (Docker image tag, k8s
namespace, Railiance host paths) are **deliberately left unrenamed for
now** — see `rein-aharness/workplans/REIN-A-WP-0002` — because they
touch a live deployment and deserve their own reviewed change, not a
silent mechanical rename bundled into an architecture decision.
4. **A new rein, `rein-openweights`, is chartered** to close the
frontier-vendor-harness gap: an agentic tool-use loop that drives
current open-weight models via OpenRouter (through `llm-connect`) as
an alternative to Claude Code / Grok CLI / Codex, usable wherever a
rein-aharness-equivalent session is wanted but a frontier vendor
dependency is not. Scaffolded at `~/rein-openweights` (local only —
no Forgejo remote yet).
## Consequences
- glas-harness's first implementation milestone is now concrete: define
the harness contract that both `rein-aharness` and `rein-openweights`
implement, plus a minimal router, rather than an abstract charter with
no consumer.
- `rein-aharness` keeps running unchanged in production (`binky-control`)
while glas-harness matures — no forced cutover, no risk to the live
Railiance deployment.
- The "retire agent-harness" question raised earlier is superseded: it
isn't retired, it's incorporated as a rein. Whether it's ever folded
directly into glas-harness's own process (vs. staying a separate
routed repo) is deferred until glas-harness's contract exists and at
least two reins have implemented it.
- Future reins (e.g. a channel-bot rein, a subagent-delegation rein) slot
into the same contract without new framework work, the same way a new
sand-boxer extension doesn't require sand-boxer's core API to change.
## Open questions (for the workplans below)
- Does the harness contract abstract scheduling/blueprint-sourcing
(kaizen-agentic, activity-core), or does only `rein-aharness` depend on
those while `rein-openweights` is triggered differently (e.g. directly
by glas-harness channels)?
- Where does credential brokering for `rein-openweights`'s OpenRouter/
llm-connect calls live — glas-harness (per the sandbox-consumption
pattern) or the rein itself?

View file

@ -0,0 +1,105 @@
---
id: GLAS-WP-0001
title: "Harness router foundation: contract + first two reins"
status: proposed
---
Turn glas-harness from a charter into the actual harness router per
`docs/adr/ADR-001-rein-harness-family.md`. Define the contract concrete
harness backends ("reins") implement, register the first two
(`rein-aharness`, `rein-openweights`), and stand up a minimal gateway
that can run a session through either. No channel work, no memory/skills
layer yet — this workplan is the sand-boxer-extension-model equivalent
for harnesses: contract + registry + one working round trip.
## Task: Define the harness contract
Specify the interface a rein implements: session start/resume/end, tool
dispatch + policy check, actor attribution (`adm`/`agt`/`atm`), sandbox
policy resolution (mode/scope/workspaceAccess) handed to sand-boxer, and
the audit envelope reported to State Hub. Mirror sand-boxer's
`SandboxExtension` ABC shape (`provision`/`wait_ready`/`teardown`) at the
harness level: something like `start_session`/`dispatch_tool`/
`end_session`. Document in `docs/harness-contract.md`.
```task
id: GLAS-WP-0001-T01
status: todo
priority: high
```
## Task: Rein registry
A named, versioned registry of reins (`registry/reins/rein-aharness.yaml`,
`registry/reins/rein-openweights.yaml`) analogous to sand-boxer's
`extensions/ext.*.yaml` — each entry declares its capabilities (e.g.
`unattended`/`interactive`, `model-class: frontier|open-weight`,
`credential-source`) and a handler reference. Extend
`registry/indexes/capabilities.yaml` with a `capability.platform.
glas-harness` entry per the registry-first-reuse principle.
```task
id: GLAS-WP-0001-T02
status: todo
priority: medium
```
## Task: Harness profile catalog seed
First harness profile, `harness.agent-dev`, paired with sand-boxer's
`profile.agent-dev` (existing `docs/integrations/glas-harness.md` contract
in sand-boxer already assumes this pairing — verify it still matches).
Add a second profile, `harness.agent-dev-local`, paired with sand-boxer's
forthcoming `profile.bwrap-local` (SAND-WP-0013) once that lands, for
fast local iteration without an SSH hop.
```task
id: GLAS-WP-0001-T03
status: todo
priority: medium
```
## Task: Minimal CLI gateway — prove the contract against rein-aharness
Implement just enough of the harness contract to run one existing
rein-aharness `run` (task-file path) *through* glas-harness: resolve
`harness.agent-dev`, request a sandbox from sand-boxer, dispatch to
rein-aharness's adapter, verify commit, report to State Hub. This is the
parity proof gating any later "retire agent-harness as a standalone
concern" conversation — deliberately not attempted until this exists.
```task
id: GLAS-WP-0001-T04
status: todo
priority: high
```
## Task: Charter and bootstrap rein-openweights
Turn the `~/rein-openweights` scaffold into a working minimal rein: an
agentic tool-use loop (plan → tool call → observe → repeat) driving an
open-weight model via `llm-connect`'s OpenRouter path, implementing the
GLAS-WP-0001-T01 contract. Start with the same tool surface as
rein-aharness's `green-commit-only` profile (Read/Write/Edit/Glob/Grep +
local git) so it's directly comparable. Needs its own Forgejo remote
before anything is pushed — coordinate repo creation with the operator.
```task
id: GLAS-WP-0001-T05
status: todo
priority: high
```
## Task: Decide credential-brokering ownership for rein-openweights
Resolve the open question from ADR-001: does glas-harness broker the
OpenRouter/llm-connect credential the same way it will broker sand-boxer
sandbox handles, or does rein-openweights acquire it directly (OpenBao/
ops-warden) the way rein-aharness does today? Record as an ADR addendum
before T05 lands, not after.
```task
id: GLAS-WP-0001-T06
status: todo
priority: medium
```