@terreno/mcp 56.0.0-beta.0 → 56.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/LICENSE +21 -0
  2. package/dist/bootstrap.js +7 -7
  3. package/dist/bootstrap.js.map +1 -1
  4. package/dist/docs/templates/bootstrap/backend/types/models/userTypes.template.md +5 -4
  5. package/dist/docs/templates/tools/model.template.md +4 -2
  6. package/dist/docs/upgrades/0.31.0.md +60 -0
  7. package/dist/docs/upgrades/56.0.0-beta.2.md +59 -0
  8. package/dist/docs/versioned/next/README.md +1 -0
  9. package/dist/docs/versioned/next/explanation/README.md +7 -1
  10. package/dist/docs/versioned/next/explanation/deployment-architecture-gcp.md +65 -0
  11. package/dist/docs/versioned/next/explanation/deployment-baseline.md +78 -0
  12. package/dist/docs/versioned/next/explanation/positioning.md +164 -0
  13. package/dist/docs/versioned/next/explanation/repository-settings.md +44 -0
  14. package/dist/docs/versioned/next/explanation/roadmap-process.md +330 -0
  15. package/dist/docs/versioned/next/explanation/roadmap-seed-issues.md +887 -0
  16. package/dist/docs/versioned/next/how-to/README.md +8 -0
  17. package/dist/docs/versioned/next/how-to/build-for-web.md +69 -0
  18. package/dist/docs/versioned/next/how-to/deploy-backend-to-cloud-run.md +115 -0
  19. package/dist/docs/versioned/next/how-to/deploy-to-gcp.md +20 -228
  20. package/dist/docs/versioned/next/how-to/deploy-web-to-gcs-cdn.md +183 -0
  21. package/dist/docs/versioned/next/implementationPlans/PLAN_INDEX.md +31 -0
  22. package/dist/docs/versioned/next/implementationPlans/README.md +56 -30
  23. package/dist/docs/versioned/next/implementationPlans/agentic-sdlc-plugin.md +2 -1
  24. package/dist/docs/versioned/next/implementationPlans/ai-dev-loop-boost.md +1 -0
  25. package/dist/docs/versioned/next/implementationPlans/b2b-platform-program.md +115 -0
  26. package/dist/docs/versioned/next/implementationPlans/billing-stripe.md +158 -0
  27. package/dist/docs/versioned/next/implementationPlans/build-terreno-app-validation.md +1 -0
  28. package/dist/docs/versioned/next/implementationPlans/comms-abstraction.md +323 -0
  29. package/dist/docs/versioned/next/implementationPlans/comms-adapter-expo-push.md +107 -0
  30. package/dist/docs/versioned/next/implementationPlans/comms-adapter-sendgrid.md +157 -0
  31. package/dist/docs/versioned/next/implementationPlans/comms-adapter-twilio-sms.md +155 -0
  32. package/dist/docs/versioned/next/implementationPlans/comms-adapter-twilio-verify.md +99 -0
  33. package/dist/docs/versioned/next/implementationPlans/comms-admin-dashboard.md +180 -0
  34. package/dist/docs/versioned/next/implementationPlans/deploy-to-gcp.md +1 -0
  35. package/dist/docs/versioned/next/implementationPlans/deploy-to-vercel.md +1 -0
  36. package/dist/docs/versioned/next/implementationPlans/deployment-foundation.md +1 -0
  37. package/dist/docs/versioned/next/implementationPlans/docs-reference-coverage.md +1 -0
  38. package/dist/docs/versioned/next/implementationPlans/docs-tutorials-ai-first.md +1 -0
  39. package/dist/docs/versioned/next/implementationPlans/examples-demo-coverage.md +1 -0
  40. package/dist/docs/versioned/next/implementationPlans/infra-mcp-research.md +188 -0
  41. package/dist/docs/versioned/next/implementationPlans/infra-mcp.md +269 -0
  42. package/dist/docs/versioned/next/implementationPlans/migrate-cicd-to-circleci-research.md +126 -0
  43. package/dist/docs/versioned/next/implementationPlans/migrate-cicd-to-circleci.md +269 -0
  44. package/dist/docs/versioned/next/implementationPlans/native-module-baseline.md +105 -0
  45. package/dist/docs/versioned/next/implementationPlans/orgs-and-teams.md +158 -0
  46. package/dist/docs/versioned/next/implementationPlans/oss-governance-baseline.md +1 -0
  47. package/dist/docs/versioned/next/implementationPlans/password-reset-and-email-verification.md +147 -0
  48. package/dist/docs/versioned/next/implementationPlans/positioning-django-rails-universal.md +1 -0
  49. package/dist/docs/versioned/next/implementationPlans/public-roadmap-github.md +1 -0
  50. package/dist/docs/versioned/next/implementationPlans/upgrade-guides-and-skill.md +1 -0
  51. package/dist/docs/versioned/next/implementationPlans/web-ssr-and-admin-spa.md +1 -0
  52. package/dist/docs/versioned/next/reference/README.md +5 -0
  53. package/dist/docs/versioned/next/reference/admin-spa.md +130 -0
  54. package/dist/docs/versioned/next/reference/ai.md +519 -0
  55. package/dist/docs/versioned/next/reference/comms.md +132 -0
  56. package/dist/docs/versioned/next/reference/environment-variables.md +229 -382
  57. package/dist/docs/versioned/next/reference/test.md +108 -0
  58. package/dist/docs/versioned/next/roadmap.md +9 -0
  59. package/dist/docs/versioned/next/tasks/README.md +42 -0
  60. package/dist/docs/versioned/next/tasks/agentic-sdlc-plugin.md +5 -5
  61. package/dist/docs/versioned/next/tasks/billing-stripe.md +75 -0
  62. package/dist/docs/versioned/next/tasks/comms-abstraction.md +90 -0
  63. package/dist/docs/versioned/next/tasks/comms-adapter-expo-push.md +29 -0
  64. package/dist/docs/versioned/next/tasks/comms-adapter-sendgrid.md +39 -0
  65. package/dist/docs/versioned/next/tasks/comms-adapter-twilio-sms.md +39 -0
  66. package/dist/docs/versioned/next/tasks/comms-adapter-twilio-verify.md +19 -0
  67. package/dist/docs/versioned/next/tasks/comms-admin-dashboard.md +52 -0
  68. package/dist/docs/versioned/next/tasks/deploy-to-gcp.md +11 -11
  69. package/dist/docs/versioned/next/tasks/deployment-foundation.md +12 -12
  70. package/dist/docs/versioned/next/tasks/docs-reference-coverage.md +4 -4
  71. package/dist/docs/versioned/next/tasks/infra-mcp.md +43 -0
  72. package/dist/docs/versioned/next/tasks/migrate-cicd-to-circleci.md +215 -0
  73. package/dist/docs/versioned/next/tasks/native-module-baseline.md +42 -0
  74. package/dist/docs/versioned/next/tasks/orgs-and-teams.md +70 -0
  75. package/dist/docs/versioned/next/tasks/oss-governance-baseline.md +18 -18
  76. package/dist/docs/versioned/next/tasks/password-reset-and-email-verification.md +60 -0
  77. package/dist/docs/versioned/next/tasks/positioning-django-rails-universal.md +4 -4
  78. package/dist/docs/versioned/next/tasks/public-roadmap-github.md +15 -15
  79. package/package.json +4 -3
  80. package/src/docs/templates/bootstrap/backend/types/models/userTypes.template.md +5 -4
  81. package/src/docs/templates/tools/model.template.md +4 -2
  82. package/src/docs/upgrades/0.31.0.md +60 -0
  83. package/src/docs/upgrades/56.0.0-beta.2.md +59 -0
  84. package/src/docs/versioned/next/README.md +1 -0
  85. package/src/docs/versioned/next/explanation/README.md +7 -1
  86. package/src/docs/versioned/next/explanation/deployment-architecture-gcp.md +65 -0
  87. package/src/docs/versioned/next/explanation/deployment-baseline.md +78 -0
  88. package/src/docs/versioned/next/explanation/positioning.md +164 -0
  89. package/src/docs/versioned/next/explanation/repository-settings.md +44 -0
  90. package/src/docs/versioned/next/explanation/roadmap-process.md +330 -0
  91. package/src/docs/versioned/next/explanation/roadmap-seed-issues.md +887 -0
  92. package/src/docs/versioned/next/how-to/README.md +8 -0
  93. package/src/docs/versioned/next/how-to/build-for-web.md +69 -0
  94. package/src/docs/versioned/next/how-to/deploy-backend-to-cloud-run.md +115 -0
  95. package/src/docs/versioned/next/how-to/deploy-to-gcp.md +20 -228
  96. package/src/docs/versioned/next/how-to/deploy-web-to-gcs-cdn.md +183 -0
  97. package/src/docs/versioned/next/implementationPlans/PLAN_INDEX.md +31 -0
  98. package/src/docs/versioned/next/implementationPlans/README.md +56 -30
  99. package/src/docs/versioned/next/implementationPlans/agentic-sdlc-plugin.md +2 -1
  100. package/src/docs/versioned/next/implementationPlans/ai-dev-loop-boost.md +1 -0
  101. package/src/docs/versioned/next/implementationPlans/b2b-platform-program.md +115 -0
  102. package/src/docs/versioned/next/implementationPlans/billing-stripe.md +158 -0
  103. package/src/docs/versioned/next/implementationPlans/build-terreno-app-validation.md +1 -0
  104. package/src/docs/versioned/next/implementationPlans/comms-abstraction.md +323 -0
  105. package/src/docs/versioned/next/implementationPlans/comms-adapter-expo-push.md +107 -0
  106. package/src/docs/versioned/next/implementationPlans/comms-adapter-sendgrid.md +157 -0
  107. package/src/docs/versioned/next/implementationPlans/comms-adapter-twilio-sms.md +155 -0
  108. package/src/docs/versioned/next/implementationPlans/comms-adapter-twilio-verify.md +99 -0
  109. package/src/docs/versioned/next/implementationPlans/comms-admin-dashboard.md +180 -0
  110. package/src/docs/versioned/next/implementationPlans/deploy-to-gcp.md +1 -0
  111. package/src/docs/versioned/next/implementationPlans/deploy-to-vercel.md +1 -0
  112. package/src/docs/versioned/next/implementationPlans/deployment-foundation.md +1 -0
  113. package/src/docs/versioned/next/implementationPlans/docs-reference-coverage.md +1 -0
  114. package/src/docs/versioned/next/implementationPlans/docs-tutorials-ai-first.md +1 -0
  115. package/src/docs/versioned/next/implementationPlans/examples-demo-coverage.md +1 -0
  116. package/src/docs/versioned/next/implementationPlans/infra-mcp-research.md +188 -0
  117. package/src/docs/versioned/next/implementationPlans/infra-mcp.md +269 -0
  118. package/src/docs/versioned/next/implementationPlans/migrate-cicd-to-circleci-research.md +126 -0
  119. package/src/docs/versioned/next/implementationPlans/migrate-cicd-to-circleci.md +269 -0
  120. package/src/docs/versioned/next/implementationPlans/native-module-baseline.md +105 -0
  121. package/src/docs/versioned/next/implementationPlans/orgs-and-teams.md +158 -0
  122. package/src/docs/versioned/next/implementationPlans/oss-governance-baseline.md +1 -0
  123. package/src/docs/versioned/next/implementationPlans/password-reset-and-email-verification.md +147 -0
  124. package/src/docs/versioned/next/implementationPlans/positioning-django-rails-universal.md +1 -0
  125. package/src/docs/versioned/next/implementationPlans/public-roadmap-github.md +1 -0
  126. package/src/docs/versioned/next/implementationPlans/upgrade-guides-and-skill.md +1 -0
  127. package/src/docs/versioned/next/implementationPlans/web-ssr-and-admin-spa.md +1 -0
  128. package/src/docs/versioned/next/reference/README.md +5 -0
  129. package/src/docs/versioned/next/reference/admin-spa.md +130 -0
  130. package/src/docs/versioned/next/reference/ai.md +519 -0
  131. package/src/docs/versioned/next/reference/comms.md +132 -0
  132. package/src/docs/versioned/next/reference/environment-variables.md +229 -382
  133. package/src/docs/versioned/next/reference/test.md +108 -0
  134. package/src/docs/versioned/next/roadmap.md +9 -0
  135. package/src/docs/versioned/next/tasks/README.md +42 -0
  136. package/src/docs/versioned/next/tasks/agentic-sdlc-plugin.md +5 -5
  137. package/src/docs/versioned/next/tasks/billing-stripe.md +75 -0
  138. package/src/docs/versioned/next/tasks/comms-abstraction.md +90 -0
  139. package/src/docs/versioned/next/tasks/comms-adapter-expo-push.md +29 -0
  140. package/src/docs/versioned/next/tasks/comms-adapter-sendgrid.md +39 -0
  141. package/src/docs/versioned/next/tasks/comms-adapter-twilio-sms.md +39 -0
  142. package/src/docs/versioned/next/tasks/comms-adapter-twilio-verify.md +19 -0
  143. package/src/docs/versioned/next/tasks/comms-admin-dashboard.md +52 -0
  144. package/src/docs/versioned/next/tasks/deploy-to-gcp.md +11 -11
  145. package/src/docs/versioned/next/tasks/deployment-foundation.md +12 -12
  146. package/src/docs/versioned/next/tasks/docs-reference-coverage.md +4 -4
  147. package/src/docs/versioned/next/tasks/infra-mcp.md +43 -0
  148. package/src/docs/versioned/next/tasks/migrate-cicd-to-circleci.md +215 -0
  149. package/src/docs/versioned/next/tasks/native-module-baseline.md +42 -0
  150. package/src/docs/versioned/next/tasks/orgs-and-teams.md +70 -0
  151. package/src/docs/versioned/next/tasks/oss-governance-baseline.md +18 -18
  152. package/src/docs/versioned/next/tasks/password-reset-and-email-verification.md +60 -0
  153. package/src/docs/versioned/next/tasks/positioning-django-rails-universal.md +4 -4
  154. package/src/docs/versioned/next/tasks/public-roadmap-github.md +15 -15
