Output:
ffmpeg version 6.1.1-3ubuntu5 Copyright (c) 2000-2023 the FFmpeg developers
  built with gcc 13 (Ubuntu 13.2.0-23ubuntu3)
  configuration: --prefix=/usr --extra-version=3ubuntu5 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --disable-omx --enable-gnutls --enable-libaom --enable-libass --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libglslang --enable-libgme --enable-libgsm --enable-libharfbuzz --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-openal --enable-opencl --enable-opengl --disable-sndio --enable-libvpl --disable-libmfx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-ladspa --enable-libbluray --enable-libjack --enable-libpulse --enable-librabbitmq --enable-librist --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libx264 --enable-libzmq --enable-libzvbi --enable-lv2 --enable-sdl2 --enable-libplacebo --enable-librav1e --enable-pocketsphinx --enable-librsvg --enable-libjxl --enable-shared
  libavutil      58. 29.100 / 58. 29.100
  libavcodec     60. 31.102 / 60. 31.102
  libavformat    60. 16.100 / 60. 16.100
  libavdevice    60.  3.100 / 60.  3.100
  libavfilter     9. 12.100 /  9. 12.100
  libswscale      7.  5.100 /  7.  5.100
  libswresample   4. 12.100 /  4. 12.100
  libpostproc    57.  3.100 / 57.  3.100
Input #0, rawvideo, from 'fd:':
  Duration: N/A, start: 0.000000, bitrate: 1194393 kb/s
  Stream #0:0: Video: rawvideo (RGB[24] / 0x18424752), rgb24, 1080x1920, 1194393 kb/s, 24 tbr, 24 tbn
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (libx264))
[libx264 @ 0x63f97dec8480] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2 AVX512
[libx264 @ 0x63f97dec8480] profile High, level 4.0, 4:2:0, 8-bit
[libx264 @ 0x63f97dec8480] 264 - core 164 r3108 31e19f9 - H.264/MPEG-4 AVC codec - Copyleft 2003-2023 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=9 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=24 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=20.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to '/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/preview_v2_caption_safe/digital-red-flags-fake-invoice-payment-route-30s_preview_v2_caption_safe_silent.mp4':
  Metadata:
    encoder         : Lavf60.16.100
  Stream #0:0: Video: h264 (avc1 / 0x31637661), yuv420p(tv, progressive), 1080x1920, q=2-31, 24 fps, 12288 tbn
    Metadata:
      encoder         : Lavc60.31.102 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
frame=    0 fps=0.0 q=0.0 size=       0kB time=N/A bitrate=N/A speed=N/A
frame=    0 fps=0.0 q=0.0 size=       0kB time=N/A bitrate=N/A speed=N/A
frame=    0 fps=0.0 q=0.0 size=       0kB time=N/A bitrate=N/A speed=N/A
frame=    0 fps=0.0 q=0.0 size=       0kB time=N/A bitrate=N/A speed=N/A
frame=    0 fps=0.0 q=0.0 size=       0kB time=N/A bitrate=N/A speed=N/A
frame=    0 fps=0.0 q=0.0 size=       0kB time=N/A bitrate=N/A speed=N/A
frame=    7 fps=2.2 q=25.0 size=       0kB time=00:00:00.20 bitrate=   1.8kbits/s speed=0.0664x
frame=   18 fps=4.9 q=25.0 size=       0kB time=00:00:00.66 bitrate=   0.6kbits/s speed=0.183x
frame=   29 fps=7.0 q=25.0 size=       0kB time=00:00:01.12 bitrate=   0.3kbits/s speed=0.271x
frame=   40 fps=8.5 q=25.0 size=       0kB time=00:00:01.58 bitrate=   0.2kbits/s speed=0.338x
frame=   50 fps=9.6 q=25.0 size=       0kB time=00:00:02.00 bitrate=   0.2kbits/s speed=0.383x
frame=   60 fps= 10 q=25.0 size=       0kB time=00:00:02.41 bitrate=   0.2kbits/s speed=0.419x
frame=   70 fps= 11 q=25.0 size=       0kB time=00:00:02.83 bitrate=   0.1kbits/s speed=0.45x
frame=   80 fps= 12 q=25.0 size=       0kB time=00:00:03.25 bitrate=   0.1kbits/s speed=0.478x
frame=   92 fps= 13 q=25.0 size=       0kB time=00:00:03.70 bitrate=   0.1kbits/s speed=0.506x
frame=  105 fps= 13 q=25.0 size=       0kB time=00:00:04.25 bitrate=   0.1kbits/s speed=0.542x
frame=  116 fps= 14 q=25.0 size=       0kB time=00:00:04.75 bitrate=   0.1kbits/s speed=0.568x
frame=  129 fps= 14 q=25.0 size=       0kB time=00:00:05.25 bitrate=   0.1kbits/s speed=0.59x
frame=  139 fps= 15 q=25.0 size=       0kB time=00:00:05.66 bitrate=   0.1kbits/s speed= 0.6x
frame=  149 fps= 15 q=25.0 size=       0kB time=00:00:06.08 bitrate=   0.1kbits/s speed=0.609x
frame=  159 fps= 15 q=25.0 size=       0kB time=00:00:06.50 bitrate=   0.1kbits/s speed=0.618x
frame=  169 fps= 15 q=25.0 size=       0kB time=00:00:06.91 bitrate=   0.1kbits/s speed=0.626x
frame=  178 fps= 15 q=25.0 size=       0kB time=00:00:07.33 bitrate=   0.1kbits/s speed=0.634x
frame=  189 fps= 16 q=25.0 size=       0kB time=00:00:07.75 bitrate=   0.0kbits/s speed=0.641x
frame=  200 fps= 16 q=25.0 size=       0kB time=00:00:08.25 bitrate=   0.0kbits/s speed=0.654x
frame=  211 fps= 16 q=25.0 size=       0kB time=00:00:08.70 bitrate=   0.0kbits/s speed=0.662x
frame=  222 fps= 16 q=25.0 size=       0kB time=00:00:09.16 bitrate=   0.0kbits/s speed=0.671x
frame=  234 fps= 17 q=25.0 size=       0kB time=00:00:09.66 bitrate=   0.0kbits/s speed=0.682x
frame=  244 fps= 17 q=25.0 size=       0kB time=00:00:10.08 bitrate=   0.0kbits/s speed=0.685x
frame=  254 fps= 17 q=25.0 size=       0kB time=00:00:10.50 bitrate=   0.0kbits/s speed=0.689x
frame=  264 fps= 17 q=25.0 size=       0kB time=00:00:10.91 bitrate=   0.0kbits/s speed=0.692x
frame=  274 fps= 17 q=25.0 size=       0kB time=00:00:11.33 bitrate=   0.0kbits/s speed=0.695x
frame=  284 fps= 17 q=25.0 size=       0kB time=00:00:11.75 bitrate=   0.0kbits/s speed=0.699x
frame=  296 fps= 17 q=25.0 size=     256kB time=00:00:12.25 bitrate= 171.2kbits/s speed=0.706x
frame=  307 fps= 17 q=25.0 size=     256kB time=00:00:12.70 bitrate= 165.1kbits/s speed=0.711x
frame=  317 fps= 17 q=25.0 size=     256kB time=00:00:13.12 bitrate= 159.8kbits/s speed=0.713x
frame=  326 fps= 17 q=25.0 size=     256kB time=00:00:13.50 bitrate= 155.4kbits/s speed=0.713x
frame=  336 fps= 17 q=25.0 size=     256kB time=00:00:13.91 bitrate= 150.7kbits/s speed=0.715x
frame=  347 fps= 17 q=25.0 size=     256kB time=00:00:14.33 bitrate= 146.3kbits/s speed=0.717x
frame=  356 fps= 17 q=25.0 size=     256kB time=00:00:14.70 bitrate= 142.6kbits/s speed=0.717x
frame=  364 fps= 17 q=25.0 size=     256kB time=00:00:15.08 bitrate= 139.1kbits/s speed=0.717x
frame=  373 fps= 17 q=25.0 size=     256kB time=00:00:15.45 bitrate= 135.7kbits/s speed=0.716x
frame=  382 fps= 17 q=25.0 size=     256kB time=00:00:15.83 bitrate= 132.5kbits/s speed=0.716x
frame=  391 fps= 17 q=25.0 size=     256kB time=00:00:16.20 bitrate= 129.4kbits/s speed=0.715x
frame=  399 fps= 17 q=25.0 size=     256kB time=00:00:16.54 bitrate= 126.8kbits/s speed=0.713x
frame=  408 fps= 17 q=25.0 size=     256kB time=00:00:16.91 bitrate= 124.0kbits/s speed=0.712x
frame=  416 fps= 17 q=25.0 size=     256kB time=00:00:17.25 bitrate= 121.6kbits/s speed=0.711x
frame=  426 fps= 17 q=25.0 size=     256kB time=00:00:17.66 bitrate= 118.7kbits/s speed=0.713x
frame=  437 fps= 17 q=25.0 size=     256kB time=00:00:18.12 bitrate= 115.7kbits/s speed=0.716x
frame=  448 fps= 17 q=25.0 size=     256kB time=00:00:18.58 bitrate= 112.9kbits/s speed=0.719x
frame=  458 fps= 17 q=25.0 size=     256kB time=00:00:19.00 bitrate= 110.4kbits/s speed=0.72x
frame=  467 fps= 17 q=25.0 size=     256kB time=00:00:19.37 bitrate= 108.3kbits/s speed=0.721x
frame=  476 fps= 17 q=25.0 size=     256kB time=00:00:19.75 bitrate= 106.2kbits/s speed=0.721x
frame=  485 fps= 17 q=25.0 size=     256kB time=00:00:20.12 bitrate= 104.2kbits/s speed=0.721x
frame=  494 fps= 17 q=25.0 size=     256kB time=00:00:20.50 bitrate= 102.3kbits/s speed=0.721x
frame=  504 fps= 17 q=25.0 size=     512kB time=00:00:20.91 bitrate= 200.5kbits/s speed=0.722x
frame=  515 fps= 17 q=25.0 size=     512kB time=00:00:21.33 bitrate= 196.6kbits/s speed=0.724x
frame=  526 fps= 18 q=25.0 size=     512kB time=00:00:21.79 bitrate= 192.5kbits/s speed=0.726x
frame=  535 fps= 17 q=25.0 size=     512kB time=00:00:22.20 bitrate= 188.9kbits/s speed=0.726x
frame=  545 fps= 18 q=25.0 size=     512kB time=00:00:22.58 bitrate= 185.7kbits/s speed=0.726x
frame=  553 fps= 17 q=25.0 size=     512kB time=00:00:22.95 bitrate= 182.7kbits/s speed=0.725x
frame=  562 fps= 17 q=25.0 size=     512kB time=00:00:23.33 bitrate= 179.8kbits/s speed=0.725x
frame=  571 fps= 17 q=25.0 size=     512kB time=00:00:23.70 bitrate= 176.9kbits/s speed=0.725x
frame=  579 fps= 17 q=25.0 size=     512kB time=00:00:24.04 bitrate= 174.5kbits/s speed=0.724x
frame=  588 fps= 17 q=25.0 size=     512kB time=00:00:24.41 bitrate= 171.8kbits/s speed=0.724x
frame=  599 fps= 17 q=25.0 size=     512kB time=00:00:24.87 bitrate= 168.6kbits/s speed=0.726x
frame=  611 fps= 18 q=25.0 size=     512kB time=00:00:25.37 bitrate= 165.3kbits/s speed=0.729x
frame=  623 fps= 18 q=25.0 size=     512kB time=00:00:25.87 bitrate= 162.1kbits/s speed=0.733x
frame=  636 fps= 18 q=25.0 size=     512kB time=00:00:26.41 bitrate= 158.8kbits/s speed=0.737x
frame=  649 fps= 18 q=25.0 size=     512kB time=00:00:26.95 bitrate= 155.6kbits/s speed=0.741x
frame=  662 fps= 18 q=25.0 size=     512kB time=00:00:27.50 bitrate= 152.5kbits/s speed=0.746x
frame=  675 fps= 18 q=25.0 size=     512kB time=00:00:28.04 bitrate= 149.6kbits/s speed=0.75x
frame=  688 fps= 18 q=25.0 size=     512kB time=00:00:28.58 bitrate= 146.8kbits/s speed=0.754x
[out#0/mp4 @ 0x63f97dec6d00] video:686kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 1.405928%
frame=  752 fps= 19 q=-1.0 Lsize=     695kB time=00:00:31.20 bitrate= 182.5kbits/s speed=0.809x
[libx264 @ 0x63f97dec8480] frame I:4     Avg QP:12.81  size: 46319
[libx264 @ 0x63f97dec8480] frame P:190   Avg QP:17.19  size:  2223
[libx264 @ 0x63f97dec8480] frame B:558   Avg QP:23.39  size:   168
[libx264 @ 0x63f97dec8480] consecutive B-frames:  1.1%  0.0%  0.0% 98.9%
[libx264 @ 0x63f97dec8480] mb I  I16..4: 70.8% 12.2% 17.0%
[libx264 @ 0x63f97dec8480] mb P  I16..4:  0.8%  0.1%  0.3%  P16..4:  0.5%  0.1%  0.1%  0.0%  0.0%    skip:98.2%
[libx264 @ 0x63f97dec8480] mb B  I16..4:  0.1%  0.0%  0.0%  B16..8:  1.6%  0.0%  0.0%  direct: 0.0%  skip:98.2%  L0:53.1% L1:46.9% BI: 0.0%
[libx264 @ 0x63f97dec8480] 8x8 transform intra:12.0% inter:14.2%
[libx264 @ 0x63f97dec8480] coded y,uvDC,uvAC intra: 11.0% 10.9% 8.2% inter: 0.0% 0.1% 0.1%
[libx264 @ 0x63f97dec8480] i16 v,h,dc,p: 26% 74%  0%  0%
[libx264 @ 0x63f97dec8480] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 37% 11% 52%  0%  0%  0%  0%  0%  0%
[libx264 @ 0x63f97dec8480] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 29% 47%  9%  2%  3%  3%  3%  2%  3%
[libx264 @ 0x63f97dec8480] i8c dc,h,v,p: 73% 15% 11%  1%
[libx264 @ 0x63f97dec8480] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 0x63f97dec8480] ref P L0: 69.6%  7.3% 18.5%  4.5%
[libx264 @ 0x63f97dec8480] ref B L0: 54.3% 45.1%  0.6%
[libx264 @ 0x63f97dec8480] ref B L1: 96.5%  3.5%
[libx264 @ 0x63f97dec8480] kb/s:179.12
ffmpeg version 6.1.1-3ubuntu5 Copyright (c) 2000-2023 the FFmpeg developers
  built with gcc 13 (Ubuntu 13.2.0-23ubuntu3)
  configuration: --prefix=/usr --extra-version=3ubuntu5 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --disable-omx --enable-gnutls --enable-libaom --enable-libass --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libglslang --enable-libgme --enable-libgsm --enable-libharfbuzz --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-openal --enable-opencl --enable-opengl --disable-sndio --enable-libvpl --disable-libmfx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-ladspa --enable-libbluray --enable-libjack --enable-libpulse --enable-librabbitmq --enable-librist --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libx264 --enable-libzmq --enable-libzvbi --enable-lv2 --enable-sdl2 --enable-libplacebo --enable-librav1e --enable-pocketsphinx --enable-librsvg --enable-libjxl --enable-shared
  libavutil      58. 29.100 / 58. 29.100
  libavcodec     60. 31.102 / 60. 31.102
  libavformat    60. 16.100 / 60. 16.100
  libavdevice    60.  3.100 / 60.  3.100
  libavfilter     9. 12.100 /  9. 12.100
  libswscale      7.  5.100 /  7.  5.100
  libswresample   4. 12.100 /  4. 12.100
  libpostproc    57.  3.100 / 57.  3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/preview_v2_caption_safe/digital-red-flags-fake-invoice-payment-route-30s_preview_v2_caption_safe_silent.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf60.16.100
  Duration: 00:00:31.33, start: 0.000000, bitrate: 181 kb/s
  Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 1080x1920, 179 kb/s, 24 fps, 24 tbr, 12288 tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
      encoder         : Lavc60.31.102 libx264
