App memory

Your agent learns an app once and reuses what it learned. Notes stay on your machine, and approved flows are shared with your team as an App Skill.

Try it autonom teach start login

Needs Autonom installed · a session on one target · a flow you can replay

How it works

A device task needs things the command line cannot know: which backend the app talks to, how its network is wired, where its response schemas live. The mobile-memory skill keeps them per app. Your agent reads them before a device task and writes back what will happen again.

They live in ~/.autonom/apps/<package>/ as plain Markdown on your machine. They are yours alone, never in the app repository or in Autonom's.

  • app.md: the app's identity, backend, network, TLS notes, where schemas live, known screens and gotchas already handled.
  • flows/<name>.md: a runbook with a goal, the endpoint, the schema source, exact steps, how to verify, and gotchas.
  • bodies/<name>.json: a ready response a runbook points at, for a network mock.
  • atlas/graph.json: the screens your runs saw and the moves between them, written by autonom atlas update.
Two places hold app knowledge. On your machine, ~/.autonom/apps/<package>/ keeps app.md, flow runbooks, mock bodies and the observed atlas. In the app repository, .autonom/ keeps flow files and promoted App Skills. Two places hold app knowledge. On your machine, ~/.autonom/apps/<package>/ keeps app.md, flow runbooks, mock bodies and the observed atlas. In the app repository, .autonom/ keeps flow files and promoted App Skills.
Notes stay on your machine; flows and App Skills are committed with the app.

A runbook that has become fully predictable, with stable selectors and no judgment calls, can become a flow that Autonom checks and replays exactly.

Teach records part of the session journal and compiles it into a flow. Approval needs three clean replays in a row, by default. Promotion copies the approved flow into the App Skill, under .autonom/apps/<app-id>/.

An App Skill has a fixed, portable layout: SKILL.md, selectors.yaml, subflows/, fixtures.yaml, compatibility.yaml and catalog.json.

Examples

The four examples are one journey on a fake Android device that ships with Autonom's tests, so you can reproduce them without an emulator. Open Reproduce these outputs at the end of this section for the exact commands.

Find what your agent already knows about an app

Goal: start a device task with the answers the last session found.

  1. Show the session.

    The app id it names is the key to the app's notes.

    autonom session show

You should see the session, with the app id it was started for.

{ "ok": true, "session": { "schema_version": 2, "session_id": "s_ffa1b527a0", "platform": "android", "target_id": "emulator-5554", … "app_id": "com.example.yarnshop", … } }

What to look at. app_id names the app's folder under ~/.autonom/apps/. The mobile-memory skill reads app.md there first, then follows a matching runbook, so your agent replays the known path instead of exploring.

Teach a flow by walking it

Goal: turn a journey you just walked into a candidate flow, without writing YAML.

  1. Start a recording, then walk the journey.

    Name the recording, here login. Then tap and find controls by what they say; the last find becomes the flow's closing check.

    autonom teach start login
  2. Stop the recording.

    This closes the range in the session's journal.

    autonom teach stop
  3. Compile the range.

    It writes a flow file, here .autonom/flows/login.yaml.

    autonom teach compile --out .autonom/flows/login.yaml

You should see a two-step candidate flow that still needs review.

{ "ok": true, "out": ".autonom/flows/login.yaml", … "description": 2, … "steps": 2 … "confidence": 0.5, "review_required": true }

What to look at. confidence is 0.5 and review_required is true, so read the file and run it before anything approves it. Both steps matched a control by its description, which quality counts.

Show full output
{ "ok": true, "recording_id": "teach_09ca8a8cdbe04b0e", "out": ".autonom/flows/login.yaml", "flow_sha256": "79daaaa471552862737b6ba91a6d8584058a37ae0fbbcf0fe1264a95876efdf2", "warnings": [], "quality": { "selectors": { "id": 0, "text": 0, "description": 2, "recorded": 2, "index": 0 }, "secrets": 0, "skipped": 0, "steps": 2 }, "secrets_required": [], "range": { "start_seq": 4, "end_seq": 5 }, "provenance": { "session_id": "s_ffa1b527a0", "journal": "/tmp/memory-demo/home/sessions/s_ffa1b527a0/journal.ndjson", "compiler": "autonom.teach/v1" }, "confidence": 0.5, "review_required": true }
Show the flow it wrote
schema: autonom.dev/flow/v1 id: flow_743f70b0cef574e9 appId: com.example.yarnshop name: login tags: - login --- - tapOn: selector: description: Sign in with Email match: caseInsensitiveExact - assertVisible: selector: description: Sign in to access all features match: caseInsensitiveExact
A journey is recorded with teach, compiled into a candidate flow, reviewed, approved after three consecutive clean replays of the current file, and promoted into an App Skill. A journey is recorded with teach, compiled into a candidate flow, reviewed, approved after three consecutive clean replays of the current file, and promoted into an App Skill.
Approval is the gate: three clean replays in a row of the current file, by default.

