Railway template source for a Codex-first community agent platform:
services/sitefor the public/admin web app and app APIservices/prism-memoryfor the Prism memory APIservices/source-adapterfor source-specific ingestion into Prism memoryservices/prism-triggerfor one-shot cron/ops triggers
Current direction:
- Codex CLI is the primary agent/operator runtime
discord-adapteris the supported Discord bridge for sync plus live chat transportcodex-runtimeis the shared Codex CLI runtime for Discord and future adapterssiteowns the app API and SQLite-backed runtime statecodex-runtimeanddiscord-adaptercallsiteover the internal network
Template authoring notes live in docs/template-authoring.md. Post-deploy template operations live in docs/template-deploy-runbook.md. Non-Railway deployment notes live in docs/local-vps-deployment.md. Prism Memory storage cleanup planning lives in docs/prism-memory-path-cleanup.md. Site/API consolidation planning lives in docs/site-api-consolidation-plan.md. Site/API live cutover steps live in docs/site-api-cutover-checklist.md. Template env deltas for that cutover live in docs/template-site-api-env-delta.md.
This repo is intentionally split by deployable service instead of using PM2 inside one container.
The current folders reflect the work in progress, not the final target shape.
- Railway service:
site - Railway service:
prism-memory - Railway service:
discord-adapter - Railway service:
codex-runtime - Railway service:
discord-sync-cron - Railway service:
memory-cron - Railway service:
knowledge-cron
Recommended deployment model:
- Import this repo into Railway as a JavaScript monorepo.
- Create one service per deployable directory.
- Point each service at its own root directory under
services/. - Keep
prism-memoryon a persistent volume. - Use
services/prism-triggertwice for the cron jobs with different env vars. - Route operator chat through the Discord-to-Codex bridge.
- Mount the app SQLite/data volume on
siteat/data.
Owns:
- public/admin routes
- auth and sessions
- profiles, points, badges, and admin flows
- change requests, executions, targets, and deploy metadata as the system of record
- agent chat sessions and Discord thread linkage as durable conversation state
- the internal app API surface consumed by Codex runtime and Discord
- the app SQLite/runtime volume at
/data
Owns:
- normalized message ingest
- the vendored
prism-memory-starterruntime underprism_seed/default, seeded into the configured runtime space - memory, knowledge, and product retrieval API
- mounted data volume at
/data/prism_seed/<PRISM_API_SPACE> - authenticated
/ops/*routes for collect, digest, memory, seeds, and knowledge jobs
Owns:
- source-specific authentication and collection
- source-specific normalization for Discord, Slack, or Telegram
- posting normalized batches into
prism-memory
Owns:
- Codex CLI-backed chat execution via HTTP
- persisted Codex auth and thread state through
CODEX_HOME - reusable runtime endpoint for Discord, Slack, and the admin console
Does not own:
- durable request state
- execution history as the source of truth
- deploy metadata
- Discord transport concerns
- durable app-side chat session storage
Current scaffold:
GET /healthfor Railway health checksGET /codex/healthPOST /v1/responses
Target direction:
- adapters call one shared Codex runtime instead of embedding it
- persisted Codex thread IDs are mapped to app-side sessions
- Prism Memory is available as optional runtime context, not forced on every turn
Owns:
- source-specific authentication and collection
- source-specific normalization for Discord, Slack, or Telegram
- posting normalized batches into
prism-memory - Discord mention/thread chat transport that forwards to
codex-runtime
Owns:
- one-shot authenticated trigger call into Prism memory
Use two Railway services from this one directory:
memory-cronwithPRISM_TRIGGER_PATH=/ops/memory/runknowledge-cronwithPRISM_TRIGGER_PATH=/ops/knowledge/run
Optionally add a third cron service from the same directory:
discord-sync-cronwithPRISM_API_BASE=https://your-discord-adapter.up.railway.appdiscord-sync-cronwithPRISM_TRIGGER_PATH=/syncdiscord-sync-cronwithPRISM_TRIGGER_AUTH_HEADER=X-Adapter-Tokendiscord-sync-cronwithPRISM_TRIGGER_AUTH_TOKEN=<SOURCE_ADAPTER_TOKEN>
This scaffold is intentionally light. It gives you a deploy shape and starter services, not a full migration of the existing app.
npm run bootstrapThat will:
- create
.envfrom.env.exampleif needed - install all npm workspaces
- create
services/prism-memory/.venv - install the Prism memory Python dependencies
- install the source adapter TypeScript workspace dependencies
Default local ports:
- Site:
3100 - Source adapter:
8789 - Prism memory:
8788
Then work service-by-service:
npm run dev --workspace @prism-railway/siteOr run the whole local stack:
npm run dev:allFor local development, use concrete loopback URLs in .env; Railway template references such as ${{api.RAILWAY_PRIVATE_DOMAIN}} only resolve inside Railway templates.
Minimum local values:
API_INTERNAL_BASE_URL=http://127.0.0.1:3100
NEXT_PUBLIC_API_BASE_URL=http://127.0.0.1:3100
APP_API_BASE_URL=http://127.0.0.1:3100
CODEX_RUNTIME_BASE_URL=http://127.0.0.1:3030
PRISM_API_BASE=http://127.0.0.1:8788
PRISM_API_KEY=replace-me
INTERNAL_SERVICE_TOKEN=replace-me
SOURCE_ADAPTER_TOKEN=replace-me
Codex runtime needs local Codex auth. The default .env.example uses your normal ~/.codex:
CODEX_HOME=$HOME/.codex
Discord and voice transcription are optional locally. Leave these blank unless you want to test Discord sync/chat or /prism-record:
DISCORD_BOT_TOKEN=
DISCORD_GUILD_ID=
VOICE_TRANSCRIPTION_BASE_URL=
VOICE_TRANSCRIPTION_API_KEY=
Shared target bootstrap data should only include stable shared environments such as staging and production.
Do not commit machine-specific local target values such as:
- local filesystem paths
- local app ports
- local dev commands
For example, if you want to work against a local target app checkout, start that app in its own repo and keep the path and port as operator-local knowledge rather than baking them into services/site/config/target-apps.default.json.
Current local example:
- repo:
../example-target-app - app URL:
http://localhost:5173/ - start command:
cd ../example-target-app
nvm use
npm install
npm run devIf the Prism app needs to reference a local target during development, create that target record manually in the local admin/API layer instead of committing it to the shared manifest.
- Each service directory includes its own
railway.json. - Do not use one repo-level
startCommandfor every service. - Set service-specific env vars in Railway, not in source control.
services/source-adapteris the preferred place for Discord/Slack/Telegram collection for memory ingest.services/source-adaptersupports persisted sync checkpoints,dry_run, and resettable sync windows.services/prism-memoryseeds the starter runtime into its mounted volume and keeps the active config at/data/prism_seed/<PRISM_API_SPACE>/config/space.json.prism-memoryandsource-adapterboth use explicit Dockerfiles so the deploy runtime stays pinned and reproducible.
Supporting docs:
For a first Railway bring-up:
- Create services for
site,prism-memory,discord-adapter,codex-runtime,discord-sync-cron,memory-cron, andknowledge-cron. - Set each service root directory to its matching folder under
services/. - Deploy
site, then runmigrate,bootstrap:admin, andbootstrap:targets. - For
prism-memory, mount a persistent volume for runtime state. - Configure
discord-adapterto post normalized batches intoprism-memoryand persist checkpoints on its service volume or data root. - Configure
discord-sync-cronto calldiscord-adapter /syncwithX-Adapter-Token. - Deploy
codex-runtimewith persistentCODEX_HOMEstorage and completecodex loginonce in the running service. - Deploy
discord-adapterwith Discord bot credentials, app API base URL, internal service token, andCODEX_RUNTIME_BASE_URL. - Set shared URLs so
codex-runtimeanddiscord-adapterpoint tosite, and services point toprism-memorywhere needed. - Set secrets in Railway, especially
SESSION_SECRET,INTERNAL_SERVICE_TOKEN,ADMIN_PASSWORD,PRISM_API_KEY,SOURCE_ADAPTER_TOKEN, and Codex/Discord credentials. - Deploy
siteand confirm/adminloads.
API bootstrap split:
npm run migrate --workspace @prism-railway/apinpm run bootstrap:admin --workspace @prism-railway/apinpm run bootstrap:targets --workspace @prism-railway/api- optional:
npm run seed:catalog --workspace @prism-railway/api - optional:
npm run seed:demo --workspace @prism-railway/api
Remote Railway API bootstrap from your local terminal:
npm run railway:bootstrap-api -- \
--environment production \
--service apiCombined deploy and bootstrap flow:
npm run railway:deploy-prism-stack -- \
--prism-api-base https://prism-memory-production.up.railway.app \
--prism-api-key <PRISM_API_KEY> \
--run-memory \
--run-knowledgeThis will:
- deploy
api - run
migrate,bootstrap:admin, andbootstrap:targetsonapi - deploy
site - deploy
prism-memory - optionally trigger
memory.runandknowledge.run
Manual steps still required:
- Codex auth/bootstrap for the chosen runtime
- Discord bridge onboarding
- Railway secret entry
- Railway cron schedule setup. Template instances may create
memory-cron,knowledge-cron, anddiscord-sync-cronwithout recurring schedules; add schedules manually after deploy. Suggested starting points: hourlymemory-cron, dailyknowledge-cron, and 15-60 minutediscord-sync-crononly after Discord is configured.
- Move the API contract first.
- Point the site at the new API.
- Move Prism memory with a volume and normalized ingest.
- Add a source adapter for Discord collection if memory ingestion needs channel history.
- Add the Discord-to-Codex bridge.
- Decide whether to flatten
siteandapiinto one Next.js app. - Add cron triggers last.