[mp3 @ 0x5f3663ac3640] Estimating duration from bitrate, this may be inaccurate
Input #1, mp3, from '/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/audio/voiceover.mp3':
  Duration: 00:00:31.32, start: 0.000000, bitrate: 48 kb/s
  Stream #1:0: Audio: mp3, 24000 Hz, mono, fltp, 48 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #1:0 -> #0:1 (mp3 (mp3float) -> aac (native))
Press [q] to stop, [?] for help
Output #0, mp4, to '/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/preview_v2_caption_safe/digital-red-flags-fake-invoice-payment-route-30s_preview_v2_caption_safe.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf60.16.100
  Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 1080x1920, q=2-31, 179 kb/s, 24 fps, 24 tbr, 12288 tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
      encoder         : Lavc60.31.102 libx264
  Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 24000 Hz, mono, fltp, 69 kb/s
    Metadata:
      encoder         : Lavc60.31.102 aac
size=       0kB time=N/A bitrate=N/A speed=N/A
[out#0/mp4 @ 0x5f3663a37280] video:686kB audio:242kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 2.071741%
size=     947kB time=00:00:31.31 bitrate= 247.6kbits/s speed=68.8x
[aac @ 0x5f3663b3abc0] Qavg: 18380.342
          "not",
          "proof"
        ],
        "start": 26.887,
        "end": 29.250000000000004
      },
      {
        "text": "It's the red flag",
        "words": [
          "It's",
          "the",
          "red",
          "flag"
        ],
        "start": 29.25,
        "end": 31.262
      }
    ]
  },
  "artifacts": {
    "preview_mp4": {
      "file_path": "/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/preview_v2_caption_safe/digital-red-flags-fake-invoice-payment-route-30s_preview_v2_caption_safe.mp4",
      "file_exists": true,
      "file_size": 969261,
      "sha256": "21be01acac26a3eb1d5b51597c9c3195f98169e9efd376e8ead0ca7d5c2f828d",
      "media_type": "video/mp4",
      "duration": 31.32,
      "resolution": "1080x1920",
      "fps": "24/1"
    },
    "silent_mp4": {
      "file_path": "/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/preview_v2_caption_safe/digital-red-flags-fake-invoice-payment-route-30s_preview_v2_caption_safe_silent.mp4",
      "file_exists": true,
      "file_size": 712114,
      "sha256": "2819f5672b990eeafe879ed66415446d46561c383afe137a6e3a7189f2939694",
      "media_type": "video/mp4",
      "duration": 31.333333,
      "resolution": "1080x1920",
      "fps": "24/1"
    },
    "qa_frame_sheet": {
      "file_path": "/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/preview_v2_caption_safe/digital-red-flags_caption_safe_contact_sheet_v2.jpg",
      "file_exists": true,
      "file_size": 230788,
      "sha256": "8da27f967519975d12807d117cccc9069139f1a7908016bdeb8e82b72b6db6c9",
      "media_type": "image/jpeg",
      "duration": "n/a",
      "resolution": "810x1440"
    },
    "subtitle_style_preview": {
      "file_path": "/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/preview_v2_caption_safe/digital-red-flags_subtitle_style_preview_v2.jpg",
      "file_exists": true,
      "file_size": 351467,
      "sha256": "4fba208eb302571ed110f19c3e7b6af3cea66c920b54c657a33b6efa76c2428d",
      "media_type": "image/jpeg",
      "duration": "n/a",
      "resolution": "1080x1920"
    }
  }
}
a9073f09b80b9b43eb421a4c523e05cf745374fbe7ef33176b082e988a220dfc  /tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/digital-red-flags-fake-invoice-payment-route-30s_manual_upload_v1.mp4
{
    "programs": [

    ],
    "streams": [
        {
            "index": 0,
            "codec_name": "h264",
            "codec_type": "video",
            "width": 1080,
            "height": 1920,
            "r_frame_rate": "24/1",
            "avg_frame_rate": "24/1"
        },
        {
            "index": 1,
            "codec_name": "aac",
            "codec_type": "audio",
            "sample_rate": "48000",
            "channels": 1,
            "r_frame_rate": "0/0",
            "avg_frame_rate": "0/0"
        }
    ],
    "format": {
        "duration": "31.400000"
    }
}


Question: Re-check final QA after switching email to reserved sample.test. Any captions clipped/off safe area, real logos/real bank data/QR codes/people, or major upload-blocking visual issues?


Image loaded into your context — you can see it natively now. Use your built-in vision to answer the user.

Question: Re-check final QA after switching email to reserved sample.test. Any captions clipped/off safe area, real logos/real bank data/QR codes/people, or major upload-blocking visual issues?


Explanation:
**Planning artifact creation**

I'm thinking about creating a package, and a Python script could be useful for that. I'll need to gather some artifact metadata and possibly a status file that indicates approval. It seems I'll be using functions like write_file and execute. I'll consider formats like JSON and CSV, but I want to avoid relying on platform APIs if possible. Okay, let's go ahead and generate everything!

