# agent-harness Architecture > Status: v0.1, 2026-07-17. Companion to ADR-001 and INTENT.md. > The code in `agent_harness/` is the prototype seed (formerly > `~/executor-worker`, built for BINKY-WP-0004-T04); this document > describes both what exists and the target shape. ## The three-layer model ``` ┌─────────────────────────────────────────────────────────────┐ │ CONSUMING REPO (e.g. binky-control) [instance] │ │ .kaizen/schedule.yml + agent manifest ← declarative only│ │ .kaizen/agents//memory.md, metrics │ └──────────────▲──────────────────────────────────────────────┘ │ reads instance state ┌──────────────┐ ┌──────────────┴──────────────┐ blueprint via │kaizen-agentic│ │ AGENT-HARNESS [runtime]│◄───────────────┤ [blueprint] │ │ task intake → persona bind │ schedule └──────────────┘ │ → credential acquisition │ prepare │ → bounded agentic session │ │ → commit verification │ ┌───────────────┐ │ → hub + kaizen reporting │◄───────┤ activity-core │ emits tasks └───┬──────────┬──────────┬───┘ │ [scheduler] │ (cron/event) │ │ │ └───────────────┘ llm-connect OpenBao State Hub (adapters) (ops-warden (REST: progress, lanes) tasks, decisions) ``` ## Components (current prototype → target) | Component | File | Today | Target | |---|---|---|---| | Task intake | `taskspec.py` | JSON task-spec file | poll issue-core sink / TaskExecutorWorkflow | | Persona | `persona.py` | `kaizen-agentic schedule prepare` (ADR-005) | unchanged, plus phase-memory profile hook | | Session | `adapter.py` | `AgenticClaudeCodeAdapter` (llm-connect subclass, cwd-pinned, hard allow-list) | + hosted adapters; tool profiles (below) | | Orchestration | `runner.py` | HEAD snapshot → session → commit check → report | + budget enforcement, kaizen metrics write | | Mail lane | `mailscan.py` | deterministic credentialed pre-step outside the session | pattern generalizes to other credentialed pre-steps | | Hub reporting | `hub.py` | REST progress event + task close | unchanged | ## Contracts **Instance manifest** (in the consuming repo; `.kaizen/schedule.yml` today, extended per-agent fields as the manifest spec lands in HARNESS-WP-0001): blueprint name, cadence, `enabled`, plus target additions: `lane` (green/blue), `tool_profile` (named, defined here), `budget` (tokens/run), `harness` (pinned major version). **Tool profiles** are named allow-lists defined centrally in the harness, referenced by name from manifests — instances never enumerate tools. Seed profile `green-commit-only` = Read/Write/Edit/Glob/Grep + local git add/commit/status/log/diff. No push, no network, no arbitrary shell. **Completion events** are the idempotence currency: each run posts a progress event (e.g. `binky_daily_brief`, `binky_mail_intake`) with `detail.repo`; activity-core's `binky_rhythm_status`-style resolvers read them to decide dueness. Failures post generic failure events so slots stay due. **Credentials** are acquired per run, held only in process memory/child env, never logged: LLM key via the llm-connect OpenBao lane, git push via per-repo forgejo deploy keys, tenant secrets (e.g. IMAP) via non-interactive AppRole. See binky-control `integrations/executor-worker-secrets.md` for the provisioned lanes. ## Regulation and evolution - **Regulation:** manifest declares, harness enforces. flex-auth gates apply at credential acquisition; ops-warden catalogs every lane; each instance runs under a named hub identity (`agt-…`). - **Evolution:** the harness emits `.kaizen/metrics` per run so the kaizen optimization loop covers both blueprints and the harness itself. Harness releases are versioned; instances pin majors; blueprint conformance tests run before rollout. ## Deployment One deployment on Railiance (single-tenant-host, multi-tenant-repos). State Hub reachable at `:18000` via ops-bridge from remote hosts. The workstation may run the harness ad hoc for development; production runs must not depend on it (that dependence is the problem this repo solves).