@terreno/mcp 57.3.0 → 57.4.0

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 (250) hide show
  1. package/README.md +7 -1
  2. package/dist/bootstrap.d.ts +0 -18
  3. package/dist/bootstrap.d.ts.map +1 -1
  4. package/dist/bootstrap.js +10 -2428
  5. package/dist/bootstrap.js.map +1 -1
  6. package/dist/docs/guidelines/admin-frontend/guidelines/core.md +5 -1
  7. package/dist/docs/guidelines/api/skills/mongoose-schema-safety/SKILL.md +23 -10
  8. package/dist/docs/resources/syncdb.md +4 -1
  9. package/dist/docs/upgrades/57.4.0.md +140 -0
  10. package/dist/docs/versioned/next/README.md +3 -0
  11. package/dist/docs/versioned/next/explanation/README.md +4 -1
  12. package/dist/docs/versioned/next/explanation/admin-interface.md +20 -13
  13. package/dist/docs/versioned/next/explanation/charts.md +29 -0
  14. package/dist/docs/versioned/next/explanation/deployment-architecture-gcp.md +32 -0
  15. package/dist/docs/versioned/next/explanation/deployment-baseline.md +1 -1
  16. package/dist/docs/versioned/next/explanation/example-coverage.md +43 -0
  17. package/dist/docs/versioned/next/explanation/local-first-data.md +5 -2
  18. package/dist/docs/versioned/next/explanation/loop-engineering.md +9 -6
  19. package/dist/docs/versioned/next/explanation/model-router-actions.md +19 -2
  20. package/dist/docs/versioned/next/explanation/organizations.md +88 -0
  21. package/dist/docs/versioned/next/explanation/planning-plugins.md +114 -0
  22. package/dist/docs/versioned/next/explanation/positioning.md +3 -3
  23. package/dist/docs/versioned/next/explanation/repository-settings.md +6 -5
  24. package/dist/docs/versioned/next/explanation/roadmap-seed-issues.md +44 -34
  25. package/dist/docs/versioned/next/explanation/source-rules.md +1 -1
  26. package/dist/docs/versioned/next/explanation/static-analysis.md +76 -16
  27. package/dist/docs/versioned/next/how-to/README.md +10 -0
  28. package/dist/docs/versioned/next/how-to/add-gpt-chat-mascot.md +92 -0
  29. package/dist/docs/versioned/next/how-to/add-organizations.md +204 -0
  30. package/dist/docs/versioned/next/how-to/admin-add-model.md +9 -1
  31. package/dist/docs/versioned/next/how-to/admin-import-prebuilt.md +7 -1
  32. package/dist/docs/versioned/next/how-to/audit-log.md +85 -0
  33. package/dist/docs/versioned/next/how-to/background-jobs.md +296 -0
  34. package/dist/docs/versioned/next/how-to/build-admin-screens.md +42 -13
  35. package/dist/docs/versioned/next/how-to/charts-and-dashboards.md +37 -0
  36. package/dist/docs/versioned/next/how-to/circleci.md +136 -27
  37. package/dist/docs/versioned/next/how-to/compare-chart-rendered-snapshots.md +36 -0
  38. package/dist/docs/versioned/next/how-to/configure-better-auth.md +4 -0
  39. package/dist/docs/versioned/next/how-to/create-a-terreno-app.md +154 -0
  40. package/dist/docs/versioned/next/how-to/deploy-backend-to-cloud-run.md +2 -0
  41. package/dist/docs/versioned/next/how-to/github-actions-ci.md +4 -3
  42. package/dist/docs/versioned/next/how-to/github-issue-lifecycle.md +12 -8
  43. package/dist/docs/versioned/next/how-to/in-app-notifications.md +147 -0
  44. package/dist/docs/versioned/next/how-to/install-agent-skills.md +24 -12
  45. package/dist/docs/versioned/next/how-to/migrate-rtk-to-syncdb.md +19 -3
  46. package/dist/docs/versioned/next/how-to/product-announcements.md +155 -0
  47. package/dist/docs/versioned/next/how-to/run-mongodb-migrations.md +127 -0
  48. package/dist/docs/versioned/next/how-to/run-tests-locally.md +102 -0
  49. package/dist/docs/versioned/next/how-to/seed-a-database.md +7 -2
  50. package/dist/docs/versioned/next/implementationPlans/README.md +8 -5
  51. package/dist/docs/versioned/next/implementationPlans/admin-scripts-durable-jobs.md +44 -0
  52. package/dist/docs/versioned/next/implementationPlans/agent-ui-blocks.md +386 -0
  53. package/dist/docs/versioned/next/implementationPlans/agentic-sdlc-plugin.md +11 -8
  54. package/dist/docs/versioned/next/implementationPlans/announcements-surfaces.md +231 -0
  55. package/dist/docs/versioned/next/implementationPlans/announcements.md +289 -0
  56. package/dist/docs/versioned/next/implementationPlans/b2b-platform-program.md +3 -1
  57. package/dist/docs/versioned/next/implementationPlans/charts-and-dashboards.md +246 -0
  58. package/dist/docs/versioned/next/implementationPlans/comms-admin-dashboard.md +4 -3
  59. package/dist/docs/versioned/next/implementationPlans/create-terreno-app.md +177 -0
  60. package/dist/docs/versioned/next/implementationPlans/datatable-server-side-filtering.md +219 -0
  61. package/dist/docs/versioned/next/implementationPlans/examples-demo-coverage.md +17 -17
  62. package/dist/docs/versioned/next/implementationPlans/framework-audit-log.md +247 -0
  63. package/dist/docs/versioned/next/implementationPlans/gpt-chat-mascot.md +40 -0
  64. package/dist/docs/versioned/next/implementationPlans/job-queues.md +330 -0
  65. package/dist/docs/versioned/next/implementationPlans/knip-cleanup.md +136 -0
  66. package/dist/docs/versioned/next/implementationPlans/migrate-admin-to-syncdb.md +210 -0
  67. package/dist/docs/versioned/next/implementationPlans/mongodb-migrations-tooling.md +254 -0
  68. package/dist/docs/versioned/next/implementationPlans/notification-center.md +185 -0
  69. package/dist/docs/versioned/next/implementationPlans/org-management-ui.md +8 -3
  70. package/dist/docs/versioned/next/implementationPlans/positioning-django-rails-universal.md +1 -1
  71. package/dist/docs/versioned/next/reference/README.md +4 -0
  72. package/dist/docs/versioned/next/reference/admin-backend.md +83 -5
  73. package/dist/docs/versioned/next/reference/admin-config.md +7 -0
  74. package/dist/docs/versioned/next/reference/admin-frontend.md +178 -5
  75. package/dist/docs/versioned/next/reference/admin-spa.md +18 -1
  76. package/dist/docs/versioned/next/reference/ai.md +2 -0
  77. package/dist/docs/versioned/next/reference/announcements.md +179 -0
  78. package/dist/docs/versioned/next/reference/api.md +343 -4
  79. package/dist/docs/versioned/next/reference/comms.md +33 -0
  80. package/dist/docs/versioned/next/reference/create-terreno-app.md +44 -0
  81. package/dist/docs/versioned/next/reference/environment-variables.md +29 -0
  82. package/dist/docs/versioned/next/reference/jobs.md +319 -0
  83. package/dist/docs/versioned/next/reference/legacy/rtk.md +5 -1
  84. package/dist/docs/versioned/next/reference/lifecycle-plugin.md +29 -11
  85. package/dist/docs/versioned/next/reference/mcp-server.md +2 -43
  86. package/dist/docs/versioned/next/reference/scan-plugin.md +169 -0
  87. package/dist/docs/versioned/next/reference/syncdb.md +38 -12
  88. package/dist/docs/versioned/next/reference/test.md +57 -6
  89. package/dist/docs/versioned/next/reference/ui-performance.md +2 -1
  90. package/dist/docs/versioned/next/reference/ui.md +257 -3
  91. package/dist/docs/versioned/next/tasks/admin-scripts-durable-jobs.md +10 -0
  92. package/dist/docs/versioned/next/tasks/agent-ui-blocks.md +114 -0
  93. package/dist/docs/versioned/next/tasks/announcements-surfaces.md +101 -0
  94. package/dist/docs/versioned/next/tasks/announcements.md +173 -0
  95. package/dist/docs/versioned/next/tasks/charts-and-dashboards.md +120 -0
  96. package/dist/docs/versioned/next/tasks/create-terreno-app.md +82 -0
  97. package/dist/docs/versioned/next/tasks/datatable-server-side-filtering.md +87 -0
  98. package/dist/docs/versioned/next/tasks/examples-demo-coverage.md +123 -17
  99. package/dist/docs/versioned/next/tasks/framework-audit-log.md +86 -0
  100. package/dist/docs/versioned/next/tasks/gpt-chat-mascot.md +13 -0
  101. package/dist/docs/versioned/next/tasks/job-queues.md +144 -0
  102. package/dist/docs/versioned/next/tasks/knip-cleanup.md +146 -0
  103. package/dist/docs/versioned/next/tasks/migrate-admin-to-syncdb.md +209 -0
  104. package/dist/docs/versioned/next/tasks/mongodb-migrations-tooling.md +107 -0
  105. package/dist/docs/versioned/next/tasks/notification-center.md +102 -0
  106. package/dist/docs/versioned/next/tasks/org-management-ui.md +14 -14
  107. package/dist/docs/versioned/next/tutorials/README.md +1 -1
  108. package/dist/docs/versioned/next/tutorials/getting-started.md +62 -22
  109. package/dist/help/excerpt.d.ts +2 -0
  110. package/dist/help/excerpt.d.ts.map +1 -0
  111. package/dist/help/excerpt.js +8 -0
  112. package/dist/help/excerpt.js.map +1 -0
  113. package/dist/help/updateNotes.d.ts +42 -0
  114. package/dist/help/updateNotes.d.ts.map +1 -0
  115. package/dist/help/updateNotes.js +235 -0
  116. package/dist/help/updateNotes.js.map +1 -0
  117. package/dist/index.js +1 -1
  118. package/dist/index.js.map +1 -1
  119. package/dist/local/tools/databaseQuery.d.ts +1 -0
  120. package/dist/local/tools/databaseQuery.d.ts.map +1 -1
  121. package/dist/local/tools/databaseQuery.js +1 -0
  122. package/dist/local/tools/databaseQuery.js.map +1 -1
  123. package/dist/packageGuidelines.d.ts +2 -2
  124. package/dist/packageGuidelines.d.ts.map +1 -1
  125. package/dist/packageGuidelines.js +2 -8
  126. package/dist/packageGuidelines.js.map +1 -1
  127. package/dist/resources.d.ts +3 -0
  128. package/dist/resources.d.ts.map +1 -1
  129. package/dist/resources.js +3 -0
  130. package/dist/resources.js.map +1 -1
  131. package/dist/search/chunker.d.ts +1 -0
  132. package/dist/search/chunker.d.ts.map +1 -1
  133. package/dist/search/chunker.js +1 -0
  134. package/dist/search/chunker.js.map +1 -1
  135. package/dist/search/docIndex.d.ts +1 -5
  136. package/dist/search/docIndex.d.ts.map +1 -1
  137. package/dist/search/docIndex.js +1 -0
  138. package/dist/search/docIndex.js.map +1 -1
  139. package/dist/search/docVersion.d.ts +2 -1
  140. package/dist/search/docVersion.d.ts.map +1 -1
  141. package/dist/search/docVersion.js +3 -1
  142. package/dist/search/docVersion.js.map +1 -1
  143. package/dist/tools.d.ts +2 -2
  144. package/dist/tools.d.ts.map +1 -1
  145. package/dist/tools.js +113 -2
  146. package/dist/tools.js.map +1 -1
  147. package/package.json +28 -27
  148. package/src/docs/guidelines/admin-frontend/guidelines/core.md +5 -1
  149. package/src/docs/guidelines/api/skills/mongoose-schema-safety/SKILL.md +23 -10
  150. package/src/docs/resources/syncdb.md +4 -1
  151. package/src/docs/upgrades/57.4.0.md +140 -0
  152. package/src/docs/versioned/next/README.md +3 -0
  153. package/src/docs/versioned/next/explanation/README.md +4 -1
  154. package/src/docs/versioned/next/explanation/admin-interface.md +20 -13
  155. package/src/docs/versioned/next/explanation/charts.md +29 -0
  156. package/src/docs/versioned/next/explanation/deployment-architecture-gcp.md +32 -0
  157. package/src/docs/versioned/next/explanation/deployment-baseline.md +1 -1
  158. package/src/docs/versioned/next/explanation/example-coverage.md +43 -0
  159. package/src/docs/versioned/next/explanation/local-first-data.md +5 -2
  160. package/src/docs/versioned/next/explanation/loop-engineering.md +9 -6
  161. package/src/docs/versioned/next/explanation/model-router-actions.md +19 -2
  162. package/src/docs/versioned/next/explanation/organizations.md +88 -0
  163. package/src/docs/versioned/next/explanation/planning-plugins.md +114 -0
  164. package/src/docs/versioned/next/explanation/positioning.md +3 -3
  165. package/src/docs/versioned/next/explanation/repository-settings.md +6 -5
  166. package/src/docs/versioned/next/explanation/roadmap-seed-issues.md +44 -34
  167. package/src/docs/versioned/next/explanation/source-rules.md +1 -1
  168. package/src/docs/versioned/next/explanation/static-analysis.md +76 -16
  169. package/src/docs/versioned/next/how-to/README.md +10 -0
  170. package/src/docs/versioned/next/how-to/add-gpt-chat-mascot.md +92 -0
  171. package/src/docs/versioned/next/how-to/add-organizations.md +204 -0
  172. package/src/docs/versioned/next/how-to/admin-add-model.md +9 -1
  173. package/src/docs/versioned/next/how-to/admin-import-prebuilt.md +7 -1
  174. package/src/docs/versioned/next/how-to/audit-log.md +85 -0
  175. package/src/docs/versioned/next/how-to/background-jobs.md +296 -0
  176. package/src/docs/versioned/next/how-to/build-admin-screens.md +42 -13
  177. package/src/docs/versioned/next/how-to/charts-and-dashboards.md +37 -0
  178. package/src/docs/versioned/next/how-to/circleci.md +136 -27
  179. package/src/docs/versioned/next/how-to/compare-chart-rendered-snapshots.md +36 -0
  180. package/src/docs/versioned/next/how-to/configure-better-auth.md +4 -0
  181. package/src/docs/versioned/next/how-to/create-a-terreno-app.md +154 -0
  182. package/src/docs/versioned/next/how-to/deploy-backend-to-cloud-run.md +2 -0
  183. package/src/docs/versioned/next/how-to/github-actions-ci.md +4 -3
  184. package/src/docs/versioned/next/how-to/github-issue-lifecycle.md +12 -8
  185. package/src/docs/versioned/next/how-to/in-app-notifications.md +147 -0
  186. package/src/docs/versioned/next/how-to/install-agent-skills.md +24 -12
  187. package/src/docs/versioned/next/how-to/migrate-rtk-to-syncdb.md +19 -3
  188. package/src/docs/versioned/next/how-to/product-announcements.md +155 -0
  189. package/src/docs/versioned/next/how-to/run-mongodb-migrations.md +127 -0
  190. package/src/docs/versioned/next/how-to/run-tests-locally.md +102 -0
  191. package/src/docs/versioned/next/how-to/seed-a-database.md +7 -2
  192. package/src/docs/versioned/next/implementationPlans/README.md +8 -5
  193. package/src/docs/versioned/next/implementationPlans/admin-scripts-durable-jobs.md +44 -0
  194. package/src/docs/versioned/next/implementationPlans/agent-ui-blocks.md +386 -0
  195. package/src/docs/versioned/next/implementationPlans/agentic-sdlc-plugin.md +11 -8
  196. package/src/docs/versioned/next/implementationPlans/announcements-surfaces.md +231 -0
  197. package/src/docs/versioned/next/implementationPlans/announcements.md +289 -0
  198. package/src/docs/versioned/next/implementationPlans/b2b-platform-program.md +3 -1
  199. package/src/docs/versioned/next/implementationPlans/charts-and-dashboards.md +246 -0
  200. package/src/docs/versioned/next/implementationPlans/comms-admin-dashboard.md +4 -3
  201. package/src/docs/versioned/next/implementationPlans/create-terreno-app.md +177 -0
  202. package/src/docs/versioned/next/implementationPlans/datatable-server-side-filtering.md +219 -0
  203. package/src/docs/versioned/next/implementationPlans/examples-demo-coverage.md +17 -17
  204. package/src/docs/versioned/next/implementationPlans/framework-audit-log.md +247 -0
  205. package/src/docs/versioned/next/implementationPlans/gpt-chat-mascot.md +40 -0
  206. package/src/docs/versioned/next/implementationPlans/job-queues.md +330 -0
  207. package/src/docs/versioned/next/implementationPlans/knip-cleanup.md +136 -0
  208. package/src/docs/versioned/next/implementationPlans/migrate-admin-to-syncdb.md +210 -0
  209. package/src/docs/versioned/next/implementationPlans/mongodb-migrations-tooling.md +254 -0
  210. package/src/docs/versioned/next/implementationPlans/notification-center.md +185 -0
  211. package/src/docs/versioned/next/implementationPlans/org-management-ui.md +8 -3
  212. package/src/docs/versioned/next/implementationPlans/positioning-django-rails-universal.md +1 -1
  213. package/src/docs/versioned/next/reference/README.md +4 -0
  214. package/src/docs/versioned/next/reference/admin-backend.md +83 -5
  215. package/src/docs/versioned/next/reference/admin-config.md +7 -0
  216. package/src/docs/versioned/next/reference/admin-frontend.md +178 -5
  217. package/src/docs/versioned/next/reference/admin-spa.md +18 -1
  218. package/src/docs/versioned/next/reference/ai.md +2 -0
  219. package/src/docs/versioned/next/reference/announcements.md +179 -0
  220. package/src/docs/versioned/next/reference/api.md +343 -4
  221. package/src/docs/versioned/next/reference/comms.md +33 -0
  222. package/src/docs/versioned/next/reference/create-terreno-app.md +44 -0
  223. package/src/docs/versioned/next/reference/environment-variables.md +29 -0
  224. package/src/docs/versioned/next/reference/jobs.md +319 -0
  225. package/src/docs/versioned/next/reference/legacy/rtk.md +5 -1
  226. package/src/docs/versioned/next/reference/lifecycle-plugin.md +29 -11
  227. package/src/docs/versioned/next/reference/mcp-server.md +2 -43
  228. package/src/docs/versioned/next/reference/scan-plugin.md +169 -0
  229. package/src/docs/versioned/next/reference/syncdb.md +38 -12
  230. package/src/docs/versioned/next/reference/test.md +57 -6
  231. package/src/docs/versioned/next/reference/ui-performance.md +2 -1
  232. package/src/docs/versioned/next/reference/ui.md +257 -3
  233. package/src/docs/versioned/next/tasks/admin-scripts-durable-jobs.md +10 -0
  234. package/src/docs/versioned/next/tasks/agent-ui-blocks.md +114 -0
  235. package/src/docs/versioned/next/tasks/announcements-surfaces.md +101 -0
  236. package/src/docs/versioned/next/tasks/announcements.md +173 -0
  237. package/src/docs/versioned/next/tasks/charts-and-dashboards.md +120 -0
  238. package/src/docs/versioned/next/tasks/create-terreno-app.md +82 -0
  239. package/src/docs/versioned/next/tasks/datatable-server-side-filtering.md +87 -0
  240. package/src/docs/versioned/next/tasks/examples-demo-coverage.md +123 -17
  241. package/src/docs/versioned/next/tasks/framework-audit-log.md +86 -0
  242. package/src/docs/versioned/next/tasks/gpt-chat-mascot.md +13 -0
  243. package/src/docs/versioned/next/tasks/job-queues.md +144 -0
  244. package/src/docs/versioned/next/tasks/knip-cleanup.md +146 -0
  245. package/src/docs/versioned/next/tasks/migrate-admin-to-syncdb.md +209 -0
  246. package/src/docs/versioned/next/tasks/mongodb-migrations-tooling.md +107 -0
  247. package/src/docs/versioned/next/tasks/notification-center.md +102 -0
  248. package/src/docs/versioned/next/tasks/org-management-ui.md +14 -14
  249. package/src/docs/versioned/next/tutorials/README.md +1 -1
  250. package/src/docs/versioned/next/tutorials/getting-started.md +62 -22
