Add ADR-001: rein harness family, and first workplan
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:
parent
e64ddad637
commit
c2a788aed9
2 changed files with 198 additions and 0 deletions
93
docs/adr/ADR-001-rein-harness-family.md
Normal file
93
docs/adr/ADR-001-rein-harness-family.md
Normal 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?
|
||||||
105
workplans/GLAS-WP-0001-harness-router-foundation.md
Normal file
105
workplans/GLAS-WP-0001-harness-router-foundation.md
Normal 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
|
||||||
|
```
|
||||||
Loading…
Add table
Add a link
Reference in a new issue