| name | intent-smell-audit |
| description | Review code, prompts, validators, regexes, heuristics, fallback logic, shell/wrapper authority, over-specific field ownership, and duality (two paths for two callers) for brittle patching or overengineering that masks product intent. Use when a function or feature may be over-controlled with deterministic regexes, fallback piles, quality gates, compatibility branches, large schemas, producer shells that carry creative/continuity authority, premature per-field authoring, detailed upstream contracts, or two parallel implementations of the same logical step that must stay in sync. |
Intent Smell Audit
Use this skill when implementation drift smells like patchwork or overengineering: broad regexes, fallback chains, quality validators, silent compatibility branches, oversized schemas, premature field-by-field authoring, or deterministic rewrites that make the system pass locally while hiding the real product contract.
The goal is not "no regex" or "no fallbacks." The goal is to keep deterministic code in the layer where it belongs and move subjective intent back into prompts, schemas, examples, source-of-truth writes, or explicit product decisions.
The goal is also not "fewer fields" for its own sake. The goal is to keep each decision at the layer that has the right context. Guidance should stay guidance unless the product requires a durable field. A high-level planner should not pre-author every downstream detail just because a schema can express it.
Core Principle
Deterministic checks are good for structural truth:
- parser shape, schema boundaries, provider-required fields, safety/security rules
- transport constraints, storage invariants, permissions, migrations
- narrow legacy compatibility with a named old state and a clear canonical path
Deterministic checks are suspect for product taste:
- prose quality, style, genre, emotion, "sounds cinematic," or action dominance
- regex repair of LLM output when clearer prompting/examples would carry the intent
- idempotence keyed on subjective quality heuristics
- fallback chains that let non-authoritative UI/cache/prose fields become truth
- try/catch branches that convert canonical failures into plausible-looking output
- hard diversity, novelty, or avoidance rules that create fake variety or
defensive output instead of motivated choices
- post-hoc cleanup that repeatedly fixes predictable LLM mistakes the prompt,
schema description, examples, or upstream write contract should prevent
Field-heavy architecture is suspect when:
- a guidance pass becomes the canonical writer for detailed downstream choices
- a large schema asks for decisions that a later per-item/per-shot/per-user-context pass can make better
- fields are persisted mainly so later code can avoid thinking, not because users need durable state
- validation failure on advisory fields blocks the user outcome
- a batch planner owns local details before the local context exists
Prompt-heavy architecture is suspect when:
- the instruction spends more space on what not to do than what good output
should choose, prioritize, or preserve
- negative rules become a substitute for positive taste, examples, or source
authority
- "never," "no two," "must vary," or "avoid" language forces arbitrary contrast
when repetition, continuity, or restraint would serve the user outcome
- the prompt tells the model to satisfy a menu of constraints instead of making
a contextual authoring decision
Shell-heavy architecture is suspect when:
- a producer shell, wrapper prompt, job envelope, adapter prompt, or orchestration
layer carries creative, continuity, policy, business, or product authority
after a more specific prompt/artifact has been authored, committed, or approved
- downstream execution reads the shell as the source of truth while the
section-level prompt, item prompt, clause, task, storyboard beat, or final
authored unit is treated as advisory
- a wrapper injects continuity or creative direction that can diverge from the
committed prompt for the unit being generated
- shell text exists mainly to rescue under-specified committed prompts instead
of repairing those committed prompts or their canonical write path
- tests only prove the wrapper contains the right idea, not that the committed
unit prompt is what binds the downstream provider, worker, renderer, or tool
Duality drift is suspect when:
- two functions, entry points, or pipelines exist for two callers because each
caller has slightly different needs, instead of one canonical operation that
takes optional input describing the variation
- a "combined" / "standalone" pair of the same logical step must stay in sync
forever — separate prompts, separate schemas, separate tests, separate places
where "what does X look like" can drift apart
- naming reveals the duality:
doX and doXSimplified, processY and
processYWithExisting, runZForBootstrap and runZForRevision, combinedQ
next to a standalone q
- one path was created to "isolate risk" to a new caller, and now both paths
drift apart on every change, fight contract drift forever, and duplicate
bug fixes
- a refactor proposal carves a single capability into "the bootstrap version"
and "the standalone version" — that is the smell, before any code is written
- the "two paths" framing assumes the callers are different; usually one is a
special case of the other with optional input, or both are special cases of
a more general operation
Workflow
1. State The Product Intent
Name the behavior that should be true for the user in plain language.
Ask:
- What should the user see, receive, or trust?
- What does "good" mean here?
- Which parts are objective structure versus subjective quality?
2. Map Authority
Before judging a patch, identify the real owner.
Record:
- canonical writer
- canonical reader
- generated/adapted transport layer
- binding source for final authored units such as committed section prompts,
approved item prompts, clauses, tasks, beats, or persisted plan rows
- caches, mirrors, UI-carried hints, and legacy fields
- producer shells, wrapper prompts, envelopes, adapters, and orchestration
layers that should carry logistics only
- advisory guidance versus durable product state
- decisions that require cross-item context versus decisions that require local/per-item context
If the wrong value is written upstream, fix the write path. Do not make every reader guess.
Ask:
- Does this field need to be persisted, or can it be derived/selected at the consuming step?
- Is this pass the only layer with the needed context, or is it pre-authoring local detail too early?
- Would the feature still work if this became prose guidance instead of a structured field?
- Is the schema large because the product is complex, or because ownership is misplaced?
- Is this code repeatedly cleaning up values that the LLM could have emitted
correctly with clearer vocabulary, examples, or field names?
- Is the cleanup a final defensive boundary, or has it become the primary way
the feature gets usable output?
- After a prompt/artifact is committed, approved, or persisted, does any shell
still override or reinterpret its creative, continuity, policy, or product
intent?
- If a section/item prompt is committed, is it the binding source for downstream
generation, or is the worker actually bound to a broader wrapper?
2b. Check Upstream Emission Before Cleanup
When code filters, maps, truncates, fuzzy-matches, or rewrites model output, do
not start by making the cleanup smarter. First ask whether the model was given a
clear enough contract to emit the right value in the first place.
For each cleanup path, check:
- Does the prompt show the exact vocabulary, enum, ID list, asset names, or
output examples that the cleanup expects?
- Is the schema field name and description specific enough that the model can
tell whether it should emit a slug, a free phrase, prose guidance, or a final
user-facing prompt?
- Is the cleanup correcting rare transport noise, or is it the normal path that
makes output usable?
- Are dropped values logged with enough telemetry to know whether the upstream
contract is wrong, the allowlist is stale, or the model ignored instructions?
- Would a smaller schema or a later local-context pass avoid the cleanup
entirely?
Prefer this pattern:
- prompt/schema/examples make the desired output obvious
- parser accepts model verbosity where safe
- post-parse normalizer trims/caps at persistence or provider boundaries
- filters remain final defensive boundaries with telemetry, not silent product
authors
2c. Prefer Structured Inventory Selection Over Prose Parsing
When an LLM must reference known entities, assets, tools, fields, files, IDs, or
other canonical objects, do not make free text the authority and then parse it
back with regex. Give the model the inventory and ask it to select from that
inventory in a structured field.
Preferred pattern:
- pass a categorized inventory when categories matter to the user outcome or
downstream ranking, for example
characters, environments, and products
- ask the LLM to return exact selected names or IDs in a structured array
- validate selections with simple allowlist/set membership at the schema or
persistence boundary
- resolve selected names/IDs to canonical records in the canonical write path
- let prose stay readable and provider-facing; do not treat prose as the
source of truth for selection
- keep inline mention parsers, markdown parsers, or rich-text document builders
as render/transport layers only, not as allocation authority
Use a flat selection array when canonical names are unique and the consumer only
needs membership. Use typed selections such as { type, name } or canonical IDs
when names may collide across categories, when provider caps require
type-specific ranking, or when the downstream reader needs to reason differently
about characters, environments, products, tools, or other buckets.
Smell: a prompt says "use exact @mentions" and code then scans prose with regex
to decide which assets, tools, or records were selected. The better correction
is usually an inventory-backed field such as selectedAssets,
mentionedAssets, selectedTools, or targetFields, then deterministic
membership validation and canonical ID resolution.
2d. Distinguish Fixed Structure From Open Guidance Packets
When an LLM returns advisory taste, style, rhythm, look, or camera-language
guidance, do not default to a closed object just because the first version had a
few known keys. Closed objects are appropriate when the consumer truly requires
those exact keys. They are brittle when the model can reasonably produce a
useful neighboring dimension such as contrast, lightingDelta,
paletteShift, textureBias, or another short look note.
Use this decision rule:
- If the field is structural truth, use a strict object, enum, ID list, count,
or provider-limit validator.
- If the field is advisory guidance with preferred dimensions, guide the model
toward stable keys in prompt/schema descriptions, but accept a
record<string,string> or equivalent string map at the LLM/provider boundary.
If the model sometimes emits a compact prose string for the same guidance,
accept it and normalize it to a small record such as { look: text }.
- Preserve every string-valued guidance entry through persistence and prompt
compilation. Render known keys first, then label unknown keys generically.
- Drop only invalid types, unsafe field names, or provider-breaking payloads,
and record telemetry that explains whether this was upstream contract drift,
an allowlist mismatch, or malformed output.
Smell: maintaining alias tables like lightingDelta -> lighting,
paletteBias -> palette, or contrast -> exposure to rescue useful guidance.
That usually means the schema is pretending open guidance is a closed taxonomy.
Prefer a stable-key prompt plus an open string record, then let downstream
prompt builders preserve and label the actual key the model chose.
2e. Keep Shells Non-Authoritative
When a system compiles prompts, plans, configs, work packets, or provider
requests in layers, separate the binding source from the shell.
A shell may route, format, carry IDs, apply provider limits, sequence work, and
add neutral connective tissue. It must not invent or override creative,
continuity, policy, business, or product decisions once a more specific
section/item prompt or source artifact has been committed, approved, or
persisted.
Reusable rule:
- The final authored unit is binding for that unit.
- The shell carries logistics and transport.
- If the shell needs to say something creative or continuity-critical, that
usually means the committed unit prompt/artifact is under-specified or the
canonical write path is wrong.
This applies beyond media generation. The same smell appears in email campaign
sections, legal clauses, support replies, workflow tasks, dashboard copy blocks,
agent tool packets, and any system where an outer envelope wraps smaller
committed units. The committed section prompt, clause, task, or item should bind
downstream behavior; the wrapper should assemble and deliver it.
Smell: a producer shell says "maintain continuity with X" or "use this creative
direction" while committed section prompts contain the actual per-section
intent. The better correction is to make each committed section prompt carry
the binding continuity/creative instruction it needs, then keep the shell
transport-only.
3. Scan For Patch Smells
Look for:
- broad regexes over prose or model output
- quality gates named like validators
- fallback chains with more than one non-authoritative source
- large structured-output schemas where many fields are advisory rather than canonical
- upstream passes that author per-item/per-shot detail before the local context exists
- duplicated decision points where an early field and a later prompt both choose the same thing
- validators that block the whole flow on missing guidance fields
- branches that silently reuse stale prompt, description, thumbnail, URL, or metadata
- model-output post-processing that changes intent rather than format
- sanitizers, mappers, fuzzy matchers, slug filters, or truncators that regularly
discard/reshape useful LLM output instead of feeding a clearer contract upstream
- prompts dominated by "do not," "never," "avoid," hard adjacency, hard
diversity, or hard novelty rules without positive criteria for when to repeat,
vary, preserve, or contrast
- "accepted then fixed" fields where the prompt permits broad prose but the
consumer actually needs a small vocabulary, enum, ID, or canonical asset name
- closed advisory objects where a string record would preserve useful LLM
guidance without alias-map maintenance
- alias maps that collapse useful neighboring dimensions into a few buckets
because a return validator or persistence schema is too closed
- producer shells, wrapper prompts, job envelopes, or adapter prompts that carry
creative, continuity, policy, business, or product authority after a more
specific unit prompt/artifact has been committed
- downstream workers/providers/renderers bound to shell prose instead of the
committed section prompt, item prompt, source clause, task, or final authored
unit
- two implementations of the same logical step (e.g.,
doXForA and doXForB,
combinedFoo and standaloneFoo) that must stay in sync; usually a sign one
is a special case of the other with optional input, or both are special cases
of a more general operation that should be factored out
- idempotence checks that decide "already good" using taste heuristics
- comments or tests that celebrate a workaround without naming the root cause
Useful searches:
rg -n "fallback|fall back|compat|legacy|heuristic|regex|RegExp|\\.replace\\(|try \\{|catch \\(" <paths>
rg -n "already|idempot|validate|quality|jargon|dominance|canonical|source of truth" <paths>
rg -n "guidance|contract|intent|emphasis|rhythm|planner|per-shot|per-item|schema|slots|fields" <paths>
rg -n "sanitize|normalize|filter|drop|dropped|allowlist|allowlisted|fuzzy|truncate|clamp|repair" <paths>
rg -n "do not|don't|never|avoid|no two|at least [0-9]+ distinct|must vary|variety|diversity|novelty|repeat|repetition" <paths>
rg -n "producer|shell|wrapper|envelope|adapter|sectionPrompt|committedPrompt|approvedPrompt|compiledPrompt|promptSections|source of truth|binding" <paths>
4. Classify Each Guard
Use these buckets:
Keep: structural contract, security/safety, parser/schema boundary, provider transport requirement, or named migration compatibility.
Narrow: valid compatibility or validation, but too broad, silent, or close to product taste.
Move upstream: the reader is compensating for an incorrect or missing canonical write.
Move to prompt/schema/examples: subjective LLM output quality is being enforced by code.
Move to upstream contract: deterministic cleanup is repeatedly repairing
predictable LLM output drift that should be prevented by clearer prompt
instructions, exact vocabularies, examples, field names, or source writes.
Move downstream: an upstream pass is pre-authoring a decision that a later local-context pass should own.
Collapse to guidance: durable fields are really advisory framing and should become a smaller brief, prose packet, or section-level guidance.
Bind to committed unit: a shell/wrapper/envelope is carrying authority that
belongs in the committed section prompt, item prompt, source artifact, clause,
task, or final authored unit.
Move to telemetry: the signal is useful for observing drift but should not block or rewrite output.
Delete: the branch masks failure, preserves stale behavior, or duplicates another owner.
Common smell categories:
Brittle regex
Fallback pile
Deterministic quality gate
Masked source-of-truth bug
Prompt/schema contract drift
Post-hoc cleanup masking upstream drift
Closed guidance object
Alias-map patchwork
Over-controlled guidance
Shell authority drift
Unbound committed prompt
Negative prompt pressure
Premature field ownership
Schema-as-product-spec
Duality drift
Compatibility shim, acceptable
False positive
5. Choose The Correction
Prefer fixes in this order:
- make the product intent explicit in prompt instructions, examples, field names, or schema descriptions
- replace negative prompt pressure with positive criteria for what to choose and
when to repeat, preserve, vary, contrast, escalate, or simplify
- when a sanitizer/filter catches expected drift, first tighten the upstream
contract so the model emits valid values; keep the sanitizer only as a final
defensive boundary with telemetry
- for advisory look/rhythm/style packets, guide preferred keys upstream but
accept open string records at LLM/provider boundaries; preserve unknown
string-valued keys instead of aliasing or dropping them
- make committed section/item prompts or final authored artifacts the binding
source for downstream generation; keep producer shells, wrappers, envelopes,
and adapters limited to logistics, assembly, and transport
- collapse advisory field sets into a smaller guidance object when downstream can make the detailed choice
- collapse two paths-for-two-callers into one canonical operation with optional
input describing the variation; resist the temptation to "isolate" by
duplicating
- move per-item decisions to the per-item/per-shot/per-user-context authoring step
- repair the canonical write/materialization/resolution path
- narrow deterministic validation to structure only
- fail loudly where canonical state is required
- keep legacy fallbacks only when named, scoped, and covered by tests
- turn subjective quality checks into telemetry or sampling review
6. Verify The Shape
Good verification proves the architecture, not just the output.
Use:
- source-contract tests that hard gates are structural only
- source-contract tests that prompts/examples expose the exact vocabulary or
canonical names that downstream filters expect
- telemetry or fixture checks showing defensive filters are rare, not the
normal path for making output usable
- source-contract tests that guidance schemas do not own downstream detail fields
- source-contract tests that downstream workers/providers/renderers bind to the
committed section/item prompt or final authored artifact, not to shell prose
- fixture checks showing producer shells do not add creative, continuity,
policy, business, or product authority after commit/approval/persistence
- tests that stale fallback paths do not become the primary source of truth
- prompt-contract tests or fixture review showing negative prohibitions were
replaced by positive authoring criteria where taste is subjective
- fixture/sample review for subjective prompt quality
- runtime trace when provider transport or generated media is the user outcome
For LLM prompt quality, prefer sampling and exemplar tests over brittle regex rejection.
Positive Prompt Lens
When reviewing prompts, look for two related smells: negative-rule pressure (telling
the model what not to do) and prescriptive palettes (handing the model a closed list
to choose from for a subjective quality, even when the list is positively phrased).
Both substitute enumeration for guidance.
For a focused audit workflow with carve-outs, reframing taxonomy, and the diagnostic
test for "is this list a cage?", use the prompt-instruction-framing skill. The
sections below are the lighter lens applied during a broader intent-smell pass.
A prompt can overcorrect after a failure by telling the model mainly what not to do.
That often produces defensive compliance: bland safe choices, fake variety, repeated
avoidance patterns, or output optimized for the rule instead of the product intent.
The corrected principle is: retrieve richly, author locally, vary meaningfully,
validate structurally.
Use this framing:
- replace hard subjective prohibitions with positive authoring direction
- describe when to repeat, preserve, echo, contrast, escalate, or simplify
- allow repetition when it supports continuity, dialogue grammar, pressure,
ritual, surveillance, escalation, or deliberate return structure
- encourage variation when emotional state, power relation, subject priority,
geography, time, or story beat changes
- keep validators focused on structure, counts, IDs, permissions, provider
limits, and persistence invariants
- use telemetry or sampling review for taste drift instead of hard rejection
Examples of prompt smells:
- "No two adjacent items may use the same choice" where motivated repetition may
be correct
- "Use at least N distinct techniques" where variety is not the actual user
outcome
- long "do not / never / avoid" blocks without an equally clear positive target
- tiny slug menus that collapse richer retrieved context into a few repeatable
buckets
- negative lists that compensate for missing examples, weak field descriptions,
or missing source-of-truth context
Prefer corrections like:
- "Avoid accidental repetition. Reuse the same choice when continuity, pressure,
dialogue grammar, or deliberate return structure earns it."
- "Prefer fresh choices unless this beat intentionally echoes a prior beat."
- "Choose contrast when the story turns; preserve language when continuity or
tension depends on it."
- "Treat retrieved examples as authoring context, not a mandatory checklist or a
tiny menu of allowed buckets."
Classify these as Negative prompt pressure, Over-controlled guidance,
Deterministic quality gate, Prompt/schema contract drift, or Move to prompt/schema/examples depending on where the pressure lives. The correction
should usually soften or remove hard negative taste rules, add positive intent
and examples, and leave structural validation intact.
Video Prompt Lens
For video-generation prompts, apply a director-first standard:
- lead with action, emotion, stakes, genre, scene state, and physical beats
- keep camera/cinematography as sparse accents at decisive moments
- let model-specific adapters handle transport and capability details
- keep subjective ratios like "action versus camera language" as telemetry or review signals, not hard rejection gates
Image prompts may need richer visual/composition specificity. Video prompts should primarily tell the model what happens and why it matters.
Output Format
## Intent Smell Audit: <feature/function>
### Verdict
Hold | Pass | Pass with narrow compatibility exception
### Product intent
...
### Authority map
- Canonical writer:
- Canonical reader:
- Non-authoritative state:
### Patch smells
1. <severity> — <category> — <file:line>
Smell:
Why it masks intent:
Canonical fix:
Acceptable compatibility scope:
Proof required:
### Classification
- Keep:
- Narrow:
- Move upstream:
- Move to prompt/schema/examples:
- Move to telemetry:
- Delete:
### Correction
...
### Verification
...
Guardrails
- Do not ban regexes or fallbacks categorically.
- Do not replace subjective quality problems with deterministic rejection loops unless the user explicitly asks for hard gates.
- Do not let compatibility become the new source of truth.
- Do not call something "validated" when it is only patched into looking valid.
- When in doubt, ask: "Why did the wrong value get written or resolved in the first place?"