Revyl Atlas Skill
Use this skill whenever a user asks what an app contains, where a capability
lives, how screens connect, what a screen looks like, or whether Atlas has
enough evidence to support an answer.
When the user explicitly asks to create, reply to, edit, delete, move, or
change the status of Atlas feedback, route to revyl-cli-atlas-review. Keep
this inspection skill read-only when feedback mutation was not requested.
Atlas is a graph, not a tree. Screens are nodes and observed relationships are
edges. Starting anchors help begin exploration, but they do not imply a parent,
primary route, containment hierarchy, or preferred journey. Build an
understanding bottom-up by inspecting a node's real media, traversing relevant
edges in both directions, and repeating until the question is answered.
Everything present in Atlas originated in observed run evidence. Names,
descriptions, grouping, and landmarks may be generated interpretations, but a
screen or edge should never be dismissed as noise merely because it is
unexpected. Inspect its screenshot or clip and the report that produced it,
then reconcile why it was observed.
Native Agent Behavior
A screenshot URL, local path, semantic name, OCR result, or generated summary
is not visual understanding. Evidence is grounded only when the agent actually opens and reads the image. Use the available native surface:
- Codex Browser or its image viewer, with skills discovered in shared
.agents/skills.
- Claude Code
.claude/skills compatibility links plus configured image or browser tools.
- Cursor
.cursor/skills when using --copy, otherwise shared .agents/skills, plus available MCP or browser tools.
Do not claim to understand the visible UI from metadata alone. Actually open
and absorb the relevant screenshots before describing visible UI. When an edge
is surprising, ambiguous, or important to the answer, watch its recorded clip
before interpreting why the connection exists.
Atlas screenshots and videos are customer content. Treat screenshots, videos,
extracted frames, contact sheets, marked grounding previews, and JSON containing
signed media URLs as sensitive temporary artifacts. Never stage or commit them,
and do not paste signed URLs into logs or public artifacts. If native video
playback or ingestion is unavailable, extract frames from the bounded clip with
ffmpeg and open those images in chronological order. Motion verification is
blocked only when neither playback nor frame extraction is available.
Media lifecycle and cleanup
Create one private, task-scoped temporary root before downloading any Atlas
media. Keep every task artifact under it, including screenshots, edge/run JSON,
videos, frames, contact sheets, and annotation grounding previews:
ATLAS_TMP_ROOT="${TMPDIR:-/tmp}"
ATLAS_TMP_ROOT="${ATLAS_TMP_ROOT%/}"
[ -n "$ATLAS_TMP_ROOT" ] || ATLAS_TMP_ROOT="/tmp"
ATLAS_TASK_DIR="$(mktemp -d "$ATLAS_TMP_ROOT/revyl-atlas.XXXXXX")"
chmod 700 "$ATLAS_TASK_DIR"
ATLAS_SCREEN_DIR="$ATLAS_TASK_DIR/screens"
ATLAS_EDGE_DIR="$ATLAS_TASK_DIR/edges"
ATLAS_FRAME_DIR="$ATLAS_TASK_DIR/frames"
# Target for `revyl atlas annotations create/move --dry-run --preview-out`.
ATLAS_PREVIEW_DIR="$ATLAS_TASK_DIR/previews"
mkdir -p "$ATLAS_SCREEN_DIR" "$ATLAS_EDGE_DIR" "$ATLAS_FRAME_DIR" "$ATLAS_PREVIEW_DIR"
cleanup_atlas_media() {
if [ -n "${ATLAS_TASK_DIR:-}" ] && [ -d "$ATLAS_TASK_DIR" ]; then
case "$ATLAS_TASK_DIR" in
"$ATLAS_TMP_ROOT"/revyl-atlas.*)
[ "${ATLAS_TASK_DIR%/*}" = "$ATLAS_TMP_ROOT" ] || return 1
rm -rf -- "$ATLAS_TASK_DIR"
;;
*)
echo "Refusing to remove unexpected Atlas path: $ATLAS_TASK_DIR" >&2
return 1
;;
esac
fi
}
trap cleanup_atlas_media EXIT
trap 'exit 130' INT
trap 'exit 129' HUP
trap 'exit 143' TERM
Apply these rules throughout the task:
- Do not put working media in the repository, workspace, current directory,
.context/, or the skill directory. A relative --screenshot-dir shown in a
pasted example is not a request to retain files; translate it to the task temp
directory.
- Use one temp root for the whole task rather than scattered
mktemp files.
Set JSON containing signed URLs to mode 0600.
- If tool calls run in separate shells, preserve the absolute task-temp path in
working state and perform the guarded cleanup explicitly before the final
response; do not assume an earlier shell's
trap is still active.
- Delete media as soon as it is no longer needed, and always clean the entire
task root after Atlas writes have been verified, including on errors or
interruption.
- Before handoff, verify the temp root no longer exists and inspect
git status
plus the staged diff for task-created Atlas artifacts. If any were created by
the task, unstage and remove them without disturbing unrelated user changes.
- Retain or export media only when the user explicitly asks to keep specific
artifacts. Copy only those requested files to the agreed destination, never
stage them automatically, disclose the path, and still delete the remaining
task temp root. Signed-URL JSON remains temporary unless explicitly required.
Required traversal workflow
Resolve the app:
revyl atlas apps --search "<app name>" --json
Get a compact orientation and download its bounded visual sample:
revyl atlas brief --app <app-id> --screenshots --screenshot-dir "$ATLAS_SCREEN_DIR" --json
Read projection.data_source. Treat starting_anchors as typed suggestions:
curated_entry, semantic_entry, and observed_root explain why each node
is a useful starting point. They are not ranks or parents.
Open every selected visual_sample[].local_screenshot_path. Record what is
visibly present: layout, labels, controls, state, platform chrome, overlays,
and obvious errors. Reconcile these facts with Atlas semantics and call out
mismatches.
Load the flat graph when the question spans the app, or search for a
question-specific node:
revyl atlas graph --app <app-id> --json
revyl atlas search "<capability or UI concept>" --app <app-id> --json
The graph contains flat nodes, edges, and starting_anchors. Do not turn
it into a recursive tree or choose one incoming edge as the real parent.
Check top-level truncated or has_more before claiming the traversal covers
the complete app graph.
Pick the most relevant anchor or search result, inspect it, then traverse:
revyl atlas screen <screen-id> --app <app-id> --screenshots --screenshot-dir "$ATLAS_SCREEN_DIR" --json
revyl atlas observations <screen-id> --app <app-id> --screenshots --screenshot-dir "$ATLAS_SCREEN_DIR" --json
revyl atlas neighbors <screen-id> --app <app-id> --json
Open the representative and question-relevant grouped screenshots. Follow
both incoming and outgoing edges when either could explain the capability.
Keep a small visited set of screen IDs and edge keys so cycles and shared
nodes do not cause repeated work.
If a screen or observation is unexpected, inspect the report that produced
it before deciding what it represents:
revyl atlas report <screen-or-observation-id> --app <app-id> --json
A screen ID resolves through its representative observation. An observation
ID resolves the exact evidence item. Read the report's test goal, steps,
actions, result, and workflow_execution_id when present. This often
distinguishes intended app behavior from test setup, system UI, an external
handoff, a failure path, or genuinely bad evidence.
For each traversed connection, distinguish observation from interpretation.
An edge proves that Atlas observed a relationship; it does not prove product
hierarchy or user intent. If the connection is misunderstood, conflicts with
the screenshots, or materially supports the answer, inspect its runs:
revyl atlas edge <source-id> <target-id> --app <app-id> --runs --json
Open evidence[].runs.active_video.video_url with a video-capable tool and
watch the interval bounded by source_video_start and source_video_end.
Identify the visible source state, exact action or redirect, and landed
target state. Classify it as direct navigation, tab switching,
back/dismissal, overlay presentation, automatic redirect, or likely bad
evidence.
When native video ingestion is unavailable, save the JSON and extract a
small bounded frame sequence. Read the newest run's signed URL and start/end
timestamps from the JSON without printing them, then run:
EDGE_JSON="$ATLAS_EDGE_DIR/<source-id>--<target-id>.json"
EDGE_FRAME_DIR="$ATLAS_FRAME_DIR/<source-id>--<target-id>"
mkdir -p "$EDGE_FRAME_DIR"
: > "$EDGE_JSON"
chmod 600 "$EDGE_JSON"
revyl atlas edge <source-id> <target-id> --app <app-id> --runs --json > "$EDGE_JSON"
ffmpeg -loglevel error -ss <source-video-start> -i "<active-video-url>" \
-t <clip-duration-seconds> -vf fps=2 "$EDGE_FRAME_DIR/frame-%03d.jpg"
Open the extracted frames in filename order and compare the source state,
interaction, intermediate state, and destination. Increase the frame rate
only if the decisive interaction falls between frames. Remove an edge's JSON
and frames once no further comparison is needed; the final task cleanup is
still mandatory.
The run objects expose report_id, execution_id, and session_id. For an
unclear edge, review the exact report that generated that run—not merely a
representative report from either endpoint screen:
revyl test report <execution-id> --json
# If only a session is present:
revyl device report --session-id <session-id> --json
If the report includes a workflow execution, continue into
revyl workflow report <workflow-execution-id> --json. Use the test goal and
preceding steps to explain why the action occurred and whether Atlas modeled
the observation correctly.
If the cause remains unclear, work backward: inspect the source node's
incoming neighbors, then watch the preceding edge clip. Repeat only until
the triggering action or entry state is understood. If runs disagree,
inspect a bounded two or three representative clips and report the conflict.
Continue outward only along question-relevant edges. Stop when the claim is
supported by opened media and the necessary graph neighborhood, not merely
when a plausible generated summary appears.
After any requested Atlas writes are read back and verified, run the guarded
media cleanup before replying. Confirm that ATLAS_TASK_DIR is absent and
that no task-created Atlas media appears in the working tree or staged diff.
For a product-area question, use its induced subgraph. Boundary edges are part
of the answer because they show how the area connects to the rest of the app:
revyl atlas area "<product area>" --app <app-id> --json
Evidence budget
- App overview: open 3-6 representative screens across major areas, beginning
with anchors and expanding through connected nodes.
- Focused screen question: open 1-3 distinct observations and the directly
relevant neighbors.
- Journey question: discover the route by graph traversal; open each materially
distinct screen and inspect ambiguous or decisive edge clips.
- Misunderstood edge: inspect the newest clip first, then at most 2-3 runs when
evidence disagrees; review the exact originating report before classifying
the connection.
Expand only when evidence conflicts or the question remains unanswered. Do not
bulk-download the entire Atlas by default.
Answer contract
Separate graph-supported facts, visually confirmed facts, clip-confirmed
actions, interpretations, and unresolved gaps. Preserve screen IDs and edge
keys in working notes so every conclusion remains attached to stable graph
entities. Never infer pixel-level details, motion, containment, or a preferred
journey from metadata or edge existence alone. Never call unexpected evidence
useless or exclude it until its media and originating report have been
inspected.
1---2name: revyl-cli-atlas3description: Explore an app bottom-up as a media-grounded knowledge graph, including its screenshots, transition clips, and originating reports.4---56# Revyl Atlas Skill78Use this skill whenever a user asks what an app contains, where a capability9lives, how screens connect, what a screen looks like, or whether Atlas has10enough evidence to support an answer.1112When the user explicitly asks to create, reply to, edit, delete, move, or13change the status of Atlas feedback, route to `revyl-cli-atlas-review`. Keep14this inspection skill read-only when feedback mutation was not requested.1516Atlas is a graph, not a tree. Screens are nodes and observed relationships are17edges. Starting anchors help begin exploration, but they do not imply a parent,18primary route, containment hierarchy, or preferred journey. Build an19understanding bottom-up by inspecting a node's real media, traversing relevant20edges in both directions, and repeating until the question is answered.2122Everything present in Atlas originated in observed run evidence. Names,23descriptions, grouping, and landmarks may be generated interpretations, but a24screen or edge should never be dismissed as noise merely because it is25unexpected. Inspect its screenshot or clip and the report that produced it,26then reconcile why it was observed.2728## Native Agent Behavior2930A screenshot URL, local path, semantic name, OCR result, or generated summary31is not visual understanding. Evidence is grounded only when the agent actually opens and reads the image. Use the available native surface:3233- Codex Browser or its image viewer, with skills discovered in shared `.agents/skills`.34- Claude Code `.claude/skills` compatibility links plus configured image or browser tools.35- Cursor `.cursor/skills` when using `--copy`, otherwise shared `.agents/skills`, plus available MCP or browser tools.3637Do not claim to understand the visible UI from metadata alone. Actually open38and absorb the relevant screenshots before describing visible UI. When an edge39is surprising, ambiguous, or important to the answer, watch its recorded clip40before interpreting why the connection exists.4142Atlas screenshots and videos are customer content. Treat screenshots, videos,43extracted frames, contact sheets, marked grounding previews, and JSON containing44signed media URLs as sensitive temporary artifacts. Never stage or commit them,45and do not paste signed URLs into logs or public artifacts. If native video46playback or ingestion is unavailable, extract frames from the bounded clip with47`ffmpeg` and open those images in chronological order. Motion verification is48blocked only when neither playback nor frame extraction is available.4950## Media lifecycle and cleanup5152Create one private, task-scoped temporary root before downloading any Atlas53media. Keep every task artifact under it, including screenshots, edge/run JSON,54videos, frames, contact sheets, and annotation grounding previews:5556```bash57ATLAS_TMP_ROOT="${TMPDIR:-/tmp}"58ATLAS_TMP_ROOT="${ATLAS_TMP_ROOT%/}"59[ -n "$ATLAS_TMP_ROOT" ] || ATLAS_TMP_ROOT="/tmp"60ATLAS_TASK_DIR="$(mktemp -d "$ATLAS_TMP_ROOT/revyl-atlas.XXXXXX")"61chmod 700 "$ATLAS_TASK_DIR"6263ATLAS_SCREEN_DIR="$ATLAS_TASK_DIR/screens"64ATLAS_EDGE_DIR="$ATLAS_TASK_DIR/edges"65ATLAS_FRAME_DIR="$ATLAS_TASK_DIR/frames"66# Target for `revyl atlas annotations create/move --dry-run --preview-out`.67ATLAS_PREVIEW_DIR="$ATLAS_TASK_DIR/previews"68mkdir -p "$ATLAS_SCREEN_DIR" "$ATLAS_EDGE_DIR" "$ATLAS_FRAME_DIR" "$ATLAS_PREVIEW_DIR"6970cleanup_atlas_media() {71 if [ -n "${ATLAS_TASK_DIR:-}" ] && [ -d "$ATLAS_TASK_DIR" ]; then72 case "$ATLAS_TASK_DIR" in73 "$ATLAS_TMP_ROOT"/revyl-atlas.*)74 [ "${ATLAS_TASK_DIR%/*}" = "$ATLAS_TMP_ROOT" ] || return 175 rm -rf -- "$ATLAS_TASK_DIR"76 ;;77 *)78 echo "Refusing to remove unexpected Atlas path: $ATLAS_TASK_DIR" >&279 return 180 ;;81 esac82 fi83}8485trap cleanup_atlas_media EXIT86trap 'exit 130' INT87trap 'exit 129' HUP88trap 'exit 143' TERM89```9091Apply these rules throughout the task:9293- Do not put working media in the repository, workspace, current directory,94 `.context/`, or the skill directory. A relative `--screenshot-dir` shown in a95 pasted example is not a request to retain files; translate it to the task temp96 directory.97- Use one temp root for the whole task rather than scattered `mktemp` files.98 Set JSON containing signed URLs to mode `0600`.99- If tool calls run in separate shells, preserve the absolute task-temp path in100 working state and perform the guarded cleanup explicitly before the final101 response; do not assume an earlier shell's `trap` is still active.102- Delete media as soon as it is no longer needed, and always clean the entire103 task root after Atlas writes have been verified, including on errors or104 interruption.105- Before handoff, verify the temp root no longer exists and inspect `git status`106 plus the staged diff for task-created Atlas artifacts. If any were created by107 the task, unstage and remove them without disturbing unrelated user changes.108- Retain or export media only when the user explicitly asks to keep specific109 artifacts. Copy only those requested files to the agreed destination, never110 stage them automatically, disclose the path, and still delete the remaining111 task temp root. Signed-URL JSON remains temporary unless explicitly required.112113## Required traversal workflow1141151. Resolve the app:116117 ```bash118 revyl atlas apps --search "<app name>" --json119 ```1201212. Get a compact orientation and download its bounded visual sample:122123 ```bash124 revyl atlas brief --app <app-id> --screenshots --screenshot-dir "$ATLAS_SCREEN_DIR" --json125 ```126127 Read `projection.data_source`. Treat `starting_anchors` as typed suggestions:128 `curated_entry`, `semantic_entry`, and `observed_root` explain why each node129 is a useful starting point. They are not ranks or parents.1301313. Open every selected `visual_sample[].local_screenshot_path`. Record what is132 visibly present: layout, labels, controls, state, platform chrome, overlays,133 and obvious errors. Reconcile these facts with Atlas semantics and call out134 mismatches.1351364. Load the flat graph when the question spans the app, or search for a137 question-specific node:138139 ```bash140 revyl atlas graph --app <app-id> --json141 revyl atlas search "<capability or UI concept>" --app <app-id> --json142 ```143144 The graph contains flat `nodes`, `edges`, and `starting_anchors`. Do not turn145 it into a recursive tree or choose one incoming edge as the real parent.146 Check top-level `truncated` or `has_more` before claiming the traversal covers147 the complete app graph.1481495. Pick the most relevant anchor or search result, inspect it, then traverse:150151 ```bash152 revyl atlas screen <screen-id> --app <app-id> --screenshots --screenshot-dir "$ATLAS_SCREEN_DIR" --json153 revyl atlas observations <screen-id> --app <app-id> --screenshots --screenshot-dir "$ATLAS_SCREEN_DIR" --json154 revyl atlas neighbors <screen-id> --app <app-id> --json155 ```156157 Open the representative and question-relevant grouped screenshots. Follow158 both incoming and outgoing edges when either could explain the capability.159 Keep a small visited set of screen IDs and edge keys so cycles and shared160 nodes do not cause repeated work.161162 If a screen or observation is unexpected, inspect the report that produced163 it before deciding what it represents:164165 ```bash166 revyl atlas report <screen-or-observation-id> --app <app-id> --json167 ```168169 A screen ID resolves through its representative observation. An observation170 ID resolves the exact evidence item. Read the report's test goal, steps,171 actions, result, and `workflow_execution_id` when present. This often172 distinguishes intended app behavior from test setup, system UI, an external173 handoff, a failure path, or genuinely bad evidence.1741756. For each traversed connection, distinguish observation from interpretation.176 An edge proves that Atlas observed a relationship; it does not prove product177 hierarchy or user intent. If the connection is misunderstood, conflicts with178 the screenshots, or materially supports the answer, inspect its runs:179180 ```bash181 revyl atlas edge <source-id> <target-id> --app <app-id> --runs --json182 ```183184 Open `evidence[].runs.active_video.video_url` with a video-capable tool and185 watch the interval bounded by `source_video_start` and `source_video_end`.186 Identify the visible source state, exact action or redirect, and landed187 target state. Classify it as direct navigation, tab switching,188 back/dismissal, overlay presentation, automatic redirect, or likely bad189 evidence.190191 When native video ingestion is unavailable, save the JSON and extract a192 small bounded frame sequence. Read the newest run's signed URL and start/end193 timestamps from the JSON without printing them, then run:194195 ```bash196 EDGE_JSON="$ATLAS_EDGE_DIR/<source-id>--<target-id>.json"197 EDGE_FRAME_DIR="$ATLAS_FRAME_DIR/<source-id>--<target-id>"198 mkdir -p "$EDGE_FRAME_DIR"199 : > "$EDGE_JSON"200 chmod 600 "$EDGE_JSON"201 revyl atlas edge <source-id> <target-id> --app <app-id> --runs --json > "$EDGE_JSON"202 ffmpeg -loglevel error -ss <source-video-start> -i "<active-video-url>" \203 -t <clip-duration-seconds> -vf fps=2 "$EDGE_FRAME_DIR/frame-%03d.jpg"204 ```205206 Open the extracted frames in filename order and compare the source state,207 interaction, intermediate state, and destination. Increase the frame rate208 only if the decisive interaction falls between frames. Remove an edge's JSON209 and frames once no further comparison is needed; the final task cleanup is210 still mandatory.211212 The run objects expose `report_id`, `execution_id`, and `session_id`. For an213 unclear edge, review the exact report that generated that run—not merely a214 representative report from either endpoint screen:215216 ```bash217 revyl test report <execution-id> --json218 # If only a session is present:219 revyl device report --session-id <session-id> --json220 ```221222 If the report includes a workflow execution, continue into223 `revyl workflow report <workflow-execution-id> --json`. Use the test goal and224 preceding steps to explain why the action occurred and whether Atlas modeled225 the observation correctly.226227 If the cause remains unclear, work backward: inspect the source node's228 incoming neighbors, then watch the preceding edge clip. Repeat only until229 the triggering action or entry state is understood. If runs disagree,230 inspect a bounded two or three representative clips and report the conflict.2312327. Continue outward only along question-relevant edges. Stop when the claim is233 supported by opened media and the necessary graph neighborhood, not merely234 when a plausible generated summary appears.2352368. After any requested Atlas writes are read back and verified, run the guarded237 media cleanup before replying. Confirm that `ATLAS_TASK_DIR` is absent and238 that no task-created Atlas media appears in the working tree or staged diff.239240For a product-area question, use its induced subgraph. Boundary edges are part241of the answer because they show how the area connects to the rest of the app:242243```bash244revyl atlas area "<product area>" --app <app-id> --json245```246247## Evidence budget248249- App overview: open 3-6 representative screens across major areas, beginning250 with anchors and expanding through connected nodes.251- Focused screen question: open 1-3 distinct observations and the directly252 relevant neighbors.253- Journey question: discover the route by graph traversal; open each materially254 distinct screen and inspect ambiguous or decisive edge clips.255- Misunderstood edge: inspect the newest clip first, then at most 2-3 runs when256 evidence disagrees; review the exact originating report before classifying257 the connection.258259Expand only when evidence conflicts or the question remains unanswered. Do not260bulk-download the entire Atlas by default.261262## Answer contract263264Separate graph-supported facts, visually confirmed facts, clip-confirmed265actions, interpretations, and unresolved gaps. Preserve screen IDs and edge266keys in working notes so every conclusion remains attached to stable graph267entities. Never infer pixel-level details, motion, containment, or a preferred268journey from metadata or edge existence alone. Never call unexpected evidence269useless or exclude it until its media and originating report have been270inspected.