@@ -49,8 +49,10 @@ the inner loop until the approved task list is done. Roast never invokes Pick. B
49
49
  Taste additionally wait while async review bots are running, preferring provider CLI
50
50
  watch hooks or harness event subscriptions over timer polling. Taste also waits in a
51
51
  loop for product CI with `gh` or `circleci` until jobs are terminal or the wait times
52
- out. Before any push it always pulls latest `master`, then lints in a no-context
53
- subagent, then pushes and watches CI.
52
+ out. Before any push it always pulls latest `master`, then records last-run failed tests
53
+ and re-verifies them locally, then runs the repository's root
54
+ `prepush` package script in a no-context subagent when present (falling back to affected
55
+ package lint, typecheck, and tests), then pushes and watches CI.
54
56
 
55
57
  Invocable outer loops in the plugin:
56
58
 
@@ -81,9 +83,10 @@ daemon. It waits until async review bots (Bugbot, CodeQL, and similar) on the cu
81
83
  head have reported, then waits in a loop for product CI using GitHub CLI
82
84
  (`gh pr checks --watch`, `gh run watch`) or CircleCI CLI (`circleci run watch`) until
83
85
  jobs are terminal or the wait times out. Before any push it always pulls latest
84
- `master`, then proves lint, typecheck, and affected tests in a fresh subagent with no
85
- parent conversation, then pushes and watches CI. It emits `PASS`, `FAIL`, `BLOCKED`, or
86
- `PENDING`, and exits.
86
+ `master`, records last-run failed tests and re-verifies them locally, then runs root
87
+ `prepush` when present in a fresh subagent with no parent
88
+ conversation. If absent, it proves affected-package lint, typecheck, and tests instead.
89
+ It then pushes and watches CI, emits `PASS`, `FAIL`, `BLOCKED`, or `PENDING`, and exits.
87
90
 
