ci(record-demos): fix the VHS install and render the tapes from this checkout - #1224
Merged
Merged
Conversation
…checkout "Install VHS" failed on every run since at least 2026-09-20 -- main, feature branches and the v10.2.0 and v10.3.0 tags -- with wget exit 8. The v0.7.1 release publishes vhs_0.7.1_Linux_x86_64.tar.gz, not vhs_0.7.1_linux_amd64.tar.gz, and `wget -qO-` wrote the archive to stdout, so the `tar xzf` after it would have opened a file that was never written even with the right URL. The step now downloads the real asset to a file, checks it against the sha256 in the release's checksums.txt, extracts only the binary (it sits at the top of the archive), installs ttyd 1.7.4 and ffmpeg from apt (VHS refuses to start without them and requires ttyd 1.7.2 or newer) and prints all three versions. No later step had ever run. A dry run of the whole job on ubuntu:24.04 amd64 showed what each one needed: - Build: zig build -Dci=true, as brain-ci.yml does, so the raylib GUI targets that need X11 and GL headers stay out. - Tapes: they typed `cd ~/trinity-w1`, one developer's checkout, and wrote their GIFs into the working directory. They now run from the repository root, put zig-out/bin first on PATH in a hidden line and write recordings/<name>.gif. The commands they type are unchanged. - Commit GIFs: `git push` cannot land. Ruleset 23148303 rejects a direct push to main with GH013 (signal-health-self.yml gets that answer daily), a tag push has no branch, and on any other branch it would commit under the author. The GIFs are uploaded as the terminal-demo-gifs artifact; recordings/ is gitignored and the demos README says how to render locally. - Triggers: push now runs for main only, because a tag push skips path filters; pull requests that touch a tape or this workflow render too. Read-only token, 30-minute timeout, one run per ref. --- ci(record-demos): исправлена установка VHS, тейпы рендерятся из этого checkout Шаг «Install VHS» падал на каждом запуске как минимум с 2026-09-20 — на main, на рабочих ветках и на тегах v10.2.0 и v10.3.0 — с кодом wget 8. В релизе v0.7.1 файл называется vhs_0.7.1_Linux_x86_64.tar.gz, а не vhs_0.7.1_linux_amd64.tar.gz, а `wget -qO-` выводил архив в stdout, так что следующий `tar xzf` открыл бы файл, которого нет, даже при верном URL. Теперь шаг скачивает настоящий архив в файл, сверяет его sha256 с checksums.txt релиза, извлекает только бинарник (он лежит в корне архива), ставит из apt ttyd 1.7.4 и ffmpeg (без них VHS не запускается, ttyd нужен не старше 1.7.2) и печатает версии всех трёх. Ни один следующий шаг ни разу не выполнялся. Прогон всего job в ubuntu:24.04 amd64 показал, что нужно каждому: - Сборка: zig build -Dci=true, как в brain-ci.yml, чтобы не собирать GUI-цели raylib, которым нужны заголовки X11 и GL. - Тейпы делали `cd ~/trinity-w1` (checkout одного разработчика) и писали GIF в рабочий каталог. Теперь они запускаются из корня репозитория, скрытой строкой ставят zig-out/bin первым в PATH и пишут recordings/<имя>.gif. Набираемые команды не изменены. - Коммит GIF: `git push` не проходит. Ruleset 23148303 отклоняет прямой push в main с GH013 (signal-health-self.yml получает этот ответ каждый день), на теге нет ветки, а на любой другой ветке это был бы коммит поверх автора. GIF загружаются артефактом terminal-demo-gifs; recordings/ добавлен в .gitignore, README с демо объясняет локальный рендер. - Триггеры: push теперь только для main, потому что push тега игнорирует фильтры путей; pull request, меняющий тейп или этот workflow, тоже рендерит. Токен только на чтение, таймаут 30 минут, один запуск на ref. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
github-actions Bot
added a commit
that referenced
this pull request
Oct 1, 2026
ci(record-demos): fix the VHS install and render the tapes from this checkout (#1224) "Install VHS" failed on every run since at least 2026-09-20 -- main, feature branches and the v10.2.0 and v10.3.0 tags -- with wget exit 8. The v0.7.1 release publishes vhs_0.7.1_Linux_x86_64.tar.gz, not vhs_0.7.1_linux_amd64.tar.gz, and `wget -qO-` wrote the archive to stdout, so the `tar xzf` after it would have opened a file that was never written even with the right URL. The step now downloads the real asset to a file, checks it against the sha256 in the release's checksums.txt, extracts only the binary (it sits at the top of the archive), installs ttyd 1.7.4 and ffmpeg from apt (VHS refuses to start without them and requires ttyd 1.7.2 or newer) and prints all three versions. No later step had ever run. A dry run of the whole job on ubuntu:24.04 amd64 showed what each one needed: - Build: zig build -Dci=true, as brain-ci.yml does, so the raylib GUI targets that need X11 and GL headers stay out. - Tapes: they typed `cd ~/trinity-w1`, one developer's checkout, and wrote their GIFs into the working directory. They now run from the repository root, put zig-out/bin first on PATH in a hidden line and write recordings/<name>.gif. The commands they type are unchanged. - Commit GIFs: `git push` cannot land. Ruleset 23148303 rejects a direct push to main with GH013 (signal-health-self.yml gets that answer daily), a tag push has no branch, and on any other branch it would commit under the author. The GIFs are uploaded as the terminal-demo-gifs artifact; recordings/ is gitignored and the demos README says how to render locally. - Triggers: push now runs for main only, because a tag push skips path filters; pull requests that touch a tape or this workflow render too. Read-only token, 30-minute timeout, one run per ref. --- ci(record-demos): исправлена установка VHS, тейпы рендерятся из этого checkout Шаг «Install VHS» падал на каждом запуске как минимум с 2026-09-20 — на main, на рабочих ветках и на тегах v10.2.0 и v10.3.0 — с кодом wget 8. В релизе v0.7.1 файл называется vhs_0.7.1_Linux_x86_64.tar.gz, а не vhs_0.7.1_linux_amd64.tar.gz, а `wget -qO-` выводил архив в stdout, так что следующий `tar xzf` открыл бы файл, которого нет, даже при верном URL. Теперь шаг скачивает настоящий архив в файл, сверяет его sha256 с checksums.txt релиза, извлекает только бинарник (он лежит в корне архива), ставит из apt ttyd 1.7.4 и ffmpeg (без них VHS не запускается, ttyd нужен не старше 1.7.2) и печатает версии всех трёх. Ни один следующий шаг ни разу не выполнялся. Прогон всего job в ubuntu:24.04 amd64 показал, что нужно каждому: - Сборка: zig build -Dci=true, как в brain-ci.yml, чтобы не собирать GUI-цели raylib, которым нужны заголовки X11 и GL. - Тейпы делали `cd ~/trinity-w1` (checkout одного разработчика) и писали GIF в рабочий каталог. Теперь они запускаются из корня репозитория, скрытой строкой ставят zig-out/bin первым в PATH и пишут recordings/<имя>.gif. Набираемые команды не изменены. - Коммит GIF: `git push` не проходит. Ruleset 23148303 отклоняет прямой push в main с GH013 (signal-health-self.yml получает этот ответ каждый день), на теге нет ветки, а на любой другой ветке это был бы коммит поверх автора. GIF загружаются артефактом terminal-demo-gifs; recordings/ добавлен в .gitignore, README с демо объясняет локальный рендер. - Триггеры: push теперь только для main, потому что push тега игнорирует фильтры путей; pull request, меняющий тейп или этот workflow, тоже рендерит. Токен только на чтение, таймаут 30 минут, один запуск на ref. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.
Why
Terminal Demo GIFs (
.github/workflows/record-demos.yml) has failed at Install VHS on every run since at least 2026-09-20: onmain(run 36894521838 today), on feature branches, and on thev10.2.0andv10.3.0tags.vhs_0.7.1_linux_amd64.tar.gz. The v0.7.1 release publishesvhs_0.7.1_Linux_x86_64.tar.gz, sowgetexited 8.wget -qO-wrote the archive to stdout, so thetar xzf vhs_0.7.1_linux_amd64.tar.gzafter it would have found no file even with the right URL.No step after that one had ever run, so I dry-ran the whole job before changing it.
What changes
Install VHS. Downloads the real asset to
$RUNNER_TEMPwithcurl -fand checks it against the sha256 in the release'schecksums.txt(748443e0…96d4). It extracts onlyvhs, which sits at the top of the archive next toREADME.md,LICENSE,completions/andmanpages/. It installsttydandffmpegfrom apt, because VHS refuses to start without them and needs ttyd 1.7.2 or newer (Ubuntu 24.04 ships 1.7.4; the runner image has neither, only Chrome). Then it prints all three versions.Build tri. Now
zig build -Dci=true, asbrain-ci.ymldoes. Without the flag the raylib GUI targets are built too, and they need X11/GL headers. The step ends withzig-out/bin/tri --version.Tapes.
cd ~/trinity-w1(one developer's checkout) is replaced by a hidden block that puts$PWD/zig-out/binfirst onPATHand clears the screen.Outputnow writesrecordings/<name>.gif; VHS creates the directory. The typed commands are unchanged.Commit GIFs → Upload GIFs.
git pushcould not land anywhere:main, ruleset 23148303 ("T27 mandatory work report", no bypass actors) rejects it withGH013 … Required status check "T27 work report" is expected, the same answersignal-health-self.ymlgets every day;The GIFs are uploaded as the
terminal-demo-gifsartifact instead (if-no-files-found: error, 30 days)./recordings/is gitignored;tri-benchmark.gifalone is 2 MB.Triggers.
pushnow runs only formain. A tag push skips path filters, so every release tag ran this job, and so did every branch that touched a.zigfile, archived stashes included.pull_requestruns when a tape or this workflow changes, andworkflow_dispatchstays. The job also getscontents: read, a 30-minute timeout and one run per ref.docs/CLI_DEMOS_README.md. The VHS section now renders from the repository root after
zig build -Dci=trueand says CI uploads an artifact.Dry run
I ran the job twice, both times in
ubuntu:24.04amd64 under Docker with Rosetta on macOS, with a non-rootrunneruser, sudo, Google Chrome and Zig 0.15.2. A driver executed the job's steps the way the runner does (bash --noprofile --norc -eo pipefail,GITHUB_PATH, the artifact glob withif-no-files-found).--security-opt seccomp=unconfinedvhs version v0.7.1 (537d03a)Run 1 stopped for a reason specific to the container. The hosted runner is a VM, and go-rod v0.114.5 (pinned by VHS v0.7.1) looks for
chrome, thengoogle-chrome. On the runner that resolves to Google Chrome; its Chromium is not onPATHunder either name. Ubuntu 24.04's apparmor package grants/opt/google/chrome/chromeuser namespaces (/etc/apparmor.d/chrome), so the workflow sets noVHS_NO_SANDBOX.On the hosted runner this PR's own
pull_requestrun (36906462795) passed every step in 5 min 40 s. Install VHS took 25 s (…vhs_0.7.1_Linux_x86_64.tar.gz: OK,vhs version v0.7.1 (537d03a),ttyd version 1.7.4,ffmpeg version 6.1.1-3ubuntu5) and Build tri 65 s (Trinity v5.1.0 (3cf38d6),Zig: 0.15.2). The five renders took 22–66 s each with Chrome's own sandbox, andterminal-demo-gifswas uploaded at 2 539 372 bytes. The GIFs show the same command output as the dry run.actionlint1.7.12 with shellcheck 0.11.0 reports nothing.What the tapes record today (not changed here)
tritri math demo,bind,similarity,phiUnknown subcommand: …followed by the 121-linetri mathhelpgit status,tri benchmark,… vsa,… vmbenchmarkis not a command, so it falls through to chat and segfaults insrc/tvc/tvc_corpus.zig:145. (tri benchexists but printsbench async: TODO - job system not configured.)tri test,--summary,vsa,vmTest command not yet implemented …tri status,tri git status,tri facultyM .trinity/command_cache.json(everytricall rewrites that tracked file), then the faculty boardls -la fpga/specs/,/fpga-synth counter,cat fpga/build/counter-report.txt/fpga-synthis a Claude Code skill:No such file or directory. The report file does not exist.The job is green, but the GIFs show none of what
docs/CLI_DEMOS_README.mdsays they do (74/74 tests, benchmark results, zero DSP). Choosing what the demos should type is up to the owners, so I left the commands alone. The GIFs committed inexamples/recordings/on 2026-04-03 showbash: tri: command not found. In tri-benchmark each crash outlasts the tape'sSleep 4s, on the hosted runner as under emulation, so the next command is typed into the middle of the stack trace.Not in this PR
signal-health-self.ymlanddiscover-callers.ymlend in the same GH013 onmainevery day.docs/CLI_DEMOS_README.mdembedshttps://gHashTag.github.io/trinity/recordings/*.gif, which return 404:deploy-docs.ymlpublishes onlyapps/website/distanddocs/build. Where the GIFs should be published is a separate decision.tri benchmarksegfault.Work report
{ "version": 1, "head_sha": "aedfc98319de5b730709bd83c52736d4d84456bb", "summary": "Terminal Demo GIFs (record-demos.yml) failed at Install VHS on every run because it downloaded an asset name the VHS v0.7.1 release does not publish. This installs VHS from the real asset with a checksum, adds the ttyd and ffmpeg VHS requires, builds tri with -Dci=true, makes the five tapes render from the repository root with the freshly built tri, and replaces the commit-and-push step, which ruleset 23148303 rejects on main, with an uploaded artifact.", "changes": [ ".github/workflows/record-demos.yml, Install VHS: downloads vhs_0.7.1_Linux_x86_64.tar.gz to RUNNER_TEMP with curl -f, checks the sha256 published in the release's checksums.txt, extracts only the vhs binary from the top of the archive, installs ttyd and ffmpeg from apt, and prints the vhs, ttyd and ffmpeg versions.", "Build tri runs zig build -Dci=true, as brain-ci.yml does, so the raylib GUI targets that need X11 and GL headers are skipped, and then runs zig-out/bin/tri --version.", "The Commit GIFs step (git add, commit, push) is replaced by actions/upload-artifact@v4, which uploads recordings/*.gif as terminal-demo-gifs with if-no-files-found: error and 30 days of retention.", "Triggers: push runs for main only, because a tag push ignores path filters and every release tag ran the job; pull_request runs when a tape or the workflow changes; workflow_dispatch stays. The job gets contents: read, a 30 minute timeout and one run per ref.", "tapes/*.tape: the visible cd ~/trinity-w1 becomes a hidden block that puts $PWD/zig-out/bin first on PATH and clears the screen, and Output writes recordings/<name>.gif. The typed commands are unchanged.", "docs/CLI_DEMOS_README.md renders the tapes from the repository root after zig build -Dci=true and says CI uploads an artifact; .gitignore ignores /recordings/." ], "tests": [ { "command": "gh run view 36894521838 --repo gHashTag/trinity --log-failed", "result": "Before this change Install VHS ends with exit code 8 on main and every later step is skipped", "status": "failed", "evidence": "Run of 2026-10-01 on main; the same failure on the v10.2.0 and v10.3.0 tag runs and on every branch run listed since 2026-09-20" }, { "command": "gh api repos/charmbracelet/vhs/releases/tags/v0.7.1, then curl the asset, shasum -a 256 and tar tzvf", "result": "The release lists vhs_0.7.1_Linux_x86_64.tar.gz and no linux_amd64 asset; the archive matches the published sha256 and holds the vhs binary at its top level", "status": "passed", "evidence": "sha256 748443e0b5df89475499330b8943bf650cf0627250290cd5a11d38d3859e96d4, identical to checksums.txt of v0.7.1" }, { "command": "gha_dryrun.py .github/workflows/record-demos.yml render, a driver that runs the job's steps as the runner does (bash -eo pipefail, GITHUB_PATH), in a clean ubuntu:24.04 amd64 container with a non-root runner user, sudo, Google Chrome and Zig 0.15.2", "result": "Install VHS installed ttyd 1.7.4 and ffmpeg 6.1.1 on an image that had neither, passed the sha256 check and printed vhs v0.7.1 (537d03a); Build tri passed, and a cold-cache zig build -Dci=true took 167 s before it", "status": "passed", "evidence": "Docker with Rosetta emulation on macOS, 2026-10-01; the first render then stopped at Chrome's namespace sandbox, which Docker's default seccomp profile blocks and the hosted runner VM does not" }, { "command": "The same driver and image with --security-opt seccomp=unconfined, on a fresh copy of the final branch files, so Chrome starts with its own sandbox and no VHS_NO_SANDBOX", "result": "All ten steps succeeded in 411 s under emulation; VHS created recordings/ itself and the upload step found five GIFs: tri-math-demo 275180, tri-benchmark 1986054, tri-test 126812, tri-status 124035 and tri-fpga-synth 143485 bytes", "status": "passed", "evidence": "First frames open at the prompt with the hidden PATH line absent, and last frames show the real output of each typed command, as listed under limitations" }, { "command": "actionlint 1.7.12 -shellcheck shellcheck 0.11.0 .github/workflows/record-demos.yml", "result": "No findings for the workflow, including its run scripts", "status": "passed", "evidence": "Local run on 2026-10-01 with release binaries of both tools, checksum checked for actionlint" }, { "command": "GitHub Actions: Terminal Demo GIFs on this pull request (pull_request event, ubuntu-latest)", "result": "All steps succeeded on ubuntu-latest in 5 min 40 s: Install VHS 25 s with the sha256 check OK and vhs v0.7.1, ttyd 1.7.4 and ffmpeg 6.1.1 printed, Build tri 65 s, five renders of 22 to 66 s each, and terminal-demo-gifs uploaded at 2539372 bytes", "status": "passed", "evidence": "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/gHashTag/trinity/actions/runs/36906462795" } ], "limitations": [ "The tapes still type the commands they always typed, and on this tri none of them shows a working feature: tri math demo, bind, similarity and phi print Unknown subcommand and the 121 line help, tri benchmark crashes with a segmentation fault in src/tvc/tvc_corpus.zig:145, tri test prints not yet implemented, tri status lists only .trinity/command_cache.json, and /fpga-synth is a Claude Code skill rather than a shell command. What the demos should show is for the owners to decide.", "Every tri invocation rewrites the tracked .trinity/command_cache.json and tri faculty rewrites two more files under .trinity, so the git status typed in later tapes shows those changes; the runner's checkout is discarded after the job.", "The GIFs are no longer committed anywhere. docs/CLI_DEMOS_README.md still embeds https://gHashTag.github.io/trinity/recordings/*.gif, which answer 404 because deploy-docs.yml publishes only apps/website/dist and docs/build; publishing them is a separate decision.", "examples/recordings/*.gif, committed on 2026-04-03, were rendered where tri was not on PATH and show bash: tri: command not found; this change does not replace them.", "The local dry runs used Docker with Rosetta amd64 emulation on macOS, where Chrome's namespace sandbox needs seccomp unconfined; the hosted runner is a virtual machine whose Ubuntu 24.04 AppArmor profile grants /opt/google/chrome/chrome user namespaces, and its run rendered all five tapes with no VHS_NO_SANDBOX set.", "In tri-benchmark each crash outlasts the tape's Sleep 4s on the hosted runner too, so the next command is typed into the middle of the stack trace; the tape's timing belongs with the decision about its commands.", "signal-health-self.yml and discover-callers.yml end in the same GH013 rejection on main every day; they are not touched here." ], "tags": [ "ci", "vhs", "demos", "workflows" ], "blog": { "title": "The demo GIF workflow ran for the first time past its install step", "summary": "Why Terminal Demo GIFs failed in under a second on every run, what the five steps behind the broken download had been hiding, and how a dry run of the whole job shaped the fix.", "outline": [ "Terminal Demo GIFs failed on every run, on main, on feature branches and on release tags, at the step that installs VHS: the download named an asset the v0.7.1 release does not publish, and even the right name would have been written to standard output instead of the file the next command extracted.", "Because that step failed first, nothing after it had ever executed, so the fix began with a dry run of the whole job in a runner-like Ubuntu 24.04 container to see what the build, the five tapes and the final commit step would actually do.", "The dry run showed a build that pulled in GUI targets, tapes that changed into one developer's home directory and wrote their GIFs to the wrong place, VHS dependencies the runner does not carry, and a final git push that the repository's own ruleset rejects on main.", "The job now installs VHS from a checksummed release asset together with ttyd and ffmpeg, builds tri the way brain-ci.yml does, renders each tape from the repository root, and uploads the GIFs as an artifact instead of pushing them, running only for main, for pull requests that touch the tapes, and on demand.", "What the GIFs show is a separate question the change deliberately leaves open: the commands the tapes type print help screens, not-yet-implemented notices or a crash on today's tri, and choosing what the demos should demonstrate belongs to the people who own them." ] } }Do not merge without the owner's go-ahead.
🤖 Generated with Claude Code