{
  "schemaVersion": 1,
  "generatedAt": "2026-06-17T22:59:00.032Z",
  "status": "CLOUD_BOOTSTRAP_WAITING_ON_API_TOKEN",
  "label": "Cloud Bootstrap Waiting On API Token",
  "discovery": {
    "status": "CLOUDFLARE_DISCOVERY_AUTH_NEEDED",
    "label": "Cloudflare Discovery Needs API Token",
    "targetMatches": 0,
    "suggestedDashboardUpdates": 0,
    "reportPath": "docs/launch_command_center/CLOUDFLARE_HANDOFF_DISCOVERY.md",
    "apiTokenPresent": false,
    "automationCredential": "CLOUDFLARE_API_TOKEN",
    "automationAuthRequired": true
  },
  "resources": [
    {
      "id": "command-center-d1",
      "type": "D1",
      "name": "nyra_command_center",
      "owner": "User + Codex",
      "status": "Waiting on Cloudflare API token",
      "createCommand": "npx wrangler d1 create nyra_command_center",
      "verifyCommand": "npm run cloudflare:discover",
      "dashboardPage": "pages/cloud.html",
      "dashboardField": "cloudMigration.d1DatabaseId",
      "statePath": "cloudMigration.d1DatabaseId",
      "noGoRule": "Do not deploy command-center Worker production until this D1 database_id is concrete in wrangler.jsonc.",
      "action": "Create a scoped Cloudflare API token for the account that will host NyrA, set it as CLOUDFLARE_API_TOKEN in the local shell or automation secret store, then rerun npm run cloudflare:discover."
    },
    {
      "id": "billing-d1",
      "type": "D1",
      "name": "nyra_billing",
      "owner": "User + Codex",
      "status": "Waiting on Cloudflare API token",
      "createCommand": "npx wrangler d1 create nyra_billing",
      "verifyCommand": "npm run cloudflare:discover",
      "dashboardPage": "pages/cloud-billing.html",
      "dashboardField": "billingCloud.d1DatabaseId",
      "statePath": "billingCloud.d1DatabaseId",
      "noGoRule": "Do not deploy billing Worker production until this D1 database_id is concrete in wrangler.jsonc.",
      "action": "Create a scoped Cloudflare API token for the account that will host NyrA, set it as CLOUDFLARE_API_TOKEN in the local shell or automation secret store, then rerun npm run cloudflare:discover."
    },
    {
      "id": "command-center-r2",
      "type": "R2",
      "name": "nyra-command-center-uploads",
      "owner": "User + Codex",
      "status": "Ready for config review",
      "createCommand": "npx wrangler r2 bucket create nyra-command-center-uploads",
      "verifyCommand": "npm run cloudflare:discover",
      "dashboardPage": "pages/cloud.html",
      "dashboardField": "cloudMigration.r2Bucket",
      "statePath": "cloudMigration.r2Bucket",
      "noGoRule": "Keep the handoff upload bucket private; never enable public bucket access for private launch evidence.",
      "action": "Run discovery/config sync and verify the non-secret ID or URL is saved in the dashboard before deployment."
    },
    {
      "id": "mobile-support-r2",
      "type": "R2",
      "name": "nyra-mobile-support-logs",
      "owner": "User + Codex",
      "status": "Ready for config review",
      "createCommand": "npx wrangler r2 bucket create nyra-mobile-support-logs",
      "verifyCommand": "npm run cloudflare:discover && npm run cloud:mobile-bridge:check",
      "dashboardPage": "pages/cloud-mobile-bridge.html",
      "dashboardField": "mobileBridge.r2BucketName",
      "statePath": "mobileBridge.r2BucketName",
      "noGoRule": "Keep mobile support diagnostics private; only redacted support-log readbacks may be exposed to support flows.",
      "action": "Run discovery/config sync and verify the non-secret ID or URL is saved in the dashboard before deployment."
    },
    {
      "id": "mobile-android-r2",
      "type": "R2",
      "name": "nyra-android-releases",
      "owner": "User + Codex",
      "status": "Ready for config review",
      "createCommand": "npx wrangler r2 bucket create nyra-android-releases",
      "verifyCommand": "npm run cloudflare:discover && npm run cloud:mobile-bridge:check",
      "dashboardPage": "pages/cloud-mobile-bridge.html",
      "dashboardField": "mobileBridge.androidReleasesBucketName",
      "statePath": "mobileBridge.androidReleasesBucketName",
      "noGoRule": "Serve APK downloads through ticketed Worker routes, not public unauthenticated bucket URLs.",
      "action": "Run discovery/config sync and verify the non-secret ID or URL is saved in the dashboard before deployment."
    },
    {
      "id": "pages-project",
      "type": "Pages",
      "name": "nyra-command-center-dashboard",
      "owner": "User + Codex",
      "status": "Ready for config review",
      "createCommand": "npx wrangler pages project create nyra-command-center-dashboard --production-branch main",
      "verifyCommand": "npm run cloudflare:discover",
      "dashboardPage": "pages/cloud.html",
      "dashboardField": "cloudPages.projectName",
      "statePath": "cloudPages.projectName",
      "noGoRule": "Protect the dashboard with Cloudflare Access or equivalent private access before storing real business records.",
      "action": "Run discovery/config sync and verify the non-secret ID or URL is saved in the dashboard before deployment."
    },
    {
      "id": "command-center-worker",
      "type": "Worker",
      "name": "nyra-command-center-api",
      "owner": "Codex",
      "status": "Waiting on Cloudflare API token",
      "createCommand": "npm run cloud:command-center:deploy",
      "verifyCommand": "npm run cloud:command-center:health",
      "dashboardPage": "pages/cloud.html",
      "dashboardField": "cloudSync.apiUrl",
      "statePath": "cloudSync.apiUrl",
      "noGoRule": "Do not deploy until command-center D1/R2, ALLOWED_ORIGIN, and NYRA_COMMAND_TOKEN are configured.",
      "action": "Create a scoped Cloudflare API token for the account that will host NyrA, set it as CLOUDFLARE_API_TOKEN in the local shell or automation secret store, then rerun npm run cloudflare:discover."
    },
    {
      "id": "billing-worker",
      "type": "Worker",
      "name": "nyra-billing-api",
      "owner": "Codex",
      "status": "Waiting on Cloudflare API token",
      "createCommand": "npm run cloud:billing:deploy",
      "verifyCommand": "npm run cloud:billing:check",
      "dashboardPage": "pages/cloud-billing.html",
      "dashboardField": "billingCloud.workerUrl",
      "statePath": "billingCloud.workerUrl",
      "noGoRule": "Do not deploy live billing until Stripe test-mode rehearsal, secrets, Customer Portal, support, and policy gates pass.",
      "action": "Create a scoped Cloudflare API token for the account that will host NyrA, set it as CLOUDFLARE_API_TOKEN in the local shell or automation secret store, then rerun npm run cloudflare:discover."
    },
    {
      "id": "mobile-bridge-worker",
      "type": "Worker",
      "name": "nyra-mobile-bridge-api",
      "owner": "Codex",
      "status": "Waiting on Cloudflare API token",
      "createCommand": "npm run cloud:mobile-bridge:bootstrap -- --worker-url=https://bridge.porterlabz.com --write-state",
      "verifyCommand": "npm run cloud:mobile-bridge:check && npm run test:mobile-bridge-security",
      "dashboardPage": "pages/cloud-mobile-bridge.html",
      "dashboardField": "mobileBridge.workerUrl",
      "statePath": "mobileBridge.workerUrl",
      "noGoRule": "Do not rebuild Android paid-beta against this Worker until R2 APK hosting, provider secrets, device-token auth, and phone self-test evidence pass.",
      "action": "Create a scoped Cloudflare API token for the account that will host NyrA, set it as CLOUDFLARE_API_TOKEN in the local shell or automation secret store, then rerun npm run cloudflare:discover."
    }
  ],
  "commandSequence": [
    {
      "id": "local-validation",
      "phase": "0. Local Validation",
      "owner": "Codex",
      "command": "npm run cloud:command-center:check && npm run cloud:billing:check && npm run cloud:mobile-bridge:check && npm run cloud:command-center:pages:check",
      "purpose": "Verify local command-center Worker, billing Worker, mobile bridge Worker, and the Pages artifact before touching Cloudflare.",
      "noGoRule": "Do not run remote creation/deploy commands while local cloud checks fail."
    },
    {
      "id": "cloudflare-api-token",
      "phase": "1. Authentication",
      "owner": "User",
      "command": "npm run cloudflare:discover",
      "purpose": "Set CLOUDFLARE_API_TOKEN in the local shell or automation secret store, then rerun discovery so daily agents can continue without an interactive browser.",
      "noGoRule": "Never paste Cloudflare API tokens into repo files, dashboard fields, Markdown, CSV, screenshots, or chat."
    },
    {
      "id": "wrangler-login-fallback",
      "phase": "1. Authentication",
      "owner": "User",
      "command": "npx wrangler login",
      "purpose": "Optional interactive browser fallback for the Windows desktop; automation still needs CLOUDFLARE_API_TOKEN.",
      "noGoRule": "Never paste Cloudflare API tokens or recovery codes into repo files, dashboard fields, screenshots, or chat."
    },
    {
      "id": "cloudflare-discovery",
      "phase": "1. Authentication",
      "owner": "Codex",
      "command": "npm run cloudflare:discover",
      "purpose": "Discover existing NyrA Cloudflare resources and avoid duplicate creation.",
      "noGoRule": "Discovery must remain non-destructive and redacted."
    },
    {
      "id": "create-command-center-d1",
      "phase": "2. Remote Resources",
      "owner": "User + Codex",
      "command": "npx wrangler d1 create nyra_command_center",
      "purpose": "Create D1 resource nyra_command_center.",
      "noGoRule": "Do not deploy command-center Worker production until this D1 database_id is concrete in wrangler.jsonc."
    },
    {
      "id": "create-billing-d1",
      "phase": "2. Remote Resources",
      "owner": "User + Codex",
      "command": "npx wrangler d1 create nyra_billing",
      "purpose": "Create D1 resource nyra_billing.",
      "noGoRule": "Do not deploy billing Worker production until this D1 database_id is concrete in wrangler.jsonc."
    },
    {
      "id": "create-command-center-r2",
      "phase": "2. Remote Resources",
      "owner": "User + Codex",
      "command": "npx wrangler r2 bucket create nyra-command-center-uploads",
      "purpose": "Create R2 resource nyra-command-center-uploads.",
      "noGoRule": "Keep the handoff upload bucket private; never enable public bucket access for private launch evidence."
    },
    {
      "id": "create-mobile-support-r2",
      "phase": "2. Remote Resources",
      "owner": "User + Codex",
      "command": "npx wrangler r2 bucket create nyra-mobile-support-logs",
      "purpose": "Create R2 resource nyra-mobile-support-logs.",
      "noGoRule": "Keep mobile support diagnostics private; only redacted support-log readbacks may be exposed to support flows."
    },
    {
      "id": "create-mobile-android-r2",
      "phase": "2. Remote Resources",
      "owner": "User + Codex",
      "command": "npx wrangler r2 bucket create nyra-android-releases",
      "purpose": "Create R2 resource nyra-android-releases.",
      "noGoRule": "Serve APK downloads through ticketed Worker routes, not public unauthenticated bucket URLs."
    },
    {
      "id": "create-pages-project",
      "phase": "2. Remote Resources",
      "owner": "User + Codex",
      "command": "npx wrangler pages project create nyra-command-center-dashboard --production-branch main",
      "purpose": "Create Pages resource nyra-command-center-dashboard.",
      "noGoRule": "Protect the dashboard with Cloudflare Access or equivalent private access before storing real business records."
    },
    {
      "id": "sync-non-secret-config",
      "phase": "3. Config Sync",
      "owner": "Codex",
      "command": "npm run cloud:command-center:config:sync && npm run cloud:billing:config:sync && npm run cloud:mobile-bridge:bootstrap -- --dry-run --skip-secrets --skip-deploy",
      "purpose": "Apply saved non-secret dashboard values to production Worker configs and verify the mobile bridge bootstrap plan.",
      "noGoRule": "This must not write Stripe secrets, bearer tokens, or Cloudflare tokens into repo files."
    },
    {
      "id": "command-token-secret",
      "phase": "4. Secrets",
      "owner": "User + Codex",
      "command": "npx wrangler secret put NYRA_COMMAND_TOKEN --cwd cloud/command-center-worker --env production",
      "purpose": "Set the private command-center API bearer token through Wrangler secrets only.",
      "noGoRule": "Do not paste this token into dashboard fields, repo files, Markdown, CSV, screenshots, or chat."
    },
    {
      "id": "billing-secret-stripe-secret-key",
      "phase": "4. Secrets",
      "owner": "User + Codex",
      "command": "npx wrangler secret put STRIPE_SECRET_KEY --cwd cloud/billing-worker --env production",
      "purpose": "Set STRIPE_SECRET_KEY for the billing Worker through Wrangler secrets only.",
      "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
    },
    {
      "id": "billing-secret-stripe-webhook-secret",
      "phase": "4. Secrets",
      "owner": "User + Codex",
      "command": "npx wrangler secret put STRIPE_WEBHOOK_SECRET --cwd cloud/billing-worker --env production",
      "purpose": "Set STRIPE_WEBHOOK_SECRET for the billing Worker through Wrangler secrets only.",
      "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
    },
    {
      "id": "billing-secret-nyra-stripe-price-pro-monthly",
      "phase": "4. Secrets",
      "owner": "User + Codex",
      "command": "npx wrangler secret put NYRA_STRIPE_PRICE_PRO_MONTHLY --cwd cloud/billing-worker --env production",
      "purpose": "Set NYRA_STRIPE_PRICE_PRO_MONTHLY for the billing Worker through Wrangler secrets only.",
      "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
    },
    {
      "id": "billing-secret-nyra-billing-success-url",
      "phase": "4. Secrets",
      "owner": "User + Codex",
      "command": "npx wrangler secret put NYRA_BILLING_SUCCESS_URL --cwd cloud/billing-worker --env production",
      "purpose": "Set NYRA_BILLING_SUCCESS_URL for the billing Worker through Wrangler secrets only.",
      "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
    },
    {
      "id": "billing-secret-nyra-billing-cancel-url",
      "phase": "4. Secrets",
      "owner": "User + Codex",
      "command": "npx wrangler secret put NYRA_BILLING_CANCEL_URL --cwd cloud/billing-worker --env production",
      "purpose": "Set NYRA_BILLING_CANCEL_URL for the billing Worker through Wrangler secrets only.",
      "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
    },
    {
      "id": "billing-secret-nyra-billing-return-url",
      "phase": "4. Secrets",
      "owner": "User + Codex",
      "command": "npx wrangler secret put NYRA_BILLING_RETURN_URL --cwd cloud/billing-worker --env production",
      "purpose": "Set NYRA_BILLING_RETURN_URL for the billing Worker through Wrangler secrets only.",
      "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
    },
    {
      "id": "billing-secret-nyra-license-api-token",
      "phase": "4. Secrets",
      "owner": "User + Codex",
      "command": "npx wrangler secret put NYRA_LICENSE_API_TOKEN --cwd cloud/billing-worker --env production",
      "purpose": "Set NYRA_LICENSE_API_TOKEN for the billing Worker through Wrangler secrets only.",
      "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
    },
    {
      "id": "billing-secret-nyra-license-signing-secret",
      "phase": "4. Secrets",
      "owner": "User + Codex",
      "command": "npx wrangler secret put NYRA_LICENSE_SIGNING_SECRET --cwd cloud/billing-worker --env production",
      "purpose": "Set NYRA_LICENSE_SIGNING_SECRET for the billing Worker through Wrangler secrets only.",
      "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
    },
    {
      "id": "mobile-bridge-secret-nyra-mobile-bridge-token",
      "phase": "4. Secrets",
      "owner": "User + Codex",
      "command": "npx wrangler secret put NYRA_MOBILE_BRIDGE_TOKEN --cwd cloud/mobile-bridge-worker --env production",
      "purpose": "Set NYRA_MOBILE_BRIDGE_TOKEN for the mobile bridge Worker through Wrangler secrets only.",
      "noGoRule": "Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo."
    },
    {
      "id": "mobile-bridge-secret-nyra-openai-api-key",
      "phase": "4. Secrets",
      "owner": "User + Codex",
      "command": "npx wrangler secret put NYRA_OPENAI_API_KEY --cwd cloud/mobile-bridge-worker --env production",
      "purpose": "Set NYRA_OPENAI_API_KEY for the mobile bridge Worker through Wrangler secrets only.",
      "noGoRule": "Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo."
    },
    {
      "id": "mobile-bridge-secret-nyra-anthropic-api-key",
      "phase": "4. Secrets",
      "owner": "User + Codex",
      "command": "npx wrangler secret put NYRA_ANTHROPIC_API_KEY --cwd cloud/mobile-bridge-worker --env production",
      "purpose": "Set NYRA_ANTHROPIC_API_KEY for the mobile bridge Worker through Wrangler secrets only.",
      "noGoRule": "Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo."
    },
    {
      "id": "mobile-bridge-secret-nyra-gemini-api-key",
      "phase": "4. Secrets",
      "owner": "User + Codex",
      "command": "npx wrangler secret put NYRA_GEMINI_API_KEY --cwd cloud/mobile-bridge-worker --env production",
      "purpose": "Set NYRA_GEMINI_API_KEY for the mobile bridge Worker through Wrangler secrets only.",
      "noGoRule": "Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo."
    },
    {
      "id": "mobile-bridge-secret-nyra-grok-api-key",
      "phase": "4. Secrets",
      "owner": "User + Codex",
      "command": "npx wrangler secret put NYRA_GROK_API_KEY --cwd cloud/mobile-bridge-worker --env production",
      "purpose": "Set NYRA_GROK_API_KEY for the mobile bridge Worker through Wrangler secrets only.",
      "noGoRule": "Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo."
    },
    {
      "id": "mobile-bridge-secret-nyra-license-signing-secret",
      "phase": "4. Secrets",
      "owner": "User + Codex",
      "command": "npx wrangler secret put NYRA_LICENSE_SIGNING_SECRET --cwd cloud/mobile-bridge-worker --env production",
      "purpose": "Set NYRA_LICENSE_SIGNING_SECRET for the mobile bridge Worker through Wrangler secrets only.",
      "noGoRule": "Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo."
    },
    {
      "id": "mobile-bridge-secret-nyra-android-download-ticket-secret",
      "phase": "4. Secrets",
      "owner": "User + Codex",
      "command": "npx wrangler secret put NYRA_ANDROID_DOWNLOAD_TICKET_SECRET --cwd cloud/mobile-bridge-worker --env production",
      "purpose": "Set NYRA_ANDROID_DOWNLOAD_TICKET_SECRET for the mobile bridge Worker through Wrangler secrets only.",
      "noGoRule": "Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo."
    },
    {
      "id": "command-center-migrations",
      "phase": "5. Migrations",
      "owner": "User + Codex",
      "command": "npx wrangler d1 migrations apply nyra_command_center --cwd cloud/command-center-worker --env production",
      "purpose": "Apply command-center D1 schema after the concrete database ID is configured.",
      "noGoRule": "Do not apply migrations to the wrong Cloudflare account or placeholder database ID."
    },
    {
      "id": "billing-migrations",
      "phase": "5. Migrations",
      "owner": "User + Codex",
      "command": "npx wrangler d1 migrations apply nyra_billing --cwd cloud/billing-worker --env production",
      "purpose": "Apply billing D1 schema after the concrete database ID is configured.",
      "noGoRule": "Do not run live billing until Stripe test-mode and legal/support gates pass."
    },
    {
      "id": "deploy-command-center-worker",
      "phase": "6. Deploy",
      "owner": "Codex",
      "command": "npm run cloud:command-center:deploy",
      "purpose": "Deploy the private command-center Worker API.",
      "noGoRule": "Do not deploy with placeholder D1 ID or placeholder ALLOWED_ORIGIN."
    },
    {
      "id": "deploy-command-center-pages",
      "phase": "6. Deploy",
      "owner": "Codex",
      "command": "npm run cloud:command-center:pages:deploy",
      "purpose": "Deploy the command-center dashboard artifact to Cloudflare Pages.",
      "noGoRule": "Protect dashboard access before storing real business records or user files."
    },
    {
      "id": "deploy-billing-worker",
      "phase": "6. Deploy",
      "owner": "Codex",
      "command": "npm run cloud:billing:deploy",
      "purpose": "Deploy the billing Worker after test-mode payment rehearsal inputs are complete.",
      "noGoRule": "Do not expose live checkout while deployability preflight still reports P0 live-money blockers."
    },
    {
      "id": "deploy-mobile-bridge-worker",
      "phase": "6. Deploy",
      "owner": "Codex",
      "command": "npm run cloud:mobile-bridge:bootstrap -- --worker-url=https://bridge.porterlabz.com --write-state",
      "purpose": "Create/verify mobile bridge R2 buckets, upload the APK, deploy the Worker, and prove status/update/APK ticket/support-log/chat before saving state.",
      "noGoRule": "Do not replace the Android bundled bridge URL for paid beta until this post-deploy smoke passes and the shared alpha token is removed."
    },
    {
      "id": "first-cloud-roundtrip",
      "phase": "7. First Sync",
      "owner": "Codex",
      "command": "npm run cloud:command-center:health && npm run cloud:command-center:push && npm run cloud:command-center:scan && npm run cloud:command-center:ingest && npm run cloud:command-center:roundtrip",
      "purpose": "Prove cloud command-center state can be pushed, scanned, safely ingested, and read back.",
      "noGoRule": "Use only temporary shell env vars for NYRA_COMMAND_CENTER_API_URL and NYRA_COMMAND_CENTER_TOKEN."
    },
    {
      "id": "billing-live-preflight-test-mode",
      "phase": "7. First Sync",
      "owner": "Codex",
      "command": "npm run billing:live-preflight -- --mode test --allow-blocked",
      "purpose": "Run a guarded test-mode billing go-live rehearsal after cloud URLs and secrets exist.",
      "noGoRule": "Do not run live-mode billing rehearsal until user explicitly confirms live Stripe readiness."
    },
    {
      "id": "mobile-phone-self-test-after-deploy",
      "phase": "7. First Sync",
      "owner": "User + Codex",
      "command": "npm run phone:self-test:ingest && npm run test:phone-self-test-ingest",
      "purpose": "Ingest and verify a physical-phone self-test after the deployed bridge replaces the temporary tunnel.",
      "noGoRule": "Do not clear the physical-phone gate from web-surface evidence; it must come from the installed Android app."
    }
  ],
  "actions": [
    {
      "id": "cloudflare-api-token",
      "phase": "1. Authentication",
      "priority": "P0",
      "owner": "User",
      "status": "Waiting on user",
      "label": "Cloudflare API token required",
      "action": "Create a scoped Cloudflare API token for the account that will host NyrA, set it as CLOUDFLARE_API_TOKEN in the local shell or automation secret store, then rerun npm run cloudflare:discover.",
      "command": "npm run cloudflare:discover",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "cloudMigration.accountReady",
      "verificationCommand": "npm run cloudflare:discover",
      "noGoRule": "Never store Cloudflare tokens, API keys, recovery codes, or password material in repo files or dashboard state."
    },
    {
      "id": "wrangler-login-fallback",
      "phase": "1. Authentication",
      "priority": "P1",
      "owner": "User",
      "status": "Optional fallback",
      "label": "Wrangler login",
      "action": "If you are sitting at the Windows desktop and prefer browser auth, run npx wrangler login and approve the Cloudflare account that will host NyrA. Automation still needs CLOUDFLARE_API_TOKEN.",
      "command": "npx wrangler login",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "cloudMigration.accountReady",
      "verificationCommand": "npm run cloudflare:discover",
      "noGoRule": "Never store Cloudflare tokens, API keys, recovery codes, or password material in repo files or dashboard state."
    },
    {
      "id": "command-center-d1",
      "phase": "2. Remote Resources",
      "priority": "P0",
      "owner": "User + Codex",
      "status": "Waiting on Cloudflare API token",
      "label": "D1: nyra_command_center",
      "action": "Create a scoped Cloudflare API token for the account that will host NyrA, set it as CLOUDFLARE_API_TOKEN in the local shell or automation secret store, then rerun npm run cloudflare:discover.",
      "command": "npx wrangler d1 create nyra_command_center",
      "dashboardPage": "pages/cloud.html",
      "dashboardField": "cloudMigration.d1DatabaseId",
      "verificationCommand": "npm run cloudflare:discover",
      "noGoRule": "Do not deploy command-center Worker production until this D1 database_id is concrete in wrangler.jsonc."
    },
    {
      "id": "billing-d1",
      "phase": "2. Remote Resources",
      "priority": "P0",
      "owner": "User + Codex",
      "status": "Waiting on Cloudflare API token",
      "label": "D1: nyra_billing",
      "action": "Create a scoped Cloudflare API token for the account that will host NyrA, set it as CLOUDFLARE_API_TOKEN in the local shell or automation secret store, then rerun npm run cloudflare:discover.",
      "command": "npx wrangler d1 create nyra_billing",
      "dashboardPage": "pages/cloud-billing.html",
      "dashboardField": "billingCloud.d1DatabaseId",
      "verificationCommand": "npm run cloudflare:discover",
      "noGoRule": "Do not deploy billing Worker production until this D1 database_id is concrete in wrangler.jsonc."
    },
    {
      "id": "command-center-r2",
      "phase": "2. Remote Resources",
      "priority": "P0",
      "owner": "User + Codex",
      "status": "Ready for config review",
      "label": "R2: nyra-command-center-uploads",
      "action": "Run discovery/config sync and verify the non-secret ID or URL is saved in the dashboard before deployment.",
      "command": "npx wrangler r2 bucket create nyra-command-center-uploads",
      "dashboardPage": "pages/cloud.html",
      "dashboardField": "cloudMigration.r2Bucket",
      "verificationCommand": "npm run cloudflare:discover",
      "noGoRule": "Keep the handoff upload bucket private; never enable public bucket access for private launch evidence."
    },
    {
      "id": "mobile-support-r2",
      "phase": "2. Remote Resources",
      "priority": "P0",
      "owner": "User + Codex",
      "status": "Ready for config review",
      "label": "R2: nyra-mobile-support-logs",
      "action": "Run discovery/config sync and verify the non-secret ID or URL is saved in the dashboard before deployment.",
      "command": "npx wrangler r2 bucket create nyra-mobile-support-logs",
      "dashboardPage": "pages/cloud-mobile-bridge.html",
      "dashboardField": "mobileBridge.r2BucketName",
      "verificationCommand": "npm run cloudflare:discover && npm run cloud:mobile-bridge:check",
      "noGoRule": "Keep mobile support diagnostics private; only redacted support-log readbacks may be exposed to support flows."
    },
    {
      "id": "mobile-android-r2",
      "phase": "2. Remote Resources",
      "priority": "P1",
      "owner": "User + Codex",
      "status": "Ready for config review",
      "label": "R2: nyra-android-releases",
      "action": "Run discovery/config sync and verify the non-secret ID or URL is saved in the dashboard before deployment.",
      "command": "npx wrangler r2 bucket create nyra-android-releases",
      "dashboardPage": "pages/cloud-mobile-bridge.html",
      "dashboardField": "mobileBridge.androidReleasesBucketName",
      "verificationCommand": "npm run cloudflare:discover && npm run cloud:mobile-bridge:check",
      "noGoRule": "Serve APK downloads through ticketed Worker routes, not public unauthenticated bucket URLs."
    },
    {
      "id": "pages-project",
      "phase": "2. Remote Resources",
      "priority": "P1",
      "owner": "User + Codex",
      "status": "Ready for config review",
      "label": "Pages: nyra-command-center-dashboard",
      "action": "Run discovery/config sync and verify the non-secret ID or URL is saved in the dashboard before deployment.",
      "command": "npx wrangler pages project create nyra-command-center-dashboard --production-branch main",
      "dashboardPage": "pages/cloud.html",
      "dashboardField": "cloudPages.projectName",
      "verificationCommand": "npm run cloudflare:discover",
      "noGoRule": "Protect the dashboard with Cloudflare Access or equivalent private access before storing real business records."
    },
    {
      "id": "command-center-worker",
      "phase": "2. Remote Resources",
      "priority": "P1",
      "owner": "Codex",
      "status": "Waiting on Cloudflare API token",
      "label": "Worker: nyra-command-center-api",
      "action": "Create a scoped Cloudflare API token for the account that will host NyrA, set it as CLOUDFLARE_API_TOKEN in the local shell or automation secret store, then rerun npm run cloudflare:discover.",
      "command": "npm run cloud:command-center:deploy",
      "dashboardPage": "pages/cloud.html",
      "dashboardField": "cloudSync.apiUrl",
      "verificationCommand": "npm run cloud:command-center:health",
      "noGoRule": "Do not deploy until command-center D1/R2, ALLOWED_ORIGIN, and NYRA_COMMAND_TOKEN are configured."
    },
    {
      "id": "billing-worker",
      "phase": "2. Remote Resources",
      "priority": "P1",
      "owner": "Codex",
      "status": "Waiting on Cloudflare API token",
      "label": "Worker: nyra-billing-api",
      "action": "Create a scoped Cloudflare API token for the account that will host NyrA, set it as CLOUDFLARE_API_TOKEN in the local shell or automation secret store, then rerun npm run cloudflare:discover.",
      "command": "npm run cloud:billing:deploy",
      "dashboardPage": "pages/cloud-billing.html",
      "dashboardField": "billingCloud.workerUrl",
      "verificationCommand": "npm run cloud:billing:check",
      "noGoRule": "Do not deploy live billing until Stripe test-mode rehearsal, secrets, Customer Portal, support, and policy gates pass."
    },
    {
      "id": "mobile-bridge-worker",
      "phase": "2. Remote Resources",
      "priority": "P1",
      "owner": "Codex",
      "status": "Waiting on Cloudflare API token",
      "label": "Worker: nyra-mobile-bridge-api",
      "action": "Create a scoped Cloudflare API token for the account that will host NyrA, set it as CLOUDFLARE_API_TOKEN in the local shell or automation secret store, then rerun npm run cloudflare:discover.",
      "command": "npm run cloud:mobile-bridge:bootstrap -- --worker-url=https://bridge.porterlabz.com --write-state",
      "dashboardPage": "pages/cloud-mobile-bridge.html",
      "dashboardField": "mobileBridge.workerUrl",
      "verificationCommand": "npm run cloud:mobile-bridge:check && npm run test:mobile-bridge-security",
      "noGoRule": "Do not rebuild Android paid-beta against this Worker until R2 APK hosting, provider secrets, device-token auth, and phone self-test evidence pass."
    },
    {
      "id": "sync-non-secret-config",
      "phase": "3. Config Sync",
      "priority": "P0",
      "owner": "Codex",
      "status": "Waiting on prior gates",
      "label": "sync non secret config",
      "action": "Apply saved non-secret dashboard values to production Worker configs and verify the mobile bridge bootstrap plan.",
      "command": "npm run cloud:command-center:config:sync && npm run cloud:billing:config:sync && npm run cloud:mobile-bridge:bootstrap -- --dry-run --skip-secrets --skip-deploy",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npm run cloud:command-center:config:sync && npm run cloud:billing:config:sync && npm run cloud:mobile-bridge:bootstrap -- --dry-run --skip-secrets --skip-deploy",
      "noGoRule": "This must not write Stripe secrets, bearer tokens, or Cloudflare tokens into repo files."
    },
    {
      "id": "command-token-secret",
      "phase": "4. Secrets",
      "priority": "P0",
      "owner": "User + Codex",
      "status": "Waiting on prior gates",
      "label": "command token secret",
      "action": "Set the private command-center API bearer token through Wrangler secrets only.",
      "command": "npx wrangler secret put NYRA_COMMAND_TOKEN --cwd cloud/command-center-worker --env production",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npx wrangler secret put NYRA_COMMAND_TOKEN --cwd cloud/command-center-worker --env production",
      "noGoRule": "Do not paste this token into dashboard fields, repo files, Markdown, CSV, screenshots, or chat."
    },
    {
      "id": "billing-secret-stripe-secret-key",
      "phase": "4. Secrets",
      "priority": "P0",
      "owner": "User + Codex",
      "status": "Waiting on prior gates",
      "label": "billing secret stripe secret key",
      "action": "Set STRIPE_SECRET_KEY for the billing Worker through Wrangler secrets only.",
      "command": "npx wrangler secret put STRIPE_SECRET_KEY --cwd cloud/billing-worker --env production",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npx wrangler secret put STRIPE_SECRET_KEY --cwd cloud/billing-worker --env production",
      "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
    },
    {
      "id": "billing-secret-stripe-webhook-secret",
      "phase": "4. Secrets",
      "priority": "P0",
      "owner": "User + Codex",
      "status": "Waiting on prior gates",
      "label": "billing secret stripe webhook secret",
      "action": "Set STRIPE_WEBHOOK_SECRET for the billing Worker through Wrangler secrets only.",
      "command": "npx wrangler secret put STRIPE_WEBHOOK_SECRET --cwd cloud/billing-worker --env production",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npx wrangler secret put STRIPE_WEBHOOK_SECRET --cwd cloud/billing-worker --env production",
      "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
    },
    {
      "id": "billing-secret-nyra-stripe-price-pro-monthly",
      "phase": "4. Secrets",
      "priority": "P0",
      "owner": "User + Codex",
      "status": "Waiting on prior gates",
      "label": "billing secret nyra stripe price pro monthly",
      "action": "Set NYRA_STRIPE_PRICE_PRO_MONTHLY for the billing Worker through Wrangler secrets only.",
      "command": "npx wrangler secret put NYRA_STRIPE_PRICE_PRO_MONTHLY --cwd cloud/billing-worker --env production",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npx wrangler secret put NYRA_STRIPE_PRICE_PRO_MONTHLY --cwd cloud/billing-worker --env production",
      "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
    },
    {
      "id": "billing-secret-nyra-billing-success-url",
      "phase": "4. Secrets",
      "priority": "P0",
      "owner": "User + Codex",
      "status": "Waiting on prior gates",
      "label": "billing secret nyra billing success url",
      "action": "Set NYRA_BILLING_SUCCESS_URL for the billing Worker through Wrangler secrets only.",
      "command": "npx wrangler secret put NYRA_BILLING_SUCCESS_URL --cwd cloud/billing-worker --env production",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npx wrangler secret put NYRA_BILLING_SUCCESS_URL --cwd cloud/billing-worker --env production",
      "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
    },
    {
      "id": "billing-secret-nyra-billing-cancel-url",
      "phase": "4. Secrets",
      "priority": "P1",
      "owner": "User + Codex",
      "status": "Waiting on prior gates",
      "label": "billing secret nyra billing cancel url",
      "action": "Set NYRA_BILLING_CANCEL_URL for the billing Worker through Wrangler secrets only.",
      "command": "npx wrangler secret put NYRA_BILLING_CANCEL_URL --cwd cloud/billing-worker --env production",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npx wrangler secret put NYRA_BILLING_CANCEL_URL --cwd cloud/billing-worker --env production",
      "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
    },
    {
      "id": "billing-secret-nyra-billing-return-url",
      "phase": "4. Secrets",
      "priority": "P1",
      "owner": "User + Codex",
      "status": "Waiting on prior gates",
      "label": "billing secret nyra billing return url",
      "action": "Set NYRA_BILLING_RETURN_URL for the billing Worker through Wrangler secrets only.",
      "command": "npx wrangler secret put NYRA_BILLING_RETURN_URL --cwd cloud/billing-worker --env production",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npx wrangler secret put NYRA_BILLING_RETURN_URL --cwd cloud/billing-worker --env production",
      "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
    },
    {
      "id": "billing-secret-nyra-license-api-token",
      "phase": "4. Secrets",
      "priority": "P1",
      "owner": "User + Codex",
      "status": "Waiting on prior gates",
      "label": "billing secret nyra license api token",
      "action": "Set NYRA_LICENSE_API_TOKEN for the billing Worker through Wrangler secrets only.",
      "command": "npx wrangler secret put NYRA_LICENSE_API_TOKEN --cwd cloud/billing-worker --env production",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npx wrangler secret put NYRA_LICENSE_API_TOKEN --cwd cloud/billing-worker --env production",
      "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
    },
    {
      "id": "billing-secret-nyra-license-signing-secret",
      "phase": "4. Secrets",
      "priority": "P1",
      "owner": "User + Codex",
      "status": "Waiting on prior gates",
      "label": "billing secret nyra license signing secret",
      "action": "Set NYRA_LICENSE_SIGNING_SECRET for the billing Worker through Wrangler secrets only.",
      "command": "npx wrangler secret put NYRA_LICENSE_SIGNING_SECRET --cwd cloud/billing-worker --env production",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npx wrangler secret put NYRA_LICENSE_SIGNING_SECRET --cwd cloud/billing-worker --env production",
      "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
    },
    {
      "id": "mobile-bridge-secret-nyra-mobile-bridge-token",
      "phase": "4. Secrets",
      "priority": "P1",
      "owner": "User + Codex",
      "status": "Waiting on prior gates",
      "label": "mobile bridge secret nyra mobile bridge token",
      "action": "Set NYRA_MOBILE_BRIDGE_TOKEN for the mobile bridge Worker through Wrangler secrets only.",
      "command": "npx wrangler secret put NYRA_MOBILE_BRIDGE_TOKEN --cwd cloud/mobile-bridge-worker --env production",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npx wrangler secret put NYRA_MOBILE_BRIDGE_TOKEN --cwd cloud/mobile-bridge-worker --env production",
      "noGoRule": "Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo."
    },
    {
      "id": "mobile-bridge-secret-nyra-openai-api-key",
      "phase": "4. Secrets",
      "priority": "P1",
      "owner": "User + Codex",
      "status": "Waiting on prior gates",
      "label": "mobile bridge secret nyra openai api key",
      "action": "Set NYRA_OPENAI_API_KEY for the mobile bridge Worker through Wrangler secrets only.",
      "command": "npx wrangler secret put NYRA_OPENAI_API_KEY --cwd cloud/mobile-bridge-worker --env production",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npx wrangler secret put NYRA_OPENAI_API_KEY --cwd cloud/mobile-bridge-worker --env production",
      "noGoRule": "Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo."
    },
    {
      "id": "mobile-bridge-secret-nyra-anthropic-api-key",
      "phase": "4. Secrets",
      "priority": "P1",
      "owner": "User + Codex",
      "status": "Waiting on prior gates",
      "label": "mobile bridge secret nyra anthropic api key",
      "action": "Set NYRA_ANTHROPIC_API_KEY for the mobile bridge Worker through Wrangler secrets only.",
      "command": "npx wrangler secret put NYRA_ANTHROPIC_API_KEY --cwd cloud/mobile-bridge-worker --env production",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npx wrangler secret put NYRA_ANTHROPIC_API_KEY --cwd cloud/mobile-bridge-worker --env production",
      "noGoRule": "Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo."
    },
    {
      "id": "mobile-bridge-secret-nyra-gemini-api-key",
      "phase": "4. Secrets",
      "priority": "P1",
      "owner": "User + Codex",
      "status": "Waiting on prior gates",
      "label": "mobile bridge secret nyra gemini api key",
      "action": "Set NYRA_GEMINI_API_KEY for the mobile bridge Worker through Wrangler secrets only.",
      "command": "npx wrangler secret put NYRA_GEMINI_API_KEY --cwd cloud/mobile-bridge-worker --env production",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npx wrangler secret put NYRA_GEMINI_API_KEY --cwd cloud/mobile-bridge-worker --env production",
      "noGoRule": "Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo."
    },
    {
      "id": "mobile-bridge-secret-nyra-grok-api-key",
      "phase": "4. Secrets",
      "priority": "P1",
      "owner": "User + Codex",
      "status": "Waiting on prior gates",
      "label": "mobile bridge secret nyra grok api key",
      "action": "Set NYRA_GROK_API_KEY for the mobile bridge Worker through Wrangler secrets only.",
      "command": "npx wrangler secret put NYRA_GROK_API_KEY --cwd cloud/mobile-bridge-worker --env production",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npx wrangler secret put NYRA_GROK_API_KEY --cwd cloud/mobile-bridge-worker --env production",
      "noGoRule": "Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo."
    },
    {
      "id": "mobile-bridge-secret-nyra-license-signing-secret",
      "phase": "4. Secrets",
      "priority": "P1",
      "owner": "User + Codex",
      "status": "Waiting on prior gates",
      "label": "mobile bridge secret nyra license signing secret",
      "action": "Set NYRA_LICENSE_SIGNING_SECRET for the mobile bridge Worker through Wrangler secrets only.",
      "command": "npx wrangler secret put NYRA_LICENSE_SIGNING_SECRET --cwd cloud/mobile-bridge-worker --env production",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npx wrangler secret put NYRA_LICENSE_SIGNING_SECRET --cwd cloud/mobile-bridge-worker --env production",
      "noGoRule": "Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo."
    },
    {
      "id": "mobile-bridge-secret-nyra-android-download-ticket-secret",
      "phase": "4. Secrets",
      "priority": "P1",
      "owner": "User + Codex",
      "status": "Waiting on prior gates",
      "label": "mobile bridge secret nyra android download ticket secret",
      "action": "Set NYRA_ANDROID_DOWNLOAD_TICKET_SECRET for the mobile bridge Worker through Wrangler secrets only.",
      "command": "npx wrangler secret put NYRA_ANDROID_DOWNLOAD_TICKET_SECRET --cwd cloud/mobile-bridge-worker --env production",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npx wrangler secret put NYRA_ANDROID_DOWNLOAD_TICKET_SECRET --cwd cloud/mobile-bridge-worker --env production",
      "noGoRule": "Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo."
    },
    {
      "id": "command-center-migrations",
      "phase": "5. Migrations",
      "priority": "P1",
      "owner": "User + Codex",
      "status": "Waiting on prior gates",
      "label": "command center migrations",
      "action": "Apply command-center D1 schema after the concrete database ID is configured.",
      "command": "npx wrangler d1 migrations apply nyra_command_center --cwd cloud/command-center-worker --env production",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npx wrangler d1 migrations apply nyra_command_center --cwd cloud/command-center-worker --env production",
      "noGoRule": "Do not apply migrations to the wrong Cloudflare account or placeholder database ID."
    },
    {
      "id": "billing-migrations",
      "phase": "5. Migrations",
      "priority": "P1",
      "owner": "User + Codex",
      "status": "Waiting on prior gates",
      "label": "billing migrations",
      "action": "Apply billing D1 schema after the concrete database ID is configured.",
      "command": "npx wrangler d1 migrations apply nyra_billing --cwd cloud/billing-worker --env production",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npx wrangler d1 migrations apply nyra_billing --cwd cloud/billing-worker --env production",
      "noGoRule": "Do not run live billing until Stripe test-mode and legal/support gates pass."
    },
    {
      "id": "deploy-command-center-worker",
      "phase": "6. Deploy",
      "priority": "P1",
      "owner": "Codex",
      "status": "Waiting on prior gates",
      "label": "deploy command center worker",
      "action": "Deploy the private command-center Worker API.",
      "command": "npm run cloud:command-center:deploy",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npm run cloud:command-center:deploy",
      "noGoRule": "Do not deploy with placeholder D1 ID or placeholder ALLOWED_ORIGIN."
    },
    {
      "id": "deploy-command-center-pages",
      "phase": "6. Deploy",
      "priority": "P1",
      "owner": "Codex",
      "status": "Waiting on prior gates",
      "label": "deploy command center pages",
      "action": "Deploy the command-center dashboard artifact to Cloudflare Pages.",
      "command": "npm run cloud:command-center:pages:deploy",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npm run cloud:command-center:pages:deploy",
      "noGoRule": "Protect dashboard access before storing real business records or user files."
    },
    {
      "id": "deploy-billing-worker",
      "phase": "6. Deploy",
      "priority": "P1",
      "owner": "Codex",
      "status": "Waiting on prior gates",
      "label": "deploy billing worker",
      "action": "Deploy the billing Worker after test-mode payment rehearsal inputs are complete.",
      "command": "npm run cloud:billing:deploy",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npm run cloud:billing:deploy",
      "noGoRule": "Do not expose live checkout while deployability preflight still reports P0 live-money blockers."
    },
    {
      "id": "deploy-mobile-bridge-worker",
      "phase": "6. Deploy",
      "priority": "P1",
      "owner": "Codex",
      "status": "Waiting on prior gates",
      "label": "deploy mobile bridge worker",
      "action": "Create/verify mobile bridge R2 buckets, upload the APK, deploy the Worker, and prove status/update/APK ticket/support-log/chat before saving state.",
      "command": "npm run cloud:mobile-bridge:bootstrap -- --worker-url=https://bridge.porterlabz.com --write-state",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npm run cloud:mobile-bridge:bootstrap -- --worker-url=https://bridge.porterlabz.com --write-state",
      "noGoRule": "Do not replace the Android bundled bridge URL for paid beta until this post-deploy smoke passes and the shared alpha token is removed."
    },
    {
      "id": "first-cloud-roundtrip",
      "phase": "7. First Sync",
      "priority": "P1",
      "owner": "Codex",
      "status": "Waiting on prior gates",
      "label": "first cloud roundtrip",
      "action": "Prove cloud command-center state can be pushed, scanned, safely ingested, and read back.",
      "command": "npm run cloud:command-center:health && npm run cloud:command-center:push && npm run cloud:command-center:scan && npm run cloud:command-center:ingest && npm run cloud:command-center:roundtrip",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npm run cloud:command-center:health && npm run cloud:command-center:push && npm run cloud:command-center:scan && npm run cloud:command-center:ingest && npm run cloud:command-center:roundtrip",
      "noGoRule": "Use only temporary shell env vars for NYRA_COMMAND_CENTER_API_URL and NYRA_COMMAND_CENTER_TOKEN."
    },
    {
      "id": "billing-live-preflight-test-mode",
      "phase": "7. First Sync",
      "priority": "P1",
      "owner": "Codex",
      "status": "Waiting on prior gates",
      "label": "billing live preflight test mode",
      "action": "Run a guarded test-mode billing go-live rehearsal after cloud URLs and secrets exist.",
      "command": "npm run billing:live-preflight -- --mode test --allow-blocked",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npm run billing:live-preflight -- --mode test --allow-blocked",
      "noGoRule": "Do not run live-mode billing rehearsal until user explicitly confirms live Stripe readiness."
    },
    {
      "id": "mobile-phone-self-test-after-deploy",
      "phase": "7. First Sync",
      "priority": "P1",
      "owner": "User + Codex",
      "status": "Waiting on prior gates",
      "label": "mobile phone self test after deploy",
      "action": "Ingest and verify a physical-phone self-test after the deployed bridge replaces the temporary tunnel.",
      "command": "npm run phone:self-test:ingest && npm run test:phone-self-test-ingest",
      "dashboardPage": "pages/cloud-bootstrap.html",
      "dashboardField": "",
      "verificationCommand": "npm run phone:self-test:ingest && npm run test:phone-self-test-ingest",
      "noGoRule": "Do not clear the physical-phone gate from web-surface evidence; it must come from the installed Android app."
    }
  ],
  "phases": [
    {
      "phase": "1. Authentication",
      "actions": [
        {
          "id": "cloudflare-api-token",
          "phase": "1. Authentication",
          "priority": "P0",
          "owner": "User",
          "status": "Waiting on user",
          "label": "Cloudflare API token required",
          "action": "Create a scoped Cloudflare API token for the account that will host NyrA, set it as CLOUDFLARE_API_TOKEN in the local shell or automation secret store, then rerun npm run cloudflare:discover.",
          "command": "npm run cloudflare:discover",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "cloudMigration.accountReady",
          "verificationCommand": "npm run cloudflare:discover",
          "noGoRule": "Never store Cloudflare tokens, API keys, recovery codes, or password material in repo files or dashboard state."
        },
        {
          "id": "wrangler-login-fallback",
          "phase": "1. Authentication",
          "priority": "P1",
          "owner": "User",
          "status": "Optional fallback",
          "label": "Wrangler login",
          "action": "If you are sitting at the Windows desktop and prefer browser auth, run npx wrangler login and approve the Cloudflare account that will host NyrA. Automation still needs CLOUDFLARE_API_TOKEN.",
          "command": "npx wrangler login",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "cloudMigration.accountReady",
          "verificationCommand": "npm run cloudflare:discover",
          "noGoRule": "Never store Cloudflare tokens, API keys, recovery codes, or password material in repo files or dashboard state."
        }
      ]
    },
    {
      "phase": "2. Remote Resources",
      "actions": [
        {
          "id": "command-center-d1",
          "phase": "2. Remote Resources",
          "priority": "P0",
          "owner": "User + Codex",
          "status": "Waiting on Cloudflare API token",
          "label": "D1: nyra_command_center",
          "action": "Create a scoped Cloudflare API token for the account that will host NyrA, set it as CLOUDFLARE_API_TOKEN in the local shell or automation secret store, then rerun npm run cloudflare:discover.",
          "command": "npx wrangler d1 create nyra_command_center",
          "dashboardPage": "pages/cloud.html",
          "dashboardField": "cloudMigration.d1DatabaseId",
          "verificationCommand": "npm run cloudflare:discover",
          "noGoRule": "Do not deploy command-center Worker production until this D1 database_id is concrete in wrangler.jsonc."
        },
        {
          "id": "billing-d1",
          "phase": "2. Remote Resources",
          "priority": "P0",
          "owner": "User + Codex",
          "status": "Waiting on Cloudflare API token",
          "label": "D1: nyra_billing",
          "action": "Create a scoped Cloudflare API token for the account that will host NyrA, set it as CLOUDFLARE_API_TOKEN in the local shell or automation secret store, then rerun npm run cloudflare:discover.",
          "command": "npx wrangler d1 create nyra_billing",
          "dashboardPage": "pages/cloud-billing.html",
          "dashboardField": "billingCloud.d1DatabaseId",
          "verificationCommand": "npm run cloudflare:discover",
          "noGoRule": "Do not deploy billing Worker production until this D1 database_id is concrete in wrangler.jsonc."
        },
        {
          "id": "command-center-r2",
          "phase": "2. Remote Resources",
          "priority": "P0",
          "owner": "User + Codex",
          "status": "Ready for config review",
          "label": "R2: nyra-command-center-uploads",
          "action": "Run discovery/config sync and verify the non-secret ID or URL is saved in the dashboard before deployment.",
          "command": "npx wrangler r2 bucket create nyra-command-center-uploads",
          "dashboardPage": "pages/cloud.html",
          "dashboardField": "cloudMigration.r2Bucket",
          "verificationCommand": "npm run cloudflare:discover",
          "noGoRule": "Keep the handoff upload bucket private; never enable public bucket access for private launch evidence."
        },
        {
          "id": "mobile-support-r2",
          "phase": "2. Remote Resources",
          "priority": "P0",
          "owner": "User + Codex",
          "status": "Ready for config review",
          "label": "R2: nyra-mobile-support-logs",
          "action": "Run discovery/config sync and verify the non-secret ID or URL is saved in the dashboard before deployment.",
          "command": "npx wrangler r2 bucket create nyra-mobile-support-logs",
          "dashboardPage": "pages/cloud-mobile-bridge.html",
          "dashboardField": "mobileBridge.r2BucketName",
          "verificationCommand": "npm run cloudflare:discover && npm run cloud:mobile-bridge:check",
          "noGoRule": "Keep mobile support diagnostics private; only redacted support-log readbacks may be exposed to support flows."
        },
        {
          "id": "mobile-android-r2",
          "phase": "2. Remote Resources",
          "priority": "P1",
          "owner": "User + Codex",
          "status": "Ready for config review",
          "label": "R2: nyra-android-releases",
          "action": "Run discovery/config sync and verify the non-secret ID or URL is saved in the dashboard before deployment.",
          "command": "npx wrangler r2 bucket create nyra-android-releases",
          "dashboardPage": "pages/cloud-mobile-bridge.html",
          "dashboardField": "mobileBridge.androidReleasesBucketName",
          "verificationCommand": "npm run cloudflare:discover && npm run cloud:mobile-bridge:check",
          "noGoRule": "Serve APK downloads through ticketed Worker routes, not public unauthenticated bucket URLs."
        },
        {
          "id": "pages-project",
          "phase": "2. Remote Resources",
          "priority": "P1",
          "owner": "User + Codex",
          "status": "Ready for config review",
          "label": "Pages: nyra-command-center-dashboard",
          "action": "Run discovery/config sync and verify the non-secret ID or URL is saved in the dashboard before deployment.",
          "command": "npx wrangler pages project create nyra-command-center-dashboard --production-branch main",
          "dashboardPage": "pages/cloud.html",
          "dashboardField": "cloudPages.projectName",
          "verificationCommand": "npm run cloudflare:discover",
          "noGoRule": "Protect the dashboard with Cloudflare Access or equivalent private access before storing real business records."
        },
        {
          "id": "command-center-worker",
          "phase": "2. Remote Resources",
          "priority": "P1",
          "owner": "Codex",
          "status": "Waiting on Cloudflare API token",
          "label": "Worker: nyra-command-center-api",
          "action": "Create a scoped Cloudflare API token for the account that will host NyrA, set it as CLOUDFLARE_API_TOKEN in the local shell or automation secret store, then rerun npm run cloudflare:discover.",
          "command": "npm run cloud:command-center:deploy",
          "dashboardPage": "pages/cloud.html",
          "dashboardField": "cloudSync.apiUrl",
          "verificationCommand": "npm run cloud:command-center:health",
          "noGoRule": "Do not deploy until command-center D1/R2, ALLOWED_ORIGIN, and NYRA_COMMAND_TOKEN are configured."
        },
        {
          "id": "billing-worker",
          "phase": "2. Remote Resources",
          "priority": "P1",
          "owner": "Codex",
          "status": "Waiting on Cloudflare API token",
          "label": "Worker: nyra-billing-api",
          "action": "Create a scoped Cloudflare API token for the account that will host NyrA, set it as CLOUDFLARE_API_TOKEN in the local shell or automation secret store, then rerun npm run cloudflare:discover.",
          "command": "npm run cloud:billing:deploy",
          "dashboardPage": "pages/cloud-billing.html",
          "dashboardField": "billingCloud.workerUrl",
          "verificationCommand": "npm run cloud:billing:check",
          "noGoRule": "Do not deploy live billing until Stripe test-mode rehearsal, secrets, Customer Portal, support, and policy gates pass."
        },
        {
          "id": "mobile-bridge-worker",
          "phase": "2. Remote Resources",
          "priority": "P1",
          "owner": "Codex",
          "status": "Waiting on Cloudflare API token",
          "label": "Worker: nyra-mobile-bridge-api",
          "action": "Create a scoped Cloudflare API token for the account that will host NyrA, set it as CLOUDFLARE_API_TOKEN in the local shell or automation secret store, then rerun npm run cloudflare:discover.",
          "command": "npm run cloud:mobile-bridge:bootstrap -- --worker-url=https://bridge.porterlabz.com --write-state",
          "dashboardPage": "pages/cloud-mobile-bridge.html",
          "dashboardField": "mobileBridge.workerUrl",
          "verificationCommand": "npm run cloud:mobile-bridge:check && npm run test:mobile-bridge-security",
          "noGoRule": "Do not rebuild Android paid-beta against this Worker until R2 APK hosting, provider secrets, device-token auth, and phone self-test evidence pass."
        }
      ]
    },
    {
      "phase": "3. Config Sync",
      "actions": [
        {
          "id": "sync-non-secret-config",
          "phase": "3. Config Sync",
          "priority": "P0",
          "owner": "Codex",
          "status": "Waiting on prior gates",
          "label": "sync non secret config",
          "action": "Apply saved non-secret dashboard values to production Worker configs and verify the mobile bridge bootstrap plan.",
          "command": "npm run cloud:command-center:config:sync && npm run cloud:billing:config:sync && npm run cloud:mobile-bridge:bootstrap -- --dry-run --skip-secrets --skip-deploy",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npm run cloud:command-center:config:sync && npm run cloud:billing:config:sync && npm run cloud:mobile-bridge:bootstrap -- --dry-run --skip-secrets --skip-deploy",
          "noGoRule": "This must not write Stripe secrets, bearer tokens, or Cloudflare tokens into repo files."
        }
      ]
    },
    {
      "phase": "4. Secrets",
      "actions": [
        {
          "id": "command-token-secret",
          "phase": "4. Secrets",
          "priority": "P0",
          "owner": "User + Codex",
          "status": "Waiting on prior gates",
          "label": "command token secret",
          "action": "Set the private command-center API bearer token through Wrangler secrets only.",
          "command": "npx wrangler secret put NYRA_COMMAND_TOKEN --cwd cloud/command-center-worker --env production",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npx wrangler secret put NYRA_COMMAND_TOKEN --cwd cloud/command-center-worker --env production",
          "noGoRule": "Do not paste this token into dashboard fields, repo files, Markdown, CSV, screenshots, or chat."
        },
        {
          "id": "billing-secret-stripe-secret-key",
          "phase": "4. Secrets",
          "priority": "P0",
          "owner": "User + Codex",
          "status": "Waiting on prior gates",
          "label": "billing secret stripe secret key",
          "action": "Set STRIPE_SECRET_KEY for the billing Worker through Wrangler secrets only.",
          "command": "npx wrangler secret put STRIPE_SECRET_KEY --cwd cloud/billing-worker --env production",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npx wrangler secret put STRIPE_SECRET_KEY --cwd cloud/billing-worker --env production",
          "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
        },
        {
          "id": "billing-secret-stripe-webhook-secret",
          "phase": "4. Secrets",
          "priority": "P0",
          "owner": "User + Codex",
          "status": "Waiting on prior gates",
          "label": "billing secret stripe webhook secret",
          "action": "Set STRIPE_WEBHOOK_SECRET for the billing Worker through Wrangler secrets only.",
          "command": "npx wrangler secret put STRIPE_WEBHOOK_SECRET --cwd cloud/billing-worker --env production",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npx wrangler secret put STRIPE_WEBHOOK_SECRET --cwd cloud/billing-worker --env production",
          "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
        },
        {
          "id": "billing-secret-nyra-stripe-price-pro-monthly",
          "phase": "4. Secrets",
          "priority": "P0",
          "owner": "User + Codex",
          "status": "Waiting on prior gates",
          "label": "billing secret nyra stripe price pro monthly",
          "action": "Set NYRA_STRIPE_PRICE_PRO_MONTHLY for the billing Worker through Wrangler secrets only.",
          "command": "npx wrangler secret put NYRA_STRIPE_PRICE_PRO_MONTHLY --cwd cloud/billing-worker --env production",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npx wrangler secret put NYRA_STRIPE_PRICE_PRO_MONTHLY --cwd cloud/billing-worker --env production",
          "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
        },
        {
          "id": "billing-secret-nyra-billing-success-url",
          "phase": "4. Secrets",
          "priority": "P0",
          "owner": "User + Codex",
          "status": "Waiting on prior gates",
          "label": "billing secret nyra billing success url",
          "action": "Set NYRA_BILLING_SUCCESS_URL for the billing Worker through Wrangler secrets only.",
          "command": "npx wrangler secret put NYRA_BILLING_SUCCESS_URL --cwd cloud/billing-worker --env production",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npx wrangler secret put NYRA_BILLING_SUCCESS_URL --cwd cloud/billing-worker --env production",
          "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
        },
        {
          "id": "billing-secret-nyra-billing-cancel-url",
          "phase": "4. Secrets",
          "priority": "P1",
          "owner": "User + Codex",
          "status": "Waiting on prior gates",
          "label": "billing secret nyra billing cancel url",
          "action": "Set NYRA_BILLING_CANCEL_URL for the billing Worker through Wrangler secrets only.",
          "command": "npx wrangler secret put NYRA_BILLING_CANCEL_URL --cwd cloud/billing-worker --env production",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npx wrangler secret put NYRA_BILLING_CANCEL_URL --cwd cloud/billing-worker --env production",
          "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
        },
        {
          "id": "billing-secret-nyra-billing-return-url",
          "phase": "4. Secrets",
          "priority": "P1",
          "owner": "User + Codex",
          "status": "Waiting on prior gates",
          "label": "billing secret nyra billing return url",
          "action": "Set NYRA_BILLING_RETURN_URL for the billing Worker through Wrangler secrets only.",
          "command": "npx wrangler secret put NYRA_BILLING_RETURN_URL --cwd cloud/billing-worker --env production",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npx wrangler secret put NYRA_BILLING_RETURN_URL --cwd cloud/billing-worker --env production",
          "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
        },
        {
          "id": "billing-secret-nyra-license-api-token",
          "phase": "4. Secrets",
          "priority": "P1",
          "owner": "User + Codex",
          "status": "Waiting on prior gates",
          "label": "billing secret nyra license api token",
          "action": "Set NYRA_LICENSE_API_TOKEN for the billing Worker through Wrangler secrets only.",
          "command": "npx wrangler secret put NYRA_LICENSE_API_TOKEN --cwd cloud/billing-worker --env production",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npx wrangler secret put NYRA_LICENSE_API_TOKEN --cwd cloud/billing-worker --env production",
          "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
        },
        {
          "id": "billing-secret-nyra-license-signing-secret",
          "phase": "4. Secrets",
          "priority": "P1",
          "owner": "User + Codex",
          "status": "Waiting on prior gates",
          "label": "billing secret nyra license signing secret",
          "action": "Set NYRA_LICENSE_SIGNING_SECRET for the billing Worker through Wrangler secrets only.",
          "command": "npx wrangler secret put NYRA_LICENSE_SIGNING_SECRET --cwd cloud/billing-worker --env production",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npx wrangler secret put NYRA_LICENSE_SIGNING_SECRET --cwd cloud/billing-worker --env production",
          "noGoRule": "Do not paste Stripe, license, or webhook secret values into the dashboard or repo."
        },
        {
          "id": "mobile-bridge-secret-nyra-mobile-bridge-token",
          "phase": "4. Secrets",
          "priority": "P1",
          "owner": "User + Codex",
          "status": "Waiting on prior gates",
          "label": "mobile bridge secret nyra mobile bridge token",
          "action": "Set NYRA_MOBILE_BRIDGE_TOKEN for the mobile bridge Worker through Wrangler secrets only.",
          "command": "npx wrangler secret put NYRA_MOBILE_BRIDGE_TOKEN --cwd cloud/mobile-bridge-worker --env production",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npx wrangler secret put NYRA_MOBILE_BRIDGE_TOKEN --cwd cloud/mobile-bridge-worker --env production",
          "noGoRule": "Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo."
        },
        {
          "id": "mobile-bridge-secret-nyra-openai-api-key",
          "phase": "4. Secrets",
          "priority": "P1",
          "owner": "User + Codex",
          "status": "Waiting on prior gates",
          "label": "mobile bridge secret nyra openai api key",
          "action": "Set NYRA_OPENAI_API_KEY for the mobile bridge Worker through Wrangler secrets only.",
          "command": "npx wrangler secret put NYRA_OPENAI_API_KEY --cwd cloud/mobile-bridge-worker --env production",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npx wrangler secret put NYRA_OPENAI_API_KEY --cwd cloud/mobile-bridge-worker --env production",
          "noGoRule": "Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo."
        },
        {
          "id": "mobile-bridge-secret-nyra-anthropic-api-key",
          "phase": "4. Secrets",
          "priority": "P1",
          "owner": "User + Codex",
          "status": "Waiting on prior gates",
          "label": "mobile bridge secret nyra anthropic api key",
          "action": "Set NYRA_ANTHROPIC_API_KEY for the mobile bridge Worker through Wrangler secrets only.",
          "command": "npx wrangler secret put NYRA_ANTHROPIC_API_KEY --cwd cloud/mobile-bridge-worker --env production",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npx wrangler secret put NYRA_ANTHROPIC_API_KEY --cwd cloud/mobile-bridge-worker --env production",
          "noGoRule": "Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo."
        },
        {
          "id": "mobile-bridge-secret-nyra-gemini-api-key",
          "phase": "4. Secrets",
          "priority": "P1",
          "owner": "User + Codex",
          "status": "Waiting on prior gates",
          "label": "mobile bridge secret nyra gemini api key",
          "action": "Set NYRA_GEMINI_API_KEY for the mobile bridge Worker through Wrangler secrets only.",
          "command": "npx wrangler secret put NYRA_GEMINI_API_KEY --cwd cloud/mobile-bridge-worker --env production",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npx wrangler secret put NYRA_GEMINI_API_KEY --cwd cloud/mobile-bridge-worker --env production",
          "noGoRule": "Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo."
        },
        {
          "id": "mobile-bridge-secret-nyra-grok-api-key",
          "phase": "4. Secrets",
          "priority": "P1",
          "owner": "User + Codex",
          "status": "Waiting on prior gates",
          "label": "mobile bridge secret nyra grok api key",
          "action": "Set NYRA_GROK_API_KEY for the mobile bridge Worker through Wrangler secrets only.",
          "command": "npx wrangler secret put NYRA_GROK_API_KEY --cwd cloud/mobile-bridge-worker --env production",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npx wrangler secret put NYRA_GROK_API_KEY --cwd cloud/mobile-bridge-worker --env production",
          "noGoRule": "Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo."
        },
        {
          "id": "mobile-bridge-secret-nyra-license-signing-secret",
          "phase": "4. Secrets",
          "priority": "P1",
          "owner": "User + Codex",
          "status": "Waiting on prior gates",
          "label": "mobile bridge secret nyra license signing secret",
          "action": "Set NYRA_LICENSE_SIGNING_SECRET for the mobile bridge Worker through Wrangler secrets only.",
          "command": "npx wrangler secret put NYRA_LICENSE_SIGNING_SECRET --cwd cloud/mobile-bridge-worker --env production",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npx wrangler secret put NYRA_LICENSE_SIGNING_SECRET --cwd cloud/mobile-bridge-worker --env production",
          "noGoRule": "Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo."
        },
        {
          "id": "mobile-bridge-secret-nyra-android-download-ticket-secret",
          "phase": "4. Secrets",
          "priority": "P1",
          "owner": "User + Codex",
          "status": "Waiting on prior gates",
          "label": "mobile bridge secret nyra android download ticket secret",
          "action": "Set NYRA_ANDROID_DOWNLOAD_TICKET_SECRET for the mobile bridge Worker through Wrangler secrets only.",
          "command": "npx wrangler secret put NYRA_ANDROID_DOWNLOAD_TICKET_SECRET --cwd cloud/mobile-bridge-worker --env production",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npx wrangler secret put NYRA_ANDROID_DOWNLOAD_TICKET_SECRET --cwd cloud/mobile-bridge-worker --env production",
          "noGoRule": "Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo."
        }
      ]
    },
    {
      "phase": "5. Migrations",
      "actions": [
        {
          "id": "command-center-migrations",
          "phase": "5. Migrations",
          "priority": "P1",
          "owner": "User + Codex",
          "status": "Waiting on prior gates",
          "label": "command center migrations",
          "action": "Apply command-center D1 schema after the concrete database ID is configured.",
          "command": "npx wrangler d1 migrations apply nyra_command_center --cwd cloud/command-center-worker --env production",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npx wrangler d1 migrations apply nyra_command_center --cwd cloud/command-center-worker --env production",
          "noGoRule": "Do not apply migrations to the wrong Cloudflare account or placeholder database ID."
        },
        {
          "id": "billing-migrations",
          "phase": "5. Migrations",
          "priority": "P1",
          "owner": "User + Codex",
          "status": "Waiting on prior gates",
          "label": "billing migrations",
          "action": "Apply billing D1 schema after the concrete database ID is configured.",
          "command": "npx wrangler d1 migrations apply nyra_billing --cwd cloud/billing-worker --env production",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npx wrangler d1 migrations apply nyra_billing --cwd cloud/billing-worker --env production",
          "noGoRule": "Do not run live billing until Stripe test-mode and legal/support gates pass."
        }
      ]
    },
    {
      "phase": "6. Deploy",
      "actions": [
        {
          "id": "deploy-command-center-worker",
          "phase": "6. Deploy",
          "priority": "P1",
          "owner": "Codex",
          "status": "Waiting on prior gates",
          "label": "deploy command center worker",
          "action": "Deploy the private command-center Worker API.",
          "command": "npm run cloud:command-center:deploy",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npm run cloud:command-center:deploy",
          "noGoRule": "Do not deploy with placeholder D1 ID or placeholder ALLOWED_ORIGIN."
        },
        {
          "id": "deploy-command-center-pages",
          "phase": "6. Deploy",
          "priority": "P1",
          "owner": "Codex",
          "status": "Waiting on prior gates",
          "label": "deploy command center pages",
          "action": "Deploy the command-center dashboard artifact to Cloudflare Pages.",
          "command": "npm run cloud:command-center:pages:deploy",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npm run cloud:command-center:pages:deploy",
          "noGoRule": "Protect dashboard access before storing real business records or user files."
        },
        {
          "id": "deploy-billing-worker",
          "phase": "6. Deploy",
          "priority": "P1",
          "owner": "Codex",
          "status": "Waiting on prior gates",
          "label": "deploy billing worker",
          "action": "Deploy the billing Worker after test-mode payment rehearsal inputs are complete.",
          "command": "npm run cloud:billing:deploy",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npm run cloud:billing:deploy",
          "noGoRule": "Do not expose live checkout while deployability preflight still reports P0 live-money blockers."
        },
        {
          "id": "deploy-mobile-bridge-worker",
          "phase": "6. Deploy",
          "priority": "P1",
          "owner": "Codex",
          "status": "Waiting on prior gates",
          "label": "deploy mobile bridge worker",
          "action": "Create/verify mobile bridge R2 buckets, upload the APK, deploy the Worker, and prove status/update/APK ticket/support-log/chat before saving state.",
          "command": "npm run cloud:mobile-bridge:bootstrap -- --worker-url=https://bridge.porterlabz.com --write-state",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npm run cloud:mobile-bridge:bootstrap -- --worker-url=https://bridge.porterlabz.com --write-state",
          "noGoRule": "Do not replace the Android bundled bridge URL for paid beta until this post-deploy smoke passes and the shared alpha token is removed."
        }
      ]
    },
    {
      "phase": "7. First Sync",
      "actions": [
        {
          "id": "first-cloud-roundtrip",
          "phase": "7. First Sync",
          "priority": "P1",
          "owner": "Codex",
          "status": "Waiting on prior gates",
          "label": "first cloud roundtrip",
          "action": "Prove cloud command-center state can be pushed, scanned, safely ingested, and read back.",
          "command": "npm run cloud:command-center:health && npm run cloud:command-center:push && npm run cloud:command-center:scan && npm run cloud:command-center:ingest && npm run cloud:command-center:roundtrip",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npm run cloud:command-center:health && npm run cloud:command-center:push && npm run cloud:command-center:scan && npm run cloud:command-center:ingest && npm run cloud:command-center:roundtrip",
          "noGoRule": "Use only temporary shell env vars for NYRA_COMMAND_CENTER_API_URL and NYRA_COMMAND_CENTER_TOKEN."
        },
        {
          "id": "billing-live-preflight-test-mode",
          "phase": "7. First Sync",
          "priority": "P1",
          "owner": "Codex",
          "status": "Waiting on prior gates",
          "label": "billing live preflight test mode",
          "action": "Run a guarded test-mode billing go-live rehearsal after cloud URLs and secrets exist.",
          "command": "npm run billing:live-preflight -- --mode test --allow-blocked",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npm run billing:live-preflight -- --mode test --allow-blocked",
          "noGoRule": "Do not run live-mode billing rehearsal until user explicitly confirms live Stripe readiness."
        },
        {
          "id": "mobile-phone-self-test-after-deploy",
          "phase": "7. First Sync",
          "priority": "P1",
          "owner": "User + Codex",
          "status": "Waiting on prior gates",
          "label": "mobile phone self test after deploy",
          "action": "Ingest and verify a physical-phone self-test after the deployed bridge replaces the temporary tunnel.",
          "command": "npm run phone:self-test:ingest && npm run test:phone-self-test-ingest",
          "dashboardPage": "pages/cloud-bootstrap.html",
          "dashboardField": "",
          "verificationCommand": "npm run phone:self-test:ingest && npm run test:phone-self-test-ingest",
          "noGoRule": "Do not clear the physical-phone gate from web-surface evidence; it must come from the installed Android app."
        }
      ]
    }
  ],
  "counts": {
    "resources": 9,
    "waitingResources": 5,
    "readyResources": 4,
    "commandSteps": 36,
    "secretCommands": 16,
    "totalActions": 37,
    "p0Actions": 11
  },
  "applyPolicy": {
    "defaultMode": "plan-only",
    "userApprovalRequired": true,
    "automationCredential": "CLOUDFLARE_API_TOKEN",
    "allowedWithoutApproval": [
      "npm run cloud:command-center:check",
      "npm run cloud:billing:check",
      "npm run cloud:command-center:pages:check",
      "npm run cloudflare:discover"
    ],
    "remoteCreationRequiresApproval": [
      "wrangler d1 create",
      "wrangler r2 bucket create",
      "wrangler pages project create",
      "wrangler secret put",
      "wrangler deploy",
      "wrangler pages deploy",
      "wrangler d1 migrations apply --env production"
    ]
  },
  "officialReferences": [
    {
      "label": "Cloudflare Wrangler Pages commands",
      "url": "https://developers.cloudflare.com/workers/wrangler/commands/pages/",
      "usage": "Pages project create and direct upload deploy commands."
    },
    {
      "label": "Cloudflare D1 Wrangler commands",
      "url": "https://developers.cloudflare.com/d1/wrangler-commands/",
      "usage": "D1 create and migrations apply commands."
    },
    {
      "label": "Cloudflare R2 Wrangler commands",
      "url": "https://developers.cloudflare.com/r2/reference/wrangler-commands/",
      "usage": "R2 bucket create/list commands."
    }
  ],
  "outputs": {
    "json": "docs/launch_command_center/cloud-bootstrap-pack.json",
    "csv": "docs/launch_command_center/cloud-bootstrap-pack.csv",
    "report": "docs/launch_command_center/CLOUD_BOOTSTRAP_PACK.md",
    "dashboard": "docs/launch_command_center/pages/cloud-bootstrap.html"
  }
}
