@rizom/ops 0.2.0-alpha.75 → 0.2.0-alpha.77

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.
@@ -0,0 +1,19 @@
1
+ import type { FetchLike } from "@brains/deploy-support/origin-ca";
2
+ import { type ResolvedUser } from "./load-registry";
3
+ export interface VerifyPilotUserOptions {
4
+ fetchImpl?: FetchLike;
5
+ logger?: (message: string) => void;
6
+ }
7
+ export interface FailedCheck {
8
+ name: string;
9
+ message: string;
10
+ }
11
+ export interface VerifyPilotUserResult {
12
+ handle: string;
13
+ preset: ResolvedUser["preset"];
14
+ domain: string;
15
+ contentRepo: string;
16
+ checks: string[];
17
+ failedChecks: FailedCheck[];
18
+ }
19
+ export declare function verifyPilotUser(rootDir: string, handle: string, options?: VerifyPilotUserOptions): Promise<VerifyPilotUserResult>;
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.2.0-alpha.75",
7
+ "version": "0.2.0-alpha.77",
8
8
  "type": "module",
9
9
  "exports": {
10
10
  ".": {
@@ -21,15 +21,23 @@
21
21
  10. Run `bunx brains-ops secrets:encrypt <repo> <handle>`.
22
22
  11. Commit and push `users/<handle>.secrets.yaml.age`.
23
23
  12. Run `bunx brains-ops onboard <repo> <handle>`.
24
- 13. Verify the deployed rover core contract:
25
- - `https://<handle>.rizom.ai/health` returns `200`
26
- - unauthenticated `POST https://<handle>.rizom.ai/mcp` returns `401`
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
27
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.
28
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.
29
37
  16. Hand over the browser defaults:
30
38
  - Dashboard: `https://<handle>.rizom.ai/`
31
39
  - CMS: `https://<handle>.rizom.ai/cms`
32
40
  - GitHub token guidance for CMS access to the user's private content repo
33
- 17. If they need direct client access, use OAuth/passkey-capable clients where possible; do not use the deprecated static `MCP_AUTH_TOKEN` path for Rover pilot users.
41
+ 17. If they need direct client access, use OAuth/passkey-capable clients where possible.
34
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.
35
43
  19. Send `docs/user-onboarding.md` to the user as the pilot handoff guide.
@@ -60,15 +60,65 @@ When `@rizom/ops` changes the scaffolded deploy contract:
60
60
  3. review the resulting changes to `.env.schema`, `deploy/scripts/`, and workflows in git
61
61
  4. commit the updated deploy artifacts together
62
62
 
63
- ## Rover-core verification notes
63
+ ## Rover verification notes
64
64
 
65
- Rover core is MCP-only. Do not expect the bare domain to serve a website.
65
+ Use the verification script after deploy:
66
66
 
67
- Use these checks after deploy:
67
+ ```sh
68
+ bunx brains-ops verify-user . <handle>
69
+ ```
70
+
71
+ It checks every Rover preset:
68
72
 
69
73
  - `https://<handle>.rizom.ai/health` should return `200`
70
- - unauthenticated `POST https://<handle>.rizom.ai/mcp` should return `401 Unauthorized: Bearer token required`
71
- - 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
72
122
 
73
123
  ## Setup email checklist
74
124
 
@@ -101,38 +151,6 @@ Notes:
101
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.
102
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`.
103
153
 
104
- ## Legacy MCP token cleanup
105
-
106
- Rover pilot onboarding no longer uses the deprecated static `MCP_AUTH_TOKEN` fallback. OAuth/passkeys and setup email are the default browser/CMS path.
107
-
108
- For existing Rover pilot repos:
109
-
110
- 1. Update the checked-in deploy contract first:
111
- - remove `mcpAuthToken` from `pilot.yaml`
112
- - remove `MCP_AUTH_TOKEN` from `.env.schema`
113
- - remove `SHARED_MCP_AUTH_TOKEN` / `MCP_AUTH_TOKEN` exports from `.github/workflows/deploy.yml`
114
- - update `deploy/scripts/decrypt-user-secrets.ts` so it no longer reads or writes `mcpAuthToken`
115
-
116
- 2. Confirm no per-user or cohort MCP overrides exist:
117
-
118
- ```sh
119
- rg "mcpAuthToken|MCP_AUTH_TOKEN" users cohorts pilot.yaml
120
- ```
121
-
122
- 3. If there were no user/cohort overrides, no `.age` re-encryption is needed: the default token lived only as the GitHub Secret named `MCP_AUTH_TOKEN`, not inside `users/<handle>.secrets.yaml.age`.
123
- 4. Redeploy all existing Rover users while the GitHub Secret still exists. A secret existing in GitHub is not inherited by jobs or containers unless the workflow references it.
124
- 5. Verify the new deploy does not pass the token:
125
- - generated `.kamal/secrets` does not contain `MCP_AUTH_TOKEN`
126
- - the running container environment does not contain `MCP_AUTH_TOKEN`
127
-
128
- 6. Delete the unused GitHub Secret last:
129
-
130
- ```sh
131
- gh secret delete MCP_AUTH_TOKEN
132
- ```
133
-
134
- Only decrypt and re-encrypt `users/<handle>.secrets.yaml.age` files if step 2 or a direct audit shows an actual `mcpAuthToken` override was stored there.
135
-
136
154
  ## Discord bot token checklist
137
155
 
138
156
  Use this when enabling Discord for a pilot user.
@@ -160,7 +178,7 @@ Notes:
160
178
  - Do not reuse the same Discord bot token across multiple pilot users.
161
179
  - Discord is the default pilot interface moving forward.
162
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.
163
- - Direct MCP client access should use OAuth/passkey-capable clients where possible; do not reintroduce `MCP_AUTH_TOKEN` for Rover pilot users.
181
+ - Direct MCP client access should use OAuth/passkey-capable clients where possible.
164
182
  - When explaining the content workflow, describe it first as a normal **git repo** of **markdown/text files**.
165
183
  - Position **Obsidian** as optional: it is just one possible editor for those same files, not the default requirement.
166
184