What the panel shows
On the done screen, under the green Package ready line, a box headed Package quality shows “N/10 tells pass”, green when all ten pass and amber otherwise, and “score N/100” on the right, the score being the passing tells times ten. Below it, one row per tell: a ✓ or ✗, the number and the title, then a dash and the detail. A passing detail says what was checked, such as “12 branch ids, all cited by a covers field” or “CLAUDE.md 84 lines, KICKOFF.md 27 lines, 3 screens × 4 states, legend in .claude/rules/”. A failing detail names the offending ids, lines or files, cut at eight entries (five for placeholders, names and budgets) with “… (+N)” after them, so the fix is a search in the file. The tells run on the rendered files, so a renderer gap shows up exactly like a model gap, and they are recomputed only when the spec, the project name, the ticks or the answers change.
Tells 1 to 5: coverage and closure
1. Branch coverage. Every branch id, meaning every .then branch, every .fail, every .back and every .alt, .else, .opt or .break section, is cited by the covers list of at least one acceptance criterion line in docs/spec.md, and no covers cites an id that does not exist. The detail lists “uncovered: …” and “covers cites ids that do not exist: …”.
2. Message coverage. For each sequence diagram, the Contracts section has exactly one row starting with that sequence's message id per message, and mentions every alternative section id somewhere in the section. The detail reads per sequence “S1: 4/4 message rows, 2/2 alternatives”, with “(missing S1.A2)” when one is absent. With no sequences it says so and passes.
3. One When per criterion. Every - US-n.ACk | … line has a Given cell, exactly one When cell and a Then cell, and the three together hold at most five steps, counting each “ And ” and “; ” as one more. A legacy one-cell criterion is reported as 0 When, no Given, no Then. The detail names the line and what it found: “US-2.AC1 (0 When, Given, no Then)” or “US-1.AC3 has 6 steps”.
4. No placeholders. No file contains TBD or TODO (case-sensitive, so the Spanish todo passes), <placeholder>, the rendered None yet marker, or the phrase lorem ipsum, outside the spec's Open questions and Appendix: Interview, which are your own words, and outside the sanctioned TODO(M0) lines. The detail cites file and line: “docs/spec.md:120 "…"”. An empty section such as Personas printing None yet fails here, which is how a spec-less package over MCP scores.
5. Field closure. Every E-Entity.field referenced in the spec or the design brief exists in a data-model table, and every field in a data-model table is referenced by a screen, a contract payload, or an .input, .wait or message text, as a whole word; a name two entities share counts only when the entity is named beside it. The detail lists “referenced but not in a data-model table: …” and “in the data model but never used by a screen, a contract or an .input: …”, the second being the same orphans the spec's Derived from lists show as having no source.
Tells 6 to 10: roles, numbers, milestones, names, budgets
6. Role closure. Every persona in the spec, every plan actor of kind user and every actor a sequence diagram declares as a user is a row of the Roles × permissions matrix, and every .if whose question names a role is a column, since a decision only some roles may take is a permission. The detail lists “not a matrix row: …” and “actor-gated decisions without a column: …”.
7. Numbers in NFRs. There is at least one NF row, and every row's target has a digit and a comparator: one of ≤ ≥ < > =, p95 or p99, max or min, at most or at least, under, within, below, above, over, or the Turkish en az, en fazla, en geç, en çok, altında, üzerinde, üstünde, aşmaz. “Fast” fails; “≤ 400 ms” and “8 saati aşmaz” pass. The detail reads “no NF-* rows” or “no unit or comparator: NF-2 "…"”.
8. Milestone closure. docs/plan.md has milestone blocks, every branch id, every criterion and every NF id appears as a - [ ] <id> line in exactly one “## M<n> — ” block, every block has a Verify sentence, and M1's Scope names exactly one flow. The detail lists “in no milestone: …”, “in two milestones: F1.X1 (M1, M2)”, “no Verify sentence: M3” or “M1 scope names 2 flows (F1, F2) — it must be one flow's happy path”.
9. Verbatim consistency. The product one-liner appears verbatim in CLAUDE.md, KICKOFF.md, the spec and the brief; every flow, entity and screen name is spelled identically after its id wherever the renderer prints it, fenced sources skipped; every “### SC-n — Name” heading is byte-identical in the spec and the brief; every docs/flows/<slug>.runic the spec cites exists; and no id-shaped token in docs/plan.md or the brief exists nowhere, with the tokens you typed yourself in a flow, the brief or an answer excused. The detail says which file lacks the one-liner, spells which name differently, or lists “ids that exist nowhere: …”.
10. Budgets. CLAUDE.md has at most 150 lines, at least four command lines (backticked or TODO(M0)) under Stack & commands, and no inlined legend; KICKOFF.md has at most 40 lines and mentions plan mode, one branch per milestone, id-named tests and the ask-versus-decide rule; every SC block in the design brief lists empty, loading, error and success; the brief lists at least one screen; with two or more screens at least one component is reused on two of them; and .claude/rules/runic-dsl.md exists with a paths: frontmatter. The detail names the first five problems, such as “SC-2 lacks the empty/loading state in the design brief” or “no component reused on ≥ 2 screens”.
The score and the copy chips
The score is the number of passing tells times ten, shown as score N/100 in the panel header and carried in the MCP tool's lint.score. Under the panel the Files list shows every path with its size in kB to one decimal. Under Copy by hand, four chips in a fixed order: Copy kickoff prompt (KICKOFF.md, for Claude Code), Copy CLAUDE.md, Copy spec (docs/spec.md) and, in blue, Copy design brief (docs/design-brief.md, for Claude Design); hovering shows the path and the destination. A clicked chip reads Copied ✓ for 1.8 seconds; clicking a second chip moves the confirmation to it and restarts the timer, so the second copy gets its full 1.8 seconds instead of ending when the first chip's timer fires. A blocked clipboard fails silently, and the zip has every file. The footer reads: “Unzip into an empty folder, run claude --permission-mode plan there, and paste the kickoff prompt. For Claude Design, paste the brief — it stands alone, the designer never sees the repo.” The primary button is Download .zip, and a failed tell never disables it.
Fixing a failed tell
Where the fix goes depends on the tell. Branch coverage and message coverage usually fail because the model skipped a criterion or a section; another run of Build, answered the same way, often closes them, and over MCP the build-spec prompt amends the spec and re-lints without touching the flows. Field closure and role closure point at the interview: a field no step names wants a longer .input line in the editor or a data answer that drops it; a persona with no row wants a roles answer naming what it may do. Numbers in NFRs is an interview answer with a digit and a comparator. Milestone closure fails when the spec's own milestones leave an id out; over MCP, dropping the milestones from the spec makes Runic derive a closed set, and in the app a second run usually places it. Verbatim consistency and budgets are renderer contracts and fail only when a name was spelled two ways in the spec or a component list is empty; adding a key element two screens share fixes the latter. When a flow has no .fail line, no answer produces an error state: that fix is in the editor, and the audit page lists what the editor flags.
Limits and gotchas
The tells are mechanical. They cannot tell a wrong permission from a right one, only a missing row from a present one, and a criterion that covers the right id with the wrong Then passes. A one-screen product passes the component rule by construction, since there is nothing to reuse. The placeholder tell is case-sensitive and matches TODO only outside TODO(M0), so an answer that says “TBD” in the interview appendix is allowed and one in a persona's goals is not. The comparator list is English and Turkish; a target written in another language with a digit but a comparator word outside the list fails, and the fix is a symbol such as ≤. Names the renderer echoes from your own text, a role written Saha elemanı beside an entity Saha Elemanı, are not compared, so casing differences in your prose never fail tell 9. Over MCP, without a spec, most tells fail because the spec sections read None yet; that is the expected starting score of the fix-and-retry loop, not a bug.
How to use it
- Generate the packageClick Build, tick the documents, answer the interview and click Generate package. The done screen opens with the Package quality panel under the green summary line.
- Read the headerN/10 tells pass and score N/100. Green means every tell passed; amber means at least one row below has a cross.
- Open the failing rowsEach ✗ row names the ids, lines or files at fault after the dash. Copy an id and search docs/spec.md or docs/plan.md for it.
- Decide where the fix goesA missing .fail or a thin .input is an editor fix; a missing role, field or number is an interview answer; a skipped criterion is another run of Build.
- Run Build again, or downloadClose the window, fix, and click Build again for a fresh interview; or download the zip as it is and let the kickoff's ask-versus-decide rule surface the gaps.
Commands & shortcuts
| 1. Branch coverage | Every .then, .fail, .back and alternative section id is cited by some criterion's covers; no covers cites a ghost id. |
| 2. Message coverage | Exactly one contract row per sequence message; every alternative section id mentioned in Contracts. |
| 3. One When per criterion | Given, exactly one When, Then, at most five steps counting And and semicolons. |
| 4. No placeholders | No TBD, TODO, <placeholder>, None yet or lorem ipsum outside Open questions, the interview appendix and TODO(M0). |
| 5. Field closure | Every cited E-Entity.field exists; every field is used by a screen, a contract or an .input, .wait or message. |
| 6. Role closure | Every persona and user actor is a matrix row; every .if that names a role is a matrix column. |
| 7. Numbers in NFRs | At least one NF row; every target has a digit and a comparator, English or Turkish. |
| 8. Milestone closure | Every branch, criterion and NF id in exactly one milestone checklist; a Verify per milestone; M1 scopes one flow. |
| 9. Verbatim consistency | One-liner, names, screen headings, flow file paths and cited ids identical across every file. |
| 10. Budgets | CLAUDE.md ≤ 150 lines with 4 commands; KICKOFF.md ≤ 40 lines with its four rules; four states per screen; a shared component; the rules file with its frontmatter. |
| score | Passing tells × 10, in the panel header and in the MCP tool's lint.score. |
Tips
- Aim for green before the first kickoff, not before every re-export. Once Claude Code is three milestones in, a re-lint tells you what a flow edit changed, which is a different use.
- Read the detail before the title. Branch coverage failing on F2.X1 means one .fail nobody wrote a criterion for; the fix is one criterion, not a rewrite.
- Put a comparator in every number you give. “400 ms” fails tell 7; “≤ 400 ms” passes; so does “400 ms altında”.
- Name a shared element in two screens' key elements, such as “Tutar alanı”, and tell 10's component rule is satisfied without inventing a design system.
- Over MCP, call export_build_package with only: "lint" while iterating. It returns the score and the failing tells without the files, so each round costs a few hundred tokens instead of twenty thousand.
Questions
Does a failed tell block the download?
No. The zip downloads at any score. The panel is a pointer at what to add in the answers, in the flows or over MCP before Claude Code finds the gap itself.
Why check the rendered files instead of the spec object?
Because the files are what Claude Code and Claude Design read. A renderer that drops a section would pass a check on the object and fail one on the file; checking the file catches both kinds of gap.
Can the model see the tells?
In the app, no; you see them and run Build again. Over MCP, yes: export_build_package returns lint.failing with the id, title and detail of every failing tell, and the build-spec prompt tells the client's model to amend the spec and call again until the list is empty.
Can my own casing fail Verbatim consistency?
No. The tell compares only the names the renderer prints right after an id, such as the heading after F2 or SC-1, and skips fenced sources and your own prose, so a role written Saha elemanı beside an entity Saha Elemanı is not a mismatch. If two spellings of a flow name appear after F2 in different files, the spec object itself carries both.
Is the score stored anywhere?
No. It is computed in the window from the rendered files and shown; the zip carries the files, not the score. The MCP tool recomputes it on every call.