Skip to content

docs(skills): make captions non-optional in changelog-video#2729

Merged
jrusso1020 merged 4 commits into
mainfrom
jerrai/changelog-video-captions-mandatory
Jul 22, 2026
Merged

docs(skills): make captions non-optional in changelog-video#2729
jrusso1020 merged 4 commits into
mainfrom
jerrai/changelog-video-captions-mandatory

Conversation

@jrusso1020

Copy link
Copy Markdown
Collaborator

Description

Follow-up to #2669 (which added Step 0 the pre-build asset gate). The Jul 13-20
weekly changelog video shipped without captions because the pipeline had two
soft failure modes that both passed lint + validate:

  • Empty `vo-words.json` — the TTS provider returned audio but no timestamp
    payload. `align-captions.mjs` silently produced an empty `captions.json`.
  • Empty `LINES` array in the master-skeleton — the caption-rail IIFE
    ships with a placeholder `const LINES = /* … */ []` that stays empty when
    `captions.json` is missing. Nothing in the pipeline caught this.

Result: a build that lint-clean-passed, validate-clean-passed, and rendered a
clean 34 MB MP4 — with no captions. Jake and James caught it after ship.

This PR adds three hard gates on top of the existing scaffold — no new
infrastructure, just closing the loopholes:

  • Step 4 — a whisper forced-alignment fallback so a missing TTS
    timestamp payload no longer breaks the caption pipeline. Whisper only
    supplies timings; captions still use the DISPLAY layer from
    `script-tokens.json`.
  • Step 5 — flags an empty `LINES` array as a shipped bug, shows the
    exact IIFE-input shape it expects.
  • Step 6 — adds gate 5: sample 3-4 frames across the VO window and
    confirm visible caption text on each. If any spoken window renders no
    caption, the build is red.

Anti-patterns table gets two rows covering both failure modes.
`.claude/skills` and `.agents/skills` mirrors stay byte-identical after
the update.

Testing

— Rames Jusso

jrusso1020 and others added 2 commits July 22, 2026 00:22
The Jul 13-20 build shipped without captions because the pipeline had two soft
failure modes:

- Empty vo-words.json from the TTS provider was silently accepted, so
  align-captions.mjs had nothing to align. captions.json was never produced.
- Step 5 tolerated the master-skeleton's LINES array staying empty. The build
  lint-checked and validated clean, but the caption rail rendered no text.

This adds three hard gates on top of the existing scaffold:

- Step 4 adds a whisper forced-alignment fallback so a missing TTS timestamp
  payload no longer breaks the caption pipeline. Whisper only supplies timings;
  captions still use the DISPLAY layer from script-tokens.json.
- Step 5 flags an empty LINES array as a shipped bug and shows the exact
  IIFE-input shape it expects.
- Step 6 adds gate 5: sample 3-4 frames across the VO window and confirm visible
  caption text on each. If any spoken window renders no caption, the build is
  red.

Anti-patterns table gets two rows covering the empty-LINES and
missing-word-timings failure modes. .claude and .agents mirrors stay
byte-identical.

Follow-up to #2669 (pre-build gate); paired with the v5 rebuild that
retrofitted captions onto the shipped Jul 13-20 video.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…gibility

25px reads too small at 1080² when the video is viewed on a phone without
zoom. Bumped to 32px (font-size 25→32, top 1002→990, height 40→52, alpha
.92→.94) so captions carry across small-screen playback. Change is CSS-only
on the master-skeleton; existing per-scene chrome and layouts are untouched.

Retrofitted the Jul 13-20 v6 build with the same values (identical CSS
block) so the shipped video and the future default match. .claude and
.agents mirrors stay byte-identical.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

@miga-heygen miga-heygen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SSOT Review: weekly changelog digest + captions non-optional in changelog-video skill

Combined review: #2664 (1 file, +45/-0) + #2729 (4 files, +118/-30)


SSOT inventory

#2664 — weekly changelog digest

Content-only docs entry — no SSOT structures to inventory.

#2729 — captions non-optional

Concept Source of truth Consumers Verdict
SKILL.md (caption gates + anti-patterns) .claude/skills/changelog-video/SKILL.md .agents/skills/changelog-video/SKILL.md (mirror) Mirrors match ✓
Master-skeleton caption CSS .claude/skills/changelog-video/examples/master-skeleton.html .agents/skills/changelog-video/examples/master-skeleton.html (mirror) Mirrors match ✓
Caption rail position master-skeleton.html #cap-line { top: 990px } SKILL.md gate 5 reference STALE — see Blocking Issues

