Align AGENTS, AutonomyPolicy, SCOPE, OperatingRhythm with fleet residual role (live intakes, not SCOPE prose). Capture BINKY-WP-0006 leftovers as AWQ-011 (brief-weekly) and AWQ-012 (open-weights retarget).
5.5 KiB
Railiance rhythm via llm-connect (not a host coding agent)
Status: live 2026-07-22 (BINKY-WP-0006 finished).
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)
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/imapvia AppRole - Output:
mailmeta/reports/email-channel-evidence-report-*.csv - Hub:
binky_mail_intakewith counts only
Phase 2 — triage (implemented)
- Prompt (metadata only): newest CSV rows + current mail-log tail + queue templates.
- llm-connect
POST /execute(same contract as activity-corellm_client.py):- In-cluster:
http://llm-connect.activity-core.svc.cluster.local:8080 - Host: Service ClusterIP (auto via
kubectlinrun-common.sh) or port-forwardhttp://127.0.0.1:18080 - Provider: OpenRouter; model currently
google/gemini-2.5-flash(open-weights retarget optional)
- In-cluster:
- Response: strict JSON, e.g.
{
"log_entries": [
{"date": "2026-07-21", "from": "…", "subject": "…", "action": "ignore|queue|suspicious"}
],
"queue_items": [],
"notes": "one-line summary"
}
- Apply (deterministic Python): append mail-log; add queue YAML only if
schema-valid; suspicious → log only;
git commit; hub eventbinky_mail_triage. - 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.
Residuals as live intakes: AWQ-011 (brief-weekly), AWQ-012 (optional
open-weights retarget) — see AutopilotWorkQueue.md and work-record residual
convention.
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.
Daily brief (implemented)
export LLM_CONNECT_URL=http://127.0.0.1:18080 # host + port-forward
agent-harness brief-daily --target-repo ~/binky-control
# skips if briefs/YYYY-MM-DD-daily-brief.md exists (Europe/Berlin); --force to rewrite
Hub event: binky_daily_brief with detail.repo=binky-control.
What already runs on railiance01
| Component | Status (2026-07-22) |
|---|---|
llm-connect Deployment in activity-core |
Running; OpenRouter; model google/gemini-2.5-flash |
| OpenRouter API key Secret | Present (operator custody) |
agent-harness mail-scan on host |
Proven |
agent-harness mail-triage |
Implemented (agent-harness 7520a53); live smoke OK via port-forward |
| Host systemd timers | Interim cadence; call mail-scan + mail-triage |
| Claude CLI on host | Must not become a dependency |
Host reachability to llm-connect
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:
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
Prefer a CronJob in-cluster later (native DNS to llm-connect.activity-core.svc).
Git identity on the host checkout (required once):
git -C ~/binky-control config user.email agent-harness@railiance.local
git -C ~/binky-control config user.name agent-harness
Anti-patterns
- Installing Claude Code / npm agent stacks on railiance for rhythm.
- Defaulting
runner.run_tasktoAgenticClaudeCodeAdapterfor 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 statusworkplans/BINKY-WP-0006-…— tasks- llm-connect
docs/activity-core-llm-endpoint.md - agent-harness
mailscan.pytwo-phase header comment