from hermes_tools import terminal
script = r'''python - <<'PY'
from pathlib import Path
from PIL import Image
import json, csv, hashlib, os, subprocess
BASE=Path('/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s')
OUT=BASE/'manual_upload_v1'
OUT.mkdir(parents=True, exist_ok=True)
CID='digital-red-flags-fake-invoice-payment-route-30s'
FINAL=OUT/f'{CID}_manual_upload_v1.mp4'
HOOK='This invoice looks normal. The trap is not the logo — it’s the payment route.'
SCRIPT="This invoice looks normal. The trap is not the logo — it’s the payment route. Same layout. Same professional tone. Same urgency. But one thing changed: where the money goes. Before you pay, check three things: sender domain, urgency language, and payment route. If the route changed, don’t pay from the email. Verify through a second channel. Urgency is not proof. It’s the red flag."

def sha(p): return hashlib.sha256(Path(p).read_bytes()).hexdigest()
def probe_video(p):
    data=json.loads(subprocess.check_output(['ffprobe','-v','error','-show_entries','format=duration:stream=index,codec_type,codec_name,width,height,r_frame_rate,avg_frame_rate,sample_rate,channels','-of','json',str(p)], text=True))
    v=next(s for s in data['streams'] if s['codec_type']=='video')
    a=next((s for s in data['streams'] if s['codec_type']=='audio'), None)
    return {'duration': round(float(data['format']['duration']),3), 'resolution': f"{v['width']}x{v['height']}", 'fps': v.get('avg_frame_rate') or v.get('r_frame_rate'), 'video_codec': v.get('codec_name'), 'audio_codec': a.get('codec_name') if a else None, 'audio_sample_rate': a.get('sample_rate') if a else None, 'audio_channels': a.get('channels') if a else None}
def meta(path, media_type):
    p=Path(path); d={'file_path':str(p),'file_exists':p.exists(),'file_size':p.stat().st_size if p.exists() else 0,'sha256':sha(p) if p.exists() else None,'media_type':media_type}
    if p.exists() and media_type.startswith('video'):
        d.update(probe_video(p))
    elif p.exists() and media_type.startswith('image'):
        im=Image.open(p); d.update({'duration':'n/a','resolution':f'{im.width}x{im.height}'})
    else:
        d.update({'duration':'n/a','resolution':'n/a'})
    return d
status={
 'candidate_id':CID,
 'status':'approved_proof_short',
 'approved_version':'preview_v2_caption_safe',
 'manual_upload_version':'manual_upload_v1',
 'posted':False,
 'auto_upload_allowed':False,
 'platform_api_used':False,
 'approval_note':'APPROVED_PROOF_SHORT received. This approves proof short quality only, not automatic posting.'
}
(OUT/'candidate_status_manual_upload_v1.json').write_text(json.dumps(status,indent=2), encoding='utf-8')
posting_pack={
 'candidate_id':CID,
 'version':'manual_upload_v1',
 'manual_only':True,
 'auto_posting':False,
 'platform_api_used':False,
 'hook':HOOK,
 'safe_claim_language':['A common red flag is…','Before you pay…','Verify through a second channel.'],
 'platforms':{
  'youtube_shorts':{
   'title':'This Invoice Looks Normal — Check the Payment Route',
   'description':'A common red flag in invoice fraud is not the logo. It is where the payment route sends the money. Before you pay from an email, check the sender domain, urgency language, and payment route. If the route changed, verify through a second channel.\n\nGeneral safety awareness only — not financial or legal advice.',
   'hashtags':['#Shorts','#DigitalSafety','#InvoiceFraud','#CyberAwareness','#SmallBusiness'],
   'short_cta':'Save this before paying from an email.',
   'shorts_compatible':True,
   'notes':'31.4s vertical 1080x1920, safe for Shorts format.'
  },
  'tiktok':{
   'caption':'This invoice looks normal. A common red flag is the payment route. Before you pay, verify through a second channel.',
   'hashtags':['#DigitalSafety','#ScamAwareness','#InvoiceFraud','#WorkTips','#CyberSafety'],
   'cta':'Save this check for your next invoice.',
   'pinned_comment_suggestion':'Quick rule: if the payment route changed, do not pay from the email — verify through a second channel.'
  },
  'instagram_reels':{
   'caption':'A fake invoice does not need a fake logo. A common red flag is a changed payment route. Before you pay from an email, check sender, urgency, and route — then verify through a second channel.',
   'hashtags':['#DigitalSafety','#ScamAwareness','#InvoiceFraud','#BusinessSafety','#CyberTips'],
   'cta':'Save this rule and share it with someone who approves invoices.',
   'cover_text_suggestion':'Check the payment route'
  },
  'linkedin_manual':{
   'hook_line':'The risky part of an invoice is not always the logo.',
   'professional_caption':'A common invoice-fraud red flag is a changed payment route. The email may look professional, use familiar formatting, and create urgency — but the key question is where the money is being sent. Before paying from an email request, check the sender domain, urgency language, and payment route. If the route changed, verify through a second channel.\n\nGeneral safety awareness, not financial or legal advice.',
   'short_context':'Useful for teams that approve invoices, vendor payments, or urgent payment requests.',
   'cta':'Worth adding to your invoice approval checklist — especially for urgent email requests.',
   'hashtags':['#CyberSecurity','#FraudPrevention','#DigitalSafety','#BusinessOperations']
  }
 },
 'ai_disclosure':{
  'summary':'Video uses deterministic mockups and TTS. No realistic humans, no real companies, no real events, no realistic synthetic persons.',
  'platform_ai_disclosure_likely_required':False,
  'manual_review_note':'Because the video uses non-realistic deterministic UI/document mockups and TTS without realistic synthetic people or real-event depiction, platform synthetic media disclosure is probably not required. If a platform UI asks whether AI-assisted media was used, disclose conservatively according to that platform prompt.'
 },
 'claim_gate':{
  'claim_type':'general safety advice / low-to-medium risk',
  'result':'pass',
  'not_claimed':['Does not claim all fake invoices work this way','Does not claim three checks prevent all scams','Does not provide legal/financial advice'],
  'safe_phrasing':['A common red flag…','Before you pay…','Verify through a second channel.']
 }
}
(OUT/'manual_posting_pack_v1.json').write_text(json.dumps(posting_pack,indent=2), encoding='utf-8')
# Markdown pack for Telegram-readable copy
md=[]
md.append('# Manual Posting Pack — Digital Red Flags / Fake Invoice Payment Route\n')
for platform, data in posting_pack['platforms'].items():
    md.append(f'## {platform}\n')
    for k,v in data.items():
        if isinstance(v, list): v=' '.join(v)
        md.append(f'- {k}: {v}')
    md.append('')
md.append('## AI Disclosure / Synthetic Media\n')
for k,v in posting_pack['ai_disclosure'].items(): md.append(f'- {k}: {v}')
md.append('\n## Claim Gate\n- result: pass\n- claim type: general safety advice / low-to-medium risk\n')
(OUT/'manual_posting_pack_v1.md').write_text('\n'.join(md), encoding='utf-8')
fields=['platform','post_url','post_time','candidate_id','version','hook','topic_cluster','format_type','duration','caption_style','visual_style','cta_type','1h_views','1h_likes','1h_comments','1h_shares','1h_saves','1h_follows','24h_views','24h_completion_rate','24h_average_watch_time','24h_shares','24h_saves','24h_follows','72h_views','7d_views','notes','qualitative_comments','followup_decision']
def row(platform):
    return {k:'' for k in fields} | {'platform':platform,'candidate_id':CID,'version':'manual_upload_v1','hook':HOOK,'topic_cluster':'digital_red_flags / invoice_fraud_awareness','format_type':'proof_short','duration':'31.4','caption_style':'static phrase segments + active-word highlight, no box/bar','visual_style':'deterministic screen/mockup-led','cta_type':'save/share/checklist'}
rows=[row(p) for p in ['youtube_shorts','tiktok','instagram_reels','linkedin_manual']]
with (OUT/'analytics_tracking_template_v1.csv').open('w', newline='', encoding='utf-8') as f:
    w=csv.DictWriter(f, fieldnames=fields); w.writeheader(); w.writerows(rows)
(OUT/'analytics_tracking_template_v1.json').write_text(json.dumps({'fields':fields,'rows':rows},indent=2), encoding='utf-8')
qa={
 'candidate_id':CID,'version':'manual_upload_v1','qa_result':'pass','upload_ready':True,
 'checks':{
  'video_plays_full_length':'pass','audio_present':'pass','captions_safe_zone':'pass','no_caption_box':'pass','no_full_width_bar':'pass','no_clipped_words':'pass','no_real_logos':'pass','no_real_bank_data':'pass','no_qr_codes':'pass','no_people':'pass','platform_ui_issues_visible':'pass','hook_first_2_seconds_understandable':'pass','takeaway_clear':'pass','claim_gate':'pass','ai_disclosure':'pass'},
 'notes':['Email mockup uses reserved .test domain: billing@sample.test.','Invoice/company/payment data are generic deterministic mockups.','No auto-posting or platform API used.'],
 'visual_qa_contact_sheet': str(OUT/'manual_upload_v1_qa_contact_sheet.jpg'),
 'final_mp4': meta(FINAL,'video/mp4'),
 'manual_posting_pack_json': meta(OUT/'manual_posting_pack_v1.json','application/json'),
 'manual_posting_pack_md': meta(OUT/'manual_posting_pack_v1.md','text/markdown'),
 'analytics_template_csv': meta(OUT/'analytics_tracking_template_v1.csv','text/csv'),
 'analytics_template_json': meta(OUT/'analytics_tracking_template_v1.json','application/json'),
 'qa_contact_sheet': meta(OUT/'manual_upload_v1_qa_contact_sheet.jpg','image/jpeg'),
 'candidate_status': meta(OUT/'candidate_status_manual_upload_v1.json','application/json')
}
(OUT/'qa_summary_manual_upload_v1.json').write_text(json.dumps(qa,indent=2), encoding='utf-8')
qa_md=['# QA Summary — manual_upload_v1','',f'- candidate_id: {CID}','- version: manual_upload_v1','- qa_result: pass','- upload_ready: true','']
for k,v in qa['checks'].items(): qa_md.append(f'- {k}: {v}')
qa_md += ['','## Notes'] + [f'- {n}' for n in qa['notes']]
(OUT/'qa_summary_manual_upload_v1.md').write_text('\n'.join(qa_md), encoding='utf-8')
# manifest of all deliverables
arts={name: qa[name] for name in ['final_mp4','manual_posting_pack_json','manual_posting_pack_md','analytics_template_csv','analytics_template_json','qa_contact_sheet','candidate_status']}
arts['qa_summary_json']=meta(OUT/'qa_summary_manual_upload_v1.json','application/json')
arts['qa_summary_md']=meta(OUT/'qa_summary_manual_upload_v1.md','text/markdown')
manifest={'candidate_id':CID,'version':'manual_upload_v1','status':'approved_proof_short','posting_status':'not_posted','auto_posting':False,'platform_api_used':False,'wan_used':False,'i2v_used':False,'t2v_used':False,'new_ai_images':False,'artifacts':arts}
(OUT/'manual_upload_v1_manifest.json').write_text(json.dumps(manifest,indent=2), encoding='utf-8')
print(json.dumps(manifest, indent=2))
PY'''
print(terminal(script, timeout=120, workdir='/home/agent/jarvis_runtime/autoshortsbot/AutoShortsBot')['output'])


