diff --git a/deploy/scripts/rein-aharness-claim b/deploy/scripts/rein-aharness-claim index f5471d8..e68963c 100755 --- a/deploy/scripts/rein-aharness-claim +++ b/deploy/scripts/rein-aharness-claim @@ -88,6 +88,22 @@ def _resolve_env(env: dict[str, str]) -> dict[str, str]: return env +def _apply_runtime_defaults(env: dict[str, str], home: Path) -> dict[str, str]: + """Provide the non-secret host wiring required by legacy mail intake.""" + env.setdefault("BAO_ADDR", "https://bao.coulomb.social") + env.setdefault("VAULT_ADDR", env["BAO_ADDR"]) + env.setdefault( + "EXECUTOR_APPROLE_DIR", + str(home / ".local/rein-aharness/approle-binky-mail"), + ) + + local_bin = str(home / ".local/bin") + path_parts = [part for part in env.get("PATH", "").split(os.pathsep) if part] + if local_bin not in path_parts: + env["PATH"] = os.pathsep.join([local_bin, *path_parts]) + return env + + def main() -> None: home = Path.home() env = os.environ.copy() @@ -95,6 +111,7 @@ def main() -> None: env.setdefault("KUBECONFIG", "/etc/rancher/k3s/k3s.yaml") file_env = _load_env_file(home / ".config/rein-aharness/claim-loop.env") env.update(file_env) + env = _apply_runtime_defaults(env, home) env = _resolve_env(env) rein = home / "rein-aharness" / ".venv" / "bin" / "rein-aharness" diff --git a/deploy/systemd/claim-loop.env.example b/deploy/systemd/claim-loop.env.example index a30aa80..6ea660b 100644 --- a/deploy/systemd/claim-loop.env.example +++ b/deploy/systemd/claim-loop.env.example @@ -15,3 +15,6 @@ AGENT_HARNESS_REPO_ROOTS=/home/tegwick:/home/tegwick/work LLM_CONNECT_URL=k8s://activity-core/llm-connect:8080 STATE_HUB_URL=k8s://activity-core/actcore-statehub-edge-relay:8000 KUBECONFIG=/etc/rancher/k3s/k3s.yaml +BAO_ADDR=https://bao.coulomb.social +VAULT_ADDR=https://bao.coulomb.social +EXECUTOR_APPROLE_DIR=/home/tegwick/.local/rein-aharness/approle-binky-mail diff --git a/deploy/systemd/rein-aharness-claim-loop.service b/deploy/systemd/rein-aharness-claim-loop.service index 14a66c2..acdd2a7 100644 --- a/deploy/systemd/rein-aharness-claim-loop.service +++ b/deploy/systemd/rein-aharness-claim-loop.service @@ -11,8 +11,8 @@ Environment=PYTHONUNBUFFERED=1 Environment=KUBECONFIG=/etc/rancher/k3s/k3s.yaml # Temporary profile-absent compatibility; remove after the four tenant migrations. Environment=AGENT_HARNESS_LEGACY_APPROACHES_UNTIL=2026-12-31 -# Ensure kubectl is available for k8s:// URL resolution in rein-aharness-claim -Environment=PATH=/usr/local/bin:/usr/bin:/bin:%h/bin +# Ensure kubectl and the host-installed OpenBao client are available. +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 ExecStart=%h/bin/rein-aharness-claim claim-loop diff --git a/tests/test_claim_launcher.py b/tests/test_claim_launcher.py new file mode 100644 index 0000000..7ed7d6b --- /dev/null +++ b/tests/test_claim_launcher.py @@ -0,0 +1,44 @@ +from __future__ import annotations + +import os +import runpy +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +SCRIPT = ROOT / "deploy" / "scripts" / "rein-aharness-claim" + + +def _launcher_namespace() -> dict: + return runpy.run_path(str(SCRIPT), run_name="rein_aharness_claim_test") + + +def test_runtime_defaults_expose_bao_and_approle(tmp_path: Path) -> None: + apply_defaults = _launcher_namespace()["_apply_runtime_defaults"] + + env = apply_defaults({"PATH": "/usr/bin:/bin"}, tmp_path) + + assert env["BAO_ADDR"] == "https://bao.coulomb.social" + assert env["VAULT_ADDR"] == env["BAO_ADDR"] + assert env["EXECUTOR_APPROLE_DIR"] == str( + tmp_path / ".local/rein-aharness/approle-binky-mail" + ) + assert env["PATH"].split(os.pathsep)[0] == str(tmp_path / ".local/bin") + + +def test_runtime_defaults_preserve_explicit_configuration(tmp_path: Path) -> None: + apply_defaults = _launcher_namespace()["_apply_runtime_defaults"] + configured_bin = str(tmp_path / ".local/bin") + env = { + "BAO_ADDR": "https://bao.example.test", + "VAULT_ADDR": "https://vault.example.test", + "EXECUTOR_APPROLE_DIR": "/run/approle", + "PATH": f"{configured_bin}:/usr/bin", + } + + resolved = apply_defaults(env, tmp_path) + + assert resolved["BAO_ADDR"] == "https://bao.example.test" + assert resolved["VAULT_ADDR"] == "https://vault.example.test" + assert resolved["EXECUTOR_APPROLE_DIR"] == "/run/approle" + assert resolved["PATH"] == f"{configured_bin}:/usr/bin" diff --git a/workplans/ADHOC-2026-09-04.md b/workplans/ADHOC-2026-09-04.md new file mode 100644 index 0000000..e220258 --- /dev/null +++ b/workplans/ADHOC-2026-09-04.md @@ -0,0 +1,39 @@ +--- +id: HARNESS-WP-ADHOC-2026-09-04 +type: workplan +title: "Restore Binky mail-scan OpenBao runtime discovery" +domain: infotech +repo: rein-aharness +status: finished +owner: codex +topic_slug: activity-core +created: "2026-09-04" +updated: "2026-09-04" +--- + +# Restore Binky mail-scan OpenBao runtime discovery + +## Repair and verify the claim-loop runtime + +```task +id: HARNESS-WP-ADHOC-2026-09-04-T01 +status: done +priority: high +``` + +Make the railiance01 claim-loop discover the existing host-installed OpenBao +client and the already-provisioned Binky mail AppRole directory. Preserve +explicit environment overrides, install the corrected launcher/unit, and prove +an AppRole login plus allowlisted IMAP field presence without exposing values. + +Completed 2026-09-04. The launcher now supplies non-secret defaults for +`BAO_ADDR`, `VAULT_ADDR`, and `EXECUTOR_APPROLE_DIR`, and ensures +`~/.local/bin` is present in `PATH`; explicit overrides remain authoritative. +The corrected wrapper and unit were installed on railiance01 and the claim loop +restarted cleanly. Its child environment resolves OpenBao v2.5.4 at the +expected address and the existing mode-0600 AppRole files. A capabilities-safe +smoke proved `read` on `tenants/data/binky/company-email/imap`, `deny` on the +sibling Qonto path, and field presence for `IMAP_USERNAME` and `IMAP_PASSWORD` +without printing either value. Focused launcher and mail-scan tests passed +5 tests. Pre-change live launcher and unit backups carry suffix +`.pre-bao-fix-20260904`.