answer-ads-questions
Answer questions about a brand's Meta ads (spend, results, which ad is winning, is it paused,…
Replace an existing video's opening with a supplied clip or free kinetic text hook while retaining and verifying every original body frame, audio, captions and ending. Use for surgical hook tests rather than regenerating the complete ad.
$ npx -y skills add gooseworks-ai/goose-skills --skill render-hook-replacement --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/render-hook-replacementContext preview
The summary Claude sees to decide when to auto-load this skill.
Replace an existing video's opening with a supplied clip or free kinetic text hook while retaining and verifying every original body frame, audio, captions and ending. Use for surgical hook tests rather than regenerating the complete ad.
name: render-hook-replacement description: Replace an existing video's opening with a supplied clip or free kinetic text hook while retaining and verifying every original body frame, audio, captions and ending. Use for surgical hook tests rather than regenerating the complete ad. owner: team status: active version: "1.0.1" created: 2026-10-05 updated: 2026-10-05 level: atom category: editing variant-of: null tags: [video, editing, hooks]
Replace only the opening of a selected video. The rest comes from the original, including its ending and burned captions. A supplied hook uses free local assembly; short text can become a free animated card. Generated footage or voice is optional and requires a separate estimate and approval.
The output is a complete MP4 and an edit manifest identifying the exact original, cut, duration change and preservation checks. It stays **needs review** until the finished video has been watched and its sound checked.
---
Perform one hard-cut opening replacement with immutable source identity and decoded retained-body verification. There is no fixed three-second boundary, mandatory creator, new music, body regeneration, whole-video caption pass or automatic final selection. Read [the editing guide](references/hook-replacement.md).
themselves before any paid step. Supplied-clip execution uses only Python stdlib.
relative to that config, so a fetched package works outside the author's checkout.
`source.sha256` refuses changed bytes; `project_id`/`render_id` are opaque caller identifiers preserved in the manifest. Compute and freeze the hash at intake.
choose a measured word/silence boundary. No silent correction of that boundary.
Or `hook.text`, `duration_sec`, `font_path` and optional `#RRGGBB` colors. Text needs Pillow (part of the video toolchain) and an explicitly supplied licensed font.
containing `source_sha256` and `words`. A cut through a measured word fails.
Complete retained cues shift by the measured duration delta. A cue crossing the cut requires measured words, so removed opening copy does not linger over the body.
are protected from overwrite. The default manifest is `<output>.manifest.json`.
The original must be CFR, unrotated square-pixel 8-bit yuv420p with zero video start time. Other sources fail before assembly. If normalization is necessary, make it a separately approved source version and freeze that version; do not quietly remaster the selected original. Audio is optional. An original audio/container tail more than 2ms beyond the last video frame also blocks; make a reviewed source version with a final-frame hold before editing. The renderer never trims that narration/music tail and calls it preserved.
1. Watch the exact original and confirm source identity, hook boundary and selected replacement. Keep the original file read-only. Ask only for missing choices. 2. Probe source/hook, validate SHA256, measured words and captions before encoding. Before creating any new hook, run `python3 scripts/replace_hook.py --preflight --config /path/to/source-config.json`. This needs only source/cut and optional words/captions, verifies runtime encoders and supported source shape, and writes no media or paid job. Generated hooks are separate work: read the chosen generation capability, quote only the required new opening, obtain approval, then bind its finished clip here. 3. Run `python3 scripts/replace_hook.py --config /path/to/config.json`. The script normalizes only the hook geometry/fps; joins original body at normal speed; uses browser-compatible High-profile libx264 CRF 12; retains original body audio with AAC 256k; shifts separate captions; and checks source integrity before publishing files. 4. Examine the manifest. All four required preservation booleans must be true. Every retained decoded video frame is compared with PSNR ≥45dB and identical frame count/order. Audio is compared at identical sample positions with normalized RMS error ≤0.08 and correlation ≥0.99 (silence uses absolute RMS error ≤0.0001). These are encode tolerances, not a listening verdict. 5. Watch the **actual complete output**, especially the join and final frame; listen to the hook/body join, narration/music and ending. Check the new hook copy and brand facts. Fix only the opening and re-run to a new path. Keep the result awaiting review until the review report names this output hash and source. Only after actual watch/audio/caption review, record `review:{status:'passed',source_sha256:<original hash>,output_sha256:<finished hash>,checked_at:<ISO datetime>}` alongside the passing quality report. Never recycle another output's review.
From a fresh package folder:
python3 scripts/make_demo.py --out-dir demo python3 scripts/replace_hook.py --config demo/config.json python3 -m unittest discover -s tests -v
The neutral fixture replaces 2.4s with 1.5s and retains the original body/end. `--font /path/to/licensed.ttf` adds burned captions to the fixture. Set `HOOK_TEST_FONT=/path/to/licensed.ttf` to test the optional kinetic text route too. The demo makes no network requests or paid calls. It is a timing fixture, not a customer ad or cat
Put your AI agent on the growth team. Research customers and competitors, analyze what is working, create the next campaign, and learn from the result.
Repo: gooseworks-ai/goose-skills
Answer questions about a brand's Meta ads (spend, results, which ad is winning, is it paused,…
Burned-in captions for a finished vertical video, three kinds. transcribe.py gets word…
Composite a generated creator track into a product layer, per beat — in the creator's zone on…
Generate an AI creator talking to camera, saying an approved script, as one continuous track…
Generate or edit an image via any FAL image model (nano-banana edit, gpt-image, flux, ...),…
Generate a single photoreal or designed image with OpenAI gpt-image via fal.ai. Supports…