Skip to main content
The Action Cache is PassAgent’s system for recording browser automation sequences during password reset flows, persisting them as versioned JSON scripts, and replaying them deterministically on future runs. Instead of relying on AI inference for every reset attempt, the Action Cache executes known-good sequences instantly, falling back to intelligent self-healing when page structures change.

How It Works

The Action Cache operates as a three-phase lifecycle: Build a script by running an AI-driven browser session and capturing every action, Store the resulting steps as a versioned JSON file keyed by domain, and Replay the cached script on subsequent resets.

Cache Builder Modes

The CacheBuilder class supports four distinct operational modes.
Launches headed Chromium, navigates to the reset URL, and uses heuristic selectors plus page classification to fill the email field and submit. Every action is captured with its XPath, CSS selector, aria-label, data-testid, placeholder text, and bounding box.
  • Iterates up to 10 classification loops detecting page state (success, captcha, recovery_method, rate_limited, no_account)
  • Auto-selects email recovery when a recovery_method page is detected
  • Annotates the domain in service-annotations.json with flags like works_perfect or captcha_found
  • Skips domains annotated as otp or sso_only
const builder = new CacheBuilder(emit);
await builder.buildCache("netflix.com", { email: "user@example.com", screencast: true });
Loads the golden script (or a specific scriptId) and replays each cached step sequentially. Uses the multi-strategy element resolver, falling back to fuzzy DOM matching when XPaths break. Healed selectors are written back to cache so future runs benefit from corrections. On failure, Vision AI produces a structured diagnosis.
const builder = new CacheBuilder(emit);
await builder.replayCache("google.com", { email: "user@gmail.com" });
Opens a headed browser and injects a JavaScript listener capturing all user clicks and input events. When the admin signals save, raw actions are converted to the standard step format and presented for review before persisting.CAPTCHA-aware: if a CAPTCHA appears mid-recording, capture pauses and filters out CAPTCHA-interaction noise once cleared.
Use manual recording for services where AI build struggles with non-standard UIs or unusual form layouts.
Replays a cached script but pauses after every step, emitting a screenshot and DOM snapshot for admin inspection. The admin UI sends debug-step (advance one) or debug-resume (run remaining) signals. Designed for verifying scripts before promoting to golden.

Self-Healing Element Resolution

When replaying, element selectors can break due to DOM changes. The engine uses a two-tier resolution strategy.

Resolution Priority

1

XPath

Exact XPath from the original recording. Fastest but most brittle.
2

CSS Selector

Constructed from tag, id, name, type, and data-testid attributes.
3

Text Content

For click actions, matches visible text via Playwright’s getByText.
4

ARIA Label

Matches via aria-label using getByLabel.
5

Name Attribute

Queries by [name="..."] selector.
6

Placeholder

Matches by placeholder text via getByPlaceholder.
7

data-testid

Queries [data-testid="..."] or [data-test="..."].
8

Fuzzy DOM Matching

Scans all visible buttons, inputs, and links. Scores by tag match (+0.15), text overlap (+0.3—0.4), name match (+0.3), placeholder match (+0.25). Accepts candidates at 0.6 or above.
When fuzzy matching succeeds, the healed XPath is written back into the stored script so subsequent replays use the corrected selector directly.

Vision AI Diagnosis

When a build or replay fails, the Cache Builder sends the final screenshot plus DOM snapshot to Claude (Sonnet). The model returns a structured JSON diagnosis with issue, pageState, recommendation, suggestedAction, and confidence. This diagnosis is appended to the domain’s service annotations as an auto-generated note for future build attempts.

Action Cache Store

ActionCacheStore manages the on-disk persistence layer in data/action-caches/, one JSON file per domain.
MethodDescription
get(domain)Load the full domain file (all scripts)
getGoldenScript(domain)Return the isGolden script, or the first script
getScript(domain, scriptId)Return a specific script by ID
saveScript(domain, script)Save a specific script (insert or update)
deleteScript(domain, scriptId)Remove a script; reassign golden if needed
setGolden(domain, scriptId)Promote a script to golden status
cloneScript(domain, scriptId, name)Deep-copy a script with a new UUID
recordSuccess(domain, scriptId)Reset consecutiveFailures, increment successCount
recordFailure(domain, scriptId)Increment consecutiveFailures; auto-delete at 3 unless pinned
listDomains()List all domain keys from the cache directory
Scripts with 3 consecutive failures are automatically deleted unless the pinned flag is set. This prevents stale scripts from blocking fresh AI builds.

