REIN-OW-WP-0001 T01-T04 landed in the rein-openweights repo. The glas_harness/reins/rein_openweights.py adapter (mirroring reins/rein_aharness.py) that actually plugs it into the gateway is the remaining piece. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
138 lines
5.8 KiB
Markdown
138 lines
5.8 KiB
Markdown
---
|
|
id: GLAS-WP-0001
|
|
title: "Harness router foundation: contract + first two reins"
|
|
status: active
|
|
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 OpenRouter, 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.
|
|
|
|
`rein-openweights/REIN-OW-WP-0001` (T01-T04) is done: standalone agentic
|
|
loop, own OpenRouter client (not llm-connect — see that workplan's T01
|
|
for why), tool surface, credential acquisition, commit-verified success
|
|
+ hub reporting, 26 tests. **Not yet done here:** a
|
|
`glas_harness/reins/rein_openweights.py` adapter implementing the `Rein`
|
|
ABC and shelling out to `rein-openweights run`, mirroring
|
|
`reins/rein_aharness.py` — that's the piece that actually plugs this
|
|
rein into glas-harness's gateway. registry/reins/rein-openweights.yaml's
|
|
`status: planned` should flip to `implemented` once that adapter lands.
|
|
|
|
```task
|
|
id: GLAS-WP-0001-T05
|
|
status: progress
|
|
priority: high
|
|
state_hub_task_id: "84fa62ae-3b34-42fd-a263-f65c35e87586"
|
|
```
|
|
|
|
## Task: Decide credential-brokering ownership for rein-openweights
|
|
|
|
Resolved in `docs/adr/ADR-002-credential-brokering-and-composable-reins.md`:
|
|
**Option B** — rein-openweights acquires its OpenRouter credential
|
|
directly (OpenBao/ops-warden), consistent with rein-aharness's own
|
|
credential-holder principle. glas-harness does not broker LLM-provider
|
|
credentials. Confirmed llm-connect itself never brokers credentials
|
|
either (`resolve_api_key()` only reads an already-materialized key) —
|
|
the earlier "does using llm-connect impose a credential model" concern
|
|
does not apply. A separate, deliberately deferred question (composable
|
|
reins as middleware for monitoring/eval/optimization) is recorded in the
|
|
same ADR as open, not blocking this task or T05.
|
|
|
|
```task
|
|
id: GLAS-WP-0001-T06
|
|
status: done
|
|
priority: medium
|
|
state_hub_task_id: "b4e775d6-ad81-40a4-9fd0-974ba27182fd"
|
|
```
|