Cloud Migration

Cloud Bootstrap

Plan-only Cloudflare setup sequence for command-center D1/R2/Pages/Worker, billing D1/Worker, secrets, migrations, deployment, and first cloud sync.

Bootstrap Controls

Open bootstrap CSV

Run npm run cloudflare:discover, then npm run cloud:bootstrap:pack. Remote resource creation stays gated on explicit user-approved execution.

Bootstrap status Cloud Bootstrap Waiting On API Token Ready
Resources 9 Ready
Waiting resources 5 Ready
Command steps 36 Ready
Secret commands 16 Ready
Discovery Cloudflare Discovery Needs API Token Ready

Resource Plan

TypeNameStatusOwnerCreate/Deploy CommandPageFieldNo-Go Rule
D1 nyra_command_center Waiting on Cloudflare API token User + Codex npx wrangler d1 create nyra_command_center pages/cloud.html cloudMigration.d1DatabaseId Do not deploy command-center Worker production until this D1 database_id is concrete in wrangler.jsonc.
D1 nyra_billing Waiting on Cloudflare API token User + Codex npx wrangler d1 create nyra_billing pages/cloud-billing.html billingCloud.d1DatabaseId Do not deploy billing Worker production until this D1 database_id is concrete in wrangler.jsonc.
R2 nyra-command-center-uploads Ready for config review User + Codex npx wrangler r2 bucket create nyra-command-center-uploads pages/cloud.html cloudMigration.r2Bucket Keep the handoff upload bucket private; never enable public bucket access for private launch evidence.
R2 nyra-mobile-support-logs Ready for config review User + Codex npx wrangler r2 bucket create nyra-mobile-support-logs pages/cloud-mobile-bridge.html mobileBridge.r2BucketName Keep mobile support diagnostics private; only redacted support-log readbacks may be exposed to support flows.
R2 nyra-android-releases Ready for config review User + Codex npx wrangler r2 bucket create nyra-android-releases pages/cloud-mobile-bridge.html mobileBridge.androidReleasesBucketName Serve APK downloads through ticketed Worker routes, not public unauthenticated bucket URLs.
Pages nyra-command-center-dashboard Ready for config review User + Codex npx wrangler pages project create nyra-command-center-dashboard --production-branch main pages/cloud.html cloudPages.projectName Protect the dashboard with Cloudflare Access or equivalent private access before storing real business records.
Worker nyra-command-center-api Waiting on Cloudflare API token Codex npm run cloud:command-center:deploy pages/cloud.html cloudSync.apiUrl Do not deploy until command-center D1/R2, ALLOWED_ORIGIN, and NYRA_COMMAND_TOKEN are configured.
Worker nyra-billing-api Waiting on Cloudflare API token Codex npm run cloud:billing:deploy pages/cloud-billing.html billingCloud.workerUrl Do not deploy live billing until Stripe test-mode rehearsal, secrets, Customer Portal, support, and policy gates pass.
Worker nyra-mobile-bridge-api Waiting on Cloudflare API token Codex npm run cloud:mobile-bridge:bootstrap -- --worker-url=https://bridge.porterlabz.com --write-state pages/cloud-mobile-bridge.html mobileBridge.workerUrl Do not rebuild Android paid-beta against this Worker until R2 APK hosting, provider secrets, device-token auth, and phone self-test evidence pass.

Safe Command Sequence

