feat(terminal-demo): constrain and compose VHS tapes - #580
Merged
Conversation
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
internal/tape: a data-only parser for behavior-only VHS tapes and a canonical composer for the trusted presentation headerOutput,Set,Source,Require,Env,Screenshot,Copy,Paste,Hide,Show, and every per-directive@timing overridelimits.V1()bounds for tape bytes, directive count, typed bytes, wait patterns, key repeats, and sleep/wait totalsRefs #458
Contract boundaries
Parsing is data-only: it never invokes a shell, VHS, the filesystem, the environment, or the network, and it never matches a wait pattern. Regular expressions are compiled solely to validate syntax. Source line numbers are preserved for sanitized structured diagnosis.
Every rejection uses the existing sanitized boundary
failure.InvalidContract/failure.StageTape/failure.RuleTapeInvalidwith public exit code 2. No public class, stage, rule, or exit code was added or renamed. The structured field carries only a bounded schema-owned category and line number; a test asserts that neitherError()nor the field leaks tape source text, patterns, commands, or output paths.Composerequires the exact approved presentation config and independently revalidates each directive, so a caller that constructs aDirectivewithoutParsecannot bypass the contract.Kindis a closed enum.Base reconciliation
The written plan and Task 3 brief name base
bd6234ac4e5ab6eebc109c76ce9d21672144da5don an isolatedfeature-458worktree. That state no longer exists: PR #460 merged on 2026-07-25 as6f6b825b, nofeature-458branch survived on origin, andbd6234ac:tools/readme-terminal-demodiffers fromorigin/main:tools/readme-terminal-demoacross 9 files. Building on the recorded base would have discarded the merged review fixes, so this work is based on currentorigin/main, which containsbd6234acas an ancestor. No Task 1-2 behavior changed.Verification against real VHS v0.11.0
The composed golden tape was fed to the actual VHS v0.11.0 lexer and parser in the pinned Go image: 0 parse errors, 18 commands,
Ctrl+"L"resolving to argsL, and eachWait@10s/Wait+Line@10s/Wait+Screen@10scarrying its fixed timeout. Upstream source confirms the assumptions encoded here:lexer.readStringperforms no escape interpretation and cannot span a newline, andreadRegexuses the odd-backslash delimiter rule.Defects found and fixed during TDD
1m30sare rejected during composition. VHSparseTimeaccepts exactly one number plus one unit and would misparse the compound Go duration form.Verification
All commands ran through the pinned
scripts/in-go-image.shwrapper (Go 1.26.5,linux/amd64); host Go was never an acceptance path.go test ./internal/tape -count=1: PASS, 14 top-level testsgo test ./internal/tape -run 'TestParseRejects|TestComposeGolden' -count=1: PASS, 59 rejection subtests, byte-stable goldengo test ./... -count=1: PASS, includinginternal/sandboxgo vet ./...: cleangofmt -l .: cleango mod tidy -diff: reports only the pre-existing Goldmark pin reserved by the approved plan for later README verification; this change introduces no module driftStatus
This is a draft implementation PR. Task 4 and later repository opening, fixture staging, README validation, rendering, render/verify orchestration, workflow and image publication, pilots, merge, release, and pattern promotion remain outstanding and maintainer-gated. No image publication, release tag, merge, pilot rollout, or pattern promotion has occurred.