# Railiance rhythm via llm-connect (not a host coding agent) > Status: design note 2026-07-21 (BINKY-WP-0006). > Supersedes the residual “install Claude on railiance01” idea from the > BINKY-WP-0004 cutover notes. ## Principle **Railiance executes infrastructure + hosted LLM inference. It does not host Claude Code, Codex, or another interactive coding harness.** | Layer | On Railiance | Not on Railiance | | --- | --- | --- | | Secrets | OpenBao AppRole / in-cluster Secret | Paste into chat | | Deterministic I/O | email-connect scan, git commit/push with deploy key | — | | LLM | **llm-connect → OpenRouter** (open-weights / cheap models) | Claude CLI agentic session | | Policy | Allow-listed apply steps (Blue/Green) | Model free-form shell | This matches agent-harness INTENT (session policy shell) and llm-connect INTENT (provider abstraction): the **server profile** uses llm-connect HTTP; laptop coding agents remain optional for interactive work only. ## Mail path (canonical) ```text timer / CronJob → agent-harness mail-scan # deterministic, AppRole IMAP → agent-harness mail-triage # NEW: llm-connect JSON + apply → hub progress + local commit ``` ### Phase 1 — scan (exists, proven) - Module: `agent_harness/mailscan.py` - Creds: `tenants/binky/company-email/imap` via AppRole - Output: `mailmeta/reports/email-channel-evidence-report-*.csv` - Hub: `binky_mail_intake` with counts only ### Phase 2 — triage (to build) 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). 3. **Response**: strict JSON, e.g. ```json { "log_entries": [ {"date": "2026-07-21", "from": "…", "subject": "…", "action": "ignore|queue|suspicious"} ], "queue_items": [], "notes": "one-line summary" } ``` 4. **Apply** (deterministic Python): append mail-log; add queue YAML only if schema-valid; **suspicious** → log only; `git commit`; hub event. 5. **Never** pass message bodies to the model if the scanner can omit them; never execute model-suggested shell. ## Daily / weekly (same shape) | Slot | Deterministic inputs | LLM output | Apply | | --- | --- | --- | --- | | Daily brief | queues, open risks, yesterday brief | structured sections | write `briefs/YYYY-MM-DD-daily-brief.md` + commit | | Weekly review | briefs week, SuccessMilestones | structured prep | write weekly prep file + commit | No tool-using coding agent required if apply is code-owned. ## What already runs on railiance01 | Component | Status (2026-07-21) | | --- | --- | | `llm-connect` Deployment in `activity-core` | Running; OpenRouter; ConfigMap model `google/gemini-2.5-flash` (may change) | | OpenRouter API key Secret | Present (operator custody) | | `agent-harness mail-scan` on host | Proven | | Host systemd timers | Interim cadence; must call llm path, not `require_claude` | | Claude CLI on host | **Must not** become a dependency | ## Anti-patterns - Installing Claude Code / npm agent stacks on railiance for rhythm. - Defaulting `runner.run_task` to `AgenticClaudeCodeAdapter` for server Jobs. - Sending full email bodies or secrets to OpenRouter. - Dual “coding agent policy” vs “server policy” that drifts (same JSON schema and apply code for all environments). ## Implementation homes | Work | Repo | | --- | --- | | HTTP adapter + mail-triage command + tests | **agent-harness** | | Model/profile ConfigMap, smoke | **llm-connect** / activity-core overlay | | Timers, binky task prompts, dogfood | **binky-control** (this doc + BINKY-WP-0006) | ## See also - `integrations/executor-cutover-runbook.md` — cutover status - `workplans/BINKY-WP-0006-…` — tasks - llm-connect `docs/activity-core-llm-endpoint.md` - agent-harness `mailscan.py` two-phase header comment