{
  "version": 1,
  "edition": "happytohelp",
  "requiredEnvironment": [],
  "commands": {
    "setup": {
      "argv": [
        "pnpm",
        "run",
        "setup",
        "--",
        "--local"
      ],
      "effects": "Collect selected migrations and prepare local D1 for first-owner setup. --plan validates a remote target and prints resource names; --remote creates D1/R2/Queues in your Cloudflare account and applies remote migrations without publishing code."
    },
    "deploy": {
      "argv": [
        "pnpm",
        "run",
        "deploy",
        "--",
        "--local"
      ],
      "effects": "Build, apply local migrations and run a Wrangler packaging dry run. --remote refuses a fresh installation (no owner yet) without a private H2H_SETUP_TOKEN of at least 32 characters, then publishes the Worker/assets to the prepared target, passing configured secrets privately, and checks D1/R2 health."
    },
    "verify": {
      "argv": [
        "pnpm",
        "run",
        "verify"
      ],
      "effects": "Run the operations descriptor, build, type check, module and emitted-Worker runtime tests and source integrity check. Browser suites run separately (package.json test:*-browser scripts)."
    }
  },
  "authentication": "Remote commands require Wrangler sign-in or CLOUDFLARE_API_TOKEN, plus CLOUDFLARE_ACCOUNT_ID, H2H_RESOURCE_PREFIX and H2H_PUBLIC_ORIGIN. Set H2H_SETUP_TOKEN before deploying a fresh installation. Provider secrets remain private. Local checks do not validate credentials; see OPERATIONS.md for token permissions and origin rules.",
  "health": {
    "path": "/health",
    "meaning": "Native Worker with reachable D1 and R2; does not prove queues, sockets, providers or product acceptance."
  },
  "acceptance": {
    "document": "ACCEPTANCE.md",
    "meaning": "Product requirements and the evidence each requires; a passing result belongs to a named source revision."
  },
  "configuration": [
    {
      "path": "wrangler.jsonc",
      "description": "Native DB/FILES/JOBS/CONVERSATIONS bindings and scheduled recovery; generated migrations are collected before setup."
    },
    {
      "path": "scripts/deployment/environment.mjs",
      "description": "Selected optional runtime variable and private-secret allowlists; values never appear in describe/plan."
    },
    {
      "path": "OPERATIONS.md",
      "description": "Local installation, remote prerequisites and publication, optional provider configuration and resumable local legacy import."
    },
    {
      "path": "docs/PUBLIC-LIMITS.md",
      "description": "Optional RATE_LIMITS and AI_DAILY_CEILINGS JSON variables: public request limits (HTTP 429 with Retry-After) and per-UTC-day automatic AI ceilings per project and installation; GET /api/dashboard/projects/:projectId/ai-usage reports the day's usage."
    },
    {
      "path": "docs/PRIVACY.md",
      "description": "Personal data stored and sent to configured providers, retention, and owner/admin contact erasure (POST /api/management/projects/:projectId/contacts/:contactId/erase or the dashboard contact page)."
    }
  ],
  "notes": [
    "Requires Node >=26.8.1 and pnpm 10.12.4 with the committed lockfile. Use pnpm run setup, not pnpm setup.",
    "node scripts/install.mjs is the guided installer; it runs these same commands after explicit approval.",
    "describe/check and a local packaging dry run do not establish a deployment, provider behavior or a production data migration.",
    "REGISTRATION_ENABLED=true lets every self-registered project spend the installation's AI provider keys; only AI_DAILY_CEILINGS.repliesPerInstallation caps the total. Set TURNSTILE_SECRET, a repliesPerInstallation you are willing to pay daily, and provider-side spending limits first."
  ]
}
