AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Hero

skill-qinghonglin-data2story-skill-hero · by QinghongLin

Craft the COVER — the one animated <video> hero that opens the page above the headline, built from a Scout-verified still (or an abstract generated still) via a deterministic source ladder. The cover is animated by DEFAULT; a static <img> is only the recorded last rung. Owns the hero video + its static furniture; the Interaction Engineer owns the pick-a-side overlay, the Cinematographer stages th…

No reviews yet
0 installs
26 views
0.0% view→install

Install

$ agentstack add skill-qinghonglin-data2story-skill-hero

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-qinghonglin-data2story-skill-hero)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
3mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Hero? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Hero

> Premium-profile stage. The orchestrator runs the Hero only in the premium profile; in fast the Designer's static cover image is used instead. The "animated cover is the default, every run has one" rules below apply within premium.

Your job is the cover — the first thing the reader sees, before the headline, before any prose. The cover is the most load-bearing detail of the whole page: it is the hook. A crafted animated cover is the DEFAULT — you walk a deterministic source ladder and the cover ends up a short muted ` loop on every rung but the last; a static ` cover is only the recorded final fallback when every animation rung degraded.

You own the hero video + its static furniture (headline band, kicker, credit, decorative monogram/chips/particles/scrim). You do NOT own the pick-a-side interactive overlay — that is the Interaction Engineer's int_01. You do NOT redo the scroll background — the Cinematographer stages your cover as the first cinematic scene (cin_00). You realize the Designer's content.hero_strategy as a rendered, verifiable cover.

Setup

  • PROJECT_DIR = first argument; SKILL_DIR = the directory containing this SKILL.md (.../skills/data2story-pro/hero).
  • Read: editor.json (interactives.hero — does the centerpiece front-load on the teaser?), scout.json (verified sct_ stills / clips), designer.json (content.hero_strategy + any registered des_ stills), interaction.json (the int_01 the centerpiece resolved to), and the shared [../references/topic_profile.json](../references/topic_profile.json) (is_visual / tags — same classifier the Detective resolved).
  • Reuse the Designer's media scripts: image2video (SKILL_DIR/../designer/scripts/openrouter-image2video/scripts/generate_video_from_image.py), text2image (.../openrouter-text2image/...), and optimize_assets.py (SKILL_DIR/../designer/scripts/optimize_assets.py). Generation routes through OpenRouter (OPENROUTER_API_KEY must be set).
  • Read [references/hero_recipes.json](references/hero_recipes.json) (the source ladder + the winning-pattern build recipe + the IP record) and [references/schema.json](references/schema.json) (the hero.json shape) before rendering.
  • Output: PROJECT_DIR/hero.json + assets → PROJECT_DIR/assets/teaser.webm + teaser_web.mp4 + teaser.jpg (poster). The hero IS the teaser section.

When to run

Always — every run has exactly one cover. There is no "skip the hero" path: the floor of the ladder (an abstract generated still, animated) is always available, so even a sober computational topic with no star entity gets a moving cover. The only thing the ladder decides is which source feeds the cover, never whether there is one. (A genuinely abstract topic still gets a cover; it is just an atmospheric/abstract one, often the interactive rung.)

Step 1 — Resolve the source (the deterministic ladder)

Walk the rungs in [references/hero_recipes.json](references/hero_recipes.json) source_ladder and take the first that resolves — this is deterministic, not a free pick. Record the chosen rung in meta.source_ladder_rung + a one-line meta.why:

  1. Interactive-hero passthrough — if editor.json.interactives.hero is non-null AND its section == "teaser", the centerpiece interaction is the Interaction Engineer's int_01. Render the animated backdrop behind it (descend rungs 1-4 for the still/motion) and yield the click surface: set hero.interactive_overlay_ref = "int_01". You own the video + static furniture; the Interaction Engineer owns the pick-a-side overlay.
  2. Scout real still (no public figure)image2video the still into a cinemagraph; default Veo is fine for non-faces.
  3. Recognizable real PUBLIC FIGURE, WITH a fetched identity-verified photoimage2video --model kwaivgi/kling-v3.0-std (the one faces-safe model — Veo/Wan deterministically refuse real faces, code 15236754). This is allowed-with-conditions, not banned: the face is held enough to avoid warping, but subtle natural motion IS permitted (slight head/body sway, a blink) on top of the moving atmosphere/lighting. Warp-quality guard: reject any candidate where the face distorts → fall back to ffmpeg Ken-Burns + boomerang on the same still (faces stay original pixels). Set subject_is_real_public_figure:true + a proportionate AI-motion-added disclosure (a small caption that the motion was added / it is not real footage — lightweight, not a banner). The thing that stays disallowed is generating the face from scratch (photoreal OR illustration) — the still here is always FETCHED.
  4. License-clean STOCK clip → a Scout sct_ kind:"video". R5 constraint: stock video isn't fetched today (fetch_stock.py is images-only), so restrict this rung to a Commons/Openverse CC clip or a verified oEmbed — not a paid stock-video API. A copyrighted self-hosted clip is a des_ publish_blocker (see the IP record).
  5. Abstract/atmospheric stilltext2image a no-real-referent still (mood/texture/metaphor), then image2video it. The always-available floor that keeps even a sober cover moving.
  6. Static fallback (only) → ship the poster as a static `: kind:"image", assets.videowebm/mp4 = null, with a recorded mediablocker. The ONLY sanctioned static-cover path — reachable only when every animation rung degraded (image2video printed FALLBACKUSED=staticposter / VIDEOUNUSED=1`, or no clip/still could be produced).

