About the project
Inspiration
Every engineering team has the same quiet tax: someone has to read the board every morning, decide what's actually runnable, do the work, get it reviewed, and open the PR. The interesting part — designing and building — is wrapped in hours of triage and coordination. We wanted to close the loop from a Jira spec to a reviewed pull request without a human in the inner loop, while keeping a hard human gate on every merge. The "loop engineering" framing — observe, act, verify, self-correct — is exactly the shape of an autonomous engineer, so we built one.
What it does
MoANT is a never-exiting orchestrator that runs an autonomous engineering agent named MoANT. Every working morning at 06:00 a scheduler wakes MoANT, who:
- Reads the whole Jira board through the Nexla MCP server and orders a runnable day, writing statuses back (
To Do → Selected, unrunnable →Blockedwith a stated reason). - Picks the top tickets by priority and, for each one, runs a bounded implement → verify loop: Claude Code writes the change on a fresh git worktree, then Codex adversarially reviews the diff refute-by-default, up to three rounds, until the change is correct or gets flagged.
- Opens a GitHub pull request against
main— and never merges it. A human reviews and merges. - Narrates every transition in Slack (plan, each verify round, PR link, blocks, summary) so a person always knows what the agent is doing. The autonomy boundary is explicit: code becomes a branch + PR only, status transitions are autonomous, and merge/apply requires a human identity — enforced at the proxy layer, not by convention.
How we built it
The core is a pure decision function (dispatcher.py) that takes the board, gates, a failure ledger, and a classifier, and returns a single next action — so it's fully unit-testable with no network and no token spend. All I/O lives at the edges in an integrations/ layer, and the daemon runs two lanes: a daily plan lane and a continuous code lane that runs exactly one heavy task at a time.
The stack is built around the hackathon's sponsor tools, each doing one job:
- Nexla MCP server — the single data plane to Jira: read tickets, transition status, post observations, all through one MCP tool surface
- Akash — every task runs in its own throwaway isolated container, so a worker can't see another task's files, tokens, or network.
- Zero.xyz — keyless service discovery, reframed as a recovery class: when a worker hits a service it has no key for, it discovers and calls it with no keys and no config instead of dead-ending.
- Claude Code as the implementer and Codex as the adversarial verifier, alternating in the fix loop.
- Slack for narration and GitHub for the PR.
A self-correction taxonomy (observe → classify → recover) maps each failure signature —
transient,missing_service,spec_gap,logic_defect,env_broken,budget_exceeded— to a specific recovery, so the box is never idle while a runnable ticket exists.
Challenges we ran into
Keeping the decision logic honest was the hard part. Making the dispatcher a pure function meant every piece of real-world messiness — auth, isolation, rate limits, partial failures — had to be pushed to the edges so the core stayed deterministic and testable. Enforcing the human-merge gate as an actual policy (a Pomerium-denied endpoint for worker tokens) rather than a polite convention took care, as did designing a bounded fix loop that fails safe: three rejected rounds still opens a PR, but flags it and moves the ticket to Blocked instead of silently giving up or looping forever.
Accomplishments that we're proud of
- A working orchestration core with a Streamable HTTP client for the Nexla MCP through Pomerium — initialization, tool discovery, board reads, transitions, and comments all verified against the live route by a
moant-jira-checkpreflight. - A genuinely testable autonomous system: the dispatcher, ledger, planner, and taxonomy all have offline tests that run with no network and no tokens.
- Turning keyless discovery (Zero.xyz) from a convenience into a first-class recovery in the self-correction taxonomy.
- Safety rails that are real: a kill switch (
touch /tmp/moant.pause), a dry-run mode, per-task wall-clock and token budgets, and an anti-thrash ledger that quarantines a ticket after three failures.
What we learned
The value of a hard boundary between the decision and the action. When the thing that decides "what should I do next" has no side effects, you can test it exhaustively and trust it in production; everything dangerous lives behind a scoped identity at the edge. We also learned that "self-correcting" is mostly a classification problem — a good failure taxonomy with a mapped recovery for each class is what keeps an autonomous agent from either dead-ending or thrashing.
What's next for MoANT
Letting Hermes propose new tickets from recurring failure patterns it observes on the board.