vybekiit 0.7.29 → 0.7.32

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 (230) hide show
  1. package/dist/bin.js +3403 -2768
  2. package/dist/global-guidance/language.md +7 -102
  3. package/dist/global-skills/add-ai/SKILL.md +7 -8
  4. package/dist/global-skills/add-analytics/SKILL.md +4 -7
  5. package/dist/global-skills/add-app-clip/SKILL.md +1 -0
  6. package/dist/global-skills/add-blog/SKILL.md +4 -7
  7. package/dist/global-skills/add-files/SKILL.md +4 -7
  8. package/dist/global-skills/add-images/SKILL.md +4 -7
  9. package/dist/global-skills/add-language/SKILL.md +5 -8
  10. package/dist/global-skills/add-notifications/SKILL.md +4 -7
  11. package/dist/global-skills/add-realtime/SKILL.md +4 -7
  12. package/dist/global-skills/add-search/SKILL.md +4 -7
  13. package/dist/global-skills/add-signin/SKILL.md +4 -8
  14. package/dist/global-skills/add-teams/SKILL.md +4 -7
  15. package/dist/global-skills/aws-cdk/SKILL.md +1 -0
  16. package/dist/global-skills/aws-cloudformation/SKILL.md +1 -0
  17. package/dist/global-skills/aws-serverless/SKILL.md +1 -0
  18. package/dist/global-skills/aws-serverless/references/compute-decision-edge-cases.md +77 -0
  19. package/dist/global-skills/better-auth-best-practices/SKILL.md +1 -0
  20. package/dist/global-skills/better-auth-security-best-practices/SKILL.md +1 -0
  21. package/dist/global-skills/building-native-ui/SKILL.md +1 -0
  22. package/dist/global-skills/buy-domain/SKILL.md +4 -7
  23. package/dist/global-skills/check-safety/SKILL.md +5 -8
  24. package/dist/global-skills/claimable-postgres/SKILL.md +1 -0
  25. package/dist/global-skills/configure-capabilities/SKILL.md +1 -1
  26. package/dist/global-skills/connect-account/SKILL.md +1 -1
  27. package/dist/global-skills/create-auth-skill/SKILL.md +1 -0
  28. package/dist/global-skills/doctor/SKILL.md +1 -1
  29. package/dist/global-skills/eas-app-stores/SKILL.md +2 -1
  30. package/dist/global-skills/eas-app-stores/agents/openai.yaml +1 -1
  31. package/dist/global-skills/eas-hosting/SKILL.md +2 -1
  32. package/dist/global-skills/eas-hosting/agents/openai.yaml +1 -1
  33. package/dist/global-skills/eas-observe/SKILL.md +2 -1
  34. package/dist/global-skills/eas-observe/agents/openai.yaml +1 -1
  35. package/dist/global-skills/eas-simulator/SKILL.md +9 -1
  36. package/dist/global-skills/eas-simulator/agents/openai.yaml +1 -1
  37. package/dist/global-skills/eas-simulator/references/logs-and-crashes.md +101 -0
  38. package/dist/global-skills/eas-simulator/references/troubleshooting.md +4 -0
  39. package/dist/global-skills/eas-update/SKILL.md +2 -1
  40. package/dist/global-skills/eas-update/agents/openai.yaml +1 -1
  41. package/dist/global-skills/eas-update-insights/SKILL.md +2 -1
  42. package/dist/global-skills/eas-update-insights/agents/openai.yaml +1 -1
  43. package/dist/global-skills/eas-workflows/SKILL.md +2 -1
  44. package/dist/global-skills/eas-workflows/agents/openai.yaml +1 -1
  45. package/dist/global-skills/email-best-practices/SKILL.md +1 -0
  46. package/dist/global-skills/expo-animation/SKILL.md +2 -1
  47. package/dist/global-skills/expo-api-routes/SKILL.md +1 -0
  48. package/dist/global-skills/expo-app-clip/SKILL.md +2 -1
  49. package/dist/global-skills/expo-brownfield/SKILL.md +2 -1
  50. package/dist/global-skills/expo-cicd-workflows/SKILL.md +1 -0
  51. package/dist/global-skills/expo-data-fetching/SKILL.md +2 -1
  52. package/dist/global-skills/expo-deployment/SKILL.md +1 -0
  53. package/dist/global-skills/expo-design-system/SKILL.md +2 -1
  54. package/dist/global-skills/expo-dev-client/SKILL.md +2 -1
  55. package/dist/global-skills/expo-dom/SKILL.md +2 -1
  56. package/dist/global-skills/expo-examples/SKILL.md +2 -1
  57. package/dist/global-skills/expo-migrate-module/SKILL.md +2 -1
  58. package/dist/global-skills/expo-module/SKILL.md +2 -1
  59. package/dist/global-skills/expo-native-ui/SKILL.md +2 -1
  60. package/dist/global-skills/expo-observe/SKILL.md +1 -0
  61. package/dist/global-skills/expo-overview/SKILL.md +2 -1
  62. package/dist/global-skills/expo-project-structure/SKILL.md +2 -1
  63. package/dist/global-skills/expo-router/SKILL.md +2 -1
  64. package/dist/global-skills/expo-skill-eval/SKILL.md +1 -0
  65. package/dist/global-skills/expo-skill-feedback/SKILL.md +1 -0
  66. package/dist/global-skills/expo-tailwind-setup/SKILL.md +1 -0
  67. package/dist/global-skills/expo-ui/SKILL.md +2 -1
  68. package/dist/global-skills/expo-upgrade/SKILL.md +2 -1
  69. package/dist/global-skills/expo-web-to-native/SKILL.md +2 -1
  70. package/dist/global-skills/extension-to-functions-codebase/SKILL.md +1 -0
  71. package/dist/global-skills/firebase-ai-logic-basics/SKILL.md +1 -0
  72. package/dist/global-skills/firebase-ai-logic-basics/references/tts_generation.md +676 -0
  73. package/dist/global-skills/firebase-app-hosting-basics/SKILL.md +1 -0
  74. package/dist/global-skills/firebase-auth-basics/SKILL.md +11 -6
  75. package/dist/global-skills/firebase-auth-basics/references/client_sdk_android.md +61 -23
  76. package/dist/global-skills/firebase-basics/SKILL.md +2 -0
  77. package/dist/global-skills/firebase-basics/references/android_setup.md +165 -23
  78. package/dist/global-skills/firebase-crashlytics/SKILL.md +1 -0
  79. package/dist/global-skills/firebase-crashlytics/references/android_setup.md +147 -119
  80. package/dist/global-skills/firebase-data-connect/SKILL.md +1 -0
  81. package/dist/global-skills/firebase-data-connect/reference/sdk_android.md +81 -25
  82. package/dist/global-skills/firebase-firestore/SKILL.md +1 -0
  83. package/dist/global-skills/firebase-firestore/references/enterprise/android_sdk_usage.md +70 -44
  84. package/dist/global-skills/firebase-firestore/references/standard/android_sdk_usage.md +63 -27
  85. package/dist/global-skills/firebase-hosting-basics/SKILL.md +1 -0
  86. package/dist/global-skills/firebase-remote-config-basics/SKILL.md +1 -0
  87. package/dist/global-skills/firebase-remote-config-basics/references/android_setup.md +87 -95
  88. package/dist/global-skills/firebase-security-rules-auditor/SKILL.md +1 -0
  89. package/dist/global-skills/firestore-rules-creation/SKILL.md +1 -0
  90. package/dist/global-skills/go-live/SKILL.md +7 -7
  91. package/dist/global-skills/harden/SKILL.md +7 -10
  92. package/dist/global-skills/instrument-feature-flags/SKILL.md +1 -0
  93. package/dist/global-skills/instrument-product-analytics/SKILL.md +1 -0
  94. package/dist/global-skills/manifest.json +2 -1
  95. package/dist/global-skills/mongodb-atlas-stream-processing/SKILL.md +1 -0
  96. package/dist/global-skills/mongodb-connection/SKILL.md +1 -0
  97. package/dist/global-skills/mongodb-mcp-setup/SKILL.md +1 -0
  98. package/dist/global-skills/mongodb-natural-language-querying/SKILL.md +1 -0
  99. package/dist/global-skills/mongodb-qe-size-estimation/SKILL.md +224 -0
  100. package/dist/global-skills/mongodb-query-optimizer/SKILL.md +1 -0
  101. package/dist/global-skills/mongodb-schema-design/SKILL.md +1 -0
  102. package/dist/global-skills/mongodb-search-and-ai/SKILL.md +1 -0
  103. package/dist/global-skills/native-data-fetching/SKILL.md +1 -0
  104. package/dist/global-skills/neon/SKILL.md +18 -5
  105. package/dist/global-skills/neon-ai-gateway/SKILL.md +1 -0
  106. package/dist/global-skills/neon-auth/SKILL.md +1 -0
  107. package/dist/global-skills/neon-functions/SKILL.md +12 -0
  108. package/dist/global-skills/neon-functions/references/native-binaries.md +188 -0
  109. package/dist/global-skills/neon-object-storage/SKILL.md +1 -0
  110. package/dist/global-skills/neon-postgres/SKILL.md +1 -0
  111. package/dist/global-skills/neon-postgres-branches/SKILL.md +1 -0
  112. package/dist/global-skills/neon-postgres-egress-optimizer/SKILL.md +1 -0
  113. package/dist/global-skills/onboarding/SKILL.md +14 -13
  114. package/dist/global-skills/plan-my-idea/SKILL.md +1 -1
  115. package/dist/global-skills/publish-app/SKILL.md +1 -1
  116. package/dist/global-skills/publish-extension/SKILL.md +1 -1
  117. package/dist/global-skills/resend/SKILL.md +2 -1
  118. package/dist/global-skills/resend/references/webhooks.md +2 -0
  119. package/dist/global-skills/reset-password/SKILL.md +4 -6
  120. package/dist/global-skills/save-data/SKILL.md +3 -0
  121. package/dist/global-skills/sentry-sdk-setup/SKILL.md +1 -0
  122. package/dist/global-skills/sentry-workflow/SKILL.md +1 -0
  123. package/dist/global-skills/setup-email/SKILL.md +7 -8
  124. package/dist/global-skills/setup-payments/SKILL.md +10 -12
  125. package/dist/global-skills/setup-sms/SKILL.md +1 -1
  126. package/dist/global-skills/sign-in-with-email-link/SKILL.md +4 -6
  127. package/dist/global-skills/sign-in-with-google/SKILL.md +14 -13
  128. package/dist/global-skills/sign-in-with-phone/SKILL.md +5 -7
  129. package/dist/global-skills/stripe-best-practices/SKILL.md +2 -1
  130. package/dist/global-skills/stripe-best-practices/references/billing.md +2 -0
  131. package/dist/global-skills/stripe-best-practices/references/payments.md +1 -1
  132. package/dist/global-skills/stripe-best-practices/references/tax.md +2 -2
  133. package/dist/global-skills/supabase/CHANGELOG.md +19 -0
  134. package/dist/global-skills/supabase/SKILL.md +1 -0
  135. package/dist/global-skills/supabase-postgres-best-practices/SKILL.md +1 -0
  136. package/dist/global-skills/track-errors/SKILL.md +12 -13
  137. package/dist/global-skills/update-kit/SKILL.md +1 -1
  138. package/dist/global-skills/upgrading-expo/SKILL.md +1 -0
  139. package/dist/global-skills/use-dom/SKILL.md +1 -0
  140. package/dist/global-skills/use-railway/SKILL.md +6 -5
  141. package/dist/global-skills/use-railway/references/configure.md +34 -1
  142. package/dist/global-skills/use-railway/references/iac.md +2 -0
  143. package/dist/global-skills/use-railway/references/tracing.md +89 -44
  144. package/dist/global-skills/vercel-composition-patterns/SKILL.md +1 -0
  145. package/dist/global-skills/vercel-react-best-practices/SKILL.md +1 -0
  146. package/dist/global-skills/vybekiitReferences/backend/AGENTS.md +11 -3
  147. package/dist/global-skills/vybekiitReferences/backend/agent/goal-index.md +1 -1
  148. package/dist/global-skills/vybekiitReferences/backend/agent/goal-routes.json +229 -0
  149. package/dist/global-skills/vybekiitReferences/backend/agent/mcp-setup.md +11 -2
  150. package/dist/global-skills/vybekiitReferences/backend/agent/session-bootstrap.md +1 -1
  151. package/dist/global-skills/vybekiitReferences/backend/agent/tech-references.md +1 -1
  152. package/dist/global-skills/vybekiitReferences/backend/language.md +7 -102
  153. package/dist/global-skills/vybekiitReferences/backend/platform-skills/deploy-railway-vybekiit.md +2 -2
  154. package/dist/global-skills/vybekiitReferences/backend/platform-skills/extend-capabilities-vybekiit.md +1 -1
  155. package/dist/global-skills/vybekiitReferences/backend/platform-skills/mongodb-vybekiit.md +1 -1
  156. package/dist/global-skills/vybekiitReferences/extension/AGENTS.md +11 -3
  157. package/dist/global-skills/vybekiitReferences/extension/agent/goal-index.md +1 -1
  158. package/dist/global-skills/vybekiitReferences/extension/agent/goal-routes.json +239 -0
  159. package/dist/global-skills/vybekiitReferences/extension/agent/mcp-setup.md +10 -1
  160. package/dist/global-skills/vybekiitReferences/extension/agent/session-bootstrap.md +1 -1
  161. package/dist/global-skills/vybekiitReferences/extension/agent/tech-references.md +1 -1
  162. package/dist/global-skills/vybekiitReferences/extension/agent/ui-sources.md +11 -8
  163. package/dist/global-skills/vybekiitReferences/extension/language.md +7 -92
  164. package/dist/global-skills/vybekiitReferences/extension/platform-skills/browser-automation-vybekiit.md +9 -1
  165. package/dist/global-skills/vybekiitReferences/extension/platform-skills/env-secrets-vybekiit.md +1 -0
  166. package/dist/global-skills/vybekiitReferences/extension/platform-skills/extend-capabilities-vybekiit.md +1 -1
  167. package/dist/global-skills/vybekiitReferences/extension/platform-skills/observability-vybekiit.md +1 -1
  168. package/dist/global-skills/vybekiitReferences/extension/platform-skills/sentry-vybekiit.md +1 -1
  169. package/dist/global-skills/vybekiitReferences/mobile/AGENTS.md +27 -12
  170. package/dist/global-skills/vybekiitReferences/mobile/agent/goal-index.md +1 -1
  171. package/dist/global-skills/vybekiitReferences/mobile/agent/goal-routes.json +279 -0
  172. package/dist/global-skills/vybekiitReferences/mobile/agent/mcp-setup.md +10 -1
  173. package/dist/global-skills/vybekiitReferences/mobile/agent/session-bootstrap.md +1 -1
  174. package/dist/global-skills/vybekiitReferences/mobile/agent/tech-references.md +1 -1
  175. package/dist/global-skills/vybekiitReferences/mobile/agent/ui-sources.mobile.md +1 -1
  176. package/dist/global-skills/vybekiitReferences/mobile/language.md +7 -93
  177. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/env-secrets-vybekiit.md +1 -0
  178. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/extend-capabilities-vybekiit.md +1 -1
  179. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/i18n-vybekiit.md +1 -1
  180. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/observability-vybekiit.md +1 -1
  181. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/sentry-vybekiit.md +1 -1
  182. package/dist/global-skills/vybekiitReferences/mobile/platform-skills/ui-port-from-web-vybekiit.md +2 -2
  183. package/dist/global-skills/vybekiitReferences/spa/AGENTS.md +11 -3
  184. package/dist/global-skills/vybekiitReferences/spa/agent/goal-index.md +1 -1
  185. package/dist/global-skills/vybekiitReferences/spa/agent/goal-routes.json +267 -0
  186. package/dist/global-skills/vybekiitReferences/spa/agent/mcp-setup.md +10 -1
  187. package/dist/global-skills/vybekiitReferences/spa/agent/session-bootstrap.md +1 -1
  188. package/dist/global-skills/vybekiitReferences/spa/agent/ui-sources.md +11 -8
  189. package/dist/global-skills/vybekiitReferences/spa/language.md +7 -11
  190. package/dist/global-skills/vybekiitReferences/web/AGENTS.md +15 -30
  191. package/dist/global-skills/vybekiitReferences/web/agent/goal-index.md +1 -1
  192. package/dist/global-skills/vybekiitReferences/web/agent/goal-routes.json +366 -0
  193. package/dist/global-skills/vybekiitReferences/web/agent/mcp-setup.md +11 -2
  194. package/dist/global-skills/vybekiitReferences/web/agent/session-bootstrap.md +1 -1
  195. package/dist/global-skills/vybekiitReferences/web/language.md +7 -102
  196. package/dist/global-skills/vybekiitReferences/web/platform-skills/ai-vybekiit.md +1 -1
  197. package/dist/global-skills/vybekiitReferences/web/platform-skills/analytics-vybekiit.md +1 -1
  198. package/dist/global-skills/vybekiitReferences/web/platform-skills/assets-vybekiit.md +1 -1
  199. package/dist/global-skills/vybekiitReferences/web/platform-skills/better-auth-vybekiit.md +1 -1
  200. package/dist/global-skills/vybekiitReferences/web/platform-skills/browser-automation-vybekiit.md +9 -1
  201. package/dist/global-skills/vybekiitReferences/web/platform-skills/cms-vybekiit.md +1 -1
  202. package/dist/global-skills/vybekiitReferences/web/platform-skills/compliance-vybekiit.md +1 -1
  203. package/dist/global-skills/vybekiitReferences/web/platform-skills/deploy-github-pages-vybekiit.md +2 -2
  204. package/dist/global-skills/vybekiitReferences/web/platform-skills/deploy-railway-vybekiit.md +2 -2
  205. package/dist/global-skills/vybekiitReferences/web/platform-skills/deploy-vercel-vybekiit.md +2 -2
  206. package/dist/global-skills/vybekiitReferences/web/platform-skills/env-secrets-vybekiit.md +1 -0
  207. package/dist/global-skills/vybekiitReferences/web/platform-skills/extend-capabilities-vybekiit.md +1 -1
  208. package/dist/global-skills/vybekiitReferences/web/platform-skills/i18n-vybekiit.md +1 -1
  209. package/dist/global-skills/vybekiitReferences/web/platform-skills/jobs-vybekiit.md +1 -1
  210. package/dist/global-skills/vybekiitReferences/web/platform-skills/kv-vybekiit.md +1 -1
  211. package/dist/global-skills/vybekiitReferences/web/platform-skills/lemon-squeezy-vybekiit.md +1 -1
  212. package/dist/global-skills/vybekiitReferences/web/platform-skills/mongodb-vybekiit.md +1 -1
  213. package/dist/global-skills/vybekiitReferences/web/platform-skills/notifications-vybekiit.md +1 -1
  214. package/dist/global-skills/vybekiitReferences/web/platform-skills/observability-vybekiit.md +1 -1
  215. package/dist/global-skills/vybekiitReferences/web/platform-skills/paypal-vybekiit.md +1 -1
  216. package/dist/global-skills/vybekiitReferences/web/platform-skills/realtime-vybekiit.md +1 -1
  217. package/dist/global-skills/vybekiitReferences/web/platform-skills/registrar-vybekiit.md +1 -1
  218. package/dist/global-skills/vybekiitReferences/web/platform-skills/search-vybekiit.md +1 -1
  219. package/dist/global-skills/vybekiitReferences/web/platform-skills/sentry-vybekiit.md +1 -1
  220. package/dist/global-skills/vybekiitReferences/web/platform-skills/seo-vybekiit.md +1 -3
  221. package/dist/global-skills/vybekiitReferences/web/platform-skills/supabase-vybekiit.md +1 -1
  222. package/dist/global-skills/vybekiitReferences/web/platform-skills/tenancy-vybekiit.md +1 -1
  223. package/dist/global-skills/web-to-native/SKILL.md +1 -0
  224. package/dist/global-skills/workers-best-practices/SKILL.md +4 -3
  225. package/dist/global-skills/workers-best-practices/references/configuration.md +1 -1
  226. package/dist/global-skills/workers-best-practices/references/platform-apis.md +5 -5
  227. package/dist/global-skills/workers-best-practices/references/runtime-patterns.md +1 -1
  228. package/dist/global-skills/wrangler/SKILL.md +27 -24
  229. package/dist/global-skills/xcode-project-setup/SKILL.md +1 -0
  230. package/package.json +10 -8
