@rizom/ops 0.2.0-alpha.8 → 0.2.0-alpha.80

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 (51) hide show
  1. package/README.md +7 -3
  2. package/dist/age-key-bootstrap.d.ts +17 -0
  3. package/dist/brains-ops.js +278 -156
  4. package/dist/cert-bootstrap.d.ts +3 -3
  5. package/dist/content-repo.d.ts +13 -0
  6. package/dist/default-user-runner.d.ts +1 -1
  7. package/dist/deploy.js +3 -170
  8. package/dist/entries/deploy.d.ts +2 -2
  9. package/dist/index.d.ts +4 -0
  10. package/dist/index.js +278 -156
  11. package/dist/load-registry.d.ts +22 -3
  12. package/dist/observed-status.d.ts +1 -1
  13. package/dist/onboard-user.d.ts +2 -2
  14. package/dist/origin-ca.d.ts +1 -1
  15. package/dist/parse-args.d.ts +2 -0
  16. package/dist/push-secrets.d.ts +1 -1
  17. package/dist/reconcile-all.d.ts +2 -2
  18. package/dist/reconcile-cohort.d.ts +2 -2
  19. package/dist/reconcile-lib.d.ts +4 -2
  20. package/dist/run-command.d.ts +1 -2
  21. package/dist/run-subprocess.d.ts +1 -0
  22. package/dist/schema.d.ts +107 -0
  23. package/dist/secrets-encrypt.d.ts +29 -0
  24. package/dist/secrets-push.d.ts +1 -1
  25. package/dist/ssh-key-bootstrap.d.ts +1 -1
  26. package/dist/user-add.d.ts +15 -0
  27. package/dist/user-runner.d.ts +5 -0
  28. package/dist/verify-user.d.ts +19 -0
  29. package/package.json +7 -3
  30. package/templates/rover-pilot/.env.schema +16 -2
  31. package/templates/rover-pilot/.github/workflows/build.yml +13 -5
  32. package/templates/rover-pilot/.github/workflows/deploy.yml +73 -20
  33. package/templates/rover-pilot/.github/workflows/reconcile.yml +16 -2
  34. package/templates/rover-pilot/README.md +6 -3
  35. package/templates/rover-pilot/deploy/scripts/decrypt-user-secrets.ts +78 -0
  36. package/templates/rover-pilot/deploy/scripts/provision-server.ts +1 -1
  37. package/templates/rover-pilot/deploy/scripts/resolve-deploy-handles.ts +15 -4
  38. package/templates/rover-pilot/deploy/scripts/resolve-user-config.ts +12 -12
  39. package/templates/rover-pilot/deploy/scripts/sync-content-repo.ts +179 -0
  40. package/templates/rover-pilot/deploy/scripts/update-dns.ts +14 -4
  41. package/templates/rover-pilot/docs/onboarding-checklist.md +40 -14
  42. package/templates/rover-pilot/docs/operator-playbook.md +129 -10
  43. package/templates/rover-pilot/docs/user-onboarding.md +182 -199
  44. package/templates/rover-pilot/package.json +3 -0
  45. package/templates/rover-pilot/pilot.yaml +3 -0
  46. package/templates/rover-pilot/users/alice.yaml +5 -1
  47. package/dist/user-secret-names.d.ts +0 -6
  48. package/templates/rover-pilot/.kamal/hooks/pre-deploy +0 -9
  49. package/templates/rover-pilot/deploy/Caddyfile +0 -66
  50. package/templates/rover-pilot/deploy/Dockerfile +0 -38
  51. package/templates/rover-pilot/deploy/kamal/deploy.yml +0 -40
@@ -1,17 +1,43 @@
1
1
  # Onboarding Checklist
2
2
 
3
3
  1. Run `bun install` so the repo uses its pinned `@rizom/ops` version.
