Files
MOPAC/DESIGN.md
T

125 lines
6.9 KiB
Markdown

# MOPAC harness — design spec v0 (2026-08-28)
A Go headless agent harness for the RCEO/TSG org. Replaces bash/screen/file-hack
inner loop. All patterns established 2026-08-28 STAY; only the substrate
changes. References: ../reference/{crush,maki}; siblings to port:
../siblings/{KNEL-AIMiddleware, KNELSecretsManager}.
## What it is NOT
- Not a TUI. Inner loop = pull Redmine -> run turn -> write Discourse/Redmine
back -> chain next turn. Humans observe via files/Redmine/Discourse, not by
attaching to the loop.
- Not a daemon. Bounded turns chaining (drip), same as dispatch-turn.sh today.
## Core loop (from DESIGN-24x7-execution.md, carried over)
1. INTAKE: poll released scope (Redmine query) + local inbox files.
2. GATE: semaphore (LLM slots, class-aware: llm-heavy|compute-long|hybrid),
budget from LiteLLM usage API (http://192.168.3.78:4001) — virtual key
per stack, hard caps enforced at proxy.
3. EXECUTE: bounded turn, fresh small context, tools below.
4. WRITEBACK: REPORT file + Redmine issue note (SoR). Discourse for docs.
5. CHAIN: completion triggers next conductor iteration. P1 first, grinders
chunked, compute-long tasks run in non-LLM slots.
6. ESCALATE: anything outside standing-release scope -> TASK file -> founder
gate. Never auto-executes.
## Tools (port from crush/KNEL, Go)
- bash exec, file edit (tree-sitter-aware parses; see maki's approach),
redmine-cli, discourse-cli, tea (gitea), docker, bitwarden (replace
KNELSecretsManager with Go bwraper around `bw` CLI; secrets never in logs).
- MCP client (crush's mcp plumbing is the reference; wrappers exist in
siblings/KNEL-AIMiddleware — port config format for compat).
- LSP: port lsp-* wrappers or embed go.lsp devkit.
- Permission model: per-tool allow/deny, tree-sitter bash parsing (maki
reference) — subshells/pipes handled; org preset: no sudo/ssh/network
exfil; writes confined to declared roots.
## Providers
- OpenAI-compatible only, pointed at LiteLLM (base_url + virtual key).
OAuth flows (crush-style) OUT of scope for v1 — proxy key is enough.
- Retry/backoff on stream truncation (z.ai "Message content shorter than
read bytes" seen 2x today) with turn resume.
## Cross-host (5 onstage + 3 offstage)
- Each host runs harness instances; coordination via _crossfeed files (v1)
and/or LiteLLM keys as the global budget broker. Event receiver (T1) later.
## Build order (go slow, grinder TASKs, quota-aware)
1. Reference studies: crush oauth/mcp/session code; maki permission parsing +
token-reduction (index/tool_search). Deliverable: PORTING-NOTES.md each.
2. harness skeleton: config, loop, redmine-pull, file writeback, exec tool.
3. Permission layer + bitwarden wrapper.
4. LiteLLM integration + semaphore/budget gates.
5. MCP/LSP ports.
6. Pilot: one RCEO stack on trivial released scope; compare vs drip loop.
## Constraints
- Quota: grinder turns only, no idle polling loops, compact aggressively.
- Never log secret values; keys from bitwarden at runtime.
- Everything it does lands in git (tooling repos) or Redmine (work records).
## Parity target (Charles, 2026-08-28 ~18:45)
Harness aims for crush FEATURE PARITY on the agent core: tool calling,
subagents (weak/medium/strong tiers), MCP client, sessions/resume, skills.
v1 skeleton (tonight) = the headless subset; parity items land in ordered
phases after the pilot. TUI explicitly stays out of scope.
## Org model + interaction layer (Charles, 2026-08-28 evening)
- VERTICALS are first-class config: each vertical/stack = identity + LiteLLM
virtual key + budget + scope query + allowed tools. The harness natively
models the whole org (5 onstage + 3 offstage), not one loop.
- INTERACTION LAYER = Redmine (work/SoR), Discourse (docs/specs), Gitea (code,
PRs). Humans and other agents talk to a stack ONLY through these + git.
- _crossfeed files/doorbells/screens = internal implementation detail of the
legacy bash stack; harness keeps file state locally but never requires a
human to touch it. Chaining is in-process, not screen-stuffing.
## Toolchain policy (Charles, 2026-08-28 evening) — HARD RULE
100% Go for the harness ecosystem: core, CLIs, tools, MCP replacements.
No Python/Rust/Node in the toolchain (CMMC L3/TS, SCI/ITAR supply-chain
posture). Exceptions only when unavoidable (e.g. Playwright-class browser
automation) and each requires explicit founder sign-off, isolated + vendored.
- Deps: minimal, vendored, reproducible builds, go vet + staticcheck clean.
- Existing Go assets to REUSE, not rewrite: tea (gitea), LiteLLM (service,
not ours). Bitwarden: Go wrapper replaces Node bw CLI dependency.
## Tooling architecture (open question -> PMO recommendation)
Recommendation: SEPARATE Go executables (MOPAC/tools/: redmine-cli,
discourse-cli, bitwarden-go, ...) driven by the harness via exec with a
JSON in/out contract + thin in-process adapter for hot paths.
Why: (1) auditable per-binary supply chain; (2) CLIs stay usable standalone
by humans/legacy stacks — interaction layer must not require the harness;
(3) Unix plumbing/porcelain split, same model as git; (4) in-process plugin
interface can come later without redesign. MCP servers we run get replaced
by these Go CLIs behind a minimal MCP adapter, killing the docker/python
MCP fleet.
## MVP demo bar (Charles, 2026-08-28 ~19:00)
Fire up the harness (screen or docker) and run a turn whose prompt is
"tell me about yourself" routed through LiteLLM; the GLM 5.3 self-
description comes back and lands as the REPORT. That is the MVP. The
0800 checklist (compile, dry-run, real single-turn, LSP wired, studies)
builds toward it; the demo itself is this one exchange.
## Model selection layer (Charles, 2026-08-28 ~19:00)
Claude-Code-style model picking for the harness and its subagents:
the harness chooses the right model per body of work (overall + per-task).
GLM fleet is wide; use it deliberately.
- Inventory on proxy today (12): glm-4.5{,-air,v}, 4.6{,v}, 4.7{,-flash},
5, 5-turbo, 5.1, 5.2, 5.3. No glm-5.3-flash configured yet; flash-class
today = glm-4.7-flash. Adding 5.3-flash later = one LiteLLM model_list
entry, zero code change (see aliases).
- v0 (tonight, skeleton): static TASK CLASS -> MODEL TIER map in
harness.toml. Classes: study/read -> flash tier; code/architecture ->
flagship (glm-5.2/5.3); review/summarize/writeback -> mid (5-turbo/5.1);
vision when needed (4.6v/4.5v). Config-only, no heuristic code.
- Aliases are the contract: harness requests `mopac-study`, `mopac-code`,
`mopac-review` ... LiteLLM resolves alias -> concrete model. Swapping
models (e.g. 4.7-flash -> 5.3-flash when live) = proxy config edit only.
- v1 (post-pilot): auto-selection — cheap flash model classifies each
incoming TASK (Redmine issue text) and picks tier + model before the
main turn spends anything; subagent spawns inherit class-based routing
with per-tier budget caps (LiteLLM vkeys already enforce spend).
- Telemetry: every REPORT logs model used + tokens + cost via LiteLLM
spend APIs, so routing decisions are auditable and tunable.