Output:
{
  "candidate_id": "digital-red-flags-fake-invoice-payment-route-30s",
  "version": "manual_upload_v1",
  "status": "approved_proof_short",
  "posting_status": "not_posted",
  "auto_posting": false,
  "platform_api_used": false,
  "wan_used": false,
  "i2v_used": false,
  "t2v_used": false,
  "new_ai_images": false,
  "artifacts": {
    "final_mp4": {
      "file_path": "/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/digital-red-flags-fake-invoice-payment-route-30s_manual_upload_v1.mp4",
      "file_exists": true,
      "file_size": 1190549,
      "sha256": "a9073f09b80b9b43eb421a4c523e05cf745374fbe7ef33176b082e988a220dfc",
      "media_type": "video/mp4",
      "duration": 31.4,
      "resolution": "1080x1920",
      "fps": "24/1",
      "video_codec": "h264",
      "audio_codec": "aac",
      "audio_sample_rate": "48000",
      "audio_channels": 1
    },
    "manual_posting_pack_json": {
      "file_path": "/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/manual_posting_pack_v1.json",
      "file_exists": true,
      "file_size": 4158,
      "sha256": "e66195587c7bc5a3ba7245cb2c988f9622a8ba62ff50cbe54eb48f7b098f3040",
      "media_type": "application/json",
      "duration": "n/a",
      "resolution": "n/a"
    },
    "manual_posting_pack_md": {
      "file_path": "/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/manual_posting_pack_v1.md",
      "file_exists": true,
      "file_size": 2976,
      "sha256": "1dca29b97479cc9afc5f4e37f3d7355fcf0ce0f6a408acf63554f074871cd204",
      "media_type": "text/markdown",
      "duration": "n/a",
      "resolution": "n/a"
    },
    "analytics_template_csv": {
      "file_path": "/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/analytics_tracking_template_v1.csv",
      "file_exists": true,
      "file_size": 1762,
      "sha256": "d464584149838bd39b2dd51dbc5763ff6143bbedc13c299c91601d53600ab421",
      "media_type": "text/csv",
      "duration": "n/a",
      "resolution": "n/a"
    },
    "analytics_template_json": {
      "file_path": "/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/analytics_tracking_template_v1.json",
      "file_exists": true,
      "file_size": 4792,
      "sha256": "089f77a681900716dbace91468ef053e0c4b68188688e299c36877e7f6c9a2f1",
      "media_type": "application/json",
      "duration": "n/a",
      "resolution": "n/a"
    },
    "qa_contact_sheet": {
      "file_path": "/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/manual_upload_v1_qa_contact_sheet.jpg",
      "file_exists": true,
      "file_size": 232844,
      "sha256": "869c71f526def74a27723a8efeee2d99f25b8ef041f340a5c6a05c5bc068866e",
      "media_type": "image/jpeg",
      "duration": "n/a",
      "resolution": "810x1440"
    },
    "candidate_status": {
      "file_path": "/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/candidate_status_manual_upload_v1.json",
      "file_exists": true,
      "file_size": 401,
      "sha256": "9a6830c68ee2e21ed148582b7de26754f8ed99db118ec993053892b951a0484e",
      "media_type": "application/json",
      "duration": "n/a",
      "resolution": "n/a"
    },
    "qa_summary_json": {
      "file_path": "/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/qa_summary_manual_upload_v1.json",
      "file_exists": true,
      "file_size": 4016,
      "sha256": "11e076447a1f569ce9e85475da84950a952c2fc9f7b92aa39b12e278273d2b70",
      "media_type": "application/json",
      "duration": "n/a",
      "resolution": "n/a"
    },
    "qa_summary_md": {
      "file_path": "/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/qa_summary_manual_upload_v1.md",
      "file_exists": true,
      "file_size": 731,
      "sha256": "4f6df0599494a4854bacdc22392eb82d160f4551d5355e440bd2e08fb7cf111a",
      "media_type": "text/markdown",
      "duration": "n/a",
      "resolution": "n/a"
    }
  }
}


Explanation:
**Processing file delivery**

I’m thinking about how to read the posting pack for the final delivery, but not too detailed. First, I need to update my to-do list and possibly run a git clean since there aren’t any repo modifications. I should check the git status later. It seems we modified some files, but that’s fine. I need to send a target with the necessary files and consider using send_message for attachments, especially for media files like MP4.

todo

Git status/tests prüfen und Sprint-3.1 Commit sichern

Preview v2 als approved_proof_short markieren

manual_upload_v1 MP4 technisch finalisieren und Metadaten erzeugen

Final QA + Claim/AI Disclosure Gate dokumentieren

Manual Posting Pack + Analytics Templates erzeugen

MP4, Pack, Analytics, QA Summary per Telegram senden/verifizieren


telegram:JARVIS Command Center / topic 4850

Sprint 3.2 — Manual Upload Pack

Upload-ready MP4:
MEDIA:/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/digital-red-flags-fake-invoice-payment-route-30s_manual_upload_v1.mp4

Manual Posting Pack JSON:
MEDIA:/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/manual_posting_pack_v1.json

Manual Posting Pack Markdown:
MEDIA:/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/manual_posting_pack_v1.md

Analytics Template CSV:
MEDIA:/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/analytics_tracking_template_v1.csv

Analytics Template JSON:
MEDIA:/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/analytics_tracking_template_v1.json

QA Summary JSON:
MEDIA:/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/qa_summary_manual_upload_v1.json

QA Contact Sheet:
MEDIA:/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/manual_upload_v1_qa_contact_sheet.jpg


Explanation:
**Updating delivery info**

I need to update the manifest delivery information for the artifacts first. After that, I'll check the final git status to ensure everything is in order. It’s essential to have that delivery info updated correctly before moving on. Once I have both tasks done, I can feel secure knowing everything is in place. It’s all about keeping things organized and straightforward to avoid any potential hiccups later!

from hermes_tools import terminal
cmd=r'''python - <<'PY'
from pathlib import Path
import json
OUT=Path('/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1')
for filename in ['manual_upload_v1_manifest.json','qa_summary_manual_upload_v1.json']:
    p=OUT/filename
    data=json.loads(p.read_text())
    if 'artifacts' in data:
        artifacts=data['artifacts']
    else:
        artifacts={k:v for k,v in data.items() if isinstance(v,dict) and 'file_path' in v}
    for v in artifacts.values():
        if isinstance(v,dict) and 'file_path' in v:
            v['telegram_delivery_attempted']=True
            v['telegram_delivery_verified']=True
            v['telegram_message_id']='5984'
            v['telegram_target']='telegram:JARVIS Command Center / topic 4850'
    data['thread_delivery']={'telegram_delivery_attempted':True,'telegram_delivery_verified':True,'telegram_message_id':'5984','chat_id':'-1003907117629','target':'telegram:JARVIS Command Center / topic 4850'}
    p.write_text(json.dumps(data,indent=2),encoding='utf-8')
print((OUT/'manual_upload_v1_manifest.json').read_text()[:9000])
PY

git status --short && git log -1 --oneline
pytest tests/test_caption_safe_zone.py tests/test_static_caption_segments.py tests/test_image_generation_policy.py tests/test_proof_short_mode.py tests/test_pilot_production_v2.py -q
'''
print(terminal(cmd, timeout=180, workdir='/home/agent/jarvis_runtime/autoshortsbot/AutoShortsBot')['output'])


Output:
{
  "candidate_id": "digital-red-flags-fake-invoice-payment-route-30s",
  "version": "manual_upload_v1",
  "status": "approved_proof_short",
  "posting_status": "not_posted",
  "auto_posting": false,
  "platform_api_used": false,
  "wan_used": false,
  "i2v_used": false,
  "t2v_used": false,
  "new_ai_images": false,
  "artifacts": {
    "final_mp4": {
      "file_path": "/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/digital-red-flags-fake-invoice-payment-route-30s_manual_upload_v1.mp4",
      "file_exists": true,
      "file_size": 1190549,
      "sha256": "a9073f09b80b9b43eb421a4c523e05cf745374fbe7ef33176b082e988a220dfc",
      "media_type": "video/mp4",
      "duration": 31.4,
      "resolution": "1080x1920",
      "fps": "24/1",
      "video_codec": "h264",
      "audio_codec": "aac",
      "audio_sample_rate": "48000",
      "audio_channels": 1,
      "telegram_delivery_attempted": true,
      "telegram_delivery_verified": true,
      "telegram_message_id": "5984",
      "telegram_target": "telegram:JARVIS Command Center / topic 4850"
    },
    "manual_posting_pack_json": {
      "file_path": "/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/manual_posting_pack_v1.json",
      "file_exists": true,
      "file_size": 4158,
      "sha256": "e66195587c7bc5a3ba7245cb2c988f9622a8ba62ff50cbe54eb48f7b098f3040",
      "media_type": "application/json",
      "duration": "n/a",
      "resolution": "n/a",
      "telegram_delivery_attempted": true,
      "telegram_delivery_verified": true,
      "telegram_message_id": "5984",
      "telegram_target": "telegram:JARVIS Command Center / topic 4850"
    },
    "manual_posting_pack_md": {
      "file_path": "/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/manual_posting_pack_v1.md",
      "file_exists": true,
      "file_size": 2976,
      "sha256": "1dca29b97479cc9afc5f4e37f3d7355fcf0ce0f6a408acf63554f074871cd204",
      "media_type": "text/markdown",
      "duration": "n/a",
      "resolution": "n/a",
      "telegram_delivery_attempted": true,
      "telegram_delivery_verified": true,
      "telegram_message_id": "5984",
      "telegram_target": "telegram:JARVIS Command Center / topic 4850"
    },
    "analytics_template_csv": {
      "file_path": "/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/analytics_tracking_template_v1.csv",
      "file_exists": true,
      "file_size": 1762,
      "sha256": "d464584149838bd39b2dd51dbc5763ff6143bbedc13c299c91601d53600ab421",
      "media_type": "text/csv",
      "duration": "n/a",
      "resolution": "n/a",
      "telegram_delivery_attempted": true,
      "telegram_delivery_verified": true,
      "telegram_message_id": "5984",
      "telegram_target": "telegram:JARVIS Command Center / topic 4850"
    },
    "analytics_template_json": {
      "file_path": "/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/analytics_tracking_template_v1.json",
      "file_exists": true,
      "file_size": 4792,
      "sha256": "089f77a681900716dbace91468ef053e0c4b68188688e299c36877e7f6c9a2f1",
      "media_type": "application/json",
      "duration": "n/a",
      "resolution": "n/a",
      "telegram_delivery_attempted": true,
      "telegram_delivery_verified": true,
      "telegram_message_id": "5984",
      "telegram_target": "telegram:JARVIS Command Center / topic 4850"
    },
    "qa_contact_sheet": {
      "file_path": "/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/manual_upload_v1_qa_contact_sheet.jpg",
      "file_exists": true,
      "file_size": 232844,
      "sha256": "869c71f526def74a27723a8efeee2d99f25b8ef041f340a5c6a05c5bc068866e",
      "media_type": "image/jpeg",
      "duration": "n/a",
      "resolution": "810x1440",
      "telegram_delivery_attempted": true,
      "telegram_delivery_verified": true,
      "telegram_message_id": "5984",
      "telegram_target": "telegram:JARVIS Command Center / topic 4850"
    },
    "candidate_status": {
      "file_path": "/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/candidate_status_manual_upload_v1.json",
      "file_exists": true,
      "file_size": 401,
      "sha256": "9a6830c68ee2e21ed148582b7de26754f8ed99db118ec993053892b951a0484e",
      "media_type": "application/json",
      "duration": "n/a",
      "resolution": "n/a",
      "telegram_delivery_attempted": true,
      "telegram_delivery_verified": true,
      "telegram_message_id": "5984",
      "telegram_target": "telegram:JARVIS Command Center / topic 4850"
    },
    "qa_summary_json": {
      "file_path": "/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/qa_summary_manual_upload_v1.json",
      "file_exists": true,
      "file_size": 4016,
      "sha256": "11e076447a1f569ce9e85475da84950a952c2fc9f7b92aa39b12e278273d2b70",
      "media_type": "application/json",
      "duration": "n/a",
      "resolution": "n/a",
      "telegram_delivery_attempted": true,
      "telegram_delivery_verified": true,
      "telegram_message_id": "5984",
      "telegram_target": "telegram:JARVIS Command Center / topic 4850"
    },
    "qa_summary_md": {
      "file_path": "/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/qa_summary_manual_upload_v1.md",
      "file_exists": true,
      "file_size": 731,
      "sha256": "4f6df0599494a4854bacdc22392eb82d160f4551d5355e440bd2e08fb7cf111a",
      "media_type": "text/markdown",
      "duration": "n/a",
      "resolution": "n/a",
      "telegram_delivery_attempted": true,
      "telegram_delivery_verified": true,
      "telegram_message_id": "5984",
      "telegram_target": "telegram:JARVIS Command Center / topic 4850"
    }
  },
  "thread_delivery": {
    "telegram_delivery_attempted": true,
    "telegram_delivery_verified": true,
    "telegram_message_id": "5984",
    "chat_id": "-1003907117629",
    "target": "telegram:JARVIS Command Center / topic 4850"
  }
}
cf66672 fix: enforce caption safe zones and image policy
........................                                                 [100%]
24 passed in 0.41s


