@rizom/ops 0.2.0-alpha.28 → 0.2.0-alpha.280

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 (59) hide show
  1. package/README.md +39 -2
  2. package/dist/brains-ops.js +404 -314
  3. package/dist/cert-bootstrap.d.ts +3 -1
  4. package/dist/content-repo-ref.d.ts +10 -0
  5. package/dist/content-repo.d.ts +1 -0
  6. package/dist/deploy.js +99 -166
  7. package/dist/directory-sync-stress-system.d.ts +74 -0
  8. package/dist/directory-sync-stress.d.ts +106 -0
  9. package/dist/entries/deploy.d.ts +3 -2
  10. package/dist/images.d.ts +79 -0
  11. package/dist/index.d.ts +7 -0
  12. package/dist/index.js +479 -298
  13. package/dist/legacy-pilot-migration.d.ts +11 -0
  14. package/dist/load-registry.d.ts +57 -6
  15. package/dist/observed-status.d.ts +1 -1
  16. package/dist/origin-ca.d.ts +1 -1
  17. package/dist/parse-args.d.ts +2 -10
  18. package/dist/preview-domain.d.ts +9 -0
  19. package/dist/push-secrets.d.ts +2 -9
  20. package/dist/push-target.d.ts +1 -2
  21. package/dist/reconcile-dry-run.d.ts +9 -0
  22. package/dist/run-command.d.ts +9 -3
  23. package/dist/run-subprocess.d.ts +1 -6
  24. package/dist/schema.d.ts +114 -162
  25. package/dist/secrets-encrypt.d.ts +7 -13
  26. package/dist/ssh-key-bootstrap.d.ts +1 -26
  27. package/dist/stage-legacy-crossover.d.ts +20 -0
  28. package/dist/stress-command.d.ts +14 -0
  29. package/dist/stress-git-checkout.d.ts +21 -0
  30. package/dist/stress-health-monitor.d.ts +46 -0
  31. package/dist/upgrade.d.ts +10 -0
  32. package/dist/user-add.d.ts +15 -0
  33. package/dist/verify-user.d.ts +19 -0
  34. package/package.json +47 -42
  35. package/templates/rover-pilot/.env.schema +24 -3
  36. package/templates/rover-pilot/.github/actions/varlock-env/action.yml +47 -0
  37. package/templates/rover-pilot/.github/workflows/build.yml +70 -17
  38. package/templates/rover-pilot/.github/workflows/deploy.yml +71 -61
  39. package/templates/rover-pilot/.github/workflows/directory-sync-stress.yml +119 -0
  40. package/templates/rover-pilot/.github/workflows/reconcile.yml +10 -4
  41. package/templates/rover-pilot/.github/workflows/upgrade.yml +58 -0
  42. package/templates/rover-pilot/README.md +14 -6
  43. package/templates/rover-pilot/deploy/scripts/decrypt-user-secrets.ts +80 -24
  44. package/templates/rover-pilot/deploy/scripts/helpers.ts +3 -0
  45. package/templates/rover-pilot/deploy/scripts/install-health-watchdog.ts +144 -0
  46. package/templates/rover-pilot/deploy/scripts/resolve-deploy-handles.ts +12 -3
  47. package/templates/rover-pilot/deploy/scripts/resolve-missing-images.ts +13 -0
  48. package/templates/rover-pilot/deploy/scripts/resolve-user-config.ts +44 -9
  49. package/templates/rover-pilot/deploy/scripts/sync-content-repo.ts +51 -47
  50. package/templates/rover-pilot/deploy/scripts/update-dns.ts +14 -4
  51. package/templates/rover-pilot/deploy/scripts/validate-secrets.ts +12 -1
  52. package/templates/rover-pilot/docs/canonical-crossover-record.md +104 -0
  53. package/templates/rover-pilot/docs/onboarding-checklist.md +29 -13
  54. package/templates/rover-pilot/docs/operator-playbook.md +241 -24
  55. package/templates/rover-pilot/docs/user-onboarding.md +49 -343
  56. package/templates/rover-pilot/pilot.yaml +3 -4
  57. package/templates/rover-pilot/.kamal/hooks/pre-deploy +0 -9
  58. package/templates/rover-pilot/deploy/Dockerfile +0 -30
  59. package/templates/rover-pilot/deploy/kamal/deploy.yml +0 -40
