← Back to list

Prompts Aren’t Dead. They Just Got a Bigger Vocabulary

Four old rules for algorithms, a little loop lingo, and Just Enough Jinja2 before the /loop, /goal, /batch, /routine machinery eats your…

Dean Peters in Dean On Delivery · 2026-07-04 16:29 · 318 claps · 16.1 min read
#ai-product-management #claude-code #product-management #vibe-coding #agentic-ai
Open on Medium ↗
Wiki topics: LLM · Large Language Models AGT · AI Agents BIZ · Business Strategy 💻 · Programming 📋 · Product Management

Prompts Aren’t Dead. They Just Got a Bigger Vocabulary

Four old rules for algorithms, a little loop lingo, and Just Enough Jinja2 before the /loop, /goal, /batch, /routine machinery eats your afternoon and tokens.

Apparently prompts are out of fashion now. /loop and /goal are the new black. So are /batch and /routine, but shinier. Four new blacks that possibly clash. Big whoop.

Yeah, you heard me. Big stinkin’ whoop.

Because you still have to prompt the loop. You still have to prompt the goal. You still have to prompt the batch and the routine. Nobody skipped a step. They renamed the step and put a slash in front of it. And here’s the part the fad conveniently leaves off the slide: the second you’re prompting a loop, you’re one bad instruction away from a runaway loop that won’t stop, or a batch that quietly burns your context window recomputing the same thing forty times before it hands you an answer that cost you triple the tokens for zero extra insight.

I still have the book that taught me why that happens. Leen Ammeraal’s Programs and Data Structures in C, Wiley, 1987, a full decade before he ever put C++ in a title. I was studying software engineering and C at Columbia in the late ’80s when it crossed my desk, and it’s one of the few from that era that never made it to a donation box. Four rules from that book still keep me out of trouble today the same way they kept me out of trouble as a C programmer back then:

  1. Calculate once, iterate often. Don’t recompute the same expensive judgment call on every pass through a loop.
  2. Order your checks by cost, not by alphabet. Cheap checks first, expensive reasoning only when the cheap check didn’t already clear it.
  3. Index before you search. Build the lookup once. Don’t rescan the whole list every time you need one thing from it.
  4. Know your critical path before you loop. Some items block others. Sequence matters more than the loop itself.

These rules were not written for LLMs. They were written for a world where compute was scarce, loops were literal, and a wasted pass through a dataset had a measurable cost that showed up on someone’s invoice. Sound familiar?

Start With What Already Works

This works today, exactly as written, no notation required:

/goal Use Richard Lawrence's story splitting rubric to break this epic into an array of right-sized user stories.

/loop Go through the story array. Split anything that still fails the rubric. Repeat until nothing splits.

/loop Go through the settled story array and render each story in canonical user story format.

That’s the Humanizing Work story-splitting rubric, Richard Lawrence’s original, called through a plain /goal and two plain /loop commands. It'll run. It'll probably even produce a decent backlog. I'm not telling you to abandon this.

I’m telling you what you can’t see when you run it this way. You can’t see how many passes it actually took. You can’t see whether it checked the cheap conditions before the expensive ones, or burned tokens doing it backwards. You can’t see whether it rescanned the whole array every time it needed one service’s worth of stories. You can’t see whether it sequenced the output by anything other than the order the stories happened to fall out in.

It’s a black box that usually works, and “usually works” is fine until story seventeen comes out wrong and you have no idea where to point the flashlight.

First, Know How These Things Fail

Goals, loops, batches, and routines are not four names for the same clever trick. Each controls a different part of the work, which means each has its own failure mode, and those failure modes compound differently at scale.

  • A /goal defines where the work is supposed to go. Its failure mode is ambiguity. If the goal does not explain what good looks like, what evidence matters, or when the work is done, the model will keep moving toward something that merely sounds successful. Usually in bullet points.
  • A /loop defines what repeats. Its failure mode is motion without progress. Without a ceiling, a stopping condition, or some way to detect that nothing useful is changing, the system can keep polishing the same artifact until the tokens are gone and every sentence sounds like it was raised by a management consultant.
  • A /batch defines the scope of repeated work. Its failure mode is scale without visibility. One weak instruction no longer damages one item. It marches through the whole folder, touching everything with the confidence of a Seagull Manager who just discovered automation.
  • A /routine defines what becomes reusable. Its failure mode is drift. Somebody changes the instructions, the source material, the rubric, or the model. Three weeks later the output behaves differently, and nobody knows whether the routine improved or merely mutated in captivity.

Four fashionable primitives. Four different failure modes. One generic instruction sprinkled over all four and called governance.

A goal needs a destination. A loop needs a stopping condition. A batch needs boundaries. A routine needs a receipt.

A loop without a ceiling is token hemorrhage. A routine without a receipt is folklore.

Play by the Old Rules Before Adding New Syntax

The temptation is to leap from that invisible machinery straight into code-shaped notation. Jinja2 in the prompt window, curly braces everywhere, the whole thing looking like a Flask template that wandered into the wrong meeting.

Resist it.

The four rules are the right first move, applied in plain language before a single brace appears.

1. Calculate Once, Iterate Often

Some context changes as the work progresses. Much of it does not.

The splitting rubric does not need to be rediscovered on every pass. Neither do the epic hypothesis, target persona, desired outcome, constraints, or agreed definition of a right-sized story. Compact those stable inputs into a working brief once, then let each pass focus only on the stories that still need attention.

The brief might contain:

  • The epic hypothesis
  • The target persona and job-to-be-done
  • The story-splitting rubric
  • The desired customer and business outcomes
  • Known constraints and dependencies
  • Decisions already made and approved

That becomes base camp. Each new pass starts there instead of launching another expedition from the airport.

Otherwise, you are paying the system to reread the same epic, reinterpret the same rubric, rediscover the same persona, and produce yet another slightly rearranged summary of things it already knew. Every pass. Every time. A hallucination wrapped in a bullet point stuffed inside a strategy recommendation you’re going to have to undo by Tuesday.

2. Order Checks by Cost

Not every question deserves the full intellectual orchestra.

Before asking the model to perform a nuanced evaluation against a sophisticated splitting rubric, check whether the story contains one recognizable persona, one coherent job, and something resembling an outcome. Before debating whether the story can be split by workflow step or business-rule variation, make sure it is not already three unrelated features hiding inside a trench coat.

The sequence moves from obvious and cheap toward subtle and expensive:

  1. Check that the required elements exist.
  2. Check that the elements do not contradict one another.
  3. Check that the story is not obviously sprawling across multiple jobs or workflows.
  4. Only then apply the full splitting rubric and deeper reasoning.

In prompt form, that can be this simple:

First, check whether each story contains one persona, one job, and one outcome.

Only if it passes those checks, evaluate it against the full story-splitting rubric.Do not send a sommelier to inspect an empty bottle.

3. Index Before You Search

Large epics, long documents, and folders full of source material invite a particularly wasteful kind of prompting: asking the system to rummage through the entire pile every time you need one thing from it. This is the LLM equivalent of a full table scan on an unindexed column, and it costs accordingly.

Before splitting, drafting, or revising, have the model map the territory. Catalogue the epics, identify the stories, note the workflows, mark the dependencies, record the unresolved questions, and connect each piece of evidence to the claim it supports.

Before processing the backlog, create an index containing:

1. Each epic and its intended outcome
2. The stories currently associated with each epic
3. Known personas, workflows, and services
4. Dependencies between stories
5. Open questions and missing evidence

Use this index throughout the rest of the workflow.
Do not rescan all source material unless I ask you to refresh it.

Now the model has somewhere to look before it goes wandering through the entire corpus again.

Without the index, every pass becomes another expedition into the same jungle with a fresh hat, a new token budget, and no institutional memory of the trail it cut yesterday.

4. Know the Critical Path Before You Loop

Sequence matters more than repetition.

Do not render beautifully formatted stories before deciding whether the epic itself is coherent. Do not polish acceptance criteria while the underlying job-to-be-done is still being argued over in another room. Do not split a story by workflow step before understanding whether those steps genuinely depend on one another.

For backlog work, the critical path looks like:

  1. Validate the epic hypothesis and intended outcome.
  2. Confirm the target persona and job-to-be-done.
  3. Identify major workflows, rules, and dependencies.
  4. Generate the initial story set.
  5. Apply the splitting rubric.
  6. Review stories for outcome alignment and independence.
  7. Render the approved stories in the desired format.

Do not loop on step six while step two is still under negotiation.

The tools changed. The physics did not.

Use Loop Lingo Before Loop Logic

Once the four rules are understood, the next level of sophistication is still not Jinja2.

It is teaching the model how to take turns.

Instead of asking:

Split this epic into stories.
Review all the stories.
Improve anything that fails the rubric.
Repeat until the backlog is complete.

Try:

Work in a multi-turn fashion.
First, identify the major workflows, business rules, and dependencies inside this epic.
Then process one workflow at a time.
For each workflow:
1. Generate an initial set of stories.
2. Apply the story-splitting rubric.
3. Identify any stories that remain too large, dependent, or ambiguous.
4. Return the proposed stories for my review.
5. Ask whether I want to modify them or continue.
Do not move to the next workflow until I approve the current story set.

That is loop lingo. A plain-English operating contract between you and the model. It tells the system how to decompose the work, where human judgment belongs, and when it has permission to continue.

The same discipline applies beyond backlog work. PRDs are simply where one-shot prompting goes to become a larger, more expensive crime scene.

Whether you are splitting an epic, drafting a PRD, synthesizing research, mapping assumptions, or comparing competitors, you are asking the system to do four things:

  1. Break the work into meaningful units.
  2. Process one unit at a time.
  3. Return control at each decision point.
  4. Continue only after the current work is approved.

The loop does not replace the prompt. The prompt teaches the loop how to behave.

Compact the Context as You Go

Breaking the work into turns solves half the problem. Each turn also needs a smaller context and a more focused ask.

Context is expensive, in tokens and attention. Every time you dump the whole backlog, six epics, eight interview transcripts, three personas, two strategy decks, a competitive analysis, and somebody’s seventeen-page Slack argument into the model, you increase the chance that it spends its reasoning budget admiring irrelevant furniture.

More context is not always more rigor. Sometimes it is merely a larger haystack with a more expensive needle.

A solid multi-turn workflow follows a simple rhythm:

  1. Map the complete work. Identify the workflows, sections, categories, epics, or decisions.
  2. Select the next unit. Focus on one bounded section, workflow, or question.
  3. Pull forward the minimum useful context. Goal, approved decisions, relevant evidence, constraints, and dependencies.
  4. Make one focused request. Draft, evaluate, split, compare, or test one thing.
  5. Compact the approved result. Carry forward the decision and essential context without dragging the entire conversation behind it like a steamer trunk.
  6. Repeat with the next unit.

One-shot prompting produces documents. Multi-turn prompting preserves decision points.

That is the difference.

Add Boundaries Before You Add Braces

For many workflows, loop lingo and plain-language discipline will be enough. You can make the important controls visible without adding a single curly brace.

markdown

For the goal:
- State the intended outcome.
- Define the evidence or conditions that indicate success.
- Stop when those conditions are satisfied or when judgment is required.

For the loop:
- Repeat no more than three times.
- Stop earlier if no material changes remain.
- After each pass, report what changed and what still requires judgment.
- If the same issue survives two passes, stop and ask me how to proceed.

For the batch:
- Process no more than ten epics in one run.
- Handle one epic at a time.
- Report the result and unresolved issues for each epic.
- If one epic fails, stop there rather than quietly contaminating the rest of the batch.

For the routine:
- Identify the routine name and version in every output.
- Record the source files and rubric used.
- List assumptions, skipped items, and failures.

Nothing here requires programming. It requires specificity. The model understands the intended flow, you know where you can intervene, and everybody has something slightly more useful than “Well, it usually works.”

Commit the Ultimate Heresy

Sometimes plain English is not enough.

Maybe the prompt has graduated from something you use occasionally into a /routine other people depend on. Maybe a /batch is about to touch forty epics while you're elsewhere making optimistic assumptions about how well things are going. Maybe your organization demands governance, repeatability, auditability, and enough receipts to satisfy a risk committee trapped in a windowless room.

That is when you season the markdown with Just Enough Jinja2.

Not a second career. Not macros, functions, recursion, inheritance, or whatever other incantations live in the darker corners of your template engine. Just enough visible structure to make the multi-step prompt legible and auditable without turning it into a software project wearing markdown pants.

Display Logic vs. Enforcement Logic

This distinction matters and most tutorials skip it entirely.

Display logic uses Jinja2 to render variable content. You’re substituting values into a template. The structure of the output is fixed; only the data changes.

Enforcement logic uses Jinja2 to enforce structural requirements. The template doesn’t just render data. It guarantees that certain structural contracts are met regardless of what the model wants to do about it.

The difference is consequential. A loop in display mode says “for each epic, show this.” A loop in enforcement mode says “for each epic, produce exactly this structure, in this order, with these required fields, or the output is malformed.”

Consider the difference between asking a model to “include acceptance criteria with multiple Given conditions” and structuring the template so that the Given conditions iterate from a data array. The first is a request. The second is a constraint. One is advisory. One is architectural.

The Isolated Examples First

A bounded loop:

{% for pass_number in range(1, 4) %}
Review pass {{ pass_number }}.
Stop if no material changes remain.
If the same issue survives two passes, stop and ask how to proceed.
{% endfor %}

A batch boundary:

{% for epic in epics[:10] %}
Process {{ epic }}.
Return its stories for review before moving to the next epic.
{% endfor %}

A routine receipt:

{% set routine_version = "backlog-split-v1.2" %}
Generated by {{ routine_version }}.

Each of these is doing something useful in isolation. None of them are doing what Jinja2 actually does when it’s operating as enforcement logic rather than display logic.

When the Primitives Compose

Here is what it looks like when all four rules, the loop lingo, and Jinja2 are operating together in a single template. This is a real pattern, the kind that runs in LangFlow or any agent framework that accepts a Jinja2-rendered system prompt, against Anthropic or OpenAI models without modification.

{% set routine_version = "backlog-split-v2.1" %}
{% set rubric = "Richard Lawrence / Humanizing Work story-splitting rubric" %}
## Routine: {{ routine_version }}
## Rubric: {{ rubric }}
## Source epics: {{ epics | length }}
---
## Working Brief (calculate once)
Epic hypothesis: {{ epic_hypothesis }}
Target persona: {{ persona }}
Job-to-be-done: {{ jtbd }}
Desired outcome: {{ desired_outcome }}
Known constraints: {{ constraints }}
Approved decisions: {{ approved_decisions }}
This brief is stable. Do not re-derive these values during iteration.
---
## Critical Path
Process epics in this sequence. Do not render stories for a later epic
until the current epic's stories are approved.
{% for epic in epics[:10] %}
## Epic {{ loop.index }}: {{ epic.title }}
Intended outcome: {{ epic.outcome }}
### Step 1 - Cost-ordered checks (cheap before expensive)
Check 1: Does this epic contain one coherent persona, one job, and one intended outcome?
  - If no: flag it and stop. Do not continue to Check 2.
Check 2: Do the persona, job, and outcome contradict one another?
  - If yes: flag the contradiction and stop. Do not continue to Check 3.
Check 3: Is the epic obviously spanning multiple jobs or workflows?
  - If yes: identify the jobs or workflows. Propose a split at the epic level before continuing.
Check 4 (expensive): Apply the full {{ rubric }} to identify story-splitting opportunities.
### Step 2 - Generate initial story set
Generate stories only after all four checks are complete.
Use the working brief above. Do not re-derive the persona, rubric, or outcome.
### Step 3 - Structure output
For each story in {{ epic.title }}:
{% for story in epic.user_stories %}
#### Story {{ loop.index }}
- **Summary**: {{ story.summary }}
- **As a** {{ story.role }}
- **I want to** {{ story.action }}
- **So that** {{ story.outcome }}
**Acceptance Criteria:**
- Scenario: {{ story.scenario }}
{% for given in story.given_conditions %}
- Given: {{ given }}
{% endfor %}
- When: {{ story.when }}
- Then: {{ story.then }}
{% endfor %}
### Step 4 - Return control
After processing {{ epic.title }}, stop.
Report: stories generated, stories flagged, open questions.
Ask whether to modify the current story set or continue to the next epic.
---
{% endfor %}
## Audit Trail
Routine: {{ routine_version }}
Rubric applied: {{ rubric }}
Epics processed this run: {{ epics[:10] | length }}
Epics deferred: {{ [epics | length - 10, 0] | max }}

A few things worth noting in that template.

The working brief is declared once, at the top, outside all loops. The persona, rubric, outcome, and constraints do not get rediscovered on every pass. That is rule one enforced in template structure, not just requested in prose.

The four checks are sequenced by cost. Check 1 is structural existence, cheap. Check 4 is rubric application, expensive. If Check 1 fails, Check 4 never runs. That is rule two enforced in conditional logic, not just asked for politely.

The {% for story in epic.user_stories %} loop with the nested {% for given in story.given_conditions %} is not display logic. It is a structural contract. The acceptance criteria will contain multiple Given conditions because the template iterates them from an array. You are not asking the model to "include multiple Given conditions." You are giving it no other option. That is enforcement logic.

The critical path comment at the top is not decorative. It tells the model the sequencing constraint before the loop begins. Rule four, in the prompt header rather than buried in a footnote.