PhaseOwnerCommandPurposeNo-Go Rule
0. Local Validation Codex npm run cloud:command-center:check && npm run cloud:billing:check && npm run cloud:mobile-bridge:check && npm run cloud:command-center:pages:check Verify local command-center Worker, billing Worker, mobile bridge Worker, and the Pages artifact before touching Cloudflare. Do not run remote creation/deploy commands while local cloud checks fail.
1. Authentication User npm run cloudflare:discover Set CLOUDFLARE_API_TOKEN in the local shell or automation secret store, then rerun discovery so daily agents can continue without an interactive browser. Never paste Cloudflare API tokens into repo files, dashboard fields, Markdown, CSV, screenshots, or chat.
1. Authentication User npx wrangler login Optional interactive browser fallback for the Windows desktop; automation still needs CLOUDFLARE_API_TOKEN. Never paste Cloudflare API tokens or recovery codes into repo files, dashboard fields, screenshots, or chat.
1. Authentication Codex npm run cloudflare:discover Discover existing NyrA Cloudflare resources and avoid duplicate creation. Discovery must remain non-destructive and redacted.
2. Remote Resources User + Codex npx wrangler d1 create nyra_command_center Create D1 resource nyra_command_center. Do not deploy command-center Worker production until this D1 database_id is concrete in wrangler.jsonc.
2. Remote Resources User + Codex npx wrangler d1 create nyra_billing Create D1 resource nyra_billing. Do not deploy billing Worker production until this D1 database_id is concrete in wrangler.jsonc.
2. Remote Resources User + Codex npx wrangler r2 bucket create nyra-command-center-uploads Create R2 resource nyra-command-center-uploads. Keep the handoff upload bucket private; never enable public bucket access for private launch evidence.
2. Remote Resources User + Codex npx wrangler r2 bucket create nyra-mobile-support-logs Create R2 resource nyra-mobile-support-logs. Keep mobile support diagnostics private; only redacted support-log readbacks may be exposed to support flows.
2. Remote Resources User + Codex npx wrangler r2 bucket create nyra-android-releases Create R2 resource nyra-android-releases. Serve APK downloads through ticketed Worker routes, not public unauthenticated bucket URLs.
2. Remote Resources User + Codex npx wrangler pages project create nyra-command-center-dashboard --production-branch main Create Pages resource nyra-command-center-dashboard. Protect the dashboard with Cloudflare Access or equivalent private access before storing real business records.
3. Config Sync Codex 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 Apply saved non-secret dashboard values to production Worker configs and verify the mobile bridge bootstrap plan. This must not write Stripe secrets, bearer tokens, or Cloudflare tokens into repo files.
4. Secrets User + Codex npx wrangler secret put NYRA_COMMAND_TOKEN --cwd cloud/command-center-worker --env production Set the private command-center API bearer token through Wrangler secrets only. Do not paste this token into dashboard fields, repo files, Markdown, CSV, screenshots, or chat.
4. Secrets User + Codex npx wrangler secret put STRIPE_SECRET_KEY --cwd cloud/billing-worker --env production Set STRIPE_SECRET_KEY for the billing Worker through Wrangler secrets only. Do not paste Stripe, license, or webhook secret values into the dashboard or repo.
4. Secrets User + Codex npx wrangler secret put STRIPE_WEBHOOK_SECRET --cwd cloud/billing-worker --env production Set STRIPE_WEBHOOK_SECRET for the billing Worker through Wrangler secrets only. Do not paste Stripe, license, or webhook secret values into the dashboard or repo.
4. Secrets User + Codex npx wrangler secret put NYRA_STRIPE_PRICE_PRO_MONTHLY --cwd cloud/billing-worker --env production Set NYRA_STRIPE_PRICE_PRO_MONTHLY for the billing Worker through Wrangler secrets only. Do not paste Stripe, license, or webhook secret values into the dashboard or repo.
4. Secrets User + Codex npx wrangler secret put NYRA_BILLING_SUCCESS_URL --cwd cloud/billing-worker --env production Set NYRA_BILLING_SUCCESS_URL for the billing Worker through Wrangler secrets only. Do not paste Stripe, license, or webhook secret values into the dashboard or repo.
4. Secrets User + Codex npx wrangler secret put NYRA_BILLING_CANCEL_URL --cwd cloud/billing-worker --env production Set NYRA_BILLING_CANCEL_URL for the billing Worker through Wrangler secrets only. Do not paste Stripe, license, or webhook secret values into the dashboard or repo.
4. Secrets User + Codex npx wrangler secret put NYRA_BILLING_RETURN_URL --cwd cloud/billing-worker --env production Set NYRA_BILLING_RETURN_URL for the billing Worker through Wrangler secrets only. Do not paste Stripe, license, or webhook secret values into the dashboard or repo.
4. Secrets User + Codex npx wrangler secret put NYRA_LICENSE_API_TOKEN --cwd cloud/billing-worker --env production Set NYRA_LICENSE_API_TOKEN for the billing Worker through Wrangler secrets only. Do not paste Stripe, license, or webhook secret values into the dashboard or repo.
4. Secrets User + Codex npx wrangler secret put NYRA_LICENSE_SIGNING_SECRET --cwd cloud/billing-worker --env production Set NYRA_LICENSE_SIGNING_SECRET for the billing Worker through Wrangler secrets only. Do not paste Stripe, license, or webhook secret values into the dashboard or repo.
4. Secrets User + Codex npx wrangler secret put NYRA_MOBILE_BRIDGE_TOKEN --cwd cloud/mobile-bridge-worker --env production Set NYRA_MOBILE_BRIDGE_TOKEN for the mobile bridge Worker through Wrangler secrets only. Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo.
4. Secrets User + Codex npx wrangler secret put NYRA_OPENAI_API_KEY --cwd cloud/mobile-bridge-worker --env production Set NYRA_OPENAI_API_KEY for the mobile bridge Worker through Wrangler secrets only. Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo.
4. Secrets User + Codex npx wrangler secret put NYRA_ANTHROPIC_API_KEY --cwd cloud/mobile-bridge-worker --env production Set NYRA_ANTHROPIC_API_KEY for the mobile bridge Worker through Wrangler secrets only. Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo.
4. Secrets User + Codex npx wrangler secret put NYRA_GEMINI_API_KEY --cwd cloud/mobile-bridge-worker --env production Set NYRA_GEMINI_API_KEY for the mobile bridge Worker through Wrangler secrets only. Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo.
4. Secrets User + Codex npx wrangler secret put NYRA_GROK_API_KEY --cwd cloud/mobile-bridge-worker --env production Set NYRA_GROK_API_KEY for the mobile bridge Worker through Wrangler secrets only. Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo.
4. Secrets User + Codex npx wrangler secret put NYRA_LICENSE_SIGNING_SECRET --cwd cloud/mobile-bridge-worker --env production Set NYRA_LICENSE_SIGNING_SECRET for the mobile bridge Worker through Wrangler secrets only. Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo.
4. Secrets User + Codex npx wrangler secret put NYRA_ANDROID_DOWNLOAD_TICKET_SECRET --cwd cloud/mobile-bridge-worker --env production Set NYRA_ANDROID_DOWNLOAD_TICKET_SECRET for the mobile bridge Worker through Wrangler secrets only. Do not paste bridge tokens, provider API keys, license signing secrets, or Android ticket secrets into the dashboard or repo.
5. Migrations User + Codex npx wrangler d1 migrations apply nyra_command_center --cwd cloud/command-center-worker --env production Apply command-center D1 schema after the concrete database ID is configured. Do not apply migrations to the wrong Cloudflare account or placeholder database ID.
5. Migrations User + Codex npx wrangler d1 migrations apply nyra_billing --cwd cloud/billing-worker --env production Apply billing D1 schema after the concrete database ID is configured. Do not run live billing until Stripe test-mode and legal/support gates pass.
6. Deploy Codex npm run cloud:command-center:deploy Deploy the private command-center Worker API. Do not deploy with placeholder D1 ID or placeholder ALLOWED_ORIGIN.
6. Deploy Codex npm run cloud:command-center:pages:deploy Deploy the command-center dashboard artifact to Cloudflare Pages. Protect dashboard access before storing real business records or user files.
6. Deploy Codex npm run cloud:billing:deploy Deploy the billing Worker after test-mode payment rehearsal inputs are complete. Do not expose live checkout while deployability preflight still reports P0 live-money blockers.
6. Deploy Codex npm run cloud:mobile-bridge:bootstrap -- --worker-url=https://bridge.porterlabz.com --write-state Create/verify mobile bridge R2 buckets, upload the APK, deploy the Worker, and prove status/update/APK ticket/support-log/chat before saving state. Do not replace the Android bundled bridge URL for paid beta until this post-deploy smoke passes and the shared alpha token is removed.
7. First Sync Codex 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 Prove cloud command-center state can be pushed, scanned, safely ingested, and read back. Use only temporary shell env vars for NYRA_COMMAND_CENTER_API_URL and NYRA_COMMAND_CENTER_TOKEN.
7. First Sync Codex npm run billing:live-preflight -- --mode test --allow-blocked Run a guarded test-mode billing go-live rehearsal after cloud URLs and secrets exist. Do not run live-mode billing rehearsal until user explicitly confirms live Stripe readiness.
7. First Sync User + Codex npm run phone:self-test:ingest && npm run test:phone-self-test-ingest Ingest and verify a physical-phone self-test after the deployed bridge replaces the temporary tunnel. Do not clear the physical-phone gate from web-surface evidence; it must come from the installed Android app.