Approve a flow and share it as an App Skill

Goal: prove a flow replays cleanly, then share it with your team.

  1. Approve it.

    With --run, approval replays the flow itself, three times here.

    autonom teach approve .autonom/flows/login.yaml --run --minimum-runs 3
  2. Promote it.

    Promotion checks the approval receipt, so a flow edited since then is refused.

    autonom app-skill promote com.example.yarnshop .autonom/flows/login.yaml

You should see three clean replays, then the flow copied into the App Skill.

autonom teach approve .autonom/flows/login.yaml --run --minimum-runs 3 { … "replay_binding": { "sha256": 3, … }, … } autonom app-skill promote com.example.yarnshop .autonom/flows/login.yaml { … "promoted": "/private/tmp/memory-demo/.autonom/apps/com.example.yarnshop/subflows/login.yaml", … }

What to look at. sha256 is 3: all three replays ran the exact bytes approval recorded. promoted is the flow's new place in the App Skill. If approval refuses because a file changed, name the file; do not edit it to get past the check.

Show full output
autonom teach approve .autonom/flows/login.yaml --run --minimum-runs 3 { "ok": true, "schema": "autonom.teach-approval/v1", "approved_at": "2026-09-28T21:38:29.149Z", "flow": ".autonom/flows/login.yaml", "flow_id": "flow_743f70b0cef574e9", "flow_sha256": "79daaaa471552862737b6ba91a6d8584058a37ae0fbbcf0fe1264a95876efdf2", "subflow_sha256": {}, "clean_replays": [ "fr_9eca104e8a", "fr_c00c9a9385", "fr_264b607345" ], "replay_binding": { "sha256": 3, "unmodified_since_run": 0 }, "legacy_unhashed": [], "receipt": ".autonom/flows/login.yaml.approved.json", "replays": [ { "run_id": "fr_264b607345", "status": "passed", "flow_sha256": "79daaaa471552862737b6ba91a6d8584058a37ae0fbbcf0fe1264a95876efdf2" }, { "run_id": "fr_c00c9a9385", "status": "passed", "flow_sha256": "79daaaa471552862737b6ba91a6d8584058a37ae0fbbcf0fe1264a95876efdf2" }, { "run_id": "fr_9eca104e8a", "status": "passed", "flow_sha256": "79daaaa471552862737b6ba91a6d8584058a37ae0fbbcf0fe1264a95876efdf2" } ] } autonom app-skill promote com.example.yarnshop .autonom/flows/login.yaml { "ok": true, "app_id": "com.example.yarnshop", "root": "/private/tmp/memory-demo/.autonom/apps/com.example.yarnshop", "subflows": [ { "path": "/private/tmp/memory-demo/.autonom/apps/com.example.yarnshop/subflows/login.yaml", "flow_id": "flow_743f70b0cef574e9", "name": "login" } ], "promoted": "/private/tmp/memory-demo/.autonom/apps/com.example.yarnshop/subflows/login.yaml", "flow_id": "flow_743f70b0cef574e9" }

See which screens your runs have covered

Goal: know which screens your flows have actually visited, with no extra capture.

  1. Update the atlas.

    It folds the session's runs into the app's screen graph.

    autonom atlas update
  2. Show it.

    It lists each screen with the labels it carries.

    autonom atlas show

You should see one screen, seen by three runs, and no moves between screens.

{ "ok": true, "app_id": "com.example.yarnshop", … "runs_ingested": 3, … "screens": 1, "variants": 1, "transitions": 0, … }

What to look at. runs_ingested counts the three approval replays. They all saw the same sign-in screen, so the graph holds one screen and no transitions.

