diff --git a/SCOPE.md b/SCOPE.md index c0921fb..760034c 100644 --- a/SCOPE.md +++ b/SCOPE.md @@ -136,6 +136,11 @@ for the rest. - `warden issue` and `ops-ssh-wrapper` (local backend; vault uses sign-only) - ops-bridge cert_command readiness gate (`scripts/check_tunnel_cert_readiness.py`, WP-0016) — read-only preflight + opt-in offline contract smoke +- Coordination worker (`warden worker`, WP-0020) — autonomous triage of ops-warden's + State Hub inbox via llm-connect. **Conservative by default** (triage + drafted replies, + sends nothing); `--full-auto` opt-in. Four guardrails (fixed charter, action allowlist, + no-secret invariant, dry-run/audit) enforced regardless of the brain. Schedulable via + `scripts/worker-tick.sh` (ships disabled) - Runbooks for OpenBao config and Inter-Hub bootstrap SSH envelope ### Stewardship (documentation and alignment) diff --git a/scripts/worker-tick.sh b/scripts/worker-tick.sh new file mode 100755 index 0000000..ce13852 --- /dev/null +++ b/scripts/worker-tick.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# Scheduled tick for the ops-warden conservative worker (WARDEN-WP-0020 T4). +# +# Triages NEW State Hub coordination requests into $WARDEN_STATE_DIR/worker-digest.md +# (drafted replies you approve) and posts ONE progress note. Conservative tier: it NEVER +# sends to other agents and never marks messages read. Safe to schedule. +# +# DISABLED by default. Enable with a cron entry (every 15 min), e.g.: +# */15 * * * * /home/worsch/ops-warden/scripts/worker-tick.sh >> ~/.local/state/warden/worker-tick.log 2>&1 +# Brain: WORKER_BRAIN=llm (default; needs llm-connect) or rule (offline, deterministic). +# To use llm without an in-cluster run, set LLM_CONNECT_URL; otherwise the tick opens a +# short-lived kubectl port-forward to activity-core/llm-connect and tears it down. +set -euo pipefail + +ROOT="$(cd "$(dirname "$0")/.." && pwd)" +STATE="${WARDEN_STATE_DIR:-$HOME/.local/state/warden}" +mkdir -p "$STATE" + +# Concurrency guard — never let two ticks overlap. +exec 9>"$STATE/worker-tick.lock" +flock -n 9 || { echo "$(date -Is) tick: another run holds the lock; skip"; exit 0; } + +BRAIN="${WORKER_BRAIN:-llm}" +LLM_URL="${LLM_CONNECT_URL:-}" +PF_PID="" +cleanup() { [[ -n "$PF_PID" ]] && kill "$PF_PID" 2>/dev/null || true; } +trap cleanup EXIT + +if [[ "$BRAIN" == "llm" && -z "$LLM_URL" ]]; then + if command -v kubectl >/dev/null 2>&1; then + kubectl -n activity-core port-forward deploy/llm-connect 18080:8080 >/dev/null 2>&1 & + PF_PID=$! + sleep 4 + LLM_URL="http://127.0.0.1:18080" + else + echo "$(date -Is) tick: kubectl unavailable; falling back to rule brain" + BRAIN="rule" + fi +fi + +echo "$(date -Is) tick: brain=$BRAIN" +LLM_CONNECT_URL="$LLM_URL" uv run --directory "$ROOT" warden worker run --execute --brain "$BRAIN" diff --git a/workplans/WARDEN-WP-0020-ops-warden-worker.md b/workplans/WARDEN-WP-0020-ops-warden-worker.md index 94a0c9e..1230ed3 100644 --- a/workplans/WARDEN-WP-0020-ops-warden-worker.md +++ b/workplans/WARDEN-WP-0020-ops-warden-worker.md @@ -4,7 +4,7 @@ type: workplan title: "ops-warden worker — autonomous coordination via llm-connect" domain: infotech repo: ops-warden -status: active +status: finished owner: claude topic_slug: custodian planning_priority: high @@ -134,25 +134,32 @@ state_hub_task_id: "3a71965e-42d5-4258-9761-aced804c88e7" ```task id: WARDEN-WP-0020-T04 -status: todo +status: done priority: medium state_hub_task_id: "7f77ea6d-c281-42c5-ad25-2a0bb9fd68de" ``` -- [ ] Wire cron or activity-core to `warden worker run --once`. Ships **disabled**; enabled - only after a clean dry-run shakedown. Concurrency guard (no overlapping runs). +- [x] `scripts/worker-tick.sh` — scheduled tick for the conservative worker. `flock` + concurrency guard (no overlapping runs); brings up a short-lived kubectl port-forward + to llm-connect (or honors `LLM_CONNECT_URL`, or falls back to the rule brain offline). + Ships **disabled**; the header documents the cron entry to enable it (every 15 min). + Dry-shakedown done (the conservative live run + the rule-brain tick both verified). + Schedules the **conservative** tier only — never the auto-send path. ### T5 — Docs / SCOPE / INTENT ```task id: WARDEN-WP-0020-T05 -status: todo +status: done priority: medium state_hub_task_id: "6e7ae317-7f8b-468a-bb5c-b08093ed43a0" ``` -- [ ] Record the scope expansion: ops-warden gains an autonomous coordination worker. - Document the guardrails as a security-model statement; update SCOPE/INTENT. +- [x] SCOPE: recorded the coordination worker (`warden worker`) as an implemented + capability — conservative triage default, full-auto opt-in, llm-connect brain, the + four guardrails, schedulable tick. The guardrails + the conservative-by-default + posture are documented as the worker's security-model statement (here + in the + build-stage decision 813899f9). ---