Explanation:
**Finalizing concise report in German**

I need to prepare a final answer in German that is concise yet detailed. I should mention the git status—if it’s clean, it won’t show extra details, and I’ll note the last commit. There may be a need to differentiate any commit messages. I think I’ll include that media has already been sent without resending it. Also, I should outline next commands and open risks, but I have to keep it straightforward without overwhelming details.


Sir, **Sprint 3.2 — Proof Short Finalization + Manual Posting Pack ist abgeschlossen.**

Der Candidate ist jetzt als **approved_proof_short** markiert und als **manual_upload_v1** uploadbereit vorbereitet.

Kein Auto-Posting. Keine Plattform-API. Kein Wan. Kein I2V/T2V. Keine neuen AI-Bilder. Also ausnahmsweise kein digitaler Zirkus mit Nebelmaschine.

## Status

Candidate:

```text
digital-red-flags-fake-invoice-payment-route-30s
```

Status:

```text
approved_proof_short
```

Manual Upload Version:

```text
manual_upload_v1
```

Posting Status:

```text
not_posted
```

Auto Upload:

```text
false
```

## Git / Tests

Git Status:

```text
clean
```

Letzter Commit:

```text
cf66672 fix: enforce caption safe zones and image policy
```

Relevante Tests:

```text
24 passed in 0.41s
```

Getestet:

```text
tests/test_caption_safe_zone.py
tests/test_static_caption_segments.py
tests/test_image_generation_policy.py
tests/test_proof_short_mode.py
tests/test_pilot_production_v2.py
```

## Final MP4

Uploadbereites MP4:

```text
/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/digital-red-flags-fake-invoice-payment-route-30s_manual_upload_v1.mp4
```

Metadata:

```text
file_exists: true
file_size: 1190549 bytes
sha256: a9073f09b80b9b43eb421a4c523e05cf745374fbe7ef33176b082e988a220dfc
media_type: video/mp4
duration: 31.4s
resolution: 1080x1920
fps: 24/1
video_codec: h264
audio_codec: aac
audio_sample_rate: 48000
audio_channels: 1
```

Encoding:

```text
H.264 high profile
AAC audio
48kHz mono
+faststart
loudnorm applied
1080x1920
24fps
```

## Kleine Safety-Korrektur

Ich habe für die uploadbereite Version die sichtbare Mockup-Absenderadresse von:

```text
billing@example-company.com
```

auf eine reservierte Test-Domain geändert:

```text
billing@sample.test
```

Grund: weniger Risiko, dass eine scheinbar echte `.com`-Adresse als real interpretiert wird. Gleiche Story, sauberer Mockup-Standard.

## Final QA Result

QA Result:

```text
pass
```

Upload Ready:

```text
true
```

Geprüft:

```text
video_plays_full_length: pass
audio_present: pass
captions_safe_zone: pass
no_caption_box: pass
no_full_width_bar: pass
no_clipped_words: pass
no_real_logos: pass
no_real_bank_data: pass
no_qr_codes: pass
no_people: pass
platform_ui_issues_visible: pass
hook_first_2_seconds_understandable: pass
takeaway_clear: pass
claim_gate: pass
ai_disclosure: pass
```

QA Contact Sheet:

```text
/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/manual_upload_v1_qa_contact_sheet.jpg
```

Metadata:

```text
file_exists: true
file_size: 232844 bytes
sha256: 869c71f526def74a27723a8efeee2d99f25b8ef041f340a5c6a05c5bc068866e
media_type: image/jpeg
resolution: 810x1440
```

## Manual Posting Pack

Erzeugt:

```text
/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/manual_posting_pack_v1.json
```

```text
/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/manual_posting_pack_v1.md
```

JSON Metadata:

```text
file_size: 4158 bytes
sha256: e66195587c7bc5a3ba7245cb2c988f9622a8ba62ff50cbe54eb48f7b098f3040
media_type: application/json
```

Markdown Metadata:

```text
file_size: 2976 bytes
sha256: 1dca29b97479cc9afc5f4e37f3d7355fcf0ce0f6a408acf63554f074871cd204
media_type: text/markdown
```

Enthalten:

- YouTube Shorts:
  - Titel
  - Beschreibung
  - Hashtags
  - Kurz-CTA
  - Shorts-Kompatibilität
- TikTok:
  - Caption
  - Hashtags
  - CTA
  - Kommentar-Pin-Vorschlag
- Instagram Reels:
  - Caption
  - Hashtags
  - CTA
  - Cover-Text-Vorschlag
- LinkedIn Manual:
  - professionellere Caption
  - Hook-Zeile
  - Kontext
  - CTA ohne Hype

Sichere Claim-Sprache ist verwendet:

```text
A common red flag…
Before you pay…
Verify through a second channel.
```

Nicht enthalten:

```text
kein “so erkennst du jeden Scam”
keine Finanzberatung
keine Rechtsberatung
keine Panikmache
keine übertriebenen Claims
```

## AI Disclosure / Synthetic Media

Dokumentiert:

```text
Video nutzt deterministische Mockups und TTS.
Keine realistischen Menschen.
Keine realistischen echten Firmen.
Keine echten Ereignisse.
Keine realistischen synthetischen Personen.
```

Plattform-Disclosure-Einschätzung:

```text
platform_ai_disclosure_likely_required: false
```

Manual Review Note:

```text
Because the video uses non-realistic deterministic UI/document mockups and TTS without realistic synthetic people or real-event depiction, platform synthetic media disclosure is probably not required. If a platform UI asks whether AI-assisted media was used, disclose conservatively according to that platform prompt.
```

## Analytics Templates

CSV:

```text
/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/analytics_tracking_template_v1.csv
```

Metadata:

```text
file_exists: true
file_size: 1762 bytes
sha256: d464584149838bd39b2dd51dbc5763ff6143bbedc13c299c91601d53600ab421
media_type: text/csv
```

JSON:

```text
/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/analytics_tracking_template_v1.json
```

Metadata:

```text
file_exists: true
file_size: 4792 bytes
sha256: 089f77a681900716dbace91468ef053e0c4b68188688e299c36877e7f6c9a2f1
media_type: application/json
```

Felder enthalten wie gefordert:

```text
platform
post_url
post_time
candidate_id
version
hook
topic_cluster
format_type
duration
caption_style
visual_style
cta_type
1h_views
1h_likes
1h_comments
1h_shares
1h_saves
1h_follows
24h_views
24h_completion_rate
24h_average_watch_time
24h_shares
24h_saves
24h_follows
72h_views
7d_views
notes
qualitative_comments
followup_decision
```

## QA Summary / Manifest

QA Summary JSON:

```text
/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/qa_summary_manual_upload_v1.json
```

Manifest:

```text
/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/manual_upload_v1_manifest.json
```

Candidate Status:

```text
/tmp/autoshorts_proof_short_sprint30/digital-red-flags-fake-invoice-payment-route-30s/manual_upload_v1/candidate_status_manual_upload_v1.json
```

## Telegram Delivery

Gesendet an:

```text
telegram:JARVIS Command Center / topic 4850
```

Telegram Status:

```text
telegram_delivery_attempted: true
telegram_delivery_verified: true
telegram_message_id: 5984
chat_id: -1003907117629
```

Gesendete Artefakte:

- Upload-ready MP4
- Manual Posting Pack JSON
- Manual Posting Pack Markdown
- Analytics Template CSV
- Analytics Template JSON
- QA Summary JSON
- QA Contact Sheet

## Nicht ausgeführt

Bestätigt nicht ausgeführt:

```text
YouTube upload: false
TikTok upload: false
Instagram upload: false
LinkedIn posting: false
platform_api_used: false
scheduling: false
wan_used: false
i2v_used: false
t2v_used: false
new_ai_images: false
new_topic_batches: false
```

## Offene Risiken

- Plattformen können beim manuellen Upload trotzdem nach AI-/Synthetic-Media-Disclosure fragen. Empfehlung: konservativ nach UI-Frage antworten.
- TTS-Stimme ist synthetisch, aber keine realistische Personendarstellung.
- LinkedIn kann bei sehr kurzen Videos anders performen als TikTok/Reels/Shorts; Analytics-Template ist vorbereitet.
- Es bleibt ein Proof Short, kein Cinematic Final. Genau der Punkt.

## Nächste mögliche Kommandos

Wenn du manuell posten möchtest:

```text
APPROVED_FOR_MANUAL_UPLOAD digital-red-flags-fake-invoice-payment-route-30s manual_upload_v1
```

Wenn du noch etwas ändern willst:

```text
REVISE_MANUAL_UPLOAD digital-red-flags-fake-invoice-payment-route-30s "Änderungswunsch"
```

Wenn wir weitere Proof Shorts erzeugen sollen:

```text
GENERATE_NEXT_PROOF_SHORT_CANDIDATES count=3
```


social-media-shorts-automation

# Image Provider Audit + Caption Safe-Zone Pattern

Use this reference when a social-short pipeline needs to verify AI image provenance/quality tiers and harden mobile subtitle layout before approving a preview/final.

## Image provider audit checklist

1. Inspect Hermes config, not memory or assumptions:
   - `image_gen.provider`
   - `image_gen.model`
   - provider-specific subconfig if present, e.g. `image_gen.openai-codex.model`
2. Inspect registered image providers/capabilities from the provider registry:
   - available providers
   - available model tiers
   - active provider resolution/fallback behavior
3. For ChatGPT/Codex image generation in Hermes, the relevant practical tiers are:
   - `gpt-image-2-low`
   - `gpt-image-2-medium`
   - `gpt-image-2-high`
4. For premium keyframes/styleframes, prefer the highest available reasonable tier (`gpt-image-2-high` when available). For deterministic UI/mockups, do not use image generation.
5. Verify recent image runs by cache filenames and metadata. The Codex backend saves PNGs under `$HERMES_HOME/cache/images/` with names like:
   - `openai_codex_gpt-image-2-medium_...png`
   - `openai_codex_gpt-image-2-high_...png`
6. If needed, run exactly one neutral capability test image, not a batch. Save provider/model/quality/size/response metadata, file path, SHA256, and resolution.
7. Inspect PNG chunks for provenance. Codex/OpenAI PNG outputs may contain a `caBX` JUMBF/C2PA chunk (`jumb`, `jumdc2pa`, `urn:c2pa:`). PIL may show no normal `info` keys; raw chunk inspection is more reliable.
8. Note that C2PA/provenance in the original PNG cache is not reliably preserved after converting into JPEG contact sheets or MP4 renders.

## AutoShorts image policy

Use image generation only for approved premium styleframes/keyframes. Keep renderer-owned/deterministic assets for:

- fake invoices
- fake emails
- payment-route cards
- UI mockups
- documents with labels/numbers/text

Recommended policy values:

```text
allowed_image_provider = openai-codex
preferred_image_model = best_available_gpt_image_model
preferred_quality = highest_available_reasonable
max_styleframes_per_scene_without_approval = 3
max_retries_per_styleframe = 1
no_random_batches = true
no_ai_images_for_mockups_when_deterministic_renderer_is_better = true
```

## Caption safe-zone implementation pattern

Hard rules for mobile subtitles:

- No caption text may exceed the left/right safe area.
- Use max width around 86–90% of video width.
- At 1080px width, keep at least 60px horizontal margin; 70px is safer.
- Keep bottom margin platform-safe; for 1080x1920, around 260–310px works better than very low captions.
- Maximum two lines per segment.
- Prefer 4–7 words per static phrase segment.
- If a phrase would exceed two lines, split the phrase earlier.
- Dynamically shrink font size only down to a minimum; after that, split.
- Active-word highlight geometry must also fit inside safe bounds.
- Treat long domains like `example-company.com` as special width stress tests.

