| name | content-preflight |
| description | MANDATORY pre-flight check that runs BEFORE any content plan or generation. Classifies the topic, verifies project/brand/product context, resolves the required reusable assets (characters, products, logos, voices) from the asset registry, and provides/generates whatever is missing โ saving paths for reuse. Use whenever the user asks to plan a campaign, make a marketing plan, or create/generate any image, video, voiceover, or music. |
| allowed-tools | Bash Read Write Edit Glob Grep |
Content Pre-flight
Run this FIRST, every time, before planning or generating content. It stops
the agent from writing generic prompts, re-describing the same character/product
for every piece, or generating with missing context.
Reference: templates/content-requirements.md
(the matrix) and templates/assets.config.template.yaml
(the registry schema). Asset functions live in workflows/dist/index.js.
Gate: do not proceed to a plan or generation until every required input
for the chosen topic + visual mode is satisfied (or minimal mode is explicitly
chosen) and the user confirms.
STEP 1: Classify the request
Ask yourself (or the user, one question) two things:
- Topic type โ is this about a product/service, a person, or a topic/idea?
Map to:
product ยท service ยท personal-brand ยท educational ยท
brand-awareness ยท event ยท announcement ยท community-cause ยท
entertainment ยท recruitment.
- Visual mode โ who/what appears?
person ยท product-only ยท mixed ยท
faceless ยท mascot ยท ui-screens.
Look the pair up in the Requirements Matrix to get the required inputs.
If it doesn't fit any type, ask once: "Is this about a specific
product/service, a person, or a topic/idea?" Default to educational.
STEP 2: Check project context
Never assume which project โ and never silently create a new one. List what
exists and match the request against it first:
ls projects/ 2>/dev/null
ls projects/{name}/ 2>/dev/null
- Request relates to an existing project (same business, product line, brand,
or audience โ read its
project.md to judge, don't match on name alone) โ
ask: "This looks like it belongs to projects/{existing}/ โ continue
there? You'd inherit its brand, characters, voices, and style refs, so
everything stays consistent." Only branch a new project if the user says so.
- Genuinely new/unrelated โ ask permission before creating:
"No existing project fits โ create
projects/{new-name}/? (or: one-off in
minimal mode, no brand context)" Don't scaffold folders until they confirm.
- No projects at all? Offer: (a) create one now (
/plan-content sets up the
folder + templates), or (b) minimal mode โ a quick one-off with no brand
context. If minimal mode, say so explicitly and skip to STEP 5.
- Project exists? Read:
projects/{name}/templates/project.md โ business, audience, pain points, offer, CTA
projects/{name}/templates/brand.md โ colors, tone, restrictions, aesthetic
Note any empty required fields (see the project template checklist).
Required-context rule by topic:
product / event(product) โ product info required
service โ offer + service area required (no object)
personal-brand โ who the person is required
educational โ topic + key points + source of truth required (don't hallucinate facts)
- brand fields โ required for everything except minimal mode
If required project/brand fields are empty โ ask the user, fill the template,
save it. Never fake stats, testimonials, press, or prices.
STEP 3: Load the asset registry
node workflows/cli.cjs loadAssetConfig '["{name}"]'
node workflows/cli.cjs validateAssets '["{name}"]'
STEP 4: Resolve required assets (provide / generate / reuse)
For each required ๐ผ๏ธ/๐๏ธ asset from the matrix (character, product, logo, voiceโฆ):
node workflows/cli.cjs resolveAsset '["{name}","char-founder"]'
r.ok === true โ REUSE. Pass r.existing[...] as reference images. Do not re-describe.
r.ok === false โ resolve it:
โโโ User has a file โ PROVIDE: get path โ validate (exists, type, resolution)
โ โ copy to assets/<type>/ โ registerAsset(...)
โโโ No file โ GENERATE: ask the asset's DETAIL questions
โ generate (generateSingleImage / character sheet / etc.)
โ STOP, show it, get approval
โ save to assets/<type>/ โ registerAsset(..., locked:true)
Detail questions per asset type are in content-requirements.md ยง4. For a
character that must stay consistent across many pieces, generate a
character model sheet โ ONE image with a full-body turnaround (front / 3โ4 /
side / back), face close-up, half-body shot and costume detail crops
(generateCharacterSheet, default layout) โ and lock it. One file = one
reference slot in every later generation.
Registering a new asset (saves the path for reuse)
node workflows/cli.cjs registerAsset '["{name}","characters",{"id":"char-founder","label":"Founder โ Sarah","description":"โฆlocked physical descriptionโฆ","source":"generated","status":"ready","locked":true,"files":{"front":"assets/characters/sarah-front.png","three_quarter":"assets/characters/sarah-34.png"},"linked_voice":"voice-sarah"},{"date":"<today ISO>"}]'
Products โ 'products', logos โ 'logos', voices โ 'voices',
locations โ 'locations', music โ 'music', style refs โ 'style_references'.
Always pass real, existing relative paths. Files live under
projects/{name}/assets/; registry paths are relative to the project root.
Style references (taste, not identity) โ check registry, then ask ONCE
Identity assets keep the SUBJECT consistent; style references keep the LOOK and
VOICE consistent. Before writing any prompt, script, or caption:
node workflows/cli.cjs resolveAsset '["{name}","style-main"]'
- Registered style refs exist โ USE them: pass image files as additional
reference images (state the ref's role: "style only, not subject"), and mirror
the
what_we_like notes in prompts/copy. Don't improvise a look the project
already has.
- None registered โ check the drop inbox first:
ls projects/{name}/style-samples/
(video/image/caption/audio examples the user added by hand, with notes.md).
Found something relevant โ confirm with the user, then PROMOTE it: copy to
assets/style/, register it (style_references, what_we_like from notes.md).
- Inbox empty too โ ask ONCE per project:
"Do you have examples of the look/voice you like โ past posts or thumbnails,
captions or scripts that performed well, or a video to emulate? (paste text,
give file paths/links, or say 'none')"
- Images โ copy to
assets/style/ โ registerAsset('{name}','style_references',...)
with a what_we_like note.
- Copy examples (captions/scripts) โ save to
assets/style/copy-examples.md,
register the same way โ the write-copy skill reads it.
- A reference video/link โ route through the
analyze-video skill first.
- "none" โ note it in brand.md so no one re-asks every piece.
STEP 5: Apply the edge-case checklist
Scan content-requirements.md ยง5 and handle anything that applies. The high-value ones:
- Third-party source material (RULES 10) โ if the user hands you a video,
image, song, or ad they did not create โ to edit, dub, re-voice, face-swap,
restyle, or republish โ ASK them to confirm they own it or have written
permission to use AND modify it before generating. Reselling a product โ owning
its marketing videos. If it's clearly stolen/infringing, decline and say why.
Client work? Advise a written warranty-of-rights + indemnity, and deliver the
file rather than publishing it.
- Real person / public figure / minors โ consent +
person_generation policy;
refuse celebrity/competitor likeness; never clone a real face/voice or put words
in their mouth without consent.
- Pre-launch product with no photo โ mockup, marked
source: mockup.
- Sensitive claims (health/finance/legal) โ enforce
restrictions, no
"guaranteed/cure/risk-free".
- Non-English / Myanmar script โ confirm font/script support.
- Series/campaign โ lock character + location + voice + music once; every
piece references the same ids. ALSO lock a Style Block
(
templates/style-block.template.md โ projects/{name}/templates/style-block.md,
registered as style_references, locked) โ it gets prepended to every prompt of
the series so the LOOK stays constant, not just the subjects.
- "Just do it" โ still resolve required inputs; state every assumption.
STEP 5b: Set a budget cap
Ask once per project (see the cost-guard skill) so no run silently overspends:
"What's your budget for this project? I'll warn before going over."
node workflows/cli.cjs setBudgetCap '["{name}",50]'
Before any expensive run, checkBudget(...) the estimate; after each generation,
recordCost(...).
STEP 6: Confirm readiness
Show the user a readiness summary, then wait for go:
โ
PRE-FLIGHT โ {project}
Topic: {topicType} Visual: {visualMode}
Project brief: complete (or: missing {fields})
Brand: loaded (or: minimal mode)
Assets ready:
โ product prod-bottle (2 refs)
โ character char-founder (3 refs, locked)
โ voice voice-sarah (Kore, friendly)
โ logo โ none (end card will be skipped)
Budget: $12.50 / $50.00 spent (remaining $37.50)
Warnings: {validation warnings, if any}
Ready to {plan / generate}. Proceed? (yes / adjust)
On yes โ hand off to /plan-content (for a plan) or the matching generate
skill (/generate-video, /generate-image, /generate-voiceover,
/generate-music), which now reuse the registered assets instead of asking again.
Generating an expensive asset? Preview cheaply first (preview-pick), QA the preview
(qa-review), then commit โ and recordCost the spend.
Quick reference โ asset registry API
| Function | Purpose |
|---|
loadAssetConfig(name) | Read config/assets.yaml (empty valid config if absent) |
resolveAsset(cfg, id) | { ok, existing[], missing[] } โ files checked on disk |
findAsset(cfg, id) | Locate an asset across collections |
registerAsset(name, collection, asset, { date }) | Upsert + save (returns WorkflowResult) |
validateAssets(cfg) | { ok, issues[] } โ dup ids, missing files, broken voice links, consent |
pendingAssets(cfg) | Ids still needs-generation / placeholder |