@@ -1,384 +1,90 @@
1
- # Rover Pilot User Onboarding
1
+ # Welcome to your brain
2
2
 
3
- Welcome to the Rover pilot.
3
+ ---
4
4
 
5
- This document is written for **first-time users**. You do **not** need prior experience with Rover, MCP, git, or the rest of the system to get started.
5
+ Most of us have more thinking happening than we can hold onto. Ideas show up in the wrong moment, notes land in five different places, and half of what you've figured out is effectively invisible by the time you need it again.
6
6
 
7
- ## What Rover is
7
+ Your brain is a private space where that thinking accumulates — notes, links, fragments, and half-formed ideas — plus an AI that can work with all of it. It can find things you saved months ago, connect topics, or help turn a rough note into a draft. The more useful material you add, the more useful it becomes.
8
8
 
9
- Rover is your private AI assistant for working with your own notes, links, and ideas.
9
+ ---
10
10
 
11
- In this pilot, Rover is intentionally simple:
11
+ ## What it is
12
12
 
13
- - you will usually talk to it in **Discord**
14
- - **there is no website to browse**
15
- - **MCP is optional** and only needed for direct client access or specific testing workflows
16
- - your content can also live in a normal git repo of markdown/text files; **Obsidian is optional** if you want a nicer note-editing interface
13
+ Your brain is a private knowledge companion. It holds your notes, links, and ideas and helps you think with them, not just store them.
17
14
 
18
- You can think of Rover as a private knowledge companion that helps you:
15
+ Ask a question and it searches what you've saved. Give it a fragment of thinking and it can help develop it.
19
16
 
20
- - save notes
21
- - save links
22
- - reflect on your own material
23
- - find patterns in what you have collected
24
- - think through questions with AI
17
+ ## Getting in
25
18
 
26
- ## What you will receive from us
19
+ We'll send you a personal URL such as `https://<handle>.rizom.ai/`.
27
20
 
28
- We will send you the details you need to get started.
21
+ The first time you open it, you will be asked to set a passkey. No password is required after that.
29
22
 
30
- That usually includes:
23
+ Your main interfaces are:
31
24
 
32
- - confirmation that Discord is enabled for you, plus the invite/setup steps
33
- - if needed, your Rover MCP URL: `https://<handle>.rizom.ai/mcp`
34
- - if needed, your **Bearer token**
35
- - if needed, an invite to your **private** Rover content repo
36
- - any extra instructions if we are testing a specific workflow with your cohort
25
+ - **Chat** (`/chat`) — talk to your brain;
26
+ - **Dashboard/site** (`/`) — the configured browser surface;
27
+ - **CMS** (`/cms`) — edit durable content in a browser.
37
28
 
38
- If we give you a **Bearer token**, treat it like a password. Do not share it.
29
+ Start with Chat.
39
30
 
40
- ## One important idea: Discord is the default, MCP is optional
31
+ ## Your first five minutes
41
32
 
42
- If you are new to Rover, the shortest explanation is:
33
+ 1. Open Chat and say: _Help me save my first note._
34
+ 2. Save a thought, link, or idea. It does not need to be polished.
35
+ 3. Ask about it and inspect what comes back.
43
36
 
44
- - **Rover** is the assistant
45
- - **Discord** is the default way most pilot users will talk to it
46
- - **MCP** is an optional direct connection method for supported AI clients
37
+ That save–ask–use loop is the core workflow.
47
38
 
48
- You do not need to understand the protocol details unless we specifically ask you to use MCP.
39
+ ## Chat or CMS?
49
40
 
50
- For most users, the practical meaning is simple:
41
+ **Chat** is for thinking aloud, asking questions, saving things quickly, and day-to-day work.
51
42
 
52
- - join Discord
53
- - message Rover there
54
- - start using it
43
+ **CMS** is for deliberate browsing and editing. It becomes more useful as your content grows.
55
44
 
56
- If your cohort is also testing MCP, we will send the URL, Bearer token, and setup help separately.
45
+ ## Other interfaces and peer brains
57
46
 
58
- ## What to use first
47
+ Chat is primary. Your configured posture may also enable Discord, Slack, MCP clients, or agent-to-agent calls. We will send setup steps for integrations enabled for your instance.
59
48
 