## Tests to add

Add tests for:

- long phrase wraps into two lines
- caption never exceeds safe width
- active word highlight never exceeds bounds
- no word clipped at left/right edge
- max two lines enforced by earlier phrase splitting
- bottom safe-zone respected
- long domain strings wrap or shrink safely

## Preview QA

After rendering, produce:

- MP4 preview
- contact sheet at known problem timestamps
- single subtitle-style preview frame
- manifest with file path, SHA256, size, duration/resolution, caption validation result, and delivery metadata

Use visual QA on the contact sheet. If any renderer-owned text card is clipped, fix it too; otherwise the preview still feels broken even if the formal subtitles pass.


Gute Frage, Sir — und ja: **wir sollten KI-Bilder verwenden**, aber **nicht für alles**.

Der Grund, warum ich sie bei diesem Proof Short bewusst *nicht* eingesetzt habe:
Bei Fake-Invoice / Email / Payment-Route ist der kritische Inhalt **Text, UI, Dokumentstruktur und Sicherheits-Kontext**. Genau dort sind KI-Bilder riskant:

- KI erzeugt gerne Fake-Text, Pseudo-Logos, Fantasie-Bankdaten.
- Sie kann echte Marken/Lookalikes halluzinieren.
- Sie macht UI oft hübsch, aber unlesbar oder inkonsistent.
- Bei Scam-/Invoice-Themen kann ein KI-Bild schnell wie eine echte Vorlage wirken.
- Der Proof Short sollte zuerst validieren: **funktioniert das Problem + Regel + Retention?**

Deshalb war die Entscheidung:

```text
Deterministische Mockups für Invoice / Email / Payment Route
KI-Bilder erst für Atmosphäre / Premium-Look / Hintergründe / Keyframes
```

Also: **nicht “keine KI-Bilder”**, sondern:
**Keine KI-Bilder als Träger der faktischen UI-/Invoice-Information.**

## Wo KI-Bilder sinnvoll wären

Für die nächste Version können wir KI sehr gut einsetzen, um das Short aufzuwerten:

### 1. Cinematic Background Layer

Zum Beispiel:

- moderner Arbeitsplatz
- Laptop/Desk-Szene
- unscharfer Office-Hintergrund
- Rechnungsprüfung bei Abendlicht
- Security-/Finance-Team-Atmosphäre

Aber:

```text
Keine lesbaren Texte
Keine Logos
Keine echten Marken
Keine QR-Codes
Keine Bankdaten
```

Der Renderer legt danach die Fake-Invoice / Email / Payment Route sauber darüber.

### 2. Premium Keyframes

Wir könnten 2–3 hochwertige textfreie KI-Keyframes erzeugen:

- **Frame A:** Close-up auf Laptop/Invoice-Review Situation
- **Frame B:** Hand/Mouse near payment approval, tense moment
- **Frame C:** Clean desk / second-channel verification moment

Dann deterministisch darüber:

- Captions
- fake UI
- red-flag highlights
- sender / urgency / payment route checks

### 3. Thumbnail / Cover

KI-Bilder sind sehr gut für einen starken Cover-Look:

```text
“CHECK THE ROUTE”
```

oder textfrei als Hintergrund, mit Renderer-Text darüber.

## Wo KI-Bilder weiterhin falsch wären

Nicht verwenden für:

- die Rechnung selbst
- Email-Screen mit lesbaren Details
- Zahlungsroute
- Bankkarte / IBAN / Account-Felder
- Warnhinweise
- QR-Codes
- Logos
- UI mit faktischen Labels

Das muss renderer-owned bleiben. Sonst bekommen wir hübschen Unsinn mit Sicherheitsrisiko. Charmant, aber dumm — also exakt das, was wir nicht bauen wollen.

## Mein Vorschlag

Wir machen eine **Visual Upgrade v1**, ohne das Konzept zu ändern:

```text
UPGRADE_PROOF_SHORT_VISUALS
digital-red-flags-fake-invoice-payment-route-30s
mode: ai_background_plus_deterministic_mockups
```

Umfang:

- 2–3 GPT-Image-2-high textfreie Background-Keyframes
- keine echten Marken / keine Texte / keine Personen nötig
- bestehende Voiceover + Captions behalten
- deterministische Fake-Invoice/UI bleibt
- neuer Preview: `visual_upgrade_v1`
- kein Wan/I2V/Posting

Das wäre der richtige Mittelweg: **professioneller Look**, aber ohne die faktische Kontrolle über das Safety-Thema zu verlieren.


Sprint 3.3 — AI Visual Upgrade v1

Visual Upgrade Preview MP4:

QA Contact Sheet:

AI Keyframes Contact Sheet:

Subtitle Style Preview:

Review Package JSON:

Manifest JSON:


---
name: social-media-shorts-automation
description: Design, generate, review, publish, and optimize automated short-form social videos across YouTube Shorts, TikTok, Instagram Reels, and related channels.
version: 1.0.0
tags: [shorts, tiktok, youtube-shorts, reels, creator-monetization, content-automation, social-media]
---

# Social-Media Shorts Automation

Reference note: see `references/controlled-pilot-production-v2.md` for the controlled first-video workflow: resource tiers, media-generation gates, pilot package shape, Wan prompt planning without generation, and no auto-posting. See `references/pilot-preview-render-v2.md` for the next approval step: `APPROVED_FOR_PREVIEW_RENDER`, EdgeTTS preview audio, time/word cue generation, deterministic 9:16 animatic MP4, checksums, and Telegram media delivery without Wan/AI-image/platform side effects. See `references/static-active-word-captions-and-final-pilot-render.md` for the corrected caption style and controlled final pilot render pattern: static 3–7 word phrase segments with only the active spoken word highlighted, hash-bound final render gates, one Wan text-free background layer, deterministic overlays, and draft-only manual posting packages. If a final render is rejected as preview-overlay-dominated or not visual-first, follow `references/visual-first-final-render-repair.md`: mark the render rejected/not-postable, fix Wan output parsing, enforce final overlay limits, produce only a short visual proof under `APPROVED_FOR_VISUAL_PROOF`, and do not run another full final until the visual direction is accepted. If even the visual proof is rejected as abstract/generic/dark or “blind T2V”, switch to `references/keyframe-first-final-visuals.md`: plan and approve start/end/style keyframes first, then run only a short I2V/first-last-frame proof with minimal renderer-owned overlays. If the user says the production method itself is wrong, keyframes are not I2V-ready, or an animatic was incorrectly substituted for a failed Wan proof, follow `references/visual-production-reset-i2v-first.md`: reject/audit the proof, stop content rendering, run technical I2V sanity first, then generate at most three styleframes for direction review. If deterministic layout proofs are useful as composition blueprints but rejected as too wireframe/PowerPoint for final style, switch to `references/premium-ai-styleframe-direction.md`: use the layouts only as mechanism blueprints, generate at most 3 tightly briefed premium text-free AI styleframes, deliver a contact sheet with verified media metadata, and keep Wan/I2V/endframes/full-final blocked until style direction approval. If those premium styleframes are better quality but still too abstract, switch to `references/real-life-premium-styleframes.md`: anchor the mechanism in a realistic work/meeting/desk scene, keep all readable overlays renderer-owned, generate at most 3 new real-life styleframes plus contact sheet, and still block Wan/I2V/endframes/full-final until explicit approval. If the user approves one or more real-life styleframe directions but wants to compare A/B/C before Wan, use `references/prerelease-animatic-preview.md`: build only a small AI-keyframe + deterministic-motion animatic per approved direction, reuse existing voiceover/captions, deliver MP4/contact/QA sheets with metadata, and keep Wan/I2V/final/posting blocked. If the user then rejects the renderer-added circles/arrows/labels/boxes/decision-target markers as destroying the premium look, switch to `references/clean-image-cut-no-overlay-pilot.md`: render only AI images + voiceover + clean subtitles, with a hard subtitles-only NoOverlayPolicy and no Wan/I2V/full-final/posting. If the user performs a strategic reset because the pilot is pretty but semantically weak, stop optimizing that candidate and follow `references/proof-short-real-problem-reset.md`: archive the old pilot as a learning case, enforce the Pretty Empty Visual Blocker, and build a screen/mockup-led Proof Short around an immediately visible real viewer problem before any premium/Wan production. If the next review focuses on image provider quality/provenance or subtitles running off-screen, follow `references/image-provider-audit-and-caption-safezone.md`: audit the configured image provider/model/tier from config + provider registry + cache metadata, run at most one neutral capability test, keep UI/invoice mockups deterministic, and add tested caption layout safe-zone bounds before re-rendering. If an approved Proof Short feels too visually flat and the user asks why no AI images were used, follow `references/proof-short-ai-visual-upgrade.md`: use AI images as a controlled text-free atmosphere/background/keyframe layer while keeping invoices, emails, payment routes, labels, facts, and captions deterministic renderer-owned.

Use this skill when building or operating systems that generate short-form social videos, especially faceless or semi-automated pipelines for YouTube Shorts, TikTok, Instagram Reels, Facebook Reels, Pinterest video pins, X video, or LinkedIn video.

## Core principle

Treat the system as a **Shorts Growth Engine** / **semi-automatic Retention Studio**, not merely a renderer. A working video generator can still fail if it produces generic, low-retention, AI-slop content. Optimize for audience identity, hook quality, retention mechanics, visual mechanism reveals, platform fit, and analytics feedback. For the user's strongest strategic direction, see `references/retention-studio-strategy.md`.

For this user's AutoShorts workflows, approval previews should be German for concept comprehension, while final social-media videos should remain English unless explicitly changed. Treat preview legibility as a quality gate: readable font sizes, pixel-width-aware line wrapping, no clipped words, and no overcrowded cards.

For the user's TrueTraceShorts / AutoShortsBot strategy, do **not** default to a narrow AI/prompt-tips channel. The current strategic direction is broader: explain hidden digital everyday mechanisms — AI, work, attention, decisions, scams, productivity, workflows, social search — and end each video with one small system rule that fixes the outcome. Use the frame `Trace the hidden system. Fix the outcome.` AI should remain an important pillar, but normally only about 30–40% of the topic mix, not the whole product. See `references/truetrace-strategic-neuausrichtung.md`.

When the user asks to start implementation work on this strategy, especially “Sprint 1: Strategic Spine Refactor”, follow `references/truetrace-strategic-spine-refactor-v2.md`: implement a side-effect-free V2 spine in parallel to existing V1 models, with mandatory strategic fields, hard quality gates, anti-AI-slop blockers, hash/version-bound ReviewPackageV2, and tests before integration with renderers or platform workflows.

When the user asks for “Sprint 1.5” or to make the V2 spine operational without production, follow `references/truetrace-v2-operational-bridge.md`: first secure/commit the Sprint-1 baseline, then add only minimal side-effect-free bridges (`to_candidate_v2`, `workflow_v2`, `demo_review_batch_v2`), deterministic ReviewPackageV2 JSON, strict approval parsing, calibrated non-generous scoring, anti-example/human-texture gates, minimal manual claim/disclosure stubs, LinkedIn manual metadata, and a Remotion-as-later-spike note. Keep it capped at 3 demo candidates and avoid rendering, platform APIs, dashboards, auto-posting, or 30-day batches.

## Retention-Studio / Mechanism-Reveal Pipeline

