binky-control/integrations/llm-connect-executor-assessment.md
tegwick 0f91a98d08 BINKY-WP-0004-T01: kaizen schedule opt-in + executor ownership decision
- .kaizen/schedule.yml scaffolded via schedule init, validates clean
  (coach + optimization weekly, tdd-workflow disabled)
- DEC-2026-002 prepared: executor worker in a new small repo, per
  ADR-005 boundaries; fallback allows sandbox prototype, no cutover
  before resolution
- Decision rationale recorded in the executor assessment

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 17:01:19 +02:00

115 lines
6.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# llm-connect as Workstation-Independent Executor — Assessment
> Status: v1 — 2026-07-16 (BINKY-WP-0003-T06). Green-lane assessment only.
> Founder note (2026-07-16): "llm-connect should enable real automated work
> based on activity-core independently from this workstation. This will
> hopefully connect well with kaizen-agentic, too."
## What each piece actually is (verified against the repos)
- **activity-core** (`~/activity-core`, production-backed on Railiance):
owns *when/what/where*. Temporal Schedules fire ActivityDefinitions,
rules emit tasks into the **issue-core REST sink**. Its
`TaskExecutorWorkflow` is explicitly a **stub** — there is a designed but
empty executor slot. The three Binky rhythm definitions are already
landed there, disabled (see `activity-core-wiring.md`).
- **llm-connect** (`~/llm-connect`, pre-release 0.1.0): a **Python client
library**, not a service — a provider-neutral `LLMAdapter` layer
(OpenAI, Gemini, OpenRouter, Anthropic-compatible, and a
`ClaudeCodeAdapter` that shells out to the installed `claude` CLI).
Its own SCOPE rules out "a complete application-level agent framework"
and secret storage. So llm-connect is the *engine block*, not the car:
the executor is a small new service that *uses* llm-connect.
- **kaizen-agentic** (`~/kaizen-agentic`, v1.1.0): agent personas
(markdown instruction sets) + project memory + Custodian MCP lookup
(`get_kaizen_agent`). Explicitly does **not** own runtime execution.
Its **active WP-0006 (with ADR-005) targets "scheduled agent execution
via activity-core"** — the convergence the founder hopes for is already
an active workstream on the kaizen side. Design (per
`wiki/EcosystemIntegration.md`): a repo opts in by committing
`.kaizen/schedule.yml` (`kaizen-agentic schedule init`); activity-core
fires the cron (resolver spec `discover-kaizen-scheduled-repos`, handoff
checklist in `docs/integrations/`) and creates one task per
`(repo, agent)` that runs `kaizen-agentic schedule prepare <agent>`.
Note the verb: *prepare*, not execute — kaizen assembles persona +
context, and runtime execution remains Claude Code's job. llm-connect is
ranked P3 in kaizen's own integration list, "when Coach/optimizer
synthesis becomes automated beyond CLI context assembly" — i.e. exactly
the executor-worker scenario below.
## Architecture that falls out
The missing piece is one thin service — call it the **executor worker**
deployable on Railiance (workstation-independent):
```text
activity-core (Temporal, Railiance)
└─ definition fires → rule emits task → issue-core REST sink
└─ executor worker (new, small; implements TaskExecutorWorkflow
or polls issue-core)
├─ persona: get_kaizen_agent(name) via dev-hub MCP / HTTP
├─ engine: llm-connect adapter
│ • ClaudeCodeAdapter where the claude CLI exists
│ • hosted-API adapters (OpenAI/Gemini/OpenRouter/…)
│ for CLI-less container runtime
├─ secrets: OpenBao via secrets-engine exec-time delivery
│ (API keys; company-email creds for mail-triage tasks —
│ same lane as integrations/company-email-openbao.md)
└─ output: git commits to target_repo (forgejo), progress
events + task closes to State Hub
```
Design points:
1. **Don't grow llm-connect into an agent framework** — its SCOPE forbids
it. The worker composes llm-connect + kaizen persona + repo checkout.
2. **Task contract**: emitted tasks already carry `target_repo`,
`task_template`, `description`, `labels` — enough to select persona
(label → agent name mapping) and workspace.
3. **Secrets**: worker gets provider API keys and repo credentials via
OpenBao/secrets-engine AppRole — no keys in configs. This is the same
plumbing T01 prepares, so the two integrations reinforce each other.
4. **Autonomy guard**: the worker must enforce lanes the way
`scripts/rhythm-session.sh` does (Green/Blue only, no push beyond its
target repo, bounded effort) — policy text lives in the persona +
AutonomyPolicy.md, enforcement in the worker's tool allow-list.
5. **Model choice** through llm-connect config (TOML) keeps cost policy
(Token Budget) adjustable per task label without code changes.
## Gaps → follow-up workplan proposal (BINKY-WP-0004 candidate)
Draft tasks, in dependency order:
1. Opt binky-control into kaizen scheduling (`.kaizen/schedule.yml` via
`kaizen-agentic schedule init`) and align executor-worker ownership
with kaizen WP-0006/ADR-005 (likely home: a new small repo or
activity-core's TaskExecutorWorkflow, per that WP's handoff checklist).
2. Implement `binky_rhythm_status` resolver in activity-core (unblocks the
three landed Binky definitions).
3. Executor worker MVP: consume one emitted task end-to-end on Railiance —
persona load, llm-connect ClaudeCodeAdapter or hosted adapter, commit
to binky-control, hub progress event (dry-run/sandbox repo first).
4. OpenBao lanes for the worker (provider API key + forgejo deploy key)
via secrets-engine catalog entries.
5. Enable `binky-daily-rhythm`, remove the workstation cron bridge line.
6. Then: email-triage task type (joins T01's mailbox lane with the
executor — real-world events driving real automated work).
Ownership note: items 15 span activity-core / kaizen-agentic / secrets-
engine domains; the follow-up workplan in binky-control should track them
as dependencies, with the implementation workplans living in those repos.
## Ownership decision (2026-07-17, BINKY-WP-0004-T01)
Recommendation recorded as **DEC-2026-002**: the executor worker lives in a
**new small repo**, not inside activity-core or kaizen-agentic. ADR-005's
boundaries exclude LLM invocation from both existing repos and explicitly
defer "headless Claude Code / cloud agent runner integration" as a future,
runner-agnostic concern — that future runner is exactly this worker.
binky-control opted into kaizen scheduling on the same date
(`.kaizen/schedule.yml`, coach + optimization weekly, tdd-workflow off).
## Verdict
Feasible and well-aligned: every layer already exists or is an active
workstream in its own domain; the only genuinely new code is a thin
executor worker plus one context resolver. Binky-control's role is
integrator and first customer, not implementor.