Repository navigation
Fix the README architecture diagram and rebuild the demo video with narration - #1
Merged
Merged
Conversation
… tests The PNG in the README was cropped on the right and several labels ran out of their boxes. The label widths had been estimated for fonts that are not installed, so the renderer fell back to a wider font, and no SVG source was tracked to measure. assets/arch-diagram.svg is now the source and pins Liberation Sans. The six pipeline stages go top to bottom, and each partner (cluster, Tavily, sandbox, model tiers, GitHub) is at the height of the stage that uses it, so every connector is one straight line. The accent colour is the green of the logo. tests/test_arch_diagram.py measures every label with rsvg-convert and fails when a label leaves its box, two labels overlap, two boxes partly overlap, a connector crosses a box or a label, or anything is outside the canvas. make diagram renders the PNG. CI installs librsvg2-bin and fonts-liberation so that the test runs there.
…narration The committed video showed "Segment error: intro - el is not defined" for its whole length and had no audio. Every segment used `el` inside play(), where it does not exist, declared one timing entry for three to six beats, animated with CSS transitions that the render clock does not drive, and loaded the logo from a URL that returns 404. The nine segments are rewritten in demo/videos/segments (the documented place; the symlink is gone). They keep the host element in a module variable, reveal beats with element.animate(), and show data from the committed eval results for the low-memory-limit case in place of the invented values. A new `mender` style uses the logo colours and locally served fonts, and replaces the OnMe style. The narration is one ElevenLabs file (voice Lily, British English). Timing in audio/tracks/v1/track.ts is computed from its word timestamps and snapped to 60 fps frames; each segment carries the same values. videowright 0.1.1 does not publish two modules that its own entry files import, so a clean install could not render. scripts/apply-videowright-fix.mjs writes them after each install. tests/video.spec.ts drives the real player in a browser, because the render exits 0 even when a segment throws. The rendered MP4 is not part of this commit; the test that checks it fails until the 1080p render is committed.
demo/mender-demo.mp4 replaces the file that showed a segment error for its whole length and had no audio stream. It is the 60 fps, 1920x1080 render of demo/videos/videos/demo with audio track v1 (voice Lily, normalised to -16 LUFS), 96.4 seconds long. All 11 browser tests pass against it, and frames from the file were checked by eye at ten narration cues. PLAN.md now names the mender style and the narration, points to the generated script, and has a log entry for this rebuild. voiceover_script/script.md is generated from the segments by `videowright script --write`.
Layout only: Biome is the formatter that the videowright project template installs, and its default layout differs from the hand-written one in eleven files. No behaviour changes; the type check and the 11 browser tests pass.
…, render again An independent review compared each value in the video with the eval run and found four claims that said more than the run shows. They are corrected: - "25 s from a broken service" was the pipeline time (triage to prepared PR), which does not include fault injection, the settle wait or evidence collection. The outro and the narration now say "from evidence". - "15 sources" were 15 search results, 14 of them distinct. - The sandbox command now marks the flags that it leaves out. - The nano prompt of 11,020 tokens is labelled as the prompt, and the triage scene shows the four signals and three suspects that the run returned. The narration is generated again with three corrected lines (93.5 s), and demo/mender-demo.mp4 is the new render (93.9 s). scripts/sync_audio.py now builds the audio track and writes the scene timing to the track and the segments, so a new voice needs no hand-copied numbers. generate.sh writes to temporary files first, so a refused or empty API response cannot replace the audio of the last good run. The nine segments share one defineScene() helper in place of nine copies of the same mount, play and unmount code. Diagram: the ledger label says "cost per model tier" (Tavily has no cost). The layout tests also check that the PNG has the shape of the SVG canvas, fail in place of a skip when CI has no renderer, and read connectors only from <line> elements. The README says where the video source is and how to render it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
assets/arch-diagram.svg, rendered bymake diagram). Each pipeline stage has its partner at the same height, so every connector is one straight line. Six layout tests measure each label withrsvg-convert, the renderer that makes the PNG.demo/mender-demo.mp4showedSegment error: intro — el is not definedfor its whole length and had no audio. The nine scenes are rebuilt (demo/videos/), use a Mender style made from the logo colours, and show values from the 2026-10-06 eval run oflow-memory-limit. The video now has a British English narration (ElevenLabs, voice Lily) and is 93.9 s long.generate.shandscripts/sync_audio.pyrebuild the narration and the scene timing. Browser tests drive the real player, becausevideowright renderexits 0 even when a scene throws.Root causes
elinsideplay(), where it does not exist. The render reports success anyway.node_modulesthat was not tracked.Notes for the reviewer
VOICE_ID=... generate.sh,python3 scripts/sync_audio.py,npm testand a new render are enough.librsvg2-binandfonts-liberationfor the diagram tests. The browser tests of the video run locally (npm testindemo/videos), not in CI.demo/videos/styles/; nothing used it.Test Plan
make test: ruff, ruff format, mypy, pytest (84 tests, 6 of them for the diagram)demo/videos:npx tsc --noEmit,npx biome check,npm test(11 browser tests)npm cifrom an emptynode_modules, then a render: works with 0npm auditfindings