@slatesvideo/shared 0.6.2 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api-url.d.ts +9 -0
- package/dist/api-url.js +9 -0
- package/dist/auth.d.ts +13 -1
- package/dist/auth.js +9 -5
- package/dist/clients/cloud.d.ts +3 -0
- package/dist/clients/cloud.js +34 -3
- package/dist/clients/desktop.js +3 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.js +44 -1
- package/dist/operations/index.d.ts +243 -31
- package/dist/operations/index.js +1483 -154
- package/dist/operations/surface.d.ts +69 -0
- package/dist/operations/surface.js +227 -0
- package/dist/prompts/agent-doctrine.d.ts +36 -0
- package/dist/prompts/agent-doctrine.js +201 -0
- package/dist/prompts/asset-label.d.ts +23 -0
- package/dist/prompts/asset-label.js +70 -0
- package/dist/prompts/banned-tokens.d.ts +40 -0
- package/dist/prompts/banned-tokens.js +219 -0
- package/dist/prompts/character-sheet.d.ts +0 -2
- package/dist/prompts/character-sheet.js +0 -2
- package/dist/prompts/craft-cards.d.ts +20 -0
- package/dist/prompts/craft-cards.js +82 -0
- package/dist/prompts/environment-sheet.js +16 -0
- package/dist/prompts/index.d.ts +1 -0
- package/dist/prompts/index.js +4 -0
- package/dist/prompts/model-capabilities.d.ts +65 -1
- package/dist/prompts/model-capabilities.js +139 -2
- package/dist/prompts/model-facts.d.ts +20 -4
- package/dist/prompts/model-facts.js +95 -27
- package/dist/prompts/partials.generated.js +2 -1
- package/dist/prompts/prompting-tips.d.ts +1 -1
- package/dist/prompts/prompting-tips.js +123 -0
- package/dist/prompts/reference-composer.d.ts +36 -7
- package/dist/prompts/reference-composer.js +75 -20
- package/dist/prompts/reference-rules.d.ts +15 -26
- package/dist/prompts/reference-rules.js +15 -93
- package/dist/prompts/shot-grammar.d.ts +154 -0
- package/dist/prompts/shot-grammar.js +184 -0
- package/dist/prompts/shot-spec.d.ts +265 -0
- package/dist/prompts/shot-spec.js +303 -0
- package/dist/skills/content.js +25 -22
- package/exports/slates-prompt-builder/generated/SKILL.md +3 -3
- package/exports/slates-prompt-builder/generated/reference-content-policy.md +6 -0
- package/exports/slates-prompt-builder/generated/reference-kling.md +22 -0
- package/exports/slates-prompt-builder/generated/reference-nano-banana.md +17 -0
- package/exports/slates-prompt-builder/generated/reference-seedance.md +19 -1
- package/exports/slates-prompt-builder/generated/slates-prompt-builder-manifest.json +17 -17
- package/exports/slates-prompt-builder/generated/slates-prompt-builder.skill +0 -0
- package/package.json +83 -73
- package/skills/_partials/decision-log.md +5 -4
- package/skills/_partials/thresholds.md +19 -0
- package/skills/slates-content-policy.md +15 -1
- package/skills/slates-cost-discipline.md +26 -4
- package/skills/slates-model-selection.md +2 -2
- package/skills/slates-one-prompt-film.md +20 -12
- package/skills/slates-project-organization.md +1 -1
- package/skills/slates-prompting-elevenlabs.md +61 -2
- package/skills/slates-prompting-flux-2-max.md +39 -0
- package/skills/slates-prompting-gpt-image-2.md +109 -70
- package/skills/slates-prompting-inworld-tts.md +166 -0
- package/skills/slates-prompting-kling-v3.md +39 -0
- package/skills/slates-prompting-lip-sync.md +38 -0
- package/skills/slates-prompting-ltx-2-5.md +218 -0
- package/skills/slates-prompting-minimax-h3.md +39 -0
- package/skills/slates-prompting-motion-transfer.md +38 -0
- package/skills/slates-prompting-nano-banana-2.md +36 -0
- package/skills/slates-prompting-omni-flash.md +41 -0
- package/skills/slates-prompting-seed-audio.md +38 -0
- package/skills/slates-prompting-seedance-2-5.md +38 -0
- package/skills/slates-prompting-seedance.md +36 -1
- package/skills/slates-prompting-seedream-5-lite.md +38 -0
- package/skills/slates-prompting-veo-3.md +39 -0
- package/skills/slates-shot-variety.md +53 -0
- package/skills/slates-storyboard-from-script.md +31 -15
- package/skills/slates-style-prompting.md +1 -1
- package/skills/slates-vision-feedback-loop.md +1 -1
|
@@ -5,6 +5,45 @@ description: How to prompt Veo 3.1 (Google). Read before calling slates_generate
|
|
|
5
5
|
|
|
6
6
|
# Veo 3.1 — prompting
|
|
7
7
|
|
|
8
|
+
<!-- @card:start -->
|
|
9
|
+
<!-- slates-only -->
|
|
10
|
+
<!-- MACHINE-READ. Everything between the @card markers is extracted by
|
|
11
|
+
src/prompts/craft-cards.ts and returned on every cost estimate for this
|
|
12
|
+
model, so it is the ONE piece of positive craft guidance the agent cannot
|
|
13
|
+
skip. Measured 2026-08-30: a fact inlined where it cannot be skipped moved
|
|
14
|
+
compliance 0/8 to 30/32; the same guidance behind a fetch moved nothing.
|
|
15
|
+
Keep it under 2,400 characters (the build fails above that) and keep the
|
|
16
|
+
rationale, the receipts and the worked examples in the body below. -->
|
|
17
|
+
<!-- /slates-only -->
|
|
18
|
+
**Card — Veo 3.1.** Google's formula, in order: `[Cinematography] + [Subject] + [Action] + [Context] + [Style & Ambiance]`. Sweet spot 50-150 words; the official benchmark is about 50.
|
|
19
|
+
|
|
20
|
+
**The five levers**
|
|
21
|
+
1. **Open with the cinematography** — `Medium shot`, `low angle`, `aerial`, `dolly in`, `rack focus`, `vertigo effect`. Veo reads the first clause as the camera.
|
|
22
|
+
2. **Texture words counter the AI-plastic look** — `fine skin pores`, `visible fabric weave`, `subtle contrast, no gloss or sharpening`. Name materials concretely: `charcoal cotton hoodie`, `matte concrete`, `silk lapel`.
|
|
23
|
+
3. **Weight verbs stop floaty motion** — `trudges`, `drops heavily`, and a ground contact: `boots crunch on gravel`.
|
|
24
|
+
4. **Terse voice direction only** — `says in a weary voice`, `whispers`, `mutters`. Veo is far less responsive to long voice blocks than Kling.
|
|
25
|
+
5. **Always include an ambience line.** Without one the mix feels dead. `Soft office ambience.` `Wind on the open ridge.` And SFX always carries a cause: `SFX: thunder cracks in the distance`, never `SFX: thunder`.
|
|
26
|
+
|
|
27
|
+
**Examples**
|
|
28
|
+
- `Medium shot, a tired founder rubbing her temples in front of a bulky monitor in a cluttered office late at night. Harsh fluorescent overheads and the green glow of the screen. Fine skin pores, visible fabric weave on a charcoal cotton hoodie. Soft office ambience, a fan hum. Retro, slightly grainy.`
|
|
29
|
+
- `Low angle, a farrier trudges across a wet yard carrying a shoeing box, boots crunching on gravel. Overcast north light, matte concrete and wet steel. Wind and distant livestock. He says in a weary voice, "One more and we're done." (no subtitles).`
|
|
30
|
+
|
|
31
|
+
**Hard constraint:** `(no subtitles)` after EVERY dialogue line you do not want burned in as text. Negatives are NOUNS, not instructions — `wall, frame`, never `no walls`. And do not cross syntaxes: Seedance's `single continuous take` suppresses Veo's cuts, and Veo timestamps in a Seedance prompt cause drift.
|
|
32
|
+
<!-- @card:end -->
|
|
33
|
+
|
|
34
|
+
<!-- @banned:start -->
|
|
35
|
+
<!-- slates-only -->
|
|
36
|
+
<!-- MACHINE-READ. Every `backticked` token between the @banned markers is
|
|
37
|
+
extracted by src/prompts/banned-tokens.ts and returned on this model's cost
|
|
38
|
+
estimate, and every submitted prompt is matched against it. Keep entries
|
|
39
|
+
backticked and prose outside the backticks. -->
|
|
40
|
+
<!-- /slates-only -->
|
|
41
|
+
**Never use** (each one is spelled out above):
|
|
42
|
+
- `single continuous take` — Seedance's phrase; in a Veo prompt it suppresses the cuts you asked for
|
|
43
|
+
- `no subtitles` is REQUIRED after dialogue, but instruction-shaped negatives are not: `no walls`, `no man-made structures`, `don't show` — negatives are NOUNS here
|
|
44
|
+
- `SFX: thunder` and any label-only effect — every effect carries a cause and a distance
|
|
45
|
+
<!-- @banned:end -->
|
|
46
|
+
|
|
8
47
|
Google DeepMind's video model. Two tiers: `veo-3.1-fast` (cheaper, quick) and `veo-3.1-standard` (higher quality). 4k variants exist for both (4K video requires Slates Pro).
|
|
9
48
|
|
|
10
49
|
**Native single-shot duration: 4, 6, or 8 seconds** — and **8s only** at 1080p or 4K, or whenever you attach reference images (that endpoint is 8s-fixed). 4s and 6s exist at 720p, text-to-video or single-start-frame only. Longer durations require chaining clips via Extend / last-frame reuse — quality degrades if naively requested past 8s in a single generation. Aspect ratio: **16:9 or 9:16** on the route Slates uses. `slates_generate_video` REFUSES anything outside these before submit and names the legal set — nothing is silently ignored or downgraded.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: slates-shot-variety
|
|
3
|
+
description: Use when planning a set of shots, before firing a batch, when the variety counts on a shot list show one bucket dominating, or when a finished piece reads as flat, samey or repetitive despite each shot being individually fine.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Shot variety — why it all starts to look the same
|
|
7
|
+
|
|
8
|
+
The failure this skill exists for is mechanical, not artistic: **every shot is fine and the sequence is dead.** It happens because a model asked ten times in a row, from ten similar prompts, returns ten similar framings — and because the person writing those prompts is thinking about *what is in the shot* rather than *how this shot differs from the one before it*.
|
|
9
|
+
|
|
10
|
+
Slates counts the sameness for you. It does not judge it. **`slates_list_shots` returns the distribution with every listing** — shot sizes, camera moves, models, durations, and any bucket repeating three or more times in a row — so the numbers are in front of you before you spend anything. Reading them is the job; deciding what to do is yours.
|
|
11
|
+
|
|
12
|
+
## Read the table as a COLUMN, not as rows
|
|
13
|
+
|
|
14
|
+
This is the whole technique, and it is one sentence:
|
|
15
|
+
|
|
16
|
+
> Sort the list by shot size and count. Sort it by camera move and count. **If push-in is the plurality, or every row says wide, the batch is wrong before a single credit is spent.**
|
|
17
|
+
|
|
18
|
+
A shot list read row by row always looks fine, because each row was written to be good on its own. The sameness only shows up in the column. That is why the counts ship in the op result rather than in your head.
|
|
19
|
+
|
|
20
|
+
## What to vary, in order of how much it matters
|
|
21
|
+
|
|
22
|
+
1. **Shot size.** The single biggest lever, and the one that collapses first. A sequence of seven mediums reads as a slideshow no matter what is in them. Wide → close is a cut; medium → medium is a dissolve nobody asked for.
|
|
23
|
+
2. **Camera move.** Second-biggest, and the one models default to: ask for "cinematic" and you get a slow push-in, every time. If five of seven cuts push in, four of them should not.
|
|
24
|
+
3. **Duration.** Rhythm is not decoration. Seven identical 8-second cuts is a metronome. A 3-second cut lands differently *because* the one before it ran twelve.
|
|
25
|
+
4. **Distance between subjects and lens.** A long lens on a close-up and a wide lens on a close-up are different shots, and the model will render the difference.
|
|
26
|
+
5. **Location and cast.** If three cuts happen in the same room with the same person, that is a scene — fine. If *nine* do, the piece has one idea.
|
|
27
|
+
|
|
28
|
+
## When repetition is deliberate — and it often is
|
|
29
|
+
|
|
30
|
+
Do not treat the counts as a defect list. Repetition is a technique with two real uses:
|
|
31
|
+
|
|
32
|
+
- **A repeated frame IS the joke, or the point.** Three identical wides with one thing changed each time is a gag structure, and varying them would destroy it.
|
|
33
|
+
- **A locked-off frame is a choice.** Static, static, static, then a move — the move only lands because the first three did not have one.
|
|
34
|
+
|
|
35
|
+
The check catches a bucket dominating. It cannot tell whether you meant it. If you did, say so and move on; the counts do not block anything and never will.
|
|
36
|
+
|
|
37
|
+
## Choosing the chop: one long take or several short ones
|
|
38
|
+
|
|
39
|
+
This is the decision that owns the rhythm, and Slates puts the price next to it: `slates_split_shot` and `slates_merge_shots` re-cut a board, and the row's duration and quote move as you do it.
|
|
40
|
+
|
|
41
|
+
- **Merge** when the words run continuously and the picture has no reason to change. One 16-second take on a model that holds up is cheaper to *make* than two 8-second cuts and reads calmer.
|
|
42
|
+
- **Split** when the words keep going and the picture should not. This is the strongest move in the format: one spoken line running unbroken while the visual hard-cuts mid-clause to a new world. Split at a word boundary mid-sentence and both rows carry the same sentence — Slates marks the second as continuing the first, so the script still reads as one line.
|
|
43
|
+
- **Split** also when a line will not fit its cut. Slates flags only lines that cannot be read at *any* plausible pace (above the fastest read in a corpus of 71 real ads), so a flag is never a matter of taste — the chop is genuinely wrong. Splitting the line across two cuts or merging into a longer one both fix it.
|
|
44
|
+
|
|
45
|
+
## Multi-shot generations count as their cuts, not as one
|
|
46
|
+
|
|
47
|
+
A model that puts three cuts inside one generation contributes **three** rows to the distribution. That is deliberate: counting generations would score a three-cut clip as a single wide shot and miss exactly the sequences this check exists to catch. Money is counted per generation; rhythm is counted per cut, and the header says which is which.
|
|
48
|
+
|
|
49
|
+
## What this cannot tell you
|
|
50
|
+
|
|
51
|
+
It measures buckets, not taste. Seven varied shot sizes can still be seven boring shots, and a piece that scores perfectly can still be flat. It catches the one mechanical failure — everything starting to look the same — and nothing else.
|
|
52
|
+
|
|
53
|
+
It also only sees what is filled in. A board where nobody wrote `shotSize` reports `other` for every cut and tells you nothing. That is correct rather than a gap: inferring a shot size from a prompt would be Slates guessing at your work, and the counts are trustworthy precisely because they are arithmetic on what you actually wrote.
|
|
@@ -21,27 +21,42 @@ If the user hasn't named the storyboard, suggest one based on the project tone.
|
|
|
21
21
|
### 2. Materialize the structure first (no generation yet)
|
|
22
22
|
- `slates_create_storyboard` with the chosen name.
|
|
23
23
|
- For each scene: `slates_add_scene` with a descriptive name and order.
|
|
24
|
-
- For each
|
|
24
|
+
- For each shot: `slates_create_shot` with a *visual-only* prompt, the model, the params, and whatever character / environment / style references the project already holds. **Don't generate yet.**
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
🚨 **A Shot needs no image, and that is the point.** `slates_add_frame` requires an `assetId`, so before Shots existed there was nowhere to put a planned shot until it had been paid for — the plan lived in chat and the user had to trust your memory of it. A Shot is a row: named, listed, priced, forkable, and readable back COMPOSED with `slates_get_shot` before a single credit is spent. Write the plan as Shots, not as sentences you will have to re-type later.
|
|
27
|
+
|
|
28
|
+
🚨 **A Shot files itself, so pass `sceneId` (or `frameId`) when you know where it goes.** Omit both and it lands in the scene the user has open, else the most recently updated storyboard's last scene, creating a storyboard named after the project if there is none. Nothing you save is ever unfiled — but naming the scene is how the board comes out in the order you wrote it.
|
|
29
|
+
|
|
30
|
+
🚨 **Shots are addressed by CODE.** Every one comes back as `SHOT-A1`, `SHOT-A2` … per project, monotonic, never reused — the same vocabulary the gallery gives assets. Speak to the user in codes, and pass a code anywhere a `shotId` is taken. It is for pointing at a row THIS session, not for retrieval later: there is no shot search and no shot library, because a Shot is workspace state.
|
|
31
|
+
|
|
32
|
+
### 2a. Write the SCRIPT COLUMNS as well as the prompt
|
|
33
|
+
|
|
34
|
+
`slates_create_shot` takes the beat itself, not only the prompt: `line` (what is said, verbatim), `speaker` (a character id, a bare name, or `VO`), `delivery` (the parenthetical), `action` (what happens, screenplay-style), `prop`, `shotSize` and `camera`. All are optional, all are free text, and none of them is sent to a model — they are what the user READS and what the variety check COUNTS.
|
|
35
|
+
|
|
36
|
+
⚠️ **In this version you state dialogue TWICE, and that is deliberate rather than an oversight.** `line` is the readable script and the input to the fit check; the model only receives what is in the Shot's *prompt*, so the spoken words still go inside that prompt verbatim, with their delivery, in the body on the beat. **Write both in the same call** — then they agree at authoring time and can only drift if a human edits one side.
|
|
37
|
+
|
|
38
|
+
A speaker who matches no saved character is a working state, not an error: it renders as plain text and groups its lines. Do not create a placeholder character to avoid it.
|
|
39
|
+
|
|
40
|
+
Surface the planned structure back to the user as a tight summary — `slates_list_shots` gives you the count and the total in one call:
|
|
41
|
+
> Storyboard "X" • 4 scenes • 12 shots • 340 credits to fire them all
|
|
42
|
+
> Scene 1: Forest opening (3 shots)
|
|
43
|
+
> Scene 2: Confrontation (4 shots)
|
|
30
44
|
> ...
|
|
31
45
|
|
|
32
46
|
**Surface a decision log alongside that summary.**
|
|
33
47
|
|
|
34
48
|
<!-- @inject:decision-log -->
|
|
35
|
-
When you surface the plan, include a short **decision log** — one line per decision *you* made that the user did not specify
|
|
49
|
+
When you surface the plan, include a short **decision log** — one line per decision *you* made that the user did not specify **and that no row already records**:
|
|
36
50
|
|
|
37
51
|
```
|
|
38
52
|
source phrase or declared default → what you wrote → what it resolves
|
|
39
|
-
"in a diner" →
|
|
53
|
+
"in a diner" → warm, and the light is the reason → why the anchor was chosen, not what it is
|
|
40
54
|
(no time of day) → late afternoon, low warm key → default; say the word and it changes
|
|
41
|
-
(no camera) → slow push-in, single move → one move per shot; stacking increases instability
|
|
42
55
|
```
|
|
43
56
|
|
|
44
|
-
**
|
|
57
|
+
🚨 **Keep it to what is NOT already data — and almost everything now IS.** A Shot holds the references and their roles, the model, every param, the shot size, the camera, the prop, the action and the spoken line, and `slates_list_shots` reads the whole board back in order with its variety counts. Narrating any of those is retelling a row the user can open. **Write the Shot, and let the log carry only the judgement no field holds** — why this world, why this light, why this register.
|
|
58
|
+
|
|
59
|
+
**Hard rule: never silently add weather, props, style, or camera movement.** Four of those are now FIELDS: put the value on the Shot (`prop`, `camera`, `shotSize`, `action`) so the user can read and change it, and put the *reason* in the log only when you invented it rather than being told it. The rule has not softened — it moved from narration into data, which is stronger, because a field can be corrected and a sentence in chat cannot.
|
|
45
60
|
|
|
46
61
|
> ❌ **Do NOT turn this into a question gate.** Clarifying questions before optimizing directly fight the locked fast-path rule: *if intent is clear, generate immediately with sane defaults, don't ask questions; only ask for production intent, and batch every question into one message.* Log the decisions, then go. The log is an **output**, not an interrogation — surfaced alongside the plan, never as a separate ceremony, and never as a reason to wait.
|
|
47
62
|
<!-- @end:decision-log -->
|
|
@@ -51,18 +66,19 @@ Turning a script into *visual* frame prompts means resolving things the script l
|
|
|
51
66
|
Ask: **"Generate frame images now? (y/N)"**
|
|
52
67
|
|
|
53
68
|
### 3. Generate frames if requested
|
|
54
|
-
|
|
55
|
-
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
- Bind to the frame via `slates_add_frame`.
|
|
69
|
+
- `slates_generate_from_shots` with every image Shot's id and no `confirm` — it returns ONE itemised quote for the set plus the largest single item. Show that total, get an explicit OK, then re-call with `confirm: true`.
|
|
70
|
+
- It fires the Shots one after another and BLOCKS until the last one lands, so it can outlast the HTTP timeout on a long set. If that happens the run is still going: poll `slates_get_shot` for each Shot's `generationIds` rather than re-firing, which double-spends.
|
|
71
|
+
- Each result returns inline. Evaluate. If one is wrong, fix that Shot (`slates_update_shot`) and re-fire only it — never the set.
|
|
72
|
+
- Bind the keeper to a frame with `slates_add_frame`, then `slates_update_shot` with `attachFrameId` so the recipe and the picture stay together.
|
|
59
73
|
|
|
60
74
|
### 4. Hand back
|
|
61
75
|
- Total frames generated, total credits spent, storyboard id.
|
|
62
|
-
- Suggest next steps: review via `slates_get_storyboard_with_frames
|
|
76
|
+
- Suggest next steps: review via `slates_get_storyboard_with_frames` (it returns every scene, every Shot in order, and the variety distribution), or take the frames to motion — fork each image Shot with `slates_duplicate_shot` (`model:` the video model), give the copy its frame with `slates_update_shot` (`firstFrameAssetId`), then fire the set with `slates_generate_from_shots`. Assemble with `slates_add_clip_to_timeline` in story order and `slates_export_video`. The full frames-to-film pipeline (batch cost authorization, model mixing) is `slates-one-prompt-film`.
|
|
63
77
|
|
|
64
78
|
## Anti-patterns
|
|
65
79
|
|
|
66
80
|
- **Don't** auto-generate without asking. Generation is the expensive step. Always confirm first.
|
|
67
81
|
- **Don't** invent shot details the script doesn't mention. If the script says "they argue," ask what the shot looks like, don't fabricate "she clenches her fists in a wide shot."
|
|
68
82
|
- **Don't** mix scene structure and frame generation in one pass — building the skeleton first lets the user catch errors before spending credits.
|
|
83
|
+
- **Don't** write the plan into chat when a Shot can hold it. A Shot is the whole recipe AND the beat — line, speaker, action, prop, framing, references, model, params — and it is the only form of the plan the user can open, price, re-chop and re-fire without you.
|
|
84
|
+
- **Don't** fire a set without reading its variety counts first. `slates_list_shots` returns them with every listing; if one shot size is the plurality or three cuts in a row share a camera move, fix the board before spending. `slates-shot-variety` is the craft behind that.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: slates-style-prompting
|
|
3
|
-
description:
|
|
3
|
+
description: Use when the user asks for a visual style ("make it anime", "painterly look", "like a Pixar film"), or when a style has to hold across several shots. Covers how photoreal, anime, painterly and 3d-render are prompted DIFFERENTLY per model, and the style-routing recipe (reference-first, styled start-frame → i2v).
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Per-style prompting (photoreal · anime · painterly · 3d-render)
|
|
@@ -94,7 +94,7 @@ When the **character** is the question, keep the location out of it: test on a p
|
|
|
94
94
|
|
|
95
95
|
- Track total credits spent across the loop. Surface to the user every 3 iterations.
|
|
96
96
|
- Stop after 3 failed iterations on the same prompt — escalate to the user with what you tried and what's not working. The slot machine never converges.
|
|
97
|
-
- For high-cost
|
|
97
|
+
- For a high-cost generation — anything past the confirm gate in `slates-cost-discipline` — confirm before *every* attempt, not just the first.
|
|
98
98
|
|
|
99
99
|
## When to break the loop
|
|
100
100
|
|