Plan: Move Slack Assistant services into brainforge-platform (Railway)
Date: 2026-03-21
Status: Draft
Audience: Platform / AI team
Goal
Consolidate Slack assistant workloads from the separate Railway project slack-assistant into brainforge-platform, so platform web, workers, and Slack apps share one project for operations, access, and deploy visibility—without changing app behavior unless intentionally updated.
Scope
In scope
- Recreate equivalent Railway services under
brainforge-platform(same repo, sameapps/slack-apps/brainforge-assistantroot). - Copy env configuration, domains, and GitHub deploy wiring; cut over Slack + internal URLs; decommission old services after validation.
- Update repo docs (root directory path, service names) and Platform
RAILWAY_PROJECT_IDSif used.
Out of scope (unless explicitly decided)
- Rewriting the Slack app or merging multiple apps into one Railway service.
- Moving unrelated projects (
google-workspace-mcp,openwork-labs, etc.).
Current vs target
| Today | Target | |
|---|---|---|
| Railway project | slack-assistant | brainforge-platform |
| Services (observed) | Nudge-Agent, brainforge-test-assistant, brainforge-assistant-gh | Same roles as new services (names can match or be renamed for clarity, e.g. brainforge-assistant, brainforge-assistant-test, nudge-agent) |
| Repo / root | brainforge-platform monorepo, subpath deploy | Unchanged: apps/slack-apps/brainforge-assistant |
Note: Railway has no “move service between projects.” Migration is create → copy env → cut over → retire.
Preconditions
- Railway CLI auth:
railway whoami(seestandards/03-knowledge/engineering/setup/railway-cli-setup.md). - Access to Brainforge Slack app settings (URLs for commands, events, interactivity).
- Access to any consumers of assistant base URLs (e.g. HubSpot nudge
BRAINFORGE_ASSISTANT_URL, Linear webhooks, internal docs). - 1Password / secret source for duplicating variables (same items as today, new service targets).
- Agreed naming: whether to keep service names
*-gh/Nudge-Agentor standardize (document the decision before cutover).
Phase 1 — Inventory
- For each service in
slack-assistant, record:- Service name, public URL(s), custom domain(s).
- Root directory (should be
apps/slack-apps/brainforge-assistant). - Builder (Railpack/Nixpacks), build command (
npm install), start command (npm run start). - Full env var set (export from Railway or document names; do not paste secrets into tickets).
- Map which Slack app / slash commands / webhooks point to which URL (prod vs test vs nudge).
- List downstream references:
apps/hubspot-lead-nudge/README.md,standards/.../slack-ticket-approval.md, vault links, any hardcoded*.up.railway.appURLs.
Exit criteria: One table: service → URL → Slack surfaces → dependents.
Phase 2 — Create services in brainforge-platform
railway link --workspace Brainforge --project brainforge-platform --environment production(or staging first if you prefer).- For each required role,
railway add --service <name>(seestandards/03-knowledge/engineering/setup/github-railway-repo-and-services-without-ui.md). - Connect GitHub repo
brainforge-ai/brainforge-platform, branchmain(or your standard). - Set source root directory to
apps/slack-apps/brainforge-assistantfor each service. - Confirm build/start match Phase 1 (typically install +
npm run start). - Do not cut traffic yet: either use temporary Railway-generated URLs or attach domains only after env copy.
Exit criteria: New services build and deploy successfully (health OK) with test or non-prod secrets first if available.
Phase 3 — Copy secrets and behavior flags
- Copy variables from old service → new service (1:1 per role), including Azure, Slack tokens,
REPO_CONTEXT_*, Linear, Ops channel IDs, etc. - Preserve test vs prod semantics:
RAILWAY_ENVIRONMENT_NAME,DEPLOYMENT_BRANCH,TEST_MODE, test Slack tokens—must match howapps/slack-apps/brainforge-assistant/ENVIRONMENT.mddefines test mode.
- Regenerate or reuse public URLs; attach custom domains if the old stack used them.
Exit criteria: Parity checklist signed off per service (same env keys; values verified in a secure way).
Phase 4 — Cutover
- Slack app configuration (per URL that moved):
- Slash commands →
https://<new-host>/slack/commands - Event subscriptions →
https://<new-host>/slack/events - Interactivity →
https://<new-host>/slack/interactive - Linear webhooks (if applicable) →
https://<new-host>/slack/linear-webhook
- Slash commands →
- Update HubSpot nudge (or any job)
BRAINFORGE_ASSISTANT_URLto the production assistant base URL. - Update internal docs / env examples that reference old hostnames.
- Run smoke tests:
- URL verification (Slack)
/brainforgeor prod command,@mention, thread behavior- Test command path if applicable (
/brainforge-test, etc.) - Nudge / internal POST routes if used
- Monitor Railway logs and Slack for 24–48 hours.
Rollback: Keep old services running until cutover is verified; revert Slack URLs and consumer env vars to old base URLs if needed.
Exit criteria: No regressions on critical paths; old URLs no longer required for production traffic.
Phase 5 — Cleanup and governance
- Scale down or delete services in
slack-assistant; archive or delete the empty project when safe. - Platform deploy-status: If
RAILWAY_PROJECT_IDSis set on the web app, remove the old project ID so onlybrainforge-platformremains (seeapps/platform/src/lib/railwayApiServer.tsand.env.example). - Docs:
- Fix
apps/slack-apps/brainforge-assistant/README.md§5: root directoryapps/slack-apps/brainforge-assistant(notslack-apps/...). - Update
knowledge/engineering/railway-setup-review-2026-03-07.md“Current Railway Shape” or add a line “Slack assistant: consolidated intobrainforge-platformas of <date>.”
- Fix
- Optional: add a short operator blurb under
standards/03-knowledge/engineering/setup/(“Slack assistant lives inbrainforge-platform”) if the team wants a single setup pointer.
Risks and mitigations
| Risk | Mitigation |
|---|---|
| Wrong env on new service (prod vs test tokens) | Copy from correct source service; label rows in inventory; smoke test in test channel first. |
| Slack URL cache / typo | Change one surface at a time; keep rollback URLs documented. |
| Missed consumer (cron, another app) | Phase 1 dependency grep + `rg ‘brainforge-assistant |
| Deploy-status noise | Tighten RAILWAY_PROJECT_IDS after consolidation. |
Success criteria
- All Slack assistant traffic for Brainforge uses services under
brainforge-platform. slack-assistantproject retired or empty with team agreement.- Repo and playbook references updated; no stale
slack-apps/brainforge-assistantpath in deployment instructions.
Related
- Prior shape notes:
knowledge/engineering/railway-setup-review-2026-03-07.md - CLI / no-UI service creation:
standards/03-knowledge/engineering/setup/github-railway-repo-and-services-without-ui.md - App env contract:
apps/slack-apps/brainforge-assistant/ENVIRONMENT.md