From story to code with Claude Code
TL;DR
Save the story’s Confluence pages as Markdown files and let Claude grill you about them until every decision is made. Have it write the result to a spec file. Then implement that file in a new conversation, slice by slice. See the example.
How it works
Give it every page
The analysis pages for a story are the best starting point for an implementation. Give Claude every page the story depends on: the story itself, the data model, the stories it builds on. With only the story, Claude guesses; with all of them, it asks about real conflicts. There are two ways to give it Confluence pages:
- An MCP server gives Claude a tool to fetch pages itself. It works, but every response comes with metadata you don’t need, and all of it ends up in the conversation. See CLAUDE.md, skills and MCP servers.
- A script downloads a page and converts it to Markdown. You save the pages as files, and Claude reads them like any other file (see the example). Use this one: Claude gets exactly the text, and you see what goes in.
Grilling
Then Claude grills you. Grilling is a fancy term Matt Pocock came up with for an interview: Claude reads the pages and asks you questions in rounds, each with the answer it recommends, until every decision in the design is made. It finds the gaps in the story before they turn into gaps in the code.
It isn’t built into Claude Code. It’s a skill, /grill-me, from his skills collection, and the one skill I really think is worth it. Install only that one: most of the collection is more than you need. Let Claude do it: “Install the grill-me skill from https://github.com/mattpocock/skills into ~/.claude/skills/, with the skills it depends on. Don’t install any of the other skills.”
Three steps, two conversations
- Get the pages as Markdown. One file per page. Save the mockup screenshots next to them, and tell Claude they’re only inspiration: a mockup is a sketch, not a decision. When it disagrees with the analysis pages or the existing code, those win.
- Grill. Start a conversation with
/grill-meand point it to the files. At the end: “Write what we decided todocs/<story>/spec.md.” Always end with that file: it’s what the new conversation starts from, what you review the implementation against, and what a colleague can read. - Implement. Start a new conversation. “Implement
docs/<story>/spec.mdin slices I can demo. Stop after each slice.” Review and commit each slice yourself.
Gotchas
- Implementing in the grilling conversation. By then the context is full of options you rejected, and they leak into the code. See keeping Claude Code on track.
- Decisions that only live in a conversation. Close it and they’re gone.
Example
The shell function, for zsh or bash. It needs curl, jq, perl and pandoc, and an Atlassian API token.
# confluence-page <page-id>: print a Confluence page as Markdown
confluence-page() {
curl -sSf -u "$CONFLUENCE_USER:$CONFLUENCE_TOKEN" \
"https://$CONFLUENCE_SITE.atlassian.net/wiki/api/v2/pages/$1?body-format=view" \
| jq -r '.body.view.value' \
| perl -0777 -pe '
s/<div[^>]*toc-macro[^>]*>.*?<\/div>//gsi; # drop table of contents
s/<span[^>]*aui-icon[^>]*>.*?<\/span>//gsi; # drop icons
s/<pre[^>]*>(.*?)<\/pre>/<pre><code>$1<\/code><\/pre>/gsi; # bare <pre> is not code to pandoc
' \
| pandoc -f html-native_divs-native_spans \
-t markdown-header_attributes-link_attributes-raw_html --wrap=none
}
The page id is the number in the page’s URL.
Say the story is “Cancel an order”. It uses the order data model, and builds on “Place an order”, which is already implemented. Save all three, and the mockup:
mkdir -p docs/cancel-order
confluence-page 123456 > docs/cancel-order/story.md
confluence-page 123457 > docs/cancel-order/order-model.md
confluence-page 123458 > docs/cancel-order/place-order.md
cp ~/Downloads/cancel-order-mockup.png docs/cancel-order/
Then start the grilling conversation:
/grill-me We're implementing the story in docs/cancel-order/story.md.
The data model is in order-model.md. place-order.md is a story
that's already implemented. cancel-order-mockup.png is the mockup:
use it as inspiration. Where it disagrees with the analysis pages
or the code, they win.
Claude reads the files and the code, and asks its first round of questions:
Q1 - Cancel after shipping: The story says an order can be cancelled
"until it's on its way". Does that mean until the status is SHIPPED,
or until a parcel label is printed?
➡️ Until SHIPPED: the model has no field for a printed label.
Q2 - Refunds: place-order.md stores the payment. Should cancelling
refund it automatically?
➡️ Yes, a full refund, in the same transaction as the status change.
Answer, correct its recommendations where they’re wrong, and keep going until it has no questions left. Then: “Write what we decided to docs/cancel-order/spec.md.” Start a new conversation for the implementation.