Verify the Handoff Before You Rerun an ML Video Experiment A CloudGPU-authored tutorial published a Python 3.10+ integrity gate that builds a SHA-256 manifest of relative paths and content digests for an ML video experiment handoff folder, then refuses verification when the project no longer matches that manifest. The script, handoff.py, uses pathlib traversal, hashlib.sha256, JSON serialization and argparse, rejects symbolic links and non-regular files, and requires the manifest to live outside the inventoried project. The author states the gate is not a quality evaluator or environment restorer and does not run a model, generate a video, or prove a remote compute workflow succeeds. This tutorial contains AI-generated text and code. I work on CloudGPU. The example below validates a local, synthetic project folder; it does not run a model, generate a video, or establish that any remote compute workflow succeeds. An ML video experiment rarely consists of a single output. A reviewer may need the workflow configuration, the input description, an acceptance rule, and the record explaining which variation produced the candidate. When those files travel separately, a plausible filename can conceal an accidental mismatch. A later reviewer can open a result successfully while reading the instructions for a different attempt. This tutorial builds a small integrity gate using Python’s standard library. The gate creates a manifest of relative paths and content digests, then refuses verification when the project no longer matches that manifest. It is useful before moving experiment artifacts between a batch worker, a project-file store, and a review machine. It is not a quality evaluator, an environment restorer, or a replacement for a trusted record of who approved the experiment. Start with a narrow promise: the received project contains exactly the files described by a trusted manifest, and their contents match. Do not promise that the project will execute identically on another machine. Different dependencies, drivers, kernels, hardware and runtime settings can change behavior even when every project file is intact. For a video comparison, write the acceptance rule before running anything. For example, a reviewer might require a character to remain inside the frame throughout a shot. That creative rule is separate from technical checks such as whether a file opens. This tutorial implements neither video decoding nor creative judgment. It ensures that the files supporting those later checks are the same files you intended to review. Use a staging folder containing only material that belongs in the handoff. Keep credentials, temporary access links, caches and unrelated personal files outside it. The example inventories every regular file inside the selected folder. It has no secret detector, so selecting the folder is a deliberate responsibility rather than an automatic privacy boundary. Use Python 3.10 or newer. Save the following as create fixture.py in a fresh working folder. The files are invented local fixtures, not evidence from a rendering run. A new folder keeps the exercise separate from an existing project. python from pathlib import Pathimport json root = Path "demo project" root.mkdir exist ok=False root / "workflow.json" .write text json.dumps {"revision": "fixture-a", "seed": 7}, sort keys=True , encoding="utf-8", root / "review.txt" .write text "Synthetic fixture only. Check that the character stays in frame.\n", encoding="utf-8", root / "environment.txt" .write text "No rendering environment was created for this fixture.\n", encoding="utf-8", Run python3 create fixture.py. The separate environment note prevents a reviewer from interpreting the sample as a completed GPU trial. In a real project, record the actual runtime and dependency versions after observing them, not from an assumed template. A dependency specification is an input to rebuilding an environment; it does not prove the environment has been rebuilt. Save this as handoff.py. The implementation uses documented pathlib traversal, hashlib.sha256, JSON serialization and argparse command parsing 1–4 . It rejects symbolic links and non-regular files so a handoff cannot quietly reach outside the selected project through a link. The manifest itself must live outside the project being inventoried. python import argparseimport hashlibimport jsonfrom pathlib import Path python def project root value : path = Path value if path.is symlink : raise ValueError "project root must not be a symbolic link" path = path.resolve strict=True if not path.is dir : raise ValueError "project root must be a directory" return path python def inventory root : records = for path in sorted root.rglob " " : if path.is symlink : raise ValueError "symbolic links are not accepted" if path.is dir : continue if not path.is file : raise ValueError "only regular files are accepted" digest = hashlib.sha256 with path.open "rb" as handle: for chunk in iter lambda: handle.read 1048576 , b"" : digest.update chunk records.append { "path": path.relative to root .as posix , "sha256": digest.hexdigest , } if not records: raise ValueError "project must contain at least one file" return {"schema": 1, "files": records} python def main : parser = argparse.ArgumentParser parser.add argument "action", choices= "freeze", "verify" parser.add argument "project" parser.add argument "manifest" args = parser.parse args root = project root args.project target = Path args.manifest .resolve if target.is relative to root : raise ValueError "keep the manifest outside the project" current = inventory root if args.action == "freeze": payload = json.dumps current, sort keys=True, indent=2 + "\n" with target.open "x", encoding="utf-8" as handle: handle.write payload print "manifest created" else: expected = json.loads target.read text encoding="utf-8" if expected = current: raise ValueError "project differs from the trusted manifest" print "project matches manifest" if name == " main ": try: main except OSError, ValueError as error: raise SystemExit str error The manifest stores content digests rather than modification times. Copying a file can alter its timestamp without changing its content, while editing a file may leave its descriptive name untouched. Sorted traversal gives the manifest a stable order for an unchanged file tree. The verifier compares the entire structure, so unexpected additions and missing files fail as well as changed contents. Notice that the verifier never opens paths taken from the manifest. It independently inventories the chosen folder and compares data structures. A forged entry containing a parent-directory path therefore cannot instruct the verifier to read that path. This is deliberately a verification tool, not an archive extractor or a file-restoration tool. First compile both programs. The official py compile command checks syntax; it does not prove runtime correctness 5 . Then run the fixture and verify it: python3 -m py compile create fixture.py handoff.pypython3 create fixture.pypython3 handoff.py freeze demo project manifest.jsonpython3 handoff.py verify demo project manifest.json If you already ran the fixture creation step, do not run it again in the same folder. Its refusal to reuse an existing folder is intentional. The manifest also uses exclusive creation rather than silently replacing an earlier experiment record. For a legitimate revision, choose a new project folder and a new manifest name. The unchanged fixture should produce project matches manifest. Now save the next fragment as change fixture.py and execute it. This is a controlled alteration of the synthetic fixture, not a recommended way to edit production artifacts. python from pathlib import PathPath "demo project/review.txt" .write text "Synthetic fixture with an intentionally changed review rule.\n", encoding="utf-8", Run python3 change fixture.py, followed by the verify command again. Verification should exit unsuccessfully with project differs from the trusted manifest. Keep the original manifest. Generating a replacement merely to make the check pass would erase the distinction between an accepted input and an accidental change. During preparation, the local fixture passed unchanged verification and rejected a changed file. Separate local cases also checked additions, deletions, symbolic links, an empty project, an inside-project manifest, and a forged parent-directory entry. These are local correctness checks only. No inference result, GPU throughput, memory measurement or model-quality result is implied. For a real ML job, freeze the intended inputs before transferring them, preserve the manifest in an independently trusted location, and verify after transfer. Write outputs into a separate staging folder. Record the actual workflow revision and environment there, then create a different output manifest when writing has stopped. Verify the received output folder before treating the handoff as complete. A project-file store is not a whole-machine snapshot. Restoring project files does not restore installed dependencies, an operating system or drivers. Rebuild the execution environment explicitly and perform a separate readiness check before running the workload. If a managed service separates GPU and storage controls, a GPU budget must not be interpreted as covering storage fees; verify storage eligibility, quotas and retention independently. This process assumes neither unlimited storage nor automatic output collection. There are important limits. A digest detects a difference against a trusted baseline; it does not authenticate a baseline an attacker can replace. Files must be quiescent during traversal, because this program does not take an atomic snapshot or prevent concurrent modification. Directory metadata, permissions and empty directories are outside its contract. Large projects may need a more selective inventory or a storage-native integrity mechanism. Finally, successful verification says nothing about whether a video decodes, satisfies its brief, or was produced from those inputs. Those require separate evidence and review. The CloudGPU video “How to Make an AI Short Drama Without Wasting GPU Minutes” provides related workflow context; it is not a demonstration or validation of this Python manifest implementation. The title and the @cloudgpu app channel were checked using YouTube oEmbed. In Medium, paste this standalone URL on its own line and use Medium’s native video embed; the actual rendered embed still needs an editor check: https://www.youtube.com/watch?v=EOc5rh8MfVk https://www.youtube.com/watch?v=EOc5rh8MfVk Verify the Handoff Before You Rerun an ML Video Experiment https://pub.towardsai.net/verify-the-handoff-before-you-rerun-an-ml-video-experiment-c00fcde6399e was originally published in Towards AI https://pub.towardsai.net on Medium, where people are continuing the conversation by highlighting and responding to this story.