@@ -278,6 +278,36 @@ railway domain delete example.com --service <service> --yes --json
278
278
 
279
279
  Domain deletion is destructive. Confirm the domain and service before running it.
280
280
 
281
+ ## Webhooks
282
+
283
+ Project webhooks POST a JSON payload to a URL whenever a chosen deployment, monitor, or volume-alert event happens anywhere in the project. They are project-scoped, not per service or environment, and are managed with five MCP tools. There is no `railway webhook` CLI command. Resolve the project ID from `railway status --json` or `list-projects` first.
284
+
285
+ | Tool | Purpose |
286
+ |---|---|
287
+ | `list-webhooks` | Every webhook in the project: URL, `eventTypes`, `includePreviewEnvironments`, the names of its custom headers (`headerNames`), and the `id` the other tools take |
288
+ | `create-webhook` | `url` plus optional `eventTypes` (defaults to `Deployment.failed`, `Deployment.crashed`, `Deployment.oom_killed`), `includePreviewEnvironments` (defaults to `true`), and `headers` |
289
+ | `update-webhook` | `webhookId` plus any of `url`, `eventTypes`, `includePreviewEnvironments`, `headers`. Only the fields passed change; `eventTypes` and `headers` each replace the whole set |
290
+ | `test-webhook` | POST a sample event and report the HTTP status. Pass `url` (and optional `headers`) to try a new endpoint, or `webhookId` to send to an existing webhook with its stored URL and headers. Nothing is stored |
291
+ | `delete-webhook` | Remove a webhook by `webhookId`. Destructive; confirm the URL with the user first |
292
+
293
+ Discord and Slack incoming-webhook URLs are detected and receive a formatted message instead of the raw JSON. Run `test-webhook` before `create-webhook`: Railway treats anything outside `2xx`/`3xx` as a failed delivery, and a dead endpoint is paused for 24 hours after repeated failures.
294
+
295
+ ```text
296
+ Create webhook for project <project-id>: url https://hooks.example.com/railway, eventTypes Deployment.failed Deployment.crashed, headers { "Authorization": "Bearer <token>" }
297
+ ```
298
+
299
+ ### Custom headers
300
+
301
+ A webhook can carry up to 20 custom HTTP headers, sent with every delivery and with `test-webhook`. Use them for whatever the receiver needs to trust or route the request: an `Authorization` bearer token, an API key, a shared secret the receiver compares, a routing header. This replaces the old advice of hiding a secret in the URL, which still works but leaks into logs more easily.
302
+
303
+ - **Values are write-only.** They are encrypted at rest and never returned: `list-webhooks` and every other tool's output carry `headerNames` only. Keep the value in the user's secret store; Railway cannot show it again.
304
+ - **`create-webhook` and `test-webhook`** take `headers` as a name-to-value map.
305
+ - **`update-webhook` replaces the whole set.** Every header not listed is removed and `{}` clears them all. A `null` value keeps the stored value for that name, so a secret survives a change without being resent: `{ "Authorization": null, "X-Env": "prod" }` keeps the token and sets `X-Env`. A URL-only update carries the stored headers forward automatically.
306
+ - **`test-webhook` with `webhookId`** sends the stored headers; any `headers` passed alongside override the stored one of the same name and the rest are still sent. Headers are validated before the request goes out, so a bad name gets a clear error instead of a `0` status.
307
+ - **Name rules.** RFC 9110 token characters, up to 128 characters; values up to 4096 characters with no CR or LF. `Host`, `Content-Type`, `Content-Length` and the hop-by-hop headers (`Transfer-Encoding`, `Connection`, `Keep-Alive`, `Upgrade`, `TE`, `Trailer`, `Expect`) are refused, as is any name starting with `proxy-` or `x-railway-`. Two names differing only by case count as a duplicate. The dashboard form applies the same rules inline and disables Save until a bad row is fixed.
308
+
309
+ Without MCP, the same fields are on the GraphQL API: `headers` inside the webhook channel config of `notificationRuleCreate` / `notificationRuleUpdate` (a `null` value keeps the stored one there too), and `webhookTest(url, payload, headers: [WebhookHeaderInput!], notificationRuleId)`. Inspect them with `railway api describe`.
310
+
281
311
  ## Networking commands
