{
  "markdown": "# Nocticas E2E Gate — GitHub Action\n\nRun a **pinned Nocticas gate** against a target URL on every push/PR, and **fail the build on a red verdict**. The browser runs on Nocticas's servers — this Action is a thin client that starts the run, polls for the verdict, and maps it to an exit code. No false greens: a harness error is never treated as a pass.\n\n## Quickstart\n\n1. **Author + pin a flow** in Nocticas (agentic run → pin → export the deterministic step script as JSON).\n2. **Commit the gate** to your repo, e.g. `.nocticas/checkout-flow.json`.\n3. **Add your key** as a repo secret: `NOCTICAS_API_KEY`.\n4. **Add the workflow:**\n\n```yaml\n# .github/workflows/nocticas.yml\nname: Nocticas E2E gate\non: [pull_request, workflow_dispatch]\njobs:\n  verify:\n    runs-on: ubuntu-latest          # standard runner = free on public repos\n    steps:\n      - uses: actions/checkout@v4   # so the gate file is available\n      - uses: Low-Latency-Labs/nocticas-action@v1\n        with:\n          api-key: ${{ secrets.NOCTICAS_API_KEY }}\n          gate: .nocticas/checkout-flow.json\n          target: ${{ vars.PREVIEW_URL }}   # your deployed preview/staging URL\n```\n\nA red verdict fails the job → blocks the PR/merge.\n\n## Inputs\n\n| Input | Required | Default | Description |\n|--|--|--|--|\n| `api-key` | yes | — | Your Nocticas API key (store as a secret). |\n| `gate` | yes | — | Path to the pinned gate JSON (array of deterministic steps) in your repo. |\n| `target` | yes | — | URL to test (e.g. the PR's preview deploy). |\n| `api-base` | no | `https://app.nocticas.com/api` | Nocticas API base. |\n| `timeout-seconds` | no | `300` | Max wait for a verdict. |\n| `poll-seconds` | no | `3` | Poll interval. |\n| `fail-on-error` | no | `true` | Treat a harness `error` (not a test fail) as a build failure. An unverified run is never a pass. |\n\n## Outputs\n\n| Output | Description |\n|--|--|\n| `run-id` | The Nocticas run id (link it in your logs). |\n| `verdict` | `passed` \\| `failed` \\| `error` \\| `timeout`. |\n\n## The gate file\n\nA JSON **array of deterministic steps** — exactly what Nocticas produces when you *pin* a passing run. Example in [`examples/gate.example.json`](examples/gate.example.json). Keeping it in your repo means your E2E test is version-controlled alongside the code it guards.\n\n> **Don't commit real credentials.** Point the gate at a staging/preview target and use a dedicated test account; Nocticas's built-in test inbox handles OTP/magic-link logins so you don't need to embed secrets in the gate.\n\n## Cost\n\n- **Publishing this Action:** free (public repo, no paid plan).\n- **Running it (your customers):** free on public repos with standard runners; within the monthly free-minutes allowance on private repos. It's a single thin job — seconds of runner time.\n- **The browser run:** billed in Nocticas credits — and **deterministic/pinned runs are free within your monthly allowance**, so gating every push typically costs nothing in credits.\n\n## Other CI systems (the recipe)\n\nNot on GitHub? The same start → poll → exit logic is a portable script — see [`recipe.sh`](recipe.sh) and [`examples/gitlab-ci.example.yml`](examples/gitlab-ci.example.yml). The contract is just JSON over HTTP:\n\n```\nPOST {api-base}/runs   { \"mode\":\"deterministic\", \"target\": \"...\", \"script\": [ ...gate... ] }   → { \"id\": \"...\" }\nGET  {api-base}/runs/{id}                                                                       → { \"status\": \"passed|failed|error|...\" }\n```\nHeader: `x-nocticas-key: <key>`. Exit non-zero unless `status == \"passed\"`.\n",
  "bytes": 3532,
  "sha": "103fca55f80c83953c101a22661dddf254e8198552da8a2a6582b4fb4c9f8aa3",
  "repo_slug": "low-latency-labs/nocticas-action",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_com_nocticas_nocticas_e226a807/readme"
}