Building with mini, Part 2/9: Shaping the vision with project Mini, a developer tool for project scaffolding, introduces a 'mini project' command that conducts a critical plan-before-code interview via Claude Code. The interview walks through four stages to shape a project's vision, pushing back on weak ideas and refining design decisions. In a real session, the tool helped a developer choose the decimal module over floats for a calculator project and define error message formats. In Part 1 we ran mini init and got pycalc — a small calculator for the terminal. init asked only four questions, and .mini/project.md is accordingly thin: a name, one line about what , who it's for , and the constraints "Python 3, standard library only" . That's enough to start, but not enough to steer. Three things are missing: how we'll build it, what we deliberately won't build , and how we'll know it's done . That's exactly what mini project adds. mini project opens an interactive Claude Code session — but not to write code. It's a plan-before-code interview . Claude gets your current project.md as the starting point it won't ask what the project is about again and walks you through four stages: project.md is shown for approval; only then does it get saved.One trait, faithful to the philosophy from Part 0: the interview is instructed to be critical, not agreeable . A weak idea doesn't get nodded through — you're told why it's weak. And what the command doesn't do: it never touches .mini/state.json . Phase state stays in tested TypeScript; project rewrites one markdown page. The finished document isn't saved by a hallucination either — at the end the agent runs mini project --apply , and the contract goes through the same parser and renderer as init . cd pycalc mini project Mini first prints the exact prompt it will send to Claude no magic — you see everything and asks whether to start the session. What follows is from a real session, condensed; the answers are mine. Claude opened by reflecting the project back and refusing to assume anything: "Terminal calculator" can mean three quite different things, and each leads to a different design. 1. How is it used?One-shot pycalc "2+3 4" → prints 14 and exits , an interactive REPL, or both? This is the most important decision — it determines the whole structure. And careful: for the one-shot case people already use python -c "print 2+3 4 " or bc . What makes pycalc different, so that it has a reason to exist? That's not nitpicking — it's the question the "What I'm building" line has to answer. 2. How much math?Just + - / with precedence? Powers, modulo? Functions like sqrt , sin ? Variables? Every extra level means a more complex parser, and variables only make sense in a REPL. 3. How will you evaluate expressions?Fair warning: the tempting shortcut is eval . It's one line, but it's a security hole it evaluates arbitrary Python and you learn nothing from it. Alternatives: ast.parse with a node whitelist, or your own parser. What's your goal — tohavea tool, or tolearn how to write a parser? My answers: one-shot; versus python -c it's less typing and nicer error messages, versus bc natural syntax and decimals without scale setup. Just the four operators and parentheses. And the goal is to learn — own tokenizer and recursive descent, no eval . Claude then proposed the pipeline tokenizer → recursive descent parser → evaluation, tokens carrying their position in the input and pushed back where my framing was lazy: Number semantics and division.You yourself list "decimals without scale setup" as the advantage over bc . So 1/2 must be 0.5 , not 0 . I'd propose floats — but floats have the known artifacts 0.1+0.2 → 0.30000000000000004 . The alternative is the decimal module still standard library . For a calculator whose selling point is decimal numbers, I'd seriously consider decimal . Which one? Good catch — decimal it is. The interview just changed a design decision I would have gotten wrong by default. Two more came out of the same batch: unary minus goes in "without it the calculator feels broken — but it's a conscious scope extension, so I'm saying it out loud" , and errors get a defined shape — stderr, non-zero exit code, and a message that points at the problem: error: unexpected character '+' at position 2 2++3 ^ Then stage three — the part I've come to value most. First the agreed leave-outs, then the things Claude would be tempted to add: Power and modulo % — tempting, "just one more rule". But is right-associative, which is a new class of problem in the parser. Leave outin v1; once recursive descent is clear to you, it's the ideal v2 exercise.Reading from stdin/pipes echo "2+2" | pycalc — useful, but it grows the CLI layer.Leave out.Colored output,— the project needs none of it. One positional argument. argparse with ten flagsLeave out.Packaging pyproject.toml, pip install — needless overhead for a learning script.Leave out. And the closing move the prompt demands — "is there any question that, answered wrong, would send us down the wrong path?" — earned its place: We chose decimal , but we never saidwhat. The default context gives 28 significant digits: 1/3 prints 0.3333333333333333333333333333 . Technically correct, absurd as calculator output — and the fix, "set your precision", is exactly the scale from bc you wanted to avoid. I propose: compute at default precision,round the output to 10 places and strip trailing zeros 6.0 → 6 . Trade-off: the output is no longer the bit-exact intermediate value, but for a calculator readability wins. After I approved the draft, Claude saved it itself — through the contract, not by editing the file freehand: mini project --apply <<'EOF' NAME: pycalc WHAT: A small command-line calculator: pycalc "2+3 4" evaluates one expression and exits. Less typing than python -c , nicer error messages, and decimal arithmetic that works without bc's scale setup. FOR WHOM: People who want quick arithmetic in the terminal CONSTRAINTS: Python 3, standard library only APPROACH: - One-shot CLI: single positional argument, result on stdout, errors on stderr with a non-zero exit code. - Pipeline: tokenizer → recursive descent parser → evaluation. No eval ; the goal is to learn how to write a parser. - Grammar: + - / with correct precedence, parentheses, unary minus. - Numbers via decimal exact decimal arithmetic: 0.1+0.2 = 0.3 ; output rounded to 10 places with trailing zeros stripped 6.0 → 6 . - Tokens carry their position in the input so errors can point at the exact spot message + caret line . - Tests: unittest with a table of cases expression → expected result or error . NON GOALS: - Do not add an interactive REPL mode in this version. - Do not add functions sqrt, sin, … , constants, variables or assignment. - Do not use eval — ever, not even as a temporary shortcut. - Do not add or % in this version right-associativity of is a v2 exercise . - Do not read expressions from stdin/pipes; one positional argument only. - Do not add packaging pyproject.toml, pip install — run as a plain script. - Do not add colors or extra CLI flags. SUCCESS: - pycalc "2+3 4" returns 14; precedence and parentheses verified by the unittest case table. - 0.1+0.2 → 0.3, 1/2 → 0.5, -5+3 → -2. - Every invalid input 2++3, 2+3, abc, empty, division by zero exits non-zero with a stderr message showing position and caret — never a traceback. - Runs on plain Python 3 with zero dependencies outside the standard library. EOF ok Updated .mini/project.md That contract is also the command's second mode: --apply reads stdin, starts no Claude, and just writes the file. Handy when you want to edit project.md from a script or by hand without a session. One thing to watch: --apply does a full replace . Whatever you omit from the contract disappears from the file. The session prompt instructs the agent to keep the existing NAME / FOR WHOM / CONSTRAINTS — but when you write the contract by hand, that's on you. No new file appeared — project.md is still one page, it just steers now. Compare the before and after: init gave us "A small command-line calculator"; the interview turned that into a sharpened one-liner, six approach points, seven non-goals and four testable success criteria. The non-goals aren't decoration: mini keeps them in front of every later step, so when an agent in phase 7 feels like "improving" the calculator with colored output, the project has it in writing that no, it won't. And the cost side: the whole thing is one interactive session, and you pay for it once. The result is a page that saves tokens afterwards — newer versions of mini send warm sessions only a reference "read .mini/project.md if you don't already have it in context" instead of inlining it again and again. Is the interview worth it for every project? Honestly, no — for a weekend script, init alone is fine. It pays off the moment a project is big enough that an agent will work on it across many sessions without you re-explaining the vision each time. project.md now says what, for whom, how, what not, and when it's done. But the interview also left something behind: ideas like the operator — rejected for v1, too good to lose. A backlog for things that aren't phases yet is exactly what mini todo is for. Capturing ideas — that's Part 3. mini is open source: npm install -g mini-orchestrator, then mini install-commands in your project. Source and docs on