What I checked

#2664

  1. Video embed. <Frame><video controls muted playsinline src="...weekly-changelog-jul13-20.mp4"> — matches the CDN URL discussed in the thread (v6 with 32px captions, CloudFront invalidated). ✓
  2. Content structure. Features → Fixes → Docs & Examples sections. Each entry has commit SHA + PR link. Reads clean. ✓
  3. Mintlify <Update> tags. label, description, tags present. Matches the existing format pattern (prepended per the {/* ... */} comment). ✓

#2729

  1. Mirror sync. Both .claude/skills/ and .agents/skills/ copies of SKILL.md have identical diffs. Both copies of master-skeleton.html have identical diffs. ✓

  2. Word-timings hard gate (step 4). Verifies vo-words.json is non-empty with a words array before proceeding to step 5. Whisper fallback for the known TTS failure mode (audio but no timestamps). Notes that whisper mishears TTS renderings — captions use DISPLAY spelling, whisper supplies only timestamps. Correct. ✓

  3. Captions non-optional gate (step 5). LINES array must be populated from captions.json before step 6. "Leaving that array empty is a shipped bug, not a style choice." Correct — this was the v4 failure. ✓

  4. Caption presence gate (step 6, gate 5). Sample 3-4 frames across the VO's spoken window, confirm the caption rail renders visible text on each. Hard fail if missing. ✓

  5. Anti-patterns table. Two new entries: "Shipping with the LINES array empty" and "No vo-words.json → skip captions." Both point at the correct fix steps. Table formatting is consistent. ✓

  6. Master-skeleton CSS changes. Caption rail: font-size: 25px → 32px, top: 1002px → 990px, height: 40px → 52px, color opacity: .92 → .94. The 32px matches the v6 build that James approved in the thread. ✓

Blocking SSOT issues

1. Stale caption rail position in SKILL.md gate 5.

SKILL.md step 6, gate 5 reads:

confirm the caption rail at top: 1002 renders visible text on each.

But this same PR changes the master-skeleton's #cap-line to top: 990px. An agent following the skill would reference the wrong position. Should read top: 990.

Verdict

#2664: Approve. Clean docs entry.

#2729: Changes Requested — one stale position reference. Fix the top: 1002top: 990 in both SKILL.md mirrors (.claude/ and .agents/), step 6 gate 5, and this is clean.

--- Miga

…+ build-spec

Miga caught: the master-skeleton bump to top: 990 / 32px / height: 52 was
not reflected in the SKILL.md prose or build-spec.md. All three files now
name the same values so the doc, gate, and code stay consistent. Also
clarifies build-spec.md's caption-rail line to point at SKILL.md step 5 as
the source of the LINES-populated requirement.

.claude and .agents mirrors byte-identical.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

@miguel-heygen miguel-heygen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original SKILL.md drift is fixed, and the three edited mirror pairs are byte-identical. One SSOT consumer remains stale:\n\nblocker — and still specify and . The updated explicitly says the caption rail is “per ” while specifying , , and , so agents still receive contradictory canonical instructions. Update both mirrors to the new values; the repo-wide skill grep is otherwise clean.\n\nVerdict: REQUEST CHANGES\nReasoning: The reported gate/build-spec drift is repaired, but its directly referenced caption-layout source still carries the old position and font size, leaving the same SSOT failure mode active.\n\n— Magi

@miguel-heygen miguel-heygen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correction with the exact paths stripped from my submitted review body:

blocker.claude/skills/changelog-video/references/script-voice.md:108 and .agents/skills/changelog-video/references/script-voice.md:108 still specify top: 1002px and 25px. The updated build-spec.md:79 explicitly says the caption rail is “per script-voice.md” while specifying top: 990, 32px, and 52px, so agents still receive contradictory canonical instructions. Update both script-voice.md mirrors to the new values; the repo-wide skill grep is otherwise clean.

Verdict: REQUEST CHANGES
Reasoning: The reported gate/build-spec drift is repaired, but its directly referenced caption-layout source still carries the old position and font size, leaving the same SSOT failure mode active.

— Magi

@vanceingalls vanceingalls left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — approving at head dd9be97 (post-Miga-fix).

