{
 "use_case": "test-runs",
 "title": "Rehearsal: verified test run on a fictional shop, one good build and one broken",
 "about": "A two-step test spec for Kiln & Co, a fictional shop served from files on the server (nothing leaves it): the model agent opens a product page, picks quantity 2 and adds it to the cart, then the cart subtotal is asserted. It runs against the good build (must pass) and against the planted total-ignores-qty build (must fail at the subtotal). The good run's signed certificate must verify, and a copy with one assertion flipped must not.",
 "licence": "Synthetic: Kiln & Co is a fictional fixture app shipped with decosa-api (AGPL-3.0-or-later); the spec was written for Decosa. No real shop or people.",
 "inputs": [
  {
   "file": "inputs/spec.yaml",
   "what": "The test spec (YAML): name, target, start page, then steps, each a plain-language 'do' for the model agent or a 'goto', with 'expect' assertions (value_equals, element_count, url_contains, text_present ...) on selectors."
  }
 ],
 "steps": [
  {
   "id": "spec",
   "method": "POST",
   "path": "/testruns/spec/check",
   "body": {
    "spec": {
     "$file": "inputs/spec.yaml"
    }
   }
  },
  {
   "id": "good",
   "method": "POST",
   "path": "/testruns/runs",
   "timeout": 180,
   "body": {
    "spec": {
     "$file": "inputs/spec.yaml"
    },
    "target": "fixture",
    "build": "good",
    "build_id": "rehearsal-good"
   }
  },
  {
   "id": "broken",
   "method": "POST",
   "path": "/testruns/runs",
   "timeout": 180,
   "body": {
    "spec": {
     "$file": "inputs/spec.yaml"
    },
    "target": "fixture",
    "build": "total-ignores-qty",
    "build_id": "rehearsal-broken"
   }
  },
  {
   "id": "verify",
   "method": "POST",
   "path": "/testruns/verify",
   "auth": false,
   "body": {
    "certificate": {
     "$ref": "good.certificate"
    }
   }
  },
  {
   "id": "tampered",
   "method": "POST",
   "path": "/testruns/verify",
   "auth": false,
   "body": {
    "certificate": {
     "$ref": "good.certificate"
    }
   },
   "tamper": {
    "at": "certificate.entries[kind=check].pass",
    "set": false
   }
  }
 ],
 "checks": [
  {
   "says": "the spec reads as valid, with 2 steps",
   "path": "spec.spec.steps",
   "count": 2
  },
  {
   "says": "the good build passes",
   "path": "good.verdict",
   "equals": "pass"
  },
  {
   "says": "every assertion on the good build passes",
   "path": "good.certificate.entries[kind=check].pass",
   "all_in": [
    true
   ]
  },
  {
   "says": "the planted total-ignores-qty build fails",
   "path": "broken.verdict",
   "equals": "fail"
  },
  {
   "says": "it fails at the subtotal: $18.00 shown instead of $36.00",
   "path": "broken.certificate.entries[kind=check,pass=false].actual",
   "equals": [
    "$18.00"
   ]
  },
  {
   "says": "the good run's certificate verifies",
   "path": "verify.ok",
   "equals": true
  },
  {
   "says": "a certificate with one assertion flipped no longer verifies",
   "path": "tampered.ok",
   "equals": false
  },
  {
   "says": "every model action in the certificate has a signed gateway receipt",
   "path": "good.certificate.entries[kind=decide].status",
   "all_in": [
    "signed",
    "attested"
   ]
  }
 ]
}
