Installs into .claude/skills of the current project.
Are you the author of Motion Verify?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/wlsdks-motion-verify)
---
name: motion-verify
description: Verify changed Atlas motion through a real screen recording when motion proof is requested or selected by design routing.
---
# Motion verification from a recording
Screenshots prove only that an animation reaches sampled states. Jank and frozen
frames hide between them. Record the real macOS display, extract uniform frames,
inspect a phase strip, then measure adjacent-frame change. This method found the
spotlight ring's speed and braided-orbit defects in 2026-07-23.
Run whenever `pnpm design:route` includes `motion-verify`. This is the completion
proof for temporal output, not an optional craft review.
## Preconditions
- The surface is visible on a real monitor. Headless sequential screenshots may
diagnose a defect but cannot approve motion; if recording is unavailable,
report the proof as deferred.
- Resolve available `ffmpeg` and `ffprobe` executables; the Homebrew path is
an example, not a requirement. Report missing instrumentation before recording.
- Inspect native motion at **60 fps minimum**. Verify the source recording's
frame rate and timestamps before extraction. A 30 fps recording resampled to
60 fps duplicates frames and cannot establish 60 fps smoothness; re-record it.
A 120 fps source may also be inspected at its native rate for a 120 Hz claim.
- Put recordings and frames in an external session scratch directory.
- Capture the same app/window/state through the computer-use capability so the accessibility
owner and screenshot bind the recording to the reviewed surface.
## 1. Prepare a deterministic state
Set the exact URL, zoom, and state. The map sleeps while idle, so confirm the
motion keeps it awake and disable simulated reduced motion unless that is the
subject.
Add `?guides=off`. A first-run overlay contaminates the opening frames; closing it
by hand adds its own animation and focus change. Use `?guides=reset` only when the
guide itself is under test.
## 2. Record and extract
```bash
cd <scratch-directory>
screencapture -v -V 4 motion.mov
mkdir -p vidframes
ffprobe -v error -select_streams v:0 -show_entries stream=width,height,r_frame_rate,avg_frame_rate,nb_frames,duration -of json motion.mov
ffprobe -v error -select_streams v:0 -show_entries frame=best_effort_timestamp_time -of csv=p=0 motion.mov > frame-times.csv
ffmpeg -y -loglevel error -i motion.mov -vf fps=60 vidframes/f%04d.png
```
Keep the original timestamps alongside the extracted frames. Check source-frame
gaps against the 16.67 ms cadence as well as pixel changes: constant-rate
extraction can hide a delayed source frame by repeating it. Report duplicates,
consecutive frozen-frame runs, and their duration in milliseconds within the
active motion interval. Exclude only observed intentional holds or rest states.
## 3. Find the crop carefully
Page coordinates differ from recording coordinates because of Retina scaling and
window position. Colour can locate candidates but cannot identify motion. A prior
amber-ring search cropped a static project hexagon and almost concluded that the
ring was frozen. Build and inspect a strip for candidate crops before computing
statistics.
## 4. Build a phase strip
Sample six frames 166ms apart and inspect them visually:
```python
from PIL import Image
box = (x0, y0, x1, y1)
strip = Image.new("RGB", (320 * 6, 320))
for k, i in enumerate([1, 11, 21, 31, 41, 51]):
frame = Image.open(f"vidframes/f{i:04d}.png").convert("RGB")
strip.paste(frame.crop(box).resize((320, 320)), (k * 320, 0))
strip.save("phase-strip.png")
```
Identify the active transition or continuous-motion interval in the strip.
Expected resting frames before or after a finite transition are not stalls.
Select that active interval for statistics; report its bounds and retain the
full recording so the selection can be checked.
## 5. Measure adjacent-frame change
```python
from PIL import Image
import statistics
from pathlib import Path
# Set start_frame/end_frame from the phase strip (zero-based, end exclusive).
frames = sorted(Path("vidframes").glob("f*.png"))[start_frame:end_frame]
if len(frames) < 2:
raise ValueError("Active interval needs at least two recorded frames")
prev, diffs = None, []
for path in frames:
frame = Image.open(path).convert("L").crop(box)
if prev is not None:
a, b = frame.tobytes(), prev.tobytes()
samples = [abs(a[j] - b[j]) for j in range(0, len(a), 7)]
if not samples:
raise ValueError("The crop contains no pixels")
diffs.append(statistics.mean(samples))
prev = frame
mean = statistics.mean(diffs)
if mean == 0:
raise ValueError("No change in the selected active interval; verify target and motion")
sd = statistics.pstdev(diffs)
stalls = [i for i, d in enumerate(diffs) if d < mean * 0.25]
spikes = [i for i, d in enumerate(diffs) if d > mean * 3]
print(f"mean={mean:.3f} cv={sd/mean:.2f} min={min(diffs):.3f} stalls={len(stalls)} spikes={len(spikes)}")
```
- `stalls == 0` is the primary pass condition within the declared active interval.
Do not apply it to an intentional hold or the settled state of a finite transition.
- Consecutive stalls suggest idle-gate sleep or dropped browser frames; inspect
`src/widgets/ontology-map/model/idle-gate.ts` activity flags first.
- `cv <= 0.4` is usually compression noise. Periodic spikes may be another motion;
identify them in the phase strip.
- Do not judge pleasing speed from the statistic. Inspect the strip and apply the
HIG principle that motion must not compete with content. Repeating above roughly
twice per second is suspicious; this slowed the spotlight orbit to 750ms.
## Report
Open with the verdict in one line (approved, or the stall or defect), then state
app/window/route, Computer Use screenshot path and accessibility owner,
recording duration and fps, crop target, stalls and cv, the visual phase-strip
finding, reduced-motion result, and before/after values when tuned. Keep raw
recordings and frames in scratch, not the repository. No recording means no
motion approval.