diff --git a/DecisionQueue.md b/DecisionQueue.md index 27e3305..3673818 100644 --- a/DecisionQueue.md +++ b/DecisionQueue.md @@ -48,7 +48,7 @@ state_hub_decision_id: "d47d288f-a76f-4e2f-b039-330028824397" created_at: "2026-07-18" consequence: "Workstation cron line removed 2026-07-21; railiance host timers installed (scripts/railiance-rhythm/); three completion event types verified. - Residual continuous intake → BINKY-WP-0006." + Continuous intake residual closed by BINKY-WP-0006 (finished 2026-07-22)." evidence: - integrations/executor-cutover-runbook.md - integrations/harness-tenant-onboarding.md diff --git a/OperatingRhythm.md b/OperatingRhythm.md index a1a0f2c..e18e57e 100644 --- a/OperatingRhythm.md +++ b/OperatingRhythm.md @@ -58,11 +58,13 @@ all `enabled: true`). Execution on Railiance: `23 8 * * 1-5 /home/worsch/binky-control/scripts/rhythm-session.sh # binky rhythm bridge` and pause railiance timers. Script kept for one month as break-glass. -**Known residual (BINKY-WP-0006):** finish **llm-connect / OpenRouter** path -for mail triage + briefs on Railiance (structured LLM output + deterministic -apply). **Do not** install Claude Code or another coding agent on railiance01. -Mail-scan is already deterministic and proven there; see -`integrations/railiance-llm-rhythm.md`. +**Railiance executor (BINKY-WP-0006 finished 2026-07-22):** mail path is +**mail-scan → mail-triage** via **llm-connect / OpenRouter** (structured JSON ++ deterministic apply). Daily brief uses `brief-daily` the same way. +**Do not** install Claude Code or another coding agent on railiance01. Host +timers resolve `LLM_CONNECT_URL` via port-forward or Service ClusterIP (see +`integrations/railiance-llm-rhythm.md`). Optional residual: `brief-weekly` +subcommand for Friday review prep. ## Weekly review (founder, ~15 min) diff --git a/integrations/executor-cutover-runbook.md b/integrations/executor-cutover-runbook.md index fe3cd15..ce99e00 100644 --- a/integrations/executor-cutover-runbook.md +++ b/integrations/executor-cutover-runbook.md @@ -38,13 +38,14 @@ cd ~/binky-control && git pull ./scripts/railiance-rhythm/install-on-railiance.sh ``` -## Residual (do not re-open T06) +## Residual after BINKY-WP-0006 (2026-07-22) -| Gap | Follow-up | +| Gap | Status / follow-up | | --- | --- | -| Post-scan **triage** still assumes coding-agent session (Claude) | BINKY-WP-0006: **llm-connect → OpenRouter** + JSON apply (see `railiance-llm-rhythm.md`) | -| Daily/review unattended without host coding agent | Same pattern via llm-connect | -| Host timers dual activity-core schedules | Simplify once llm path is the only executor | +| Post-scan **triage** via llm-connect | **Done** — `agent-harness mail-triage`; three clean railiance cycles 2026-07-22 | +| Daily brief without host coding agent | **Done** — `brief-daily` | +| Weekly review prep without host coding agent | **Open** — need `brief-weekly` (same pattern) | +| Host timers dual activity-core schedules | Simplify when in-cluster CronJob/poller owns cadence | | **Out of scope / rejected:** install Claude Code on railiance01 | — | ## Rollback diff --git a/integrations/harness-tenant-onboarding.md b/integrations/harness-tenant-onboarding.md index 62424c4..387a8d0 100644 --- a/integrations/harness-tenant-onboarding.md +++ b/integrations/harness-tenant-onboarding.md @@ -1,7 +1,7 @@ # agent-harness tenant onboarding — binky-control (HARNESS-WP-0001-T07) -> Status: done 2026-07-18; cutover **BINKY-WP-0004-T06 completed 2026-07-21**. -> Residual continuous intake: BINKY-WP-0006. +> Status: done 2026-07-18; cutover **BINKY-WP-0004-T06 completed 2026-07-21**; +> llm-connect continuous intake **BINKY-WP-0006 finished 2026-07-22**. ## Instance manifest diff --git a/integrations/railiance-llm-rhythm.md b/integrations/railiance-llm-rhythm.md index 3799ca6..8a29456 100644 --- a/integrations/railiance-llm-rhythm.md +++ b/integrations/railiance-llm-rhythm.md @@ -1,6 +1,6 @@ # Railiance rhythm via llm-connect (not a host coding agent) -> Status: design note 2026-07-21 (BINKY-WP-0006). +> Status: **live 2026-07-22** (BINKY-WP-0006 finished). > Supersedes the residual “install Claude on railiance01” idea from the > BINKY-WP-0004 cutover notes. @@ -36,16 +36,17 @@ timer / CronJob - Output: `mailmeta/reports/email-channel-evidence-report-*.csv` - Hub: `binky_mail_intake` with counts only -### Phase 2 — triage (to build) +### Phase 2 — triage (**implemented**) 1. **Prompt** (metadata only): newest CSV rows + current mail-log tail + queue templates. -2. **llm-connect** `POST` (same contract as activity-core `llm_client.py`): - - URL: `http://llm-connect.activity-core.svc.cluster.local:8080` - - Provider: OpenRouter (already configured on railiance) - - Model: cost-efficient; **prefer open-weights** (pick at T03; examples to - evaluate: Llama/Qwen/Mistral class on OpenRouter — measure quality on - fixture CSV before locking). +2. **llm-connect** `POST /execute` (same contract as activity-core + `llm_client.py`): + - In-cluster: `http://llm-connect.activity-core.svc.cluster.local:8080` + - Host: Service ClusterIP (auto via `kubectl` in `run-common.sh`) or + port-forward `http://127.0.0.1:18080` + - Provider: OpenRouter; model currently `google/gemini-2.5-flash` + (open-weights retarget optional) 3. **Response**: strict JSON, e.g. ```json @@ -59,10 +60,14 @@ timer / CronJob ``` 4. **Apply** (deterministic Python): append mail-log; add queue YAML only if - schema-valid; **suspicious** → log only; `git commit`; hub event. + schema-valid; **suspicious** → log only; `git commit`; hub event + `binky_mail_triage`. 5. **Never** pass message bodies to the model if the scanner can omit them; never execute model-suggested shell. +**Dogfood (closure T06):** three clean unattended cycles on railiance01 +2026-07-22 ~08:26–08:27 UTC — each scan+triage `ok` with hub progress. + ## Daily / weekly (same shape) | Slot | Deterministic inputs | LLM output | Apply | @@ -95,11 +100,12 @@ Hub event: `binky_daily_brief` with `detail.repo=binky-control`. ### Host reachability to llm-connect -In-cluster DNS does not resolve on the bare host. Interim: +In-cluster DNS does not resolve on the bare host. `run-common.sh` probes, in +order: port-forward `127.0.0.1:18080` → Service ClusterIP (via `kubectl`) → +cluster DNS. Manual override: ```bash -kubectl -n activity-core port-forward svc/llm-connect 18080:8080 & -export LLM_CONNECT_URL=http://127.0.0.1:18080 +export LLM_CONNECT_URL=http://$(kubectl -n activity-core get svc llm-connect -o jsonpath='{.spec.clusterIP}'):8080 export STATE_HUB_URL=http://127.0.0.1:18000 agent-harness mail-triage --target-repo ~/binky-control ``` diff --git a/scripts/railiance-rhythm/run-common.sh b/scripts/railiance-rhythm/run-common.sh index f319160..e562b68 100755 --- a/scripts/railiance-rhythm/run-common.sh +++ b/scripts/railiance-rhythm/run-common.sh @@ -30,14 +30,31 @@ require_repo() { require_llm_connect() { # Server-side rhythm uses llm-connect HTTP (OpenRouter), never Claude CLI. + # Host cannot resolve in-cluster DNS; try reachable bases in order: + # 1) explicit LLM_CONNECT_URL 2) local port-forward 3) Service ClusterIP + # 4) cluster DNS (works only in-pod). if [[ -z "${LLM_CONNECT_URL:-}" ]]; then - # Host cannot resolve cluster DNS; default to local port-forward target. - # In-cluster Jobs should set LLM_CONNECT_URL to the cluster service. - if curl -sf -m 1 "http://127.0.0.1:18080/health" >/dev/null 2>&1 \ - || curl -sf -m 1 "http://127.0.0.1:18080/" >/dev/null 2>&1; then - export LLM_CONNECT_URL="http://127.0.0.1:18080" - else - export LLM_CONNECT_URL="http://llm-connect.activity-core.svc.cluster.local:8080" + local candidates=() + candidates+=("http://127.0.0.1:18080") + if command -v kubectl >/dev/null 2>&1; then + local cip + cip="$(kubectl -n activity-core get svc llm-connect \ + -o jsonpath='{.spec.clusterIP}' 2>/dev/null || true)" + if [[ -n "${cip}" ]]; then + candidates+=("http://${cip}:8080") + fi + fi + candidates+=("http://llm-connect.activity-core.svc.cluster.local:8080") + local u + for u in "${candidates[@]}"; do + if curl -sf -m 2 "${u}/health" >/dev/null 2>&1; then + export LLM_CONNECT_URL="${u}" + break + fi + done + if [[ -z "${LLM_CONNECT_URL:-}" ]]; then + export LLM_CONNECT_URL="${candidates[-1]}" + log "WARN: no llm-connect health probe succeeded; using ${LLM_CONNECT_URL}" fi fi log "LLM_CONNECT_URL=${LLM_CONNECT_URL}" diff --git a/scripts/railiance-rhythm/run-mail.sh b/scripts/railiance-rhythm/run-mail.sh index 6a6cc40..3b22fe1 100755 --- a/scripts/railiance-rhythm/run-mail.sh +++ b/scripts/railiance-rhythm/run-mail.sh @@ -17,14 +17,14 @@ log "mail-scan rc=${scan_rc}" if [[ "${scan_rc}" -ne 0 ]]; then exit "${scan_rc}" fi -# Triage must use llm-connect (OpenRouter), not a host coding agent. -# Until agent-harness mail-triage exists (BINKY-WP-0006), scan-only is OK. -if agent-harness mail-triage --help >/dev/null 2>&1; then - log "START mail-triage (llm-connect)" - agent-harness mail-triage \ - --target-repo "${BINKY_REPO}" \ - 2>&1 | tee -a "${LOG_DIR}/mail.log" || log "WARN: mail-triage failed" -else - log "SKIP mail-triage: command not available yet (BINKY-WP-0006); scan-only" +# Triage uses llm-connect (OpenRouter), never a host coding agent. +log "START mail-triage (llm-connect)" +agent-harness mail-triage \ + --target-repo "${BINKY_REPO}" \ + 2>&1 | tee -a "${LOG_DIR}/mail.log" +triage_rc=${PIPESTATUS[0]} +log "mail-triage rc=${triage_rc}" +if [[ "${triage_rc}" -ne 0 ]]; then + exit "${triage_rc}" fi log "END mail-intake" diff --git a/workplans/BINKY-WP-0006-railiance-rhythm-continuous-intake.md b/workplans/BINKY-WP-0006-railiance-rhythm-continuous-intake.md index 58ee80c..7b6090d 100644 --- a/workplans/BINKY-WP-0006-railiance-rhythm-continuous-intake.md +++ b/workplans/BINKY-WP-0006-railiance-rhythm-continuous-intake.md @@ -4,7 +4,7 @@ type: workplan title: "Railiance rhythm: llm-connect execution (no host coding agent)" domain: infotech repo: binky-control -status: ready +status: finished owner: codex topic_slug: the-custodian created: "2026-07-21" @@ -155,10 +155,16 @@ grows, spawn BINKY-WP-0007 and mark this task done with handoff. ```task id: BINKY-WP-0006-T06 -status: todo +status: done priority: low state_hub_task_id: "3a93d7d4-f949-4a85-ad2e-a566ccc1f966" ``` Three clean unattended mail cycles on railiance (scan+triage); milestone; `statehub fix-consistency`. + +**2026-07-22:** Three clean scan+triage cycles on railiance01 (UTC 08:26–08:27), +each `ok` with hub events `binky_mail_intake` + `binky_mail_triage`. Host +`LLM_CONNECT_URL` discovery now prefers reachable ClusterIP (not broken +cluster DNS). Residual: `brief-weekly` still unimplemented (weekly timer will +fail until shipped); open-weights model retarget optional.