Convergence with Miga's SSOT audit. My independent lens surfaced the same P1 he did — top: 1002 reference in SKILL.md step 6 gate 5 was stale against the master-skeleton.html change to top: 990px. Rames pushed the fix commit dd9be971817e ~1 min after Miga's review posted, and it's clean:

  • .claude/skills/changelog-video/SKILL.md — line 42 + line 161 both cite top: 990
  • .agents/skills/changelog-video/SKILL.md — same, mirror byte-identical ✓
  • references/build-spec.md × 2 mirrors — updated to top: 990, font-size: 32px, height: 52
  • master-skeleton.html × 2 mirrors — #cap-line { top: 990px; height: 52px; font-size: 32px; ... }

Rest of the diff LGTM:

  • Caption size 25px → 32px matches the v6 James approved in the thread.
  • Step 4 whisper forced-alignment fallback closes the "audio but no timestamps" failure mode; DISPLAY-spelling-from-tokens rule is called out (whisper only supplies timings, not text).
  • Step 5 LINES-population example is unambiguous — empty array is called out as "a shipped bug, not a style choice."
  • Step 6 gate 5 is the right shape (sample 3-4 frames across the VO's spoken window, hard-fail on missing text).
  • Anti-patterns table gains the two rows that would have caught the v4 uncaptioned ship.

No further asks.

— Via

Third and final stale reference to top: 1002 / 25px — script-voice.md was
still stating the pre-bump values. Now matches master-skeleton.html,
build-spec.md, and SKILL.md. Also bumps the 'keep critical small text out'
guidance from ~80px to ~100px to reflect the slightly taller caption rail.

Full-directory sweep confirms zero remaining occurrences of 1002 or 25px
across .claude/ and .agents/ skill mirrors.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

@miguel-heygen miguel-heygen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Freshness review at bdc2b96:

  • The requested script-voice.md fix is present in both mirrors: top 990px, height 52px, 32px, and .94 ink.
  • Repo-wide grep under both changelog-video skill trees finds zero remaining top 1002 or 25px references.
  • SKILL.md, master-skeleton.html, build-spec.md, and script-voice.md are byte-identical across .claude and .agents (matching SHA-256 for every pair).
  • Required regression and semantic-title checks pass; path-filtered build/test jobs correctly skip.

The SSOT blocker is fully resolved.

Verdict: APPROVE
Reasoning: All caption-layout sources and mirrored consumers now agree on the same rail contract, and the exact-head required checks are green.

— Magi

@jrusso1020
jrusso1020 merged commit 807078c into main Jul 22, 2026
41 checks passed
@jrusso1020
jrusso1020 deleted the jerrai/changelog-video-captions-mandatory branch July 22, 2026 00:38

@vanceingalls vanceingalls left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-stamp at head bdc2b96 (my prior APPROVE at dd9be97 was auto-dismissed by Rames's post-Magi fix push under require_last_push_approval).

n=3 lens convergence on SSOT drift. Miga (SSOT lens, at 0affee5) → me (cross-lens fresh scan, at dd9be97) both hit SKILL.md + build-spec.md residuals of top: 1002. Magi (adversarial lens, at dd9be97) then hit references/script-voice.md:108 — where the caption-rail spec is cited by build-spec.md as the SoT ("caption rail per script-voice.md") but still carried the old 1002/25px values. Real P1 that I missed on my first pass because my grep scoped to what MY subagent thought were the canonical files, not the doc chain build-spec explicitly points at. Fair catch.

Verified at bdc2b96 — 8 files in the diff (SKILL.md × 2 mirrors, master-skeleton.html × 2, build-spec.md × 2, script-voice.md × 2):

  • Zero residual 1002 or 25px refs across any of them.
  • 990 / 32px / 52px consistent everywhere.
  • ink .92 → .94 propagated to script-voice.md line 109.
  • "bottom ~80px" → "bottom ~100px" reserved-band note updated in script-voice.md consistent with the taller caption rail.
  • Both mirrors byte-identical.

Rest of the substantive diff (whisper forced-alignment step 4 gate, LINES-mandatory step 5, sample-3-4-frames step 6 gate 5, two new anti-pattern rows) is unchanged from my prior read — still LGTM.

Magi's block is stale post-fix. Rames — nudge Magi to re-review at bdc2b96 so his CHANGES_REQUESTED lifts, or ask vance to dismiss his review as branch-admin. Once that clears + James is happy, this is mergeable.

— Via

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants