How to surface ambiguity, lock decisions, generate scenarios, and implement safely

Part 1 argued that the hard part of LLM-assisted refactoring is not coding. It is transferring intent. Part 2 is the practical playbook: how to run the refinement conversation so ambiguity and inconsistency get revealed early, then turned into a coherent set of rules that can actually be implemented. I’ll keep using the bulk calendar edit example because it is familiar, but the workflow applies broadly.

1. The Workflow at a Glance

Here is the process that works in practice:

  1. Write the initial headline requirement
  2. Ask the LLM to find ambiguities and contradictions
  3. Answer those questions as concrete decisions
  4. Record decisions in a decision log
  5. Convert decisions into a scenario matrix
  6. Use scenarios as acceptance tests
  7. Implement only after rules and scenarios align

The key is that you do not implement during steps 2 to 6.

2. The Refinement Prompts That Actually Help

Here are prompt patterns that consistently produce value.

Prompt A: “Ambiguity sweep”

Ask the model to list:

  • ambiguous terms
  • missing decisions
  • edge cases

Example:

List all ambiguous phrases and undefined behaviors in these requirements. For each, ask a clarifying question that changes the implementation.

Prompt B: “Contradiction hunt”

Example:

Assume these rules are implemented. Find scenarios where two rules conflict. Explain why and propose decision points.

Prompt C: “Scenario generator”

Example:

Generate test scenarios as (state, action, expected outcome). Cover mixed values, required fields, confirmation semantics, and invalid actions.

Prompt D: “Minimal change plan”

Only after clarity:

Propose the smallest set of code changes to implement these rules while preserving existing single-select behavior.

These prompts keep the LLM in “requirements pressure test” mode rather than “guess and code” mode.

3. Simulated Refinement Rounds That Match the Real Process

Here is a simulation designed to match your real workflow: we will iteratively refine requirements by repeatedly asking targeted questions until the rules are internally consistent and unambiguous.

Start by telling the LLM that this is a requirements refinement session. The goal is to clarify requirements, terminology, edge cases, and expected behaviors, not to write or propose implementation details or code. Open the session with something like:

We are going to run a requirements refinement session. I will provide a list of ambiguous phrases, missing definitions, and unclear behaviors from the requirements. For each item, ask one clarifying question whose answer would materially affect the implementation. Ask questions only, do not implement or suggest code. After each question, I will answer, and my answer becomes a binding decision that updates the requirements.

Then proceed item by item:

  • Ask exactly one high-impact clarifying question per ambiguity.
  • Treat each answer as a final decision and incorporate it into the refined requirements before moving to the next item.
  • Continue until the requirements are coherent, complete, and testable.

Round 1: The first headline requirement

You:

Bulk edit calendar events. If values match, show them. If values differ, show empty.

Assistant:

Empty is ambiguous. Does empty mean “clear” or “mixed”? What happens if the user confirms without typing?

Decision recorded:

Mixed is distinct from empty. The UI must represent mixed explicitly.

Round 2: Mixed value representation

You:

Show a placeholder like “multiple values” when values differ.

Assistant:

Great. Now define commit semantics. Does typing auto-save? Or do we require explicit confirmation?

Decision recorded:

In bulk edit, UI changes are pending. Saving requires explicit confirmation.

Round 3: Confirming changes

You:

Each field gets an Apply button. Only confirmed fields are applied.

Assistant:

Now define atomicity. If the user applies location but some selected events would be invalid overall, do we apply to the valid ones only?

Decision recorded:

No partial saves. Changes are atomic across the selection.

Round 4: Required fields vs optional fields

You:

Start and end time are required, but users often want to change only the location.

Assistant:

If you require re-entering required fields every time, UX becomes painful. Can stored required values count as satisfying “required”?

Decision recorded:

If all selected items already have valid required fields in stored data, allow applying optional changes without re-entering required fields.

Round 5: Clearing required values

You:

If the ticked field is required and the input is empty, do not apply the change.

Assistant:

That blocks destructive clears. Now define behavior when type changes: does changing type save immediately or only when at least one field is applied?

Decision recorded:

Type changes in bulk edit are pending. They are only committed when the user applies at least one field, and validation must pass.

At this point, the rules stop contradicting each other, and you can move to scenarios.

4. The Decision Log: The Short List That Prevents Rework

A decision log is a list of statements that are unambiguous and testable.

Here is the final decision log for the bulk edit example:

1. Single-select behavior remains unchanged.

2. Bulk edit mode uses pending UI state. Editing fields does not persist.

3. Values display rules:

  • If all selected items share a value, show it.
  • If values differ, show empty plus “multiple values” indicator.

4. A field is only applied when the user clicks Apply for that field.

5. Saves are atomic across the selection. No partial updates.

6. Validation rules:

  • If a required field is being applied and input is empty, ignore the action.
  • If required fields are already valid in stored data for all selected items, optional fields may be applied without re-entering required fields.
  • If any selected item lacks required validity for the final state, block the save.

7. Type changes in bulk mode are pending and only commit when at least one Apply occurs and validation passes.

This is already enough to implement, but scenarios make it safer.

5. The Scenario Matrix: Turning Rules Into Tests

A scenario matrix prevents “we thought it was obvious” bugs.

Format:

  • State
  • UI display
  • Action
  • Expected outcome

Scenario 1: Shared optional value

  • State: all selected events have location “Office” and valid times
  • UI: location shows “Office”
  • Action: user sets location to “Home” and clicks Apply
  • Expected: all locations become “Home”

Scenario 2: Mixed optional values

  • State: locations differ, times valid
  • UI: location empty with “multiple values” placeholder
  • Action: user enters “Home” and clicks Apply
  • Expected: all locations become “Home”

Scenario 3: Mixed optional values, no confirmation

  • State: locations differ, times valid
  • UI: “multiple values” placeholder
  • Action: user types “Home” but does not click Apply, then exits
  • Expected: no changes saved

Scenario 4: Optional apply with existing valid required fields

  • State: all have valid start/end, locations differ
  • Action: apply location only
  • Expected: location updates, start/end unchanged, other fields untouched

Scenario 5: Some items missing required validity

  • State: one event missing end time
  • Action: apply location
  • Expected: nothing changes (atomic block)

Scenario 6: Attempt to clear the required field

  • State: all valid times
  • Action: clear the end time input and click Apply on the end time
  • Expected: no change applied

Scenario 7: Pending type change alone

  • State: selected items have mixed types
  • Action: user chooses a new type but does not apply any field
  • Expected: nothing saved

Scenario 8: Type change plus apply requires validity

  • State: selected items have valid required fields for the old type
  • Action: choose a new type that requires extra fields, then apply the location
  • Expected: blocked unless new type required fields are satisfied

Once scenarios cover your rules, you have practical acceptance tests.

6. Where “Stop Refining” Actually Makes Sense

This is how you avoid endless loops. Stop refining when:

  • Every scenario has an unambiguous expected outcome
  • There are no contradictory decisions
  • The implementation approach is clear in plain language
  • Remaining uncertainties are explicitly deferred

This is the moment where the LLM stops being a question generator and becomes a productivity tool for implementation.

7. Implementation Becomes Mechanical Once Rules Exist

With the rules above, implementation can follow a predictable structure:

  1. Detect mode: single vs bulk
  2. For bulk mode, compute per-field display state:
  • common value or mixed
  1. Maintain pending UI state separate from persisted records
  2. On Apply:
  • gather selected items
  • validate according to the decision log
  • if valid, apply changes atomically
  • refresh selection and UI

Notice what is missing: guesswork. The decisions already handle the hard parts.

8. Is the time and effort worth it if the final implementation still isn’t good?

Yes, it can still be worth it even when the final implementation is not satisfactory, because the main output is not only “code”, it is clarity.

  • Implementable clarity: Even if the AI output is weak, refining requirements gives you a clear, actionable definition of what the feature should do. If you decide to implement it manually, you already know what to implement.
  • Requirements refinement practice: The time spent is not wasted, because you exercised the skill of turning a vague idea into a concrete scope, flows, and constraints. That skill transfers to every future project.
  • Less dependence on AI: Doing the thinking yourself builds confidence and judgment. It helps you avoid outsourcing critical decisions to tools and keeps you capable of working without them.
  • Structured thinking and analysis: Breaking down the feature into user journeys, edge cases, and acceptance criteria trains you to think systematically, not reactively.
  • Clear acceptance criteria: A refined spec gives you a measurable way to judge success. Even if implementation quality varies, you have a stable reference for what “done” means.
  • Early risk discovery: Requirements work often reveals missing assumptions, tricky integrations, performance concerns, or security gaps before you spend time building the wrong thing.
  • Better alignment and communication: A written, refined description reduces misunderstandings across product, engineering, QA, and stakeholders, and prevents costly back-and-forth later.
  • Faster iteration later: Once the “what” is clear, you can change the “how” more easily. Different tools, different approaches, or phased delivery become much simpler.
  • Reusable project asset: Good requirements can be reused for documentation, onboarding, testing, and future enhancements. The value lasts longer than the initial attempt at implementation.

9. Lessons Learned

  1. Refactoring with an LLM is intent transfer. Code is the easy part once intent is explicit.
  2. Ambiguity is the real bug factory. It produces plausible implementations that are wrong.
  3. Use the LLM to pressure test requirements, not to guess them.
  4. Decision logs prevent circular refinement.
  5. Scenario matrices turn rules into testable reality.
  6. Know when to stop. “Consistent and testable” beats “perfect.”

10. Closing: A Single Sentence Summary

If you want one sentence that captures the whole approach:

We did not iterate on code. We iterated on the rules until the code stopped being risky.