From f6930ad115df6ddd60dde1cefb640346dd51f8fb Mon Sep 17 00:00:00 2001 From: tegwick Date: Sun, 26 Jul 2026 14:22:18 +0200 Subject: [PATCH] Rename package, CLI, and deploy artifacts to rein-aharness (HARNESS-WP-0002-T02) agent_harness -> rein_aharness (package + all imports), CLI command agent-harness -> rein-aharness, Docker image tag, k8s namespace/labels/ names, Makefile targets, deploy script env var/paths. In-repo identity strings (hub event source, metrics harness field, default assignee, argparse prog name, commit author identity) updated to match. Historical documents left untouched on purpose: docs/adr/ADR-001-agent-harness-architecture.md, docs/architecture.md (dated v0.1 snapshot), workplans/HARNESS-WP-0001 (completed under the old name), and the SSH host alias "forgejo-agent-harness" (external ~/.ssh/config entry, not owned here). Verified: 47/47 tests pass, CLI runs correctly from a fresh venv, `make image` builds and the resulting container runs correctly. deploy/README.md gained an explicit rename cutover checklist for what this session cannot safely do unattended -- moving the host-side secrets dir and checkout on railiance01, and not deleting the old k8s namespace until the new one is confirmed working. The actual live cutover (running that checklist against the real Railiance deployment) is not attempted here -- real production surgery on binky-control's live automation, needs the operator present. Co-Authored-By: Claude Sonnet 5 --- Containerfile | 8 +-- Makefile | 8 +-- README.md | 35 +++++++------ WORK-RECORDS.md | 2 +- deploy/README.md | 45 ++++++++++++----- deploy/k8s/railiance/00-namespace.yaml | 6 +-- deploy/k8s/railiance/configmap.yaml | 6 +-- deploy/k8s/railiance/deployment.yaml | 20 ++++---- deploy/k8s/railiance/job-smoke.yaml | 12 ++--- deploy/k8s/railiance/kustomization.yaml | 2 +- deploy/scripts/railiance-smoke.sh | 15 ++++-- docs/instance-manifest.md | 14 +++--- docs/task-intake.md | 16 +++--- examples/schedule.harness.yml | 4 +- pyproject.toml | 4 +- {agent_harness => rein_aharness}/__init__.py | 0 {agent_harness => rein_aharness}/adapter.py | 2 +- .../brief_daily.py | 4 +- {agent_harness => rein_aharness}/cli.py | 22 ++++----- {agent_harness => rein_aharness}/hub.py | 2 +- {agent_harness => rein_aharness}/intake.py | 8 +-- .../llm_connect_client.py | 2 +- .../mail_triage.py | 4 +- {agent_harness => rein_aharness}/mailscan.py | 4 +- {agent_harness => rein_aharness}/manifest.py | 4 +- {agent_harness => rein_aharness}/metrics.py | 2 +- {agent_harness => rein_aharness}/persona.py | 0 {agent_harness => rein_aharness}/profiles.py | 0 {agent_harness => rein_aharness}/runner.py | 12 ++--- {agent_harness => rein_aharness}/smoke.py | 10 ++-- {agent_harness => rein_aharness}/taskspec.py | 0 scripts/tenant_onboard_runs.py | 8 +-- tests/test_brief_daily.py | 2 +- tests/test_intake.py | 12 ++--- tests/test_mail_triage.py | 8 +-- tests/test_mailscan.py | 2 +- tests/test_manifest.py | 6 +-- tests/test_metrics.py | 4 +- tests/test_runner.py | 6 +-- tests/test_smoke.py | 2 +- ...-0002-rename-and-glas-harness-alignment.md | 49 +++++++++++++++---- 41 files changed, 214 insertions(+), 158 deletions(-) rename {agent_harness => rein_aharness}/__init__.py (100%) rename {agent_harness => rein_aharness}/adapter.py (98%) rename {agent_harness => rein_aharness}/brief_daily.py (99%) rename {agent_harness => rein_aharness}/cli.py (95%) rename {agent_harness => rein_aharness}/hub.py (98%) rename {agent_harness => rein_aharness}/intake.py (97%) rename {agent_harness => rein_aharness}/llm_connect_client.py (97%) rename {agent_harness => rein_aharness}/mail_triage.py (99%) rename {agent_harness => rein_aharness}/mailscan.py (98%) rename {agent_harness => rein_aharness}/manifest.py (98%) rename {agent_harness => rein_aharness}/metrics.py (99%) rename {agent_harness => rein_aharness}/persona.py (100%) rename {agent_harness => rein_aharness}/profiles.py (100%) rename {agent_harness => rein_aharness}/runner.py (95%) rename {agent_harness => rein_aharness}/smoke.py (93%) rename {agent_harness => rein_aharness}/taskspec.py (100%) diff --git a/Containerfile b/Containerfile index 292ca17..3a54d0b 100644 --- a/Containerfile +++ b/Containerfile @@ -1,5 +1,5 @@ -# agent-harness — shared unattended agent runtime (Railiance / local). -# Build: docker build -f Containerfile -t agent-harness:local . +# rein-aharness — shared unattended agent runtime (Railiance / local). +# Build: docker build -f Containerfile -t rein-aharness:local . # Optional llm-connect sibling: docker build --build-arg WITH_LLM_CONNECT=1 ... FROM python:3.12-slim @@ -17,7 +17,7 @@ RUN apt-get update \ && useradd -u 10001 -g 10001 -m -s /usr/sbin/nologin harness COPY pyproject.toml README.md ./ -COPY agent_harness ./agent_harness +COPY rein_aharness ./rein_aharness # Populated by `make image` from ../llm-connect when present. COPY llm_connect_vendor ./llm_connect_vendor @@ -31,5 +31,5 @@ RUN pip install --no-cache-dir "httpx>=0.27" "PyYAML>=6.0" \ USER 10001:10001 # No long-running HTTP API yet — image is invoked as CLI (run / smoke / validate). -ENTRYPOINT ["agent-harness"] +ENTRYPOINT ["rein-aharness"] CMD ["profiles"] diff --git a/Makefile b/Makefile index 227fa55..1af464d 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ .PHONY: test image image-export deploy-rsync help UV ?= $(shell command -v uv 2>/dev/null || echo uv) -IMAGE ?= agent-harness:railiance01 -TAR ?= /tmp/agent-harness-railiance01.tar +IMAGE ?= rein-aharness:railiance01 +TAR ?= /tmp/rein-aharness-railiance01.tar help: ## Show targets @grep -Eh '^[a-zA-Z_-]+:.*?##' $(MAKEFILE_LIST) | \ @@ -26,8 +26,8 @@ image-export: image ## Save image tar for k3s import docker save -o $(TAR) $(IMAGE) @ls -lh $(TAR) -deploy-rsync: ## Rsync tree to railiance01:~/agent-harness +deploy-rsync: ## Rsync tree to railiance01:~/rein-aharness rsync -az --delete \ --exclude '.git' --exclude '__pycache__' --exclude '.pytest_cache' \ --exclude 'llm_connect_vendor' --exclude '*.egg-info' \ - ./ railiance01:agent-harness/ + ./ railiance01:rein-aharness/ diff --git a/README.md b/README.md index 6abe9d2..bcebf1f 100644 --- a/README.md +++ b/README.md @@ -14,14 +14,17 @@ tenants that need governed cron-style agent runs. See [glas-harness ADR-001](../glas-harness/docs/adr/ADR-001-rein-harness-family.md) for how it relates to other reins (e.g. `rein-openweights`). -The CLI command (`agent-harness`), Python package (`agent_harness`), and -deploy artifacts (Docker image tag, k8s namespace, Railiance host paths) -still use the old name — that rename is tracked separately in -[workplans/REIN-A-WP-0002](workplans/REIN-A-WP-0002-rename-and-glas-harness-alignment.md) -because it touches a live Railiance deployment. +The CLI command (`rein-aharness`) and Python package (`rein_aharness`) are +renamed. Deploy artifacts (Docker image tag, k8s namespace, Railiance host +paths) are renamed in this repo too, but the live Railiance cutover itself +(moving the host-side checkout + secrets dir, redeploying) is a separate, +deliberate step — tracked in +[workplans/HARNESS-WP-0002](workplans/HARNESS-WP-0002-rename-and-glas-harness-alignment.md) +and [deploy/README.md](deploy/README.md)'s rename cutover checklist. - Why and boundaries: [INTENT.md](INTENT.md) -- Decision + architecture: [docs/adr/ADR-001](docs/adr/ADR-001-agent-harness-architecture.md), +- Decision + architecture: [docs/adr/ADR-001](docs/adr/ADR-001-agent-harness-architecture.md) + (kept under its original filename — it documents the pre-rename decision), [docs/architecture.md](docs/architecture.md) - Current work: [workplans/](workplans/) @@ -29,33 +32,33 @@ because it touches a live Railiance deployment. ``` # Validate a consuming repo's instance manifest (.kaizen/schedule.yml) -agent-harness validate --target ~/binky-control -agent-harness validate --target ~/binky-control --strict # require harness fields +rein-aharness validate --target ~/binky-control +rein-aharness validate --target ~/binky-control --strict # require harness fields # List named tool profiles -agent-harness profiles +rein-aharness profiles # Run exactly one task (local JSON task-file path — dev) -agent-harness run --task-file examples/task-hello-sandbox.json [--no-hub] [--no-metrics] +rein-aharness run --task-file examples/task-hello-sandbox.json [--no-hub] [--no-metrics] # Production intake: poll issue-core (activity-core emissions), claim, run, close export ISSUE_CORE_URL=http://127.0.0.1:8765 ISSUE_CORE_API_KEY=… -agent-harness poll -agent-harness run --from-issue-core +rein-aharness poll +rein-aharness run --from-issue-core # Deterministic mailbox scan (no LLM session) -agent-harness mail-scan --target-repo ~/binky-control +rein-aharness mail-scan --target-repo ~/binky-control # Mail triage via llm-connect HTTP (OpenRouter behind the service; no Claude CLI) export LLM_CONNECT_URL=http://llm-connect.activity-core.svc.cluster.local:8080 -agent-harness mail-triage --target-repo ~/binky-control +rein-aharness mail-triage --target-repo ~/binky-control # Daily brief via llm-connect (structured JSON → briefs/YYYY-MM-DD-daily-brief.md) -agent-harness brief-daily --target-repo ~/binky-control +rein-aharness brief-daily --target-repo ~/binky-control # Railiance packaging smoke (commit + optional push + hub; no Claude required) -agent-harness smoke --work-dir ~/work/executor-sandbox +rein-aharness smoke --work-dir ~/work/executor-sandbox ``` Railiance deploy: [deploy/README.md](deploy/README.md). diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index ec77ac3..cf18423 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -20,7 +20,7 @@ | task | HARNESS-WP-0001-T07 | done | — | workplans/HARNESS-WP-0001-harness-foundation.md | | task | HARNESS-WP-0002-T01 | done | — | workplans/HARNESS-WP-0002-rename-and-glas-harness-alignment.md | | task | HARNESS-WP-0002-T02 | todo | — | workplans/HARNESS-WP-0002-rename-and-glas-harness-alignment.md | -| task | HARNESS-WP-0002-T03 | todo | — | workplans/HARNESS-WP-0002-rename-and-glas-harness-alignment.md | +| task | HARNESS-WP-0002-T03 | progress | — | workplans/HARNESS-WP-0002-rename-and-glas-harness-alignment.md | | task | HARNESS-WP-0002-T04 | todo | — | workplans/HARNESS-WP-0002-rename-and-glas-harness-alignment.md | | task | REIN-A-0001-T01 | todo | — | workplans/REIN-A-0001-statehub-bootstrap.md | | task | REIN-A-0001-T02 | todo | — | workplans/REIN-A-0001-statehub-bootstrap.md | diff --git a/deploy/README.md b/deploy/README.md index f383914..90b0726 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -3,6 +3,25 @@ Single shared harness instance on **railiance01**. Secrets stay on the host (Lanes 2–3); the container image is the portable runtime package. +> **Renamed from agent-harness (HARNESS-WP-0002-T02).** Image tag, k8s +> namespace/labels, CLI command, and Python package are all renamed in +> this repo already. The commands below assume the **rename cutover +> checklist** just below has been done on railiance01 first — this is a +> live production deployment for `binky-control`, so the cutover itself +> is deliberately not automated from a workstation session. + +## Rename cutover checklist (do this on railiance01 before redeploying) + +1. Move the host-side secrets dir: `mv ~/.local/agent-harness ~/.local/rein-aharness` + (or symlink, if anything else still reads the old path). +2. Move/rename the checkout: `mv ~/agent-harness ~/rein-aharness` (or a fresh + `deploy-rsync` to the new path — see Makefile). +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 | @@ -10,31 +29,31 @@ Single shared harness instance on **railiance01**. Secrets stay on the host | `Containerfile` | Image: Python CLI + git + openssh; optional vendored llm-connect | | `deploy/k8s/railiance/` | Namespace, ConfigMap, Deployment, smoke Job | | `deploy/scripts/railiance-smoke.sh` | Host e2e: clone sandbox → commit → push → hub | -| `agent-harness smoke` | Deterministic smoke (no Claude Code required) | +| `rein-aharness smoke` | Deterministic smoke (no Claude Code required) | -## Prerequisites (done 2026-07-17) +## 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/agent-harness/approle-binky-mail` -- `source ~/.local/agent-harness/env` +- Lane 3 AppRole under `~/.local/rein-aharness/approle-binky-mail` +- `source ~/.local/rein-aharness/env` - Hub: `http://127.0.0.1:18000` (ops-bridge) or in-cluster `state-hub.state-hub.svc` ## Build & load image (workstation → railiance01) ```bash -# from agent-harness repo root -make image # tags agent-harness:railiance01 -make image-export # /tmp/agent-harness-railiance01.tar -scp /tmp/agent-harness-railiance01.tar railiance01:/tmp/ -ssh railiance01 sudo k3s ctr images import /tmp/agent-harness-railiance01.tar +# 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:agent-harness/deploy/k8s/railiance/ -ssh railiance01 kubectl apply -k agent-harness/deploy/k8s/railiance/ -ssh railiance01 kubectl -n agent-harness rollout status deploy/agent-harness +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) @@ -42,7 +61,7 @@ ssh railiance01 kubectl -n agent-harness rollout status deploy/agent-harness Full path uses the host deploy key and hub bridge: ```bash -ssh railiance01 'bash ~/agent-harness/deploy/scripts/railiance-smoke.sh' +ssh railiance01 'bash ~/rein-aharness/deploy/scripts/railiance-smoke.sh' ``` Expect: local commit + push to `executor-sandbox`, hub event `harness_smoke`, diff --git a/deploy/k8s/railiance/00-namespace.yaml b/deploy/k8s/railiance/00-namespace.yaml index 93375a3..dac0910 100644 --- a/deploy/k8s/railiance/00-namespace.yaml +++ b/deploy/k8s/railiance/00-namespace.yaml @@ -1,7 +1,7 @@ apiVersion: v1 kind: Namespace metadata: - name: agent-harness + name: rein-aharness labels: - app.kubernetes.io/part-of: agent-harness - app.kubernetes.io/name: agent-harness + app.kubernetes.io/part-of: rein-aharness + app.kubernetes.io/name: rein-aharness diff --git a/deploy/k8s/railiance/configmap.yaml b/deploy/k8s/railiance/configmap.yaml index 6de25b2..02a0e0f 100644 --- a/deploy/k8s/railiance/configmap.yaml +++ b/deploy/k8s/railiance/configmap.yaml @@ -1,10 +1,10 @@ apiVersion: v1 kind: ConfigMap metadata: - name: agent-harness-config - namespace: agent-harness + name: rein-aharness-config + namespace: rein-aharness labels: - app.kubernetes.io/name: agent-harness + app.kubernetes.io/name: rein-aharness data: # In-cluster State Hub (production). Host-level smoke may override to # http://127.0.0.1:18000 (ops-bridge reverse tunnel to workstation hub). diff --git a/deploy/k8s/railiance/deployment.yaml b/deploy/k8s/railiance/deployment.yaml index d62b8ec..06b6b00 100644 --- a/deploy/k8s/railiance/deployment.yaml +++ b/deploy/k8s/railiance/deployment.yaml @@ -3,32 +3,32 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: agent-harness - namespace: agent-harness + name: rein-aharness + namespace: rein-aharness labels: - app.kubernetes.io/name: agent-harness - app.kubernetes.io/part-of: agent-harness + app.kubernetes.io/name: rein-aharness + app.kubernetes.io/part-of: rein-aharness spec: replicas: 1 selector: matchLabels: - app.kubernetes.io/name: agent-harness + app.kubernetes.io/name: rein-aharness template: metadata: labels: - app.kubernetes.io/name: agent-harness - app.kubernetes.io/part-of: agent-harness + app.kubernetes.io/name: rein-aharness + app.kubernetes.io/part-of: rein-aharness spec: securityContext: fsGroup: 10001 containers: - - name: agent-harness - image: agent-harness:railiance01 + - name: rein-aharness + image: rein-aharness:railiance01 imagePullPolicy: Never command: ["sleep", "infinity"] envFrom: - configMapRef: - name: agent-harness-config + name: rein-aharness-config resources: requests: cpu: 25m diff --git a/deploy/k8s/railiance/job-smoke.yaml b/deploy/k8s/railiance/job-smoke.yaml index 08ba245..fd518cf 100644 --- a/deploy/k8s/railiance/job-smoke.yaml +++ b/deploy/k8s/railiance/job-smoke.yaml @@ -4,10 +4,10 @@ apiVersion: batch/v1 kind: Job metadata: - name: agent-harness-smoke - namespace: agent-harness + name: rein-aharness-smoke + namespace: rein-aharness labels: - app.kubernetes.io/name: agent-harness + app.kubernetes.io/name: rein-aharness app.kubernetes.io/component: smoke spec: ttlSecondsAfterFinished: 600 @@ -15,7 +15,7 @@ spec: template: metadata: labels: - app.kubernetes.io/name: agent-harness + app.kubernetes.io/name: rein-aharness app.kubernetes.io/component: smoke spec: restartPolicy: Never @@ -23,13 +23,13 @@ spec: fsGroup: 10001 containers: - name: smoke - image: agent-harness:railiance01 + image: rein-aharness:railiance01 imagePullPolicy: Never args: - "profiles" envFrom: - configMapRef: - name: agent-harness-config + name: rein-aharness-config resources: requests: cpu: 50m diff --git a/deploy/k8s/railiance/kustomization.yaml b/deploy/k8s/railiance/kustomization.yaml index e9dbf38..baee3a8 100644 --- a/deploy/k8s/railiance/kustomization.yaml +++ b/deploy/k8s/railiance/kustomization.yaml @@ -1,6 +1,6 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization -namespace: agent-harness +namespace: rein-aharness resources: - 00-namespace.yaml - configmap.yaml diff --git a/deploy/scripts/railiance-smoke.sh b/deploy/scripts/railiance-smoke.sh index 09adc88..75d63a4 100755 --- a/deploy/scripts/railiance-smoke.sh +++ b/deploy/scripts/railiance-smoke.sh @@ -1,17 +1,22 @@ #!/usr/bin/env bash -# Host-level Railiance smoke for agent-harness (HARNESS-WP-0001-T06). +# Host-level Railiance smoke for rein-aharness (HARNESS-WP-0001-T06). # Run on railiance01 after install. Uses deploy key + AppRole env + hub :18000. +# +# HARNESS-WP-0002-T02 rename: ROOT default and the AppRole env path below +# changed from agent-harness to rein-aharness. Both must exist under the +# NEW name on the host (checkout dir + ~/.local/rein-aharness/) before this +# script is deployed — see deploy/README.md "Rename cutover checklist". set -euo pipefail -ROOT="${AGENT_HARNESS_ROOT:-$HOME/agent-harness}" +ROOT="${REIN_AHARNESS_ROOT:-$HOME/rein-aharness}" # shellcheck disable=SC1090 -source "${HOME}/.local/agent-harness/env" +source "${HOME}/.local/rein-aharness/env" export STATE_HUB_URL="${STATE_HUB_URL:-http://127.0.0.1:18000}" export PATH="${HOME}/.local/bin:${PATH}" export PYTHONPATH="${ROOT}:${HOME}/llm-connect${PYTHONPATH:+:$PYTHONPATH}" cd "$ROOT" -if ! command -v agent-harness >/dev/null 2>&1; then +if ! command -v rein-aharness >/dev/null 2>&1; then python3 -m pip install --user -e . -q fi @@ -19,6 +24,6 @@ echo "STATE_HUB_URL=$STATE_HUB_URL" curl -sS -m 5 "$STATE_HUB_URL/state/health" || curl -sS -m 5 "${STATE_HUB_URL%/}/" || true echo -agent-harness smoke \ +rein-aharness smoke \ --work-dir "${HOME}/work/executor-sandbox" \ --remote "ssh://git@forgejo-agent-harness/coulomb/executor-sandbox.git" diff --git a/docs/instance-manifest.md b/docs/instance-manifest.md index fc0df58..3d398a2 100644 --- a/docs/instance-manifest.md +++ b/docs/instance-manifest.md @@ -10,7 +10,7 @@ ``` **Same file as ADR-005.** kaizen-agentic owns the base schedule keys; -agent-harness owns the extension keys below. A sibling file is reserved +rein-aharness owns the extension keys below. A sibling file is reserved only if kaizen owners later prefer hard separation — until then, one manifest keeps cadence and runtime policy colocated. @@ -18,8 +18,8 @@ Validate: ```bash kaizen-agentic schedule validate --target # base ADR-005 keys -agent-harness validate --target # base + harness extensions -agent-harness validate --target --strict # require harness fields on enabled agents +rein-aharness validate --target # base + harness extensions +rein-aharness validate --target --strict # require harness fields on enabled agents ``` ## Schema @@ -39,12 +39,12 @@ agent-harness validate --target --strict # require harness fields on e | `agents..budget` | harness | no | int | Token cap per run (positive) | | `agents..harness` | harness | no | int | Per-agent major pin; overrides top-level | -\* Required for enabled agents under `agent-harness validate --strict`. +\* Required for enabled agents under `rein-aharness validate --strict`. ## Example (tenant-ready) ```yaml -# .kaizen/schedule.yml — ADR-005 + agent-harness extensions +# .kaizen/schedule.yml — ADR-005 + rein-aharness extensions version: "1" timezone: Europe/Berlin harness: 0 @@ -75,7 +75,7 @@ agents: ## Tool profiles -Defined **only** in agent-harness (see `agent_harness/profiles.py`). +Defined **only** in rein-aharness (see `rein_aharness/profiles.py`). Manifests reference them by name; unknown names refuse to run. | Name | Lane | Session tools | @@ -99,7 +99,7 @@ deliberate. ## Relationship to task files -Local development may still use JSON task files (`agent-harness run +Local development may still use JSON task files (`rein-aharness run --task-file …`). When the target repo has a matching agent entry, the runner resolves `tool_profile`, `budget`, and `lane` from the manifest; otherwise it defaults to `green-commit-only` with no budget cap. diff --git a/docs/task-intake.md b/docs/task-intake.md index 2179efa..ed94d02 100644 --- a/docs/task-intake.md +++ b/docs/task-intake.md @@ -1,13 +1,13 @@ # Task intake (HARNESS-WP-0001-T03) activity-core emits tasks via IssueSink → `POST /issues/` on **issue-core**. -agent-harness **consumes** them by polling the same service: +rein-aharness **consumes** them by polling the same service: ``` activity-core (cron/rule) → IssueCoreRestSink POST /issues/ → issue-core backend (sqlite / gitea) - → agent-harness poll/claim GET+PATCH /issues/ + → rein-aharness poll/claim GET+PATCH /issues/ → run_task (profile + budget + persona + session) → PATCH close + hub progress + .kaizen/metrics ``` @@ -17,8 +17,8 @@ activity-core (cron/rule) ## Mail path (server / Railiance) ``` -agent-harness mail-scan # deterministic IMAP (AppRole) -agent-harness mail-triage # llm-connect HTTP → JSON → apply mail-log + commit +rein-aharness mail-scan # deterministic IMAP (AppRole) +rein-aharness mail-triage # llm-connect HTTP → JSON → apply mail-log + commit ``` Requires `LLM_CONNECT_URL` (e.g. in-cluster @@ -45,14 +45,14 @@ export ISSUE_CORE_API_KEY=… export AGENT_HARNESS_REPO_MAP='{"binky-control":"/home/tegwick/binky-control"}' # Peek / claim without executing -agent-harness poll -agent-harness poll --no-claim +rein-aharness poll +rein-aharness poll --no-claim # Claim → run → close (or reopen on failure) -agent-harness run --from-issue-core +rein-aharness run --from-issue-core # Local dev (unchanged) -agent-harness run --task-file examples/task-hello-sandbox.json --no-hub +rein-aharness run --task-file examples/task-hello-sandbox.json --no-hub ``` ## Label filter diff --git a/examples/schedule.harness.yml b/examples/schedule.harness.yml index d02de89..4ae383a 100644 --- a/examples/schedule.harness.yml +++ b/examples/schedule.harness.yml @@ -1,7 +1,7 @@ -# Example instance manifest (ADR-005 + agent-harness extensions). +# Example instance manifest (ADR-005 + rein-aharness extensions). # Copy keys into a consuming repo's .kaizen/schedule.yml. # Validate with: -# agent-harness validate --target --strict +# rein-aharness validate --target --strict version: "1" timezone: Europe/Berlin harness: 0 diff --git a/pyproject.toml b/pyproject.toml index b6310b0..285f4a7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ dependencies = [ ] [project.scripts] -agent-harness = "agent_harness.cli:main" +rein-aharness = "rein_aharness.cli:main" [tool.uv.sources] llm-connect = { path = "../llm-connect", editable = true } @@ -23,4 +23,4 @@ requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] -packages = ["agent_harness"] +packages = ["rein_aharness"] diff --git a/agent_harness/__init__.py b/rein_aharness/__init__.py similarity index 100% rename from agent_harness/__init__.py rename to rein_aharness/__init__.py diff --git a/agent_harness/adapter.py b/rein_aharness/adapter.py similarity index 98% rename from agent_harness/adapter.py rename to rein_aharness/adapter.py index 8b17a40..1697646 100644 --- a/agent_harness/adapter.py +++ b/rein_aharness/adapter.py @@ -20,7 +20,7 @@ from llm_connect.claude_code import ClaudeCodeAdapter from llm_connect.exceptions import LLMSubprocessError, LLMTimeoutError from llm_connect.models import LLMResponse, RunConfig -from agent_harness.profiles import ToolProfile, get_profile +from rein_aharness.profiles import ToolProfile, get_profile # Backward-compatible alias for the seed profile allow-list string. ALLOWED_TOOLS = get_profile("green-commit-only").allowed_tools diff --git a/agent_harness/brief_daily.py b/rein_aharness/brief_daily.py similarity index 99% rename from agent_harness/brief_daily.py rename to rein_aharness/brief_daily.py index ee730df..89346e4 100644 --- a/agent_harness/brief_daily.py +++ b/rein_aharness/brief_daily.py @@ -16,8 +16,8 @@ from pathlib import Path from typing import Any, Callable from zoneinfo import ZoneInfo -from agent_harness import hub -from agent_harness.llm_connect_client import ( +from rein_aharness import hub +from rein_aharness.llm_connect_client import ( LLMConnectClient, LLMConnectError, get_llm_connect_client, diff --git a/agent_harness/cli.py b/rein_aharness/cli.py similarity index 95% rename from agent_harness/cli.py rename to rein_aharness/cli.py index 566a70d..83fb207 100644 --- a/agent_harness/cli.py +++ b/rein_aharness/cli.py @@ -7,15 +7,15 @@ import json import sys from pathlib import Path -from agent_harness.manifest import ( +from rein_aharness.manifest import ( ManifestError, load_manifest_for_repo, manifest_path, validate_manifest, ) -from agent_harness.profiles import list_profiles -from agent_harness.runner import run_task -from agent_harness.taskspec import TaskSpec, TaskSpecError +from rein_aharness.profiles import list_profiles +from rein_aharness.runner import run_task +from rein_aharness.taskspec import TaskSpec, TaskSpecError def _cmd_validate(args: argparse.Namespace) -> int: @@ -69,7 +69,7 @@ def _cmd_profiles(_args: argparse.Namespace) -> int: def _cmd_poll(args: argparse.Namespace) -> int: - from agent_harness.intake import IntakeError, IssueCoreClient, poll_next + from rein_aharness.intake import IntakeError, IssueCoreClient, poll_next try: client = IssueCoreClient() @@ -100,7 +100,7 @@ def _cmd_poll(args: argparse.Namespace) -> int: def _cmd_run(args: argparse.Namespace) -> int: - from agent_harness.intake import IntakeError, IssueCoreClient, poll_next + from rein_aharness.intake import IntakeError, IssueCoreClient, poll_next issue_id: str | None = None client: IssueCoreClient | None = None @@ -171,7 +171,7 @@ def _cmd_run(args: argparse.Namespace) -> int: def main(argv: list[str] | None = None) -> int: - parser = argparse.ArgumentParser(prog="agent-harness") + parser = argparse.ArgumentParser(prog="rein-aharness") sub = parser.add_subparsers(dest="command", required=True) run = sub.add_parser( @@ -305,7 +305,7 @@ def main(argv: list[str] | None = None) -> int: return _cmd_run(args) if args.command == "smoke": - from agent_harness.smoke import ensure_sandbox_clone, run_smoke + from rein_aharness.smoke import ensure_sandbox_clone, run_smoke if args.target_repo: repo = Path(args.target_repo).expanduser().resolve() @@ -348,7 +348,7 @@ def main(argv: list[str] | None = None) -> int: return 0 if ok else 1 if args.command == "mail-triage": - from agent_harness.mail_triage import run_mail_triage + from rein_aharness.mail_triage import run_mail_triage triage_result = run_mail_triage( target_repo=Path(args.target_repo).expanduser(), @@ -377,7 +377,7 @@ def main(argv: list[str] | None = None) -> int: if args.command == "brief-daily": from datetime import date as date_cls - from agent_harness.brief_daily import run_brief_daily + from rein_aharness.brief_daily import run_brief_daily day = None if args.date: @@ -408,7 +408,7 @@ def main(argv: list[str] | None = None) -> int: return 0 if brief_result.ok else 1 if args.command == "mail-scan": - from agent_harness.mailscan import run_mail_scan + from rein_aharness.mailscan import run_mail_scan result = run_mail_scan( target_repo=Path(args.target_repo).expanduser(), diff --git a/agent_harness/hub.py b/rein_aharness/hub.py similarity index 98% rename from agent_harness/hub.py rename to rein_aharness/hub.py index edcbad2..1f88f7b 100644 --- a/agent_harness/hub.py +++ b/rein_aharness/hub.py @@ -71,7 +71,7 @@ def post_token_event( payload: dict[str, Any] = { "repo": repo, "tokens": tokens, - "source": "agent-harness", + "source": "rein-aharness", "ok": ok, } if budget is not None: diff --git a/agent_harness/intake.py b/rein_aharness/intake.py similarity index 97% rename from agent_harness/intake.py rename to rein_aharness/intake.py index 7eb4876..5add966 100644 --- a/agent_harness/intake.py +++ b/rein_aharness/intake.py @@ -8,11 +8,11 @@ Environment: ISSUE_CORE_URL default http://127.0.0.1:8765 ISSUE_CORE_API_KEY required for live poll AGENT_HARNESS_INTAKE_LABELS comma list; issue must have ALL (default: automated) - AGENT_HARNESS_ASSIGNEE claim assignee (default: agent-harness) + AGENT_HARNESS_ASSIGNEE claim assignee (default: rein-aharness) AGENT_HARNESS_REPO_MAP JSON object name→path, e.g. {"binky-control":"~/binky-control"} AGENT_HARNESS_REPO_ROOTS colon-separated search roots (default: ~:~/work) -Local development still uses `agent-harness run --task-file …`. +Local development still uses `rein-aharness run --task-file …`. """ from __future__ import annotations @@ -25,11 +25,11 @@ from typing import Any import httpx -from agent_harness.taskspec import TaskSpec, TaskSpecError +from rein_aharness.taskspec import TaskSpec, TaskSpecError DEFAULT_ISSUE_CORE_URL = "http://127.0.0.1:8765" DEFAULT_INTAKE_LABELS = ("automated",) -DEFAULT_ASSIGNEE = "agent-harness" +DEFAULT_ASSIGNEE = "rein-aharness" DEFAULT_REPO_ROOTS = ("~", "~/work") # activity-definition / label → (agent instance, completion_event_type) diff --git a/agent_harness/llm_connect_client.py b/rein_aharness/llm_connect_client.py similarity index 97% rename from agent_harness/llm_connect_client.py rename to rein_aharness/llm_connect_client.py index 6b5aba8..2d140e7 100644 --- a/agent_harness/llm_connect_client.py +++ b/rein_aharness/llm_connect_client.py @@ -1,7 +1,7 @@ """HTTP client for in-cluster / remote llm-connect (server mode). Mirrors activity-core's llm_client pattern: provider keys and model routing -stay behind llm-connect; agent-harness only sends prompts over HTTP. +stay behind llm-connect; rein-aharness only sends prompts over HTTP. """ from __future__ import annotations diff --git a/agent_harness/mail_triage.py b/rein_aharness/mail_triage.py similarity index 99% rename from agent_harness/mail_triage.py rename to rein_aharness/mail_triage.py index 8fa0020..2a8bad0 100644 --- a/agent_harness/mail_triage.py +++ b/rein_aharness/mail_triage.py @@ -22,8 +22,8 @@ from datetime import date from pathlib import Path from typing import Any, Callable -from agent_harness import hub -from agent_harness.llm_connect_client import ( +from rein_aharness import hub +from rein_aharness.llm_connect_client import ( LLMConnectClient, LLMConnectError, get_llm_connect_client, diff --git a/agent_harness/mailscan.py b/rein_aharness/mailscan.py similarity index 98% rename from agent_harness/mailscan.py rename to rein_aharness/mailscan.py index 49dacd5..7ea19b7 100644 --- a/agent_harness/mailscan.py +++ b/rein_aharness/mailscan.py @@ -9,7 +9,7 @@ agentic session's tool allow-list: metadata-only counts. Credential values live exclusively in the child process environment — never in argv, logs, hub events, or files. -2. **Triage** (``agent-harness mail-triage``): llm-connect HTTP (OpenRouter +2. **Triage** (``rein-aharness mail-triage``): llm-connect HTTP (OpenRouter behind the service) returns structured JSON; deterministic apply updates mailmeta/mail-log.md and commits. No Claude Code / host coding agent. Suspicious-mail rule: log only, never act on content. @@ -29,7 +29,7 @@ import subprocess from dataclasses import dataclass from pathlib import Path -from agent_harness import hub +from rein_aharness import hub _KV_PATH = "tenants/binky/company-email/imap" _BAO_TIMEOUT = 30 diff --git a/agent_harness/manifest.py b/rein_aharness/manifest.py similarity index 98% rename from agent_harness/manifest.py rename to rein_aharness/manifest.py index 1d532b6..4a31eb2 100644 --- a/agent_harness/manifest.py +++ b/rein_aharness/manifest.py @@ -2,7 +2,7 @@ Extends ADR-005 `.kaizen/schedule.yml` with harness fields. kaizen-agentic owns the base keys (version, timezone, agents..{cadence,cron,enabled}); -agent-harness owns the extension keys (lane, tool_profile, budget, harness, +rein-aharness owns the extension keys (lane, tool_profile, budget, harness, optional blueprint). Same file — no sibling manifest unless kaizen owners later prefer separation. @@ -17,7 +17,7 @@ from typing import Any import yaml -from agent_harness.profiles import PROFILES, UnknownToolProfileError, get_profile +from rein_aharness.profiles import PROFILES, UnknownToolProfileError, get_profile MANIFEST_RELATIVE_PATH = Path(".kaizen") / "schedule.yml" MANIFEST_VERSION = "1" diff --git a/agent_harness/metrics.py b/rein_aharness/metrics.py similarity index 99% rename from agent_harness/metrics.py rename to rein_aharness/metrics.py index be18cf6..4e5fcc5 100644 --- a/agent_harness/metrics.py +++ b/rein_aharness/metrics.py @@ -33,7 +33,7 @@ class ExecutionRecord: committed: bool | None = None head_after: str | None = None reason: str | None = None - harness: str = "agent-harness" + harness: str = "rein-aharness" def to_json_line(self) -> str: data = asdict(self) diff --git a/agent_harness/persona.py b/rein_aharness/persona.py similarity index 100% rename from agent_harness/persona.py rename to rein_aharness/persona.py diff --git a/agent_harness/profiles.py b/rein_aharness/profiles.py similarity index 100% rename from agent_harness/profiles.py rename to rein_aharness/profiles.py diff --git a/agent_harness/runner.py b/rein_aharness/runner.py similarity index 95% rename from agent_harness/runner.py rename to rein_aharness/runner.py index 7248f01..c9d9e4a 100644 --- a/agent_harness/runner.py +++ b/rein_aharness/runner.py @@ -15,11 +15,11 @@ import time from dataclasses import dataclass from pathlib import Path -from agent_harness import hub, metrics -from agent_harness.manifest import resolve_run_policy -from agent_harness.persona import load_persona_bundle -from agent_harness.profiles import UnknownToolProfileError, get_profile -from agent_harness.taskspec import TaskSpec +from rein_aharness import hub, metrics +from rein_aharness.manifest import resolve_run_policy +from rein_aharness.persona import load_persona_bundle +from rein_aharness.profiles import UnknownToolProfileError, get_profile +from rein_aharness.taskspec import TaskSpec PROMPT_TEMPLATE = """\ You are an unattended executor session (agent persona below, if any). @@ -104,7 +104,7 @@ def run_task( ) if adapter is None: - from agent_harness.adapter import AgenticClaudeCodeAdapter + from rein_aharness.adapter import AgenticClaudeCodeAdapter adapter = AgenticClaudeCodeAdapter( workdir=spec.target_repo, diff --git a/agent_harness/smoke.py b/rein_aharness/smoke.py similarity index 93% rename from agent_harness/smoke.py rename to rein_aharness/smoke.py index b8ca122..233858d 100644 --- a/agent_harness/smoke.py +++ b/rein_aharness/smoke.py @@ -12,8 +12,8 @@ from dataclasses import dataclass from datetime import datetime, timezone from pathlib import Path -from agent_harness.runner import RunResult, run_task -from agent_harness.taskspec import TaskSpec +from rein_aharness.runner import RunResult, run_task +from rein_aharness.taskspec import TaskSpec @dataclass @@ -35,7 +35,7 @@ class _CommittingSmokeAdapter: self.prompts.append(prompt) path = self.repo / "SMOKE.md" path.write_text( - f"# agent-harness smoke\n\nstamp: {self.stamp}\n", + f"# rein-aharness smoke\n\nstamp: {self.stamp}\n", encoding="utf-8", ) subprocess.run(["git", "add", "SMOKE.md"], cwd=self.repo, check=True) @@ -43,9 +43,9 @@ class _CommittingSmokeAdapter: [ "git", "-c", - "user.email=agent-harness@railiance.local", + "user.email=rein-aharness@railiance.local", "-c", - "user.name=agent-harness", + "user.name=rein-aharness", "commit", "-qm", f"harness smoke: {self.stamp}", diff --git a/agent_harness/taskspec.py b/rein_aharness/taskspec.py similarity index 100% rename from agent_harness/taskspec.py rename to rein_aharness/taskspec.py diff --git a/scripts/tenant_onboard_runs.py b/scripts/tenant_onboard_runs.py index 1f129d8..7eb5df5 100644 --- a/scripts/tenant_onboard_runs.py +++ b/scripts/tenant_onboard_runs.py @@ -19,8 +19,8 @@ _ROOT = Path(__file__).resolve().parents[1] if str(_ROOT) not in sys.path: sys.path.insert(0, str(_ROOT)) -from agent_harness.runner import run_task -from agent_harness.taskspec import TaskSpec +from rein_aharness.runner import run_task +from rein_aharness.taskspec import TaskSpec class EvidenceAdapter: @@ -47,9 +47,9 @@ class EvidenceAdapter: [ "git", "-c", - "user.email=agent-harness@local", + "user.email=rein-aharness@local", "-c", - "user.name=agent-harness", + "user.name=rein-aharness", "commit", "-qm", f"harness onboard: {self.slug}", diff --git a/tests/test_brief_daily.py b/tests/test_brief_daily.py index c57b31d..67816a4 100644 --- a/tests/test_brief_daily.py +++ b/tests/test_brief_daily.py @@ -5,7 +5,7 @@ import subprocess from datetime import date from pathlib import Path -from agent_harness import brief_daily +from rein_aharness import brief_daily def _git_repo(tmp_path: Path) -> Path: diff --git a/tests/test_intake.py b/tests/test_intake.py index 6abedca..780a15d 100644 --- a/tests/test_intake.py +++ b/tests/test_intake.py @@ -7,7 +7,7 @@ from unittest.mock import MagicMock, patch import pytest -from agent_harness.intake import ( +from rein_aharness.intake import ( EmittedIssue, IntakeConfig, IssueCoreClient, @@ -16,7 +16,7 @@ from agent_harness.intake import ( poll_next, resolve_target_repo, ) -from agent_harness.taskspec import TaskSpecError +from rein_aharness.taskspec import TaskSpecError def _make_repo(tmp_path: Path, name: str = "binky-control") -> Path: @@ -110,7 +110,7 @@ def test_client_list_claim_close() -> None: base_url="http://issue-core.test", api_key="k", require_labels=("automated",), - assignee="agent-harness", + assignee="rein-aharness", ) client = IssueCoreClient(cfg) @@ -126,11 +126,11 @@ def test_client_list_claim_close() -> None: "activity_definition_id": "binky-daily-rhythm", } ] - claim_body = {**list_body[0], "state": "in_progress", "assignee": "agent-harness"} + claim_body = {**list_body[0], "state": "in_progress", "assignee": "rein-aharness"} close_body = {**claim_body, "state": "closed"} - with patch("agent_harness.intake.httpx.get") as get_mock, patch( - "agent_harness.intake.httpx.patch" + with patch("rein_aharness.intake.httpx.get") as get_mock, patch( + "rein_aharness.intake.httpx.patch" ) as patch_mock: get_resp = MagicMock() get_resp.raise_for_status = MagicMock() diff --git a/tests/test_mail_triage.py b/tests/test_mail_triage.py index 83b15c6..ad50d69 100644 --- a/tests/test_mail_triage.py +++ b/tests/test_mail_triage.py @@ -6,8 +6,8 @@ from pathlib import Path import pytest -from agent_harness import mail_triage -from agent_harness.llm_connect_client import LLMConnectClient, LLMConnectError +from rein_aharness import mail_triage +from rein_aharness.llm_connect_client import LLMConnectClient, LLMConnectError def _git_repo(tmp_path: Path) -> Path: @@ -166,7 +166,7 @@ def test_run_mail_triage_no_report(tmp_path: Path, monkeypatch) -> None: def test_llm_connect_client_complete(monkeypatch) -> None: - import agent_harness.llm_connect_client as mod + import rein_aharness.llm_connect_client as mod class FakeResp: def raise_for_status(self) -> None: @@ -190,6 +190,6 @@ def test_llm_connect_client_complete(monkeypatch) -> None: def test_get_client_requires_env(monkeypatch) -> None: monkeypatch.delenv("LLM_CONNECT_URL", raising=False) with pytest.raises(LLMConnectError, match="LLM_CONNECT_URL"): - from agent_harness.llm_connect_client import get_llm_connect_client + from rein_aharness.llm_connect_client import get_llm_connect_client get_llm_connect_client() diff --git a/tests/test_mailscan.py b/tests/test_mailscan.py index 3d476a1..6889a49 100644 --- a/tests/test_mailscan.py +++ b/tests/test_mailscan.py @@ -5,7 +5,7 @@ from pathlib import Path import pytest -from agent_harness import mailscan +from rein_aharness import mailscan class FakeCompleted: diff --git a/tests/test_manifest.py b/tests/test_manifest.py index 11b56a5..4b78c68 100644 --- a/tests/test_manifest.py +++ b/tests/test_manifest.py @@ -5,8 +5,8 @@ from pathlib import Path import pytest import yaml -from agent_harness.cli import main -from agent_harness.manifest import ( +from rein_aharness.cli import main +from rein_aharness.manifest import ( HARNESS_MAJOR, ManifestError, load_manifest, @@ -14,7 +14,7 @@ from agent_harness.manifest import ( resolve_run_policy, validate_manifest, ) -from agent_harness.profiles import UnknownToolProfileError, get_profile, list_profiles +from rein_aharness.profiles import UnknownToolProfileError, get_profile, list_profiles def _write_manifest(tmp_path: Path, data: dict) -> Path: diff --git a/tests/test_metrics.py b/tests/test_metrics.py index 171849e..24c2369 100644 --- a/tests/test_metrics.py +++ b/tests/test_metrics.py @@ -3,7 +3,7 @@ from __future__ import annotations import json from pathlib import Path -from agent_harness.metrics import record_execution, regenerate_summary +from rein_aharness.metrics import record_execution, regenerate_summary def test_record_execution_writes_jsonl_and_summary(tmp_path: Path) -> None: @@ -25,7 +25,7 @@ def test_record_execution_writes_jsonl_and_summary(tmp_path: Path) -> None: assert rec["agent"] == "coach" assert rec["success"] is True assert rec["tokens"] == 100 - assert rec["harness"] == "agent-harness" + assert rec["harness"] == "rein-aharness" assert rec["metadata"]["task_title"] == "hello" summary = json.loads( diff --git a/tests/test_runner.py b/tests/test_runner.py index 89774eb..da6e805 100644 --- a/tests/test_runner.py +++ b/tests/test_runner.py @@ -7,9 +7,9 @@ from pathlib import Path import pytest import yaml -from agent_harness.manifest import HARNESS_MAJOR -from agent_harness.runner import RunResult, run_task -from agent_harness.taskspec import TaskSpec, TaskSpecError +from rein_aharness.manifest import HARNESS_MAJOR +from rein_aharness.runner import RunResult, run_task +from rein_aharness.taskspec import TaskSpec, TaskSpecError def _make_repo(tmp_path: Path) -> Path: diff --git a/tests/test_smoke.py b/tests/test_smoke.py index 4352cdd..c7becdc 100644 --- a/tests/test_smoke.py +++ b/tests/test_smoke.py @@ -3,7 +3,7 @@ from __future__ import annotations import subprocess from pathlib import Path -from agent_harness.smoke import run_smoke +from rein_aharness.smoke import run_smoke def _make_repo(tmp_path: Path) -> Path: diff --git a/workplans/HARNESS-WP-0002-rename-and-glas-harness-alignment.md b/workplans/HARNESS-WP-0002-rename-and-glas-harness-alignment.md index 0476d5e..725fbf6 100644 --- a/workplans/HARNESS-WP-0002-rename-and-glas-harness-alignment.md +++ b/workplans/HARNESS-WP-0002-rename-and-glas-harness-alignment.md @@ -33,19 +33,48 @@ state_hub_task_id: "bf04ed50-cbe2-4f8f-9876-d06c579d19e6" Rename the parts of this repo that a mechanical identity rename would otherwise silently break, because they touch a *live* Railiance -deployment: the `agent-harness` CLI command (`pyproject.toml -[project.scripts]`, `agent_harness/cli.py` entry point), the -`agent_harness` Python package directory, the Docker image tag -(`agent-harness:railiance01`), the k8s namespace/labels/ConfigMap names -(`deploy/k8s/railiance/*.yaml`), the Railiance host directory -(`~/agent-harness/deploy/...`), and `deploy/scripts/railiance-smoke.sh`'s -`AGENT_HARNESS_ROOT` env var and SSH remote alias. Do this as one -reviewed change with a Railiance re-deploy and smoke-test run -immediately after, not as incidental cleanup. +deployment: the `agent-harness` CLI command, the `agent_harness` Python +package directory, the Docker image tag, the k8s namespace/labels/ +ConfigMap names, the Railiance host directory, and +`deploy/scripts/railiance-smoke.sh`'s env var and paths. + +**Code/config side done (2026-07-26):** +- `agent_harness/` → `rein_aharness/` (`git mv` + all internal imports) +- `pyproject.toml`: `[project.scripts]` → `rein-aharness = + "rein_aharness.cli:main"`; wheel package name +- `Containerfile`: `COPY rein_aharness`, `ENTRYPOINT ["rein-aharness"]` +- `Makefile`: `IMAGE`/`TAR` → `rein-aharness:railiance01` / + `rein-aharness-railiance01.tar`; `deploy-rsync` target path +- `deploy/k8s/railiance/*.yaml`: namespace/labels/names/image all + `rein-aharness` +- `deploy/scripts/railiance-smoke.sh`: `AGENT_HARNESS_ROOT` → + `REIN_AHARNESS_ROOT`, default checkout path, AppRole env source path + (SSH host alias for Forgejo left untouched — that's an external + `~/.ssh/config` entry, not owned by this repo) +- In-repo identity strings updated too: `hub.py`'s `source` field, + `metrics.py`'s `harness` field default, `intake.py`'s + `DEFAULT_ASSIGNEE`, `cli.py`'s `argparse` prog name, commit + author identity in `smoke.py`/`tenant_onboard_runs.py` +- Verified: 47/47 tests pass, `rein-aharness` CLI runs correctly from a + fresh venv, `docker build` succeeds and the built image runs + (`ENTRYPOINT`/`CMD` dispatch correctly) +- `deploy/README.md` gained an explicit **rename cutover checklist** + for the parts this session cannot safely do unattended: moving the + host-side secrets dir (`~/.local/agent-harness` → `~/.local/rein-aharness`) + and checkout (`~/agent-harness` → `~/rein-aharness`) on railiance01 + itself, and not deleting the old k8s namespace until the new one is + confirmed working + +**Still open — the actual live cutover:** running the checklist on +railiance01, rebuilding+importing the image there, applying the renamed +k8s manifests, and running the host smoke script against the live +deployment. Not attempted from this session — real production surgery +on `binky-control`'s live automation, needs the operator present for +the actual host-side moves and a confirmed rollback point. ```task id: HARNESS-WP-0002-T02 -status: todo +status: progress priority: medium state_hub_task_id: "7c5d23cd-d7fd-4c79-8847-448b83feb673" ```