Migrating AlgoSu Ops & Dev Process to the Hermes Agent System (Phase 1)
SummaryPhase 1 of migrating AlgoSu orchestration (Oracle + 12 agents) from Claude Code tmux dispatch to the Hermes Agent native path (skill + delegate_task + Oracle-direct codex + memory). Seven decisions agreed with the user: (1) full replacement (retire tmux); (2) concurrency max_concurrent_children 3->6, keep depth 1, redesign auto-critic as an Oracle sequential call; (3) twelve individual skills; (4) Critic runs as an Oracle-direct codex review (zero self-report risk); (5) lifecycle keeps only the procedure as a skill and invokes the verified scripts/*.mjs as-is (hybrid); (6) drop inbox -> delegate return, keep MEMORY.md as the source of truth + a Hermes memory index mirror; (7) spike first, then promote to a formal sprint. Two spike cycles proved it out: Sensei (read-only analysis quality passed) and Gatekeeper (full cycle: jwt.middleware.ts two log calls converted to 2-arg structured logging 7bb885a -> Oracle-direct verification diff/tsc/eslint/jest 18/18 -> Oracle-direct codex review CLEAN). Key finding: the default Codex models gpt-5.3-codex and gpt-5.5-codex are unsupported on the ChatGPT account (400); only gpt-5.5 (no suffix) works -> pin -c model=gpt-5.5 into the critic procedure (resolves the carried-over 'Codex model pin' memory item). Phase 1 deliverables: 12 persona skills (algosu-agent-*), algosu-agent-critic (codex pin), /start /stop lifecycle skills, max_concurrent_children 3->6, Hermes memory mirror. Most deliverables live in the ~/.hermes/ profile, outside repo git; the only repo change is spike commit 7bb885a plus this ADR. Phases 2-4 (production validation, live lifecycle runs, .claude/commands thin-shim) carried over.
Goal
- Migrate AlgoSu's orchestration foundation (single Oracle command + 12 specialist agents) from the Claude Code-based tmux dispatch (
oracle-*.sh,inbox/*.md,oracle-auto-critic.sh) to the Hermes Agent native path (Hermes skill +delegate_task+ Oracle-directcodex review+ Hermes memory). - This is Phase 1 — persona skill conversion + foundational infra + spike validation. Full production migration, live lifecycle runs, and
.claude/commandscleanup are split into Phases 2-4 (a multi-sprint roadmap). - Reduce risk via spike first -> validate -> formal migration rather than wholesale replacement.
Background
- Existing system: tmux spawns the 12 agents with unlimited parallelism + chaining + nested auto-critic (depth 2). Results return as
inbox/{agent}-{task}.mdfiles; sprint memory's source of truth is theMEMORY.md+memory/*.mdfiles. - For this profile, Hermes
delegate_taskis constrained to 3 concurrent / spawn depth 1 -> a 1:1 port would break parallel scale and nesting. So "what moves to native vs. what stays" had to be made explicit as decisions. - Key insight: tmux nesting (auto-critic) existed only because "an agent calls another agent." In Hermes, Oracle itself is the main orchestrator, so flattening it to "two sequential Oracle calls after the work" reproduces the same result losslessly at
depth 1.
Decisions
D1. Migration mode — full replacement (user)
- Retire tmux dispatch; move all agent execution onto Hermes
delegate_task. Custom shell glue (oracle-dispatch/reap/auto-critic.sh) andinboxfile returns become removal targets.
D2. Concurrency/nesting constraint — raise config (option 2)
delegation.max_concurrent_children: 3 -> 6(restore parallel width, covers nearly all real usage), keepmax_spawn_depth: 1.- Redesign auto-critic from an "agent commit hook (nested)" into an Oracle post-work sequential routine -> nesting unnecessary. Allowing depth 2 (option 3) was rejected for higher token cost, accumulating unverified self-reports, and conflict with the Oracle single-command principle.
D3. Persona conversion — 12 individual skills
- Port each of the 12 agent personas (
.claude/commands/agents/*.md) to an independent Hermes native skill (algosu-agent-{name}). Inject the relevant skill as context on eachdelegate_task. - What was exposed as
agents:*was a Claude Code ACP bridge prompt-only slash command (not wired to orchestration), so formal skill conversion was required.
D4. Critic execution — Oracle-direct codex review (option A)
- Critic is a verification gate, so instead of going through a sub-agent (trusting self-reports), Oracle directly runs
codex review --commit <SHA>(or--base) and judges the raw output. 1:1 alignment with the "review only the diff" logic oforacle-auto-critic.sh, zero self-report risk.
D5. Lifecycle conversion — hybrid (option B)
- Only the procedure (step definitions) of
/start/stopbecome Hermes skills; the actual work (ADR generation,translate-adr.mjsauto-translation, sliding-window update, 4-file consistency check) invokes the verified existingscripts/*.mjsas-is. Do not rewrite deterministic node logic as model prose (prevents drift/regression). - Rationale: the value of the Hermes move is orchestration/interface/runtime integration, not prose-ification of deterministic build scripts. The
.mjslive inscripts/(repo), orthogonal to removing the.claudeSSOT (Phase 4).
D6. Result return/memory — drop inbox + keep MEMORY as source of truth (option B)
- The
inbox/{agent}-{task}.mdfile return is tmux async-structure glue -> drop it, replaced bydelegate_taskreturn summaries. - Sprint memory keeps
MEMORY.md+memory/*.mdas the source of truth (a domain asset directly referenced by ADR generation, blog conversion, and the/stop4-file consistency check). The Hermes profile memory holds only a quick-recall summary index mirror (explicitly not the source of truth).
D7. Execution unit — spike first, then formal migration
- To validate the unverified areas of a first native transition (persona-injected delegation quality, Oracle-sequential critic) as cheaply as possible, run 2 spike cycles first -> on validation, promote to a formal sprint (plan A: the spike branch becomes the formal starting point).
Implementation
Spike validation (2 cycles)
- Sensei (read-only): validate persona injection -> delegation -> structured report quality. Cross-checked
ai-analysis/src/circuit_breaker.pyagainst the cockatiel CB spec (config.py:37-39), found a real issue (can_execute()is 42 lines = violates the 20-line rule; the callback re-entry outside the lock needs documentation). Report format, line citations, and no-speculation all passed. - Gatekeeper (full cycle): converted two interpolated-string log calls in
services/gateway/src/.../jwt.middleware.tsto 2-arg structured logging (7bb885a, +2/-2, aligned with the S241/242 logging direction). Oracle-direct verification (diff clean, zero type errors in that file, eslint exit 0, jest 18/18) -> Oracle-directcodex review --commit 7bb885a-> CLEAN (0 P0/P1, proving decision 4). One self-report inaccuracy (the agent claimed "tsc exit 0" but the real exit 2 was a pre-existingtsconfig.json:12baseUrl deprecation, harmless to the changed file) was caught by Oracle-direct verification -> proving decision 6's value.
Foundational infra
delegation.max_concurrent_children: 3 -> 6(decision 2), keepmax_spawn_depth: 1.- New
algosu-agent-criticskill — Oracle-direct call procedure + Codex-c model="gpt-5.5"pin (reflecting the key finding). /start/stop->algosu-lifecycle-startalgosu-lifecycle-stopskills (decision 5, invoke onlytranslate-adr.mjs/check-adr-en-coverage.mjs).- Mirror the sprint index + decisions + Codex pin into the Hermes profile memory (decision 6, explicitly not the source of truth).
12 persona skills
- Created
algosu-agent-{conductor,gatekeeper,librarian,architect,scribe,postman,curator,critic,herald,palette,scout,sensei}. Echelon tier/model mapping consistent (Tier1 opus 3 · Tier2 sonnet 4 + critic codex · Tier3 sonnet 3 + palette opus exception). 9 were ported via parallel delegation on the newwidth-6concurrency (= dogfooding the migration itself).
⚠️ Key finding — Codex model pin required
- Default model
gpt-5.3-codex-> unsupported on the ChatGPT account (400),gpt-5.5-codex-> likewise unsupported,gpt-5.5(no suffix) -> works. Root cause: no top-levelmodelset in codexconfig.toml. The critic call must pin-c model="gpt-5.5". Exactly matches the accumulated memory carry-over "Codex model pin" -> resolved.
Verification
- Spike commit
7bb885a: diff +2/-2 clean (no other changes), zero type errors injwt.middleware.ts, eslint exit 0, jest 18/18 pass — re-run directly by Oracle. - Critic (Codex
gpt-5.5) CLEAN — "merely converted two JWT middleware log calls to structured logger arguments; compatible with StructuredLoggerService behavior; no functional regression." - Full check of the 12 skills: existence, frontmatter tier/model consistency, zero dispatch-glue leakage (the 1 critic match is an intentional contrast phrasing), zero plaintext secrets, format consistency.
- The 2 lifecycle skills: registration, frontmatter consistency, verification-script invocation lines preserved (zero logic rewrite), mirror block reflected.
Phase 1 Follow-up (2026-06-24)
Right after the formal transition, a transplant-fidelity inspection found and closed one dispatch-criteria gap. All changes are ~/.hermes/ profile assets (SOUL.md, skills); the only repo source-of-truth change is this ADR supplement.
- Full transplant-fidelity inspection: compared the
.claude/commandsoriginals against the Hermes profile skills. Confirmed the_baseOracle protocol is embedded in the body of the 12 agent skills rather than a separate skill (the correct pattern). Remaining.claude/commandsmentions are all frontmattersource:attributions — zero runtime glue leakage. Lifecycle complies with decision 5 (hybrid). - Ported 2 auxiliary skills: formally ported the previously-unmigrated
algosu-adr-blog(ADR→blog conversion) andalgosu-review(code-review checklist) → thealgosu/category goes 14→16 skills (measured).algosu-reviewadopts complementary separation instead of absorption into critic (this skill = shared self-check for domain agents/Gatekeeper;algosu-agent-critic= Codex external cross-review). - Dispatch-matrix reinforcement (gap closure): the Hermes-native dispatch decision criteria missing from the 12-persona port were added as 6 rules under
## Orchestration & Dispatchin the always-injected personaSOUL.md(49 lines). The originalalgosu-oracle.mddispatch section was entirely tmux-based (retired by decision 1), so a replacement matrix was a migration gap → now closed. Covers the direct-handle vsdelegate_taskboundary, 12-agent Tier domain routing, the Critic gate (codex review -c model="gpt-5.5"), lifecycle, and decision priority (stability > speed > completeness). Re-verified zero glue leakage. - Lesson: even after a first-pass verdict of "the body is absorbed by the system prompt," the dispatch criteria alone were a measured gap — always-applied behavioral rules must live in always-injected context (SOUL.md), not a load-on-demand skill, to fire every turn.