{
 "use_case": "flight-recorder",
 "title": "Rehearsal: agent flight recorder on a fictional shop",
 "about": "A browser agent is asked to buy a mug on Harbor Supply, a fictional demo shop. Two observations (screenshot, element table and page text) go to the receipted decision model: on the cart page it must choose an action, and on the order review page the Place order click must be escalated by the needs_approval guard instead of executed. The run is sealed; the record must verify, and a copy whose recorded click target was changed must fail at step 1.",
 "licence": "Synthetic: Harbor Supply is a fictional demo shop shipped with decosa-api (AGPL-3.0-or-later); the screenshots were rendered from its pages. No real shop, orders or people.",
 "inputs": [
  {
   "file": "inputs/run.json",
   "what": "The run: the task in plain words (values to type in quotes) and the agent's name."
  },
  {
   "file": "inputs/cart.jpg",
   "what": "A screenshot of the page the agent sees (JPEG or PNG); sent base64 with the observation."
  },
  {
   "file": "inputs/cart-elements.json",
   "what": "The page's interactive elements as a numbered table [{i, role, name, value?, options?}]."
  },
  {
   "file": "inputs/cart-text.txt",
   "what": "The page's visible text."
  },
  {
   "file": "inputs/step-1-action.json",
   "what": "What the agent then did and what happened: {step, action {type, target}, result}."
  },
  {
   "file": "inputs/review.jpg",
   "what": "The order review page, with the Place order button."
  },
  {
   "file": "inputs/review-elements.json",
   "what": "The review page's element table."
  },
  {
   "file": "inputs/review-text.txt",
   "what": "The review page's visible text."
  },
  {
   "file": "inputs/review-history.json",
   "what": "The actions taken so far, as short lines."
  },
  {
   "file": "inputs/seal.json",
   "what": "How the run ended: {outcome, detail}."
  }
 ],
 "steps": [
  {
   "id": "start",
   "method": "POST",
   "path": "/flight/runs",
   "body": {
    "$file": "inputs/run.json"
   }
  },
  {
   "id": "decide1",
   "method": "POST",
   "path": "/flight/runs/${start.run_id}/decide",
   "timeout": 90,
   "body": {
    "step": 1,
    "observation": {
     "url": "https://shop.flight-demo.test/cart.html",
     "title": "Harbor Supply",
     "screenshot_b64": {
      "$b64": "inputs/cart.jpg"
     }
    },
    "elements": {
     "$file": "inputs/cart-elements.json"
    },
    "page_text": {
     "$file": "inputs/cart-text.txt"
    },
    "history": [
     "click 'Add to cart' on Enamel Mug",
     "click 'Cart (1)'"
    ]
   }
  },
  {
   "id": "act1",
   "method": "POST",
   "path": "/flight/runs/${start.run_id}/steps",
   "body": {
    "$file": "inputs/step-1-action.json"
   }
  },
  {
   "id": "decide2",
   "method": "POST",
   "path": "/flight/runs/${start.run_id}/decide",
   "timeout": 90,
   "body": {
    "step": 2,
    "observation": {
     "url": "https://shop.flight-demo.test/review.html",
     "title": "Harbor Supply",
     "screenshot_b64": {
      "$b64": "inputs/review.jpg"
     }
    },
    "elements": {
     "$file": "inputs/review-elements.json"
    },
    "page_text": {
     "$file": "inputs/review-text.txt"
    },
    "history": {
     "$file": "inputs/review-history.json"
    }
   }
  },
  {
   "id": "seal",
   "method": "POST",
   "path": "/flight/runs/${start.run_id}/seal",
   "body": {
    "$file": "inputs/seal.json"
   }
  },
  {
   "id": "verify",
   "method": "POST",
   "path": "/flight/verify",
   "auth": false,
   "body": {
    "record": {
     "$ref": "seal.record"
    }
   }
  },
  {
   "id": "tampered",
   "method": "POST",
   "path": "/flight/verify",
   "auth": false,
   "body": {
    "record": {
     "$ref": "seal.record"
    }
   },
   "tamper": {
    "at": "record.entries[kind=act].target.name",
    "set": "Delete account"
   }
  }
 ],
 "checks": [
  {
   "says": "on the cart page the model chooses to click Checkout",
   "path": "decide1.decision.element",
   "equals": 8
  },
  {
   "says": "on the review page the Place order click is caught by the needs_approval guard",
   "path": "decide2.guard.rule",
   "equals": "needs_approval"
  },
  {
   "says": "the agent is stopped and the run escalated to a person",
   "path": "decide2.guard.decision",
   "equals": "escalated"
  },
  {
   "says": "the guard event is chained in the sealed record",
   "path": "seal.record.entries[kind=guard]",
   "count": 1
  },
  {
   "says": "the sealed record verifies",
   "path": "verify.ok",
   "equals": true
  },
  {
   "says": "both screenshots are in the record and match their recorded hashes",
   "path": "verify.checks[name=images][0].ok",
   "equals": true
  },
  {
   "says": "a record whose recorded click target was changed no longer verifies",
   "path": "tampered.ok",
   "equals": false
  },
  {
   "says": "verification points at step 1, where the change was made",
   "path": "tampered.first_bad_step",
   "equals": 1
  },
  {
   "says": "every model call has a signed receipt",
   "receipts": "signed"
  }
 ]
}