Show full output
{ "ok": true, "app_id": "com.example.yarnshop", "graph": "/tmp/memory-demo/home/apps/com.example.yarnshop/atlas/graph.json", "runs_ingested": 3, "transitions_touched": 3, "screens": 1, "variants": 1, "transitions": 0, "updated_at": "2026-09-28T21:38:29Z", "screen_list": [ { "screen_id": "scr_844ce9b26616", "labels": [ "Back", "Welcome to Yarn Shop", "Sign in to access all features" ], "variants": 1, "last_seen": "2026-09-28T21:38:29.147Z" } ] }
Reproduce these outputs

From the root of an Autonom d0f7211 checkout, in bash or zsh. Ids, times and paths differ on every run.

S=$PWD W=/tmp/memory-demo rm -rf $W && mkdir -p $W/.autonom/flows && cd $W export AUTONOM_HOME=$W/home AUTONOM_FAKE_STATE=$W/state.json echo "{\"ui_dump\": \"$S/tests/fixtures/woolbox/android_sign_in.xml\"}" > $AUTONOM_FAKE_STATE autonom() { python3 $S/scripts/autonom.py --platform android --serial emulator-5554 --adb $S/tests/fakes/fake_adb.py "$@"; } autonom session start --app-id com.example.yarnshop autonom session show autonom teach start login autonom ui tap --desc "Sign in with Email" --mode exact autonom ui find --desc "Sign in to access all features" --mode exact autonom teach stop autonom teach compile --out .autonom/flows/login.yaml cat .autonom/flows/login.yaml autonom teach approve .autonom/flows/login.yaml --run --minimum-runs 3 autonom app-skill promote com.example.yarnshop .autonom/flows/login.yaml autonom atlas update autonom atlas show

Good to know

  • Read before you drive. Resolve the app id and read app.md first. It answers the questions that otherwise cost the most time.
  • Save only what is durable, reusable and backed by evidence. The exact endpoint, glob, schema path or gotcha is worth a line. One-off exploration is not, and a single command is not a runbook.
  • Never write secrets into memory. Write "log in as the test driver", not an account or a token.
  • Keep entries concrete and keyed by id. com.example.rides and POST /api/v1/orders help the next reader; "the orders call" does not. Update an existing file rather than add a near duplicate.
  • Approval counts only replays of the current file. Edit the flow, and you replay it again.
  • Recording never guesses. A coordinate tap or a point-to-point swipe becomes a warning, not a step.
  • The atlas records only what runs saw. A missing move between two screens means unknown, not impossible. Clock ticks, counters, list length and the status bar do not make a new screen.
  • An App Skill loads no helper program. Validation also rejects prose that looks like a credential.

Reference

Teach works inside an active session, because it records from that session's journal. Approval replays on the session's target.

CommandWhat it does
autonom session showShows the current session, including the app id your notes are keyed by.
autonom teach start <name>Opens a named recording range in the session's journal. teach mark adds a named boundary, teach stop freezes the range, and teach show lists recordings.
autonom teach compile --out PATHDerives selectors, secrets, confidence and provenance, and checks the result as a flow.
autonom teach approve <flow> [--minimum-runs N] [--run]Approves after consecutive clean replays of the current file, three by default, and writes a receipt. --run performs the replays itself.
autonom app-skill validate <app-id>Checks the App Skill. It rejects malformed flows, missing files, unsafe app ids and prose that looks like a credential.
autonom app-skill promote <app-id> <flow>Adds an approved flow to the App Skill. A flow edited since its receipt is refused.
autonom atlas updateFolds the session's runs into the app's observed screen graph.
autonom atlas showShows the screens, variants and transitions in the graph.
autonom atlas coverageCounts observed screens and moves, and lists screens with no observed move.
autonom atlas paths --from <SCREEN> --to <SCREEN>Finds observed paths between two screens.
autonom atlas export --out <PATH>Writes the graph to a file.
autonom atlas diff --base <PATH>Compares the graph with an exported one.

Android and iOS differences

Notes, runbooks and the atlas work the same on Android and the iOS Simulator. What differs is what a taught flow can hold.

CapabilityAndroidiOS
The atlasYesYes, on the Simulator
A taught flow with clearState or backRunsCannot run: both steps are Android-only
A recorded session clearCompiles into the flowSkipped with a warning; declare a reset in setup instead

Next steps

Your agent can keep what it learns and share a proven flow.