For quality-first automated Shorts, especially Hidden Money & AI Systems concepts, prefer the pipeline documented in `references/retention-studio-pipeline-pattern.md`:

```text
strategy → scored ideas → mechanism explainer → shot plan → keyframe/I2V prompt plan → seeded clip jobs → clip review → deterministic final renderer
```

When implementing a new repo or core pipeline, first scaffold the approval-first typed artifact chain in `references/approval-first-retention-studio-core.md`:

```text
ContentPillar → ContentBrief → ScriptDraft → VideoCandidate → TestBatch → ReviewBatch → Telegram ReviewDelivery → ShotPlan
```

Hard rule for this class: AI-video clips provide photorealistic texture and motion only. Captions, numbers, labels, arrows, UI text, price/risk/margin layers, and factual claims are renderer-owned. Final content should keep `static_card_limit = 0`, use visual changes every 1–2 seconds, and reject technically successful clips that do not serve the retention beat.

Before video generation, build an inspectable content-to-review spine: `ContentBrief → ScriptDraft → CandidateDraft → VideoCandidate → TestBatch → ReviewBatch → Telegram ReviewDelivery`. Keep it deterministic, side-effect free, and human-approval-first so hooks, retention beats, visual concepts, policy notes, and review copy can be optimized before spending GPU/API time. See `references/content-to-review-pipeline.md` for the implementation pattern and guardrails.

Hard rule for this class: AI-video clips provide photorealistic texture and motion only. Captions, numbers, labels, arrows, UI text, price/risk/margin layers, and factual claims are renderer-owned. Final content should keep `static_card_limit = 0`, use visual changes every 1–2 seconds, and reject technically successful clips that do not serve the retention beat.

## Recommended workflow

1. **Define channel position**
   - Niche(s): e.g. life optimization, AI life systems, Christian faith/FaithTok.
   - Target audience and emotional problem.
   - Language and tone.
   - Whether the brand is faceless, AI-persona-led, or creator-led.
   - No-go topics and theological/ethical boundaries if faith-related.

2. **Generate test ideas before code-heavy automation**
   - Create 20–30 candidate ideas across 2–4 content pillars.
   - For each: hook, script kernel, visual concept, caption, CTA, risk/quality score.
   - Select a small first batch (e.g. 3 per pillar) for real testing.
   - Before renderers or external AI APIs, add a deterministic content-development core: `ContentPillar → ContentBrief → ScriptDraft → CandidateDraft → VideoCandidate`. See `references/content-development-core.md`.

3. **Use hook-first, retention-led scripting**
   - First 1–2 seconds must contain a clear tension, identity statement, pain point, contrarian line, or immediate self-recognition.
   - Prefer one idea per video over generic “4 tips” unless the list format is the explicit series.
   - Avoid generic advice viewers have already heard unless framed with a new angle, concrete payoff, or strong story.
   - For TrueTraceShorts, prefer the structure `visible fail → identification → mechanism → fix → before/after → memorable takeaway` over generic AI-tip narration. Every video must answer: what goes wrong, why it happens, what rule fixes it, what sentence sticks, why viewers save/share it, and why they follow the series.
   - For unvalidated first pilots, apply the `Pretty Empty Visual Blocker`: if the first frame is beautiful but does not show a concrete viewer pain without voiceover, block the concept and switch to a Proof Short. Do not keep polishing abstract AI visuals, glass metaphors, or generic laptop B-roll before validating the real problem. See `references/proof-short-real-problem-reset.md`.
   - After a Proof Short concept is approved for usefulness/clarity, do not interpret `ProofShortMode` as a permanent ban on AI images. If the user wants the video “aufgepeppt”, add a controlled AI visual-upgrade layer: 2–3 text-free premium backgrounds/keyframes, while all invoice/email/UI/payment-route text, labels, facts, captions, claims, and red-flag overlays remain deterministic renderer-owned. See `references/proof-short-ai-visual-upgrade.md`.
   - Reward hooks with direct address, specificity, open loops, tension, and a visible payoff; reject slow intros such as “In this video...”.
   - See `references/retention-led-shorts.md` for scoring signals, penalties, and voiceover finalization rules.

4. **Quality gate before rendering**
   Score drafts on:
   - hook strength
   - novelty
   - emotional pull
   - clarity
   - retention risk
   - comment/share potential
   - AI-slop risk
   - platform/policy risk
   - first-frame clarity
   - mechanism value
   - practical payoff
   - save/share/follow reason
   - trust/human texture
   - series fit and saturation defense
   Render only drafts above the chosen threshold, e.g. 8/10.
   For TrueTraceShorts, use the 100-point scoring and hard blockers in `references/truetrace-strategic-neuausrichtung.md`: block generic AI hooks, pure text first frames, unsourced claims, missing before/after, missing human texture, unclear AI disclosure, and candidates too similar to recent videos.

5. **Visual strategy**
   - Avoid obvious AI artifacts, fake UI text, illegible generated lettering, generic charts, and soulless stock visuals.
   - Prefer high-contrast kinetic captions, visible hook text in first seconds, relatable B-roll, screen recordings for AI/tutorial content, phone/screen close-ups, before/after transformations, cards, and timer visuals.
   - Use pattern interrupts every 2–3 seconds for retention.
   - Before rendering, generate a shot plan from the finalized voiceover: first-frame hook, pattern interrupt, core explanation, screen/card visual, CTA, caption beats, and asset type.
   - Before writing a renderer, convert shot plans into deterministic render manifests: machine-readable timeline items, asset placeholders, caption tracks, style constraints, and approval constraints. See `references/render-manifest-pipeline.md`.
   - Treat this as a deterministic intermediate artifact, not optional prose. See `references/retention-render-planning.md` for the five-scene shot-plan pattern and renderer-facing fields.
   - For the first video output, build a manifest-driven preview renderer before any AI-video or polished asset pipeline: first create a side-effect-free local preview plan, then write deterministic PNG scene cards, then build a side-effect-free FFmpeg concat plan, and only then call FFmpeg from an explicit renderer boundary. The boundary should report side effects such as `write_png`, `write_concat`, `call_ffmpeg`, and `write_mp4`; keep generated PNG/MP4 artifacts out of Git. See `references/manifest-preview-renderer.md`.
   - When the user rejects static/slideshow output, add an `asset_plan.v2` layer that maps each scene to motion-led local asset modes such as `cinematic_ai_video`, `screen_recording_simulation`, `mechanism_animation`, or `kinetic_text_overlay` with no baked text. If the user requires a free workflow, do not depend on paid video-credit tools; use local procedural motion and optional free NVIDIA LLM text refinement. See `references/ai-video-asset-planning.md`.
   - For hybrid workflows, add an imported-clip assembly layer: provider handoff prompts create short manual AI-video clips, humans drop them into deterministic `data/imported_ai_clips/<slug>/scene_XX.mp4` paths, and the final renderer combines imported clips with local mechanism animations/captions. See `references/imported-ai-clip-assembly.md`.
   - For local Wan2.2 quality workflows, prefer keyframe/image-to-video over raw text-to-video: generate/select a clean keyframe, run native Wan2.2 I2V variants, review clips bluntly for subject clarity/motion/artifacts, then add all labels/numbers/captions via deterministic renderer. See `references/wan-i2v-retention-studio.md`.
   - For final renders, Wan must carry the visual scene, not merely provide a blurred/looped background underneath preview cards. Use full-bleed, scene-specific Wan clips, minimal renderer-owned overlays, and a final overlay policy that blocks preview frames, large UI cards/textboxes, debug bars, and overlay overload. If architecture is rejected, create a short visual proof first; see `references/visual-first-final-render-repair.md`.
   - If a visual proof still looks like blind text-to-video or random abstract AI output, stop T2V and move to a keyframe-first workflow: generate/approve 1–2 text-free start/end/style keyframes for the scene, then attempt only a short Wan I2V/first-last-frame proof. See `references/keyframe-first-final-visuals.md`.
   - When using NVIDIA Build/API Catalog for keyframes, prefer hosted `ai.api.nvidia.com` calls before considering self-hosted NIM deployment; implement a configurable model fallback chain, store the key as a runtime secret, and inspect/clean logos, emblems, license plates, and fake text before I2V. See `references/nvidia-keyframe-generation.md`.

6. **Social-media draft and content-preview approval packages before TTS/rendering polish**
   - Before TTS, platform APIs, or polished video generation, build a typed `SocialMediaDraft` from the approved candidate plus render manifest/preview.
   - Include platform targets, title variants, caption, hashtags, CTA, hook, duration, quality/risk summary, and preview reference.
   - Render this into a Telegram-safe approval message and wrap it in a side-effect-free delivery plan with `requires_human_approval=True` and `side_effects=()`.
   - After a local MP4 timing preview exists, combine the MP4 path plus social draft review into a side-effect-free content preview approval package. This package should carry `approval_language=de`, `final_video_language=en`, explicit approval commands, no external calls, and no side effects.
   - Add local demo CLIs that print metadata first, then review text; draft-only CLIs must not write files, call renderers, call Telegram, or access credentials. MP4 preview CLIs may write local artifacts and call FFmpeg only at explicit renderer boundaries that report side effects.
   - See `references/social-draft-approval-package.md` and `references/content-automation-patterns.md` for concrete artifact sequence, user-specific language rules, and external workflow patterns.

7. **Human approval loop before posting**
   - Send preview to the user through the requested channel, usually Telegram.
   - Include: video or preview reference, title, caption, hashtags, platform recommendation, duration, quality/risk score.
   - When sending multiple preview videos, verify and label distinct artifacts before delivery: candidate ID/title, absolute path, duration, and preferably checksum/hash. If several previews are visually similar timing cards, do not spam them as separate unlabeled media; send a concise indexed list first or bundle with clear labels so the user can tell them apart.
   - Wait for explicit approval such as `Freigabe alle`, `Freigabe YouTube`, `Freigabe TikTok`, `Ablehnen`, or `Ändern: ...`.
   - Do not publish automatically unless the user has explicitly authorized that workflow.

8. **TTS / voice layer after draft approval**
   - Treat TTS as a later layer, not the starting point for a first post draft.
   - Decide voice, final voiceover script, words-per-second, scene timing, caption sync, audio format, provider, and separate voice approval only after the social draft package is reviewable.
   - This avoids spending TTS/rendering effort on unapproved hooks, captions, or platform positioning.
  - For final-near previews, keep one copy source of truth: final voiceover → script draft/retention beats → shot plan → top card text → scene captions → subtitle track → TTS audio. Do not mix old approval-card text with new spoken/subtitle text.
  - If the user says the result is too abstract/abgehoben, rewrite around a concrete beginner-friendly everyday failure example before polishing visuals. Prefer “one weird email arrives” / missing field / unclear request / wrong confident action over jargon such as `exception path`, `input boundary`, or `output standard`. See `references/beginner-friendly-audio-caption-alignment.md`.
  - If the user says subtitles are irritating or not simultaneous with voiceover, treat this as a blocking quality issue: use forced alignment or simplify captions before sending another final-near clip. For this user's AutoShorts/TrueTraceShorts default, do **not** show one word alone and do **not** slide a changing word-window every word. Use static phrase segments: keep 3–7 words fixed on screen while only the currently spoken word highlights/pulses left-to-right; replace the full segment only at a sentence/phrase boundary. See `references/static-active-word-captions-and-final-pilot-render.md`.
  - If deterministic layouts explain the mechanism but look like wireframes/PowerPoint, do not promote them to final style. Treat them as composition blueprints and run a small, tightly prompted premium AI styleframe pass instead: AI supplies glassmorphism/product-film quality and atmosphere; the renderer still owns labels, arrows, captions, facts, and final assembly. See `references/premium-ai-styleframe-direction.md`.
  - If premium AI styleframes improve quality but still feel like abstract SaaS symbolism, do not continue iterating abstract funnels/rings. Move to real-life anchored work scenes: desk/laptop, empty meeting room/glass board, or project table/work evidence, with only subtle glass/holographic mechanism overlays. See `references/real-life-premium-styleframes.md`.
  - If real-life styleframe directions are accepted but the user has not approved Wan/I2V yet, insert a pre-release animatic comparison step rather than jumping to endframes or video generation. Create small per-direction AI keyframe sets, deterministic push-ins/crossfades, existing voiceover, static active-word captions, contact sheets, and QA frame sheets; report Telegram delivery metadata. See `references/prerelease-animatic-preview.md`.
  - If the user rejects added visual explanation overlays as making the result look like a technical explainer board, treat this as a hard style failure. For the clean pilot, use only AI images, voiceover, and clean subtitles; block circles, arrows, labels, boxes, connector lines, decision-target markers, debug/diagram elements, and caption boxes/bars. See `references/clean-image-cut-no-overlay-pilot.md`.
  - For mechanism-reveal final renders, use the hybrid pattern in `references/final-motion-hybrid-rendering.md`: ChatGPT Image/Codex or similar tools create text-free scene backgrounds only; deterministic renderer owns cards, labels, arrows, subtitles, and FFmpeg assembly. Use compact phrase-boundary subtitle cues before 1080 export.