88
91
  Brew review-bot waits use only hooks targeted to the matched bot so ordinary CI cannot
89
92
  extend Brew. Taste's product-CI wait uses unfiltered GitHub/CircleCI watches on purpose.
@@ -118,7 +121,7 @@ include:
118
121
  | UI/app | `terreno-ui`, `building-terreno-apps`, `verify-ui-changes` |
119
122
  | AI/prompts | `ai-prompt-governance` |
120
123
  | Docs/submission | `update-docs`, Brew, `fix-conflicts` |
121
- | GitHub issues | `create-github-issue`, `work-github-issues`, `implement-ready-for-dev` (Pick plan comment is the Roast contract) |
124
+ | GitHub issues | `create-github-issue`, `work-github-issues`, `implement-ready-for-dev` (Pick plan comment is the Roast contract; unattended Grow may also write an IP) |
122
125
  | Deployment/runtime | `deploy-gcp`, Expo deployment/workflow skills |
123
126
 
124
127
  This inventory is descriptive, not a plugin dependency list. Stages inspect the actual
@@ -6,18 +6,35 @@ CRUD **create, update, and delete** (not named actions) share one write pipeline
6
6
 
7
7
  ## When to use actions
8
8
 
9
+ Use `collectionActions` / `instanceActions` for every application GET or POST that is not
10
+ plain document CRUD. Do **not** register `app.get`, `app.post`, `router.get`, or
11
+ `router.post` for those endpoints.
12
+
9
13
  Use actions when an endpoint performs an operation that is not a plain create/read/update/delete on the model document:
