rein-aharness/deploy/README.md
tegwick 4310c15eac feat(deploy): gate claims on pinned runtime readiness
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a06ba0-10aa-7ea0-b20a-4f3fac39efe9
2026-09-04 20:08:37 +02:00

131 lines
6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Railiance deployment (HARNESS-WP-0001-T06)
Single shared harness instance on **railiance01**. Secrets stay on the host
(Lanes 23); the container image is the portable runtime package.
## Supported runtime topology
The authoritative production runtime is the railiance01 user service
`rein-aharness-claim-loop.service`. It owns the configured repository
checkouts, private runtime state, worker credential, lease heartbeats, and
signal-driven shutdown behavior.
The Kubernetes Deployment is explicitly labeled `packaging-smoke` and runs
`sleep infinity`. It proves that the image can be scheduled with its hardened
container settings; it is not ready to claim work and is not a failover worker.
Do not give it an Activity Core worker credential or scale it as execution
capacity. Promoting Kubernetes requires a separate reviewed cutover with real
workspace, credential, repository-lock, Glas/sandbox, shutdown, and recovery
semantics.
> **Renamed from agent-harness (HARNESS-WP-0002-T02) — cutover done
> 2026-07-26.** Railiance now runs `rein-aharness` end to end: image tag,
> k8s namespace, CLI command, Python package, host secrets dir, and
> checkout are all renamed, verified via the authoritative host smoke
> script (`ok: true, committed: true, pushed: true`), and the old
> `agent-harness` namespace/checkout are gone. Checklist kept below as a
> record and in case this ever needs redoing (e.g. a second host).
## Rename cutover checklist (done on railiance01 2026-07-26)
1. Move the host-side secrets dir: `mv ~/.local/agent-harness ~/.local/rein-aharness`
(or symlink, if anything else still reads the old path).
**Also needed, not anticipated by this checklist originally:** two
path references *inside* `~/.local/rein-aharness/env` (AppRole dir,
PYTHONPATH — fixed with a blind, precise `sed` substitution; the
file wasn't read directly, a direct `cat` was correctly classifier-blocked
as a secrets file) and `~/.ssh/config`'s `Host forgejo-agent-harness`
`IdentityFile` (alias name itself left unchanged, only the path it
points at). Check both again if redoing this elsewhere.
2. Move/rename the checkout: `mv ~/agent-harness ~/rein-aharness` (or a fresh
`deploy-rsync` to the new path — see Makefile). If the checkout has an
associated venv, **recreate it from scratch** rather than moving it —
a venv's shebang lines embed absolute paths, so renaming the directory
alone breaks `pip` and every installed entry point.
3. Verify no other host cron/systemd unit still references
`~/agent-harness` or the `agent-harness` command directly.
4. Once the above is done, `kubectl delete namespace agent-harness` **after**
confirming the new `rein-aharness` namespace deploys and smokes clean —
don't delete the old one first, in case cutover needs a rollback.
## Layout
| Path | Role |
|------|------|
| `Containerfile` | Image: Python CLI + git + openssh; optional vendored llm-connect |
| `runtime-contract-lock.json` | Exact sibling source revisions and cross-service contract pins |
| `deploy/k8s/railiance/` | Namespace, ConfigMap, Deployment, smoke Job |
| `deploy/scripts/install-pinned-runtime.sh` | Frozen, non-editable host runtime installation |
| `deploy/scripts/railiance-smoke.sh` | Host e2e: clone sandbox → commit → push → hub |
| `rein-aharness smoke` | Deterministic smoke (no Claude Code required) |
## Prerequisites (done 2026-07-17, paths renamed per checklist above)
- Lane 2 deploy key on host + Forgejo write on `coulomb/executor-sandbox`
- Lane 3 AppRole under `~/.local/rein-aharness/approle-binky-mail`
- `source ~/.local/rein-aharness/env`
- `uv` for the frozen host runtime installation
- Hub: `http://127.0.0.1:18000` (ops-bridge) or in-cluster `state-hub.state-hub.svc`
- While profile-absent tenant definitions remain, set a reviewed ISO expiry in
`AGENT_HARNESS_LEGACY_APPROACHES_UNTIL`. The checked-in example expires
2026-12-31; missing or expired values refuse compatibility dispatch.
- Before enabling a profiled definition, list its exact `profile@version` in
`AGENT_HARNESS_REQUIRED_PROFILE_REFS`. Service startup then requires Glas
operational readiness and exercises bwrap/AppArmor for local profiles.
- Treat any `preflight` failure or close-outbox quarantine as not ready. Pending
close evidence is replayed by the first claim-loop cycle before a new claim.
Install or refresh the worker environment only from the checked-in locks:
```bash
./deploy/scripts/install-pinned-runtime.sh
make contract-test
./deploy/scripts/install-claim-loop-user.sh
```
The installer rejects a missing, dirty, or revision-mismatched llm-connect,
Glas, or sand-boxer sibling and uses `uv sync --frozen --no-editable` so the
service does not depend on mutable editable checkout state.
## Build & load image (workstation → railiance01)
```bash
# from rein-aharness repo root
make image # tags rein-aharness:railiance01
make image-export # /tmp/rein-aharness-railiance01.tar
scp /tmp/rein-aharness-railiance01.tar railiance01:/tmp/
ssh railiance01 sudo k3s ctr images import /tmp/rein-aharness-railiance01.tar
```
## Apply k8s
```bash
rsync -a deploy/k8s/railiance/ railiance01:rein-aharness/deploy/k8s/railiance/
ssh railiance01 kubectl apply -k rein-aharness/deploy/k8s/railiance/
ssh railiance01 kubectl -n rein-aharness rollout status deploy/rein-aharness
```
## Host smoke (authoritative e2e gate)
Full path uses the host deploy key and hub bridge:
```bash
ssh railiance01 'bash ~/rein-aharness/deploy/scripts/railiance-smoke.sh'
```
Expect: local commit + push to `executor-sandbox`, hub event `harness_smoke`,
`.kaizen/metrics/coach/` on the sandbox checkout.
Before starting or restarting the authoritative service, run the same gate the
unit uses:
```bash
ssh railiance01 '~/bin/rein-aharness-claim preflight'
ssh railiance01 '~/bin/rein-aharness-claim close-outbox status'
```
## Personal follow-ups (not T06)
- At **binky cutover only**: attach the same deploy key to `coulomb/binky-control`
- Claude Code on the host (or hosted adapter) for real agentic sessions
- T03 issue-core intake for scheduled task consumption