4
- 2. Fill in `pilot.yaml`.
5
- 3. Add or edit `users/<handle>.yaml`.
6
- 4. Add the user to a cohort in `cohorts/*.yaml`.
7
- 5. Run `bunx brains-ops render <repo>`.
8
- 6. Run `bunx brains-ops ssh-key:bootstrap <repo> --push-to gh`.
9
- 7. Run `bunx brains-ops cert:bootstrap <repo> <handle> --push-to gh`.
10
- 8. Run `bunx brains-ops secrets:push <repo> <handle>`.
11
- 9. Run `bunx brains-ops onboard <repo> <handle>`.
12
- 10. Verify the deployed rover core contract:
13
- - `https://<handle>.rizom.ai/health` returns `200`
14
- - unauthenticated `POST https://<handle>.rizom.ai/mcp` returns `401`
15
- 11. For fleet upgrades, edit `pilot.yaml.brainVersion` and push once; CI rebuilds the shared image tag, refreshes generated user env files, and redeploys affected users.
16
- 12. Hand the MCP connection details to the user.
17
- 13. Send `docs/user-onboarding.md` to the user as the pilot handoff guide.
4
+ 2. Run `bunx brains-ops age-key:bootstrap <repo> --push-to gh`.
5
+ 3. Fill in `pilot.yaml`.
6
+ - keep your pinned `brainVersion`
7
+ - confirm shared selectors for `aiApiKey`, `gitSyncToken`, and `contentRepoAdminToken`
8
+ - use different tokens for `contentRepoAdminToken` and `gitSyncToken`: admin creates/checks content repos; sync is used by runtime directory-sync
9
+ - confirm `agePublicKey`
10
+ 4. Run `bunx brains-ops user:add <repo> <handle> --cohort <cohort>`.
11
+ - Discord is enabled by default for pilot users.
12
+ - if the user should be an anchor there, add `--anchor-id <discord-user-id>`.
13
+ - the command creates `users/<handle>.yaml`, `users/<handle>.secrets.yaml`, and the cohort membership without duplicating existing entries.
14
+ 5. Edit the generated user file if the anchor profile needs richer metadata.
15
+ - For browser/CMS-first onboarding, add `setup.delivery: email` and `setup.email` to the user file.
16
+ - Ensure `SETUP_EMAIL_API_KEY` and `SETUP_EMAIL_FROM` exist as GitHub Secrets before deploying any email-setup user.
17
+ 6. Run `bunx brains-ops render <repo>`.
18
+ 7. Run `bunx brains-ops ssh-key:bootstrap <repo> --push-to gh`.
19
+ 8. Run `bunx brains-ops cert:bootstrap <repo> --push-to gh`.
20
+ 9. Keep raw user secret material locally for now (`.env.local`, file-backed env vars, or equivalent local inputs), including `CONTENT_REPO_ADMIN_TOKEN` for operator onboarding.
21
+ 10. Run `bunx brains-ops secrets:encrypt <repo> <handle>`.
22
+ 11. Commit and push `users/<handle>.secrets.yaml.age`.
23
+ 12. Run `bunx brains-ops onboard <repo> <handle>`.
24
+ 13. Verify the deployed Rover contract:
25
+ - all presets:
26
+ - `https://<handle>.rizom.ai/health` returns `200`
27
+ - unauthenticated `POST https://<handle>.rizom.ai/mcp` returns the expected auth failure
28
+ - background jobs are not repeatedly failing, except for expected missing optional integrations
29
+ - for `presetOverride: default` users:
30
+ - `https://<handle>.rizom.ai/` loads the browser/site surface
31
+ - `https://<handle>.rizom.ai/cms` loads the CMS/login surface
32
+ - initial site build completes
33
+ - content repo exists and runtime sync is healthy
34
+ - passkey setup/handoff is completed
35
+ 14. For fleet upgrades, edit `pilot.yaml.brainVersion` and push once; CI rebuilds the shared image tag, refreshes generated user env files, and redeploys affected users.
36
+ 15. For Discord users, hand the Discord setup details to the user. For email-setup users, confirm they received the setup email and completed passkey registration.
37
+ 16. Hand over the browser defaults:
38
+ - Dashboard: `https://<handle>.rizom.ai/`
39
+ - CMS: `https://<handle>.rizom.ai/cms`
40
+ - GitHub token guidance for CMS access to the user's private content repo
41
+ 17. If they need direct client access, use OAuth/passkey-capable clients where possible.
42
+ 18. If you are also giving them a content repo workflow, describe it as optional and frame git/Obsidian as an advanced file-based path, not the default.
43
+ 19. Send `docs/user-onboarding.md` to the user as the pilot handoff guide.
@@ -35,14 +35,21 @@ They are scaffolded from `@rizom/ops`, then versioned in this repo like any othe
35
35
 