10
14
 
11
15
  - **Collection scope** (`POST /todos/bulkComplete`) — operate on many documents or the collection as a whole.
12
16
  - **Instance scope** (`POST /todos/:id/markComplete`) — operate on one loaded document.
13
17
 
14
- Use [custom routes with `createOpenApiBuilder`](./modular-api-design.md) when the URL does not fit the `/:id/{actionName}` or `/{actionName}` pattern.
18
+ Leave Express `app.get` / `app.post` only for:
19
+
20
+ - Inbound webhooks (`WebhooksApp`)
21
+ - Static SPA / file serving
22
+ - Framework auth, health, and version-check plugins
23
+ - SSE or other streaming handlers that write the response themselves
24
+ - Tests and harnesses
25
+
26
+ PATCH and DELETE are CRUD (or a POST action that performs the same work). Do not add a
27
+ hand-rolled DELETE next to a modelRouter.
28
+
29
+ Use [custom routes with `createOpenApiBuilder`](./modular-api-design.md) only when the
30
+ URL cannot be `/{actionName}` or `/:id/{actionName}` **and** the exceptions above do not
31
+ apply.
15
32
 
16
33
  ## Example
17
34
 
18
35
  ```typescript
19
36
  import {modelRouter, Permissions, z} from "@terreno/api";
20
- import {Todo} from "../models";
37
+ import {Todo} from "../models/todo";
21
38
 
22
39
  export const todoRouter = modelRouter("/todos", Todo, {
23
40
  permissions: {
@@ -0,0 +1,88 @@
1
+ # How organization tenancy works
2
+
3
+ Terreno treats organizations as an optional framework primitive. Existing
4
+ single-tenant apps do not pay a migration or authorization cost; multi-tenant
5
+ apps opt in at the access, application, model, and admin layers. New apps
6
+ generated by `create-terreno-app` opt in by default.
7
+
8
+ ## Identity and authorization layers
9
+
10
+ Platform and tenant authority are separate:
11
+
12
+ | Authority | Storage | Scope |
13
+ | --- | --- | --- |
14
+ | `superadmin` | `User.roles` | Every framework permission |
15
+ | `operator` | `User.roles` | Organization directory and every organization |
16
+ | `org-admin` | `Membership.roleName` | One organization |
17
+ | `member` | `Membership.roleName` | One organization; app permissions decide actions |
18
+
19
+ `user.admin` does not imply operator access. `org-admin` is deliberately not a
20
+ global RBAC role: putting it on `User.roles` grants nothing. During an
21
+ organization request, `createAccess({organizations: true})` adds the current
22
+ active Membership grants to the normal role permissions.
23
+
24
+ ## Request context
25
+
26
+ Tenant routes resolve `X-Organization-Id` after authentication. An operator or
27
+ superadmin may enter any organization but must choose one. An org-admin with
28
+ exactly one administered organization may omit the header; Terreno infers it.
29
+ Ambiguous or unauthorized context fails before model queries run.
30
+
31
+ The resolved organization and membership are stored in AsyncLocalStorage as
32
+ well as `req.organization` / `req.membership`. This lets `OrgQueryFilter` add
33
+ the server-owned organization id without trusting a client query parameter.
34
+
35
+ ## Isolation boundaries
36
+
37
+ Tenant isolation uses multiple checks rather than one convention:
38
+
39
+ 1. `orgContextMiddleware({required: true})` rejects missing or unauthorized context.
40
+ 2. `OrgQueryFilter` ANDs the selected organization into list and search queries.
41
+ 3. `Permissions.IsOrganizationMember` rejects cross-org object reads and writes.
42
+ 4. Create hooks overwrite client-supplied organization ids.
43
+ 5. `orgScopedPlugin` rejects any post-create change to `organizationId` (REST, admin, sync, direct save).
44
+ 6. Sync scopes resolve active Membership rows and partition streams by organization.
45
+
46
+ `AdminApp({organizations: true})` applies these boundaries automatically to
47
+ admin models whose schema contains `organizationId`. Models without that path
48
+ remain platform-scoped.
49
+
50
+ ## Disabled organizations
51
+
52
+ When `Organization.disabled` is `true`, tenant context and membership mutations
53
+ stop, but operators can still manage the organization record itself:
54
+
55
+ | Surface | Disabled org behavior |
56
+ | --- | --- |
57
+ | `orgContextMiddleware` / inferred org context | 403 `Organization is disabled` |
58
+ | `GET /orgs/mine` | Disabled orgs omitted from the switcher list |
59
+ | `GET /orgs` (operator directory) | Disabled orgs still listed |
60
+ | `GET` / `PATCH /orgs/:id` | Allowed (operators use `PATCH` with `disabled: false` to re-enable) |
61
+ | `POST` / `PATCH` / `DELETE /orgs/:id/members` | 403 while disabled |
62
+ | Soft-deleted orgs | Still 404 everywhere |
63
+
64
+ Disabling or deleting an organization suspends its memberships. Re-enabling does
65
+ not automatically reactivate them.
66
+
67
+ ## Why organizations are optional
68
+
69
+ Automatically registering routes, roles, or Mongoose models would change
70
+ existing apps merely because they upgraded `@terreno/api`. Instead:
71
+
72
+ - `createAccess` omits Membership grants and the `operator` seed unless
73
+ `organizations: true`;
74
+ - `TerrenoApp` does not mount `/orgs` unless organizations are enabled;
75
+ - `AdminApp` does not scope models unless organizations are enabled;
76
+ - Organization and Membership Mongoose models register lazily on first use.
77
+ Apps add fields to `Organization.settings` with `createOrganizationSettingsSchema`
78
+ and `registerOrganizationSettings`, not by replacing the Organization model.
79
+
80
+ This keeps upgrades backward compatible while letting bootstrap generate
81
+ multi-tenant-ready apps.
82
+
83
+ ## Related
84
+
85
+ - [Add organizations](../how-to/add-organizations.md)
86
+ - [API reference](../reference/api.md#organizations)
87
+ - [Admin backend reference](../reference/admin-backend.md#organization-scoping)
88
+ - [Admin frontend reference](../reference/admin-frontend.md#orgdirectoryscreen)
@@ -0,0 +1,114 @@
1
+ # Planning plugins
2
+
3
+ Terreno ships its agentic workflows as **two host plugins**. They divide along one line:
4
+ the lifecycle plugin knows *how to build one approved thing correctly*, and the scan
5
+ plugin knows *what is worth building next and whether it worked*.
6
+
7
+ ```text
8
+ terreno-scan terreno (lifecycle)
9
+ ------------ -------------------
10
+ Aim charter a measurable goal
11
+ Sweep shard + map the repository
12
+ Sift reduce to verified findings
13
+ Plot slice findings into briefs ───► Grow shape IP + tasks
14
+ Pick ⇄ Roast build and prove
15
+ Brew submit the PR
16
+ Taste react to CI and review
17
+ Track re-measure, close findings ◄─── (merged)
18
+ ```
19
+
20
+ A scan never edits product code. The lifecycle never decides what the repository should
21
+ become. Every slice crosses that boundary exactly once, as an approved IP and task list.
22
+
23
+ ## terreno (lifecycle plugin)
24
+
25
+ Five bounded transitions plus three outer loops. Canonical source:
26
+ `plugins/terreno-planning/`; Claude Code consumes the generated `plugins/terreno-claude/`.
27
+
28
+ | Stage | Owns | PASS next |
29
+ | --- | --- | --- |
30
+ | Grow | Research, grilling, approved IP and dependency-aware task list, criterion → verification map | Pick |
31
+ | Pick | Implement one task, then Roast it, then take the next until the list is done | Roast, or Brew when done |
32
+ | Roast | Independently prove the current task against its criteria | Pick if tasks remain, else Brew |
33
+ | Brew | Final checks, commit, push, PR, evidence, CI trigger, wait for review bots | Taste |
34
+ | Taste | One reaction to the current head: bots, CI on every host, conflicts, comments | null or fresh Taste |
35
+
36
+ | Outer loop | Walks |
37
+ | --- | --- |
38
+ | `pick-roast-loop` | An approved plan through every Pick/Roast retry, one ledger, stop only at completion or a genuine human gate |
39
+ | `planning-loop` | Grow/Pick/Brew/Taste, restrictable with `phases=` |
40
+ | `taste-sweep` | Every open PR of yours that is conflicting or failing, until each is mergeable |
41
+
42
+ Full contract: [lifecycle plugin reference](../reference/lifecycle-plugin.md) and
43
+ [loop engineering](loop-engineering.md).
44
+
45
+ ## terreno-scan (scan plugin)
46
+
47
+ Five bounded transitions plus two outer loops. Canonical source: `plugins/terreno-scan/`;
48
+ Claude Code consumes the generated `plugins/terreno-scan-claude/`. It depends on the
49
+ lifecycle plugin — Plot hands every slice to Grow.
50
+
51
+ | Stage | Owns | PASS next |
52
+ | --- | --- | --- |
53
+ | Aim | Charter: metric with a command, measured baseline, dry-run detection rules, exclusions, validity rule, severity rubric, slice policy, review routing, budget | Sweep |
54
+ | Sweep | Run the rules, shard hits deterministically, map fresh workers into candidate findings | Sift |
55
+ | Sift | Dedupe, adversarially verify, drop what does not reproduce, rank, write the findings report | Plot, or Track when dry |
56
+ | Plot | Slice findings into PR-sized units with standalone Grow briefs | Track, handing off to Grow |
57
+ | Track | Re-measure the metric, close or reopen findings with evidence, record the round, choose the next move | Plot, Sweep, or null |
58
+
59
+ | Outer loop | Walks |
60
+ | --- | --- |
61
+ | `campaign` | Bounded rounds: Aim → Sweep → Sift → Plot → lifecycle → Track. Stops at every gate. |
62
+ | `loop` | Resident session: the same rounds, plus a heartbeat over open campaign PRs — route, answer review through Taste, fix red CI, Track merges — refilling work up to `wipLimit`. |
63
+
64
+ Full contract: [scan plugin reference](../reference/scan-plugin.md).
65
+
66
+ ## Which one to invoke
67
+
68
+ | Situation | Start with |
69
+ | --- | --- |
70
+ | You know what to build | `1-grow` |
71
+ | You have an approved plan and want it built | `pick-roast-loop` |
72
+ | A PR of yours is red or conflicting | `5-taste`, or `taste-sweep` for all of them |
73
+ | You know the outcome you want, not the work | `scan 1-aim` |
74
+ | You want that outcome pursued unattended | `scan loop` |
75
+
76
+ ## What each plugin persists
77
+
78
+ | Artifact | Owner | Committed |
79
+ | --- | --- | --- |
80
+ | IP and task list | Grow | yes |
81
+ | Execution state (`.terreno/pipeline/<slug>.json`) | Lifecycle outer loops | no |
82
+ | Charter (`docs/scans/<goal>/charter.md`) | Aim | yes |
83
+ | Findings report (`docs/scans/<goal>/round-<n>-findings.md`) | Sift | yes |
84
+ | Campaign state (`.terreno/scan/<goal>.json`) | Scan outer loops | no |
85
+
86
+ Both plugins emit the same shaped result — `v: 2`, `status` of `PASS` / `FAIL` /
87
+ `BLOCKED` / `PENDING`, a `next`, and a concrete `action` — in a collapsed details block,
88
+ with `status` / `next` / `action` as the visible lines. Neither persists
89
+ chain-of-thought.
90
+
91
+ ## Why the split
92
+
93
+ Three properties fall out of keeping discovery and delivery in separate plugins:
94
+
95
+ - **A finding must earn its slice.** Sift drops anything that cannot be tied to the
96
+ goal metric, so the lifecycle only ever receives work with a stated payoff.
97
+ - **Delivery rules stay in one place.** Review response, CI waiting, the pre-push gate,
98
+ and documentation obligations live in the lifecycle, so a scan cannot invent a
99
+ shortcut around them.
100
+ - **Progress is measured, not asserted.** Track re-runs the metric command after the
101
+ work merges, so "we improved it" is always a number with its command output.
102
+
103
+ ## Hosts
104
+
105
+ | Host | Lifecycle | Scan |
106
+ | --- | --- | --- |
107
+ | Cursor | `terreno-planning`, `/terreno-1-grow` | `terreno-scan`, `/terreno-scan-1-aim` |
108
+ | Codex | `terreno-planning`, `$terreno-1-grow` | `terreno-scan`, `$terreno-scan-1-aim` |
109
+ | Claude Code | `terreno`, `/terreno:1-grow` | `terreno-scan`, `/terreno-scan:1-aim` |
110
+
111
+ Install both from the marketplaces described in
112
+ [install agent skills](../how-to/install-agent-skills.md). Claude Code resolves a plugin
113
+ skill's command from its frontmatter `name`, which is why the two `*-claude/` trees are
114
+ generated with shortened names by `bun run skills:sync`.
@@ -103,8 +103,8 @@ your codebase is the 20% that is unique to your product.
103
103
 
104
104
  The analogy earns two honest caveats. First, Terreno targets a document store
105
105
  (MongoDB via Mongoose), not a relational ORM, and it has no migrations framework.
106
- Second, it is younger — several Django/Rails staples (background jobs,
107
- server-side rendering, role-based access control) are not shipped yet. The
106
+ Second, it is younger — several Django/Rails staples (server-side rendering,
107
+ role-based access control) are not shipped yet. The
108
108
  comparison table below is deliberately straight about where the analogy holds and
109
109
  where it does not; being honest about the gaps is what makes the analogy credible
110
110
  rather than marketing.
@@ -125,7 +125,7 @@ shipped" row links the implementation plan or roadmap item that tracks it.
125
125
  | Auth + permissions | Better Auth (`api/src/betterAuthApp.ts`) + `Permissions` (`api/src/permissions.ts`) | Fine-grained RBAC is in progress ([`rbac-permissions`](../implementationPlans/rbac-permissions.md)) |
126
126
  | Templates / views | `@terreno/ui` components — one universal codebase for iOS, Android, and web | Server-side rendering for web is not shipped yet ([`web-ssr-and-admin-spa`](../implementationPlans/web-ssr-and-admin-spa.md)) |
127
127
  | `manage.py` / generators | MCP server tools — the *tool* layer (`mcp-server/src/tools.ts`) + the `/terreno-*` SDLC pipeline — the *process* layer (`plugins/terreno-planning/skills/`) | Agent-driven rather than CLI-driven; the pipeline is not yet packaged for consumer apps ([`agentic-sdlc-plugin`](../implementationPlans/agentic-sdlc-plugin.md) Task 2.5) |
128
- | Celery / ActiveJob (background jobs) | Not shipped | On the [roadmap](../../ROADMAP.md) |
128
+ | Celery / ActiveJob (background jobs) | `@terreno/jobs` `JobsApp` (`jobs/`) | [How-to](../how-to/background-jobs.md), [reference](../reference/jobs.md); optional GCP Cloud Tasks and Vercel Queues runners |
129
129
  | Migrations | No migrations framework | Schema evolution is convention plus the published `mongoose-schema-safety` skill |
130
130
 
131
131
  ## Language rules
@@ -31,8 +31,9 @@ descriptions):
31
31
  **Path:** Settings → Branches → Branch protection rules → `master`
32
32
 
33
33
  - Require a pull request before merging
34
- - Require status checks to pass (include Repository policies, package CI, and
35
- Rulesync Check jobs relevant to the change)
34
+ - Require status checks to pass (include CircleCI `repo-policies`, package CI,
35
+ and Rulesync Check jobs relevant to the change — see the check name map in
36
+ [how-to/circleci.md](../how-to/circleci.md))
36
37
  - Require branches to be up to date before merging
37
38
  - Do not allow bypassing the above settings
38
39
 
@@ -50,9 +51,9 @@ as GitHub App checks; they are not CircleCI jobs.
50
51
 
51
52
  **Path:** Settings → Environments
52
53
 
53
- Same-repo PR jobs in `cd.yml` (`Terraform preview`, `Backend deploy (preview)`)
54
- skip when `head.repo.full_name != github.repository`. Also restrict the
55
- `gcp-cd-preview` environment (create it on first deploy if missing) with a
54
+ Same-repo PR jobs in `cd.yml` (`Terraform preview`, `Tasks deploy (preview)`,
55
+ `Backend deploy (preview)`) skip when `head.repo.full_name != github.repository`.
56
+ Also restrict the `gcp-cd-preview` environment (create it on first deploy if missing) with a
56
57
  **deployment branch policy** or **required reviewers** so a fork that edits
57
58
  `cd.yml` cannot mint a prod WIF token.
58
59
 
@@ -553,7 +553,9 @@ org-admins manage only the current org. Invites and billing are design-only plac
553
553
 
554
554
  - **Implementation plan:** [org-management-ui.md](https://github.com/FlourishHealth/terreno/blob/master/docs/implementationPlans/org-management-ui.md)
555
555
  - **Tasks:** [org-management-ui.md](https://github.com/FlourishHealth/terreno/blob/master/docs/tasks/org-management-ui.md)
556
- - **RTK flag:** Partial — admin screens use generated SDK / `useAdminApi`
556
+ - **RTK flag:** Partial — custom non-synced routes use the generated SDK;
557
+ ObjectId admin compatibility may use `useAdminApi` in Terreno 57, while
558
+ eligible String-`_id` CRUD uses windowed syncdb
557
559
  - **Depends on:** rbac-permissions
558
560
 
559
561
  ---
@@ -605,15 +607,15 @@ same binary. Manifest finalized 2026-08-09 (decisions D1/D3/D7); TenTap excluded
605
607
  **Title:** `create-terreno-app scaffolding CLI`
606
608
 
607
609
  **Labels:** `area:dx`, `type:feature`
608
- **Project fields:** Area=`dx`, Target=`Next`, Impact=`Feature`, IP=*(not yet written)*, Status=`Planned`
610
+ **Project fields:** Area=`dx`, Target=`Next`, Impact=`Feature`, IP=`create-terreno-app`, Status=`In progress`
609
611
 
610
612
  Today the MCP bootstrap tool returns markdown instructions and writes no files. This ships
611
613
  a real `create-terreno-app` CLI (or template repo) that produces a running, deployable app
612
614
  — backend, Expo app, env files, seeded auth — in one command, with the MCP bootstrap
613
615
  delegating to it.
614
616
 
615
- - **Implementation plan:** *(not yet written)*
616
- - **Tasks:** *(not yet written)*
617
+ - **Implementation plan:** [create-terreno-app.md](https://github.com/FlourishHealth/terreno/blob/master/docs/implementationPlans/create-terreno-app.md)
618
+ - **Tasks:** [create-terreno-app.md](https://github.com/FlourishHealth/terreno/blob/master/docs/tasks/create-terreno-app.md)
617
619
  - **RTK flag:** Partial — scaffold output follows the syncdb + Better Auth direction
618
620
  - **Depends on:** deployment-foundation
619
621
 
@@ -624,15 +626,14 @@ delegating to it.
624
626
  **Title:** `Charts and dashboard primitives`
625
627
 
626
628
  **Labels:** `area:ui`, `type:feature`
627
- **Project fields:** Area=`ui`, Target=`Next`, Impact=`Feature`, IP=*(not yet written)*, Status=`Planned`
629
+ **Project fields:** Area=`ui`, Target=`Next`, Impact=`Feature`, IP=`charts-and-dashboards`, Status=`In progress`
628
630
 
629
- `@terreno/ui` has a stubbed `Chart` export and no implementation. Adds themed chart
630
- components (line, bar, area, donut) on `victory-native` — JS-only, since its Skia /
631
- Reanimated / Gesture Handler peers are already linked — plus a simple dashboard grid
632
- layout, with demo stories and docs.
631
+ `@terreno/ui` ships themed `LineChart`, `BarChart`, `AreaChart`, `DonutChart` on owned
632
+ `react-native-svg` (not `victory-native`) plus `DashboardGrid`. Demo stories and Diátaxis
633
+ docs are the proof; comms admin stats consume these primitives later.
633
634
 
634
- - **Implementation plan:** *(not yet written)*
635
- - **Tasks:** *(not yet written)*
635
+ - **Implementation plan:** [charts-and-dashboards.md](https://github.com/FlourishHealth/terreno/blob/master/docs/implementationPlans/charts-and-dashboards.md)
636
+ - **Tasks:** [charts-and-dashboards.md](https://github.com/FlourishHealth/terreno/blob/master/docs/tasks/charts-and-dashboards.md)
636
637
  - **RTK flag:** None
637
638
  - **Depends on:** —
638
639
 
@@ -662,14 +663,14 @@ root views and system chrome follow the scheme.
662
663
  **Title:** `DataTable server-side filtering and search`
663
664
 
664
665
  **Labels:** `area:ui`, `type:feature`
665
- **Project fields:** Area=`ui`, Target=`Next`, Impact=`Feature`, IP=*(not yet written)*, Status=`Planned`
666
+ **Project fields:** Area=`ui`, Target=`Next`, Impact=`Feature`, IP=`datatable-server-side-filtering`, Status=`Planned`
666
667
 
667
668
  DataTable sorts and paginates but has no filter UI. Adds per-column filter controls and a
668
669
  search box that emit modelRouter-compatible query params (`queryFields`, `$and`/`$or`), so
669
670
  list screens get server-side filtering without custom plumbing. Admin tables adopt it.
670
671
 
671
- - **Implementation plan:** *(not yet written)*
672
- - **Tasks:** *(not yet written)*
672
+ - **Implementation plan:** [datatable-server-side-filtering.md](../implementationPlans/datatable-server-side-filtering.md)
673
+ - **Tasks:** [datatable-server-side-filtering.md](../tasks/datatable-server-side-filtering.md)
673
674
  - **RTK flag:** Partial — query wiring examples depend on the frontend data layer
674
675
  - **Depends on:** —
675
676
 
@@ -699,14 +700,14 @@ native module baseline regardless, so this lands as a JS/OTA feature when schedu
699
700
  **Title:** `In-app notification center`
700
701
 
701
702
  **Labels:** `area:ui`, `type:feature`
702
- **Project fields:** Area=`ui`, Target=`Next`, Impact=`Feature`, IP=*(not yet written)*, Status=`Planned`
703
+ **Project fields:** Area=`ui`, Target=`Next`, Impact=`Feature`, IP=`notification-center` (Approved), Status=`Planned`
703
704
 
704
705
  Adds a Notification model with per-user preferences, realtime delivery over the existing
705
706
  change-stream socket layer, and a bell/inbox UI in `@terreno/ui` with read/unread state —
706
707
  the in-app channel beside `@terreno/comms` mail/SMS/push.
707
708
 
708
- - **Implementation plan:** *(not yet written)*
709
- - **Tasks:** *(not yet written)*
709
+ - **Implementation plan:** [notification-center.md](../implementationPlans/notification-center.md)
710
+ - **Tasks:** [notification-center.md](../tasks/notification-center.md)
710
711
  - **RTK flag:** Partial — inbox screens target the syncdb data layer where available
711
712
  - **Depends on:** comms-abstraction
712
713
 
@@ -826,17 +827,20 @@ enforcement hooks in the permission layer.
826
827
  **Title:** `Framework-level audit log`
827
828
 
828
829
  **Labels:** `area:api`, `type:feature`
829
- **Project fields:** Area=`api`, Target=`Next`, Impact=`Feature`, IP=*(not yet written)*, Status=`Planned`
830
+ **Project fields:** Area=`api`, Target=`Next`, Impact=`Feature`, IP=`framework-audit-log`, Status=`Planned`
830
831
 
831
832
  Generalizes the admin/consent audit patterns into a first-class audit log: an AuditEvent
832
833
  model, modelRouter hooks that record who changed what (with before/after diffs), org
833
834
  scoping, retention policy, and an admin viewer — a hard requirement for compliance-minded
834
835
  B2B customers.
835
836
 
836
- - **Implementation plan:** *(not yet written)*
837
- - **Tasks:** *(not yet written)*
837
+ Shipping this work **closes** https://github.com/FlourishHealth/terreno/issues/1186.
838
+
839
+ - **Implementation plan:** [framework-audit-log.md](https://github.com/FlourishHealth/terreno/blob/master/docs/implementationPlans/framework-audit-log.md)
840
+ - **Tasks:** [framework-audit-log.md](https://github.com/FlourishHealth/terreno/blob/master/docs/tasks/framework-audit-log.md)
841
+ - **How-to:** [audit-log.md](../how-to/audit-log.md)
838
842
  - **RTK flag:** None
839
- - **Depends on:** org-management-ui
843
+ - **Depends on:** — (optional `organizationId` now; org-admin list filter waits on org-management-ui)
840
844
 
841
845
  ---
842
846
 
@@ -866,15 +870,19 @@ Shipping this work **closes** https://github.com/FlourishHealth/terreno/issues/1
866
870
  **Title:** `Durable background jobs`
867
871
 
868
872
  **Labels:** `area:api`, `type:feature`
869
- **Project fields:** Area=`api`, Target=`Next`, Impact=`Feature`, IP=*(not yet written)*, Status=`Planned`
873
+ **Project fields:** Area=`api`, Target=`Released`, Impact=`Feature`, IP=`job-queues`, Status=`Shipped`
870
874
 
871
- Terreno has an in-process cron helper and admin script runner but no durable queue. Adds a
872
- job abstraction with retries, scheduling, and dead-lettering — Mongo-backed by default with
873
- a Redis/BullMQ driver — so email sends, webhook retries, and billing sync survive restarts.
875
+ Adds `@terreno/jobs`: Mongo-recorded jobs with retries, schedules, dead-lettering, in-process or
876
+ standalone workers, and pluggable runners (Mongo, GCP Cloud Tasks, Vercel Queues, custom).
877
+ Email/webhook/billing consumers enqueue later; this item ships the queue.
874
878
 
875
- - **Implementation plan:** *(not yet written)*
876
- - **Tasks:** *(not yet written)*
877
- - **RTK flag:** None
879
+ Shipping this work **closes** https://github.com/FlourishHealth/terreno/issues/1188.
880
+
881
+ - **Implementation plan:** [job-queues.md](https://github.com/FlourishHealth/terreno/blob/master/docs/implementationPlans/job-queues.md)
882
+ - **Tasks:** [job-queues.md](https://github.com/FlourishHealth/terreno/blob/master/docs/tasks/job-queues.md)
883
+ - **How-to:** [background-jobs.md](../how-to/background-jobs.md)
884
+ - **Reference:** [jobs.md](../reference/jobs.md)
885
+ - **RTK flag:** Partial — admin screens use generated SDK
878
886
  - **Depends on:** —
879
887
 
880
888
  ---
@@ -883,15 +891,17 @@ a Redis/BullMQ driver — so email sends, webhook retries, and billing sync surv
883
891
 
884
892
  **Title:** `MongoDB migrations tooling`
885
893
 
886
- **Labels:** `area:api`, `type:feature`
887
- **Project fields:** Area=`api`, Target=`Future`, Impact=`Feature`, IP=*(not yet written)*, Status=`Planned`
894
+ **Labels:** `area:api`, `type:feature`
895
+ **Project fields:** Area=`api`, Target=`Future`, Impact=`Feature`, IP=`mongodb-migrations-tooling`, Status=`Planned`
888
896
 
889
897
  A migrations runner for Terreno apps: versioned migration files, up/down with a lock
890
- collection, CI checks, and integration with the mongoose-schema-safety guidance — replacing
891
- ad-hoc backfill scripts.
898
+ collection, CI checks, CLI generate-from-schema-diff, optional boot apply, and an admin
899
+ Migrations page — replacing ad-hoc backfill scripts for once-per-environment schema changes.
892
900
 
893
- - **Implementation plan:** *(not yet written)*
894
- - **Tasks:** *(not yet written)*
901
+ Shipping this work **closes** https://github.com/FlourishHealth/terreno/issues/1189.
902
+
903
+ - **Implementation plan:** [mongodb-migrations-tooling.md](https://github.com/FlourishHealth/terreno/blob/master/docs/implementationPlans/mongodb-migrations-tooling.md)
904
+ - **Tasks:** [mongodb-migrations-tooling.md](https://github.com/FlourishHealth/terreno/blob/master/docs/tasks/mongodb-migrations-tooling.md)
895
905
  - **RTK flag:** None
896
906
  - **Depends on:** —
897
907
 
@@ -49,7 +49,7 @@ bun test scripts/check-source-rules/
49
49
  | Layer | What it does |
50
50
  | --- | --- |
51
51
  | **`bun run check:source-rules`** | Scans scoped production sources and fails on any remaining hit |
52
- | **Repository policies CI** | GitHub Actions job `Production source rules` (CircleCI twin `source-rules`) |
52
+ | **Repository policies CI** | CircleCI job `repo-policies` (includes `check:source-rules`) |
53
53
  | **`bun run check`** | Local aggregate that includes this scanner |
54
54
 
55
55
  A **new** production file that uses `export function`, `Date.now()`, `throw new Error`, `console.log`, `Model.findOne`, or unsuppressed `as any` fails CI.
@@ -3,6 +3,18 @@
3
3
  Run `bun run analyze:full` before pushing changes that alter imports, exports, package
4
4
  dependencies, or module boundaries.
5
5
 
6
+ Taste does not need to infer that policy in this repository. The root `prepush` package
7
+ script is the canonical local gate and runs lint, TypeScript compilation, and full static
8
+ analysis:
9
+
10
+ ```bash
11
+ bun run prepush
12
+ ```
13
+
14
+ The reusable Taste stage checks for a root `prepush` script before every push and runs it
15
+ in a fresh, no-context subagent. Repositories without one retain Taste's fallback:
16
+ package-level lint, typecheck, and locally affected tests.
17
+
6
18
  Terreno uses two analysis speeds so agents receive quick edit feedback without replacing
7
19
  repository-wide correctness checks with a partial changed-file scan.
8
20
 
@@ -12,7 +24,8 @@ repository-wide correctness checks with a partial changed-file scan.
12
24
  | --- | --- | --- | --- |
13
25
  | Biome | `bun run analyze:fast` | Changed and untracked analyzable files | Agent post-edit hooks |
14
26
  | Biome | `bun run analyze:staged` | Staged analyzable files | Git pre-commit |
15
- | Knip | `bun run analyze:full` | Both development and production module graphs | Agent stop hooks and CI |
27
+ | Knip | `bun run check:knip` | Both development and production module graphs | Dedicated GitHub workflow |
28
+ | Knip | `bun run analyze:full` | Both development and production module graphs | Agent stop hooks and CircleCI |
16
29
  | dependency-cruiser | `bun run analyze:full` | Workspace source dependency graph | Agent stop hooks and CI |
17
30
 
18
31
  Biome runs from the nearest workspace configuration. Knip finds unused files, exports,
@@ -26,28 +39,73 @@ development runs `bun run bootstrap`; without that exclusion, each package's com
26
39
  `dist/*.d.ts` entry point contributes unlisted-dependency findings that CI can never
27
40
  reproduce.
28
41
 
29
- ## Ratchets
42
+ ## Entry graph
43
+
44
+ Knip only follows files reachable from entries. Register executed-but-unimported files
45
+ in `knip.jsonc` `workspaces.<name>.entry` instead of deleting them or stuffing them into
46
+ the JSON baseline.
47
+
48
+ Setting `entry` **replaces** Knip’s default `{index,cli,main}` / `src/{index,cli,main}`
49
+ patterns for that workspace, so those defaults must be repeated next to extra globs.
50
+
51
+ | Kind | Why Knip misses it | Entry |
52
+ | --- | --- | --- |
53
+ | `*.isolated.ts(x)` | Run as `bun test $file`, not `*.test.ts` | `src/isolated/**/*.isolated.{ts,tsx}` on the owning package |
54
+ | `scripts/**/*.test.ts`, `.github/scripts/**/*.test.ts` | Root `test` is `bun run --filter '*' test:ci`, so the Bun plugin never loads them | Root workspace `"."` |
55
+ | `example-frontend/e2e/**/*.ts` | Playwright helpers and setup files are executed through project configuration, not app imports | `example-frontend` entry glob |
56
+ | Generated SDK contracts not yet imported by a screen | Codegen output is retained for compatibility verification | `ignoreFiles` for only the unused-file issue; exports and dependencies remain analyzed |
57
+ | OpenAPI codegen configs, Metro `jspdf` stubs, Expo fingerprint configs, Playwright CI config, `ui/babel.config.js`, Docusaurus `src/theme/**` swizzles, `scripts/ci/prepare-package-publish.mjs` | Invoked by Expo/Metro/Docusaurus/CI, not imported from app `index` | Extra `entry` globs on the owning workspace |
58
+ | Generated `expo-cicd-workflows/scripts/*.js` (including `.rulesync/`) | Skill copies; they import `ajv` / `js-yaml` outside this repo’s package graph | `ignore` globs |
59
+ | `example-backend` production dependencies | Knip's package-script entry for `bun run src/index.ts` shadows the explicit `src/index.ts!` entry in production mode | Keep default-mode enforcement; use exact dependency names suffixed with `!` as production-only exceptions |
60
+ | `mcp-server/src/__tests__/preload.ts` | `bunfig.toml` `test.preload`; Knip's Bun plugin is disabled for this workspace | `mcp-server` extra entry |
61
+
62
+ ## Runtime-only dependencies
63
+
64
+ Do not remove an Expo, React Native, or Metro dependency solely because Knip cannot find
65
+ a static import. Expo autolinking, `app.json` plugin strings, Metro aliases/polyfills,
66
+ platform-specific modules, and published UI peer surfaces load dependencies outside
67
+ Knip's source graph. Keep those dependencies in the owning `package.json` and list them
68
+ under that workspace's `ignoreDependencies` in `knip.jsonc`, with a comment naming the
69
+ runtime loader.
70
+
71
+ The same rule covers externally installed CLIs (`maestro`, `eas`), catalog pins retained
72
+ for native fingerprint compatibility, and optional peers consumed by published-package
73
+ users. Declare those narrowly with `ignoreBinaries` or `ignoreDependencies`; do not add a
74
+ fake local import.
75
+
76
+ ## Exports and test seams
77
+
78
+ Remove `export` from unused module internals. Keep published package-entry exports for
79
+ compatibility even when this monorepo has no consumer; suppress only their `exports` or
80
+ `types` issue on the defining file, with a public-API comment in `knip.jsonc`.
81
+
82
+ Some internal helpers are intentionally exported so tests can exercise deterministic
83
+ logic without widening the npm entry point. Mark those declarations `@internal`: default
84
+ Knip still proves that tests use them, while production mode excludes the test-only seam.
85
+ Generated SDK files use a path-scoped `ignoreIssues` entry instead of hand edits.
30
86
 
31
- The repository already contains findings that cannot be removed in one change. The
32
- checked-in baselines allow existing findings to remain while rejecting new ones:
87
+ ## Zero-finding policy
33
88
 
34
- - `scripts/static-analysis/knip-baseline.json`
35
- - `.dependency-cruiser-known-violations.json`
89
+ Knip has no baseline. `bun run check:knip` runs the default and production graphs and
90
+ fails on every finding. The dedicated `Knip / Zero findings` GitHub workflow runs this
91
+ command for every pull request and every push to `master`.
36
92
 
37
- Knip fingerprints omit line and column positions, so moving an existing declaration does
38
- not create a false regression. A renamed symbol, moved file, or new finding must be fixed
39
- or deliberately reviewed into the baseline.
93
+ Fix every Knip finding or add the narrowest justified exception to `knip.jsonc` with a
94
+ comment naming the runtime loader, public compatibility promise, generated source, or
95
+ tool limitation. Do not create a Knip baseline or any other separate finding inventory.
40
96
 
41
- After intentionally accepting repository-wide analysis changes, regenerate both
42
- baselines:
97
+ dependency-cruiser still uses `.dependency-cruiser-known-violations.json` to ratchet its
98
+ remaining findings. After intentionally accepting repository-wide dependency-graph
99
+ changes, regenerate only that baseline:
43
100
 
44
101
  ```bash
45
- bun run analyze:baseline
102
+ bun run analyze:dependency-baseline
46
103
  bun run analyze:full
47
104
  ```
48
105
 
49
- Review the baseline diff before committing it. Never run `knip --fix` unattended because
50
- an incomplete entry graph can remove runtime-loaded code.
106
+ Review the dependency-cruiser baseline diff before committing; findings may only stay
107
+ level or decrease. Never run `knip --fix` unattended because an incomplete entry graph
108
+ can remove runtime-loaded code.
51
109
 
52
110
  ## Agent hooks
53
111
 
@@ -56,7 +114,9 @@ native configuration for Cursor, Claude Code, Codex CLI, GitHub Copilot, Copilot
56
114
  Google Antigravity CLI, and Devin.
57
115
 
58
116
  Post-edit events run the changed-file Biome command. Stop events run both repository-wide
59
- ratchets. Hook failure and retry behavior differs by host, so CircleCI remains the merge
117
+ ratchets. `analyze:full` retries Knip without `--cache` when a concurrent stop-hook and
118
+ prepush run corrupt or lock the cache, so the stop hook does not fail with empty JSON.
119
+ Hook failure and retry behavior differs by host, so CircleCI remains the merge
60
120
  gate and the real Git pre-commit hook covers commits made outside an agent.
61
121
 
62
122
  `simple-git-hooks` installs the pre-commit hook during `bun install` through the root
@@ -69,7 +129,7 @@ gate and the real Git pre-commit hook covers commits made outside an agent.
69
129
  | `knip.jsonc` | Entry graph, plugins, generated-code exceptions |
70
130
  | `.dependency-cruiser.js` | Dependency rules and resolver conditions |
71
131
  | `.rulesync/hooks.json` | Canonical agent lifecycle hooks |
72
- | `scripts/static-analysis/` | Portable hook commands, ratchet logic, and tests |
132
+ | `scripts/static-analysis/` | Portable direct Knip checks, dependency ratchet logic, and tests |
73
133
 
74
134
  Generated agent hook files must not be edited directly. Change `.rulesync/hooks.json`,
75
135
  then run `bun run rules`.