Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a02b6f-7db1-7222-918b-e813a6bda38d
5.4 KiB
Ops run claim loop (REIN-A-0002)
Primary intake for activity-core scheduled automation.
Architecture: ACT-ADR-005 · activity-core ops-run-queue.md
Does not require issue-core or Forgejo for FI / Binky-style ops.
Flow
activity-core emit_tasks
→ INSERT ops_run (open, optional harness_profile_ref) + activity_task_spawn
│
▼
rein-aharness claim-loop
POST /ops-runs/claim
harness_profile_ref present? ─ yes → Glas ExecutionRequest → gateway
│ no
└─→ select_approach(labels, definition, hint) → legacy executor
POST complete | fail(+reopen)
harness_profile_ref is authoritative under ACT-ADR-006. A profiled row never
consults approach_hint, select_approach, or a legacy executor, including
after profile resolution refusal. The claim worker sends the complete
GatewayResult to Activity Core; Activity Core persists its allowlisted
ExecutionEvidence and drops direct tool output/error. Profile-absent rows keep
the legacy coexistence path until the migration flag is enabled upstream.
Environment
| Variable | Default | Meaning |
|---|---|---|
ACTIVITY_CORE_URL |
http://127.0.0.1:8010 |
actcore-api base |
ACTIVITY_CORE_WORKER_TOKEN |
unset | X-Worker-Token / Bearer |
AGENT_HARNESS_WORKER_ID |
rein-aharness@hostname |
claim owner |
AGENT_HARNESS_OPS_LABELS |
automated |
claim label filter |
AGENT_HARNESS_OPS_LABELS_MODE |
any |
any or all |
AGENT_HARNESS_OPS_LEASE_SECONDS |
900 |
claim lease |
AGENT_HARNESS_CLAIM_INTERVAL |
30 |
empty-queue poll interval |
AGENT_HARNESS_REPO_MAP |
{} |
JSON slug→checkout path |
AGENT_HARNESS_REPO_ROOTS |
~:~/work |
slug search roots |
Example map on railiance01:
export AGENT_HARNESS_REPO_MAP='{
"freedom-intelligence":"/home/tegwick/freedom-intelligence",
"binky-control":"/home/tegwick/binky-control"
}'
export ACTIVITY_CORE_URL=http://127.0.0.1:8010 # or ClusterIP via tunnel
export ACTIVITY_CORE_WORKER_TOKEN=… # from actcore-runtime-secret
Approach registry
| Match | Approach |
|---|---|
labels research-brief / freedom-intelligence or fi-daily* |
fi-research-brief |
labels rhythm / binky-daily or binky-daily* |
brief-daily |
labels binky + weekly-review or binky-weekly-review* |
brief-weekly |
labels mail-intake |
mail-scan then mail-triage |
labels agent-session |
agentic run (TaskSpec) |
| none | fail ops_run (no silent drop) |
For a profile-absent legacy row, optional approach_hint overrides matching.
It has no effect when harness_profile_ref is present.
Add a row: edit rein_aharness/approaches.py (APPROACH_RULES + execute_approach)
and tests in tests/test_approaches.py. Prefer cheapest correct path
(structured llm-connect before open-ended agent session).
CLI
# Peek open ops_runs + selected approach
rein-aharness poll --source=ops-run --no-claim
# Claim one, execute approach, complete/fail
rein-aharness run --from-ops-run
# or
rein-aharness poll --source=ops-run
# Continuous worker (systemd)
rein-aharness claim-loop
rein-aharness claim-loop --once --verbose
# Dry-run: claim then fail+reopen without domain work
rein-aharness poll --source=ops-run --dry-run
Legacy issue-core (external tickets only):
rein-aharness poll --source=issue-core
rein-aharness run --from-issue-core
Install claim-loop on railiance01 (user systemd)
# From rein-aharness checkout on railiance01
python3 -m venv .venv
.venv/bin/pip install -e . -e ../llm-connect -e ../sand-boxer -e ../glas-harness
./deploy/scripts/install-claim-loop-user.sh
# Or manually:
mkdir -p ~/.config/systemd/user
cp deploy/systemd/rein-aharness-claim-loop.service ~/.config/systemd/user/
# Edit Environment= paths / token in the unit or env file
systemctl --user daemon-reload
systemctl --user enable --now rein-aharness-claim-loop.service
journalctl --user -u rein-aharness-claim-loop -f
Host access to cluster services (no port-forward)
On railiance01 (single-node k3s), set k8s:// pseudo-URLs in
claim-loop.env (see deploy/systemd/claim-loop.env.example). The
~/bin/rein-aharness-claim wrapper resolves them to Service ClusterIPs at
start. Canon: activity-core docs/llm-connect-host-access.md.
# migrate existing env
./deploy/scripts/refresh-claim-loop-k8s-urls.sh
# reinstall wrapper
./deploy/scripts/install-claim-loop-user.sh
systemctl --user restart rein-aharness-claim-loop.service
Deprecated: long-lived kubectl port-forward to 127.0.0.1:8010 / :8080.
Legacy note (break-glass only) if ClusterIP routing is broken:
kubectl -n activity-core port-forward svc/actcore-api 8010:8010
export ACTIVITY_CORE_URL=http://127.0.0.1:8010
Cutover from host timers (T05)
Host oneshot timers (FI 07:35, Binky rhythm) remain break-glass until:
- claim-loop is running and healthy
- 5 clean weekday cycles (or 5 forced triggers) with open→claimed→succeeded
- Then disable or demote timers — see
deploy/docs/timer-cutover.md
Until then dual-path is intentional: schedule truth is activity-core; timers are a safety net if claim-loop is down.
Labels required on definitions
| Domain | Labels (min) |
|---|---|
| Freedom Intelligence | automated, research-brief (already on FI rule) |
| Binky daily | automated, rhythm |
| Binky mail | automated, mail-intake |