glas-harness/docs/adr/ADR-001-rein-harness-family.md
tegwick 7a3c8669c7
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 3s
Fix ADR-001 workplan reference after HARNESS-WP-0002 rename
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-26 12:33:07 +02:00

4.5 KiB

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/HARNESS-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?