Batteries-included agent-harness base, extracted from mort's agent layer. This first cut establishes the module + the zero-coupling core primitives: - lane, dispatchguard, pendingattach, run/progress.go: moved verbatim from mort - config: host config Source seam + env-var default (nil-safe helpers) - deliver: output-egress seam + Discard/Stdout defaults - identity: AdminPolicy + MemberResolver seams (nil-safe) - fanout: programmatic N×M swarm (bounded global + per-key concurrency) - README/CLAUDE.md with the vibe-coded banner; CI with Go gates + the "core stays majordomo+stdlib only" invariant Core builds with stdlib only today; majordomo enters at P1 (model/structured). go build/vet/test -race all green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
# executus — developer & agent guide
|
||||
|
||||
> ⚠️ **This project is vibe-coded** (AI-authored, human-steered). See `README.md`.
|
||||
|
||||
executus is a **batteries-included base for LLM agent harnesses**, layered
|
||||
strictly above [majordomo]. majordomo is the lean substrate (agent loop, `llm`
|
||||
types, providers, media, parse/failover/tiering). executus is the opinionated
|
||||
layer majordomo deliberately omits. **executus requires no majordomo changes** —
|
||||
it decorates `llm.Model` and wraps `majordomo/agent.Agent`.
|
||||
|
||||
[majordomo]: https://gitea.stevedudenhoeffer.com/steve/majordomo
|
||||
|
||||
## North star
|
||||
|
||||
A brand-new project imports executus, does a little setup, and is most of the way
|
||||
to agentic capabilities. The mechanism is **one shipped default per seam**:
|
||||
`executus.New()` (once the runtime lands) is agentic with zero host wiring; the
|
||||
same builder lets a serious host swap each default for its own implementation and
|
||||
register its own tools.
|
||||
|
||||
Two consumers define the envelope:
|
||||
|
||||
- **mort** (heavy) — Discord, mortbux, media, MySQL/GORM, DB-backed convar config,
|
||||
saved skills, audit, scheduling, run-critic.
|
||||
- **gadfly** (light) — a CI PR-reviewer Docker image, env-var configured, running
|
||||
an N-models × M-lenses structured-output swarm. Needs model fleet, lanes,
|
||||
bounded runs, structured output, fan-out, a few read tools — and **none** of the
|
||||
batteries.
|
||||
|
||||
That spread is why executus is **tiered**: a light host imports core only; a heavy
|
||||
host opts into batteries.
|
||||
|
||||
## Module & layering
|
||||
|
||||
One module `gitea.stevedudenhoeffer.com/steve/executus`, `go.mod` = **majordomo +
|
||||
stdlib only** (no gorm/redis/discordgo/cgo). A second nested module
|
||||
`contrib/store` carries the SQLite dependency so the core never inherits it.
|
||||
|
||||
```
|
||||
CORE (majordomo + stdlib):
|
||||
config/ ConfigSource seam (+ env default) [P0 ✓]
|
||||
lane/ bounded fair-share worker pool [P0 ✓]
|
||||
fanout/ programmatic N×M swarm [P0 ✓]
|
||||
deliver/ output egress seam (+ Discard/Stdout) [P0 ✓]
|
||||
identity/ caller identity seams [P0 ✓]
|
||||
run/ progress bridge now; the executor kernel + [P0 partial]
|
||||
nil-safe Ports + RunnableAgent later [P2]
|
||||
dispatchguard/ loop/depth/fan-out caps [P0 ✓]
|
||||
pendingattach/ attachment dedupe [P0 ✓]
|
||||
tool/ registry + 3-stage permissions + ssrf/llmmeta [P1]
|
||||
model/ config-driven tier resolution over majordomo [P1]
|
||||
compact/ context compactor (WithCompactor hook) [P2]
|
||||
tools/{web,net,store,compose,meta,comms} generic tools [P3]
|
||||
structured/ Generate[T] convenience over majordomo [P1]
|
||||
|
||||
BATTERIES (opt-in siblings, each nil-safe + a default):
|
||||
persona/ Agent noun + AgentStore seam + yml loader [P4]
|
||||
skill/ rich Skill + SkillStore seam + toml loader [P4]
|
||||
audit/ run-trace Sink (+ Noop/Slog) [P4]
|
||||
critic/ two-tier timeout state machine + Escalator [P4]
|
||||
schedule/ cron runner cores [P4]
|
||||
checkpoint/ durable resume seam [P4]
|
||||
budget/ rolling-window tracker (+ NoOp) [P4]
|
||||
|
||||
contrib/store/ SECOND module (+ modernc.org/sqlite): [P4]
|
||||
in-memory + pure-Go SQLite impls of every *Store seam
|
||||
```
|
||||
|
||||
### The one architectural move
|
||||
|
||||
The kernel must import **no battery**. In mort today, `agentexec` imports
|
||||
`agents`, `agentcritic`, and `skillaudit` directly — those three up-pointing edges
|
||||
get inverted into nil-safe `run.Ports` interfaces (`PaletteSource`, `Critic`,
|
||||
`Audit`) plus a `RunnableAgent` DTO. Everything else is wide-but-shallow
|
||||
repackaging.
|
||||
|
||||
## Invariants (enforced in CI)
|
||||
|
||||
- The core module builds with **majordomo + stdlib only**. `go.sum` must not
|
||||
contain gorm/redis/discordgo/sqlite/gin.
|
||||
- No `core/*` package imports a `battery/*` package.
|
||||
- Standard Go gates: `go build`, `go vet`, `go test -race`, `go mod tidy` clean.
|
||||
|
||||
## Extraction roadmap
|
||||
|
||||
P0 module + zero-coupling moves + core seams (this) → P1 tool registry + model →
|
||||
P2 run kernel + Ports inversion → P3 generic tools + defaults → P4 persona/skill
|
||||
redesign + batteries + SQLite store → P5 gadfly on core (light-tier canary) → P6
|
||||
rewire mort + tag v0.1.0. The mort-side rewrite reuses mort's existing
|
||||
`mort_*_adapters.go` wall as the host adapter layer.
|
||||
|
||||
## Conventions
|
||||
|
||||
- Mirror majordomo's house style: gofmt; check errors immediately and wrap with
|
||||
`fmt.Errorf("...: %w", err)`; `// Why:` comments where rationale isn't obvious;
|
||||
hermetic tests (majordomo's fake provider; no network in the default suite).
|
||||
- Every seam is an interface with a nil-safe accessor and a shipped default.
|
||||
- Keep the core seam surface small and stable — push churn into tools and host
|
||||
adapters, not core interfaces.
|
||||
Reference in New Issue
Block a user