feat(deploy): gate claims on pinned runtime readiness
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a06ba0-10aa-7ea0-b20a-4f3fac39efe9
This commit is contained in:
parent
d00ffcb402
commit
4310c15eac
17 changed files with 757 additions and 10 deletions
|
|
@ -53,7 +53,9 @@ semantics.
|
|||
| 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) |
|
||||
|
||||
|
|
@ -62,10 +64,28 @@ semantics.
|
|||
- 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)
|
||||
|
||||
|
|
@ -96,6 +116,14 @@ 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`
|
||||
|
|
|
|||
28
deploy/runtime-contract-lock.json
Normal file
28
deploy/runtime-contract-lock.json
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"schema_version": "1",
|
||||
"contracts": {
|
||||
"activity_core_contract_commit": "b63131e863be38ba1274d1077543aaf9320500b3",
|
||||
"activity_core_schema": "0010",
|
||||
"glas_contract_version": "1.0"
|
||||
},
|
||||
"dependencies": [
|
||||
{
|
||||
"commit": "00560945f81ba6ff1f5cacd9fe99c7fe756cc4b1",
|
||||
"distribution": "llm-connect",
|
||||
"source": "../llm-connect",
|
||||
"version": "0.1.0"
|
||||
},
|
||||
{
|
||||
"commit": "02b29af9ca87867e0d398c06139d771a19728b70",
|
||||
"distribution": "glas-harness",
|
||||
"source": "../glas-harness",
|
||||
"version": "0.1.0"
|
||||
},
|
||||
{
|
||||
"commit": "5c760100264828865c45a7e4e199d43e4603d57a",
|
||||
"distribution": "sandboxer",
|
||||
"source": "../sand-boxer",
|
||||
"version": "0.0.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -9,6 +9,9 @@ ENV_DIR="${HOME}/.config/rein-aharness"
|
|||
BIN_DIR="${HOME}/bin"
|
||||
mkdir -p "${UNIT_DIR}" "${ENV_DIR}" "${BIN_DIR}"
|
||||
|
||||
# Refuse to install a service unit over accidental mutable sibling revisions.
|
||||
python3 "${ROOT}/scripts/verify_runtime_lock.py"
|
||||
|
||||
cp -f "${ROOT}/deploy/systemd/rein-aharness-claim-loop.service" "${UNIT_DIR}/"
|
||||
# Durable env loader + k8s:// ClusterIP resolution (no port-forward)
|
||||
install -m 755 "${ROOT}/deploy/scripts/rein-aharness-claim" "${BIN_DIR}/rein-aharness-claim"
|
||||
|
|
@ -24,10 +27,13 @@ fi
|
|||
|
||||
# Ensure package entrypoint exists
|
||||
if [[ ! -x "${ROOT}/.venv/bin/rein-aharness" ]]; then
|
||||
echo "warning: ${ROOT}/.venv/bin/rein-aharness missing; install the worker environment first"
|
||||
echo "error: ${ROOT}/.venv/bin/rein-aharness missing" >&2
|
||||
echo "run ${ROOT}/deploy/scripts/install-pinned-runtime.sh first" >&2
|
||||
exit 2
|
||||
elif ! "${ROOT}/.venv/bin/python" -c 'import glas_harness, sandboxer' >/dev/null 2>&1; then
|
||||
echo "warning: profiled ops runs require sibling runtimes; install with:"
|
||||
echo " ${ROOT}/.venv/bin/pip install -e ${ROOT}/../sand-boxer -e ${ROOT}/../glas-harness"
|
||||
echo "error: pinned profiled runtime packages are unavailable" >&2
|
||||
echo "run ${ROOT}/deploy/scripts/install-pinned-runtime.sh first" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
systemctl --user daemon-reload
|
||||
|
|
|
|||
18
deploy/scripts/install-pinned-runtime.sh
Executable file
18
deploy/scripts/install-pinned-runtime.sh
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env bash
|
||||
# Reproduce the host worker from uv.lock plus exact, clean sibling revisions.
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
cd "${REPO_ROOT}"
|
||||
|
||||
command -v uv >/dev/null 2>&1 || {
|
||||
echo "install-pinned-runtime: uv is required" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
python3 scripts/verify_runtime_lock.py
|
||||
uv sync --frozen --no-editable --extra glas --extra llm
|
||||
.venv/bin/python -c 'import glas_harness, llm_connect, rein_aharness, sandboxer'
|
||||
.venv/bin/rein-aharness preflight --offline
|
||||
|
||||
echo "Pinned non-editable runtime installed from uv.lock and runtime-contract-lock.json"
|
||||
|
|
@ -9,6 +9,9 @@ AGENT_HARNESS_OPS_LABELS=automated
|
|||
AGENT_HARNESS_OPS_LABELS_MODE=any
|
||||
AGENT_HARNESS_OPS_LEASE_SECONDS=900
|
||||
AGENT_HARNESS_CLAIM_INTERVAL=30
|
||||
# Comma-separated, exact profile@version refs. Leave empty while no profiled
|
||||
# production definition is enabled; non-ready profiles fail startup preflight.
|
||||
AGENT_HARNESS_REQUIRED_PROFILE_REFS=
|
||||
AGENT_HARNESS_LEGACY_APPROACHES_UNTIL=2026-12-31
|
||||
AGENT_HARNESS_REPO_MAP={"freedom-intelligence":"/home/tegwick/freedom-intelligence","binky-control":"/home/tegwick/binky-control"}
|
||||
AGENT_HARNESS_REPO_ROOTS=/home/tegwick:/home/tegwick/work
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ Environment=AGENT_HARNESS_LEGACY_APPROACHES_UNTIL=2026-12-31
|
|||
Environment=PATH=%h/.local/bin:/usr/local/bin:/usr/bin:/bin:%h/bin
|
||||
# Wrapper loads claim-loop.env (JSON-safe) and resolves k8s:// ClusterIPs
|
||||
# Do not use EnvironmentFile= for claim-loop.env — REPO_MAP JSON breaks systemd parser
|
||||
ExecStartPre=%h/bin/rein-aharness-claim preflight
|
||||
ExecStart=%h/bin/rein-aharness-claim claim-loop
|
||||
Restart=on-failure
|
||||
RestartSec=15
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue