demi
A demi-glace starts concentrated. Nothing extra goes in just because the kitchen has it nearby. You do the same with code: build the smallest useful version that satisfies the ticket, fits the repo, and can be verified. Complexity has to earn its way into the pan.
Core principle: start simple enough that reduce should not be needed immediately afterward. Small means understandable and verifiable, not cramped. The shortest version that hides intent is not demi; it is just dense.
The demi ladder
Before writing custom code, stop at the first rung that holds:
- Does this need to exist? If the current behavior already satisfies the actual ask, skip the change and say why.
- Can the repo already do it? Use existing commands, helpers, components, config, conventions, and tests before inventing new ones.
- Does the standard library cover it? Prefer built-in language or framework features over custom code.
- Does the platform cover it? Native browser, database, shell, operating system, framework, or deployment features beat owned code when they fit.
- Does an already-installed dependency cover it? Use what is already in the project. Do not add a dependency for a few clear lines.
- Can one explicit local change do it? One function, one component, one endpoint, one flag, one small data path.
- Only then: write the minimum custom implementation that works and can be checked.
The ladder is quick. Do not turn it into a research project. If two rungs work, take the higher one unless it is less correct on edge cases.
The demi pass
Run this before editing:
- Restate the actual ask. One sentence. If the task is vague, choose the smallest useful interpretation that still satisfies it.
- Find the local pattern. Read the nearest existing code, helpers, tests, and naming conventions. Prefer what the repo already uses.
- Climb the ladder. Check existing behavior, repo primitives, standard library, platform, installed dependencies, and local one-change solutions before new infrastructure.
- Name the smallest useful slice. Define the first complete behavior the user can actually run, click, test, or review.
- Cut speculative scope. Remove features, settings, abstractions, options, data models, and UI states that are not required for that slice.
- Pick the boring implementation. Use direct code, existing helpers, and local composition. New abstractions need evidence.
- Set a growth trigger. Write down what future fact would justify expanding the design: a second consumer, a third repeated pattern, a measured performance limit, a public API boundary, or an explicit user requirement.
- Verify the slice. Run the narrowest meaningful check through check. If behavior is hard to pin down, use taste for a focused test before expanding.
Simplicity gates
Before adding a new layer, answer these. If any answer is no, keep it local.
- Is this required by the current request?
- Does the repo already have a pattern for this?
- Is there a standard library, platform, or existing dependency path?
- Will at least two real callers use this now? Three is better for shared abstractions.
- Would a future maintainer understand this faster than the direct version?
- Can I verify the behavior after this change?
What to build first
Prefer these moves:
- One vertical slice over a broad scaffold.
- One explicit function over a generic utility.
- Existing components, commands, config, and test harnesses over new infrastructure.
- Clear local logic over premature indirection.
- A small typed data shape over a general schema system.
- A direct UI state path over a reusable state machine.
- A narrow CLI flag over an interactive prompt or new config file.
- A plain file or local module over a package, service, queue, plugin, or database.
- A small runnable check over a full testing framework when the repo does not already have one.
What to refuse early
Do not build these unless the current task proves they are needed:
- Framework swaps.
- Plugin systems.
- Generic registries.
- New persistence layers.
- Background workers.
- Multi-provider abstractions.
- Config formats for a single value.
- Theme systems for one screen.
- Large component libraries for one view.
- Repository-wide rewrites.
- Public API reshapes.
- "Future-proof" abstractions without a future requirement.
Not skimping
demi is not permission to be careless. Never simplify away:
- Trust-boundary validation.
- Error handling that prevents data loss.
- Security controls.
- Accessibility basics.
- Compatibility shims that protect real users.
- Calibration or tuning points for real hardware or external systems.
- Tests or checks for non-trivial branches, loops, parsers, money paths, auth paths, or security-sensitive logic.
- Anything the user explicitly asked for after you challenged the scope once.
A simple implementation without a check is not finished. Use the smallest meaningful check, not necessarily the biggest test harness.
Shortcut notes
If the small version has a known ceiling, name it in the plan or final report. Add an inline comment only when future maintainers would otherwise mistake the simplification for ignorance.
Examples:
Global lock is fine for single-user CLI; move to per-account locks if concurrent accounts matter.
Linear scan is fine below the current file sizes; index when measured input size makes it hot.
Native date input is enough here; custom picker only if design or browser support requirements change.
The one-screen plan
For non-trivial work, write this before editing:
## demi: <task>
Actual ask: <one sentence>
Smallest useful slice: <what will work when done>
Highest rung that holds: existing behavior | repo primitive | stdlib | platform | installed dependency | local change | custom code
Existing pattern to follow: <file/helper/test/component>
Cut from scope: <what is intentionally not being built>
Growth trigger: <what would justify expanding later>
Verification: <command/check/user-visible proof>
Keep it short. This is a guardrail, not a design doc.
Mode
demi is apply-by-default. After the quick pass, implement the smallest slice unless the task is architectural, public-interface-heavy, security-sensitive, under-specified in a way that changes the outcome, or the user explicitly asks for options first. In those cases, report the demi plan and wait.
For large work, combine with recipe: use demi to keep each recipe task small, vertical, and verifiable.
Boundaries
- Use mise when context is missing.
- Use recipe when the work needs sequencing.
- Use taste when the slice needs tests before confidence.
- Use check before claiming done.
- Use reduce only after code exists and needs behavior-preserving cleanup.
Common mistakes
| Mistake |
Reality |
| Building a full framework because the feature might grow |
Growth is a trigger, not a prediction. Ship the slice. |
| Adding config before there are real variants |
One value can be code. Two may still be code. Three starts a conversation. |
| Creating a generic utility from one use |
That is not reuse, it is disguise. Keep it local. |
| Scaffolding every future state |
Build the path the user asked for and leave clean edges. |
| Calling fewer files "less complex" |
A thousand-line god file is not demi. Small means understandable, not cramped. |
| Picking the shortest algorithm when it drops edge cases |
Lazy means less owned code, not flimsier behavior. Correctness wins ties. |
| Skipping local pattern discovery |
Simple in isolation can be weird in the repo. Match the kitchen. |
| Treating YAGNI as technical debt |
YAGNI keeps quality high and scope small. Skimping leaves a mess for later. |
1---2name: demi3description: Use before implementing, scaffolding, prototyping, or adding a feature when the work should start with the smallest useful code path, avoid speculative architecture, or prevent overbuilding before reduce would be needed.4license: MIT5---67# demi89A demi-glace starts concentrated. Nothing extra goes in just because the kitchen has it nearby. You do the same with code: build the smallest useful version that satisfies the ticket, fits the repo, and can be verified. Complexity has to earn its way into the pan.1011**Core principle:** start simple enough that [reduce](../reduce/SKILL.md) should not be needed immediately afterward. Small means understandable and verifiable, not cramped. The shortest version that hides intent is not demi; it is just dense.1213## The demi ladder1415Before writing custom code, stop at the first rung that holds:16171. **Does this need to exist?** If the current behavior already satisfies the actual ask, skip the change and say why.182. **Can the repo already do it?** Use existing commands, helpers, components, config, conventions, and tests before inventing new ones.193. **Does the standard library cover it?** Prefer built-in language or framework features over custom code.204. **Does the platform cover it?** Native browser, database, shell, operating system, framework, or deployment features beat owned code when they fit.215. **Does an already-installed dependency cover it?** Use what is already in the project. Do not add a dependency for a few clear lines.226. **Can one explicit local change do it?** One function, one component, one endpoint, one flag, one small data path.237. **Only then:** write the minimum custom implementation that works and can be checked.2425The ladder is quick. Do not turn it into a research project. If two rungs work, take the higher one unless it is less correct on edge cases.2627## The demi pass2829Run this before editing:30311. **Restate the actual ask.** One sentence. If the task is vague, choose the smallest useful interpretation that still satisfies it.322. **Find the local pattern.** Read the nearest existing code, helpers, tests, and naming conventions. Prefer what the repo already uses.333. **Climb the ladder.** Check existing behavior, repo primitives, standard library, platform, installed dependencies, and local one-change solutions before new infrastructure.344. **Name the smallest useful slice.** Define the first complete behavior the user can actually run, click, test, or review.355. **Cut speculative scope.** Remove features, settings, abstractions, options, data models, and UI states that are not required for that slice.366. **Pick the boring implementation.** Use direct code, existing helpers, and local composition. New abstractions need evidence.377. **Set a growth trigger.** Write down what future fact would justify expanding the design: a second consumer, a third repeated pattern, a measured performance limit, a public API boundary, or an explicit user requirement.388. **Verify the slice.** Run the narrowest meaningful check through [check](../check/SKILL.md). If behavior is hard to pin down, use [taste](../taste/SKILL.md) for a focused test before expanding.3940## Simplicity gates4142Before adding a new layer, answer these. If any answer is no, keep it local.4344- **Is this required by the current request?**45- **Does the repo already have a pattern for this?**46- **Is there a standard library, platform, or existing dependency path?**47- **Will at least two real callers use this now?** Three is better for shared abstractions.48- **Would a future maintainer understand this faster than the direct version?**49- **Can I verify the behavior after this change?**5051## What to build first5253Prefer these moves:5455- One vertical slice over a broad scaffold.56- One explicit function over a generic utility.57- Existing components, commands, config, and test harnesses over new infrastructure.58- Clear local logic over premature indirection.59- A small typed data shape over a general schema system.60- A direct UI state path over a reusable state machine.61- A narrow CLI flag over an interactive prompt or new config file.62- A plain file or local module over a package, service, queue, plugin, or database.63- A small runnable check over a full testing framework when the repo does not already have one.6465## What to refuse early6667Do not build these unless the current task proves they are needed:6869- Framework swaps.70- Plugin systems.71- Generic registries.72- New persistence layers.73- Background workers.74- Multi-provider abstractions.75- Config formats for a single value.76- Theme systems for one screen.77- Large component libraries for one view.78- Repository-wide rewrites.79- Public API reshapes.80- "Future-proof" abstractions without a future requirement.8182## Not skimping8384`demi` is not permission to be careless. Never simplify away:8586- Trust-boundary validation.87- Error handling that prevents data loss.88- Security controls.89- Accessibility basics.90- Compatibility shims that protect real users.91- Calibration or tuning points for real hardware or external systems.92- Tests or checks for non-trivial branches, loops, parsers, money paths, auth paths, or security-sensitive logic.93- Anything the user explicitly asked for after you challenged the scope once.9495A simple implementation without a check is not finished. Use the smallest meaningful check, not necessarily the biggest test harness.9697## Shortcut notes9899If the small version has a known ceiling, name it in the plan or final report. Add an inline comment only when future maintainers would otherwise mistake the simplification for ignorance.100101Examples:102103- `Global lock is fine for single-user CLI; move to per-account locks if concurrent accounts matter.`104- `Linear scan is fine below the current file sizes; index when measured input size makes it hot.`105- `Native date input is enough here; custom picker only if design or browser support requirements change.`106107## The one-screen plan108109For non-trivial work, write this before editing:110111```markdown112## demi: <task>113114Actual ask: <one sentence>115Smallest useful slice: <what will work when done>116Highest rung that holds: existing behavior | repo primitive | stdlib | platform | installed dependency | local change | custom code117Existing pattern to follow: <file/helper/test/component>118Cut from scope: <what is intentionally not being built>119Growth trigger: <what would justify expanding later>120Verification: <command/check/user-visible proof>121```122123Keep it short. This is a guardrail, not a design doc.124125## Mode126127`demi` is apply-by-default. After the quick pass, implement the smallest slice unless the task is architectural, public-interface-heavy, security-sensitive, under-specified in a way that changes the outcome, or the user explicitly asks for options first. In those cases, report the demi plan and wait.128129For large work, combine with [recipe](../recipe/SKILL.md): use `demi` to keep each recipe task small, vertical, and verifiable.130131## Boundaries132133- Use [mise](../mise/SKILL.md) when context is missing.134- Use [recipe](../recipe/SKILL.md) when the work needs sequencing.135- Use [taste](../taste/SKILL.md) when the slice needs tests before confidence.136- Use [check](../check/SKILL.md) before claiming done.137- Use [reduce](../reduce/SKILL.md) only after code exists and needs behavior-preserving cleanup.138139## Common mistakes140141| Mistake | Reality |142|---|---|143| Building a full framework because the feature might grow | Growth is a trigger, not a prediction. Ship the slice. |144| Adding config before there are real variants | One value can be code. Two may still be code. Three starts a conversation. |145| Creating a generic utility from one use | That is not reuse, it is disguise. Keep it local. |146| Scaffolding every future state | Build the path the user asked for and leave clean edges. |147| Calling fewer files "less complex" | A thousand-line god file is not demi. Small means understandable, not cramped. |148| Picking the shortest algorithm when it drops edge cases | Lazy means less owned code, not flimsier behavior. Correctness wins ties. |149| Skipping local pattern discovery | Simple in isolation can be weird in the repo. Match the kitchen. |150| Treating YAGNI as technical debt | YAGNI keeps quality high and scope small. Skimping leaves a mess for later. |