282
312
 
283
313
  ### Private networking
@@ -365,10 +395,13 @@ While active, browser visitors must pass a check. Non-browser API clients and we
365
395
  - **Outbound allowlist still sees old IPs**: redeploy after enabling/disabling Static Outbound IPs
366
396
  - **IPv6 still disabled**: commit the staged environment change and wait for redeploy
367
397
  - **CDN appears ineffective**: check `x-cache`, `age`, cache headers, `Set-Cookie`, `Authorization`, method, and response size
398
+ - **Webhook header rejected**: the name is reserved (`Host`, `Content-Type`, `Content-Length`, hop-by-hop), starts with `proxy-` or `x-railway-`, duplicates another name ignoring case, or the value has a newline; rename it or drop it, and stay under 20 headers
399
+ - **Webhook headers disappeared after an update**: `update-webhook` replaces the whole `headers` set, so a map without a name removes it; pass `null` for names to keep, or omit `headers` entirely
368
400
  - **WAF breaks API clients**: Under Attack Mode blocks non-browser traffic; disable it or scope protection to browser-facing services
369
401
  - **Multi-region patch ignored**: verify region names match the exact identifiers (`us-west2`, `us-east4-eqdc4a`, `europe-west4-drams3a`, `asia-southeast1-eqsg3a`)
370
402
 
371
403
  ## Validated against
372
404
 
