Skip to content

Ask about example data, offer to add more before building, and plan new apps in 4-8 revisions - #50

Merged
pstrzalk merged 4 commits into
mainfrom
chat-example-data-and-plan-size
Sep 12, 2026
Merged

pstrzalk merged 4 commits into
mainfrom
chat-example-data-and-plan-size

Conversation

@pstrzalk

Copy link
Copy Markdown
Owner

Three prose changes to the chat and planner prompts. No Ruby logic, no schema, no migration.

What changes

The chat asks about example data before a first build. Most generated apps ship with an empty database, so the preview lands on blank index pages. The planner already knows how to write db/seeds.rb — nothing ever asked the user whether they wanted it. Confirmed end to end: answering yes produced a plan containing "Seed database with example books and loans", with no planner-prompt change needed.

The readiness ask offers a way out. "Ready to start?" becomes "Ready to start building, or would you like to add anything else?" — the last cheap moment to catch a missing feature. Creation only; modifications keep "Should I apply this?".

New-app plans are 4-8 revisions, preferring the smallest that fits. Widened from 3-6, then steered, because the model treats the upper bound as a target rather than a limit.

Two things worth a reviewer's attention

Scoping to the creation path is prose, not plumbing. Sections A and B of instructions.txt.erb split on whether a build is running, not on whether an application exists — section A covers both tools. A flat bullet would therefore also fire on "make the banner green". Since A already establishes that exactly one of create_application / modify_application is bound, keying the new rules to the offered tool is enough; no ERB local or second template needed.

"at most 2 clarifying questions" became "approximately 2". Under the hard cap the model spent one of its two slots on the example-data question instead of adding a third — the opposite of the intent. The cap was an arbitrary number to begin with.

Verification

Every prompt change was probed against the live LLM, not just asserted on.

Chat (bin/generate respond on scratch projects, since prompt wording can't be unit-tested for behaviour):

  • Creation → two clarifying questions plus "Also, would you like the app to come pre-filled with some example books and lending records…", then "Ready to start building, or would you like to add anything else?"
  • Modification (Gemfile in workspace, so ModifyApplication binds) → neither the example-data question nor the "start building" wording; "Should I apply this?" intact.
  • Confirmation gate intact — zero tool-call rows at the readiness turn.

Planner (bin/inspect-plan-application-creation), before and after the low-end directive:

Intent 4-8 alone + directive
a todo list app 8 5
a recipe box, tagged by cuisine 6
personal finance tracker with expenses, budgets, dashboard 8 8

Both padding cases disappeared: the todo plan now folds the migration into the model revision and CRUD into the scaffold revision, where before they were separate. The large intent still reaches 8, so the directive steers rather than caps.

bin/rails test 742 runs / 3435 assertions / 0 failures · bin/rubocop clean.

Deliberately not done

  • No seeds rule in the planner prompts. The clarification answer is the whole mechanism.
  • No min_items/max_items on PlanSchema. They would emit real minItems/maxItems, turning an off-range plan into "Could not generate a plan. Ask the user to rephrase." — worse than a plan of three. The range stays a hint, as it always was; the new plan_schema_test assertion only keeps the two copies of it from drifting into a contradictory instruction.
  • Modification planner's 1-6 untouched — deliberately divergent since the Bug A fix.
  • Feature invention left open. The 8-revision finance plan adds scope the intent didn't ask for (category management, income tracking, filtering, export). That is a different problem from revision count.

Notes

Wall time per generation rises with revision count — roughly 20-27 min at 8 revisions against the ~9 min three-revision runs on record. Nothing gates this at runtime; WALL_TIME_BUDGET lives inside the E2E_GENERATE test, which uses a pinned 3-revision fixture and does not move with this change.

Unrelated, found while running the suite: the local test database held a stale ruby_llm_models row (anthropic/claude-sonnet-5). A non-empty table suppresses RubyLLM's fallback to the gem's bundled models.json, so every chat-touching test errored with ModelNotFoundError on anthropic/claude-haiku-4.5 — including files this branch never touches. bin/rails db:test:prepare clears it, but no fixture keeps that table empty, so it can recur.

Plan and research: thoughts/shared/plans/2026-09-12/chat-example-data-question-and-plan-size.md, thoughts/shared/research/2026-09-12/seed-data-question-and-plan-size.md.

🤖 Generated with Claude Code

https://claude.ai/code/session_01SW7desfNVvjcghfMuPHbT3

Most generated apps ship with an empty database, so the preview lands on
blank index pages. The planner already knows how to write db/seeds.rb --
what was missing was ever asking the user whether they want it.

Adds an always-asked question to STATE A, scoped in prose to the creation
path: sections A/B split on whether a build is running, not on whether an
app exists, so a flat bullet would also fire on "make the banner green".
Keying it to the bound tool is enough, since A already establishes that
exactly one of create_application/modify_application is offered.

"at most 2 clarifying questions" becomes "approximately 2": under the hard
cap the model spent one of its two slots on the example-data question
instead of adding a third, which is the opposite of the intent.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SW7desfNVvjcghfMuPHbT3
The readiness ask was a bare "Ready to start?", which invites yes/no and
nothing else. For a first build that is the last cheap moment to catch a
missing feature, so name the alternative in the question itself.

Creation only. The bullet carries paired examples rather than one, since
"ready to start building" reads wrong for "make the banner green" -- the
modification path keeps "Should I apply this?".

The confirmation gate itself (Decision D2, 2026-05-04) is untouched: the
tool still fires only on the user's next confirming message.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SW7desfNVvjcghfMuPHbT3
Three to six was an authored heuristic from the phase 2 plan with no
recorded rationale; four to eight leaves room for the work a first build
actually covers.

Both places that state the range move together -- the prompt the model
reads and PlanSchema's array description, which it also reads. The new
plan_schema_test assertion exists to keep them from drifting apart into a
contradictory instruction.

Still a hint, not a constraint: PlanSchema passes no min_items/max_items,
so nothing rejects an off-range plan. Adding them would turn a stray
count into "Could not generate a plan", which is worse than a plan of
three. The modification planner's 1-6 is unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SW7desfNVvjcghfMuPHbT3
The model reads the range's upper bound as a target. Probed live, both "a
todo list app" and a finance tracker came back at exactly 8, and the old
"3 to 6" anchored on 6 the same way -- widening the range only moved where
it landed. The todo plan padded to fit: a migration revision after the
model revision that implies it, CRUD actions after the scaffold.

Mirrors how the modification prompt beat the same behaviour after Bug A --
range, then a directive toward the low end, then criteria for both ends.
The closing sentence names the two splits the probes actually produced
rather than warning about padding in general.

Re-probed: todo list 8 -> 5, recipe box 6, finance tracker 8. Counts now
track complexity, and the large intent still reaches the ceiling, so this
steers rather than caps.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SW7desfNVvjcghfMuPHbT3
@pstrzalk
pstrzalk merged commit 7b05810 into main Sep 12, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants