The skill half of the persona/skill pair, as a clean redesign (not a faithful
lift of mort's 60-method skills.Storage kitchen sink):
- skill.go/skill_version.go/validate.go/inputs.go/schedule.go moved clean; the
only host couplings severed: llms.IsTierName -> model.IsTierName, and the
chatbot DefaultChatbotInputName const localized.
- store.go: a DELIBERATELY LEAN SkillStore — skill lifecycle (CRUD + visibility)
+ versioning + scheduling ONLY. The KV/file/quota sub-stores that were fused
into mort's interface are the tools/ store seams; email/channel grants stay
host concerns.
- runnable.go: Skill.ToRunnable() lowers a skill into run.RunnableAgent (flat
tool list, no palette — composition is a host concern); DueAt() helper.
- memory.go: NewMemory() — zero-dep in-process SkillStore (visibility filters,
newest-first versions).
Tests: ToRunnable mapping, visibility (public/shared/private) listing, version
ordering + lookup. No mort dependency (go.mod tidy clean); core imports ZERO
from skill.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The headline P4 piece (clean redesign): the Agent persona noun, decoupled from
its Discord shell.
- agent.go/storage.go/builtin_loader.go moved from mort's pkg/logic/agents; the
Storage seam drops the Discord CommandBindingStorage embedding (a host
concern). The host-entangled files (commands, chatbot_provider, command-
binding dispatcher, personalization, system) stay in mort.
- runnable.go: Agent.ToRunnable() lowers a persona into run.RunnableAgent — the
bridge that lets run.Executor run a persona without importing this battery
(the inversion of agentexec.Run(*agents.Agent)).
- memory.go: NewMemory() — zero-dep in-process persona Storage (all 11 CRUD +
trigger-query methods).
Tests: ToRunnable field/phase mapping; Memory round-trip. CI invariant: core
imports ZERO from persona.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Lifts mort's pkg/logic/llms into executus/model, decoupled from mort:
- tiers.go: the tier resolver now reads a host-supplied config.Source under
"model.tier.<name>" with host-supplied fallbacks (Configure(cfg, defaults,
ttl)), instead of convar.Manager. Tier NAMES + specs are host config; the
resolution mechanism (cache, reasoning-suffix dialect, chain validation) is
generic. No tier names hard-coded in the harness.
- sink.go: usage/trace recording inverted off mort's llmusage/llmtrace into
UsageSink / TraceSink seams + a model-owned Span, with nil-safe context
attribution helpers (WithModel/WithTraceID/WithUsageTool/WithUsageUser).
Both sinks optional (nil = off) so a light host records nothing.
- lane decoration repointed to executus/lane; utils.Errorf -> fmt.Errorf.
- call.go keeps GenerateWith[T] (instrumented structured output) — this is the
structured-output primitive; no separate structured/ package.
- llmmeta moved over model/ (the meta-LLM helper: tier allowlist + JSON retry
+ ledger). Its tests configure a minimal tier table via TestMain.
New tests cover the inversion: config overrides fallback, tier registration,
reasoning-suffix survival, nested-tier rejection, nil-sink no-ops.
Full module: go build/vet/test -race green; core go.sum still free of
gorm/redis/discordgo/sqlite.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The tool registry core (registry, permission model, Invocation, gated-tool
wrapper, ssrf guard, hmac, encryption, argcoerce, helpers, rootrun,
session_tools, webhook_rate_limit) had zero mort coupling — it imports only
majordomo/llm + x/crypto/hkdf — so it moves verbatim with a package rename
(skilltools -> tool). All same-package tests came along and pass; the SSRF,
gated-wrapper, encryption and output-pattern invariants are re-anchored here.
majordomo re-enters the module graph (now pinned to the latest, incl. the
front-loaded-output fix). model/ + llmmeta + structured follow next.
Docs: CLAUDE.md now requires README/examples to stay in sync with changes in
the same commit; CI skips docs/example-only pushes via paths-ignore.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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>