The real-subject guard from the Designer doctrine still holds: a recognizable real subject is a FETCHED verified still (Scout sct_ / Detective ref_), never a generated one; image2video of a real face is only ever a held cinemagraph (subtle motion within the warp guard) via the faces-safe model with proportionate disclosure. The model facts (which models refuse real faces, the 4/6/8 duration constraint, the upscale recipe) live in [references/hero_recipes.json](references/hero_recipes.json) ip_record (and the Designer's video_pipeline.json).

Honor topic_profile.ai_face_policy (real-person subjects). When the Detective resolved an ai_face_policy (the topic involves real people — see [../detective/SKILL.md](../detective/SKILL.md) and [../references/topic_profile.json](../references/topic_profile.json)), it governs the cover. The default is animate the real photo: a real-person subject WITH a fetched, identity-verified photo → rung 2 (the subtle cinemagraph + warp guard + proportionate disclosure above). AI face is allowed-with-conditions, never blanket-banned here. When the real-person subject has NO usable verified photo (no_photo_fallback:"theme_first_no_person"), do NOT generate the person — neither a photoreal fake nor an illustration of the person — and skip rung 2; instead take a THEME-FIRST non-person cover, in this order, stopping at the first that expresses the theme: (a) real scene/object media — license-clean real imagery of the setting/objects/symbols (NOT the person), animated per rung 1/3; (b) data-as-cover — the story's signature visualization animated (the data IS the theme); (c) conceptual / typographic cover; (d) abstract atmospheric (generative, non-figurative) via rung 4 — last resort only. Theme-first means: if real scene/object media or the data can carry the theme, do not drop to the abstract floor. Sensitivity is NOT a hard gate — animate regardless of context and optimize for quality; if ai_face_policy.sensitivity_advisory is set (deceased persons, minors, criminal allegations), carry it through as a one-line note for the Critic — it never blocks the build.

Step 2 — Render + optimize

  • Animate with a motion-only prompt (describe only what moves: flags ripple, smoke drifts, floodlights flicker; subject and faces held still, no camera shake). The cover must read as ALIVE at a glance — never near-still. Require a clearly-visible PRIMARY motion + 1-2 strong SECONDARY motions. GOOD: the canonical hero_v5 — a player standoff with national flags waving boldly behind (subjects held, atmosphere unmistakably moving). BAD: the dusk sky and thin clouds drift slowly, a faint pulse over an otherwise-static stadium (a subtle cinemagraph that reads as a still — the weak current output, a richness fail). When the subject itself must stay still (building / landscape / held face), require a bold animated foreground: rippling/waving flags, a surging crowd, rising smoke/steam/embers, a sweeping floodlight, strong sky parallax. Motion is IN-PLACE / cyclic (wheels spinning, flags waving, smoke rising, crowd surging, sky drifting) — never translate the subject across/off the frame (a train driving off-screen / a rocket flying out of frame cannot loop seamlessly). Pick the concrete motion concept from [references/hero_recipes.json](references/hero_recipes.json) topic_motion_library (topic-adaptive; free choice within the guides). Keep the source still as the ` so the cover degrades to frame-0. Duration is one of 4 | 6 | 8` (the OpenRouter video endpoint accepts no other).
  • Seamless loop (hard): post-process every hero clip into a clean loop so head meets tail invisibly — a raw model clip almost always jumps. Default = ffmpeg boomerang/ping-pong (forward then reversed: [0]reverse[r];[0][r]concat, inherently seamless); alt = crossfade the loop point (xfade, blend last ~0.5s into first ~0.5s) when reverse looks unnatural. ffmpeg is not on PATH — resolve it via the imageio-ffmpeg wheel (python3 -c "import imageio_ffmpeg,sys;sys.stdout.write(imageio_ffmpeg.get_ffmpeg_exe())"), exactly as optimize_assets.py does. Record the technique in hero.json as loop ("boomerang" | "xfade" | "native"); the on-page ` keeps the loop` attribute. (The ffmpeg Ken-Burns fallback is already a boomerang.)
  • After the render, always run python3 SKILL_DIR/../designer/scripts/optimize_assets.py PROJECT_DIR/assets/ — it writes the VP9 .webm + H.264 _web.mp4 + poster and repoints filenames. **Web-weight cover budget: (or a on the rung-5 fallback), **wrapped in .cin-stage** — cinematic-ON it is the cin_00 layer of the live cinematic stage; cinematic-OFF a degenerate that still paints the poster as backdrop. Either way the existing isDecorative() (which excludes el.closest('.cin-stage')`) auto-excludes the cover from Verify.
  • A reduced-motion ` fallback (the poster) is always in the DOM; under prefers-reduced-motion / JS-off it shows and autoplay never fires. The keeps autoplay muted loop playsinline` (those attributes are correct — do not change them).
  • Autoplay-retry (additive over the attributes above): muted-autoplay can be blocked on iOS Low-Power / some mobile, leaving the cover frozen on the poster. So the Programmer also wires a JS video.play() retry on the first user gesture — a one-time handler on the broad first-interaction set (mirror the BGM sndKick multi-event pattern: pointerdown/touchstart/keydown/click + scroll/wheel/touchmove), removed only on a resolved .play() promise — plus a visible tap-to-play affordance (a centred play glyph over the cover) shown if .play() rejects. Skip the retry under prefers-reduced-motion.
  • A single .teaser overlay carries data-des="des_hero_video" — the cover's one Verify hit. Decorative furniture (VS monogram, FC-26-style chips, particle canvas, headline band, scrim) is pointer-events:none with no data-*; on rung 0 the interactive halves are role="link" (off the verify inner-interactive allow-list).
  • Reuse data-des="des_hero_video"NO new provenance prefix is minted.

The winning-pattern build recipe (the flagship cover: held-subject cinemagraph + transparent furniture overlay + the cinematic-stage handoff) is in [references/hero_recipes.json](references/hero_recipes.json) build_recipe.

Output — hero.json

Full schema in [references/schema.json](references/schema.json). hero is a single object (exactly one cover). Reuses data-des="des_hero_video" — no new prefix:

{
  "meta": { "role": "hero", "version": "1.0", "source_ladder_rung": 2, "why": "the real star is the cover subject; Kling animates the fetched still" },
  "hero": {
    "id": "des_hero_video",
    "kind": "video",
    "backs": "teaser",
    "subject_is_real_public_figure": true,
    "source": {
      "origin": "scout_real_figure", "still_ref": "sct_03",
      "model": "kwaivgi/kling-v3.0-std", "tool": "image2video",
      "prompt": "flags ripple, floodlights flicker; faces and subject held still, no camera shake",
      "duration": 6, "fallback_used": null
    },
    "loop": "boomerang",
    "assets": { "video_webm": "assets/teaser.webm", "video_mp4": "assets/teaser_web.mp4", "poster": "assets/teaser.jpg" },
    "reduced_motion_fallback": "assets/teaser.jpg",
    "furniture": { "headline_band": "Who wins 2026?", "kicker": "World Cup forecast",
                   "credit_line": "Photo:  / Wikimedia Commons (CC BY-SA 4.0) — identity verified; motion added",
                   "decorative": ["VS monogram", "particle canvas", "scrim"] },
    "interactive_overlay_ref": "int_01",
    "verify": { "hit_target": ".teaser", "data_attr": "data-des", "id": "des_hero_video", "class_marker": "teaser" },
    "disclosure": "Fetched verified still; motion = a camera move on the still (not AI video of a real person).",
    "publish_blocker": false,
    "ip_record_ref": "references/hero_recipes.json#ip_record"
  }
}

Team coordination

  • Interaction Engineer owns the pick-a-side overlay (int_01) when the Editor places the centerpiece on the teaser (rung 0); the Hero owns the video + static furniture and references it via interactive_overlay_ref. The two coexist — the overlay's halves are role="link", off the verify inner-interactive allow-list.
  • Cinematographer consumes the cover as cin_00 via [../cinematographer/references/cinematic_recipes.json](../cinematographer/references/cinematic_recipes.json) hero_as_cin_00_continuous_backdrop — the same crossfade engine carries the cover seamlessly into cin_01. The hero's Verify hit stays on the .teaser overlay (data-des=des_hero_video), NOT on cin_00.
  • Designer hands over content.hero_strategy (the rung intent) + any registered des_/sct_ stills; the Hero realizes that strategy as the rendered, verifiable cover. The animated cover is the default — a static cover is only the recorded last rung.
  • Programmer builds the .cin-stage-wrapped `/ + the single .teaser hit + the reduced-motion fallback + the autoplay-retry per Step 3; **Inspector validate.py Section 12** asserts the assets resolve on disk, the poster + reduced-motion are present, the .teaser carries data-des, the video sits inside a .cin-stage wrapper, **hero.json carries a loop` marker, and the page wires an autoplay-retry** (the last two WARN by default, ERROR on a visual topic).

References

  • [references/schema.json](references/schema.json) — the full hero.json shape + field notes.
  • [references/hero_recipes.json](references/hero_recipes.json) — the source ladder, the winning-pattern build recipe, and the IP record (Veo/Wan refuse real faces code 15236754; Kling works; the fallback ladder; the AI-likeness disclosure; the stock-clip publish-gate).
  • [../cinematographer/references/cinematic_recipes.json](../cinematographer/references/cinematic_recipes.json) — hero_as_cin_00_continuous_backdrop, the seamless hero→scroll handoff.
  • [../designer/references/video_pipeline.json](../designer/references/video_pipeline.json) — the still→motion mechanics (cinemagraph pipeline, the faces table, the upscale recipe, disclosure).
  • [../references/topic_profile.json](../references/topic_profile.json) — the

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.