@@ -0,0 +1,269 @@
1
+ # Implementation Plan: Migrate CI/CD to CircleCI
2
+
3
+ **Status:** Draft — decisions recorded; awaiting Approval
4
+ **Discussion:** _(none)_
5
+ **Roadmap issue:** _(pending — hand off via `roadmap-item` when Approved)_
6
+ **Linear:** _(none)_
7
+ **Priority:** High
8
+ **Effort:** Large (cross-cutting infra; many workflows)
9
+ **Owner:** unassigned (CircleCI org/plan: requester)
10
+ **Created:** 2026-08-17
11
+ **Branch:** `cursor/migrate-cicd-circleci-2b6d`
12
+ **Research:** [`migrate-cicd-to-circleci-research.md`](migrate-cicd-to-circleci-research.md)
13
+ **Depends on:** CircleCI org + paid plan created by requester; GCP project access for OIDC terraform
14
+
15
+ ## Goal
16
+
17
+ Move Terreno’s CI/CD from GitHub Actions to CircleCI end-to-end: every pipeline that builds, tests, deploys, publishes, or gates PRs runs on CircleCI. Use a dual-run cutover (GHA stays required until the matching CircleCI workflow is green, then delete the GHA workflow). End state: no `.github/workflows/*.yml` CI/CD jobs remain; GitHub keeps only what CircleCI cannot replace (if any residual is accepted, document it explicitly under Not Included).
18
+
19
+ ## Non-Goals
20
+
21
+ - Changing what tests assert (only where they run), except for runner-parity fixes.
22
+ - Migrating sibling repos (Flourish, Zapling, etc.).
23
+ - Redesigning product deploy topology (Cloud Run / Netlify / EAS stay; only the orchestrator changes).
24
+ - Shipping Appium **iOS** on CircleCI in **v1** (deferred to a late phase; Android Appium may move earlier if ubuntu parity is easy).
25
+ - Rewriting gh-aw agentic *prompt* content; only re-home or replace the *runner*.
26
+
27
+ ## Decisions
28
+
29
+ Recorded 2026-08-17 from Blend clarification.
30
+
31
+ | # | Question | Decision |
32
+ |---|----------|----------|
33
+ | CC1 | Scope | **A — Full cutover.** All CI/CD moves to CircleCI; GHA workflows deleted after dual-run proves green. |
34
+ | CC2 | Cutover style | **A — Dual-run.** Keep GHA required checks until the CircleCI twin is trusted, then remove GHA. |
35
+ | CC3 | v1 must include | **GCP CD + terraform**, **npm publish-on-tag**, **Netlify** (demo / example-frontend / docs), **EAS PR + fingerprint gate**. Not Appium iOS in v1. |
36
+ | CC4 | CircleCI account | Requester creates the CircleCI plan/org and links the GitHub repo. |
37
+ | CC5 | Branch protection | Remapping required checks is in scope; maintainers apply GitHub settings when CircleCI check names are stable. |
38
+ | CC6 | Config shape | **A — Dynamic config** (`setup: true`) + **path-filtering** orb. |
39
+
40
+ ## Architecture
41
+
42
+ ### Target topology
43
+
44
+ ```mermaid
45
+ flowchart TB
46
+ subgraph gh [GitHub]
47
+ PUSH[push / PR / tag / schedule]
48
+ BP[branch protection required checks]
49
+ end
50
+
51
+ subgraph cci [CircleCI]
52
+ SETUP[setup workflow path-filtering]
53
+ CONT[continue config]
54
+ PKG[package CI + policy]
55
+ E2E[Playwright e2e]
56
+ NET[Netlify deploys]
57
+ EAS[EAS + fingerprint]
58
+ GCP[GCP CD via OIDC]
59
+ PUB[npm publish on tag]
60
+ MOB[Appium / Maestro late phase]
61
+ REP[replacements: CodeQL alt, bots, triage]
62
+ end
63
+
64
+ PUSH --> SETUP --> CONT
65
+ CONT --> PKG & E2E & NET & EAS & GCP & PUB & MOB & REP
66
+ PKG & E2E & EAS --> BP
67
+ GCP --> CR[Cloud Run / Artifact Registry / Infra Manager]
68
+ NET --> NL[Netlify sites]
69
+ PUB --> NPM[npmjs @terreno/*]
70
+ EAS --> EXPO[EAS Cloud]
71
+ ```
72
+
73
+ ### Config layout
74
+
75
+ ```
76
+ .circleci/
77
+ config.yml # setup: true — path-filtering only
78
+ continue-config.yml # all real workflows/jobs
79
+ src/ # optional: generated fragments if we split by package
80
+ ```
81
+
82
+ - Use `circleci/path-filtering` to set boolean parameters (`run-api`, `run-ui`, `run-cd`, …) from changed paths (mirror today’s path filters).
83
+ - Use `circleci/node` orb (≥7.2.0) for Bun install + cache (`pkg-manager: bun`).
84
+ - Shared commands: `bun_install`, `start_mongo` (Docker service or `cimg` + mongo service), `compile_workspace_deps`.
85
+ - Prefer a **private org orb** later for reuse; v1 may inline commands in `continue-config.yml` to ship faster, then extract.
86
+
87
+ ### Secrets: CircleCI Contexts
88
+
89
+ | Context | Contents (from current GHA) |
90
+ |---------|------------------------------|
91
+ | `terreno-npm` | `NPM_TOKEN` |
92
+ | `terreno-netlify` | `NETLIFY_AUTH_TOKEN`, site IDs |
93
+ | `terreno-expo` | `EXPO_TOKEN` |
94
+ | `terreno-gcp` | CircleCI OIDC (no long-lived key for CD); migrate `GCP_SA_KEY` off preview-cleanup onto OIDC |
95
+ | `terreno-e2e` | `E2E_TOKEN_SECRET`, `E2E_REFRESH_TOKEN_SECRET`, `E2E_SESSION_SECRET` |
96
+ | `terreno-release` | `REPO_ADMIN_TOKEN`, `ZOOM_WEBHOOK_URL`, `ZOOM_WEBHOOK_TOKEN` |
97
+ | `terreno-agentic` | `CURSOR_API_KEY` (and replacements for Copilot/gh-aw tokens if re-homed) |
98
+ | `terreno-github-api` | PAT with `pull-requests`, `deployments`, `contents` as needed for comments / Deployments API / roadmap |
99
+
100
+ Restrict context access by project + environment (e.g. `release` context only on tag workflows).
101
+
102
+ ### GCP identity (blocking infra for Phase GCP)
103
+
104
+ Today `terraform/modules/github_oidc` trusts **only** `https://token.actions.githubusercontent.com`. CircleCI CD requires:
105
+
106
+ 1. New Workload Identity pool provider for CircleCI’s OIDC issuer.
107
+ 2. Attribute condition on org/project/VCS origin.
108
+ 3. Bind `roles/iam.workloadIdentityUser` for deployer + terraform SAs.
109
+ 4. Dual-trust during dual-run (GitHub + CircleCI providers both valid), then remove GitHub provider when GHA CD is deleted.
110
+
111
+ Prefer extending the module (`circleci_oidc` or rename to `ci_oidc` with multiple providers) over a one-off in Flourish terraform only — keep consumer docs honest.
112
+
113
+ ### GitHub ↔ CircleCI integration
114
+
115
+ - CircleCI GitHub App (or OAuth) on `FlourishHealth/terreno`.
116
+ - Status checks reported to GitHub for branch protection (job names documented in `docs/explanation/repository-settings.md`).
117
+ - PR comments / labels / Deployments API: call GitHub REST via `gh` or `curl` with `terreno-github-api` context (replaces `GITHUB_TOKEN` action privileges).
118
+ - Tag + schedule triggers: CircleCI pipeline triggers (or GitHub → CircleCI API webhook) for cron jobs currently on GHA.
119
+
120
+ ### Dual-run protocol (every phase)
121
+
122
+ 1. Land CircleCI twin; name check `cci/<old-job-name>` or stable CircleCI job name.
123
+ 2. Add CircleCI check as **non-required** optional signal; keep GHA required.
124
+ 3. Observe green on `master` + representative PRs.
125
+ 4. Flip branch protection: require CircleCI; unrequire GHA.
126
+ 5. Delete the GHA workflow file in the same PR window as the protection flip (or immediately after).
127
+ 6. Never leave tag publish listening on **both** systems.
128
+
129
+ ## Models / APIs / Notifications / UI
130
+
131
+ None (infra-only). Zoom release notify stays a webhook call from the publish workflow.
132
+
133
+ ## Phases
134
+
135
+ ### Phase 0 — Prerequisites (human + docs)
136
+
137
+ - Create CircleCI org/plan; link repo; enable dynamic config.
138
+ - Create empty Contexts; document secret migration checklist.
139
+ - Inventory required check names vs today’s GHA job `name:` fields.
140
+
141
+ ### Phase 1 — Foundation
142
+
143
+ - Add `.circleci/config.yml` + `continue-config.yml` skeleton.
144
+ - Path-filtering parameter map covering all packages + terraform + docs + demo.
145
+ - Shared Bun + cache + Mongo patterns.
146
+ - Smoke workflow on every push that only validates config.
147
+
148
+ ### Phase 2 — Package CI + repo policy (v1)
149
+
150
+ Port and dual-run:
151
+
152
+ - `api-ci`, `ai-ci`, `rtk-ci`, `ui-ci`, `ui-demo-ci`, `comms-ci`, `mcp-server-ci`
153
+ - `example-frontend-ci`, `example-backend-ci`, `example-backend-script-runner`, `example-backend-docker`
154
+ - `admin-spa-ci`
155
+ - `repo-policies`, `rulesync-check`, `dco` (DCO via GitHub API + CircleCI)
156
+
157
+ ### Phase 3 — Playwright E2E (v1)
158
+
159
+ - `e2e-ci`, `admin-spa-integration` (Mongo replica set + secrets context).
160
+
161
+ ### Phase 4 — Netlify deploys (v1)
162
+
163
+ - `demo-deploy`, `frontend-example-deploy`, `docs-deploy`
164
+ - Recreate preview aliases + optional GitHub Deployments via API.
165
+ - `preview-cleanup` equivalent for Netlify/GCP previews as applicable.
166
+
167
+ ### Phase 5 — EAS + fingerprint (v1)
168
+
169
+ - Port `eas-pr`, `eas-dev-build`, `fingerprint-gate` scripts under `.circleci/` or keep scripts in `.github/workflows/scripts/` and invoke from CircleCI until relocated to `scripts/ci/`.
170
+ - PR comment + `fingerprint-acknowledged` label via GitHub API.
171
+
172
+ ### Phase 6 — GCP CD + OIDC (v1)
173
+
174
+ - Terraform: CircleCI OIDC provider + dual-trust.
175
+ - Port `cd.yml` (detect → terraform → backend/mcp deploy).
176
+ - Port `preview-cleanup` onto OIDC (eliminate `GCP_SA_KEY`).
177
+ - Dual-run CD carefully (concurrency: one deployer).
178
+
179
+ ### Phase 7 — npm publish (v1)
180
+
181
+ - Port `publish-on-tag` + `publish-feature-flags-manual`.
182
+ - **Single-writer rule:** disable GHA tag trigger in the same change that enables CircleCI tag pipeline.
183
+ - Keep Zoom notify + master version bump + docs cut + demo dispatch.
184
+
185
+ ### Phase 8 — Mobile runners (post-v1 / still required for full cutover)
186
+
187
+ - Maestro (`maestro-e2e`).
188
+ - Appium Android on Linux VM.
189
+ - Appium iOS on CircleCI macOS resource class (image pin parity with `macos-15` intent).
190
+ - Then delete `demo-appium-ci.yml` / `maestro-e2e.yml`.
191
+
192
+ ### Phase 9 — GitHub-native + agentic replacements (full cutover)
193
+
194
+ | Current GHA | Replacement approach |
195
+ |-------------|----------------------|
196
+ | `codeql-analysis` | CircleCI job uploading SARIF to GitHub Code Scanning API **or** third-party SAST orb; preserve Security tab if possible |
197
+ | `dependabot-auto-merge` | Keep Dependabot PRs on GitHub; auto-merge via CircleCI on Dependabot branches **or** Renovate on CircleCI |
198
+ | `triage.yml` | CircleCI pipeline trigger on `issues` via GitHub Apps webhook → CircleCI API, or GitHub Action **stub** only if product accepts residual GHA (conflicts with CC1 — prefer webhook) |
199
+ | `roadmap-generate` | Scheduled CircleCI job with `ROADMAP_PROJECT_TOKEN` |
200
+ | `architectural-pr-review` | CircleCI job + `CURSOR_API_KEY` (lose `pull_request_target` free fork safety — use least privilege + fork policy) |
201
+ | `agentics-maintenance` + `*.lock.yml` gh-aw | Re-home to CircleCI scheduled pipelines calling the same scripts **or** retire features; do not leave gh-aw as the only runner if CC1 holds |
202
+ | `docs-audit` | Scheduled CircleCI job |
203
+
204
+ ### Phase 10 — Cleanup + docs
205
+
206
+ - Delete remaining `.github/workflows/*.yml` (and lock sources if retired).
207
+ - Update `CONTRIBUTING.md`, `docs/explanation/repository-settings.md`, `terraform/README.md`, deploy how-tos, AGENTS.md Cloud CI notes.
208
+ - Archive research; mark IP Complete.
209
+
210
+ ## Feature Flags & Migrations
211
+
212
+ - No product feature flags.
213
+ - Infra migration: dual OIDC trust window; dual CI check window; **no dual tag-publish**.
214
+ - Secret migration checklist is the migration artifact (Contexts populated before jobs go required).
215
+
216
+ ## Activity Log & User Updates
217
+
218
+ - Announce in Discord/Slack/Zoom when required checks flip and when tag publish moves.
219
+ - Changelog: under Unreleased chore — “CI/CD runs on CircleCI”.
220
+
221
+ ## Not Included / Future Work
222
+
223
+ - Private orb publication + versioning pipeline (nice follow-up after Phase 1–2 stabilize).
224
+ - Moving Netlify sites to GCS+CDN (separate deploy architecture IPs).
225
+ - Self-hosted CircleCI runners.
226
+ - Credit-cost optimization beyond path-filtering (test splitting, resource-class tuning).
227
+
228
+ ## Risks & Mitigations
229
+
230
+ | Risk | Mitigation |
231
+ |------|------------|
232
+ | Double npm publish | Single-writer cutover for tags; disable GHA first or in same commit |
233
+ | GCP deploy from wrong IdP | Dual-trust then remove GitHub provider; dry-run terraform preview on CircleCI first |
234
+ | Branch protection gaps during flip | Document exact check names; flip in a dedicated maintainer window |
235
+ | macOS/Appium flake | Deferred to Phase 8; keep GHA Appium until CircleCI macOS proven |
236
+ | gh-aw feature loss | Phase 9 explicit replace-or-retire decision per lockfile before deleting |
237
+ | Credit burn during dual-run | Path filters; timebox dual-run per phase (target: days, not months) |
238
+ | `mcp-server-ci` still filters `main` | Normalize to `master` while porting |
239
+
240
+ ## Files to Create / Modify
241
+
242
+ **Create**
243
+
244
+ - `.circleci/config.yml`
245
+ - `.circleci/continue-config.yml`
246
+ - `docs/how-to/circleci.md` (or `docs/explanation/ci-cd-circleci.md`)
247
+ - `terraform/modules/circleci_oidc/` or extend `github_oidc` → multi-provider `ci_oidc`
248
+ - `scripts/ci/` (relocated EAS/fingerprint helpers)
249
+
250
+ **Modify**
251
+
252
+ - `docs/explanation/repository-settings.md`
253
+ - `terraform/README.md`, Flourish/terreno terraform roots that wire OIDC
254
+ - `CONTRIBUTING.md`, root/CI docs references to GitHub Actions
255
+ - Delete `.github/workflows/*` progressively per phase
256
+
257
+ ## Task List
258
+
259
+ See [`docs/tasks/migrate-cicd-to-circleci.md`](../tasks/migrate-cicd-to-circleci.md).
260
+
261
+ ## Acceptance Criteria
262
+
263
+ - [ ] All v1 workflows (package CI, policy, Playwright e2e, Netlify, EAS/fingerprint, GCP CD, npm publish) are green on CircleCI and required on `master` where applicable.
264
+ - [ ] Matching GHA workflows for those surfaces are deleted; tag publish has exactly one listener.
265
+ - [ ] CircleCI OIDC can deploy Cloud Run without `GCP_SA_KEY` for CD paths.
266
+ - [ ] Path-filtering skips unrelated package jobs on a docs-only change.
267
+ - [ ] `repository-settings.md` lists CircleCI check names; branch protection matches.
268
+ - [ ] Phase 8–9 either complete (full cutover) or are tracked as blocking follow-ups before calling CC1 done.
269
+ - [ ] CONTRIBUTING / terraform / deploy docs no longer instruct maintainers to use GHA for Terreno CI/CD.
@@ -0,0 +1,105 @@
1
+ # Implementation Plan: Native module baseline for the next major release
2
+
3
+ **Status:** Draft
4
+ **Roadmap issue:** https://github.com/FlourishHealth/terreno/issues/1026
5
+ **Priority:** High
6
+ **Effort:** Small batch (code) — coordination cost is the release itself
7
+ **Owner:** unassigned
8
+ **Created:** 2026-08-09
9
+ **Program:** [B2B platform](b2b-platform-program.md)
10
+ **Depends on:** decisions D1/D3/D7 (resolved 2026-08-09)
11
+ **RTK deprecation flag:** None
12
+
13
+ ## Goal
14
+
15
+ Adding a native module to an Expo app invalidates every existing dev-client and store
16
+ binary, so each addition after a release costs consumers a rebuild cycle. This IP lands
17
+ **all** native dependencies the B2B program needs in one breaking (major) release, so every
18
+ subsequent program feature — billing UI, MFA, dark mode, SSO, push, mobile IAP — ships as a
19
+ JS/OTA update against the same binary.
20
+
21
+ ## Non-Goals
22
+
23
+ - Implementing any feature that uses these modules (their own IPs).
24
+ - Expo SDK version upgrades (separate effort; this IP targets the current SDK).
25
+ - `@10play/tentap-editor` — excluded by decision D3 (markdown stays).
26
+
27
+ ## Decisions
28
+
29
+ | Question | Decision |
30
+ |----------|----------|
31
+ | Manifest (D7, resolved) | `@stripe/stripe-react-native`, `react-native-purchases` + `react-native-purchases-ui`, `expo-device`, `expo-crypto`, `expo-local-authentication`, `expo-system-ui`, `react-native-otp-verify` |
32
+ | Where dependencies live | Root catalog entries; linked in `example-frontend` and `demo` app manifests; `@terreno/ui`/feature packages reference them only when their feature IPs land (this IP is binary readiness, not usage) |
33
+ | Stripe Android constraints | Pin Kotlin 2.x / `compileSdkVersion` 36 via `expo-build-properties` per stripe-react-native requirements |
34
+ | Expo Go story | Document which flows degrade in Expo Go (purchases → RevenueCat Preview API mode; stripe/local-auth → dev build required); CI smoke keeps web unaffected |
35
+ | Release process | Follows the `release` skill + the upgrade-notes-for-breaking-releases CI gate (PR #987): major tag, upgrade note required |
36
+
37
+ ## Architecture
38
+
39
+ Changes are dependency + config only:
40
+
41
+ 1. **Root `package.json` catalog:** add the seven packages (sorted), per the dependency
42
+ catalog rule (shared by `example-frontend` + `demo`).
43
+ 2. **`example-frontend/app.json` + `demo/app.json` plugins:**
44
+ `@stripe/stripe-react-native` (merchantIdentifier placeholder, `enableGooglePay:
45
+ true`), `react-native-purchases`, and `expo-build-properties` with the Kotlin/compileSdk
46
+ pins.
47
+ 3. **EAS builds:** refresh dev-client profiles via the existing `eas-dev-build` workflow;
48
+ verify Android + iOS builds compile with the new pods/gradle deps.
49
+ 4. **Upgrade note:** `docs` upgrade note describing the new binary requirement and the
50
+ consumer checklist (rebuild dev clients, add config plugins, set merchant id when using
51
+ Stripe).
52
+
53
+ ## Models / APIs / Notifications
54
+
55
+ None.
56
+
57
+ ## UI
58
+
59
+ None visible — binary-only change. `demo` gains a hidden diagnostics story listing
60
+ resolved native module versions so builds are verifiable at runtime.
61
+
62
+ ## Phases
63
+
64
+ 1. **Dependencies + config:** catalog entries, app.json plugins, build-properties pins,
65
+ `bun install` + compile green, web export unaffected.
66
+ 2. **Builds + verification:** EAS dev builds for iOS/Android; diagnostics story confirms
67
+ modules resolve on device; Expo Go degradation documented.
68
+ 3. **Release:** upgrade note, coordinate the major tag via the release process.
69
+
70
+ ## Feature Flags & Migrations
71
+
72
+ None. Runtime behavior is unchanged until feature IPs consume the modules.
73
+
74
+ ## Activity Log & User Updates
75
+
76
+ None.
77
+
78
+ ## Not Included / Future Work
79
+
80
+ - TenTap (revisit in a later major if WYSIWYG is adopted — decision D3).
81
+ - Any feature wiring of the added modules.
82
+
83
+ ## Files to Create / Modify
84
+
85
+ - Root `package.json` (catalog), `example-frontend/package.json`, `demo/package.json`
86
+ - `example-frontend/app.json`, `demo/app.json`
87
+ - `demo` diagnostics story
88
+ - `docs/` upgrade note for the major release
89
+ - (No `@terreno/ui` source changes)
90
+
91
+ ## Task List
92
+
93
+ See [docs/tasks/native-module-baseline.md](../tasks/native-module-baseline.md).
94
+
95
+ ## Acceptance Criteria
96
+
97
+ - [ ] `bun install`, full compile, and `example-frontend` web export succeed with the
98
+ seven packages added.
99
+ - [ ] iOS and Android EAS dev builds compile; the diagnostics story shows all seven
100
+ modules resolved on device.
101
+ - [ ] Android build carries the Kotlin 2.x / compileSdk 36 pins without breaking
102
+ gesture-handler or other existing native deps.
103
+ - [ ] Expo Go still launches the app with documented degradations only.
104
+ - [ ] The release PR carries the required upgrade note and the breaking-release CI gate
105
+ passes.
@@ -0,0 +1,158 @@
1
+ # Implementation Plan: Organizations, teams, and multi-tenant scoping
2
+
3
+ **Status:** Draft
4
+ **Roadmap issue:** https://github.com/FlourishHealth/terreno/issues/1024
5
+ **Priority:** High
6
+ **Effort:** Big batch
7
+ **Owner:** unassigned
8
+ **Created:** 2026-08-09
9
+ **Program:** [B2B platform](b2b-platform-program.md)
10
+ **Depends on:** none (soft: [rbac-permissions](rbac-permissions.md) for role vocabulary; this IP ships coarse org roles that RBAC later subsumes)
11
+ **RTK deprecation flag:** None — backend only; frontend surfaces are `org-management-ui`
12
+
13
+ ## Goal
14
+
15
+ Terreno's entire access story is per-user: `ownerId` fields, `OwnerQueryFilter`,
16
+ `Permissions.IsOwner`. A B2B app needs data owned by an **organization** and accessed by
17
+ its **members**. This IP adds the tenant analog of the owner stack to `@terreno/api`:
18
+ Organization and Membership models, an org-context middleware, an `orgScopedPlugin` for
19
+ schemas, `OrgQueryFilter` and `Permissions.IsOrgMember`/`IsOrgAdmin` for modelRouter, and
20
+ CRUD routes for orgs and memberships — so `modelRouter(Todo, {queryFilter: OrgQueryFilter,
21
+ permissions: {...IsOrgMember}})` is all an app needs for tenant-safe endpoints.
22
+
23
+ ## Non-Goals
24
+
25
+ - Invitations, seat counting (`invitations-and-seats` item).
26
+ - Fine-grained RBAC (roles beyond `member`/`admin` — [rbac-permissions](rbac-permissions.md)).
27
+ - Org switcher and management screens (`org-management-ui` item).
28
+ - Billing linkage (`billing-stripe` maps customers to orgs later).
29
+ - Cross-org data sharing, nested teams/sub-orgs (future work).
30
+
31
+ ## Decisions
32
+
33
+ | Question | Decision |
34
+ |----------|----------|
35
+ | **D6 (resolved 2026-08-09):** native Mongoose models vs Better Auth `organization` plugin | **Native models.** The JWT/passport path (still supported and the example default) cannot use a Better-Auth-only construct; native models serve both auth paths, keep modelRouter/query-filter integration first-class, and can sync to Better Auth's plugin later if wanted |
36
+ | Org context transport | `X-Organization-Id` header, resolved by middleware into `req.organization` + `req.membership`; explicit query/body override rejected |
37
+ | One org or many per user? | Many (Membership join collection); apps wanting single-org enforce via option `maxOrgsPerUser: 1` |
38
+ | Coarse roles now | `Membership.role: "admin" \| "member"` — deliberately minimal; RBAC IP replaces this enum with role references, migration documented there |
39
+ | Scoping mechanism | `orgScopedPlugin` adds required indexed `organizationId`; `OrgQueryFilter` filters lists by active memberships; `preCreate` helper injects the context org |
40
+ | Personal orgs? | No auto-created personal org; apps opt in via `createDefaultOrgOnSignup` option |
41
+
42
+ ## Architecture
43
+
44
+ ```
45
+ api/src/orgs/
46
+ organizationModel.ts # Organization + Membership schemas/models
47
+ orgContext.ts # middleware: header → req.organization/req.membership
48
+ orgPlugin.ts # orgScopedPlugin(schema) — organizationId field + index
49
+ orgPermissions.ts # IsOrgMember, IsOrgAdmin, OrgQueryFilter
50
+ orgsApp.ts # OrgsApp TerrenoPlugin — routes + options
51
+ ```
52
+
53
+ `OrgsApp` options:
54
+
55
+ ```typescript
56
+ new OrgsApp({
57
+ maxOrgsPerUser?: number;
58
+ createDefaultOrgOnSignup?: boolean;
59
+ onOrgCreated?: (org, owner) => Promise<void>;
60
+ })
61
+ ```
62
+
63
+ Request flow: `authenticateMiddleware` → `orgContextMiddleware` (loads org by header,
64
+ verifies an active membership for `req.user`, 403 otherwise) → route. Routes that take
65
+ `Permissions.IsOrgMember`/`IsOrgAdmin` require the context; `OrgQueryFilter` works with or
66
+ without a context (no header → all orgs the user belongs to; header → that org only).
67
+
68
+ ## Models
69
+
70
+ Both use the five-type pattern, `description` on every field, `createdUpdatedPlugin` +
71
+ `isDeletedPlugin`, `strict: "throw"`.
72
+
73
+ **Organization** — `name` (string, required), `slug` (string, unique, indexed, generated),
74
+ `ownerId` (ref User, required — the creating user; ownership transferable), `settings`
75
+ (Mixed, app-defined), `disabled` (boolean).
76
+
77
+ **Membership** — `organizationId` (ref Organization, required, indexed), `userId` (ref
78
+ User, required, indexed), `role` ("admin" | "member", default "member"), `status`
79
+ ("active" | "suspended", default "active"), compound unique index on
80
+ `(organizationId, userId)`. Statics: `findActiveForUser`, `isMember`, `isOrgAdmin`.
81
+
82
+ ## APIs
83
+
84
+ | Method | Path | Permissions | Notes |
85
+ |---|---|---|---|
86
+ | POST | `/orgs` | IsAuthenticated | Creates org + admin membership for creator; respects `maxOrgsPerUser` |
87
+ | GET | `/orgs` | IsAuthenticated | Lists orgs the user belongs to (membership join) |
88
+ | GET | `/orgs/:id` | IsOrgMember | |
89
+ | PATCH | `/orgs/:id` | IsOrgAdmin | name/settings; ownership transfer admin-only |
90
+ | DELETE | `/orgs/:id` | IsOrgAdmin | Soft delete; memberships cascade to suspended |
91
+ | GET | `/orgs/:id/members` | IsOrgMember | Paginated membership list (populated user name/email) |
92
+ | PATCH | `/orgs/:id/members/:memberId` | IsOrgAdmin | Role/status change; cannot demote last admin |
93
+ | DELETE | `/orgs/:id/members/:memberId` | IsOrgAdmin | Remove member; cannot remove last admin |
94
+
95
+ Member creation is **not** exposed here — members arrive via `invitations-and-seats`
96
+ (or `createDefaultOrgOnSignup`). All routes via modelRouter where shapes fit, custom
97
+ `createOpenApiBuilder` routes for member management.
98
+
99
+ ## Notifications
100
+
101
+ None in this IP (invitation emails belong to `invitations-and-seats`).
102
+
103
+ ## UI
104
+
105
+ None in this IP (`org-management-ui`). example-backend gains an org-scoped demo model
106
+ (`Project`) exercising `orgScopedPlugin` + `OrgQueryFilter` end to end.
107
+
108
+ ## Phases
109
+
110
+ 1. **Models + plugin:** Organization, Membership, `orgScopedPlugin`, statics, unit tests.
111
+ 2. **Context + permissions:** middleware, `IsOrgMember`/`IsOrgAdmin`, `OrgQueryFilter`,
112
+ modelRouter integration tests (member of A cannot read B's rows — the critical suite).
113
+ 3. **Routes + app:** `OrgsApp`, org/member routes, last-admin guards, OpenAPI, supertest.
114
+ 4. **Example + docs:** example-backend `Project` model + routes, seeds, admin panel model
115
+ registration, `docs/how-to/add-organizations.md`, reference docs, SDK regen.
116
+
117
+ ## Feature Flags & Migrations
118
+
119
+ No migration for existing apps (new collections; opt-in plugin). Adopting apps that
120
+ backfill `organizationId` onto existing collections get a documented backfill recipe —
121
+ formal tooling arrives with `mongo-migrations`.
122
+
123
+ ## Activity Log & User Updates
124
+
125
+ Org create/delete and membership role changes fire an `onOrgAudit` hook (mirroring
126
+ `onAdminAudit`) so apps can log them; framework-wide audit persistence is the
127
+ `framework-audit-log` item.
128
+
129
+ ## Not Included / Future Work
130
+
131
+ - Teams within orgs (the Membership schema reserves a `teamIds` extension point but ships
132
+ without it — YAGNI until a consumer needs it).
133
+ - Org-level settings UI, domain capture/auto-join (SSO IP touches this).
134
+ - Per-org rate limits, quotas.
135
+
136
+ ## Files to Create / Modify
137
+
138
+ - `api/src/orgs/*` (new), `api/src/index.ts` exports
139
+ - `api/src/permissions.ts` — export org permissions alongside existing ones
140
+ - `example-backend/src/models/project.ts`, `api/projects.ts`, seeds, `server.ts`
141
+ - `docs/how-to/add-organizations.md`, `docs/reference/api.md`
142
+ - `example-frontend` SDK regen (`bun run sdk`) after backend routes land
143
+
144
+ ## Task List
145
+
146
+ See [docs/tasks/orgs-and-teams.md](../tasks/orgs-and-teams.md).
147
+
148
+ ## Acceptance Criteria
149
+
150
+ - [ ] A user can create an org, becoming its admin member; `maxOrgsPerUser` is enforced.
151
+ - [ ] With two orgs seeded, a member of org A listing an org-scoped model with
152
+ `OrgQueryFilter` never receives org B documents — including via crafted `$or` /
153
+ query-param attempts.
154
+ - [ ] Requests with an `X-Organization-Id` the user is not an active member of get 403.
155
+ - [ ] The last admin of an org cannot be demoted or removed.
156
+ - [ ] Org routes appear in `/openapi.json`; regenerated SDK compiles; admin panel can
157
+ browse Organizations and Memberships.
158
+ - [ ] Soft-deleting an org suspends its memberships and hides its scoped data from lists.
@@ -1,6 +1,7 @@
1
1
  # Implementation Plan: OSS Governance Baseline
2
2
 
3
3
  **Status:** Approved — decisions recorded (2026-07-29)
4
+ **Roadmap issue:** https://github.com/FlourishHealth/terreno/issues/1003
4
5
  **Priority:** High
5
6
  **Effort:** Small batch
6
7
  **Owner:** unassigned