60
- For most users, the easiest first setup is:
49
+ With permission, you can save another participant's brain as a contact and call it by its shared address:
61
50
 
62
- - **Discord** for talking to Rover
63
- - a normal **git repo of markdown/text files** only if you also want to work directly with your content later
64
- - **Obsidian** only if you want a friendlier interface for those same files
65
- - **Claude Desktop** or another MCP client only if we explicitly ask you to test a direct MCP workflow
51
+ - _Add jane.rizom.ai to my contacts._
52
+ - _Call jane.rizom.ai and ask [your question]._
66
53
 
67
- ## Default setup: Discord
54
+ ## Connecting other tools
68
55
 
69
- For most users, getting started means:
56
+ MCP is a standard protocol that lets compatible AI clients use your brain's tools and lets configured integrations connect to external services. If MCP is part of your setup, we will send specific instructions alongside your URL.
70
57
 
71
- - join the Discord server we send you
72
- - open the Rover channel or DM
73
- - send a first message
58
+ ## Common questions
74
59
 
75
- Try a first message like:
60
+ **How do I access my data?**
76
61
 
77
- > What can you help me do, and what should I use you for?
62
+ Use the CMS. If your cohort includes GitHub access, the same durable markdown also lives in a private repository.
78
63
 
79
- Or:
64
+ **Does it search the public internet?**
80
65
 
81
- > Help me save my first note.
66
+ Not by default. Answers are grounded in your own knowledge unless an explicitly configured integration provides another source.
82
67
 
83
- If Discord is not enabled for you yet, tell us and we will share the right next step.
68
+ **What does this cost?**
84
69
 
85
- ## Optional: direct MCP access
70
+ Nothing during the pilot; hosting is covered by the programme.
86
71
 
87
- If we have asked you to use an MCP client, use one that supports:
72
+ ## This is a pilot
88
73
 
89
- - **HTTP / Streamable HTTP MCP**
90
- - **Bearer token authentication**
74
+ The product works, but it is not finished. You will encounter rough edges and missing behavior. If something breaks or falls short, tell us what you tried, what you expected, and what happened.
91
75
 
92
- When your client asks for connection details, use:
76
+ A built-in wishlist can record unsupported requests as product feedback.
93
77
 
94
- - **Server URL:** `https://<handle>.rizom.ai/mcp`
95
- - **Authentication type:** Bearer token
96
- - **Bearer token:** the token we sent you
78
+ ## Your access details
97
79
 