The audit trail at the bottom is the routine’s receipt. Routine version, rubric applied, epics processed, epics deferred. When something goes wrong three weeks from now and the output behaves differently, you have somewhere to look.

Markdown remains the meal. Jinja2 is the seasoning.

The moment the template requires a debugger, a code review, and a pale engineering lead whispering “who did this?”, you have over-salted it.

Yes, This Is More Work

Breaking the work into sections takes time. Defining the sequence takes time. Compacting the context takes time. Adding modify-or-continue checkpoints, loop boundaries, batch caps, and routine versions takes time. It is more prescriptive, less spontaneous, and occasionally a colossal pain in the ass.

For a casual one-off prompt, the ceremony is ridiculous. You do not need a governed, versioned, multi-turn routine to rewrite a meeting invitation, suggest five headlines, or make your email sound slightly less like it was dictated during a hostage negotiation.

But once the prompt becomes infrastructure, the economics change.

When your elegant one-liner works, invisible logic feels magical. When it fails, invisible logic becomes a locked room containing your tokens, your afternoon, and seventeen user stories that all somehow forgot the user.

The structure gives you something to inspect when it does fail:

  • Which epic was being processed?
  • Which of the four checks stopped the workflow?
  • What context did it receive on that pass?
  • Which pass was running when the stopping condition fired?
  • Which item in the batch failed, and which items came after it that now need to be rerun?
  • Which routine version produced the output?

Without that logic, your diagnosis is: “Something somewhere in the batch went wrong.” With it, you identify the failed step, inspect the instruction, adjust the relevant control, and continue from a known point. You spend more time designing the route. You spend far less time wandering through the wreckage carrying a flashlight and blaming the model.

That is the bargain.

What’s in the loops Directory

The worked examples from this post, including the goals, loops, batches, routines, and the composite template above, are live in the [loops directory of my product-manager-prompts library](https://github.com/deanpeters/product-manager-prompts/tree/main/loops).

Here is what you’ll find there and what each file is for:

  • **goal-with-destination.md** — A /goal prompt that defines the intended outcome, the evidence that indicates success, and an explicit stopping condition. The antidote to ambiguity.
  • **bounded-loop.md** — A /loop with a ceiling, a stopping condition, a change-detection check, and a modify-or-continue handoff. The antidote to token hemorrhage.
  • **batch-with-boundaries.md** — A /batch prompt that caps scope, handles one item at a time, and stops cleanly on failure rather than contaminating the rest of the run.
  • **routine-with-receipt.md** — A /routine template that stamps its own version, records its source rubric, and produces an audit trail on every execution.
  • **composite-backlog-split.jinja2** — The full composed template from the section above. All four Ammeraal rules in one working file, designed to run in LangFlow or any agent framework that renders Jinja2 system prompts. Compatible with Anthropic and OpenAI models as-is.

Clone it, pull what you need, and drop it into whatever agent framework you’re running. The prompts are annotated. The Jinja2 is intentionally minimal. If you find yourself adding a fourth level of nesting, step back and ask whether the extra complexity is earning its keep or just expressing anxiety as syntax.

Why Scripted Beats Silent

/loop, /goal, /batch, /routine: keep using every one of them exactly the way you already type them. I'm not against the primitives and I never was. I'm against running them unseasoned and calling the result governed, when all you actually have is a black box that hasn't failed yet. A /loop is not a strategy. A /goal is not an outcome. But a /goal, /loop, /batch, and /routine seasoned with four rules a Dutch professor put in a textbook before most of these platforms' founders were out of grade school: that is an auditable set. You need four small habits, a light hand with the salt, and the discipline to season the commands you're already writing.

The tools changed.

The physics did not.

And yes, this is exactly the kind of AI and Product Management work I teach and coach at Productside. For those who can’t wait, I’ve added a loops subdirectory to my nearly-world famous “Product Manager’s Prompts” github repo.


메타데이터
post_id
fcbb3fad95db
slug
prompts-arent-dead-they-just-got-a-bigger-vocabulary-fcbb3fad95db
url
https://medium.com/deanondelivery/prompts-arent-dead-they-just-got-a-bigger-vocabulary-fcbb3fad95db
canonical_url
https://medium.com/deanondelivery/prompts-arent-dead-they-just-got-a-bigger-vocabulary-fcbb3fad95db
author_url
https://medium.com/@deanpeters
status
ok
fetched_at
2026-07-09 22:34:41