Action Queue

PhasePriorityOwnerStatusActionWhat To DoPageFieldVerify
1. Authentication P0 User Waiting on user Cloudflare API token required 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. pages/cloud-bootstrap.html cloudMigration.accountReady npm run cloudflare:discover
1. Authentication P1 User Optional fallback Wrangler login 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. pages/cloud-bootstrap.html cloudMigration.accountReady npm run cloudflare:discover
2. Remote Resources P0 User + Codex Waiting on Cloudflare API token D1: nyra_command_center 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. pages/cloud.html cloudMigration.d1DatabaseId npm run cloudflare:discover
2. Remote Resources P0 User + Codex Waiting on Cloudflare API token D1: nyra_billing 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. pages/cloud-billing.html billingCloud.d1DatabaseId npm run cloudflare:discover
2. Remote Resources P0 User + Codex Ready for config review R2: nyra-command-center-uploads Run discovery/config sync and verify the non-secret ID or URL is saved in the dashboard before deployment. pages/cloud.html cloudMigration.r2Bucket npm run cloudflare:discover
2. Remote Resources P0 User + Codex Ready for config review R2: nyra-mobile-support-logs Run discovery/config sync and verify the non-secret ID or URL is saved in the dashboard before deployment. pages/cloud-mobile-bridge.html mobileBridge.r2BucketName npm run cloudflare:discover && npm run cloud:mobile-bridge:check
2. Remote Resources P1 User + Codex Ready for config review R2: nyra-android-releases Run discovery/config sync and verify the non-secret ID or URL is saved in the dashboard before deployment. pages/cloud-mobile-bridge.html mobileBridge.androidReleasesBucketName npm run cloudflare:discover && npm run cloud:mobile-bridge:check
2. Remote Resources P1 User + Codex Ready for config review Pages: nyra-command-center-dashboard Run discovery/config sync and verify the non-secret ID or URL is saved in the dashboard before deployment. pages/cloud.html cloudPages.projectName npm run cloudflare:discover
2. Remote Resources P1 Codex Waiting on Cloudflare API token Worker: nyra-command-center-api 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. pages/cloud.html cloudSync.apiUrl npm run cloud:command-center:health
2. Remote Resources P1 Codex Waiting on Cloudflare API token Worker: nyra-billing-api 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. pages/cloud-billing.html billingCloud.workerUrl npm run cloud:billing:check
2. Remote Resources P1 Codex Waiting on Cloudflare API token Worker: nyra-mobile-bridge-api 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. pages/cloud-mobile-bridge.html mobileBridge.workerUrl npm run cloud:mobile-bridge:check && npm run test:mobile-bridge-security
3. Config Sync P0 Codex Waiting on prior gates sync non secret config Apply saved non-secret dashboard values to production Worker configs and verify the mobile bridge bootstrap plan. pages/cloud-bootstrap.html 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
4. Secrets P0 User + Codex Waiting on prior gates command token secret Set the private command-center API bearer token through Wrangler secrets only. pages/cloud-bootstrap.html npx wrangler secret put NYRA_COMMAND_TOKEN --cwd cloud/command-center-worker --env production
4. Secrets P0 User + Codex Waiting on prior gates billing secret stripe secret key Set STRIPE_SECRET_KEY for the billing Worker through Wrangler secrets only. pages/cloud-bootstrap.html npx wrangler secret put STRIPE_SECRET_KEY --cwd cloud/billing-worker --env production
4. Secrets P0 User + Codex Waiting on prior gates billing secret stripe webhook secret Set STRIPE_WEBHOOK_SECRET for the billing Worker through Wrangler secrets only. pages/cloud-bootstrap.html npx wrangler secret put STRIPE_WEBHOOK_SECRET --cwd cloud/billing-worker --env production
4. Secrets P0 User + Codex Waiting on prior gates billing secret nyra stripe price pro monthly Set NYRA_STRIPE_PRICE_PRO_MONTHLY for the billing Worker through Wrangler secrets only. pages/cloud-bootstrap.html npx wrangler secret put NYRA_STRIPE_PRICE_PRO_MONTHLY --cwd cloud/billing-worker --env production
4. Secrets P0 User + Codex Waiting on prior gates billing secret nyra billing success url Set NYRA_BILLING_SUCCESS_URL for the billing Worker through Wrangler secrets only. pages/cloud-bootstrap.html npx wrangler secret put NYRA_BILLING_SUCCESS_URL --cwd cloud/billing-worker --env production
4. Secrets P1 User + Codex Waiting on prior gates billing secret nyra billing cancel url Set NYRA_BILLING_CANCEL_URL for the billing Worker through Wrangler secrets only. pages/cloud-bootstrap.html npx wrangler secret put NYRA_BILLING_CANCEL_URL --cwd cloud/billing-worker --env production
4. Secrets P1 User + Codex Waiting on prior gates billing secret nyra billing return url Set NYRA_BILLING_RETURN_URL for the billing Worker through Wrangler secrets only. pages/cloud-bootstrap.html npx wrangler secret put NYRA_BILLING_RETURN_URL --cwd cloud/billing-worker --env production
4. Secrets P1 User + Codex Waiting on prior gates billing secret nyra license api token Set NYRA_LICENSE_API_TOKEN for the billing Worker through Wrangler secrets only. pages/cloud-bootstrap.html npx wrangler secret put NYRA_LICENSE_API_TOKEN --cwd cloud/billing-worker --env production
4. Secrets P1 User + Codex Waiting on prior gates billing secret nyra license signing secret Set NYRA_LICENSE_SIGNING_SECRET for the billing Worker through Wrangler secrets only. pages/cloud-bootstrap.html npx wrangler secret put NYRA_LICENSE_SIGNING_SECRET --cwd cloud/billing-worker --env production
4. Secrets P1 User + Codex Waiting on prior gates mobile bridge secret nyra mobile bridge token Set NYRA_MOBILE_BRIDGE_TOKEN for the mobile bridge Worker through Wrangler secrets only. pages/cloud-bootstrap.html npx wrangler secret put NYRA_MOBILE_BRIDGE_TOKEN --cwd cloud/mobile-bridge-worker --env production
4. Secrets P1 User + Codex Waiting on prior gates mobile bridge secret nyra openai api key Set NYRA_OPENAI_API_KEY for the mobile bridge Worker through Wrangler secrets only. pages/cloud-bootstrap.html npx wrangler secret put NYRA_OPENAI_API_KEY --cwd cloud/mobile-bridge-worker --env production
4. Secrets P1 User + Codex Waiting on prior gates mobile bridge secret nyra anthropic api key Set NYRA_ANTHROPIC_API_KEY for the mobile bridge Worker through Wrangler secrets only. pages/cloud-bootstrap.html npx wrangler secret put NYRA_ANTHROPIC_API_KEY --cwd cloud/mobile-bridge-worker --env production
4. Secrets P1 User + Codex Waiting on prior gates mobile bridge secret nyra gemini api key Set NYRA_GEMINI_API_KEY for the mobile bridge Worker through Wrangler secrets only. pages/cloud-bootstrap.html npx wrangler secret put NYRA_GEMINI_API_KEY --cwd cloud/mobile-bridge-worker --env production
4. Secrets P1 User + Codex Waiting on prior gates mobile bridge secret nyra grok api key Set NYRA_GROK_API_KEY for the mobile bridge Worker through Wrangler secrets only. pages/cloud-bootstrap.html npx wrangler secret put NYRA_GROK_API_KEY --cwd cloud/mobile-bridge-worker --env production
4. Secrets P1 User + Codex Waiting on prior gates mobile bridge secret nyra license signing secret Set NYRA_LICENSE_SIGNING_SECRET for the mobile bridge Worker through Wrangler secrets only. pages/cloud-bootstrap.html npx wrangler secret put NYRA_LICENSE_SIGNING_SECRET --cwd cloud/mobile-bridge-worker --env production
4. Secrets P1 User + Codex Waiting on prior gates mobile bridge secret nyra android download ticket secret Set NYRA_ANDROID_DOWNLOAD_TICKET_SECRET for the mobile bridge Worker through Wrangler secrets only. pages/cloud-bootstrap.html npx wrangler secret put NYRA_ANDROID_DOWNLOAD_TICKET_SECRET --cwd cloud/mobile-bridge-worker --env production
5. Migrations P1 User + Codex Waiting on prior gates command center migrations Apply command-center D1 schema after the concrete database ID is configured. pages/cloud-bootstrap.html npx wrangler d1 migrations apply nyra_command_center --cwd cloud/command-center-worker --env production
5. Migrations P1 User + Codex Waiting on prior gates billing migrations Apply billing D1 schema after the concrete database ID is configured. pages/cloud-bootstrap.html npx wrangler d1 migrations apply nyra_billing --cwd cloud/billing-worker --env production
6. Deploy P1 Codex Waiting on prior gates deploy command center worker Deploy the private command-center Worker API. pages/cloud-bootstrap.html npm run cloud:command-center:deploy
6. Deploy P1 Codex Waiting on prior gates deploy command center pages Deploy the command-center dashboard artifact to Cloudflare Pages. pages/cloud-bootstrap.html npm run cloud:command-center:pages:deploy
6. Deploy P1 Codex Waiting on prior gates deploy billing worker Deploy the billing Worker after test-mode payment rehearsal inputs are complete. pages/cloud-bootstrap.html npm run cloud:billing:deploy
6. Deploy P1 Codex Waiting on prior gates deploy mobile bridge worker Create/verify mobile bridge R2 buckets, upload the APK, deploy the Worker, and prove status/update/APK ticket/support-log/chat before saving state. pages/cloud-bootstrap.html npm run cloud:mobile-bridge:bootstrap -- --worker-url=https://bridge.porterlabz.com --write-state
7. First Sync P1 Codex Waiting on prior gates first cloud roundtrip Prove cloud command-center state can be pushed, scanned, safely ingested, and read back. pages/cloud-bootstrap.html 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
7. First Sync P1 Codex Waiting on prior gates billing live preflight test mode Run a guarded test-mode billing go-live rehearsal after cloud URLs and secrets exist. pages/cloud-bootstrap.html npm run billing:live-preflight -- --mode test --allow-blocked
7. First Sync P1 User + Codex Waiting on prior gates mobile phone self test after deploy Ingest and verify a physical-phone self-test after the deployed bridge replaces the temporary tunnel. pages/cloud-bootstrap.html npm run phone:self-test:ingest && npm run test:phone-self-test-ingest

Remote Creation Rule

Default operation is plan-only. Creating D1 databases, R2 buckets, Pages projects, Workers deployments, production migrations, or live billing endpoints requires an authenticated Cloudflare session and explicit user approval at execution time.

Secret Rule

Use Wrangler secrets, Cloudflare dashboard secret stores, Stripe, or temporary shell variables only. Do not paste Cloudflare tokens, Stripe secrets, webhook secrets, license signing secrets, certificate passwords, recovery codes, private keys, or bearer tokens into dashboard fields, repo files, Markdown, CSV, screenshots, or chat.

Official References

ReferenceURLUsed For
Cloudflare Wrangler Pages commands https://developers.cloudflare.com/workers/wrangler/commands/pages/ Pages project create and direct upload deploy commands.
Cloudflare D1 Wrangler commands https://developers.cloudflare.com/d1/wrangler-commands/ D1 create and migrations apply commands.
Cloudflare R2 Wrangler commands https://developers.cloudflare.com/r2/reference/wrangler-commands/ R2 bucket create/list commands.

Agent Run Log

Each manual intake or scheduled cloud marker becomes a visible build handoff. Use this to confirm the dashboard was read and routed.

No intake runs loaded yet.

Cloud Bootstrap JSON

{
  "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"
  }
}