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.
Log in or sign up for Devpost to join the conversation.