98
- If the client asks for a name, use something simple like:
99
-
100
- - `Rover (<handle>)`
101
-
102
- ## Optional: Claude Desktop setup
103
-
104
- If we ask you to connect through Claude Desktop and your version supports a **remote HTTP / Streamable HTTP MCP server**, enter:
105
-
106
- - **Server URL:** `https://<handle>.rizom.ai/mcp`
107
- - **Authentication:** Bearer token
108
- - **Token:** the token we sent you
109
-
110
- Then try a first message like:
111
-
112
- > What can you help me do, and what should I use you for?
113
-
114
- Or:
115
-
116
- > Help me save my first note.
117
-
118
- If your Claude Desktop version only supports local MCP servers and not remote HTTP MCP cleanly, tell us what version you are using and we will help you.
119
-
120
- ## Your first 5 minutes
121
-
122
- Once you are connected, try this sequence:
123
-
124
- ### 1. Check that Rover responds
125
-
126
- Ask:
127
-
128
- > What can you help me do?
129
-
130
- ### 2. Save a first note
131
-
132
- Ask:
133
-
134
- > Save a note: I want to use Rover to collect ideas from my work, reading, and conversations.
135
-
136
- ### 3. Save a useful link
137
-
138
- Ask:
139
-
140
- > Save this link and note why it matters to me: <paste URL>
141
-
142
- ### 4. Ask Rover to reflect back what it knows
143
-
144
- Ask:
145
-
146
- > Based on what I’ve stored so far, what themes are starting to emerge?
147
-
148
- ### 5. Use it as a thinking partner
149
-
150
- Ask:
151
-
152
- > I am thinking through a problem in my work. Help me structure the question and identify what context is missing.
153
-
154
- ## Wishlist: when Rover cannot do something yet
155
-
156
- Rover has a built-in **wishlist**.
157
-
158
- This is important for first-time users because Rover will not be able to do everything yet.
159
-
160
- If you ask for something Rover cannot do, it should add that request to the wishlist instead of just failing silently.
161
-
162
- You can think of the wishlist as:
163
-
164
- - a backlog of missing capabilities
165
- - a record of things users want Rover to do
166
- - a way for the pilot team to see which missing features matter most
167
-
168
- ### When the wishlist is useful
169
-
170
- The wishlist is especially useful when you ask Rover to do something like:
171
-
172
- - connect to a tool it does not support yet
173
- - perform an action it cannot perform yet
174
- - add a workflow or feature that does not exist yet
175
-
176
- Examples:
177
-
178
- > I want Rover to draft and send emails for me.
179
-
180
- > I want Rover to connect to my calendar.
181
-
182
- > I want Rover to summarize voice notes automatically.
183
-
184
- If Rover cannot actually do those things yet, it should tell you that and add the request to the wishlist.
185
-
186
- ### What happens when something is added to the wishlist
187
-
188
- When a request is added to the wishlist:
189
-
190
- - it is saved as a **wish**
191
- - it starts in a **new** state
192
- - similar requests can be grouped together instead of creating endless duplicates
193
- - repeated demand can increase the count of how many times that wish was requested
194
-
195
- That helps us see which gaps are one-off ideas and which ones keep coming up across real usage.
196
-
197
- ### How you should use it
198
-
199
- You do **not** need special commands.
200
-
201
- Just ask naturally.
202
-
203
- If Rover cannot do what you asked, a good response from Rover is something like:
204
-
205
- - it explains the limitation clearly
206
- - it says the request was added to the wishlist
207
-
208
- If that does **not** happen, that is useful feedback for us too.
209
-
210
- ## Git, text files, and Obsidian
211
-
212
- The underlying content workflow is a normal **git repo** with normal **markdown/text files**.
213
-
214
- Obsidian is optional. It is just one possible editor for those files.
215
-
216
- That means:
217
-
218
- - use **Discord** as the main way to talk to Rover
219
- - use a normal editor plus **git** if you want to browse, draft, and edit your files directly
220
- - use **Obsidian** only if you want a more note-focused interface for the same files
221
- - Rover can pick up those file changes through the normal git-sync / directory-sync flow
222
-
223
- A simple mental model:
224
-
225
- - **Discord** = talk to Rover
226
- - **git repo + text files** = the underlying content
227
- - **Obsidian** = an optional editor for that content
228
-
229
- ### Important: your content repo is private
230
-
231
- If you use the git/text-file workflow, you will be working in your own **private** GitHub repo.
232
-
233
- That means:
234
-
235
- - you do **not** need repo access just to use Rover in Discord or through MCP
236
- - you **do** need GitHub access if you want to clone, edit, and push to your content repo
237
- - we will invite you only to **your own** content repo, not to the operator repo and not to other users' repos
238
-
239
- ### How you get access
240
-
241
- If you want the git/text-file workflow, we will:
242
-
243
- 1. create or confirm your private content repo
244
- 2. invite your GitHub account to that repo
245
- 3. ask you to accept the GitHub invite
246
- 4. send you the repo URL
247
-
248
- ### Easiest setup for most users
249
-
250
- The easiest path for most first-time users is:
251
-
252
- 1. install **GitHub Desktop**
253
- 2. accept the repo invite in GitHub
254
- 3. clone the private repo with GitHub Desktop
255
- 4. open the cloned folder in your normal editor and edit the markdown/text files directly
256
- 5. optionally open that same folder as an **Obsidian** vault if you prefer
257
- 6. commit and push your changes
258
-
259
- ### Authentication options
260
-
261
- To work with a private repo, you need GitHub authentication.
262
-
263
- Usually the easiest order is:
264
-
265
- 1. **GitHub Desktop** or normal GitHub sign-in
266
- 2. **SSH key** if you already use git that way
267
- 3. a **fine-grained personal access token** only if another tool specifically requires it
268
-
269
- You do **not** need a personal access token just to use Rover in Discord or through MCP.
270
-
271
- If we have already shared your content repo workflow with you, the normal setup is:
272
-
273
- 1. clone your Rover content repo locally
274
- 2. edit the markdown/text files in your normal editor, or open that same folder as an Obsidian vault if you prefer
275
- 3. optionally install the **Obsidian Git** plugin if you want in-app commit/push/pull support
276
- 4. edit or organize your notes there
277
- 5. commit and push your changes through normal git, GitHub Desktop, or the Obsidian Git plugin
278
- 6. let the normal git-sync flow carry those changes into Rover
279
-
280
- If we have **not** given you a direct content repo workflow yet, that is fine. You can ignore git, text files, and Obsidian for now and use Rover in Discord. If we have also asked you to test MCP, you can use that too.
281
-
282
- ## Discord (default)
283
-
284
- Discord is the default interface for this pilot.
285
-
286
- Think of it as the main place to:
287
-
288
- - save quick notes
289
- - drop in links to save
290
- - ask short or long questions
291
- - use Rover day to day without setting up a separate client
292
-
293
- Important:
294
-
295
- - **Discord is the main pilot interface moving forward**
296
- - MCP is **optional**
297
- - if Discord is enabled, we will send the exact invite/setup steps separately
298
- - for some pilot setups, Discord-enabled users may need to supply their own bot token
299
-
300
- If Discord is **not** enabled for you yet, ask us and we will tell you whether your cohort is on the Discord-first workflow.
301
-
302
- ## What to expect in the pilot
303
-
304
- This is a real working system, but it is still an early pilot.
305
-
306
- So you should expect:
307
-
308
- - some rough edges
309
- - a setup process that may still be a bit manual
310
- - a Rover that becomes more useful as you add more notes and links
311
- - occasional follow-up questions from us about your experience
312
- - improvements and changes during the pilot
313
-
314
- That is normal. The point of the pilot is to learn from real use.
315
-
316
- ## Privacy and boundaries
317
-
318
- For the pilot:
319
-
320
- - your Rover is deployed specifically for you
321
- - if you are using MCP, access to `/mcp` is protected by your Bearer token
322
- - you should avoid putting highly sensitive material into the pilot unless we have explicitly agreed that it is in scope
323
-
324
- If you are unsure whether something belongs in Rover, ask us first.
325
-
326
- ## Troubleshooting
327
-
328
- ### I opened the domain and it does not look like a normal site
329
-
330
- That is expected. In this pilot, **there is no website to browse**. Rover runs through Discord and, optionally, a direct MCP endpoint.
331
-
332
- ### I got an authentication error in MCP
333
-
334
- Usually this means one of three things:
335
-
336
- - the Bearer token was missing
337
- - the Bearer token was pasted incorrectly
338
- - the client is using the wrong authentication type
339
-
340
- Double-check that you are using:
341
-
342
- - URL: `https://<handle>.rizom.ai/mcp`
343
- - auth type: **Bearer token**
344
- - token: exactly the token we sent you
345
-
346
- ### My MCP client says it cannot connect
347
-
348
- Some clients support local MCP servers better than remote HTTP MCP servers.
349
-
350
- If that happens, send us:
351
-
352
- - the name of the client
353
- - the version you are using
354
- - the exact error message
355
- - a screenshot if possible
356
-
357
- ## What feedback helps us most
358
-
359
- We especially want to hear:
360
-
361
- - what was confusing during setup
362
- - what felt useful immediately
363
- - what felt weak, awkward, or unclear
364
- - what you expected Rover to do but could not get it to do
365
- - whether you would keep using it after the pilot
366
-
367
- Short, honest feedback is perfect.
368
-
369
- ## Quick handoff template
370
-
371
- When we onboard you, the message will look roughly like this:
80
+ We will send details in this shape:
372
81
 
