character-consistency — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited character-consistency (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Generated clips drift. Ask the same model for the same person twice and you get cousins. This is the method that actually holds identity across a sequence, and it costs one extra image generation, not a custom model.
Each clip is generated independently. A text prompt — however detailed — does not pin a face. "A woman in her late twenties with shoulder-length brown hair" describes thousands of people and you will meet several of them.
clip 1 ─ generate ─► extract last frame ─► upload_image
│
clip 2 ◄─ generate from that frame as the first frame
│
clip 3 ◄─ …and so onIdentity holds perfectly, because clip 2 does not re-invent the person — it starts from a picture of them.
Any text-to-video model. This one establishes the person, the wardrobe and the room, so spend your prompt effort here.
generate_video { "model": "seedance-2.0-t2v", "prompt": "…", "duration": 5 }Download the MP4 and pull a frame with ffmpeg — late in the clip, where the pose has settled:
ffmpeg -ss 4.5 -i clip1.mp4 -frames:v 1 frame1.pngupload_image { "image_base64": "…" }generate_video {
"model": "seedance-2.0-frames",
"image_url": "<the uploaded frame>",
"prompt": "<what happens next>",
"duration": 5
}The *-frames models take the image as the literal first frame. seedance-2.0-frames is the quality option; seedance-2.0-fast-frames is cheaper and silent, which is fine for B-roll where nobody speaks.
This is the part that surprises people, and it cost us a render to learn.
If clip 1 ends on a tearful face and clip 2's prompt asks for a suspicious squint, you get a tearful squint. The first frame does not just pin the identity — it pins the emotion and the pose, and the prompt cannot override it.
To change expression or posture between clips:
frame from clip 1 ──► generate_image (new expression, frame as reference)
│
└──► generate_video *-frames from THATYou are generating a new keyframe of the same person wearing the new expression, then animating it. One extra image call, and the sequence works.
Product text mutates between shots unless it is in a reference image. Generate each shot's keyframe with generate_image using one product photo as the reference, then animate the keyframes. We have run four shots this way with the label correct in all four.
Rules that made the difference:
objects to juggle — bottles vanish, hands swap.
sequence.
If you want a finished ad rather than a sequence you assemble yourself, use create_ad_video — it handles the creator and product internally and returns one rendered MP4. This skill is for multi-clip work where you are cutting the clips together in your own editor.
does not work, and it is everyone's first attempt.
keyframe.
generate_video and generate_image call spends credits. quotefirst — it charges nothing and returns exactly what the call will cost.
sequence before the first one.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.