All checks were successful
Work Records / validate (push) Successful in 23s
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).
146 lines
5.5 KiB
Markdown
146 lines
5.5 KiB
Markdown
# 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)
|
||
|
||
```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 (**implemented**)
|
||
|
||
1. **Prompt** (metadata only): newest CSV rows + current mail-log tail +
|
||
queue templates.
|
||
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
|
||
{
|
||
"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
|
||
`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.
|
||
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)
|
||
|
||
```bash
|
||
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:
|
||
|
||
```bash
|
||
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):
|
||
|
||
```bash
|
||
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_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
|