{"slug": "building-with-mini-part-4-9-the-main-loop-next-plan-do-done", "title": "Building with mini, Part 4/9: The main loop — next plan do done", "summary": "In the fourth installment of a series on building with mini, a developer demonstrates the main loop of the mini tool—propose, break down, build, close—using a Python calculator project called pycalc. The loop enforces a structured workflow where each phase corresponds to a single commit, with the agent proposing tasks, planning steps, executing code, and requiring human approval for closure. The developer highlights how the tool's non-goals and backlog interact to guide decisions, and shows that the tokenizer phase was completed with 27 test cases passing.", "body_md": "pycalc has a vision (Part 2) and a backlog (Part 3) — and still not a single line of Python. Today we fix that. Four commands form the heart of mini: **propose, break down, build, close**. One turn of the loop = one phase = one commit.\n\n`next`\n\n— propose\n\n```\nmini next\n```\n\n`next`\n\nis the entry point of the loop, and the only step that begins with a question: do you have your own idea, or do you leave it to the agent? I left it to the agent — and it's worth showing what it did with last episode's backlog:\n\nThe backlog has two items so far ([1]\n\n`**`\n\nand`%`\n\n, [2] reading from stdin), but both are explicitly out of scope for this version (non-goals), so neither fits the first phase.\n\nThis is exactly the interplay that `project.md`\n\nand `todo.md`\n\nexist for: the backlog offered itself, the non-goals stopped it. Instead, three candidates came up — tokenizer with positions, a CLI skeleton, a walking skeleton — each with its trade-off:\n\nI propose candidate 1: Tokenizer with positions.Why not the walking skeleton: it sounds tempting, but for a project this small the rewriting overhead outweighs the benefit — the pipeline has only three pieces, and in three phases it will be end-to-end anyway. The trade-off of candidate 1: until there's a CLI, you can't poke at anything by hand; verification is purely through tests.\n\nAfter approval the agent saves the phase itself, via `mini next --apply --title … --goal …`\n\n. State is never changed by the model's hand:\n\n```\nPhases:\n  [proposed] > 1. Tokenizer with positions\n\n  Next: mini plan (break it down) or mini do (run directly)\n```\n\n`plan`\n\n— break down\n\n```\nmini plan\n```\n\n`plan`\n\nbreaks the phase into steps — a short title plus a one-sentence detail (that pairing is deliberate: only the titles go into later steps' prompts, the detail is fetched when needed). For the tokenizer it produced five steps, from the `Token`\n\nNamedTuple through the number scanner into `Decimal`\n\nto the unittest table. And here too a decision surfaced that would otherwise only emerge in the code:\n\n`.5`\n\nand`2.`\n\nare deliberately rejected (simplest rule with exact error positions; trade-off:`.5`\n\nis valid in many calculators — say so if you want it supported and I'll adjust step 3).\n\nApproved, saved (`mini plan --apply`\n\nreads the steps from stdin):\n\n```\n[planned]  > 1. Tokenizer with positions\n  Steps:\n    [todo]     Token type and CalcError in pycalc.py\n    [todo]     tokenize() loop: operators, parens, whitespace\n    [todo]     Number scanning into Decimal\n    [todo]     Invalid character raises CalcError with position\n    [todo]     unittest case table in test_pycalc.py\n```\n\n`do`\n\n— build\n\n```\nmini do\n```\n\nOnly now does code get written. The session gets the phase, the steps and a reference to the project — not the whole conversation history. The agent ticks steps off as it goes (`mini do --apply --step-done \"<title>\"`\n\n), so `mini status`\n\nshows live progress, and at the end it writes a **run report** to `.mini/run/phase-001.md`\n\n: the verdict, the step statuses, and notes beyond the plan. Those notes are the most valuable thing in the report:\n\n- I deliberately rejected\n`str.isdigit()`\n\n— it accepts Unicode digits like`٣`\n\n, which`Decimal()`\n\nwould happily parse too. A helper restricts numbers to ASCII 0-9; there's a test that`1+٣`\n\nraises an error at position 2.- I verified the \"no input ever produces an unhandled exception\" claim with a fuzz over 20,000 strings — only\n`CalcError`\n\nwas ever raised.- One of my own test expectations was off by one (\n`10.25+0.75`\n\npositions); the tokenizer was correct, the test data was fixed.\n\nAll five steps done, 27 test cases green. And note what *didn't* happen: no REPL, no `sin`\n\n, no colors. The non-goals hold.\n\n`done`\n\n— close\n`done`\n\nis the loop's human gate — the one place mini insists on a person. State, incidentally, now reminds you itself that there's something to close:\n\n```\n[doing]    > 1. Tokenizer with positions\n            ⚠ stuck: phase \"doing\", but it has no open steps — close it via mini done\nmini done\n```\n\nThe agent summarizes the phase from the run report, proposes an entry for `CHANGELOG.md`\n\n, and asks the one thing that matters: **does it work for you?** Verification is my job, not its:\n\n```\npython3 -m unittest -v\n...\nRan 3 tests in 0.001s\nOK\n```\n\nAfter confirmation it writes the CHANGELOG (Keep a Changelog format, Unreleased section) and calls `mini done --apply`\n\n. That does three things at once: moves the state, writes the **phase memory** to `.mini/memory/phase-001.md`\n\n(goal, steps, run report — what the next phase will find useful), and wraps the entire phase's work into a single commit:\n\n```\ngit log --oneline\na01eb36 Phase 1: Tokenizer with positions\n9cf1df1 init: mini project setup\n```\n\nThe version isn't bumped by default and nothing is pushed — both are opt-in (`--bump patch --push`\n\n), no surprises on the remote.\n\n```\nPhases:\n  [done]       1. Tokenizer with positions (took 2m 6s)\n\n  Next: mini next (proposes the first phase)\n```\n\nTwo minutes six seconds from `do`\n\nto commit. And the backlog? Still 2 open items — the loop never touched it, because it never came up.\n\nThis is where the whole architecture from Part 0 pays off. Every step of the loop starts from **saved state**, not from a conversation: `plan`\n\ndoesn't need to know what was said in `next`\n\n, it reads the phase from `.mini/`\n\n. Between phases `/clear`\n\nis recommended — the context is thrown away, because everything that matters survives in files: state in `state.json`\n\n, experience in the phase memory, history in git and the CHANGELOG. The conversation is disposable; the state is permanent.\n\nA trade-off, to put it fairly on the table: one phase = one commit means a half-done phase isn't in git. If a `do`\n\nsession crashes mid-way, the code on disk stays (so do the report and the ticked steps), but the commit doesn't — which is why keeping phases small helps, exactly as `next`\n\nenforces (1-3 days, one verifiable goal).\n\nAnd about those three human stops (approving the proposal, approving the plan, verifying in `done`\n\n): for one phase a day they're priceless, for five phases in an evening they're a chore. That's precisely why `mini auto`\n\nexists — but more on that in a later episode.\n\nThe loop can build. Next we'll look at the two human checkpoints around it — `discuss`\n\n, when a phase needs talking through first, and `verify`\n\n, when \"the tests passed\" isn't enough and it calls for a human UI/UX review.\n\n*mini is open source: npm install -g mini-orchestrator, then mini install-commands in your project. Source and docs on *", "url": "https://wpnews.pro/news/building-with-mini-part-4-9-the-main-loop-next-plan-do-done", "canonical_source": "https://dev.to/stkremen/building-with-mini-part-4-the-main-loop-next-plan-do-done-344a", "published_at": "2026-07-01 11:00:00+00:00", "updated_at": "2026-07-01 11:18:54.727565+00:00", "lang": "en", "topics": ["developer-tools", "artificial-intelligence", "machine-learning"], "entities": ["mini", "pycalc", "Python", "Decimal", "CalcError"], "alternates": {"html": "https://wpnews.pro/news/building-with-mini-part-4-9-the-main-loop-next-plan-do-done", "markdown": "https://wpnews.pro/news/building-with-mini-part-4-9-the-main-loop-next-plan-do-done.md", "text": "https://wpnews.pro/news/building-with-mini-part-4-9-the-main-loop-next-plan-do-done.txt", "jsonld": "https://wpnews.pro/news/building-with-mini-part-4-9-the-main-loop-next-plan-do-done.jsonld"}}