glas-harness/workplans/GLAS-WP-0001-harness-router-foundation.md
tegwick 5681fce787
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 3s
Implement the harness contract and prove it against rein-aharness (GLAS-WP-0001-T02/T03/T04)
- src/glas_harness/contract.py: Rein ABC (start_session/dispatch_tool/
  end_session), SandboxHandle/ToolCall/ToolResult, per docs/harness-contract.md.
- reins/rein_aharness.py: adapter around the rein-aharness CLI. Collapses
  a whole `agent-harness run` into one dispatch_tool call for now (no
  per-tool hooks yet — tracked in rein-aharness HARNESS-WP-0002-T03);
  verifies success via new-commit detection, mirroring rein-aharness's
  own success signal.
- gateway.py + cli.py: resolves a sand-boxer sandbox, runs one task
  through a rein, tears the sandbox down.
- registry/reins/*.yaml (rein-aharness implemented, rein-openweights
  planned) and profiles/harness.agent-dev{,-local}.yaml, pairing with
  sand-boxer's profile.agent-dev and the new profile.bwrap-local.

Tested against a real local git repo + mocked SandboxManager/CLI
subprocess (10 tests, all passing). A real live run against the actual
Claude Code CLI is deliberately left for a human-triggered follow-up —
not executed autonomously since it spends real API credits/credentials.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-26 13:02:59 +02:00

123 lines
4.8 KiB
Markdown

---
id: GLAS-WP-0001
title: "Harness router foundation: contract + first two reins"
status: proposed
state_hub_workstream_id: "4b8740d9-9ea8-4c11-abfc-af9e9ac1c2df"
---
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: done
priority: high
state_hub_task_id: "e4e6e7e4-ad30-42b7-a278-39d24ec5cecc"
```
## 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: done
priority: medium
state_hub_task_id: "c09e617b-a2d1-42c4-8c90-47ab0056c09c"
```
## 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: done
priority: medium
state_hub_task_id: "e599f276-a010-4284-bddd-a5a121b57de9"
```
## 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.
Wiring is built and unit-tested: `src/glas_harness/gateway.py` +
`reins/rein_aharness.py` implement start_session/dispatch_tool/
end_session, tested against a real local git repo and a mocked
`SandboxManager`/`agent-harness` subprocess (`tests/test_gateway.py`,
`tests/test_rein_aharness.py`). **Not yet done:** an actual live run
(`glas-harness run --sandbox-profile profile.bwrap-local ...`) against
the real Claude Code CLI — that spends real API credits/credentials and
was deliberately left for a human-triggered run rather than executed
autonomously. State Hub reporting from the gateway itself is also not
wired yet (only rein-aharness's own `--no-hub` path was exercised).
```task
id: GLAS-WP-0001-T04
status: progress
priority: high
state_hub_task_id: "cdcacf98-62a1-47ae-92b9-e0320968ac1f"
```
## 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
state_hub_task_id: "84fa62ae-3b34-42fd-a263-f65c35e87586"
```
## 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
state_hub_task_id: "b4e775d6-ad81-40a4-9fd0-974ba27182fd"
```