{
  "manifest_version": "1.0.0",
  "template": {
    "id": "c925f323-da97-4ccb-8df6-8163fc8c56d1",
    "slug": "prism-agent-stack",
    "name": "prism-agent-stack",
    "description": "a template for the prism stack",
    "url": "https://railway.com/deploy/prism-agent-stack",
    "upstream": {
      "repo_url": "https://github.com/superprismio/prism-railway-template"
    }
  },
  "services": [
    {
      "name": "comms-adapter",
      "source": {
        "repo": "https://github.com/superprismio/prism-railway-template"
      },
      "needs_volume": true,
      "volume_mount_path": "/data",
      "http": true
    },
    {
      "name": "codex-runtime",
      "source": {
        "repo": "https://github.com/superprismio/prism-railway-template"
      },
      "needs_volume": true,
      "volume_mount_path": "/data",
      "http": false
    },
    {
      "name": "prism-gateway",
      "source": {
        "repo": "https://github.com/superprismio/prism-railway-template"
      },
      "needs_volume": true,
      "volume_mount_path": "/data",
      "http": false
    },
    {
      "name": "task-runner",
      "source": {
        "repo": "https://github.com/superprismio/prism-railway-template"
      },
      "needs_volume": false,
      "http": false
    },
    {
      "name": "prism-memory",
      "source": {
        "repo": "https://github.com/superprismio/prism-railway-template"
      },
      "needs_volume": true,
      "volume_mount_path": "/data",
      "http": true
    },
    {
      "name": "site",
      "source": {
        "repo": "https://github.com/superprismio/prism-railway-template"
      },
      "needs_volume": true,
      "volume_mount_path": "/data",
      "http": true
    }
  ],
  "required_inputs": [
    {
      "key": "PORT",
      "service": "comms-adapter",
      "description": "Port the Comms adapter listens on.",
      "secret": false,
      "strategy": "default",
      "default": "8789"
    },
    {
      "key": "NODE_ENV",
      "service": "comms-adapter",
      "description": "Runtime environment for the Comms adapter.",
      "secret": false,
      "strategy": "default",
      "default": "production"
    },
    {
      "key": "SOURCE_KIND",
      "service": "comms-adapter",
      "description": "Source provider handled by this adapter.",
      "secret": false,
      "strategy": "default",
      "default": "discord"
    },
    {
      "key": "SOURCE_SPACE",
      "service": "comms-adapter",
      "description": "Prism Memory space this adapter writes into. Must match PRISM_API_SPACE.",
      "secret": false,
      "strategy": "default",
      "default": "community"
    },
    {
      "key": "PRISM_API_KEY",
      "service": "comms-adapter",
      "description": "Prism Memory API key reference.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PRISM_API_BASE",
      "service": "comms-adapter",
      "description": "Private URL for Prism Memory ingest calls.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "APP_API_BASE_URL",
      "service": "comms-adapter",
      "description": "Private URL for the API service using",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "SOURCE_SYNC_MODE",
      "service": "comms-adapter",
      "description": "Sync mode for Discord ingestion.",
      "secret": false,
      "strategy": "default",
      "default": "manual"
    },
    {
      "key": "PRISM_INGEST_PATH",
      "service": "comms-adapter",
      "description": "Prism Memory ingest endpoint path.",
      "secret": false,
      "strategy": "default",
      "default": "/ingest/messages"
    },
    {
      "key": "DISCORD_CHAT_ENABLED",
      "service": "comms-adapter",
      "description": "Enables Discord mention/thread chat bridge.",
      "secret": false,
      "strategy": "default",
      "default": "true"
    },
    {
      "key": "SOURCE_ADAPTER_TOKEN",
      "service": "comms-adapter",
      "description": "Token used to authorize calls to the adapter.",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "VOICE_DAVE_ENCRYPTION",
      "service": "comms-adapter",
      "description": "Enables Discord DAVE voice encryption support when available.",
      "secret": false,
      "strategy": "default",
      "default": "true"
    },
    {
      "key": "CODEX_RUNTIME_BASE_URL",
      "service": "comms-adapter",
      "description": "Private URL",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "INTERNAL_SERVICE_TOKEN",
      "service": "comms-adapter",
      "description": "Internal API service token reference.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "SOURCE_ADAPTER_DATA_ROOT",
      "service": "comms-adapter",
      "description": "Mounted data directory for checkpoints and recordings.",
      "secret": false,
      "strategy": "default",
      "default": "/data"
    },
    {
      "key": "DISCORD_REGISTER_COMMANDS",
      "service": "comms-adapter",
      "description": "Automatically registers Discord slash commands on startup.",
      "secret": false,
      "strategy": "default",
      "default": "true"
    },
    {
      "key": "DISCORD_SYNC_WINDOW_HOURS",
      "service": "comms-adapter",
      "description": "Lookback window for Discord sync.",
      "secret": false,
      "strategy": "default",
      "default": "24"
    },
    {
      "key": "VOICE_TRANSCRIPTION_MODEL",
      "service": "comms-adapter",
      "description": "Model sent to the transcription endpoint.",
      "secret": false,
      "strategy": "default",
      "default": "nvidia/parakeet-tdt-0.6b-v3"
    },
    {
      "key": "DISCORD_EMBED_TEXT_ENABLED",
      "service": "comms-adapter",
      "description": "Enables preservation of Discord embed text.",
      "secret": false,
      "strategy": "default",
      "default": "true"
    },
    {
      "key": "DISCORD_IGNORE_BOT_MESSAGES",
      "service": "comms-adapter",
      "description": "Whether bot messages are skipped during sync.",
      "secret": false,
      "strategy": "default",
      "default": "false"
    },
    {
      "key": "VOICE_TRANSCRIPTION_BASE_URL",
      "service": "comms-adapter",
      "description": "Optional Whisper-compatible",
      "secret": false,
      "strategy": "default",
      "default": "https://api.venice.ai/api/v1/audio/transcriptions"
    },
    {
      "key": "VOICE_TRANSCRIPTION_LANGUAGE",
      "service": "comms-adapter",
      "description": "Optional transcription language hint.",
      "secret": false,
      "strategy": "default",
      "default": "en"
    },
    {
      "key": "PRISM_ARTIFACT_PUBLIC_BASE_URL",
      "service": "comms-adapter",
      "description": "Public url for prism memory artifacts",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "VOICE_CHAT_IGNORE_BOT_MESSAGES",
      "service": "comms-adapter",
      "description": "Skips bot messages when stitching voice channel chat into transcripts.",
      "secret": false,
      "strategy": "default",
      "default": "true"
    },
    {
      "key": "VOICE_TRANSCRIPTION_TIMESTAMPS",
      "service": "comms-adapter",
      "description": "Requests timestamp segments from the transcription endpoint.",
      "secret": false,
      "strategy": "default",
      "default": "true"
    },
    {
      "key": "DISCORD_ATTACHMENT_TEXT_ENABLED",
      "service": "comms-adapter",
      "description": "Enables extraction of text-like Discord attachments.",
      "secret": false,
      "strategy": "default",
      "default": "true"
    },
    {
      "key": "DISCORD_INCLUDE_ARCHIVED_THREADS",
      "service": "comms-adapter",
      "description": "Whether archived threads are included during sync.",
      "secret": false,
      "strategy": "default",
      "default": "false"
    },
    {
      "key": "DISCORD_MAX_MESSAGES_PER_CHANNEL",
      "service": "comms-adapter",
      "description": "Maximum messages fetched per channel per sync.",
      "secret": false,
      "strategy": "default",
      "default": "200"
    },
    {
      "key": "SOURCE_CHECKPOINT_OVERLAP_MINUTES",
      "service": "comms-adapter",
      "description": "Minutes of overlap when resuming Discord sync checkpoints.",
      "secret": false,
      "strategy": "default",
      "default": "5"
    },
    {
      "key": "VOICE_TRANSCRIPTION_RESPONSE_FORMAT",
      "service": "comms-adapter",
      "description": "Response format sent to the transcription endpoint.",
      "secret": false,
      "strategy": "default",
      "default": "json"
    },
    {
      "key": "CODEX_RUNTIME_REQUEST_TIMEOUT_SECONDS",
      "service": "comms-adapter",
      "description": "Timeout for adapter calls to Codex Runtime.",
      "secret": false,
      "strategy": "default",
      "default": "660"
    },
    {
      "key": "PORT",
      "service": "codex-runtime",
      "description": "Port the Codex Runtime service listens on.",
      "secret": false,
      "strategy": "default",
      "default": "3030"
    },
    {
      "key": "NODE_ENV",
      "service": "codex-runtime",
      "description": "Runtime environment for Codex Runtime.",
      "secret": false,
      "strategy": "default",
      "default": "production"
    },
    {
      "key": "CODEX_HOME",
      "service": "codex-runtime",
      "description": "Mounted Codex home directory for auth and thread state.",
      "secret": false,
      "strategy": "default",
      "default": "/data/codex"
    },
    {
      "key": "PRISM_API_KEY",
      "service": "codex-runtime",
      "description": "Prism Memory API key reference.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PRISM_API_BASE",
      "service": "codex-runtime",
      "description": "Private URL for Prism",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "GIT_AUTHOR_NAME",
      "service": "codex-runtime",
      "description": "Git author name used for Codex-created commits.",
      "secret": false,
      "strategy": "default",
      "default": "Prism Codex"
    },
    {
      "key": "APP_API_BASE_URL",
      "service": "codex-runtime",
      "description": "Private URL for the API service using",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "GIT_AUTHOR_EMAIL",
      "service": "codex-runtime",
      "description": "Git author email used for Codex-created commits.",
      "secret": false,
      "strategy": "default",
      "default": "prism-codex@users.noreply.github.com"
    },
    {
      "key": "PRISM_RUNTIME_KEY",
      "service": "codex-runtime",
      "description": "Stable runtime identity used for assignments and audit",
      "secret": true,
      "strategy": "default",
      "default": "codex-default"
    },
    {
      "key": "PRISM_GATEWAY_TOKEN",
      "service": "codex-runtime",
      "description": "Runtime-",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "CODEX_WORKSPACE_ROOT",
      "service": "codex-runtime",
      "description": "Default workspace root for Codex execution.",
      "secret": false,
      "strategy": "default",
      "default": "/app"
    },
    {
      "key": "APP_API_SERVICE_TOKEN",
      "service": "codex-runtime",
      "description": "Internal API service token reference.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PRISM_GATEWAY_ENABLED",
      "service": "codex-runtime",
      "description": "Enables connected services for agent runs",
      "secret": false,
      "strategy": "default",
      "default": "true"
    },
    {
      "key": "PRISM_GATEWAY_BASE_URL",
      "service": "codex-runtime",
      "description": "Provide a value for PRISM_GATEWAY_BASE_URL.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "CODEX_RUNTIME_TIMEOUT_MS",
      "service": "codex-runtime",
      "description": "Maximum Codex execution timeout in milliseconds.",
      "secret": false,
      "strategy": "default",
      "default": "600000"
    },
    {
      "key": "CODEX_TARGET_WORKSPACE_ROOT",
      "service": "codex-runtime",
      "description": "Mounted directory for cloned target repositories.",
      "secret": false,
      "strategy": "default",
      "default": "/data/workspaces"
    },
    {
      "key": "COMMUNICATION_ADAPTER_TOKEN",
      "service": "codex-runtime",
      "description": "direct source adapter token",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "COMMUNICATION_ADAPTER_BASE_URL",
      "service": "codex-runtime",
      "description": "direct source adapter",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "PORT",
      "service": "prism-gateway",
      "description": "Gateway HTTP port",
      "secret": false,
      "strategy": "default",
      "default": "8794"
    },
    {
      "key": "NODE_ENV",
      "service": "prism-gateway",
      "description": "Production runtime mode",
      "secret": false,
      "strategy": "default",
      "default": "production"
    },
    {
      "key": "GATEWAY_SITE_TOKEN",
      "service": "prism-gateway",
      "description": "Authenticates Site administration calls",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "GATEWAY_TASK_RUNNER_TOKEN",
      "service": "prism-gateway",
      "description": "Authenticates Task Runner",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "GATEWAY_MASTER_KEY_VERSION",
      "service": "prism-gateway",
      "description": "Encryption-key version recorded with encrypted",
      "secret": true,
      "strategy": "default",
      "default": "v1"
    },
    {
      "key": "GATEWAY_CODEX_RUNTIME_TOKEN",
      "service": "prism-gateway",
      "description": "Authenticates runtime",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "GATEWAY_MASTER_ENCRYPTION_KEY",
      "service": "prism-gateway",
      "description": "Encrypts credentials stored",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "PORT",
      "service": "task-runner",
      "description": "Task runner HTTP port",
      "secret": false,
      "strategy": "default",
      "default": "8790"
    },
    {
      "key": "PRISM_API_KEY",
      "service": "task-runner",
      "description": "Auth token for Prism Memory",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "APP_API_BASE_URL",
      "service": "task-runner",
      "description": "Provide a value for APP_API_BASE_URL.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "TASK_RUNNER_TOKEN",
      "service": "task-runner",
      "description": "Auth token for manual",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PRISM_GATEWAY_TOKEN",
      "service": "task-runner",
      "description": "Task Runner-specific Gateway caller token",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "TASK_RUNNER_DISABLED",
      "service": "task-runner",
      "description": "Keep scheduler enabled",
      "secret": false,
      "strategy": "default",
      "default": "false"
    },
    {
      "key": "APP_API_SERVICE_TOKEN",
      "service": "task-runner",
      "description": "Auth token for site",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PRISM_GATEWAY_ENABLED",
      "service": "task-runner",
      "description": "Enables Gateway credentials for scheduled jobs",
      "secret": false,
      "strategy": "default",
      "default": "true"
    },
    {
      "key": "PRISM_MEMORY_BASE_URL",
      "service": "task-runner",
      "description": "Provide a value for PRISM_MEMORY_BASE_URL.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "CODEX_RUNTIME_BASE_URL",
      "service": "task-runner",
      "description": "codex runtime for codex-prompt tasks",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "PRISM_GATEWAY_BASE_URL",
      "service": "task-runner",
      "description": "Private Gateway endpoint",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "TASK_RUNNER_POLL_SECONDS",
      "service": "task-runner",
      "description": "Poll DB schedules once per minute",
      "secret": false,
      "strategy": "default",
      "default": "60"
    },
    {
      "key": "COMMUNICATION_ADAPTER_TOKEN",
      "service": "task-runner",
      "description": "Auth token",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "COMMUNICATION_ADAPTER_BASE_URL",
      "service": "task-runner",
      "description": "comms adapter",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "PORT",
      "service": "prism-memory",
      "description": "Port the Prism Memory service listens on.",
      "secret": false,
      "strategy": "default",
      "default": "8788"
    },
    {
      "key": "PRISM_API_KEY",
      "service": "prism-memory",
      "description": "API key used to authorize Prism Memory API calls.",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "PRISM_API_SPACE",
      "service": "prism-memory",
      "description": "Runtime Prism Memory space slug.",
      "secret": false,
      "strategy": "default",
      "default": "community"
    },
    {
      "key": "PRISM_GITHUB_TOKEN",
      "service": "prism-memory",
      "description": "github auth for private repos",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PRISM_API_DATA_ROOT",
      "service": "prism-memory",
      "description": "Mounted data directory for Prism Memory runtime state.",
      "secret": false,
      "strategy": "default",
      "default": "/data"
    },
    {
      "key": "PORT",
      "service": "site",
      "description": "Port the site service listens on.",
      "secret": false,
      "strategy": "default",
      "default": "3100"
    },
    {
      "key": "NODE_ENV",
      "service": "site",
      "description": "Runtime environment for the site service.",
      "secret": false,
      "strategy": "default",
      "default": "production"
    },
    {
      "key": "ADMIN_EMAIL",
      "service": "site",
      "description": "Admin bootstrap email",
      "secret": false,
      "strategy": "default",
      "default": "admin@local.agent"
    },
    {
      "key": "PRISM_API_KEY",
      "service": "site",
      "description": "Full Prism Memory key used",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "ADMIN_PASSWORD",
      "service": "site",
      "description": "Temporary admin password; change after deploy",
      "secret": true,
      "strategy": "default",
      "default": "changeme"
    },
    {
      "key": "SESSION_SECRET",
      "service": "site",
      "description": "Session signing secret for admin auth",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "PRISM_GATEWAY_TOKEN",
      "service": "site",
      "description": "Site-specific",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "TASK_RUNNER_BASE_URL",
      "service": "site",
      "description": "Private task-runner URL for admin Tasks tab and manual runs",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "PRISM_AGENT_DATA_ROOT",
      "service": "site",
      "description": "App SQLite/data root mounted on site",
      "secret": false,
      "strategy": "default",
      "default": "/data"
    },
    {
      "key": "PRISM_GATEWAY_ENABLED",
      "service": "site",
      "description": "Enables Gateway administration in Settings",
      "secret": false,
      "strategy": "default",
      "default": "true"
    },
    {
      "key": "PRISM_MEMORY_BASE_URL",
      "service": "site",
      "description": "Prism Memory base URL",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "CODEX_RUNTIME_BASE_URL",
      "service": "site",
      "description": "Internal Codex runtime base URL",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "INTERNAL_SERVICE_TOKEN",
      "service": "site",
      "description": "Shared internal service token for",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "PRISM_GATEWAY_BASE_URL",
      "service": "site",
      "description": "Provide a value for PRISM_GATEWAY_BASE_URL.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "SITE_USE_LOCAL_APP_API",
      "service": "site",
      "description": "Makes site own the app API and SQLite-backed",
      "secret": false,
      "strategy": "default",
      "default": "true"
    },
    {
      "key": "NEXT_PUBLIC_API_BASE_URL",
      "service": "site",
      "description": "Browser-",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    }
  ],
  "deploy": {
    "mcp": {
      "server": "railway",
      "tool": "deploy_template",
      "args": {
        "template_code": "prism-agent-stack"
      }
    },
    "cli": "railway deploy --template prism-agent-stack",
    "api": {
      "method": "POST",
      "path": "/graphql/v2",
      "body": {
        "query": "mutation templateDeploy($input: TemplateDeployV2Input!) { templateDeployV2(input: $input) { projectId workflowId } }",
        "variables": {
          "input": {
            "templateId": "c925f323-da97-4ccb-8df6-8163fc8c56d1",
            "serializedConfig": {
              "buckets": {},
              "services": {
                "011ce4ea-1a04-4c2a-bee6-26b031278e27": {
                  "icon": "https://hackmd.io/_uploads/ByrAlUHpWg.png",
                  "name": "comms-adapter",
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": "/health",
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "repo": "superprismio/prism-railway-template",
                    "branch": null,
                    "rootDirectory": "/services/source-adapter"
                  },
                  "variables": {
                    "PORT": {
                      "isOptional": false,
                      "description": "Port the Comms adapter listens on.",
                      "defaultValue": "8789"
                    },
                    "NODE_ENV": {
                      "isOptional": false,
                      "description": "Runtime environment for the Comms adapter.",
                      "defaultValue": "production"
                    },
                    "SOURCE_KIND": {
                      "isOptional": false,
                      "description": "Source provider handled by this adapter.",
                      "defaultValue": "discord"
                    },
                    "SOURCE_SPACE": {
                      "isOptional": false,
                      "description": "Prism Memory space this adapter writes into. Must match PRISM_API_SPACE.",
                      "defaultValue": "community"
                    },
                    "PRISM_API_KEY": {
                      "isOptional": false,
                      "description": "Prism Memory API key reference.",
                      "defaultValue": "${{prism-memory.PRISM_API_KEY}}"
                    },
                    "PRISM_API_BASE": {
                      "isOptional": false,
                      "description": "Private URL for Prism Memory ingest calls.",
                      "defaultValue": "https://${{prism-memory.RAILWAY_PRIVATE_DOMAIN}}:${{prism-memory.PORT}}"
                    },
                    "APP_API_BASE_URL": {
                      "isOptional": false,
                      "description": "Private URL for the API service using",
                      "defaultValue": "http://${{site.RAILWAY_PRIVATE_DOMAIN}}:${{site.PORT}}"
                    },
                    "DISCORD_GUILD_ID": {
                      "isOptional": true,
                      "description": "Discord guild ID to sync and serve. Required to enable Discord.",
                      "defaultValue": ""
                    },
                    "SOURCE_SYNC_MODE": {
                      "isOptional": false,
                      "description": "Sync mode for Discord ingestion.",
                      "defaultValue": "manual"
                    },
                    "DISCORD_BOT_TOKEN": {
                      "isOptional": true,
                      "description": "Discord bot token. Required to enable Discord sync/chat.",
                      "defaultValue": ""
                    },
                    "PRISM_INGEST_PATH": {
                      "isOptional": false,
                      "description": "Prism Memory ingest endpoint path.",
                      "defaultValue": "/ingest/messages"
                    },
                    "DISCORD_CHAT_ENABLED": {
                      "isOptional": false,
                      "description": "Enables Discord mention/thread chat bridge.",
                      "defaultValue": "true"
                    },
                    "SOURCE_ADAPTER_TOKEN": {
                      "isOptional": false,
                      "description": "Token used to authorize calls to the adapter.",
                      "defaultValue": "{{SOURCE_ADAPTER_TOKEN}}"
                    },
                    "VOICE_DAVE_ENCRYPTION": {
                      "isOptional": false,
                      "description": "Enables Discord DAVE voice encryption support when available.",
                      "defaultValue": "true"
                    },
                    "CODEX_RUNTIME_BASE_URL": {
                      "isOptional": false,
                      "description": "Private URL",
                      "defaultValue": "http://${{codex-runtime.RAILWAY_PRIVATE_DOMAIN}}:${{codex-runtime.PORT}}"
                    },
                    "DISCORD_APPLICATION_ID": {
                      "isOptional": true,
                      "description": "Optional Discord application ID. Recommended for slash command registration.",
                      "defaultValue": ""
                    },
                    "INTERNAL_SERVICE_TOKEN": {
                      "isOptional": false,
                      "description": "Internal API service token reference.",
                      "defaultValue": "${{site.INTERNAL_SERVICE_TOKEN}}"
                    },
                    "SOURCE_ADAPTER_DATA_ROOT": {
                      "isOptional": false,
                      "description": "Mounted data directory for checkpoints and recordings.",
                      "defaultValue": "/data"
                    },
                    "DISCORD_REGISTER_COMMANDS": {
                      "isOptional": false,
                      "description": "Automatically registers Discord slash commands on startup.",
                      "defaultValue": "true"
                    },
                    "DISCORD_SYNC_WINDOW_HOURS": {
                      "isOptional": false,
                      "description": "Lookback window for Discord sync.",
                      "defaultValue": "24"
                    },
                    "VOICE_TRANSCRIPTION_MODEL": {
                      "description": "Model sent to the transcription endpoint.",
                      "defaultValue": "nvidia/parakeet-tdt-0.6b-v3"
                    },
                    "DISCORD_EMBED_TEXT_ENABLED": {
                      "isOptional": false,
                      "description": "Enables preservation of Discord embed text.",
                      "defaultValue": "true"
                    },
                    "DISCORD_IGNORE_BOT_MESSAGES": {
                      "isOptional": false,
                      "description": "Whether bot messages are skipped during sync.",
                      "defaultValue": "false"
                    },
                    "VOICE_TRANSCRIPTION_API_KEY": {
                      "isOptional": true,
                      "description": "Optional API key for the configured voice transcription endpoint.",
                      "defaultValue": ""
                    },
                    "VOICE_TRANSCRIPTION_BASE_URL": {
                      "description": "Optional Whisper-compatible",
                      "defaultValue": "https://api.venice.ai/api/v1/audio/transcriptions"
                    },
                    "VOICE_TRANSCRIPTION_LANGUAGE": {
                      "description": "Optional transcription language hint.",
                      "defaultValue": "en"
                    },
                    "PRISM_ARTIFACT_PUBLIC_BASE_URL": {
                      "isOptional": false,
                      "description": "Public url for prism memory artifacts",
                      "defaultValue": "https://${{prism-memory.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "VOICE_CHAT_IGNORE_BOT_MESSAGES": {
                      "isOptional": false,
                      "description": "Skips bot messages when stitching voice channel chat into transcripts.",
                      "defaultValue": "true"
                    },
                    "VOICE_TRANSCRIPTION_TIMESTAMPS": {
                      "description": "Requests timestamp segments from the transcription endpoint.",
                      "defaultValue": "true"
                    },
                    "DISCORD_ATTACHMENT_TEXT_ENABLED": {
                      "isOptional": false,
                      "description": "Enables extraction of text-like Discord attachments.",
                      "defaultValue": "true"
                    },
                    "DISCORD_INCLUDE_ARCHIVED_THREADS": {
                      "isOptional": false,
                      "description": "Whether archived threads are included during sync.",
                      "defaultValue": "false"
                    },
                    "DISCORD_MAX_MESSAGES_PER_CHANNEL": {
                      "isOptional": false,
                      "description": "Maximum messages fetched per channel per sync.",
                      "defaultValue": "200"
                    },
                    "SOURCE_CHECKPOINT_OVERLAP_MINUTES": {
                      "isOptional": false,
                      "description": "Minutes of overlap when resuming Discord sync checkpoints.",
                      "defaultValue": "5"
                    },
                    "VOICE_TRANSCRIPTION_RESPONSE_FORMAT": {
                      "description": "Response format sent to the transcription endpoint.",
                      "defaultValue": "json"
                    },
                    "CODEX_RUNTIME_REQUEST_TIMEOUT_SECONDS": {
                      "isOptional": false,
                      "description": "Timeout for adapter calls to Codex Runtime.",
                      "defaultValue": "660"
                    }
                  },
                  "networking": {
                    "serviceDomains": {
                      "<hasDomain>": {}
                    }
                  },
                  "volumeMounts": {
                    "011ce4ea-1a04-4c2a-bee6-26b031278e27": {
                      "mountPath": "/data"
                    }
                  }
                },
                "4d9798bf-6591-46c8-af7d-d336ad19cf76": {
                  "icon": "https://hackmd.io/_uploads/ByrAlUHpWg.png",
                  "name": "codex-runtime",
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": "/health",
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "repo": "superprismio/prism-railway-template",
                    "branch": null,
                    "rootDirectory": "/services/codex-runtime"
                  },
                  "variables": {
                    "PORT": {
                      "isOptional": false,
                      "description": "Port the Codex Runtime service listens on.",
                      "defaultValue": "3030"
                    },
                    "NODE_ENV": {
                      "isOptional": false,
                      "description": "Runtime environment for Codex Runtime.",
                      "defaultValue": "production"
                    },
                    "CODEX_HOME": {
                      "isOptional": false,
                      "description": "Mounted Codex home directory for auth and thread state.",
                      "defaultValue": "/data/codex"
                    },
                    "PRISM_API_KEY": {
                      "isOptional": false,
                      "description": "Prism Memory API key reference.",
                      "defaultValue": "${{prism-memory.PRISM_API_KEY}}"
                    },
                    "PRISM_API_BASE": {
                      "isOptional": false,
                      "description": "Private URL for Prism",
                      "defaultValue": "http://${{prism-memory.RAILWAY_PRIVATE_DOMAIN}}:${{prism-memory.PORT}}"
                    },
                    "GIT_AUTHOR_NAME": {
                      "isOptional": false,
                      "description": "Git author name used for Codex-created commits.",
                      "defaultValue": "Prism Codex"
                    },
                    "APP_API_BASE_URL": {
                      "isOptional": false,
                      "description": "Private URL for the API service using",
                      "defaultValue": "http://${{site.RAILWAY_PRIVATE_DOMAIN}}:${{site.PORT}}"
                    },
                    "GIT_AUTHOR_EMAIL": {
                      "isOptional": false,
                      "description": "Git author email used for Codex-created commits.",
                      "defaultValue": "prism-codex@users.noreply.github.com"
                    },
                    "PRISM_RUNTIME_KEY": {
                      "description": "Stable runtime identity used for assignments and audit",
                      "defaultValue": "codex-default"
                    },
                    "PRISM_GATEWAY_TOKEN": {
                      "description": "Runtime-",
                      "defaultValue": "${{prism-gateway.GATEWAY_CODEX_RUNTIME_TOKEN}}"
                    },
                    "CODEX_WORKSPACE_ROOT": {
                      "isOptional": false,
                      "description": "Default workspace root for Codex execution.",
                      "defaultValue": "/app"
                    },
                    "APP_API_SERVICE_TOKEN": {
                      "isOptional": false,
                      "description": "Internal API service token reference.",
                      "defaultValue": "${{site.INTERNAL_SERVICE_TOKEN}}"
                    },
                    "PRISM_GATEWAY_ENABLED": {
                      "description": "Enables connected services for agent runs",
                      "defaultValue": "true"
                    },
                    "PRISM_GATEWAY_BASE_URL": {
                      "defaultValue": "http://${{prism-gateway.RAILWAY_PRIVATE_DOMAIN}}:${{prism-gateway.PORT}}"
                    },
                    "CODEX_RUNTIME_TIMEOUT_MS": {
                      "isOptional": false,
                      "description": "Maximum Codex execution timeout in milliseconds.",
                      "defaultValue": "600000"
                    },
                    "TARGET_REPO_GITHUB_TOKEN": {
                      "isOptional": true,
                      "description": "Optional GitHub token for cloning or pushing private target repositories.",
                      "defaultValue": ""
                    },
                    "CODEX_TARGET_WORKSPACE_ROOT": {
                      "isOptional": false,
                      "description": "Mounted directory for cloned target repositories.",
                      "defaultValue": "/data/workspaces"
                    },
                    "COMMUNICATION_ADAPTER_TOKEN": {
                      "description": "direct source adapter token",
                      "defaultValue": "${{comms-adapter.SOURCE_ADAPTER_TOKEN}}"
                    },
                    "COMMUNICATION_ADAPTER_BASE_URL": {
                      "description": "direct source adapter",
                      "defaultValue": "http://${{comms-adapter.RAILWAY_PRIVATE_DOMAIN}}:${{comms-adapter.PORT}}"
                    }
                  },
                  "volumeMounts": {
                    "4d9798bf-6591-46c8-af7d-d336ad19cf76": {
                      "mountPath": "/data"
                    }
                  }
                },
                "93a58885-ffbb-4a92-aea6-352b8393f141": {
                  "name": "prism-gateway",
                  "deploy": {
                    "healthcheckPath": "/health"
                  },
                  "source": {
                    "repo": "superprismio/prism-railway-template",
                    "branch": null,
                    "rootDirectory": "/services/prism-gateway"
                  },
                  "variables": {
                    "PORT": {
                      "description": "Gateway HTTP port",
                      "defaultValue": "8794"
                    },
                    "NODE_ENV": {
                      "description": "Production runtime mode",
                      "defaultValue": "production"
                    },
                    "GATEWAY_SITE_TOKEN": {
                      "description": "Authenticates Site administration calls",
                      "defaultValue": "{{GATEWAY_SITE_TOKEN}}"
                    },
                    "GATEWAY_TASK_RUNNER_TOKEN": {
                      "description": "Authenticates Task Runner",
                      "defaultValue": "{{GATEWAY_TASK_RUNNER_TOKEN}}"
                    },
                    "GATEWAY_MASTER_KEY_VERSION": {
                      "description": "Encryption-key version recorded with encrypted",
                      "defaultValue": "v1"
                    },
                    "GATEWAY_CODEX_RUNTIME_TOKEN": {
                      "description": "Authenticates runtime",
                      "defaultValue": "{{GATEWAY_CODEX_RUNTIME_TOKEN}}"
                    },
                    "GATEWAY_MASTER_ENCRYPTION_KEY": {
                      "description": "Encrypts credentials stored",
                      "defaultValue": "{{GATEWAY_MASTER_ENCRYPTION_KEY}}"
                    }
                  },
                  "volumeMounts": {
                    "93a58885-ffbb-4a92-aea6-352b8393f141": {
                      "mountPath": "/data"
                    }
                  }
                },
                "d180e163-8167-4d1e-a25b-8f5154b379d3": {
                  "name": "task-runner",
                  "deploy": {
                    "healthcheckPath": "/health"
                  },
                  "source": {
                    "repo": "superprismio/prism-railway-template",
                    "branch": null,
                    "rootDirectory": "/services/task-runner"
                  },
                  "variables": {
                    "PORT": {
                      "description": "Task runner HTTP port",
                      "defaultValue": "8790"
                    },
                    "PRISM_API_KEY": {
                      "description": "Auth token for Prism Memory",
                      "defaultValue": "${{prism-memory.PRISM_API_KEY}}"
                    },
                    "APP_API_BASE_URL": {
                      "defaultValue": "http://${{site.RAILWAY_PRIVATE_DOMAIN}}:${{site.PORT}}"
                    },
                    "TASK_RUNNER_TOKEN": {
                      "description": "Auth token for manual",
                      "defaultValue": "${{site.INTERNAL_SERVICE_TOKEN}}"
                    },
                    "PRISM_GATEWAY_TOKEN": {
                      "description": "Task Runner-specific Gateway caller token",
                      "defaultValue": "${{prism-gateway.GATEWAY_TASK_RUNNER_TOKEN}}"
                    },
                    "TASK_RUNNER_DISABLED": {
                      "description": "Keep scheduler enabled",
                      "defaultValue": "false"
                    },
                    "APP_API_SERVICE_TOKEN": {
                      "description": "Auth token for site",
                      "defaultValue": "${{site.INTERNAL_SERVICE_TOKEN}}"
                    },
                    "PRISM_GATEWAY_ENABLED": {
                      "description": "Enables Gateway credentials for scheduled jobs",
                      "defaultValue": "true"
                    },
                    "PRISM_MEMORY_BASE_URL": {
                      "defaultValue": "http://${{prism-memory.RAILWAY_PRIVATE_DOMAIN}}:${{prism-memory.PORT}}"
                    },
                    "CODEX_RUNTIME_BASE_URL": {
                      "isOptional": false,
                      "description": "codex runtime for codex-prompt tasks",
                      "defaultValue": "http://${{codex-runtime.RAILWAY_PRIVATE_DOMAIN}}:${{codex-runtime.PORT}}"
                    },
                    "PRISM_GATEWAY_BASE_URL": {
                      "description": "Private Gateway endpoint",
                      "defaultValue": "http://${{prism-gateway.RAILWAY_PRIVATE_DOMAIN}}:${{prism-gateway.PORT}}"
                    },
                    "TASK_RUNNER_POLL_SECONDS": {
                      "description": "Poll DB schedules once per minute",
                      "defaultValue": "60"
                    },
                    "COMMUNICATION_ADAPTER_TOKEN": {
                      "description": "Auth token",
                      "defaultValue": "${{comms-adapter.SOURCE_ADAPTER_TOKEN}}"
                    },
                    "COMMUNICATION_ADAPTER_BASE_URL": {
                      "description": "comms adapter",
                      "defaultValue": "http://${{comms-adapter.RAILWAY_PRIVATE_DOMAIN}}:${{comms-adapter.PORT}}"
                    }
                  }
                },
                "f6f7b640-dee9-4d45-8a48-47411363782f": {
                  "icon": "https://hackmd.io/_uploads/ByrAlUHpWg.png",
                  "name": "prism-memory",
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": "/health"
                  },
                  "source": {
                    "repo": "superprismio/prism-railway-template",
                    "branch": null,
                    "rootDirectory": "/services/prism-memory"
                  },
                  "variables": {
                    "PORT": {
                      "isOptional": false,
                      "description": "Port the Prism Memory service listens on.",
                      "defaultValue": "8788"
                    },
                    "PRISM_API_KEY": {
                      "isOptional": false,
                      "description": "API key used to authorize Prism Memory API calls.",
                      "defaultValue": "{{PRISM_API_KEY}}"
                    },
                    "PRISM_API_SPACE": {
                      "isOptional": false,
                      "description": "Runtime Prism Memory space slug.",
                      "defaultValue": "community"
                    },
                    "PRISM_GITHUB_TOKEN": {
                      "isOptional": false,
                      "description": "github auth for private repos",
                      "defaultValue": "${{codex-runtime.TARGET_REPO_GITHUB_TOKEN}}"
                    },
                    "PRISM_API_DATA_ROOT": {
                      "isOptional": false,
                      "description": "Mounted data directory for Prism Memory runtime state.",
                      "defaultValue": "/data"
                    }
                  },
                  "networking": {
                    "serviceDomains": {
                      "<hasDomain>": {}
                    }
                  },
                  "volumeMounts": {
                    "f6f7b640-dee9-4d45-8a48-47411363782f": {
                      "mountPath": "/data"
                    }
                  }
                },
                "feeb07c7-85e6-4aab-a468-3cd378029d85": {
                  "icon": "https://hackmd.io/_uploads/ByrAlUHpWg.png",
                  "name": "site",
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": "/api/health",
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "repo": "superprismio/prism-railway-template",
                    "branch": null,
                    "rootDirectory": "/services/site"
                  },
                  "variables": {
                    "PORT": {
                      "isOptional": false,
                      "description": "Port the site service listens on.",
                      "defaultValue": "3100"
                    },
                    "NODE_ENV": {
                      "isOptional": false,
                      "description": "Runtime environment for the site service.",
                      "defaultValue": "production"
                    },
                    "ADMIN_EMAIL": {
                      "description": "Admin bootstrap email",
                      "defaultValue": "admin@local.agent"
                    },
                    "PRISM_API_KEY": {
                      "isOptional": false,
                      "description": "Full Prism Memory key used",
                      "defaultValue": "${{prism-memory.PRISM_API_KEY}}"
                    },
                    "ADMIN_PASSWORD": {
                      "description": "Temporary admin password; change after deploy",
                      "defaultValue": "changeme"
                    },
                    "SESSION_SECRET": {
                      "description": "Session signing secret for admin auth",
                      "defaultValue": "{{SESSION_SECRET}}"
                    },
                    "PRISM_GATEWAY_TOKEN": {
                      "description": "Site-specific",
                      "defaultValue": "${{prism-gateway.GATEWAY_SITE_TOKEN}}"
                    },
                    "TASK_RUNNER_BASE_URL": {
                      "description": "Private task-runner URL for admin Tasks tab and manual runs",
                      "defaultValue": "http://${{task-runner.RAILWAY_PRIVATE_DOMAIN}}:${{task-runner.PORT}}"
                    },
                    "PRISM_AGENT_DATA_ROOT": {
                      "description": "App SQLite/data root mounted on site",
                      "defaultValue": "/data"
                    },
                    "PRISM_GATEWAY_ENABLED": {
                      "description": "Enables Gateway administration in Settings",
                      "defaultValue": "true"
                    },
                    "PRISM_MEMORY_BASE_URL": {
                      "isOptional": false,
                      "description": "Prism Memory base URL",
                      "defaultValue": "http://${{prism-memory.RAILWAY_PRIVATE_DOMAIN}}:${{prism-memory.PORT}}"
                    },
                    "CODEX_RUNTIME_BASE_URL": {
                      "description": "Internal Codex runtime base URL",
                      "defaultValue": "http://${{codex-runtime.RAILWAY_PRIVATE_DOMAIN}}:${{codex-runtime.PORT}}"
                    },
                    "INTERNAL_SERVICE_TOKEN": {
                      "description": "Shared internal service token for",
                      "defaultValue": "{{INTERNAL_SERVICE_TOKEN}}"
                    },
                    "PRISM_GATEWAY_BASE_URL": {
                      "defaultValue": "http://${{prism-gateway.RAILWAY_PRIVATE_DOMAIN}}:${{prism-gateway.PORT}}"
                    },
                    "SITE_USE_LOCAL_APP_API": {
                      "description": "Makes site own the app API and SQLite-backed",
                      "defaultValue": "true"
                    },
                    "NEXT_PUBLIC_API_BASE_URL": {
                      "isOptional": false,
                      "description": "Browser-",
                      "defaultValue": "https://${{site.RAILWAY_PUBLIC_DOMAIN}}"
                    }
                  },
                  "networking": {
                    "serviceDomains": {
                      "<hasDomain>": {}
                    }
                  },
                  "volumeMounts": {
                    "feeb07c7-85e6-4aab-a468-3cd378029d85": {
                      "mountPath": "/data"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "post_deploy": {
    "healthcheck": {
      "service": "comms-adapter",
      "method": "GET",
      "path": "/health",
      "expect_status": 200
    }
  },
  "resources": {
    "expected_services": 6,
    "needs_volume": true
  },
  "generated_at": "2026-09-10T16:14:52.212Z",
  "generator_version": "0.1.0",
  "status": "degraded",
  "validated_at": "2026-09-09T08:39:23.242Z",
  "success_rate_30d": 0,
  "validation": {
    "last_run_id": "run_17ffab8d15bc4d559016",
    "checks": [
      {
        "name": "workflow_completed",
        "passed": true
      },
      {
        "name": "all_services_deployed",
        "passed": false,
        "detail": "SUCCESS,FAILED,SUCCESS,DEPLOYING,DEPLOYING,DEPLOYING"
      }
    ]
  }
}
