{
  "schemaVersion": 1,
  "project": "just-every/uptime-monitor",
  "release": "0.3.0",
  "provenance": {
    "kind": "publisher-release",
    "repository": "https://github.com/just-every/run-uptime",
    "revision": "bceec10fc6c6df8d78876d0fc91b7d927d5909d7",
    "tree": "6a806ff3d0e3467d4462eed824ac9906ba508d63",
    "publication": "local-release",
    "tag": "v0.3.0",
    "gates": {
      "verify": {
        "status": "PASS",
        "exitCode": 0,
        "tests": 0,
        "passed": 0,
        "failed": 0,
        "skipped": 0,
        "flaky": 0,
        "release": {
          "status": "PASS",
          "exitCode": 0,
          "tests": 0,
          "passed": 0,
          "failed": 0,
          "skipped": 0,
          "flaky": 0
        }
      },
      "publishCheck": {
        "status": "PASS",
        "findings": 0,
        "reportSha256": "0751be75d06282c03573962a2c72b764938c41d5a253a2ee87ca0038b780df0d"
      }
    },
    "note": "Local tag and export; no push, deployment or visibility change."
  },
  "listing": {
    "id": "uptime",
    "name": "Uptime",
    "licence": "MIT",
    "repository": "https://github.com/just-every/run-uptime",
    "category": "monitoring",
    "categoryLabel": "monitoring",
    "version": "0.3.0",
    "oneLiner": "Private uptime console for scheduled HTTP(S), keyword, and heartbeat probes, with Base owner sign-in, installation-wide incident notifications, and portable product archives.",
    "summary": "Private uptime console for scheduled HTTP(S), keyword, and heartbeat probes, with Base owner sign-in, installation-wide incident notifications, and portable product archives.",
    "maturity": "local-installer-and-owner-deploy-implemented-hosted-unverified",
    "replaces": [
      {
        "name": "UptimeRobot",
        "edition": null
      },
      {
        "name": "Pingdom",
        "edition": null
      },
      {
        "name": "Better Stack",
        "edition": null
      }
    ],
    "clauses": [
      {
        "id": "HTTP-001",
        "title": "Signed HTTP monitoring",
        "text": "Public hosted HTTP(S) and keyword checks run in the Cloudflare Worker; private checks use the separately scoped Node runner. They retain the exact immutable assertion bundle and bounded transport evidence, and require authenticated claims and signed results; the control plane must reject contradictory completion. See [Integrity and authority](#integrity-and-authority) and [Network and credentials](#network-and-credentials)."
      },
      {
        "id": "EVIDENCE-001",
        "title": "Immutable scheduled evidence",
        "text": "Definitions, scheduled slots and every retry attempt retain revision, policy, fixed selected probes, runner identity, timings, status, assertions and error category; retries never erase failures, and observation/state/outbox commit atomically. See [Evidence and state](#evidence-and-state) and [Integrity and authority](#integrity-and-authority)."
      },
      {
        "id": "STATE-001",
        "title": "Fixed coverage and incident hysteresis",
        "text": "Missing or expired passing coverage is Unknown, partial failure stays visible, independent-vantage agreement and scheduled confirmation determine Failing, and complete fresh scheduled passing evidence plus recovery threshold is required for recovery; manual checks and maintenance never rewrite observations or scheduled policy. See [Evidence and state](#evidence-and-state)."
      },
      {
        "id": "AUTHORITY-001",
        "title": "Server-side scoped authority",
        "text": "Every private document, read, mutation and export requires server-side operator or scoped runner authority, missing configuration fails closed, browser mutations enforce configured origin, and expired/foreign attempts cannot alter current evidence, and duplicate attempt identities cannot overwrite it; a signature identifies a key holder rather than proving truthful observation. See [Integrity and authority](#integrity-and-authority)."
      },
      {
        "id": "NETWORK-001",
        "title": "Pinned bounded destination execution",
        "text": "Every public DNS answer and redirect hop is validated fail closed; private-runner numeric sockets preserve Host and TLS identity, hosted checks use Cloudflare’s public Internet fetch transport, unsafe/mixed addresses and HTTPS downgrade are rejected, cross-origin redirects strip request authority, and synthetic grants and protected origin-bound local credential files retain their separate custody limits. See [Network and credentials](#network-and-credentials)."
      },
      {
        "id": "HEARTBEAT-001",
        "title": "Revision-scoped receipt evaluation",
        "text": "Hashed owner-issued tokens and increasing sequences protect server-time receipts, ingress cannot advance health, and scheduled signed completion must match its exact installation-local claim snapshot; stale, future, paused, foreign-revision or imported receipts cannot establish Healthy. See [Network and credentials](#network-and-credentials)."
      },
      {
        "id": "ARCHIVE-001",
        "title": "Inactive validated restore",
        "text": "Bounded versioned archives require integrity and semantic validation before transactional restore into empty product data, preserve historical evidence, erasure receipts and the permanent anonymised action audit, create paused current revisions, interrupt leases and quarantine alerts; installation-local sessions, keys, grants, request credential values, heartbeat authority, contact, webhook and Slack URLs, and signing keys are excluded; destination definitions and retained notification histories are portable, and imported evidence cannot establish current health or replay events. The source erasure journal fences copies made before a later erasure when that journal accompanies the restore. A local CLI receiving checkout must run setup first to establish its owner and settings. The owner accepted this installation-authority and endpoint-credential archive policy on 2026-10-13; it is an intentional replacement, not BASE-DATA-001 equivalence. See [Portability and retention](#portability-and-retention) and [Integrity and authority](#integrity-and-authority)."
      },
      {
        "id": "IMPORT-001",
        "title": "Reviewed definition files and inactive imports",
        "text": "A versioned definition file (2 MiB, 500 monitors, UTF-8 JSON, editor fields only, no request secrets or installation authority) or saved UptimeRobot v3 monitor pages are previewed without writes as create, unchanged, change, refused or unsupported per entry with a plan digest, validated by the editor's own validation; apply refuses a digest that no longer matches and otherwise writes the whole plan in one transaction as new paused monitors or new revisions that keep enabled, maintenance and runner assignments; nothing in a file enables a monitor, issues a heartbeat token, schedules a notification or touches a destination. Each apply is a batch; undo pauses what it created and restores what it changed while their revisions are unchanged, reports the rest and never removes history. Batches travel in archives as restored history without authority. A log export is counted, never stored or turned into evidence. Unmeasured: no real UptimeRobot export and no hosted run. See [Definition files and imports](#definition-files-and-imports)."
      },
      {
        "id": "RETENTION-001",
        "title": "Explicit storage custody",
        "text": "Product and observation metadata and legacy development sign-in records have no automatic age/count deletion; operator erasure removes captures for the associated operator, and local reset clears the installation. Expired sessions, authentication/public rate-limit state and short-lived login-attempt counters are cleaned up. Expired or confirmed alert-drill links lose their capability material while drill history stays; retired destination secrets are scrubbed only after owner rotation/deletion and in-flight sends finish; a proven-unsent integration-attempt reservation can be removed while its delivery history remains. Other expired operational records, including discovery jobs, change status and remain stored unless an owner erases the associated entity or resets the installation. Raw target response bodies and probe-request secrets are not retained in observations, webhook and Slack endpoint URLs and signing keys remain installation-local, available email addresses travel as destination definitions, view/archive bounds are not deletion or capacity claims, and retention changes must never silently improve the fixed denominator or historical health. See [Portability and retention](#portability-and-retention)."
      },
      {
        "id": "ERASURE-001",
        "title": "Operator-directed entity erasure",
        "text": "An owner can erase a monitor with its evidence and dependent notification/heartbeat records, a destination with its credential copies, or an operator while another active owner remains. Monitor erasure requires typing the current monitor name. Each completed erasure returns a receipt with entity kind, per-table counts and completion time, and returns it only after the transaction containing the erasure, audit entry and portability fence succeeds. Requests based on stale monitor or destination state cannot re-create erased rows. The last active owner cannot be erased: local installations use `rer reset --yes`, while hosted installations require replacement by redeployment. Uptime has no R2 upload feature, so product erasure has no uploaded attachments to remove. Already downloaded archives, messages already sent to external recipients and requests already in progress remain outside local erasure. See [Erasure and audit](#erasure-and-audit)."
      },
      {
        "id": "AUDIT-001",
        "title": "Durable anonymised audit",
        "text": "Destructive actions, automated notification attempts and operator authentication-mail sends record actor or feature, time, action, subject kind and an opaque subject reference. Audit history is portable and survives erasure of the subject; erasing an operator anonymises its prior actor references. The audit contains no monitor names, target URLs, email addresses or destination URLs. See [Erasure and audit](#erasure-and-audit) and [Portability and retention](#portability-and-retention)."
      },
      {
        "id": "PRESENCE-001",
        "title": "Contact separate from health",
        "text": "Only accepted scoped claims and signed results refresh server-time contact, the 120-second freshness threshold never proves process liveness or target health, and restart, unavailable reads and archive omission preserve that distinction. See [Contact, interface and delivery](#contact-interface-and-delivery)."
      },
      {
        "id": "INTERFACE-001",
        "title": "Honest durable operator feedback",
        "text": "Textual state/freshness/reasons, immutable history, labels, keyboard controls and responsive layout expose persisted evidence; failed reads show Unknown, action errors survive polling, busy reconciliation excludes controls and editing rejects assertion overrides. See [Contact, interface and delivery](#contact-interface-and-delivery)."
      },
      {
        "id": "NOTIFY-001",
        "title": "Authorized installation-wide destinations",
        "text": "An owner may configure email, signed JSON webhook, or Slack incoming webhook destinations for all monitors in one installation; only scheduled incident transitions generate automatic notifications, and a test send cannot change monitor evidence or incident state. The hosted Worker submits email through the configured Base mail adapter and sends webhooks and Slack without a private runner; a private runner can also claim notification work. Destination credentials are installation-local and are not restored from archives. See [Contact, interface and delivery](#contact-interface-and-delivery) and [Network and credentials](#network-and-credentials)."
      },
      {
        "id": "DELIVERY-001",
        "title": "Bounded notification acknowledgement",
        "text": "Each event and destination gets one automatic send attempt. A RER relay 429 with Retry-After confirms non-acceptance and queues another submission after that delay. HTTP 500, connection loss, timeout, and unknown outcomes remain uncertain and are not automatically sent again. Accepted means the configured provider or endpoint acknowledged the request; it does not mean a person received, read, or acted on it. See [Contact, interface and delivery](#contact-interface-and-delivery)."
      },
      {
        "id": "PUBLIC-001",
        "title": "Public landing and documentation",
        "text": "At the app origin, `/` is the unauthenticated Lobby, `/docs` is public documentation, `/setup` is first-run setup, and the private operator console and editor are `/app` and `/app/monitor`; private documents require an owner session. The separate marketing site serves `https://run-uptime.com/` and `https://run-uptime.com/run`. The app Lobby at `/` and the marketing landing at the run-site `/` are distinct surfaces."
      },
      {
        "id": "BOUNDARY-001",
        "title": "Bounded delivery and operating claims",
        "text": "Destinations apply to all monitors in the installation, while runners with the same network label remain one vantage. Provider acknowledgement and stored delivery state do not prove inbox receipt or human notification. Teams, Discord, SMS, on-call paging, incident escalation, and public status communication are outside the product; network isolation, browser execution, and accessibility conformance require separate evidence. See [Contact, interface and delivery](#contact-interface-and-delivery)."
      },
      {
        "id": "DRILL-001",
        "title": "Recipient-reported alert drills",
        "text": "An owner can run an alert drill on one destination: the existing test event with drill wording, sent once through the same path with no automatic resend, plus a one-time confirmation link (random capability, stored only as a bound hash, single use, 24-hour expiry, one drill and one destination). Opening the link shows a page; only a same-origin POST confirms, and unknown, used, expired and foreign links answer 404 alike. The console keeps Submitted, Acknowledged (or Uncertain/Failed with its code) and Recipient confirmed as separate lines, and does not measure whether anyone acted. A confirmed drill is a report by the recipient that one message reached a person at one time. It is never evidence of monitoring, a delivery guarantee or a human response, and it changes no monitor evidence, state or incident. Proof belongs to the destination's current credential: a new address or URL or a rotated secret makes it Never proven, and drill history stays with the installation, so a restored destination is Never proven. See [Alert drills](#alert-drills)."
      },
      {
        "id": "STARTUP-001",
        "title": "Required configuration diagnostics",
        "text": "A shared configuration table validates required and conditional bindings for the Worker, scheduled entry point, local app, preview, setup, deployment and private runner before each begins work. Missing or malformed required values stop the entry point and name the variable without printing its value; a Worker configuration failure returns 503, including at `/health`. Hosted mode requires the selected Base mail provider and its sender configuration. See [Configuration diagnostics](#configuration-diagnostics)."
      },
      {
        "id": "PUBLIC-002",
        "title": "Declared sessionless paths and rate limits",
        "text": "Every sessionless route and emitted static path is declared in `seed.json` with its authentication rule and rate-limit class. D1 applies owner-tunable per-client limits in fixed 60-second windows and returns 429 with `Retry-After` after the class limit. A declaration does not bypass route-specific session, runner, heartbeat or development-key checks. Limit values are marked estimated and not load-tested. See [Public paths and rate limits](#public-paths-and-rate-limits) and [Integrity and authority](#integrity-and-authority)."
      },
      {
        "id": "FLOW-001",
        "title": "One isolated browser flow (implementation only, outside the supported public feature set)",
        "text": "A flow monitor is a revision like any other: a plain-language intent, a start URL under the public-target rules, an ordered list of steps from a closed vocabulary (go to a page, click, fill a field with a named runner-local credential, wait for or expect text, a URL or an element) and the required outcomes that must all be observed for a pass. It carries no script, expression or secret, and nothing is added to the bounded HTTP path. A runner that has a browser runs each flow in its own process with a fresh private profile, a sanitized environment, one flow at a time and a process-tree kill at the wall-clock limit; all browser traffic goes through one filtering door that enforces NETWORK-001. A runner without a browser reports that, and the flow is Unknown with that reason. Credentials stay on the runner. Each observation keeps an immutable, sanitized step trace and the digest of the revision it ran, and no screenshot or page body. Exceeding any stated bound is a failure naming the bound. A pass is evidence of that flow only. See [Flows](#flows) and [Network and credentials](#network-and-credentials)."
      }
    ],
    "clauseCount": 21,
    "nonGoals": [
      "Real provider or production target actions before explicit authority and verification",
      "Public communication, people paging, and independent geographic monitoring",
      "Fresh-account hosted operation and recipient acceptance remain unverified"
    ],
    "externals": [
      {
        "name": "cloudflare",
        "reason": "An owner-directed deployment sends the application, migrations, configured Worker bindings and secrets, resource settings, and health requests to the owner's Cloudflare account; Cloudflare hosts the Worker, D1 database, and scheduled Cron.",
        "required": false,
        "data": [
          "Cloudflare API account and resource identities, deployment-token authorization, the Worker program and static assets, D1 schema and migrations, Cron settings, bindings, and configured deployment secret values",
          "Deployment readiness requests and responses for the hosted Worker",
          "Hosted Worker requests and responses carrying monitor definitions and target URLs, observations, owner identities and sessions, authentication mail state, notification events and delivery state, runner contact, and audit records",
          "Product and installation records stored in the owner's Cloudflare D1 database, scheduled execution metadata, and configured secret bindings"
        ],
        "adapters": []
      },
      {
        "name": "sendgrid-mail",
        "reason": "SendGrid sends hosted sign-in, incident email and monitoring watch mail when selected as the Base mail adapter.",
        "required": false,
        "data": [
          "SendGrid API-key authorization, sender and recipient/operator email addresses, message subject and text/HTML body, and single-use sign-in links",
          "Delivery ID in the rer_delivery_id custom argument; click, open and analytics tracking are disabled in the submitted provider settings",
          "Incident/test title, target URL, state, monitor and incident identity when present, probe names/outcomes/reasons, explanation, observation time, and private console URL as rendered in message content",
          "For an owner-run drill, the one-time recipient confirmation link and drill time",
          "Owner stale-runner identity/network-label notice or all-healthy digest text, including any monitoring-configuration warning"
        ],
        "adapters": []
      },
      {
        "name": "incident-webhook",
        "reason": "Owner-configured webhook (custom-webhook) sends to custom destination owner-configured-json-receiver: deliver scheduled incident events to the owner's public HTTPS endpoint. The endpoint runs outside this installation.",
        "required": false,
        "data": [
          "The configured endpoint receives the signed JSON request, signature and timestamp headers, source address, and delivery time",
          "Event ID, type, incident key, monitor ID and revision, name, target URL, scheduled slot, state, observation time, probe outcomes and reasons, explanation, and private console URL",
          "A drill event additionally carries the one-time recipient confirmation URL, start time, and expiry; ordinary incident and test events do not",
          "The endpoint's bounded HTTP status, headers, and response body return to the runner for delivery classification"
        ],
        "adapters": []
      },
      {
        "name": "slack-incoming-webhook",
        "reason": "Slack (slack) sends to provider destination slack-incoming-webhook: post escaped notification content to the owner's incoming webhook. Slack runs outside this installation and accepts the configured remote request.",
        "required": false,
        "data": [
          "The configured Slack webhook receives the escaped message body, source address, and delivery time",
          "Incident title and state, monitor identity and target URL, probe outcomes and reasons, explanation, observation time, and console URL",
          "A drill message additionally carries the one-time recipient confirmation URL and drill time",
          "The endpoint's bounded HTTP status, headers, and response body return to the runner for delivery classification"
        ],
        "adapters": []
      },
      {
        "name": "external-heartbeat",
        "reason": "Owner-selected independent HTTPS heartbeat service; optional empty GET while self-check passes. The configured URL is a capability and its path is sent to that service.",
        "required": false,
        "data": [
          "HTTPS host and capability path from the owner-configured URL, request time, and source network address; no request body or product record",
          "The heartbeat service's response status is read and its response body is canceled rather than retained"
        ],
        "adapters": []
      },
      {
        "name": "runner-watch",
        "reason": "Independent webhook or Slack notice configured only in the runner environment.",
        "required": false,
        "data": [
          "Owner-configured webhook receives only unreachable/restored state and times; owner-configured Slack receives the same short notice text",
          "Notification URL capability, runner source address, and request time; no monitor name, target URL, probe result, or product event",
          "The destination's bounded status, response headers, and response body are read for transport classification"
        ],
        "adapters": []
      },
      {
        "name": "owner-app-readiness",
        "reason": "The local setup/dev/preview lifecycle checks the selected Uptime application readiness endpoint; it may be local loopback or an owner-selected remote origin.",
        "required": false,
        "data": [
          "A GET request for the selected application's readiness URL and any HTTP redirect destinations followed by the CLI; no request body or configured authorization header is sent",
          "The destination sees the CLI source address and request timing; the CLI reads only the returned health status and JSON readiness value"
        ],
        "adapters": []
      },
      {
        "name": "configured-dns-resolver",
        "reason": "Private runners and owner tools use their configured DNS resolver. Hosted public checks validate A/AAAA answers through Cloudflare DNS over HTTPS; Workers fetch uses Cloudflare’s public Internet resolver and transport.",
        "required": false,
        "data": [
          "Queried hostnames for A/AAAA or system address lookup, resolver source address, and lookup timing; DNS carries no URL path, request body, or HTTP credential",
          "Hosted checks send the target and canary hostnames as A/AAAA queries to https://cloudflare-dns.com/dns-query; no target URL path, body or credential is included."
        ],
        "adapters": []
      },
      {
        "name": "public-monitor-targets",
        "reason": "The hosted Worker or an explicitly assigned private runner sends scheduled requests to the owner’s public target and optional canary URLs.",
        "required": false,
        "data": [
          "Target hostname, path and query, method, request time and runner source address; configured headers and request body where the monitor has them",
          "An owner-held request credential is sent only to its exact authorized target origin and monitor; credentials, custom headers and body are stripped on a cross-origin redirect",
          "The target returns status and headers plus a bounded response body used for assertions; raw response bodies are not retained in observations",
          "An external canary is a status-only GET: it sends no request credential, custom header or body and reads zero response-body bytes; validated public redirect hops may also be contacted"
        ],
        "adapters": []
      },
      {
        "name": "site-discovery",
        "reason": "The runner performs bounded read-only discovery of the owner's chosen site, following its public redirects and crawling permitted pages and related API/status hosts.",
        "required": false,
        "data": [
          "The owner-selected URL, request host/path/query, GET or HEAD method, discovery User-Agent and other headers, request time, and runner source address",
          "The initial URL's public redirect chain, then robots files, pages, JSON/spec documents and redirect destinations on its permitted registrable domains and linked status hosts are read with bounded bodies in runner memory",
          "Only the input/final URL, contacted hostnames, request count and duration, short notes, and validated proposed monitor definitions return to the console; raw target HTML, JSON and response headers are not returned, stored, logged, or rendered as console HTML"
        ],
        "adapters": []
      },
      {
        "name": "isolated-browser-flow-targets",
        "reason": "A fresh runner browser follows owner-defined flows through the filtering proxy; target pages and their public network dependencies receive ordinary browser requests.",
        "required": false,
        "data": [
          "Owner-defined top-level URLs and paths, redirects that remain within the declared origins, and requests to public subresources and WebSocket destinations initiated by those pages; DNS names, source address, and request timing are visible at the relevant destinations",
          "Browser-generated request headers, referrer/origin information, and cookies a destination sets may be sent to the relevant public destination; page content is processed locally in the runner to execute steps, while no raw page body or screenshot returns in the control-plane result or observation",
          "A named owner-held flow credential is filled only at its exact configured origin and may be sent by that site-form submission; the secret itself remains in runner-local custody and is redacted from traces",
          "Private, loopback, link-local and metadata addresses are blocked; top-level navigation is limited to declared origins, while public subresources and WebSockets are individually passed through the filtering proxy"
        ],
        "adapters": []
      },
      {
        "name": "runner-control-plane",
        "reason": "The separately operated runner uses signed HTTPS requests to the configured Uptime Worker control plane for enrolment, claims, results, discovery, notification custody, and contact.",
        "required": false,
        "data": [
          "Runner key authentication and signature, runner identity, declared network label, browser capability, request times, and claimed task identifiers",
          "Assigned monitor and flow definitions, canary URLs, retry and lease data, and signed attempt evidence, including status, assertions, timings, and bounded flow trace",
          "Discovery input URLs and derived host/proposal results",
          "For notification delivery, the claimed endpoint URL, signing credential and event payload are returned to the runner for the one configured send; signed outcome and bounded provider response details return to the Worker"
        ],
        "adapters": []
      },
      {
        "name": "optional-identity-provider-setup",
        "reason": "The shared setup CLI can read selected provider discovery documents. The completed local probe read dependency metadata, then failed at unmounted application dependency approval (404) before owner creation or any provider link request. Uptime does not mount linked-provider routes; runtime OIDC callback, token, JWKS and dependency exchange are unsupported.",
        "required": false,
        "data": [
          "Selected issuer hostname and read-only setup requests for its OIDC configuration, RER provider document, and dependency-interface metadata",
          "A setup approval request to the Uptime origin carries issuer/interface and the configured setup token; the current unmounted route returns 404 before owner creation. The measured probe made no one-time provider link request. A future shared linking path may send app origin, interface and a temporary link capability, requiring separate adoption and evidence.",
          "No linked sign-in, authorization-code callback, runtime token/JWKS exchange or user-profile exchange is implemented by the current Uptime server; do not infer an operational provider integration from the optional declaration"
        ],
        "adapters": []
      },
      {
        "name": "optional-management-editor",
        "reason": "An authenticated owner page may create the configured management editor iframe while the editor is hidden. This is an explicit private management integration, not a public embeddable widget. This is the explicit BASE-DATA-005 exception: the configured origin may belong to the author and receive opted-in requests; the native product has no operational dependency on this integration.",
        "required": false,
        "data": [
          "The exact configured management origin receives an iframe request containing the installation ID, parent page origin, and editor surface; after handshake it also receives the current page path",
          "Rendered page title and up to 60 visible text/element descriptors are sent only after the owner opens the editor and explicitly enables context sharing; form values and private-marked elements are excluded",
          "Editor protocol messages, live-edit requests and results are exchanged with the configured management origin"
        ],
        "adapters": []
      },
      {
        "name": "resend-mail",
        "reason": "Resend sends hosted sign-in, incident email and monitoring watch mail when selected as the Base mail adapter.",
        "required": false,
        "data": [
          "Resend API-key authorization, sender and recipient/operator email addresses, message subject and text/HTML body, and single-use sign-in links",
          "Delivery ID in the Idempotency-Key request header",
          "Incident/test title, target URL, state, monitor and incident identity when present, probe names/outcomes/reasons, explanation, observation time, and private console URL as rendered in message content",
          "For an owner-run drill, the one-time recipient confirmation link and drill time",
          "Owner stale-runner identity/network-label notice or all-healthy digest text, including any monitoring-configuration warning"
        ],
        "adapters": []
      },
      {
        "name": "cloudflare-mail",
        "reason": "Cloudflare Email Sending sends hosted sign-in, incident email and monitoring watch mail when selected as the Base mail adapter.",
        "required": false,
        "data": [
          "Cloudflare API-key authorization and configured account identity, sender and recipient/operator email addresses, message subject and text/HTML body, and single-use sign-in links",
          "Account-scoped email-sending API request with no Uptime attachment payload",
          "Incident/test title, target URL, state, monitor and incident identity when present, probe names/outcomes/reasons, explanation, observation time, and private console URL as rendered in message content",
          "For an owner-run drill, the one-time recipient confirmation link and drill time",
          "Owner stale-runner identity/network-label notice or all-healthy digest text, including any monitoring-configuration warning"
        ],
        "adapters": []
      }
    ],
    "extensionPoints": [],
    "shots": [],
    "landing": null,
    "hasReadme": true,
    "hasBaseline": true,
    "manifestFile": "seed.json",
    "spine": {
      "id": "monitor",
      "record": "Immutable scheduled slot observations and explained private alert outbox"
    },
    "composition": {
      "base": "base",
      "family": "uptime",
      "edition": "uptime",
      "modules": [
        "operator-auth",
        "mail",
        "integrations",
        "deploy-kit",
        "onboarding"
      ]
    },
    "operatingCost": {
      "status": "unmeasured"
    },
    "limits": {
      "status": "estimated-not-tested",
      "publicRequestsPerMinutePerIp": {
        "documents": 180,
        "health": 180,
        "authentication": 120,
        "setup": 180,
        "editor": 180,
        "redirects": 180,
        "heartbeats": 600,
        "runner": 1800,
        "assets": 600,
        "development": 600,
        "drills": 30,
        "development-assets": 1800
      },
      "notes": "Owner-tunable source settings; each class shares one fixed 60-second D1 window per client. Production assets retain their own budget. Local Vite compiler assets use a separate budget for the unbundled browser graph: about 140 module requests per console load, with room for twelve loads per minute. These defaults are estimated, not load tested. Hosted CF-Connecting-IP must be a valid single IP; missing/malformed values share an unknown-client bucket. Local mode ignores all forwarding headers and uses one loopback bucket. Only keyed hashes of client identities are stored."
    },
    "accessibility": {
      "level": "WCAG 2.2 AA",
      "status": "target; unaudited"
    }
  },
  "artifacts": [
    {
      "path": "documents/seed.json",
      "target": "agents/seeds/uptime/seed.json",
      "sha256": "905f34ce37efdf61cbec03a8ca461583bffbf3d86d846836101cd39cea0799dd"
    },
    {
      "path": "documents/CONTRACT.md",
      "target": "agents/seeds/uptime/CONTRACT.md",
      "sha256": "8a7311a1925da24179c62a83cb4c1f1027c3833eab8eef97cab658b97fcee76d"
    },
    {
      "path": "documents/AGENTS.md",
      "target": "agents/seeds/uptime/AGENTS.md",
      "sha256": "b232927d9e75c9d85227e7736d0204acc44929abff56f3c30e1285331eeaf2a4"
    },
    {
      "path": "documents/LICENSE",
      "target": "agents/seeds/uptime/LICENSE",
      "sha256": "2f5076ef027045b9e0e72df8aa61ca8551e54b1877d531656d6e7985b2c32324"
    },
    {
      "path": "documents/RELEASE.json",
      "target": "agents/seeds/uptime/RELEASE.json",
      "sha256": "a517b33fbb3fbb0dc8c253f5b2fc348be0605904e5b3d79dfbcab804f0f78336"
    },
    {
      "path": "documents/README.md",
      "target": "agents/seeds/uptime/README.md",
      "sha256": "fb1afff383644bb9080e70a2227b9f058a1de37fea24e1b8b8641dabd555fdac"
    },
    {
      "path": "documents/BASELINE.md",
      "target": "agents/seeds/uptime/BASELINE.md",
      "sha256": "5575956564905e94e5d3e1e164228f81c213f2ad3e7bf66849885c839b788369"
    },
    {
      "path": "documents/OPERATIONS.md",
      "target": "agents/seeds/uptime/OPERATIONS.md",
      "sha256": "8141362f164f946e44a74ecdd3081034b236ad51d5ed85385e0d3e2914c2111d"
    },
    {
      "path": "documents/ACCEPTANCE.md",
      "target": "agents/seeds/uptime/ACCEPTANCE.md",
      "sha256": "45b5566da7b3975848c4d992a77b7679d3c1ca2fbed0be35b362eb6c01e4ed7b"
    }
  ]
}