373
82
  ```text
374
- Discord enabled: yes/no
375
- Discord setup: <invite link or setup steps>
376
- MCP access: optional / enabled / not enabled
377
-
378
- If MCP is enabled:
379
- MCP URL: https://<handle>.rizom.ai/mcp
380
- Auth type: Bearer token
381
- Bearer token: <token>
83
+ Chat URL: https://<handle>.rizom.ai/chat
84
+ Dashboard URL: https://<handle>.rizom.ai/
85
+ CMS URL: https://<handle>.rizom.ai/cms
86
+ Discord: yes/no — setup steps if enabled
87
+ MCP: enabled/not enabled — setup details if enabled
382
88
  ```
383
89
 
384
- If anything is unclear, reply with the exact error text or a screenshot and we will help.
90
+ If anything is unclear, reply with what you see and we will help.
@@ -1,11 +1,10 @@
1
- schemaVersion: 1
2
1
  brainVersion: 0.1.1-alpha.14
3
- model: rover
4
2
  githubOrg: <github-org>
5
3
  contentRepoPrefix: rover-
6
4
  domainSuffix: .rizom.ai
7
- preset: core
5
+ bundles:
6
+ - core
8
7
  aiApiKey: AI_API_KEY
9
8
  gitSyncToken: GIT_SYNC_TOKEN