Golden Scripts

Every domain has exactly one golden script — the primary script used for production replays. When a new script is marked golden, all others have their isGolden flag cleared. If the golden script is deleted, the first remaining script is automatically promoted.

Data Format

All cache files use version 2 of the schema. Version 1 files are automatically migrated on read.
{
  "version": 2,
  "domain": "netflix.com",
  "serviceName": "Netflix",
  "scripts": [{
    "scriptId": "07930a82-...",
    "scriptName": "Default Flow",
    "scriptType": "golden",
    "isGolden": true,
    "actionCache": {
      "taskId": "9c260b34-...",
      "status": "completed",
      "steps": [
        { "stepIndex": 0, "actionType": "wait", "success": true },
        { "stepIndex": 1, "actionType": "goToUrl", "arguments": ["https://www.netflix.com/loginhelp"] },
        { "stepIndex": 2, "actionType": "actElement", "method": "fill",
          "xpath": "/html[1]/body[1]/.../input[1]",
          "selectors": { "cssSelector": "input[name='email']", "name": "email" },
          "arguments": ["test@passagent.app"], "success": true },
        { "stepIndex": 3, "actionType": "complete", "success": true }
      ]
    },
    "entryUrl": "https://www.netflix.com/loginhelp",
    "consecutiveFailures": 0,
    "successCount": 5,
    "totalRuns": 6
  }]
}

Step Action Types

Action TypeDescription
waitPause for DOM mutations to settle (MutationObserver-based, up to 4s)
goToUrlNavigate the browser to a specific URL
actElementInteract with a DOM element via click or fill method
completeTerminal step marking the task as done
Each actElement step stores a selectors object with redundant strategies: xpath, cssSelector, textContent, ariaLabel, name, placeholder, and dataTestId.

Extension Integration

The Chrome extension prefetches cached scripts via GET /api/ext/action-cache.
?manifest=true returns a lightweight list of all cached domains with MD5 version hashes, used to detect stale local caches.
{ "domains": [{ "domain": "google.com", "version": "a3f8c1d2" }], "generatedAt": "..." }

Admin API

The admin API at /api/admin/action-cache is protected by admin auth and risk-adaptive step-up verification.

GET — Read and Health

ParameterDescription
domainLoad all scripts for a domain
domain + scriptIdLoad a specific script with full step details
action=healthReturn health scores (0-100) for all cached domains based on age, failures, and success rate

PUT — Script Management

ActionDescription
set-goldenPromote a script to golden status
rename / delete / cloneModify script metadata or create variants
set-notes / set-pinnedAttach notes or pin to prevent auto-deletion

POST — Execute Operations (SSE)

Streams progress events via Server-Sent Events:
ActionDescription
build / replay / record / replay-debugExecute the corresponding CacheBuilder mode
batch-validateReplay all cached domains sequentially
stop-record / save-recordSignal an active manual recording session
review-confirm / review-discardConfirm or discard reviewed recording steps
debug-step / debug-resumeControl step-by-step debug replay

Service Annotations

The Cache Builder reads and writes data/service-annotations.json for per-domain metadata that affects execution:
FlagEffect
captcha_foundEnables auto-solve attempts during build
steps_did_nothing / cloudflare_blockExtends DOM wait times and navigation timeouts
works_perfectSet after successful builds (informational)
steps_brokenSet when replay fails with zero completed goals
Login type annotations (otp, sso_only, magic_link) cause the builder to skip or adapt accordingly. Domains marked otp or sso_only are skipped entirely.

Manual Recording Internals

The recordManual mode injects a self-contained JavaScript snippet into the page that:
  1. Attaches a click listener (capture phase) recording XPath, CSS selector, text, ARIA label, placeholder, data-testid, and bounding box
  2. Attaches an input listener that coalesces rapid keystrokes into a single fill event per element
  3. Re-injects itself on framenavigated events to track page navigations
  4. Stores all actions in window.__pa_actions for retrieval by convertRecordedToCache
Recorded scripts include durationMs timing between steps, which the replay engine uses to insert realistic delays between actions.