From 7eae49c4990fac700f6b2f032dedc63062b3c69c Mon Sep 17 00:00:00 2001 From: teknium1 <127238744+teknium1@users.noreply.github.com> Date: Mon, 14 Sep 2026 21:13:46 -0700 Subject: [PATCH] fix(skills): auteur follows the modern section order and routes assets through image_generate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SKILL.md is restructured to authoring standard 5 (When to Use, Prerequisites, How to Run, Quick Reference, Procedure, Pitfalls, Verification) — headings only, upstream body text kept. The asset references still carried the upstream per-CLI routing tables and command lines for other agent products; those are replaced with the native `image_generate` route (product names are allowed only in LICENSE and credit lines). `WebSearch` residue in recon docs/refscout becomes `web_search`. source.mjs wrote its ~2.6MB Google Fonts metadata cache to $TEMP||$TMPDIR||'.', which is the project cwd on most Linux shells; it now uses os.tmpdir() and Pitfalls documents the location. Network-access note now mentions that moodboard.mjs also downloads the image URLs the search hosts return. Docs page regenerated for this skill only. --- optional-skills/creative/auteur/SKILL.md | 123 +++++++++--------- .../creative/auteur/references/assets.md | 92 ++++--------- .../creative/auteur/references/direct.md | 6 +- .../creative/auteur/references/recon.md | 6 +- .../auteur/references/scroll-cinema.md | 4 +- .../auteur/references/scroll-flight.md | 22 ++-- .../creative/auteur/scripts/refscout.mjs | 4 +- .../creative/auteur/scripts/source.mjs | 3 +- .../creative/auteur/templates/STORYBOARD.md | 2 +- .../auteur/templates/scroll-flight-engine.js | 2 +- tests/skills/test_auteur_skill.py | 6 +- .../optional/creative/creative-auteur.md | 123 +++++++++--------- 12 files changed, 184 insertions(+), 209 deletions(-) diff --git a/optional-skills/creative/auteur/SKILL.md b/optional-skills/creative/auteur/SKILL.md index 77fb187899..b7fd0ee826 100644 --- a/optional-skills/creative/auteur/SKILL.md +++ b/optional-skills/creative/auteur/SKILL.md @@ -22,7 +22,7 @@ metadata: Auteur designs and builds web experiences the way a film director makes a film: script first, then assets, then the shoot, then the cut. It has three registers — **build** (an excellent conventional site), **direct** (a cinematic scroll-directed site) and **system** (a multi-screen product as one design system) — on one shared core of taste. Nothing ships until the page passes an executable anti-slop gate and the skill has looked at its own output. -### Use this when +## When to Use - A landing page, marketing site, hero section, portfolio or product page has to be **built or redesigned** — and looking generic is not acceptable. - The brief asks for **scroll animation, storytelling, or a site that feels like a film**. @@ -31,6 +31,15 @@ Auteur designs and builds web experiences the way a film director makes a film: Not for polishing a UI someone else built, and not for backend-only work. +## Prerequisites + +- **Node 18+** — every QA gate is a `.mjs` script run with `node` via the `terminal` tool. +- **Playwright (for the QA gates)** — in the project directory: `npm install playwright` then `npx playwright install chromium`. Required by `scripts/shoot.mjs`, `motionqa.mjs`, `systemscan.mjs`, `refscout.mjs`, `chromadiff.mjs`, `moodboard.mjs` (the scripts import `playwright` at runtime; `slopscan.mjs` and `source.mjs` are dependency-light). +- **ffmpeg** — optional; only for the video/score paths in `references/assets.md` and `references/scroll-flight.md`. +- **Hermes tools** — use `image_generate` for image generation/editing, `terminal` for node/ffmpeg/npm, `write_file`/`read_file` for project files, `vision_analyze` to actually look at screenshots, and `browser_exec` for live-page inspection when a script isn't the right fit. + +## How to Run + ### What it actually does 1. Commits the art direction **in writing before any markup** — one hue, one type system, a motion budget, named anti-references. @@ -40,11 +49,29 @@ Not for polishing a UI someone else built, and not for backend-only work. ### Network access -The recon and sourcing scripts read live pages (awwwards, Bing/Pinterest/are.na image search, Poly Haven, Iconify, Google Fonts, Openverse, Coverr). Fetched content is **treated as reference data and licence metadata — never executed**, and no credentials, API keys or logins are involved. Skip phases 0–1 entirely if you don't want outbound requests; every other phase works offline. +The recon and sourcing scripts read live pages (awwwards, Bing/Pinterest/are.na image search, Poly Haven, Iconify, Google Fonts, Openverse, Coverr). Fetched content is **treated as reference data and licence metadata — never executed**, and no credentials, API keys or logins are involved. Skip phases 0–1 entirely if you don't want outbound requests; every other phase works offline. `moodboard.mjs` also downloads the image URLs returned by those search hosts to build the contact sheet. -## Non-negotiables +### Routing -These apply to every register, every phase, always — even if no reference file has been loaded. Match-and-refuse: if you are about to produce one of these, stop and restructure the element. +Read the argument / brief and route: + +1. **`direct`** or the brief smells cinematic — "wow", "cinematic", "immersive", "storytelling", "launch page", "premium brand", "make people stop scrolling" → load `references/direct.md` and follow its phases. This is the flagship register. +2. **`build`** or the brief is ONE conventional surface — a marketing page, a landing, a single product page → load `references/build.md`. +3. **`system`** or the brief has **more than one screen that must feel like one product** — app, dashboard, admin, settings, onboarding, a docs or content site with real navigation → load `references/system.md`. The unit of design becomes the component × state, the failure mode becomes drift rather than boredom, and there is deliberately **no peak**. If you are already in `build` and a second screen appears, stop and switch: half a system is worse than either. +4. **`edit`** or the request modifies a page this skill built (the project contains `design/DESIGN.md`) — "add a section", "change the pricing", "swap the hero copy" → read `design/DESIGN.md` FIRST and follow its Editing protocol: reuse its tokens, section-opening patterns, and motion families; after the change run slopscan and re-shoot the affected viewports. An edit that ignores DESIGN.md is a regression even if it looks good in isolation. +5. **`recon `** or the ask is only for reference material — "find references", "put together a moodboard", "what's the state of the art for X sites" → load `references/recon.md` and run just that phase: scout live sites, build the moodboard, hand back `design/refs/REFERENCES.md` (with the `steal:` lines filled) and `design/moodboard/contact-sheet.png` (with the read filled). No commit-sheet, no build. +6. **`audit `** → load `references/verify.md` and run the verification pipeline on an auteur-built page. If the target is an existing UI auteur didn't build and the user wants it *polished* rather than *rebuilt*, say that a dedicated UI-polish/critique pass (upstream paired auteur with a separate 'impeccable' skill, not vendored here) is the right tool and offer to continue only if they want a rebuild. +7. **Ambiguous** (e.g. plain "make a landing page") → ask exactly one question: "A great conventional landing page, or cinema mode with scroll direction and generated assets?" (upstream phrased these example briefs in Russian; translated here.) Then route. (Multi-screen briefs are not ambiguous — they are `system`.) Don't ask anything else yet — each register runs its own intake. + +All three registers share phase zero, and its centre of gravity is the commit-sheet. Order differs: **build** runs recon → commit-sheet → mockup; **direct** runs recon → storyboard → commit-sheet → mockup, because the film's scenes are what the six decisions get made *about*; **system** runs recon → system-sheet (route map + component inventory) → commit-sheet → mockup, because the six decisions get made about a product, not a page. Either way nothing is coded before the sheet is full. + +### Working relationship with other skills + +Auteur *builds*; it does not re-polish foreign UI. If the user has an existing interface that needs refinement, run a separate UI-critique pass (e.g. `vision_analyze` on screenshots plus the sibling design skills). Upstream paired auteur with an 'impeccable' critique skill (not vendored here); auteur's verify gate and an outside critique measure different things and coexist happily. + +## Quick Reference + +The non-negotiables and the phase table. They apply to every register, every phase, always — even if no reference file has been loaded. Match-and-refuse: if you are about to produce one of these, stop and restructure the element. ### Banned (rewrite, don't tweak) @@ -84,35 +111,7 @@ A ban may be overridden only through a written `auteur-allow` (see Verification) - `prefers-reduced-motion` = an alternative art direction (gentler, not zero), never an afterthought. - Content must be readable with JS disabled: reveals enhance an already-visible default, never gate visibility. -## Routing - -Read the argument / brief and route: - -1. **`direct`** or the brief smells cinematic — "wow", "cinematic", "immersive", "storytelling", "launch page", "premium brand", "make people stop scrolling" → load `references/direct.md` and follow its phases. This is the flagship register. -2. **`build`** or the brief is ONE conventional surface — a marketing page, a landing, a single product page → load `references/build.md`. -3. **`system`** or the brief has **more than one screen that must feel like one product** — app, dashboard, admin, settings, onboarding, a docs or content site with real navigation → load `references/system.md`. The unit of design becomes the component × state, the failure mode becomes drift rather than boredom, and there is deliberately **no peak**. If you are already in `build` and a second screen appears, stop and switch: half a system is worse than either. -4. **`edit`** or the request modifies a page this skill built (the project contains `design/DESIGN.md`) — "add a section", "change the pricing", "swap the hero copy" → read `design/DESIGN.md` FIRST and follow its Editing protocol: reuse its tokens, section-opening patterns, and motion families; after the change run slopscan and re-shoot the affected viewports. An edit that ignores DESIGN.md is a regression even if it looks good in isolation. -5. **`recon `** or the ask is only for reference material — "find references", "put together a moodboard", "what's the state of the art for X sites" → load `references/recon.md` and run just that phase: scout live sites, build the moodboard, hand back `design/refs/REFERENCES.md` (with the `steal:` lines filled) and `design/moodboard/contact-sheet.png` (with the read filled). No commit-sheet, no build. -6. **`audit `** → load `references/verify.md` and run the verification pipeline on an auteur-built page. If the target is an existing UI auteur didn't build and the user wants it *polished* rather than *rebuilt*, say that a dedicated UI-polish/critique pass (upstream paired auteur with a separate 'impeccable' skill, not vendored here) is the right tool and offer to continue only if they want a rebuild. -7. **Ambiguous** (e.g. plain "make a landing page") → ask exactly one question: "A great conventional landing page, or cinema mode with scroll direction and generated assets?" (upstream phrased these example briefs in Russian; translated here.) Then route. (Multi-screen briefs are not ambiguous — they are `system`.) Don't ask anything else yet — each register runs its own intake. - -All three registers share phase zero, and its centre of gravity is the commit-sheet. Order differs: **build** runs recon → commit-sheet → mockup; **direct** runs recon → storyboard → commit-sheet → mockup, because the film's scenes are what the six decisions get made *about*; **system** runs recon → system-sheet (route map + component inventory) → commit-sheet → mockup, because the six decisions get made about a product, not a page. Either way nothing is coded before the sheet is full. - -## The commit-sheet (before any code, both registers) - -Slop is what happens when defaults make the decisions. The commit-sheet forces seven real decisions onto paper before the first line of code. Copy `templates/COMMIT-SHEET.md` into the project (e.g. `design/COMMIT-SHEET.md`) and fill all seven fields with non-defaults: - -1. **Peak** — the ONE primary wow moment (direct) or signature element (build). One sentence. If you can't name it, you're not ready to build. -2. **Color** — primary as OKLCH + commitment tier (restrained / committed / full-palette / drenched) + one line: *why this is not lavender, not cream, and not the category reflex* + **the background lightness as a number** (target mean L), because "dark feels premium" is where this skill drifts, and a number can be checked afterwards where a mood cannot. -3. **Type** — display + text pairing on a contrast axis (serif+sans, geometric+humanist, mono+serif...) + one line: *why not Inter*. -4. **Grid break** — the one concrete thing that breaks the symmetric-grid default: an overlap, an asymmetric split, a diagonal flow, a full-bleed interruption. Name it specifically. -5. **Motion budget** — how many scroll-pattern families (≤3) and what they are. -6. **Reflex check** — write down: (a) what a generic AI would do for this category (first-order reflex), (b) what a generic AI avoiding (a) would do (second-order reflex — e.g. fintech → "terminal dark mode" is *also* saturated now), (c) your chosen deviation from both. If recon ran, (a) is not a guess: whatever `design/refs/REFERENCES.md` showed five times *is* the reflex, dated and with receipts. -7. **House tells broken** — name the **two (minimum)** items from `taste.md` §2.5 you are deliberately not doing this time, and what replaces each. Fields 6a/6b are the reflexes of the *category*; these are the reflexes of *this skill*, which recur across unrelated projects and are invisible from inside any one of them: near-black backgrounds, mono service labels, the logo/status/action header, the scroll-instruction footer, amber-or-acid accents, the wordmark-as-hero, glow standing in for lighting. Measured across nine showcase builds, eight were dark and three landed within 0.002 of the same lightness. A tell that genuinely belongs here can stay — say why, as with an `auteur-allow`. - -Gate: every field filled with a specific, non-default answer. An empty or generic field ("modern, clean look") means stop and decide. This artifact is checked again at verification. - -## Phases at a glance +### Phases at a glance | Phase | build register | direct register | system register | Reference to load | |---|---|---|---|---| @@ -126,7 +125,23 @@ The hero mockup gate (one static throwaway screen, screenshotted and approved be Never skip a gate because the intermediate result "looks done". The gates exist because a page that merely looks done is exactly what every other AI ships. -## Reference files +## Procedure + +### The commit-sheet (before any code, both registers) + +Slop is what happens when defaults make the decisions. The commit-sheet forces seven real decisions onto paper before the first line of code. Copy `templates/COMMIT-SHEET.md` into the project (e.g. `design/COMMIT-SHEET.md`) and fill all seven fields with non-defaults: + +1. **Peak** — the ONE primary wow moment (direct) or signature element (build). One sentence. If you can't name it, you're not ready to build. +2. **Color** — primary as OKLCH + commitment tier (restrained / committed / full-palette / drenched) + one line: *why this is not lavender, not cream, and not the category reflex* + **the background lightness as a number** (target mean L), because "dark feels premium" is where this skill drifts, and a number can be checked afterwards where a mood cannot. +3. **Type** — display + text pairing on a contrast axis (serif+sans, geometric+humanist, mono+serif...) + one line: *why not Inter*. +4. **Grid break** — the one concrete thing that breaks the symmetric-grid default: an overlap, an asymmetric split, a diagonal flow, a full-bleed interruption. Name it specifically. +5. **Motion budget** — how many scroll-pattern families (≤3) and what they are. +6. **Reflex check** — write down: (a) what a generic AI would do for this category (first-order reflex), (b) what a generic AI avoiding (a) would do (second-order reflex — e.g. fintech → "terminal dark mode" is *also* saturated now), (c) your chosen deviation from both. If recon ran, (a) is not a guess: whatever `design/refs/REFERENCES.md` showed five times *is* the reflex, dated and with receipts. +7. **House tells broken** — name the **two (minimum)** items from `taste.md` §2.5 you are deliberately not doing this time, and what replaces each. Fields 6a/6b are the reflexes of the *category*; these are the reflexes of *this skill*, which recur across unrelated projects and are invisible from inside any one of them: near-black backgrounds, mono service labels, the logo/status/action header, the scroll-instruction footer, amber-or-acid accents, the wordmark-as-hero, glow standing in for lighting. Measured across nine showcase builds, eight were dark and three landed within 0.002 of the same lightness. A tell that genuinely belongs here can stay — say why, as with an `auteur-allow`. + +Gate: every field filled with a specific, non-default answer. An empty or generic field ("modern, clean look") means stop and decide. This artifact is checked again at verification. + +### Reference files - `references/recon.md` — **phase 0 scouting**, two executable legs: `scripts/refscout.mjs` profiles live award-level sites (real stack, pinned scenes, scroll budget, fonts, painted palette, screenshots — mechanics, not skins) and `scripts/moodboard.mjs` builds a numbered contact sheet from Bing / Pinterest / are.na so the art direction is decided from live material instead of memory. Also: query craft, the steal rule, how recon feeds the commit-sheet, and the "reference images are not assets" line. Load at the top of phase 0. - `references/taste.md` — the full anti-slop system: extended bans with replacements, second-order category reflex table, color strategy tiers, typography pairing, copy rules. Load for any visual decision-making. @@ -134,41 +149,31 @@ Never skip a gate because the intermediate result "looks done". The gates exist - `references/build.md` — the standard register process. Load when routed to build. - `references/system.md` — the **multi-screen register**: route map, the component inventory as a gate, the state matrix (empty/loading/error are not edge cases), density rules, the no-peak rule, and `scripts/systemscan.mjs` — which crawls every route, reads what the browser actually painted, fails a control type over its declared variant budget — counting *states* (disabled, current, inside a `data-state` row) separately, so implementing the state matrix never reads as drift — presses Tab to catch controls with no visible focus state, and renders one tile per rendered variant so drift is visible as well as counted. Load when routed to system. - `references/direct.md` — the cinematic register: screenplay contract, scene-sheets, dramaturgy, assembly order. Load when routed to direct. -- `references/assets.md` — the media crew and routing (in Hermes: `image_generate` for all image generation and edits, `terminal` for ffmpeg/node; upstream's video/score CLI routing kept as reference), **§0.5 source-vs-generate** (`scripts/source.mjs`: CC0 glTF meshes, HDRIs and PBR materials from Poly Haven, icons, fonts, CC images, stock video — with a licence ledger, because generation cannot make geometry or an IBL and stock video must never be the peak), the consistency trick (edit frame A into frame B), local video via the first→last-frame chain, generated elements/mockups, the ambient score, the degradation ladder, and asset caching. Load during direct phase 1. +- `references/assets.md` — the media crew and routing (in Hermes: `image_generate` for all image generation and edits, `terminal` for ffmpeg/node; video via whatever image→video backend the user has), **§0.5 source-vs-generate** (`scripts/source.mjs`: CC0 glTF meshes, HDRIs and PBR materials from Poly Haven, icons, fonts, CC images, stock video — with a licence ledger, because generation cannot make geometry or an IBL and stock video must never be the peak), the consistency trick (edit frame A into frame B), local video via the first→last-frame chain, generated elements/mockups, the ambient score, the degradation ladder, and asset caching. Load during direct phase 1. - `references/scroll-cinema.md` — working code recipes: scroll-scrubbed video, canvas sequences, GSAP+Lenis foundation, CSS scroll-driven animations, text reveals, the two-keyframe WebGL displacement transition, view transitions, ambient audio, and the cinematic transition library (wipe, curtain, letterbox, shutter, depth parallax). Load during assembly. - `references/scroll-flight.md` — the **video-scrub tier**: a photoreal "fly through the world" hero driven by scroll, using the drop-in `templates/scroll-flight-engine.js`. The canonical recipe for scroll-scrubbed *video* (encode-for-scrubbing `-g 8`, encoded-frame posters, SSIM seam gate, chain architecture A/B, iOS/mobile decode hardening, crossfade-vs-seamless seams). Load when the hero should be photoreal footage/AI-video rather than real-time WebGL. - `references/ambient-backgrounds.md` — **quiet** texture for secondary sections and simpler builds (not a hero): a curated 6 editorial/analog effects (paper grain, ledger/blueprint rules, topographic contour, ink tide, sparse dust, one heat-haze shader) + a zero-motion static-mesh default. The governing rule (weaker than the quietest foreground element; one ambient per page), the CSS/SVG-first stack, and the `feTurbulence`-static perf rule. Load when a section needs to not be flat but must NOT compete with copy. - `references/verify.md` — the acceptance pipeline: slopscan → screenshot journey → motion/perf/audio QA (FPS at DPR 2 on a production build, long-tasks, audio-gate, reduced-motion, for Tier-1 scenes) → numeric rubric → **reference diff** (your frame beside the reference that set the direction, with `scripts/chromadiff.mjs` measuring the colour drift a model never sees in itself) → QA sign-off. Load at phase 3. -## Verification is part of the build - -The page is not done when the code compiles. It is done when: - -1. `node scripts/slopscan.mjs ` exits 0 (fails are fixed, not suppressed — `/* auteur-allow: RULE_ID -- reason */` exists for deliberate choices and demands a real reason); -2. `node scripts/shoot.mjs ` has produced screenshot journeys at 390 / 768 / 1440 and you have **looked at every frame** — text overflow, blank scenes, broken reveals, layout collapse are found by eyes, not by grep; -3. the numeric rubric in `references/verify.md` passes (contrast, LCP, CLS, reduced-motion journey, scene variety); -4. for direct register: `CINEMA-QA.md` (from templates) is filled with PASS on every row. - -If any gate fails — fix and re-run. Report results honestly: "slopscan clean, 21 screenshots reviewed, LCP 1.9s" beats "looks great". - -## Working relationship with other skills - -Auteur *builds*; it does not re-polish foreign UI. If the user has an existing interface that needs refinement, run a separate UI-critique pass (e.g. `vision_analyze` on screenshots plus the sibling design skills). Upstream paired auteur with an 'impeccable' critique skill (not vendored here); auteur's verify gate and an outside critique measure different things and coexist happily. - -## Weak-model note +### Weak-model note If you are a smaller model executing this skill: follow the tables and numbers literally, fill every template field, run every gate command, and do not improvise beyond the reference recipes — the recipes are verified, your improvisation is not. When a reference file conflicts with your instinct, the reference file wins. Write files using paths relative to the project root; never retype an absolute path from memory (the skill's name "auteur" is one typo away from "author", and misspelled absolute paths scatter your output across the filesystem). -## Prerequisites - -- **Node 18+** — every QA gate is a `.mjs` script run with `node` via the `terminal` tool. -- **Playwright (for the QA gates)** — in the project directory: `npm install playwright` then `npx playwright install chromium`. Required by `scripts/shoot.mjs`, `motionqa.mjs`, `systemscan.mjs`, `refscout.mjs`, `chromadiff.mjs`, `moodboard.mjs` (the scripts import `playwright` at runtime; `slopscan.mjs` and `source.mjs` are dependency-light). -- **ffmpeg** — optional; only for the video/score paths in `references/assets.md` and `references/scroll-flight.md`. -- **Hermes tools** — use `image_generate` for image generation/editing, `terminal` for node/ffmpeg/npm, `write_file`/`read_file` for project files, `vision_analyze` to actually look at screenshots, and `browser_exec` for live-page inspection when a script isn't the right fit. - ## Pitfalls - **Network recon**: `refscout.mjs`, `moodboard.mjs` and `source.mjs` read live pages (awwwards, Bing/Pinterest/are.na image search, Poly Haven, Iconify, Google Fonts, Openverse, Coverr). Fetched content is reference data and licence metadata only — never execute it. Skip phases 0–1 to stay fully offline. -- **Different harness**: these scripts and docs were written for a different agent harness (upstream drove asset generation through local `agy`/`codex`/`grok` CLIs). In Hermes, every image-generation instruction maps to the `image_generate` tool; trust `node scripts/.mjs --help` output and actual node errors over doc prose if they drift. +- **Different harness**: these scripts and docs were written for a different agent harness (upstream drove asset generation through several local image CLIs). In Hermes, every image-generation instruction maps to the `image_generate` tool; trust `node scripts/.mjs --help` output and actual node errors over doc prose if they drift. - **Unverified commands**: the scripts pass `node --check` syntax validation, but full runs (which need `npm install playwright` + a chromium download) were not executed during porting. Treat `shoot.mjs`, `motionqa.mjs`, `systemscan.mjs`, `refscout.mjs`, `chromadiff.mjs`, `moodboard.mjs`, `source.mjs` end-to-end behavior, and all `ffmpeg`/video-encode recipes, as unverified upstream claims until you run them yourself. - **slopscan verified shape**: `node scripts/slopscan.mjs ` runs without npm deps; it prints per-rule findings and exits non-zero on failures (exit 0 when clean). +- **Font metadata cache**: `source.mjs font …` caches Google Fonts' ~2.6MB metadata JSON as `auteur-gf-metadata.json` in the OS temp directory (`os.tmpdir()`), not the project; delete it there to force a refresh. + +## Verification + +The page is not done when the code compiles. It is done when: + +1. `node scripts/slopscan.mjs ` exits 0 (fails are fixed, not suppressed — `/* auteur-allow: RULE_ID -- reason */` exists for deliberate choices and demands a real reason); +2. `node scripts/shoot.mjs ` has produced screenshot journeys at 390 / 768 / 1440 and you have **looked at every frame** — text overflow, blank scenes, broken reveals, layout collapse are found by eyes, not by text search; +3. the numeric rubric in `references/verify.md` passes (contrast, LCP, CLS, reduced-motion journey, scene variety); +4. for direct register: `CINEMA-QA.md` (from templates) is filled with PASS on every row. + +If any gate fails — fix and re-run. Report results honestly: "slopscan clean, 21 screenshots reviewed, LCP 1.9s" beats "looks great". diff --git a/optional-skills/creative/auteur/references/assets.md b/optional-skills/creative/auteur/references/assets.md index 336badfb48..f7ad96b002 100644 --- a/optional-skills/creative/auteur/references/assets.md +++ b/optional-skills/creative/auteur/references/assets.md @@ -1,4 +1,4 @@ -> **Hermes adaptation note:** upstream auteur generated assets through local agent CLIs (`agy`, `codex`, `grok`). In Hermes, read every such invocation as a call to the built-in `image_generate` tool with the same prompt (then move the returned file into the project's `assets/gen/` path), use the `terminal` tool for `ffmpeg`/`node`/`npx`, and `browser_exec` or Playwright-via-terminal for screenshot loops. The per-CLI routing/strength tables below are upstream reference material — the taste guidance transfers, the CLI names do not. +> **Hermes adaptation note:** upstream auteur routed asset generation to several local image CLIs by strength. In Hermes there is one route: the built-in `image_generate` tool for every still and edit (move the returned file into the project's `assets/gen/` path), the `terminal` tool for `ffmpeg`/`node`/`npx`, and `browser_exec` or Playwright-via-terminal for screenshot loops. The taste guidance below transfers; the per-CLI shootout tables were dropped in the port. # assets.md — producing visual assets @@ -6,36 +6,25 @@ The storyboard's `asset:` lines are a shot list. This file turns them into files ## 0. The crew — probe once, route by strength -**Probe with a real round trip, never with `--version`.** These are subscription CLIs and the failure -that actually happens is expired auth, not a missing binary — measured: all three passed `--version` -and all three were dead. Worse, they fail dishonestly: **`grok` exits 0 while printing "Not signed -in"** and **`agy` exits 2 while printing nothing at all**. Read the OUTPUT, not the exit code. +**Probe with a real round trip, never with a version flag.** The failure that actually happens is an unconfigured or expired backend, not a missing binary. Before the shoot, run one tiny `image_generate` call and confirm a file or URL actually came back; run `ffmpeg -version` in `terminal` for the encode leg. Read the OUTPUT, not the exit code. -```bash -agy -p "reply with the single word: ok" # Gemini: fast image gen + edit, writes straight to a path -codex exec --skip-git-repo-check "reply with: ok" # gpt-image: highest fidelity -grok -p "reply with the single word: ok" # grok-4.5: gen + edit + real video, one consistent engine -ffmpeg -version # not a subscription; --version is fine here -``` +A route that does not return a real asset is unavailable. Note it as unavailable in the asset plan and route around it — §0.5 and §4 — rather than discovering it mid-shoot. -A tool that does not answer `ok` is unavailable, whatever its version says. Note it as unavailable in -the asset plan and route around it — §0.5 and §4 — rather than discovering it mid-shoot. +MiniMax music (ambient score) needs `MINIMAX_API_KEY` — skip the audio leg if unset. -Grok reaches **grok-4.5** only through the non-EU proxy (`ALL_PROXY="$GROK_PROXY" HTTPS_PROXY="$GROK_PROXY"`); without it grok still gens/edits/videos on grok-build. MiniMax music (ambient score) needs `MINIMAX_API_KEY` — skip the audio leg if unset. +**Route each asset to its strength:** -**Route each asset to its strength** (locked by a shootout, 2026-07): - -| Asset | Tool | Why | +| Asset | Route | Why | |---|---|---| -| Hero / brand-critical stills — peak scene, abstract hero background (needs clean negative space for text), product mockup / UI screen, premium transparent element or icon | **codex** | quality king across every type tested: cleanest UI render, most negative space, best material realism. Weaknesses: palette drifts warm (weak on teal-shadow / cool briefs), and it cannot make video. It *can* edit an existing frame — via stdin only, see §2 | -| Any scene that becomes VIDEO or needs a consistent A→B edit pair; exact brand-COLOR adherence | **grok-4.5** | one engine does gen + edit + video → zero scene drift across the A→B→clip pipeline; best palette adherence when codex drifts warm | -| Volume & CONTEXT — lifestyle/environmental shots (room, hands, props, in-situ), bulk backgrounds, fast iteration | **agy** | fast, natural environmental context, writes direct to file | -| Real video | **grok** `image_to_video` (6 or 10s) | animate an approved keyframe | +| Hero / brand-critical stills — peak scene, abstract hero background (needs clean negative space for text), product mockup / UI screen, premium transparent element or icon | `image_generate` | one frame first, approve, then batch style-locked to the anchor. Watch for warm palette drift on cool briefs — anchor the palette in the prompt | +| Any scene that becomes VIDEO or needs a consistent A→B edit pair; exact brand-COLOR adherence | `image_generate` edit of frame A (§2) | editing keeps the world intact; a second generation never does | +| Volume & CONTEXT — lifestyle/environmental shots (room, hands, props, in-situ), bulk backgrounds, fast iteration | `image_generate` | cheap iteration; keep the anchor still as the style reference | +| Real video | an image→video model on an approved keyframe (6–10s) — user-supplied backend or browser tool | animate an approved keyframe; Hermes ships no native video tool | | Ambient score | **MiniMax** music | one loopable bed matched to the commit-sheet mood | -All three do transparent PNG (alpha): codex crispest, grok close, agy usable-but-softer. **Match the asset's background to the page** — generate the subject on the SAME ground the page uses (white-on-white, or true alpha) so it melts into the layout with no visible frame; a photographic rectangle floating on a flat page is an instant slop tell. +Transparent PNG (alpha) depends on the configured backend. **Match the asset's background to the page** — generate the subject on the SAME ground the page uses (white-on-white, or true alpha) so it melts into the layout with no visible frame; a photographic rectangle floating on a flat page is an instant slop tell. -Missing a tool → don't fake it: descend the ladder (§4), ask the user for assets, or pivot to type-led/CSS scenes (a great film can be shot entirely in typography). Note what's available in the asset plan. +Missing a route → don't fake it: descend the ladder (§4), ask the user for assets, or pivot to type-led/CSS scenes (a great film can be shot entirely in typography). Note what's available in the asset plan. ## 0.5 Source before you generate — the routing decision @@ -88,7 +77,7 @@ Name the ~20 symbols you actually use in `entry.js` rather than `export * from ' | a typeface | **source** — Google Fonts | and check it against ban #8/#18 before falling in love | | **the peak scene keyframe** | **generate** | it has to be this brand's world and nobody else's — this is the whole point | | the hero video | **generate** (§3) | the wow moment cannot be a clip three thousand pages already use | -| an environmental / lifestyle still | **generate** (agy) | unless the brief needs a *real, identifiable* place | +| an environmental / lifestyle still | **generate** (`image_generate`) | unless the brief needs a *real, identifiable* place | | a documentary photo of a real thing or place | **source** — Openverse | generation invents; if it must be true, it must be photographed | | an ambient background loop or video texture | **source ok** — Coverr | supporting layer only | @@ -120,43 +109,23 @@ Build the prompt FROM the scene-sheet — `subject` + `camera` + `lighting` are > "⟨subject⟩, ⟨camera: low-angle close shot / orbital view / macro detail⟩, ⟨lighting: hard rim light at dusk / soft studio / neon-soaked⟩, color palette anchored on ⟨primary OKLCH → describe as human color⟩, photographic, no text, no watermark, 16:9" -**agy (fast, direct to file):** -```bash -agy -p "Generate an image: . Save to /assets/gen/s3-peak-a.png" -``` -Always give an absolute path; verify the file actually landed on disk (agy occasionally reports success without writing — re-run once if missing). +**Generate with `image_generate`:** pass the prompt above, then move the returned file to `assets/gen/s3-peak-a.png` (project-relative). Verify the file actually landed on disk before building on it — re-run once if missing. -**codex (higher quality, for the peak scene / brand-critical frames):** -```bash -codex exec --skip-git-repo-check "Generate an image: " -``` -codex cannot write into your project (read-only sandbox). Pick up the newest PNG from its output store and copy it yourself — PowerShell: -```powershell -Get-ChildItem "$env:USERPROFILE\.codex\generated_images" -Recurse -Filter *.png | - Sort-Object LastWriteTime -Descending | Select-Object -First 1 | - Copy-Item -Destination "assets/gen/s3-peak-a.png" -``` - -Default split: agy for volume and iteration speed; codex for the peak scene and anything the viewer will stare at. +Default split: cheap iteration for volume; spend the retries on the peak scene and anything the viewer will stare at. ## 2. The consistency trick: frame B is an EDIT of frame A, never a second generation Two independent generations of "the same scene" are never the same scene — lighting, geometry and lens drift. Editing frame A into frame B keeps the world intact and is what makes the two-keyframe cinema moves (displacement morph, before/after scrub) look like camera work instead of a jump cut. -**agy edit — word the change HARSHLY.** agy ignores soft phrasing ("replace X with Y" often returns the original). Use the REQUIRED CHANGE pattern: -```bash -agy -p "Load the image /assets/gen/s3-peak-a.png and edit it. REQUIRED CHANGE: the laptop is now open, screen glowing, and the room lights have dimmed. KEEP IDENTICAL: camera angle, framing, composition, every other object, lighting direction, color grade. Save to /assets/gen/s3-peak-b.png" -``` +**Edit — word the change HARSHLY.** Image models ignore soft phrasing ("replace X with Y" often returns the original). Call `image_generate` with frame A as the input image and the REQUIRED CHANGE pattern: -**codex edit — prompt via stdin only** (a positional prompt together with `-i` fails with "No prompt provided"): -```bash -printf '%s' "REQUIRED CHANGE: ... KEEP IDENTICAL: camera, composition, lighting." | codex exec --skip-git-repo-check -i assets/gen/s3-peak-a.png - -``` -…then pick up from `generated_images` as above. +> "REQUIRED CHANGE: the laptop is now open, screen glowing, and the room lights have dimmed. KEEP IDENTICAL: camera angle, framing, composition, every other object, lighting direction, color grade." -**Verify the pair eyes-on before building on it:** open A and B side by side. Same camera? Same composition? Only the intended state changed? Small texture drift is fine — the displacement transition tolerates it (it *hides* mid-morph mush). A camera/framing shift is a FAIL: re-edit with harder KEEP IDENTICAL wording, then try codex, then descend the ladder. +…then move the result to `assets/gen/s3-peak-b.png`. -**Retry policy:** any generation/edit gets ONE sharpened retry on the same tool, then ONE attempt on the other tool, then descend the ladder. Do not burn ten generations chasing a frame — reshape the scene instead. +**Verify the pair eyes-on before building on it:** open A and B side by side. Same camera? Same composition? Only the intended state changed? Small texture drift is fine — the displacement transition tolerates it (it *hides* mid-morph mush). A camera/framing shift is a FAIL: re-edit with harder KEEP IDENTICAL wording, then descend the ladder. + +**Retry policy:** any generation/edit gets ONE sharpened retry, then descend the ladder. Do not burn ten generations chasing a frame — reshape the scene instead. ### N-frame chains (for the scroll-cinema state-machine engine) @@ -164,7 +133,7 @@ Extend the A→B pair to a chain: **A→B→C→D…, each an EDIT of the previo the whole world stays photographically consistent while it ages / opens / transforms / gets crowded. 4–6 frames covers most stories. Verify each link same-camera before editing the next; keep the chain in scroll order (`s1-a … s1-d`). This chain IS the input to scroll-cinema's Tier-1 scrubber — do the whole chain in -ONE grok session so the image model never drifts. +ONE sitting with the same backend so the image model never drifts. ## 2.5 Depth maps (for the 2.5D composite / rack-focus) @@ -184,18 +153,13 @@ Alternatives: a **Blender Z-pass** when the scene is a 3D render (Blender CLI; grayscale "depth-style" version (fast, imperfect — ok for subtle pointer-parallax, NOT for rack-focus). Depth is a cached master like any still. Feed color + depth to scroll-cinema §3 (2.5D composite). -## 3. Video — now local via grok +## 3. Video — animate an approved keyframe -Grok animates an approved keyframe: `grok image_to_video` (6 or 10 seconds). Run it through the proxy for grok-4.5, save into `assets/gen/`, then optimize (§5). **Spend video like the motion budget spends attention** — one hero clip + at most a couple supporting; a video that isn't the wow peak is usually a still that should have stayed a still. +An image→video model animates an approved keyframe (6 or 10 seconds); Hermes has no native video tool, so use whatever image→video backend the user has (or a browser tool via `browser_exec`), save into `assets/gen/`, then optimize (§5). **Spend video like the motion budget spends attention** — one hero clip + at most a couple supporting; a video that isn't the wow peak is usually a still that should have stayed a still. -```bash -ALL_PROXY="$GROK_PROXY" HTTPS_PROXY="$GROK_PROXY" grok -m grok-4.5 --yolo -p \ - "image_to_video on /assets/gen/s1-hero-a.png: slow push-in, rising steam, 6s. Save the mp4 to /assets/gen/s1-hero.mp4" -``` - -**Directed A→B state change (before/after, "first+last frame").** ⚠️ grok has NO true first+last-frame interpolator (checked 2026-07): `image_to_video` animates ONE source frame with no end frame; `reference_to_video` takes 2–7 images but treats them as style/content *references*, not strict start/end keyframes — an A+B reference clip is organic drift, not a controlled morph. Routes, best first: +**Directed A→B state change (before/after, "first+last frame").** ⚠️ Most image→video models have NO true first+last-frame interpolator: image-to-video animates ONE source frame with no end frame; reference-to-video modes treat extra images as style/content *references*, not strict start/end keyframes — an A+B reference clip is organic drift, not a controlled morph. Routes, best first: - **Controlled, on the web (preferred):** the WebGL displacement morph between frame A and frame B (scroll-cinema.md) — exact, scroll-scrubbable, no video model, and it's the skill's signature move anyway. This is the real answer to "we have two frames and want the transition". -- **Organic video:** `reference_to_video` with A+B as references for a loose transition, or `image_to_video` on A for pure motion (push-in, steam, drift) — endpoints not guaranteed. +- **Organic video:** reference-to-video with A+B as references for a loose transition, or image-to-video on A for pure motion (push-in, steam, drift) — endpoints not guaranteed. - **A TRUE controlled first→last VIDEO** (hard requirement) still means browser Kling (first+last mode) / Runway / Veo: package frame A + frame B + the motion prompt for the user, continue other scenes, drop the clip in when it arrives. **Going past 10s — chain segments.** Clips cap at 6–10s: `image_to_video` frame A, generate/edit the next state, animate that, `ffmpeg` concat. Each segment starts on the previous last frame so the seams hide. @@ -256,8 +220,8 @@ Budgets (verify.md re-checks): hero video ≤2MB · poster ≤300KB · sequence The crew also produces the small stuff — but every generated element must survive slopscan; a generated gradient/texture that's just decoration is banned like any other. Spend it, then make it earn its place. -- **Textures / grain / noise / abstract shapes** → agy (fast, transparent where possible). Use as CSS `background`, `mask-image`, or a low-opacity overlay. Generate once, cache, reuse. -- **UI mockups in a scene** (device frame + screen, product-in-hand) → codex or grok for the still; Remotion when the mockup must move. +- **Textures / grain / noise / abstract shapes** → `image_generate` (transparent where the backend allows). Use as CSS `background`, `mask-image`, or a low-opacity overlay. Generate once, cache, reuse. +- **UI mockups in a scene** (device frame + screen, product-in-hand) → `image_generate` for the still; Remotion when the mockup must move. - **Hero mockup gate** (phase 0) can now be a *generated* frame, not only a hand-built HTML screen — one throwaway, screenshotted, approved before the real build. - **Iconography / brand marks** → generate a set, then hand-pick: generated icon sets drift in weight/style, so treat them as sketches to redraw in SVG, not final assets. diff --git a/optional-skills/creative/auteur/references/direct.md b/optional-skills/creative/auteur/references/direct.md index 12893093af..3ee3621fdd 100644 --- a/optional-skills/creative/auteur/references/direct.md +++ b/optional-skills/creative/auteur/references/direct.md @@ -1,4 +1,4 @@ -> **Hermes adaptation note:** upstream auteur generated assets through local agent CLIs (`agy`, `codex`, `grok`). In Hermes, read every such invocation as a call to the built-in `image_generate` tool with the same prompt (then move the returned file into the project's `assets/gen/` path), use the `terminal` tool for `ffmpeg`/`node`/`npx`, and `browser_exec` or Playwright-via-terminal for screenshot loops. The per-CLI routing/strength tables below are upstream reference material — the taste guidance transfers, the CLI names do not. +> **Hermes adaptation note:** upstream auteur generated assets through several local image CLIs. In Hermes, read every generation instruction as a call to the built-in `image_generate` tool with the same prompt (then move the returned file into the project's `assets/gen/` path), use the `terminal` tool for `ffmpeg`/`node`/`npx`, and `browser_exec` or Playwright-via-terminal for screenshot loops. The per-CLI routing/strength tables below are upstream reference material — the taste guidance transfers, the CLI names do not. # direct.md — the cinematic register @@ -65,10 +65,10 @@ media: the director's shot spec for this scene's asset (→ the asset pla · route: SOURCE or GENERATE — assets.md §0.5 decides. Geometry, IBL lighting and tiling materials are SOURCE (source.mjs, CC0); the peak keyframe and the hero video are always GENERATE; stock video is never the peak - · tool: codex (peak photoreal) | grok-4.5 (color hero + ANYTHING that becomes video) | agy (volume/elements) + · tool: image_generate (stills, A→B edits) | image→video backend (anything that becomes video) | source.mjs hdri|model|texture|icon|image|video · frame prompt: the literal keyframe prompt = subject + camera + lighting + palette anchor (write it now) - · motion prompt: (video/morph only) what moves — e.g. "grok image_to_video on frame A: slow push-in + steam, 6s". Controlled A→B state change = WebGL displacement morph (two frames), NOT a video model + · motion prompt: (video/morph only) what moves — e.g. "image-to-video on frame A: slow push-in + steam, 6s". Controlled A→B state change = WebGL displacement morph (two frames), NOT a video model · score: (peak/ambient scenes only) mood/tempo for MiniMax music, or "none" fallback: what this scene is when WebGL/video/motion is unavailable (static frame + one line) ``` diff --git a/optional-skills/creative/auteur/references/recon.md b/optional-skills/creative/auteur/references/recon.md index 3768e5aa87..b5a2582a2a 100644 --- a/optional-skills/creative/auteur/references/recon.md +++ b/optional-skills/creative/auteur/references/recon.md @@ -30,7 +30,7 @@ node scripts/refscout.mjs --from awwwards --limit 8 node scripts/refscout.mjs --from awwwards:scrolling --limit 6 node scripts/refscout.mjs --from awwwards --search "coffee" --limit 5 -# or profile sites you already know / found with WebSearch +# or profile sites you already know / found with web_search node scripts/refscout.mjs https://a.com https://b.com --shots 4 ``` @@ -39,7 +39,7 @@ Output lands in `design/refs/`: `REFERENCES.md` (read it), `refs.json`, `shots/* **Finding candidates.** `--from awwwards` is the only harvester wired in, because it is the only gallery whose listing *and* detail pages render reliably headless and expose the outbound site URL. For everything else — godly.website, curated.design, minimal.gallery, land-book, siteinspire, -thefwa, lapa.ninja, mobbin — use WebSearch to find the write-ups, then pass the site URLs to +thefwa, lapa.ninja, mobbin — use `web_search` to find the write-ups, then pass the site URLs to refscout positionally. Searching for the *page about* a site is more reliable than scraping the gallery that lists it. @@ -198,7 +198,7 @@ and none of them ships: | symptom | what it means | do this | |---|---|---| -| `awwwards listing returned no cards` | the gallery markup moved | fall back to WebSearch + positional URLs | +| `awwwards listing returned no cards` | the gallery markup moved | fall back to `web_search` + positional URLs | | most entries are `NO CAPTURE` | network or a broad bot wall | profile fewer, better-known sites; lean on the shots and your own eyes | | `pinterest returned 0` | login wall, normal | ignore, bing covered it | | the sheet is 20 variants of one image | single narrow query | re-run with 2–3 queries on different axes | diff --git a/optional-skills/creative/auteur/references/scroll-cinema.md b/optional-skills/creative/auteur/references/scroll-cinema.md index 1460139453..2d0850ef48 100644 --- a/optional-skills/creative/auteur/references/scroll-cinema.md +++ b/optional-skills/creative/auteur/references/scroll-cinema.md @@ -847,7 +847,7 @@ Rules: rAF-throttle (one transform write per frame, never per event); clamp so t ## State-machine cinema — A→B→C morph + audio-reactive (Tier-1 engine) The signature 2026 move: ONE world that transforms through a chain of scene-consistent frames -(assets.md §2 — grok edit-chain A→B→C…N), scrubbed by scroll AND driven by an audio track, both feeding +(assets.md §2 — the edit-chain A→B→C…N), scrubbed by scroll AND driven by an audio track, both feeding the SAME `uMix`/`uEnergy` uniforms so picture and sound move as one. Extends the two-frame displacement to N frames. One persistent WebGL context; swap textures, never remount. @@ -864,7 +864,7 @@ the current position with a noise-driven wipe, so it reads as a morph, not a cro ```js import * as THREE from 'three' import Lenis from 'lenis' -const FRAMES = ['/gen/s1-a.webp','/gen/s1-b.webp','/gen/s1-c.webp','/gen/s1-d.webp'] // grok edit-chain, in order +const FRAMES = ['/gen/s1-a.webp','/gen/s1-b.webp','/gen/s1-c.webp','/gen/s1-d.webp'] // edit-chain, in order const canvas = document.getElementById('c') const renderer = new THREE.WebGLRenderer({ canvas, antialias:true }) renderer.setPixelRatio(Math.min(devicePixelRatio, 2)) diff --git a/optional-skills/creative/auteur/references/scroll-flight.md b/optional-skills/creative/auteur/references/scroll-flight.md index 900b4e903e..2e94da1e4e 100644 --- a/optional-skills/creative/auteur/references/scroll-flight.md +++ b/optional-skills/creative/auteur/references/scroll-flight.md @@ -1,4 +1,4 @@ -> **Hermes adaptation note:** upstream auteur generated assets through local agent CLIs (`agy`, `codex`, `grok`). In Hermes, read every such invocation as a call to the built-in `image_generate` tool with the same prompt (then move the returned file into the project's `assets/gen/` path), use the `terminal` tool for `ffmpeg`/`node`/`npx`, and `browser_exec` or Playwright-via-terminal for screenshot loops. The per-CLI routing/strength tables below are upstream reference material — the taste guidance transfers, the CLI names do not. +> **Hermes adaptation note:** upstream auteur generated assets through several local image CLIs. In Hermes, read every generation instruction as a call to the built-in `image_generate` tool with the same prompt (then move the returned file into the project's `assets/gen/` path), use the `terminal` tool for `ffmpeg`/`node`/`npx`, and `browser_exec` or Playwright-via-terminal for screenshot loops. The per-CLI routing/strength tables below are upstream reference material — the taste guidance transfers, the CLI names do not. # scroll-flight — photoreal scroll-scrubbed video ("fly through the world") @@ -24,8 +24,8 @@ They compose: a WebGL hero can hand off into a scrubbed-video mid-section. ## ⚠️ AI clips barely move the camera — the scroll-dolly does the travelling -The single most important thing to know here. **`grok image_to_video` (and -most image→video models) animate a still *ambiently* — light shimmers, water +The single most important thing to know here. **image→video models (all the +common ones) animate a still *ambiently* — light shimmers, water drifts, particles float — but they do NOT fly the camera through the scene.** Verified on disk: a clip's first and last frame are near-identical. So a scene built only from a raw AI clip reads as *a slightly-moving photo*, not a journey. @@ -58,11 +58,11 @@ never reveal. *That* is what manufactures forward/descent travel; the clip's 1. **Scene stills** — one anchor still first, get art-direction approval, then batch the rest **style-locked to the anchor** (pass the approved still as the style reference). A style miss caught on the anchor costs 1 gen, not N. - Sources: `codex`/`agy` (Gemini)/`grok` image gen — see `assets.md`. -2. **Dive clips** — animate each still into a short camera push-in (grok - `image_to_video`, or any image→video model). One clip per scene. + Source: `image_generate` — see `assets.md`. +2. **Dive clips** — animate each still into a short camera push-in (any + image→video model). One clip per scene. 3. **Seams** — two ways, pick by what your video model can do: - - **Crossfade seams (default, grok/start-image-only models).** Leave + - **Crossfade seams (default, start-image-only models).** Leave `connectors` empty/`null`; the engine crossfades directly between adjacent dives. Ship-safe, always works, reads clean. This is auteur's baseline. - **Seamless flight (only with an end-image model — Higgsfield seedance / @@ -73,8 +73,8 @@ never reveal. *That* is what manufactures forward/descent travel; the clip's 5. **Posters** — extract each encoded clip's first frame (§ below). 6. **Wire** the engine config; run the motion + slopscan gates. -> auteur has no Higgsfield account by default; grok `image_to_video` is the -> baseline. So the honest default is **crossfade-seam** photoreal scrub — still +> auteur has no Higgsfield account by default; a start-image-only +> image→video model is the baseline. So the honest default is **crossfade-seam** photoreal scrub — still > Apple-tier. Fully-seamless chaining is an upgrade you unlock only with an > end-image-capable video model. @@ -188,5 +188,5 @@ it only when video-scrub genuinely stutters on the target hardware. --- *Technique & engine adapted from **scroll-world** by cyw -(github.com/cth9191/scroll-world), MIT. auteur pairs it with grok/Gemini asset -generation and its own slopscan / motionqa gates.* +(github.com/cth9191/scroll-world), MIT. auteur pairs it with `image_generate` asset +production and its own slopscan / motionqa gates.* diff --git a/optional-skills/creative/auteur/scripts/refscout.mjs b/optional-skills/creative/auteur/scripts/refscout.mjs index d82698ba5f..b905e07277 100644 --- a/optional-skills/creative/auteur/scripts/refscout.mjs +++ b/optional-skills/creative/auteur/scripts/refscout.mjs @@ -279,7 +279,7 @@ async function fingerprint(ctx, url) { // --- gallery harvesting ------------------------------------------------------- // awwwards is the one gallery whose listing AND detail pages both render reliably headless // and expose the outbound site URL. Other galleries either need JS we can't wait out or bury -// the real URL behind affiliate redirects — for those, find URLs with WebSearch and pass them +// the real URL behind affiliate redirects — for those, find URLs with web_search and pass them // positionally. async function harvestAwwwards(ctx, tag, text, n) { const page = await ctx.newPage(); @@ -322,7 +322,7 @@ let targets = urls.map(u => ({ site: u, name: null, via: 'direct' })); if (from) { const [gallery, tag] = from.split(':'); if (gallery === 'awwwards') targets = targets.concat(await harvestAwwwards(ctx, tag, search, limit)); - else console.error(`[refscout] unknown gallery "${gallery}" — supported: awwwards. Pass URLs directly instead (find them with WebSearch).`); + else console.error(`[refscout] unknown gallery "${gallery}" — supported: awwwards. Pass URLs directly instead (find them with web_search).`); } targets = targets.slice(0, limit); diff --git a/optional-skills/creative/auteur/scripts/source.mjs b/optional-skills/creative/auteur/scripts/source.mjs index 3a94eb41c9..441fab2b6d 100644 --- a/optional-skills/creative/auteur/scripts/source.mjs +++ b/optional-skills/creative/auteur/scripts/source.mjs @@ -36,6 +36,7 @@ import { mkdir, writeFile, readFile } from 'fs/promises'; import { existsSync } from 'fs'; import { resolve, join, dirname } from 'path'; +import { tmpdir } from 'os'; const args = process.argv.slice(2); const KINDS = ['hdri', 'model', 'texture', 'icon', 'font', 'image', 'video']; @@ -172,7 +173,7 @@ async function icons() { const GF_BANNED = ['Inter', 'Space Grotesk', 'Instrument Serif', 'Playfair Display']; async function fonts() { // Not inside --out: that just relocates 1.5MB from your cwd into your shipped assets tree. - const cacheFile = join(process.env.TEMP || process.env.TMPDIR || '.', 'auteur-gf-metadata.json'); + const cacheFile = join(tmpdir(), 'auteur-gf-metadata.json'); let meta; if (existsSync(cacheFile)) meta = JSON.parse(await readFile(cacheFile, 'utf8')); else { diff --git a/optional-skills/creative/auteur/templates/STORYBOARD.md b/optional-skills/creative/auteur/templates/STORYBOARD.md index 4646b09bff..2da960e27d 100644 --- a/optional-skills/creative/auteur/templates/STORYBOARD.md +++ b/optional-skills/creative/auteur/templates/STORYBOARD.md @@ -40,7 +40,7 @@ - **copy:** H: "…" / sub: "…" - **media:** - type: - - route: + - route: - frame prompt: - motion prompt: - score: diff --git a/optional-skills/creative/auteur/templates/scroll-flight-engine.js b/optional-skills/creative/auteur/templates/scroll-flight-engine.js index fdc7178f0b..d32e957a19 100644 --- a/optional-skills/creative/auteur/templates/scroll-flight-engine.js +++ b/optional-skills/creative/auteur/templates/scroll-flight-engine.js @@ -3,7 +3,7 @@ ---------------------------------------------------------------------------- Portable scroll-scrubbed camera-flight engine. Photoreal AI-video "fly through the world" — auteur's video-scrub tier, complementary to its real-time WebGL - recipes. Asset-source-agnostic: feed it ANY .mp4 clips (grok image_to_video, + recipes. Asset-source-agnostic: feed it ANY .mp4 clips (image→video models, Gemini, real footage). See references/scroll-flight.md for the full recipe. VENDORED from scroll-world (github.com/cth9191/scroll-world), MIT (c) 2026 cyw. diff --git a/tests/skills/test_auteur_skill.py b/tests/skills/test_auteur_skill.py index ed6a760f55..0ad596c2a3 100644 --- a/tests/skills/test_auteur_skill.py +++ b/tests/skills/test_auteur_skill.py @@ -29,9 +29,9 @@ def test_mentioned_paths_exist_or_annotated(): assert not missing, f"paths mentioned but absent and unannotated: {missing}" -def test_no_claude_residue(): - """Upstream is a Claude Code plugin; its plugin-only frontmatter keys and - harness name must not leak into the Hermes port.""" +def test_no_upstream_harness_residue(): + """Upstream ships as a plugin for another agent harness; its plugin-only + frontmatter keys and harness name must not leak into the Hermes port.""" text = SKILL_MD.read_text(encoding="utf-8").lower() for token in ("claude", "allowed-tools", "argument-hint"): assert token not in text, f"residual '{token}' in SKILL.md" diff --git a/website/docs/user-guide/skills/optional/creative/creative-auteur.md b/website/docs/user-guide/skills/optional/creative/creative-auteur.md index 2f43dfb8b2..096e4a062c 100644 --- a/website/docs/user-guide/skills/optional/creative/creative-auteur.md +++ b/website/docs/user-guide/skills/optional/creative/creative-auteur.md @@ -38,7 +38,7 @@ The following is the complete skill definition that Hermes loads when this skill Auteur designs and builds web experiences the way a film director makes a film: script first, then assets, then the shoot, then the cut. It has three registers — **build** (an excellent conventional site), **direct** (a cinematic scroll-directed site) and **system** (a multi-screen product as one design system) — on one shared core of taste. Nothing ships until the page passes an executable anti-slop gate and the skill has looked at its own output. -### Use this when +## When to Use - A landing page, marketing site, hero section, portfolio or product page has to be **built or redesigned** — and looking generic is not acceptable. - The brief asks for **scroll animation, storytelling, or a site that feels like a film**. @@ -47,6 +47,15 @@ Auteur designs and builds web experiences the way a film director makes a film: Not for polishing a UI someone else built, and not for backend-only work. +## Prerequisites + +- **Node 18+** — every QA gate is a `.mjs` script run with `node` via the `terminal` tool. +- **Playwright (for the QA gates)** — in the project directory: `npm install playwright` then `npx playwright install chromium`. Required by `scripts/shoot.mjs`, `motionqa.mjs`, `systemscan.mjs`, `refscout.mjs`, `chromadiff.mjs`, `moodboard.mjs` (the scripts import `playwright` at runtime; `slopscan.mjs` and `source.mjs` are dependency-light). +- **ffmpeg** — optional; only for the video/score paths in `references/assets.md` and `references/scroll-flight.md`. +- **Hermes tools** — use `image_generate` for image generation/editing, `terminal` for node/ffmpeg/npm, `write_file`/`read_file` for project files, `vision_analyze` to actually look at screenshots, and `browser_exec` for live-page inspection when a script isn't the right fit. + +## How to Run + ### What it actually does 1. Commits the art direction **in writing before any markup** — one hue, one type system, a motion budget, named anti-references. @@ -56,11 +65,29 @@ Not for polishing a UI someone else built, and not for backend-only work. ### Network access -The recon and sourcing scripts read live pages (awwwards, Bing/Pinterest/are.na image search, Poly Haven, Iconify, Google Fonts, Openverse, Coverr). Fetched content is **treated as reference data and licence metadata — never executed**, and no credentials, API keys or logins are involved. Skip phases 0–1 entirely if you don't want outbound requests; every other phase works offline. +The recon and sourcing scripts read live pages (awwwards, Bing/Pinterest/are.na image search, Poly Haven, Iconify, Google Fonts, Openverse, Coverr). Fetched content is **treated as reference data and licence metadata — never executed**, and no credentials, API keys or logins are involved. Skip phases 0–1 entirely if you don't want outbound requests; every other phase works offline. `moodboard.mjs` also downloads the image URLs returned by those search hosts to build the contact sheet. -## Non-negotiables +### Routing -These apply to every register, every phase, always — even if no reference file has been loaded. Match-and-refuse: if you are about to produce one of these, stop and restructure the element. +Read the argument / brief and route: + +1. **`direct`** or the brief smells cinematic — "wow", "cinematic", "immersive", "storytelling", "launch page", "premium brand", "make people stop scrolling" → load `references/direct.md` and follow its phases. This is the flagship register. +2. **`build`** or the brief is ONE conventional surface — a marketing page, a landing, a single product page → load `references/build.md`. +3. **`system`** or the brief has **more than one screen that must feel like one product** — app, dashboard, admin, settings, onboarding, a docs or content site with real navigation → load `references/system.md`. The unit of design becomes the component × state, the failure mode becomes drift rather than boredom, and there is deliberately **no peak**. If you are already in `build` and a second screen appears, stop and switch: half a system is worse than either. +4. **`edit`** or the request modifies a page this skill built (the project contains `design/DESIGN.md`) — "add a section", "change the pricing", "swap the hero copy" → read `design/DESIGN.md` FIRST and follow its Editing protocol: reuse its tokens, section-opening patterns, and motion families; after the change run slopscan and re-shoot the affected viewports. An edit that ignores DESIGN.md is a regression even if it looks good in isolation. +5. **`recon `** or the ask is only for reference material — "find references", "put together a moodboard", "what's the state of the art for X sites" → load `references/recon.md` and run just that phase: scout live sites, build the moodboard, hand back `design/refs/REFERENCES.md` (with the `steal:` lines filled) and `design/moodboard/contact-sheet.png` (with the read filled). No commit-sheet, no build. +6. **`audit `** → load `references/verify.md` and run the verification pipeline on an auteur-built page. If the target is an existing UI auteur didn't build and the user wants it *polished* rather than *rebuilt*, say that a dedicated UI-polish/critique pass (upstream paired auteur with a separate 'impeccable' skill, not vendored here) is the right tool and offer to continue only if they want a rebuild. +7. **Ambiguous** (e.g. plain "make a landing page") → ask exactly one question: "A great conventional landing page, or cinema mode with scroll direction and generated assets?" (upstream phrased these example briefs in Russian; translated here.) Then route. (Multi-screen briefs are not ambiguous — they are `system`.) Don't ask anything else yet — each register runs its own intake. + +All three registers share phase zero, and its centre of gravity is the commit-sheet. Order differs: **build** runs recon → commit-sheet → mockup; **direct** runs recon → storyboard → commit-sheet → mockup, because the film's scenes are what the six decisions get made *about*; **system** runs recon → system-sheet (route map + component inventory) → commit-sheet → mockup, because the six decisions get made about a product, not a page. Either way nothing is coded before the sheet is full. + +### Working relationship with other skills + +Auteur *builds*; it does not re-polish foreign UI. If the user has an existing interface that needs refinement, run a separate UI-critique pass (e.g. `vision_analyze` on screenshots plus the sibling design skills). Upstream paired auteur with an 'impeccable' critique skill (not vendored here); auteur's verify gate and an outside critique measure different things and coexist happily. + +## Quick Reference + +The non-negotiables and the phase table. They apply to every register, every phase, always — even if no reference file has been loaded. Match-and-refuse: if you are about to produce one of these, stop and restructure the element. ### Banned (rewrite, don't tweak) @@ -100,35 +127,7 @@ A ban may be overridden only through a written `auteur-allow` (see Verification) - `prefers-reduced-motion` = an alternative art direction (gentler, not zero), never an afterthought. - Content must be readable with JS disabled: reveals enhance an already-visible default, never gate visibility. -## Routing - -Read the argument / brief and route: - -1. **`direct`** or the brief smells cinematic — "wow", "cinematic", "immersive", "storytelling", "launch page", "premium brand", "make people stop scrolling" → load `references/direct.md` and follow its phases. This is the flagship register. -2. **`build`** or the brief is ONE conventional surface — a marketing page, a landing, a single product page → load `references/build.md`. -3. **`system`** or the brief has **more than one screen that must feel like one product** — app, dashboard, admin, settings, onboarding, a docs or content site with real navigation → load `references/system.md`. The unit of design becomes the component × state, the failure mode becomes drift rather than boredom, and there is deliberately **no peak**. If you are already in `build` and a second screen appears, stop and switch: half a system is worse than either. -4. **`edit`** or the request modifies a page this skill built (the project contains `design/DESIGN.md`) — "add a section", "change the pricing", "swap the hero copy" → read `design/DESIGN.md` FIRST and follow its Editing protocol: reuse its tokens, section-opening patterns, and motion families; after the change run slopscan and re-shoot the affected viewports. An edit that ignores DESIGN.md is a regression even if it looks good in isolation. -5. **`recon `** or the ask is only for reference material — "find references", "put together a moodboard", "what's the state of the art for X sites" → load `references/recon.md` and run just that phase: scout live sites, build the moodboard, hand back `design/refs/REFERENCES.md` (with the `steal:` lines filled) and `design/moodboard/contact-sheet.png` (with the read filled). No commit-sheet, no build. -6. **`audit `** → load `references/verify.md` and run the verification pipeline on an auteur-built page. If the target is an existing UI auteur didn't build and the user wants it *polished* rather than *rebuilt*, say that a dedicated UI-polish/critique pass (upstream paired auteur with a separate 'impeccable' skill, not vendored here) is the right tool and offer to continue only if they want a rebuild. -7. **Ambiguous** (e.g. plain "make a landing page") → ask exactly one question: "A great conventional landing page, or cinema mode with scroll direction and generated assets?" (upstream phrased these example briefs in Russian; translated here.) Then route. (Multi-screen briefs are not ambiguous — they are `system`.) Don't ask anything else yet — each register runs its own intake. - -All three registers share phase zero, and its centre of gravity is the commit-sheet. Order differs: **build** runs recon → commit-sheet → mockup; **direct** runs recon → storyboard → commit-sheet → mockup, because the film's scenes are what the six decisions get made *about*; **system** runs recon → system-sheet (route map + component inventory) → commit-sheet → mockup, because the six decisions get made about a product, not a page. Either way nothing is coded before the sheet is full. - -## The commit-sheet (before any code, both registers) - -Slop is what happens when defaults make the decisions. The commit-sheet forces seven real decisions onto paper before the first line of code. Copy `templates/COMMIT-SHEET.md` into the project (e.g. `design/COMMIT-SHEET.md`) and fill all seven fields with non-defaults: - -1. **Peak** — the ONE primary wow moment (direct) or signature element (build). One sentence. If you can't name it, you're not ready to build. -2. **Color** — primary as OKLCH + commitment tier (restrained / committed / full-palette / drenched) + one line: *why this is not lavender, not cream, and not the category reflex* + **the background lightness as a number** (target mean L), because "dark feels premium" is where this skill drifts, and a number can be checked afterwards where a mood cannot. -3. **Type** — display + text pairing on a contrast axis (serif+sans, geometric+humanist, mono+serif...) + one line: *why not Inter*. -4. **Grid break** — the one concrete thing that breaks the symmetric-grid default: an overlap, an asymmetric split, a diagonal flow, a full-bleed interruption. Name it specifically. -5. **Motion budget** — how many scroll-pattern families (≤3) and what they are. -6. **Reflex check** — write down: (a) what a generic AI would do for this category (first-order reflex), (b) what a generic AI avoiding (a) would do (second-order reflex — e.g. fintech → "terminal dark mode" is *also* saturated now), (c) your chosen deviation from both. If recon ran, (a) is not a guess: whatever `design/refs/REFERENCES.md` showed five times *is* the reflex, dated and with receipts. -7. **House tells broken** — name the **two (minimum)** items from `taste.md` §2.5 you are deliberately not doing this time, and what replaces each. Fields 6a/6b are the reflexes of the *category*; these are the reflexes of *this skill*, which recur across unrelated projects and are invisible from inside any one of them: near-black backgrounds, mono service labels, the logo/status/action header, the scroll-instruction footer, amber-or-acid accents, the wordmark-as-hero, glow standing in for lighting. Measured across nine showcase builds, eight were dark and three landed within 0.002 of the same lightness. A tell that genuinely belongs here can stay — say why, as with an `auteur-allow`. - -Gate: every field filled with a specific, non-default answer. An empty or generic field ("modern, clean look") means stop and decide. This artifact is checked again at verification. - -## Phases at a glance +### Phases at a glance | Phase | build register | direct register | system register | Reference to load | |---|---|---|---|---| @@ -142,7 +141,23 @@ The hero mockup gate (one static throwaway screen, screenshotted and approved be Never skip a gate because the intermediate result "looks done". The gates exist because a page that merely looks done is exactly what every other AI ships. -## Reference files +## Procedure + +### The commit-sheet (before any code, both registers) + +Slop is what happens when defaults make the decisions. The commit-sheet forces seven real decisions onto paper before the first line of code. Copy `templates/COMMIT-SHEET.md` into the project (e.g. `design/COMMIT-SHEET.md`) and fill all seven fields with non-defaults: + +1. **Peak** — the ONE primary wow moment (direct) or signature element (build). One sentence. If you can't name it, you're not ready to build. +2. **Color** — primary as OKLCH + commitment tier (restrained / committed / full-palette / drenched) + one line: *why this is not lavender, not cream, and not the category reflex* + **the background lightness as a number** (target mean L), because "dark feels premium" is where this skill drifts, and a number can be checked afterwards where a mood cannot. +3. **Type** — display + text pairing on a contrast axis (serif+sans, geometric+humanist, mono+serif...) + one line: *why not Inter*. +4. **Grid break** — the one concrete thing that breaks the symmetric-grid default: an overlap, an asymmetric split, a diagonal flow, a full-bleed interruption. Name it specifically. +5. **Motion budget** — how many scroll-pattern families (≤3) and what they are. +6. **Reflex check** — write down: (a) what a generic AI would do for this category (first-order reflex), (b) what a generic AI avoiding (a) would do (second-order reflex — e.g. fintech → "terminal dark mode" is *also* saturated now), (c) your chosen deviation from both. If recon ran, (a) is not a guess: whatever `design/refs/REFERENCES.md` showed five times *is* the reflex, dated and with receipts. +7. **House tells broken** — name the **two (minimum)** items from `taste.md` §2.5 you are deliberately not doing this time, and what replaces each. Fields 6a/6b are the reflexes of the *category*; these are the reflexes of *this skill*, which recur across unrelated projects and are invisible from inside any one of them: near-black backgrounds, mono service labels, the logo/status/action header, the scroll-instruction footer, amber-or-acid accents, the wordmark-as-hero, glow standing in for lighting. Measured across nine showcase builds, eight were dark and three landed within 0.002 of the same lightness. A tell that genuinely belongs here can stay — say why, as with an `auteur-allow`. + +Gate: every field filled with a specific, non-default answer. An empty or generic field ("modern, clean look") means stop and decide. This artifact is checked again at verification. + +### Reference files - `references/recon.md` — **phase 0 scouting**, two executable legs: `scripts/refscout.mjs` profiles live award-level sites (real stack, pinned scenes, scroll budget, fonts, painted palette, screenshots — mechanics, not skins) and `scripts/moodboard.mjs` builds a numbered contact sheet from Bing / Pinterest / are.na so the art direction is decided from live material instead of memory. Also: query craft, the steal rule, how recon feeds the commit-sheet, and the "reference images are not assets" line. Load at the top of phase 0. - `references/taste.md` — the full anti-slop system: extended bans with replacements, second-order category reflex table, color strategy tiers, typography pairing, copy rules. Load for any visual decision-making. @@ -150,41 +165,31 @@ Never skip a gate because the intermediate result "looks done". The gates exist - `references/build.md` — the standard register process. Load when routed to build. - `references/system.md` — the **multi-screen register**: route map, the component inventory as a gate, the state matrix (empty/loading/error are not edge cases), density rules, the no-peak rule, and `scripts/systemscan.mjs` — which crawls every route, reads what the browser actually painted, fails a control type over its declared variant budget — counting *states* (disabled, current, inside a `data-state` row) separately, so implementing the state matrix never reads as drift — presses Tab to catch controls with no visible focus state, and renders one tile per rendered variant so drift is visible as well as counted. Load when routed to system. - `references/direct.md` — the cinematic register: screenplay contract, scene-sheets, dramaturgy, assembly order. Load when routed to direct. -- `references/assets.md` — the media crew and routing (in Hermes: `image_generate` for all image generation and edits, `terminal` for ffmpeg/node; upstream's video/score CLI routing kept as reference), **§0.5 source-vs-generate** (`scripts/source.mjs`: CC0 glTF meshes, HDRIs and PBR materials from Poly Haven, icons, fonts, CC images, stock video — with a licence ledger, because generation cannot make geometry or an IBL and stock video must never be the peak), the consistency trick (edit frame A into frame B), local video via the first→last-frame chain, generated elements/mockups, the ambient score, the degradation ladder, and asset caching. Load during direct phase 1. +- `references/assets.md` — the media crew and routing (in Hermes: `image_generate` for all image generation and edits, `terminal` for ffmpeg/node; video via whatever image→video backend the user has), **§0.5 source-vs-generate** (`scripts/source.mjs`: CC0 glTF meshes, HDRIs and PBR materials from Poly Haven, icons, fonts, CC images, stock video — with a licence ledger, because generation cannot make geometry or an IBL and stock video must never be the peak), the consistency trick (edit frame A into frame B), local video via the first→last-frame chain, generated elements/mockups, the ambient score, the degradation ladder, and asset caching. Load during direct phase 1. - `references/scroll-cinema.md` — working code recipes: scroll-scrubbed video, canvas sequences, GSAP+Lenis foundation, CSS scroll-driven animations, text reveals, the two-keyframe WebGL displacement transition, view transitions, ambient audio, and the cinematic transition library (wipe, curtain, letterbox, shutter, depth parallax). Load during assembly. - `references/scroll-flight.md` — the **video-scrub tier**: a photoreal "fly through the world" hero driven by scroll, using the drop-in `templates/scroll-flight-engine.js`. The canonical recipe for scroll-scrubbed *video* (encode-for-scrubbing `-g 8`, encoded-frame posters, SSIM seam gate, chain architecture A/B, iOS/mobile decode hardening, crossfade-vs-seamless seams). Load when the hero should be photoreal footage/AI-video rather than real-time WebGL. - `references/ambient-backgrounds.md` — **quiet** texture for secondary sections and simpler builds (not a hero): a curated 6 editorial/analog effects (paper grain, ledger/blueprint rules, topographic contour, ink tide, sparse dust, one heat-haze shader) + a zero-motion static-mesh default. The governing rule (weaker than the quietest foreground element; one ambient per page), the CSS/SVG-first stack, and the `feTurbulence`-static perf rule. Load when a section needs to not be flat but must NOT compete with copy. - `references/verify.md` — the acceptance pipeline: slopscan → screenshot journey → motion/perf/audio QA (FPS at DPR 2 on a production build, long-tasks, audio-gate, reduced-motion, for Tier-1 scenes) → numeric rubric → **reference diff** (your frame beside the reference that set the direction, with `scripts/chromadiff.mjs` measuring the colour drift a model never sees in itself) → QA sign-off. Load at phase 3. -## Verification is part of the build - -The page is not done when the code compiles. It is done when: - -1. `node scripts/slopscan.mjs ` exits 0 (fails are fixed, not suppressed — `/* auteur-allow: RULE_ID -- reason */` exists for deliberate choices and demands a real reason); -2. `node scripts/shoot.mjs ` has produced screenshot journeys at 390 / 768 / 1440 and you have **looked at every frame** — text overflow, blank scenes, broken reveals, layout collapse are found by eyes, not by grep; -3. the numeric rubric in `references/verify.md` passes (contrast, LCP, CLS, reduced-motion journey, scene variety); -4. for direct register: `CINEMA-QA.md` (from templates) is filled with PASS on every row. - -If any gate fails — fix and re-run. Report results honestly: "slopscan clean, 21 screenshots reviewed, LCP 1.9s" beats "looks great". - -## Working relationship with other skills - -Auteur *builds*; it does not re-polish foreign UI. If the user has an existing interface that needs refinement, run a separate UI-critique pass (e.g. `vision_analyze` on screenshots plus the sibling design skills). Upstream paired auteur with an 'impeccable' critique skill (not vendored here); auteur's verify gate and an outside critique measure different things and coexist happily. - -## Weak-model note +### Weak-model note If you are a smaller model executing this skill: follow the tables and numbers literally, fill every template field, run every gate command, and do not improvise beyond the reference recipes — the recipes are verified, your improvisation is not. When a reference file conflicts with your instinct, the reference file wins. Write files using paths relative to the project root; never retype an absolute path from memory (the skill's name "auteur" is one typo away from "author", and misspelled absolute paths scatter your output across the filesystem). -## Prerequisites - -- **Node 18+** — every QA gate is a `.mjs` script run with `node` via the `terminal` tool. -- **Playwright (for the QA gates)** — in the project directory: `npm install playwright` then `npx playwright install chromium`. Required by `scripts/shoot.mjs`, `motionqa.mjs`, `systemscan.mjs`, `refscout.mjs`, `chromadiff.mjs`, `moodboard.mjs` (the scripts import `playwright` at runtime; `slopscan.mjs` and `source.mjs` are dependency-light). -- **ffmpeg** — optional; only for the video/score paths in `references/assets.md` and `references/scroll-flight.md`. -- **Hermes tools** — use `image_generate` for image generation/editing, `terminal` for node/ffmpeg/npm, `write_file`/`read_file` for project files, `vision_analyze` to actually look at screenshots, and `browser_exec` for live-page inspection when a script isn't the right fit. - ## Pitfalls - **Network recon**: `refscout.mjs`, `moodboard.mjs` and `source.mjs` read live pages (awwwards, Bing/Pinterest/are.na image search, Poly Haven, Iconify, Google Fonts, Openverse, Coverr). Fetched content is reference data and licence metadata only — never execute it. Skip phases 0–1 to stay fully offline. -- **Different harness**: these scripts and docs were written for a different agent harness (upstream drove asset generation through local `agy`/`codex`/`grok` CLIs). In Hermes, every image-generation instruction maps to the `image_generate` tool; trust `node scripts/.mjs --help` output and actual node errors over doc prose if they drift. +- **Different harness**: these scripts and docs were written for a different agent harness (upstream drove asset generation through several local image CLIs). In Hermes, every image-generation instruction maps to the `image_generate` tool; trust `node scripts/.mjs --help` output and actual node errors over doc prose if they drift. - **Unverified commands**: the scripts pass `node --check` syntax validation, but full runs (which need `npm install playwright` + a chromium download) were not executed during porting. Treat `shoot.mjs`, `motionqa.mjs`, `systemscan.mjs`, `refscout.mjs`, `chromadiff.mjs`, `moodboard.mjs`, `source.mjs` end-to-end behavior, and all `ffmpeg`/video-encode recipes, as unverified upstream claims until you run them yourself. - **slopscan verified shape**: `node scripts/slopscan.mjs ` runs without npm deps; it prints per-rule findings and exits non-zero on failures (exit 0 when clean). +- **Font metadata cache**: `source.mjs font …` caches Google Fonts' ~2.6MB metadata JSON as `auteur-gf-metadata.json` in the OS temp directory (`os.tmpdir()`), not the project; delete it there to force a refresh. + +## Verification + +The page is not done when the code compiles. It is done when: + +1. `node scripts/slopscan.mjs ` exits 0 (fails are fixed, not suppressed — `/* auteur-allow: RULE_ID -- reason */` exists for deliberate choices and demands a real reason); +2. `node scripts/shoot.mjs ` has produced screenshot journeys at 390 / 768 / 1440 and you have **looked at every frame** — text overflow, blank scenes, broken reveals, layout collapse are found by eyes, not by text search; +3. the numeric rubric in `references/verify.md` passes (contrast, LCP, CLS, reduced-motion journey, scene variety); +4. for direct register: `CINEMA-QA.md` (from templates) is filled with PASS on every row. + +If any gate fails — fix and re-run. Report results honestly: "slopscan clean, 21 screenshots reviewed, LCP 1.9s" beats "looks great".