10
- mcpAuthToken: MCP_AUTH_TOKEN
9
+ contentRepoAdminToken: CONTENT_REPO_ADMIN_TOKEN
11
10
  agePublicKey: age1replace-with-your-public-key
@@ -1,9 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
-
4
- BRAIN_FILE="${BRAIN_YAML_PATH:-brain.yaml}"
5
- SSH_USER="$(ruby -e 'require "yaml"; config = YAML.load_file("deploy/kamal/deploy.yml") || {}; puts(config.dig("ssh", "user") || "root")')"
6
- IFS=',' read -ra HOSTS <<< "$KAMAL_HOSTS"
7
- for host in "${HOSTS[@]}"; do
8
- scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "$BRAIN_FILE" "${SSH_USER}@${host}:/opt/brain.yaml"
9
- done
@@ -1,30 +0,0 @@
1
- ARG BUN_VERSION=1.3.10
2
- FROM oven/bun:${BUN_VERSION}-slim AS runtime
3
-
4
- WORKDIR /app
5
-
6
- RUN apt-get update && apt-get install -y --no-install-recommends \
7
- curl ca-certificates git \
8
- && rm -rf /var/lib/apt/lists/*
9
-
10
- ENV XDG_DATA_HOME=/data
11
- ENV XDG_CONFIG_HOME=/config
12
- RUN mkdir -p /app/data /app/cache /app/brain-data && \
13
- chmod -R 777 /app/data /app/cache /app/brain-data
14
-
15
- EXPOSE 8080
16
-
17
- CMD ["./node_modules/.bin/brain", "start"]
18
-
19
- # --- standalone: bake full project into image (brain-cli deploy) ---
20
- FROM runtime AS standalone
21
- COPY package.json ./package.json
22
- RUN bun install --production --ignore-scripts
23
- COPY . .
24
-
25
- # --- fleet: install published brain at pinned version (ops deploy) ---
26
- FROM runtime AS fleet
27
- ARG BRAIN_VERSION
28
- RUN test -n "$BRAIN_VERSION" \
29
- && printf '{"name":"rover-pilot-runtime","private":true}\n' > package.json \
30
- && bun add @rizom/brain@$BRAIN_VERSION
@@ -1,40 +0,0 @@
1
- service: rover
2
- image: <%= ENV['IMAGE_REPOSITORY'] %>
3
-
4
- servers:
5
- web:
6
- hosts:
7
- - <%= ENV['SERVER_IP'] %>
8
-
9
- proxy:
10
- ssl:
11
- certificate_pem: CERTIFICATE_PEM
12
- private_key_pem: PRIVATE_KEY_PEM
13
- hosts:
14
- - <%= ENV['BRAIN_DOMAIN'] %>
15
- - <%= ENV['PREVIEW_DOMAIN'] %>
16
- app_port: 8080
17
- healthcheck:
18
- path: /health
19
-
20
- registry:
21
- server: ghcr.io
22
- username: <%= ENV['REGISTRY_USERNAME'] %>
23
- password:
24
- - KAMAL_REGISTRY_PASSWORD
25
-
26
- builder:
27
- arch: amd64
28
-
29
- env:
30
- clear:
31
- NODE_ENV: production
32
- secret:
33
- - AI_API_KEY
34
- - GIT_SYNC_TOKEN
35
- - MCP_AUTH_TOKEN
36
- - DISCORD_BOT_TOKEN
37
-
38
- volumes:
39
- - /opt/brain-data:/app/brain-data
40
- - /opt/brain.yaml:/app/brain.yaml