9. **Publish and measure**
   Track at minimum:
   - platform, video id/url, niche, format, hook, duration
   - views at 2h/24h/7d
   - likes, comments, shares, saves, follows
   - retention metrics if available
   Use results to generate the next batch.

## Platform duration/monetization notes

See `references/preview-media-delivery-guardrails.md` for avoiding duplicate-looking/unlabeled preview-video spam in Telegram review workflows.

See `references/truetrace-strategic-spine-refactor-v2.md` for implementing the new TrueTraceShorts strategy in code: V2 strategic models, hard gates, anti-AI-slop blockers, SeriesRegistry, 100-point scoring, hash-bound ReviewPackageV2, and deterministic five-candidate examples without rendering or platform side effects. See `references/truetrace-v2-operational-bridge.md` for the next implementation step: secure the Sprint-1 commit, add minimal side-effect-free bridge/workflow/CLI modules, deterministic ReviewPackageV2 JSON, strict approval parsing, calibrated scoring, anti-example/human-texture gates, manual claim/disclosure stubs, LinkedIn manual metadata, and Remotion-as-later-spike documentation without production expansion.

See `references/audio-caption-preview-pipeline.md` for the approval-first EdgeTTS + ASS subtitles + FFmpeg review-MP4 pipeline, including actual-audio-duration probing and the explicit `preserve_video` vs `trim_to_audio` duration-mode guardrail. See `references/pilot-preview-render-v2.md` for the stricter first-pilot preview pattern: preview-only approval state, EdgeTTS sentence SRT to preview word cues when forced alignment is unavailable, deterministic card/diagram animatic rendering, SHA256/duration verification, and Telegram media delivery while Wan/AI-image/platform calls remain blocked. See `references/static-active-word-captions-and-final-pilot-render.md` for the corrected Hormozi-style caption behaviour and the one-render final pilot review-package checklist.

See `references/final-motion-hybrid-rendering.md` for the final-near hybrid renderer pattern: ChatGPT Image/Codex or other AI tools provide text-free background/keyframe texture while deterministic renderer overlays own text, arrows, labels, captions, and final assembly. For quick prototypes, prefer ChatGPT Image/Codex backgrounds before local Qwen/ComfyUI unless privacy/cost/local-only constraints dominate. After a 1080 export, create a side-effect-free final approval package with media path, SHA256, platform metadata, social copy, quality notes, and approval commands before any delivery or platform step.

See `references/visual-first-final-render-repair.md` for the repaired final-render architecture after a rejected pilot: mark rejected renders as not-postable, avoid preview-board overlays, enforce `FinalOverlayPolicy`, validate ComfyUI/Wan output histories robustly, and use `APPROVED_FOR_VISUAL_PROOF` for one short visual proof before any second full final.

See `references/hybrid-scene-backgrounds-codex.md` for the concrete ChatGPT Image/Codex scene-background workflow: side-effect-free `SceneBackgroundPlan`, per-scene text-free backgrounds, renderer-owned overlays, and visual QA before review delivery. Prefer this over local Qwen/ComfyUI when the user allows Codex image generation and local GPU should be reserved for video/model work.

See `references/monetization-and-approval-notes.md` for current working notes captured from official YouTube/TikTok docs and the recommended approval/posting setup. See `references/retention-led-shorts.md` for retention scoring signals, no-faith/adjacent-pillar handling, and voiceover finalization rules. See `references/render-manifest-pipeline.md` for the script → shot plan → render manifest → renderer sequence that prevents generic AI slideshow output. See `references/manifest-preview-renderer.md` for the first deterministic Pillow/FFmpeg preview-renderer pattern. See `references/local-preview-frame-writer.md` for the staged `LocalPreviewPlan → PNG scene cards → FFmpeg concat plan` boundary before MP4 rendering. See `references/social-draft-approval-package.md` for the typed first-post approval package to build before TTS or platform APIs. See `references/content-automation-patterns.md` for public workflow patterns, queue/status/cost tracking, versioned approval, synthetic-content disclosure, originality gates, and the user's German-preview/English-final rule. See `references/ai-video-asset-planning.md` for motion-led final-render asset planning with Kling/Hailuo/Runway-style clips and screen simulations. See `references/imported-ai-clip-assembly.md` for hybrid assembly where manually generated provider clips are imported into a deterministic local renderer. See `references/nvidia-keyframe-generation.md` for NVIDIA-hosted keyframe generation, model fallback, secret handling, and pre-I2V logo/plate cleanup. Re-check official docs before making business-critical decisions because platform programs change often.

## Project/repo hygiene for automated video bots

- Keep source code in Git; keep generated videos, assets, `.env`, OAuth tokens, API keys, and downloaded secrets out of Git.
- Use `.gitignore` aggressively for outputs, media caches, local credentials, and temp files.
- Store platform credentials as runtime secrets; never print raw tokens.
- Build the repo as modular components: idea generation, scripting, rendering, review, publishing, analytics.
- For approval-first Retention Studio implementations, use a typed side-effect-free core before real I/O: `ContentBrief`, `ScriptDraft`, `VideoCandidate`, review batches, Telegram delivery plans, then shot plans. See `references/approval-first-retention-studio-core.md`.

## Sensitive-content positioning

When AI/productivity automation is the primary brand, be cautious about mixing in religious/FaithTok, health, finance, or other high-trust themes. If the user flags the combination as sensitive, pause that pillar rather than forcing it into the same testbatch. Replace it with a safer adjacent pillar (for example `attention_design`) and document the paused pillar in config so it can be revisited only with explicit approval and a separate brand strategy.

## Pitfalls

- Do not send several generated preview videos as unlabeled media attachments just because they are distinct files. Telegram/mobile previews can make timing-card MP4s look identical. Verify uniqueness (path + title + hash/duration) and provide labels or an indexed summary; if the user complains about duplicate-looking media, stop resending, verify artifacts, and continue the pipeline.
- Do not let final-near preview layers drift apart: if the top field, voiceover, and subtitles do not say the same thing, rebuild the render plan from one final script source before sending another clip.
- Do not make broad-audience AI-system shorts sound like architecture lectures. For early-AI users, convert abstract workflow concepts into concrete everyday failures first, then reveal the principle.
- Do not over-optimize renderer quality before testing whether the content format earns retention.
- Do not keep iterating a polished pilot when the user identifies the core failure as “pretty but semantically weak.” Archive it as a learning case, preserve what worked, and restart with a Proof Short whose first second shows a real visible fail and an immediately useful rule.
- Do not overcorrect from “validate with Proof Shorts” into “never use AI images.” Once the real problem/rule is approved, AI images can legitimately improve perceived quality as text-free atmosphere, backgrounds, keyframes, or thumbnails. Keep factual UI/document/payment layers deterministic; use AI for polish, not truth.
- Do not let German approval previews become unreadable technical cards: use pixel-width-aware wrapping, readable fonts, limited line counts, visual checks for clipped/overcrowded text, and hard mobile safe-zone tests for captions/highlights before delivery.
- Do not confuse approval language with final audience language. For this user, approval previews are German by default; final social videos remain English unless explicitly changed.
- Do not copy public automation workflows wholesale: keep their queue/status/cost tracking and template structure, but remove blind auto-publishing until a human approval/version lock exists.
- Do not mass-generate repetitive shorts without originality/inauthentic-content gates; this can harm monetization/account health and create AI slop.
- Do not jump directly from a script idea to ComfyUI/Wan/Qwen/Image/video generation. First build and inspect the content-to-review spine so weak hooks, generic scripts, policy issues, and static visual concepts are killed before render time.
- Do not assume local Qwen/ComfyUI is the best first image step for every final-near short. If the user permits ChatGPT Image/Codex, use it for text-free scene backgrounds/keyframes when the deterministic renderer owns labels/captions and local GPU should be saved for video/model work. When provider quality matters, verify the actual `image_gen.provider`/model from config and the image cache filenames/metadata rather than guessing; for premium styleframes prefer the highest available reasonable GPT Image tier, but keep fake invoice/email/UI/payment-route mockups deterministic.
- Do not create a parallel candidate path for content experiments; convert content artifacts into the existing candidate factory input so IDs, hashtags, duration classes, quality gates, and pillar/platform validation stay centralized.
- Do not use `x or default` for optional content/script overrides in factories; explicit blank strings and zero durations must pass through to validation so tests can catch them.
- Do not assume TikTok monetization rules match YouTube: TikTok Creator Rewards emphasizes 1min+ eligible videos, while shorter videos may still be better for growth.
- Do not treat a keyframe animatic as a successful Wan/I2V proof. If ComfyUI/Wan I2V fails or history contains no valid video output, label any fallback MP4 as `not_wan` / composition-review-only and block full-final progression.
- Do not treat deterministic layout proofs as the final premium visual style when the user asked for a high-end social-video look. Layouts are for mechanism composition; after approval, use a tightly scoped premium AI styleframe pass with strict negative prompts and verified delivery before endframes/Wan.
- Do not mistake premium abstract glassmorphism for an approved final direction if the user wants a credible everyday work scene. When the user says the motif is still too abstract, switch to real-life work-scene styleframes with laptop/tablet/meeting-room/project-table anchors; keep motion graphics subtle and renderer-owned.
- If the user rejects the production method itself, do not keep iterating content visuals. Reject/audit the proof, run a technical I2V sanity test with a trivial non-content image, and only after it passes generate a small set of styleframes for direction review; see `references/visual-production-reset-i2v-first.md`.
- Do not keep trying blind text-to-video after the user rejects a proof as abstract, dark, generic, or semantically ungrounded. Move to keyframe-first planning, review the keyframes, then run at most one short I2V/first-last-frame proof.
- Do not publish religious or health-adjacent content with overconfident claims; preserve humility, nuance, and platform safety.
- Do not rely on platform payout as the only monetization path; plan indirect monetization such as newsletter, templates, affiliates, digital products, or services.

To view linked files, call skill_view(name, file_path) where file_path is e.g. 'references/api.md' or 'assets/config.yaml'