36
36
  ## Bootstrap flow
37
37
 
38
+ For this fleet, operator-local secret material remains the source of truth during onboarding and rotation. The repo stores encrypted per-user secrets, not raw values.
39
+
38
40
  For a new pilot user, the operator bootstrap order is:
39
41
 
40
- 1. `bunx brains-ops ssh-key:bootstrap <repo> --push-to gh`
41
- 2. `bunx brains-ops cert:bootstrap <repo> <handle> --push-to gh`
42
- 3. `bunx brains-ops secrets:push <repo> <handle>`
43
- 4. `bunx brains-ops onboard <repo> <handle>`
42
+ 1. `bunx brains-ops age-key:bootstrap <repo> --push-to gh`
43
+ 2. `bunx brains-ops ssh-key:bootstrap <repo> --push-to gh`
44
+ 3. `bunx brains-ops cert:bootstrap <repo> --push-to gh`
45
+ 4. `bunx brains-ops secrets:encrypt <repo> <handle>`
46
+ 5. `bunx brains-ops onboard <repo> <handle>`
47
+
48
+ `age-key:bootstrap` keeps a repo-local canonical age identity under `.brains-ops/age/identity.txt`, writes the matching public recipient to `pilot.yaml.agePublicKey`, and can push the private key to GitHub as `AGE_SECRET_KEY`.
49
+
50
+ The shared cert bootstrap writes local cert artifacts under `.brains-ops/certs/shared/`, which stays repo-local and ignored by git.
44
51
 
45
- `brains-ops cert:bootstrap` writes local cert artifacts under `.brains-ops/`, which stays repo-local and ignored by git.
52
+ Preview hosts use the shape `<handle>-preview.rizom.ai`, so one wildcard origin cert for `*.rizom.ai` covers both the primary and preview hosts for every pilot user.
46
53
 
47
54
  ## Upgrading operator behavior
48
55
 
@@ -53,15 +60,127 @@ When `@rizom/ops` changes the scaffolded deploy contract:
53
60
  3. review the resulting changes to `.env.schema`, `deploy/scripts/`, and workflows in git
54
61
  4. commit the updated deploy artifacts together
55
62
 
56
- ## Rover-core verification notes
63
+ ## Rover verification notes
57
64
 
58
- Rover core is MCP-only. Do not expect the bare domain to serve a website.
65
+ Use the verification script after deploy:
59
66
 
60
- Use these checks after deploy:
67
+ ```sh
68
+ bunx brains-ops verify-user . <handle>
69
+ ```
70
+
71
+ It checks every Rover preset:
61
72
 
62
73
  - `https://<handle>.rizom.ai/health` should return `200`