373
- - Docs: [environment.md](https://docs.railway.com/cli/environment), [variable.md](https://docs.railway.com/cli/variable), [domain.md](https://docs.railway.com/cli/domain), [tcp-proxy.md](https://docs.railway.com/cli/tcp-proxy), [private-network.md](https://docs.railway.com/cli/private-network), [outbound-network.md](https://docs.railway.com/cli/outbound-network), [cdn.md](https://docs.railway.com/cli/cdn), [waf.md](https://docs.railway.com/cli/waf)
405
+ - Docs: [environment.md](https://docs.railway.com/cli/environment), [variable.md](https://docs.railway.com/cli/variable), [domain.md](https://docs.railway.com/cli/domain), [tcp-proxy.md](https://docs.railway.com/cli/tcp-proxy), [private-network.md](https://docs.railway.com/cli/private-network), [outbound-network.md](https://docs.railway.com/cli/outbound-network), [cdn.md](https://docs.railway.com/cli/cdn), [waf.md](https://docs.railway.com/cli/waf), [webhooks.md](https://docs.railway.com/observability/webhooks)
406
+ - Platform source (railwayapp/mono): `packages/backboard/src/handlers/http/routes/mcp/tools/webhooks.ts` (webhook MCP tools), `packages/backboard/src/controllers/notifications/validation.ts` (`validateWebhookHeaders`), `packages/backboard/src/graphql/v2/schema/schema.graphql` (`webhookTest`, `WebhookHeaderInput`)
374
407
  - CLI source: [environment/mod.rs](https://github.com/railwayapp/cli/blob/v5.23.3/src/commands/environment/mod.rs), [environment/edit.rs](https://github.com/railwayapp/cli/blob/v5.23.3/src/commands/environment/edit.rs), [variable.rs](https://github.com/railwayapp/cli/blob/v5.49.1/src/commands/variable.rs), [domain.rs](https://github.com/railwayapp/cli/blob/v5.23.3/src/commands/domain.rs), [tcp_proxy.rs](https://github.com/railwayapp/cli/blob/v5.23.3/src/commands/tcp_proxy.rs), [private_network.rs](https://github.com/railwayapp/cli/blob/v5.23.3/src/commands/private_network.rs), [outbound_networking.rs](https://github.com/railwayapp/cli/blob/v5.23.3/src/commands/outbound_networking.rs), [cdn.rs](https://github.com/railwayapp/cli/blob/v5.23.3/src/commands/cdn.rs), [waf.rs](https://github.com/railwayapp/cli/blob/v5.23.3/src/commands/waf.rs)
@@ -113,6 +113,8 @@ const media = bucket("media", { region: "iad" });
113
113
  const backend = group("Backend", [api, worker, db]);
114
114
  ```
115
115
 
116
+ A traced service also carries `tracing: { enabled: true, autoInstrumentation: true }`, which `config pull` renders but the `service()` helper does not pass through yet; see [Infrastructure as code in tracing.md](tracing.md#infrastructure-as-code) before applying a plan that touches `tracing`.
117
+
116
118
  Advanced placement can map regions to replica counts:
117
119
 
118
120
  ```ts
@@ -1,6 +1,6 @@
1
1
  # Tracing
2
2
 
3
- Trace a request from Railway's edge through a service and into the services it calls. Turn tracing on with the `set-service-tracing` and `set-project-tracing` MCP tools and read the result with `list-traces` and `get-trace`, or do both on the project's **Traces** tab.
3
+ Trace a request from Railway's edge through a service and into the services it calls. Tracing is switched on per service **and per environment**: with the `set-service-tracing` MCP tool, `railway trace enable`, or the **Tracing setup** drawer on the project's **Traces** tab. Read the result with `list-traces` and `get-trace`, or on the same tab.
4
4
 
5
5
  Tracing is a preview feature. If the project has no **Traces** tab, the account needs **Tracing** enabled in Priority Boarding first.
6
6
 
@@ -13,56 +13,89 @@ Spans from inside the service only appear once the service exports them, through
13
13
 
14
14
  ## Enable tracing
15
15
 
16
- Tracing has three settings. The project default (`tracingEnabled`) and the sample rate (`tracingSampleRate`) live on the project; a per-service override (`tracingEnabled`, `null` follows the project) and the automatic instrumentation switch (`autoInstrumentationEnabled`) live on the service. Automatic instrumentation only takes effect while the service's tracing is on.
16
+ Tracing is two switches on each service instance, so they are set per service and per environment. `tracingEnabled` makes the edge trace requests to the service and gives its next deploy the OpenTelemetry variables below; `autoInstrumentationEnabled` attaches eBPF probes to the service's processes and only does anything while tracing is on. There is no project-wide default and no sample rate: every client-facing request to a traced service is traced. Enabling a service in `production` says nothing about `staging`, so check and set each environment the user cares about.
17
17
 
18
- **Dashboard:** open the **Traces** tab → **Tracing setup**. Toggle **Trace requests by default** under Project, optionally set a **Sample rate** (percentage), and use each service row's **Traced** switch for overrides and **Automatic instrumentation** / **Manual instrumentation** to pick how it exports spans. The same controls are on the service under **Settings → Tracing**.
18
+ **Dashboard:** open the **Traces** tab → **Tracing setup**. The drawer lists the services of the environment the dashboard is on (the subtitle names it); each row's **Traced** switch and **Automatic instrumentation** / **Manual instrumentation** choice apply to that environment only. Switch environment to configure another. The service's **Settings → Tracing** section links to the same drawer.
19
19
 
20
- **Agent path:** three MCP tools read and change these settings, and `railway trace` does the same from the CLI. Resolve IDs from the URL or `railway status --json` first, and read before writing. On a Railway cloud agent in a dashboard chat session the `railway` CLI is unauthenticated, so resolve IDs with `list-services` and stay on the MCP tools throughout.
20
+ **Agent path:** two MCP tools read and change these settings, and `railway trace` does the same from the CLI. Resolve IDs from the URL or `railway status --json` first, and read before writing. Both tools use the `production` environment when `environmentId` is omitted, so pass it whenever the user is looking at another environment. On a Railway cloud agent in a dashboard chat session the `railway` CLI is unauthenticated, so resolve IDs with `list-services` and stay on the MCP tools throughout.
21
21
 
22
22
  | Tool | Access | Purpose |
23
23
  |---|---|---|
24
- | `get-tracing` | viewer | The project default (`tracingEnabled`, `sampleRate`) and, per service, `tracingOverride` (`true`/`false` pinned, `null` follows the project), the resolved `tracingEnabled`, `autoInstrumentationEnabled` and whether it is `autoInstrumentationActive`. Pass `serviceId` for one service, omit it for every service in the project |
25
- | `set-service-tracing` | member | `tracingEnabled` `true`/`false` pins one service regardless of the project default, `null` makes it follow the project again; `autoInstrumentationEnabled` switches OBI for the service. Each is optional and independent; omit what should stay as it is. Service-wide, not per environment |
26
- | `set-project-tracing` | member | `tracingEnabled` sets the project default for every service without an override; `sampleRate` is the fraction of client-facing requests the edge traces, `0..1`, `null` resets to Railway's default of every request. Each is optional |
24
+ | `get-tracing` | viewer | The `environment` and, per service in it, `tracingEnabled`, `autoInstrumentationEnabled` and whether it is `autoInstrumentationActive` (both on). Pass `serviceId` for one service, omit it for every service in the environment |
25
+ | `set-service-tracing` | member | `tracingEnabled` and `autoInstrumentationEnabled` for one service in one environment. Each is optional and independent; omit what should stay as it is. Returns the service's state in that environment |
27
26
 
28
- All three take `projectId`. `describe-service` reports the same tracing state for one service.
27
+ Both take `projectId` and an optional `environmentId`. `describe-service` reports the same tracing state for one service in the environment it was asked about.
29
28
 
30
29
  ```text
31
- Get tracing for project 6adb5ae3-0e3a-4ead-b42c-1fd36f217ffb
30
+ Get tracing for project 6adb5ae3-0e3a-4ead-b42c-1fd36f217ffb in environment <environment-id>
32
31
  ```
33
32
 
34
33
  ```text
35
- Set service tracing for project 6adb5ae3-0e3a-4ead-b42c-1fd36f217ffb, service <service-id>: tracingEnabled true
34
+ Set service tracing for project 6adb5ae3-0e3a-4ead-b42c-1fd36f217ffb, service <service-id>, environment <environment-id>: tracingEnabled true
36
35
  ```
37
36
 
38
37
  ```text
39
- Set project tracing for project 6adb5ae3-0e3a-4ead-b42c-1fd36f217ffb: tracingEnabled true, sampleRate 0.25
38
+ Set service tracing for project 6adb5ae3-0e3a-4ead-b42c-1fd36f217ffb, service <service-id>, environment <environment-id>: autoInstrumentationEnabled true
40
39
  ```
41
40
 
42
- ```text
43
- Set service tracing for project 6adb5ae3-0e3a-4ead-b42c-1fd36f217ffb, service <service-id>: autoInstrumentationEnabled true
41
+ `set-service-tracing` warns when it switches auto-instrumentation on for a service whose tracing is off: the switch does nothing until tracing is enabled too. Without Railway MCP or `railway trace`, the public `serviceInstanceUpdate` mutation sets the same fields through `railway api`, and the environment's service instances carry them for reading; see [request.md](request.md). That fallback needs an authenticated CLI, which a cloud agent's chat session does not have.
42
+
43
+ ```bash
44
+ railway api \
45
+ 'mutation traceInstance($serviceId: String!, $environmentId: String!) {
46
+ serviceInstanceUpdate(serviceId: $serviceId, environmentId: $environmentId,
47
+ input: { tracingEnabled: true, autoInstrumentationEnabled: false })
48
+ }' \
49
+ --variables '{"serviceId":"<service-id>","environmentId":"<environment-id>"}'
50
+
51
+ railway api \
52
+ 'query tracing($id: String!) {
53
+ environment(id: $id) { serviceInstances { edges { node {
54
+ serviceId serviceName tracingEnabled autoInstrumentationEnabled
55
+ } } } }
56
+ }' \
57
+ --variables '{"id":"<environment-id>"}'
44
58
  ```
45
59
 
46
- The sample rate is a fraction from 0 to 1 in the tools and the API; the dashboard shows it as a percentage. `set-service-tracing` warns when it switches auto-instrumentation on for a service whose tracing is off: the switch does nothing until the service, or the project default, is enabled. Without Railway MCP or `railway trace`, the public `projectUpdate` (`tracingEnabled`, `tracingSampleRate`) and `serviceUpdate` (`tracingEnabled`, `autoInstrumentationEnabled`) mutations through `railway api` set the same fields; see [request.md](request.md). That fallback needs an authenticated CLI, which a cloud agent's chat session does not have.
60
+ The older `Project` and `Service` tracing fields still exist as deprecated stubs: `projectUpdate(tracingEnabled)` switches every instance in the project, `serviceUpdate(tracingEnabled)` the service in every environment, and `tracingSampleRate` is ignored. Don't use them; they flip environments the user didn't mention.
47
61
 
48
- **CLI:** `railway trace` (aliases `traces`, `tracing`) sets the same fields. Use it when the user works in a linked repo or wants exact command output; on a cloud agent's chat session the CLI is unauthenticated, so stay on MCP there.
62
+ **CLI:** `railway trace` (aliases `traces`, `tracing`) sets the same switches, in one environment at a time: the linked one, or `--environment <name>`. This needs a CLI release newer than 5.62.1. An older CLI still runs `railway trace enable`, but through the deprecated service field, so it sets the service in every environment, and its `inherit`, `--project-default` and `--sample-rate` belong to the model that is gone. Use the CLI when the user works in a linked repo or wants exact command output; on a cloud agent's chat session stay on MCP.
49
63
 
50
64
  ```bash
51
- railway trace status --all # project default, every service, last edge/app span
52
- railway trace enable --service <service> # pin tracing on for one service
65
+ railway trace status # linked service in the linked environment
66
+ railway trace status --all # every service in the environment, last edge/app span
67
+ railway trace enable --service <service> # trace one service in the linked environment
53
68
  railway trace enable --auto-instrument # tracing plus OBI for the linked service
54
- railway trace enable --project-default --sample-rate 0.25
55
- railway trace disable --auto-instrument # pin tracing off and switch OBI off
56
- railway trace inherit # follow the project default again
69
+ railway trace enable --all --environment staging # every service in staging
70
+ railway trace disable --auto-instrument # tracing and OBI off
57
71
  ```
58
72
 
59
- Tracing is service-wide, so `--environment` only scopes `status`, `list` and `get`; pass `--project <id> --environment <name>` when nothing is linked. `--json` prints one document with the project default and the service state. Changing tracing needs a user or workspace token; a project token (`RAILWAY_TOKEN`) can only read. The CLI has no switch for auto-instrumentation alone: `railway trace disable --auto-instrument` followed by `railway trace enable` leaves tracing on and OBI off.
73
+ `--all` and `--service` are mutually exclusive. Pass `--project <id> --environment <name>` together when nothing is linked. `--json` prints one document with `environment: { id, name }` and the service state. Changing tracing needs a user or workspace token; a project token (`RAILWAY_TOKEN`) can only read. The CLI has no switch for auto-instrumentation alone: `railway trace disable --auto-instrument` followed by `railway trace enable` leaves tracing on and OBI off, or use `set-service-tracing` with only `autoInstrumentationEnabled`.
60
74
 
61
75
  What happens next:
62
76
 
63
- - The edge starts tracing requests to the service's domains within seconds.
77
+ - The edge starts tracing requests to the service's domains in that environment within seconds.
64
78
  - Automatic instrumentation reaches the running containers within about a minute. No redeploy.
65
- - The OpenTelemetry variables below are added on the **next deploy**. An app with an SDK exports nothing until it is redeployed: `railway redeploy --service <service> --yes`.
79
+ - The OpenTelemetry variables below are added on the **next deploy** in that environment. An app with an SDK exports nothing until it is redeployed: `railway redeploy --service <service> --yes`.
80
+
81
+ ### Infrastructure as code
82
+
83
+ The environment config carries the same two switches as `services[<id>].tracing: { enabled, autoInstrumentation }`, so tracing is part of what `railway config pull`, `plan` and `apply` manage (see [iac.md](iac.md)). Railway serialises only the switches that are on: an untraced service has no `tracing` block, and `enabled: false` is the same as leaving it out. `railway config pull` renders the block for a traced service:
84
+
85
+ ```ts
86
+ const api = service("api", {
87
+ source: github("owner/repo", { branch: "main" }),
88
+ tracing: { enabled: true, autoInstrumentation: true },
89
+ });
90
+ ```
91
+
92
+ A plan shows a tracing change as a `resource.update` with `field: "tracing"`. Turning `enabled` on or off has `deployEffect: deploy`, because the `OTEL_*` variables land with a deploy; an `autoInstrumentation`-only change is `deployEffect: none` and reaches the running containers live. A new service carries `tracing` on its create.
93
+
94
+ **Current limitation: the SDKs don't carry `tracing` yet.** The TypeScript `service()` helper, and the Python and Go ones, whitelist their config keys and `tracing` is not among them, so a `tracing:` the user writes in `railway.ts` is dropped before the CLI sees it and never applies. The other direction is worse: a compiled config with no `tracing` block asks to remove it, so `railway config plan` against a service that is traced shows a `tracing` update with `after: null` and `deployEffect: deploy`, and `railway config apply` turns tracing off and redeploys. Until the SDKs ship the field:
95
+
96
+ - Set tracing with `set-service-tracing`, `railway trace` or the dashboard, not in `railway.ts`, and say why when the user asks for it in config.
97
+ - Read every plan for a `tracing` change nobody authored, and don't apply one. `railway config pull` reproduces the block, but the SDK drops it again on the next plan, so pulling doesn't fix it.
98
+ - If an apply already disabled tracing, re-enable it with `set-service-tracing`; the redeploy for the variables follows.
66
99
 
67
100
  ## Choose how the service exports spans
68
101
 
@@ -80,7 +113,7 @@ Pick one per service. Running an SDK in a service that also has automatic instru
80
113
 
81
114
  ## Instrument with an OpenTelemetry SDK
82
115
 
83
- When tracing is on for a service, its next deploy gets these variables. They show up in the service's **Variables** tab alongside the other Railway-provided variables and every OpenTelemetry SDK reads them, so an SDK configured without an explicit endpoint exports to Railway:
116
+ When tracing is on for a service in an environment, its next deploy there gets these variables. They show up in the service's **Variables** tab alongside the other Railway-provided variables and every OpenTelemetry SDK reads them, so an SDK configured without an explicit endpoint exports to Railway:
84
117
 
85
118
  | Variable | Value |
86
119
  |---|---|
@@ -89,8 +122,6 @@ When tracing is on for a service, its next deploy gets these variables. They sho
89
122
  | `OTEL_EXPORTER_OTLP_HEADERS` | A header the receiver requires on every export |
90
123
  | `OTEL_SERVICE_NAME` | The Railway service name |
91
124
  | `OTEL_SERVICE_VERSION` | The commit SHA, or the deployment ID for image and CLI deploys |
92
- | `OTEL_TRACES_SAMPLER` | `parentbased_traceidratio`, only when the project set its own sample rate |
93
- | `OTEL_TRACES_SAMPLER_ARG` | The project's sample rate as a fraction, only when the project set its own sample rate |
94
125
 
95
126
  Rules the agent must apply:
96
127
 
@@ -101,7 +132,7 @@ Rules the agent must apply:
101
132
  Set variables for project <project-id>, service <service-id>: OTEL_METRICS_EXPORTER=none, OTEL_LOGS_EXPORTER=none, skipDeploys true
102
133
  ```
103
134
 
104
- - **User variables win.** A service that sets its own `OTEL_EXPORTER_OTLP_ENDPOINT` or `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` (for example to keep exporting to its own collector) gets none of the tracing variables, and its spans don't reach the Traces tab; edge spans still do. A service that sets either `OTEL_TRACES_SAMPLER` or `OTEL_TRACES_SAMPLER_ARG` keeps both of its own and Railway adds neither. Check `railway variable list --service <service> --json` before assuming the provided values apply.
135
+ - **User variables win.** A service that sets its own `OTEL_EXPORTER_OTLP_ENDPOINT` or `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` (for example to keep exporting to its own collector) gets none of the tracing variables, and its spans don't reach the Traces tab; edge spans still do. Railway sets no sampler variables, so a sampler the service configures is the only one in play. Check `railway variable list --service <service> --json` before assuming the provided values apply.
105
136
  - **Load the SDK first.** Instrumentation libraries (`@opentelemetry/auto-instrumentations-node`, `opentelemetry-instrumentation-*` and the like) patch libraries at import time, so the SDK must be loaded before the app's modules: a `--require`/`--import` flag in the start command, `NODE_OPTIONS`, a Python `opentelemetry-instrument` wrapper, a Java `-javaagent`, and so on. Set it with `railway environment edit --service-config <service> deploy.startCommand "<command>"` or as a variable; see [deploy.md](deploy.md).
106
137
  - **Keep W3C Trace Context propagation on** (the SDK default in most languages; Go requires setting the propagator explicitly) so the service continues the edge's trace instead of starting its own.
107
138
  - **Don't override `OTEL_SERVICE_NAME`** unless the user wants spans attributed under a different name than the Railway service.
@@ -113,7 +144,15 @@ Per-language install steps, framework notes, and a custom-span example are in th
113
144
  Instrumentation libraries give a trace its skeleton: a server span per request and a client span per call a library recognises. On its own that is barely better than automatic instrumentation. The value comes from spans the app opens itself around the units of work its authors think in. When adding tracing to a codebase, or when asked what to instrument, cover these three layers, in this order:
114
145
 
115
146
  1. **Inbound work.** One span per HTTP handler, gRPC method, queue or job consumer invocation, cron run and WebSocket message. The HTTP and gRPC server instrumentations usually cover handlers. Consumers, cron and background jobs are not covered by the edge or by most instrumentations, so wrap each message or run in its own span (kind `CONSUMER` or `INTERNAL`) and, where the message carries a `traceparent`, continue that context so the trace links back to the producer. Without this, background work is invisible or shows up as orphaned client spans.
116
- 2. **I/O: database queries, cache calls, outgoing HTTP and gRPC calls, queue publishes.** This is where latency and failures hide. Use the driver or client instrumentation where one exists. Where none does (a raw socket client, a vendor SDK the instrumentations don't know), wrap the call in a `CLIENT` span with the standard `db.*`, `server.address` or `url.full` attributes. Every remote call should be visible as its own span.
147
+ 2. **I/O: database queries, cache calls, outgoing HTTP and gRPC calls, queue publishes.** This is where latency and failures hide. Use the driver or client instrumentation where one exists. Where none does (a raw socket client, a vendor SDK the instrumentations don't know), wrap the call in a `CLIENT` span with the standard `db.*`, `server.address` or `url.full` attributes. Every remote call should be visible as its own span. List every database driver or ORM, cache, HTTP and queue client in the dependency manifest and check each one, because the bundles miss common ones:
148
+ - **Node.js**: `@opentelemetry/auto-instrumentations-node` covers `pg`, `mysql2`, `ioredis`, `mongodb`, `mongoose`, `knex` and `undici`/`http`, but not Prisma (add `@prisma/instrumentation` to the SDK's instrumentations) and not postgres.js, Drizzle on postgres.js, `Bun.sql` or the Neon serverless driver (no instrumentation exists; wrap queries in a `CLIENT` span with `db.system`, `db.namespace`, `db.operation.name`). An app written as ES modules needs the `@opentelemetry/instrumentation/hook.mjs` loader, or imported drivers stay unpatched while the `http` server span still appears.
149
+ - **Python**: `opentelemetry-distro` alone instruments nothing; run `opentelemetry-bootstrap -a install` so the instrumentations for the installed drivers (`psycopg2`, `asyncpg`, `SQLAlchemy`, `redis`, `pymongo`, `requests`, `httpx`) are installed too.
150
+ - **Go**: nothing is automatic. Wrap `database/sql` with `otelsql`, pgx with `otelpgx`, go-redis with `redisotel`, HTTP clients with `otelhttp.NewTransport`.
151
+ - **Rust**: `sqlx` emits tracing events, not spans; wrap queries in a span. `reqwest` needs `reqwest-tracing`.
152
+ - **Deno**: `OTEL_DENO=true` covers `fetch`, `Deno.serve` and `node:http`; npm database drivers need their own instrumentation or a hand-written span.
153
+ - **Java, Ruby, .NET, PHP**: the agent, `opentelemetry-instrumentation-all`, the per-library packages (`Npgsql.OpenTelemetry`, `OpenTelemetry.Instrumentation.SqlClient`, ...) and `opentelemetry-auto-pdo` cover JDBC, ActiveRecord, ADO.NET and PDO; confirm the package for the driver in use is present.
154
+ A server span with no client spans under it means this layer was skipped. Before opening the PR, run the app once with the console exporter (`OTEL_TRACES_EXPORTER=console` or the runtime's equivalent) and hit a route that queries the database: a `CLIENT` span carrying `db.system`, even a failed one, proves the driver is patched. List each client and the instrumentation that covers it, or why it is not covered, in the PR description.
155
+
117
156
  3. **Logical units of work.** A function that groups several I/O calls into one meaningful step (`checkout`, `syncUser`, `renderInvoice`), or one that is CPU-heavy on its own (parsing a large payload, image resizing, template rendering, serialising a big response). Give each an `INTERNAL` span carrying the identifiers a person debugging it would want (`order.id`, `tenant`, item counts). This turns twelve sibling `SELECT` spans under a handler into a tree that reads like the code and says which step took the time. Rule of thumb: if you would want log lines saying "starting X" and "finished X in N ms", X is a span.
118
157
 
119
158
  Keep spans out of tight loops and trivial helpers. A span per item in a loop of thousands hits the per-replica export limit (see Sampling) and adds nothing a `count` attribute on the parent wouldn't; instrument the loop, not the iteration. Name spans with low-cardinality names (`GET /users/{id}`, `db.query users`, `process order`) and put the variable parts in attributes. Set span status to `ERROR` and record the exception when a unit fails, so `@status:error` finds it. Never put secrets, tokens or raw personal data in span names or attributes.
@@ -131,7 +170,7 @@ What differs from a repo service:
131
170
 
132
171
  Recipe:
133
172
 
134
- 1. Turn tracing on for the function with `set-service-tracing` (or `railway trace enable --service <function>`) if `get-tracing` shows it off. Leave `autoInstrumentationEnabled` off; it does nothing for Bun.
173
+ 1. Turn tracing on for the function in the environment it runs in with `set-service-tracing` (or `railway trace enable --service <function>`) if `get-tracing` shows it off there. Leave `autoInstrumentationEnabled` off; it does nothing for Bun.
135
174
  2. Set the exporter variables with `set-variables`. `NodeSDK` exports metrics and logs over OTLP by default and the receiver rejects both. Pass `skipDeploys: true`; the code push in step 5 is the deploy that picks them up. Check `list-variables` first: a function that sets its own `OTEL_EXPORTER_OTLP_ENDPOINT` gets none of Railway's tracing variables.
136
175
 
137
176
  ```text
@@ -147,8 +186,8 @@ Recipe:
147
186
  import { Hono } from "hono@4";
148
187
  import { httpInstrumentationMiddleware } from "@hono/otel@1";
149
188
 
150
- // Reads OTEL_EXPORTER_OTLP_*, OTEL_SERVICE_NAME and OTEL_TRACES_SAMPLER*
151
- // from the variables Railway provides. Nothing to configure.
189
+ // Reads OTEL_EXPORTER_OTLP_* and OTEL_SERVICE_NAME from the variables
190
+ // Railway provides. Nothing to configure.
152
191
  const sdk = new NodeSDK();
153
192
  sdk.start();
154
193
  process.on("SIGTERM", () => sdk.shutdown().finally(() => process.exit(0)));
@@ -175,7 +214,7 @@ Recipe:
175
214
  export default { port: Number(Bun.env.PORT ?? 3000), fetch: app.fetch };
176
215
  ```
177
216
 
178
- For a function that calls `Bun.serve` itself, wrap its `fetch` handler: take the parent from `propagation.extract(context.active(), req.headers, { get: (h, k) => h.get(k) ?? undefined, keys: (h) => [...h.keys()] })` and run the handler inside `tracer.startActiveSpan(name, { kind: SpanKind.SERVER }, parent, ...)`. For an outgoing call, start a `SpanKind.CLIENT` span and `propagation.inject(context.active(), headers, { set: (h, k, v) => h.set(k, v) })` into a `Headers` object before `fetch`. A cron or script function has no server: its spans are new roots (sampled at the project rate through the sampler variables) and it must `await sdk.shutdown()` as its last statement, or the batch never leaves the process. The docs page has all three in full.
217
+ For a function that calls `Bun.serve` itself, wrap its `fetch` handler: take the parent from `propagation.extract(context.active(), req.headers, { get: (h, k) => h.get(k) ?? undefined, keys: (h) => [...h.keys()] })` and run the handler inside `tracer.startActiveSpan(name, { kind: SpanKind.SERVER }, parent, ...)`. For an outgoing call, start a `SpanKind.CLIENT` span and `propagation.inject(context.active(), headers, { set: (h, k, v) => h.set(k, v) })` into a `Headers` object before `fetch`. A cron or script function has no server: its spans are new roots, recorded on every run, and it must `await sdk.shutdown()` as its last statement, or the batch never leaves the process. The docs page has all three in full.
179
218
 
180
219
  5. Write it back with `update-function-source-code` (the whole file; pass `staged: true` to stage instead of deploying live) or `railway functions push --path <file>`. This deploy also adds the variables.
181
220
  6. Verify with the steps below: `curl -sI https://<domain>/hello/x | grep -i x-railway-trace-id`, then `get-trace` on the ID. A span with `component` `service` and scope `@hono/otel` (or the tracer name) means the function exports. If the deploy logs show `bun install` failing, an import specifier is wrong; if they show OTLP export errors for metrics or logs, step 2 was skipped.
@@ -184,9 +223,8 @@ Docs: [Functions](https://docs.railway.com/observability/tracing/functions).
184
223
 
185
224
  ## Sampling
186
225
 
187
- - **Default is every request.** With no project sample rate, the edge traces 100% of client-facing requests and Railway adds neither sampler variable, so the SDK's default parent-based sampler follows the edge's decision and records every root span of its own.
188
- - **A project rate applies everywhere.** The edge draws once per client-facing request and writes the decision into the `traceparent` sampled flag; requests it didn't sample carry a cleared flag, so the SDK records nothing for them. The two sampler variables make the SDK sample roots the edge never saw (cron jobs, queue consumers, private-network calls without a `traceparent`) at the same rate.
189
- - **A client `traceparent` overrides the draw.** A request that arrives with the sampled flag set is always traced; one with it cleared never is. Use this to force a single trace while debugging a service with a low rate:
226
+ - **Every request is traced.** The edge traces 100% of client-facing requests to a traced service and writes the decision into the `traceparent` sampled flag. Railway sets no sampler variables, so the SDK's default parent-based sampler follows the edge and records every root span of its own (cron jobs, queue consumers, private-network calls without a `traceparent`). There is no project or service rate to set.
227
+ - **A client `traceparent` overrides.** A request that arrives with the sampled flag set is always traced; one with it cleared never is. An instrumented client can start a trace that continues into Railway, and a caller can keep a request out of tracing by sending a cleared flag. To trace one specific request while debugging:
190
228
 
191
229
  ```bash
192
230
  curl -H "traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01" https://<domain>/<path>
@@ -194,7 +232,7 @@ Docs: [Functions](https://docs.railway.com/observability/tracing/functions).
194
232
 
195
233
  Generate a fresh random 32-hex trace ID (the second field) for each request; reusing one merges requests into a single trace.
196
234
 
197
- - Lower the rate for busy services. Each replica can export 1,000 spans per 10 seconds; exports over the limit are rejected and the SDK reports a partial success.
235
+ - **Sample in the SDK when the volume is too high.** Each replica can export 1,000 spans per 10 seconds; exports over the limit are rejected and the SDK reports a partial success. Disable noisy instrumentations first. If that isn't enough, set `OTEL_TRACES_SAMPLER=traceidratio` and `OTEL_TRACES_SAMPLER_ARG=<fraction>` on the service yourself; a `parentbased_*` sampler follows the edge's flag and would change nothing for edge requests. Traces the SDK drops still show the edge and proxy hops.
198
236
 
199
237
  ## Read traces
200
238
 
@@ -203,7 +241,8 @@ Traces are read through **Remote MCP** (the default agent path), `railway trace
203
241
  | Tool | Access | Purpose |
204
242
  |---|---|---|
205
243
  | `list-traces` | viewer | Traces of an environment, newest first, one row per request with at least one span matching `filter`. Optional `serviceId`, `startDate`/`endDate` (ISO 8601 with timezone; defaults to the last hour), `limit` (default 100, max 500) |
206
- | `get-trace` | viewer | One trace as an indented span tree, with every span's attributes, events and links in the structured result. Takes `traceId` (32 hex characters); `maxSpans` caps the result and the output says when it was hit |
244
+ | `get-trace` | viewer | One trace as an indented span tree (each line shows the span kind and the attribute that says what it talked to: `db.system`, `http.route`, `url.full` or `server.address`), with every span's attributes, events and links in the structured result. Takes `traceId` (32 hex characters); `maxSpans` caps the result and the output says when it was hit |
245
+ | `get-tracing-coverage` | viewer | What one service's own instrumentation covers: its spans in the window (default the last hour) by span kind, by the remote system they name (`db.system`, `messaging.system`, `rpc.system`, or `http` for HTTP client spans) and by the instrumentation scope that emitted them (`@opentelemetry/instrumentation-pg`, ...). Takes `serviceId`; optional `startDate`/`endDate`. Edge and proxy spans are left out. The one call that answers "are the database queries instrumented?" |
207
246
 
208
247
  Both take `projectId` and an optional `environmentId`; omit it and the `production` environment is used, so pass the ID explicitly when the user is looking at another environment. Traces belong to the environment they were exported from.
209
248
 
@@ -240,22 +279,28 @@ Workflow for "why is this request slow / failing":
240
279
  ```
241
280
 
242
281
  2. **Fetch that trace** with `get-trace` or `railway trace get <trace-id>` and the returned ID. Edge and proxy spans confirm tracing is on; a span with `component` `service` confirms the app is exporting. After enabling an SDK, that only happens once the redeploy that added the variables is live; after enabling automatic instrumentation, allow about a minute.
243
- 3. **Or watch the dashboard.** The Traces tab is at `https://railway.com/project/<project-id>/traces?environmentId=<environment-id>`; its **Trace ID** field accepts a bare 32-hex ID or a whole `traceparent` header. In **Tracing setup**, each service row shows when the edge and the app last exported a span, and the **App** indicator turns green on the first span from the service itself.
282
+ 3. **Check what the app covers** with `get-tracing-coverage` for the service, after sending a few requests that hit the database. Every database, cache and queue the service uses must appear under "Remote systems" and the driver instrumentations under "Instrumentation scopes". `SERVER` spans with no database client span mean a driver is still unpatched (see the I/O layer in [What to instrument](#what-to-instrument)); `list-traces` with `@kind:client @db.system:*` is the same check as a trace list.
283
+ 4. **Or watch the dashboard.** The Traces tab is at `https://railway.com/project/<project-id>/traces?environmentId=<environment-id>`; its **Trace ID** field accepts a bare 32-hex ID or a whole `traceparent` header. In **Tracing setup**, each service row shows when the edge and the app last exported a span, and the **App** indicator turns green on the first span from the service itself.
244
284
 
245
285
  ## Troubleshoot
246
286
 
247
- - **No traces at all**: confirm `get-tracing` or `railway trace status` reports tracing on for the service (its override, then the project default), the service has a public domain, and the account has Tracing in Priority Boarding. With a low rate and little traffic, force one with the `traceparent` curl above, then `get-trace` it.
287
+ - **No traces at all**: confirm `get-tracing` or `railway trace status` reports tracing on for the service in the environment the user is looking at (the switches and the traces both belong to an environment), the service has a public domain, and the account has Tracing in Priority Boarding. With little traffic, send a request and check for `x-railway-trace-id` on the response, then `get-trace` it.
288
+ - **Traced in `production` but not elsewhere**: tracing is set per environment. Enable it in the other environment with `set-service-tracing` and its `environmentId`, or `railway trace enable --environment <name>`.
248
289
  - **Edge spans only, nothing from the app** (`get-trace` shows only `edge` and `proxy` components): the variables land on the next deploy, so redeploy. Then check the service doesn't set its own `OTEL_EXPORTER_OTLP_ENDPOINT`, the SDK loads before the app serves, and, for OBI, the process is a supported runtime handling HTTP or gRPC.
290
+ - **Server spans but no database or client spans** (`get-tracing-coverage` shows `SERVER` and `INTERNAL` only, or `get-trace` shows a request span with no `CLIENT` children): the driver is not instrumented. In Node.js an ES-module app without the `@opentelemetry/instrumentation/hook.mjs` loader, Prisma without `@prisma/instrumentation`, or a client no instrumentation covers (postgres.js, Drizzle on it, `Bun.sql`); in Python a missing `opentelemetry-bootstrap -a install`; in Go an unwrapped `database/sql`. See the I/O layer in [What to instrument](#what-to-instrument).
249
291
  - **App spans appear as separate traces** (`list-traces` shows service-rooted traces with `hasEdge` false next to edge-only ones): the SDK isn't reading `traceparent`. Enable the W3C Trace Context propagator and make sure nothing in front of the handlers strips the header.
250
292
  - **SDK logs metrics or logs export errors**: set `OTEL_METRICS_EXPORTER=none` and `OTEL_LOGS_EXPORTER=none`.
251
293
  - **Duplicate spans per request**: the service runs an SDK with automatic instrumentation on. Switch it off with `set-service-tracing` (`autoInstrumentationEnabled` false), or on the CLI `railway trace disable --auto-instrument` then `railway trace enable`.
252
- - **Spans missing from a busy service**: over 1,000 spans per replica per 10 seconds. Disable noisy instrumentations or lower the sample rate.
294
+ - **Spans missing from a busy service**: over 1,000 spans per replica per 10 seconds. Disable noisy instrumentations or sample in the SDK; see [Sampling](#sampling).
253
295
  - **A Function shows edge spans only**: automatic instrumentation can't help (Bun); the SDK has to be in the file. Check `get-function-source-code` for the `NodeSDK` block and the request wrapper, that the deploy logs show `bun install` succeeding, and that `OTEL_METRICS_EXPORTER`/`OTEL_LOGS_EXPORTER` are `none`. See [Instrument a Function (Bun)](#instrument-a-function-bun).
254
- - **Setting the sample rate fails validation**: `set-project-tracing`, `railway trace enable --project-default --sample-rate` and the API take a fraction 0..1, not a percentage.
296
+ - **`railway config plan` wants to remove `tracing`**: the IaC SDKs drop the field, so every plan against a traced service proposes turning it off. Don't apply it; see [Infrastructure as code](#infrastructure-as-code).
255
297
 
256
298
  ## Validated against
257
299
 
258
- - Docs: [tracing.md](https://docs.railway.com/observability/tracing), [automatic-instrumentation.md](https://docs.railway.com/observability/tracing/automatic-instrumentation), [nodejs.md](https://docs.railway.com/observability/tracing/nodejs), [tracing/functions.md](https://docs.railway.com/observability/tracing/functions), [functions.md](https://docs.railway.com/functions), [variables/reference.md](https://docs.railway.com/variables/reference)
259
- - Platform source (railwayapp/mono): `common/javascript/models/src/tracingVariables.ts` (provided variables and precedence), `common/javascript/models/src/functions.ts` and `services.ts` (function start command, image prefix), `packages/backboard/src/graphql/v2/schema/schema.graphql` (`Project.tracingEnabled`, `Project.tracingSampleRate`, `Service.tracingEnabled`, `Service.autoInstrumentationEnabled`, `ProjectUpdateInput`, `ServiceUpdateInput`), `packages/hikari/src/settings/tunables.rs` (default sample rate), `packages/stacker-oteld/configs/main.go` (span limit), `packages/backboard/src/handlers/http/routes/mcp/tools/listTraces.ts`, `getTrace.ts`, `getTracing.ts`, `setServiceTracing.ts`, `setProjectTracing.ts`, `tracingMcpHelpers.ts`, `getFunctionSourceCode.ts` and `updateFunctionSourceCode.ts` (MCP tools)
260
- - Function runtime (railwayapp/code-images): `bun/Dockerfile` (Bun 1.4.0), `bun/run.sh` (import scan, `bun install` per start, `bun run --smol index.tsx`)
300
+ - Docs: [tracing.md](https://docs.railway.com/observability/tracing), [automatic-instrumentation.md](https://docs.railway.com/observability/tracing/automatic-instrumentation), [nodejs.md](https://docs.railway.com/observability/tracing/nodejs), [tracing/functions.md](https://docs.railway.com/observability/tracing/functions), [functions.md](https://docs.railway.com/functions), [variables/reference.md](https://docs.railway.com/variables/reference), [cli/trace.md](https://docs.railway.com/cli/trace), [infrastructure-as-code/reference.md](https://docs.railway.com/infrastructure-as-code/reference)
301
+ - Public GraphQL API (`railway api schema`): `ServiceInstance.tracingEnabled`, `ServiceInstance.autoInstrumentationEnabled` and `ServiceInstanceUpdateInput` as the per-environment path; `Project.tracingEnabled`, `Project.tracingSampleRate`, `Service.tracingEnabled`, `Service.autoInstrumentationEnabled` and their update inputs marked deprecated; the `traces`, `trace` and `tracingStatus` queries
302
+ - Railway MCP (`https://mcp.railway.com`) tool descriptions and schemas: `get-tracing` and `set-service-tracing` with `environmentId`, `describe-service`, `list-traces`, `get-trace`, `get-tracing-coverage`, `get-function-source-code`, `update-function-source-code`
303
+ - CLI source (railwayapp/cli, per-environment `railway trace` and the IaC `tracing` block in #1239): `src/commands/trace.rs` (subcommands, `--all`, `--environment`), `src/iac/compiler.rs` (`services[id].tracing` on service nodes), `src/iac/change_set.rs` (tracing diff, `deployEffect`, removal when the block is absent), `src/commands/config/mod.rs` (pull renderer)
304
+ - Provided variables observed on a traced service's deploy: the five `OTEL_*` variables in the table above and no sampler variables
305
+ - Function runtime: the public `ghcr.io/railwayapp/function-bun:1.4.0` image (Bun 1.4.0, bare imports turned into a `package.json` and installed with `bun install` at every start)
261
306
  - Function examples run on Bun 1.4.0 with `@opentelemetry/sdk-node` 0.222.0 and `@hono/otel` 1.1.2 against a stub OTLP receiver: server span continues the incoming `traceparent`, client span propagates it, script flushes on `sdk.shutdown()`
@@ -10,6 +10,7 @@ license: MIT
10
10
  metadata:
11
11
  author: vercel
12
12
  version: '1.0.0'
13
+ disable-model-invocation: true
13
14
  ---
14
15
 
15
16
  # React Composition Patterns
@@ -5,6 +5,7 @@ license: MIT
5
5
  metadata:
6
6
  author: vercel
7
7
  version: "1.0.0"
8
+ disable-model-invocation: true
8
9
  ---
9
10
 
10
11
  # Vercel React Best Practices
@@ -1,7 +1,9 @@
1
1
  # AGENTS.md — your build agent (read this first)
2
2
 
3
- > **Single source of truth** for Claude Code, Cursor, and Codex — `CLAUDE.md` and `.cursor/rules`
4
- > point here. You are talking to a non-technical vibe coder.
3
+ > **Single source of truth** for Claude Code, Cursor, and Codex. Claude Code and Codex read this
4
+ > file directly; `.cursor/rules` points here. You are talking to a non-technical vibe coder.
5
+
6
+ Use the plain words in @language.md whenever you talk to the vibe coder.
5
7
 
6
8
  <!-- vybekiit:generated:start contract -->
7
9
  ## The contract: Decide + Guide
@@ -19,7 +21,9 @@ A request such as "Can people book my classes?" means build the working feature.
19
21
 
20
22
  ## How to work
21
23
 
22
- Simple questions need brief answers, without setup or skill searches. Inspect before making
24
+ A greeting, a plain "help", or "what is this" in a project whose `checklist.md` Decision log has
25
+ no dated entries starts the onboarding skill (`.vybekiit/skills/onboarding.md`). Other simple
26
+ questions need brief answers, without setup or skill searches. Inspect before making
23
27
  project-specific claims. Requests for work mean do the work and verify the requested behavior.
24
28
  Reuse instructions already loaded in the conversation. Continue authorized work independently;
25
29
  one action at a time limits steps the buyer must take. Prefer this project's skills over global
@@ -39,4 +43,8 @@ copies. Do not use helper agents for simple exchanges.
39
43
  - MVC layout: `src/routes/`, `src/controllers/`, `src/middleware/`, `src/services/`.
40
44
  - Use `@vybekiit/*` packages — never reinvent auth, db, or payments.
41
45
  - Secret settings live in `.env` only — never read values aloud in chat.
46
+ - Settings that are not secret (which services the app uses, public ids, web addresses, ports)
47
+ live in `settings.env`, saved with the code. A key listed there is set there; secrets and
48
+ private values stay in `.env`. Never put a secret in `settings.env`. A value the host already
49
+ sets wins over both files.
42
50
  - Session cookies are httpOnly; mobile/extension clients use `APP_URL` pointing here.
@@ -2,7 +2,7 @@
2
2
 
3
3
  | The builder says something like… | Use this skill |
4
4
  |---|---|
5
- | "set up my server", "let's start" | `skills/onboarding.md` |
5
+ | "hi", "help", "what is this", "set up my server", "let's start" | `skills/onboarding.md` |
6
6
  | "let people sign in" | `skills/wire-auth.md` |
7
7
  | "save my data", "add a database" | `skills/wire-database.md` |
8
8
  | "add payments" | `skills/wire-payments.md` |