63
- - unauthenticated `POST https://<handle>.rizom.ai/mcp` should return `401 Unauthorized: Bearer token required`
64
- - a bare `GET /` may also return `401`; that is expected for rover core and does not indicate a bad deploy
74
+ - unauthenticated `POST https://<handle>.rizom.ai/mcp` should return the expected auth failure
75
+ - background jobs should not be repeatedly failing, except for expected missing optional integrations
76
+
77
+ Additional `rover:core` note:
78
+
79
+ - Rover core is MCP-only; a bare `GET /` may return `401`, which does not indicate a bad deploy.
80
+
81
+ For `preset: default`, the script also checks:
82
+
83
+ - `https://<handle>.rizom.ai/` loads the browser/site surface
84
+ - `https://<handle>.rizom.ai/cms` loads the CMS/login surface
85
+
86
+ Manual checks that remain:
87
+
88
+ - initial site build is correct for the expected content/theme
89
+ - content repo exists and runtime sync is healthy beyond the basic `/health` response
90
+ - passkey setup/handoff is completed from the setup email
91
+
92
+ ## One-user `rover:default` baseline canary
93
+
94
+ Run this before adding custom site/theme packages or rolling a larger browser/CMS-first cohort.
95
+
96
+ 1. Create or choose a canary cohort with the default preset:
97
+
98
+ ```yaml
99
+ presetOverride: default
100
+ ```
101
+
102
+ 2. Add exactly one canary user to that cohort.
103
+ 3. For browser/CMS-first onboarding, configure setup email in `users/<handle>.yaml`:
104
+
105
+ ```yaml
106
+ setup:
107
+ delivery: email
108
+ email: user@example.com
109
+ ```
110
+
111
+ 4. Encrypt the user's secrets and commit only the `.age` file.
112
+ 5. Run `bunx brains-ops onboard . <handle>`.
113
+ 6. Run `bunx brains-ops verify-user . <handle>` with no custom site/theme overrides.
114
+ 7. Ask the user to complete passkey setup from the setup email.
115
+ 8. Continue to visual customization only after the canary is healthy.
116
+
117
+ Rollback:
118
+
119
+ - move the canary back to a core cohort, or remove `presetOverride: default` from the cohort
120
+ - reconcile generated outputs
121
+ - rebuild/redeploy the affected user
122
+
123
+ ## Setup email checklist
124
+
125
+ Use this for browser/CMS-first users who should receive their own first-passkey setup link by email.
126
+
127
+ 1. Add setup delivery to the user file:
128
+
129
+ ```yaml
130
+ setup:
131
+ delivery: email
132
+ email: user@example.com
133
+ ```
134
+
135
+ 2. Configure these GitHub Secrets before deploy:
136
+ - `SETUP_EMAIL_API_KEY`
137
+ - `SETUP_EMAIL_FROM`
138
+
139
+ 3. Reconcile/deploy the user or cohort:
140
+ - `bunx brains-ops onboard . <handle>`
141
+ - or `bunx brains-ops reconcile-cohort . <cohort>`
142
+
143
+ 4. Verify the generated `users/<handle>/brain.yaml` contains `auth-service.setupEmail` and `email-resend` config.
144
+ 5. Ask the user to complete passkey setup from the email link, then use:
145
+ - Dashboard: `https://<handle>.rizom.ai/`
146
+ - CMS: `https://<handle>.rizom.ai/cms`
147
+
148
+ Notes:
149
+
150
+ - The setup URL is generated and sent by the running brain; operators should not scrape logs or SSH into the instance to retrieve it.
151
+ - The auth service owns setup email dedupe. It should not resend for the same persisted setup token after restart, but should retry failed delivery and resend after token rotation.
152
+ - `SETUP_EMAIL_FROM` is not marked required because fleets without email setup can omit it, but it is required for users with `setup.delivery: email`.
153
+
154
+ ## Discord bot token checklist
155
+
156
+ Use this when enabling Discord for a pilot user.
157
+
158
+ 1. Pick the user handle (for example `smoke`).
159
+ 2. Open the Discord Developer Portal.
160
+ 3. Create a **new application** for that user's rover.
161
+ 4. Add a **Bot** to the application.
162
+ 5. Copy the bot token.
163
+ 6. Put that value in `.env` or `.env.local` in this repo as `DISCORD_BOT_TOKEN=...` while onboarding that user.
164
+ 7. Keep `discord.enabled: true` in `users/<handle>.yaml` unless you explicitly want to disable the primary pilot interface.
165
+ 8. Encrypt the current per-user secret payload:
166
+ - `bunx brains-ops secrets:encrypt . <handle>`
167
+ 9. Reconcile/deploy the user or cohort:
168
+
169
+ - `bunx brains-ops onboard . <handle>`
170
+ - or `bunx brains-ops reconcile-cohort . <cohort>`
171
+
172
+ 11. In the Discord Developer Portal, generate an install URL and invite the bot to the right server.
173
+ 12. Send a test message in Discord and confirm the rover responds.
174
+
175
+ Notes:
176
+
177
+ - Use **one bot token per user/rover**.
178
+ - Do not reuse the same Discord bot token across multiple pilot users.
179
+ - Discord is the default pilot interface moving forward.
180
+ - The encrypted `users/<handle>.secrets.yaml.age` file is the durable checked-in deploy input; your local env is only the operator staging source.
181
+ - Direct MCP client access should use OAuth/passkey-capable clients where possible.
182
+ - When explaining the content workflow, describe it first as a normal **git repo** of **markdown/text files**.
183
+ - Position **Obsidian** as optional: it is just one possible editor for those same files, not the default requirement.
65
184
 
66
185
  ## Recovery notes
67
186