@rizom/ops 0.2.0-alpha.6 → 0.2.0-alpha.600

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 (82) hide show
  1. package/README.md +88 -4
  2. package/dist/age-key-bootstrap.d.ts +17 -0
  3. package/dist/brains-ops.js +790 -166
  4. package/dist/capability-bundle-migration.d.ts +22 -0
  5. package/dist/cert-bootstrap.d.ts +6 -4
  6. package/dist/content-repo-ref.d.ts +10 -0
  7. package/dist/content-repo.d.ts +13 -0
  8. package/dist/default-user-runner.d.ts +1 -1
  9. package/dist/deploy.js +110 -166
  10. package/dist/directory-sync-stress-system.d.ts +75 -0
  11. package/dist/directory-sync-stress.d.ts +117 -0
  12. package/dist/entries/deploy.d.ts +4 -2
  13. package/dist/health-watchdog-smoke.d.ts +54 -0
  14. package/dist/image-inventory.d.ts +4 -0
  15. package/dist/image-types.d.ts +7 -0
  16. package/dist/images.d.ts +89 -0
  17. package/dist/index.d.ts +11 -0
  18. package/dist/index.js +802 -166
  19. package/dist/legacy-pilot-migration.d.ts +11 -0
  20. package/dist/legacy-projection-job-recovery.d.ts +29 -0
  21. package/dist/load-registry.d.ts +88 -6
  22. package/dist/observed-status.d.ts +1 -1
  23. package/dist/onboard-user.d.ts +2 -2
  24. package/dist/parse-args.d.ts +2 -10
  25. package/dist/preview-domain.d.ts +9 -0
  26. package/dist/reconcile-all.d.ts +2 -2
  27. package/dist/reconcile-cohort.d.ts +2 -2
  28. package/dist/reconcile-dry-run.d.ts +9 -0
  29. package/dist/reconcile-lib.d.ts +4 -2
  30. package/dist/run-command.d.ts +22 -6
  31. package/dist/runtime-image-lock.d.ts +12 -0
  32. package/dist/schema.d.ts +147 -69
  33. package/dist/secrets-encrypt.d.ts +26 -0
  34. package/dist/secrets-push.d.ts +2 -2
  35. package/dist/ssh-key-bootstrap.d.ts +1 -26
  36. package/dist/stage-legacy-crossover.d.ts +25 -0
  37. package/dist/stress-command.d.ts +14 -0
  38. package/dist/stress-git-checkout.d.ts +21 -0
  39. package/dist/stress-health-monitor.d.ts +46 -0
  40. package/dist/upgrade.d.ts +10 -0
  41. package/dist/user-add.d.ts +16 -0
  42. package/dist/user-offboard.d.ts +61 -0
  43. package/dist/user-runner.d.ts +5 -0
  44. package/dist/verify-user.d.ts +22 -0
  45. package/package.json +51 -40
  46. package/templates/rover-pilot/.env.schema +28 -2
  47. package/templates/rover-pilot/.github/actions/varlock-env/action.yml +47 -0
  48. package/templates/rover-pilot/.github/workflows/build.yml +72 -17
  49. package/templates/rover-pilot/.github/workflows/deploy.yml +118 -49
  50. package/templates/rover-pilot/.github/workflows/directory-sync-stress.yml +119 -0
  51. package/templates/rover-pilot/.github/workflows/health-watchdog-smoke.yml +95 -0
  52. package/templates/rover-pilot/.github/workflows/offboard.yml +107 -0
  53. package/templates/rover-pilot/.github/workflows/reconcile.yml +23 -3
  54. package/templates/rover-pilot/.github/workflows/upgrade.yml +104 -0
  55. package/templates/rover-pilot/README.md +19 -8
  56. package/templates/rover-pilot/deploy/scripts/create-predeploy-backup.ts +948 -0
  57. package/templates/rover-pilot/deploy/scripts/decrypt-user-secrets.ts +139 -0
  58. package/templates/rover-pilot/deploy/scripts/helpers.ts +3 -0
  59. package/templates/rover-pilot/deploy/scripts/install-health-watchdog.ts +144 -0
  60. package/templates/rover-pilot/deploy/scripts/provision-server.ts +52 -22
  61. package/templates/rover-pilot/deploy/scripts/resolve-deploy-handles.ts +19 -4
  62. package/templates/rover-pilot/deploy/scripts/resolve-missing-images.ts +13 -0
  63. package/templates/rover-pilot/deploy/scripts/resolve-user-config.ts +56 -14
  64. package/templates/rover-pilot/deploy/scripts/sync-content-repo.ts +183 -0
  65. package/templates/rover-pilot/deploy/scripts/update-dns.ts +72 -16
  66. package/templates/rover-pilot/deploy/scripts/validate-secrets.ts +12 -1
  67. package/templates/rover-pilot/deploy/scripts/verify-runtime-image.ts +18 -0
  68. package/templates/rover-pilot/docs/canonical-crossover-record.md +107 -0
  69. package/templates/rover-pilot/docs/onboarding-checklist.md +39 -13
  70. package/templates/rover-pilot/docs/operator-playbook.md +421 -22
  71. package/templates/rover-pilot/docs/user-onboarding.md +90 -0
  72. package/templates/rover-pilot/package.json +4 -0
  73. package/templates/rover-pilot/pilot.yaml +9 -3
  74. package/templates/rover-pilot/users/alice.yaml +5 -1
  75. package/dist/origin-ca.d.ts +0 -1
  76. package/dist/push-secrets.d.ts +0 -9
  77. package/dist/push-target.d.ts +0 -2
  78. package/dist/run-subprocess.d.ts +0 -5
  79. package/dist/user-secret-names.d.ts +0 -6
  80. package/templates/rover-pilot/.kamal/hooks/pre-deploy +0 -9
  81. package/templates/rover-pilot/deploy/Dockerfile +0 -15
  82. package/templates/rover-pilot/deploy/kamal/deploy.yml +0 -39
@@ -0,0 +1,11 @@
1
+ import { type CohortConfig, type PilotConfig } from "./schema";
2
+ /** Offline-only conversion. Active desired-state loading never calls this. */
3
+ export declare function migrateLegacyPilotConfig(input: unknown): PilotConfig;
4
+ /** Offline-only cohort conversion. */
5
+ export declare function migrateLegacyCohortConfig(input: unknown): CohortConfig;
6
+ /** Offline-only YAML rewrite that retains comments while changing the schema. */
7
+ export declare function migrateLegacyPilotYaml(input: string): string;
8
+ /** Offline-only cohort rewrite that retains comments while changing selection. */
9
+ export declare function migrateLegacyCohortYaml(input: string): string;
10
+ export declare function renderPilotConfig(config: PilotConfig): string;
11
+ export declare function renderCohortConfig(config: CohortConfig): string;
@@ -0,0 +1,29 @@
1
+ import { type JobInfo } from "@brains/job-queue";
2
+ import { z } from "@brains/utils/zod";
3
+ export declare const LEGACY_PROJECTION_JOB_TYPES: readonly ["conversation-memory:project", "skill:project", "swot:derive", "topic:project"];
4
+ export declare const legacyProjectionJobTypeSchema: z.ZodEnum<{
5
+ "conversation-memory:project": "conversation-memory:project";
6
+ "skill:project": "skill:project";
7
+ "swot:derive": "swot:derive";
8
+ "topic:project": "topic:project";
9
+ }>;
10
+ export type LegacyProjectionJobType = z.output<typeof legacyProjectionJobTypeSchema>;
11
+ export declare const LEGACY_PROJECTION_RETIREMENT_REASON = "Retired legacy projection job superseded by scheduler-owned projections";
12
+ export interface RetireLegacyProjectionJobOptions {
13
+ databasePath: string;
14
+ jobId: string;
15
+ jobType: LegacyProjectionJobType;
16
+ confirmation?: string | undefined;
17
+ dryRun?: boolean | undefined;
18
+ now?: (() => number) | undefined;
19
+ }
20
+ export interface RetireLegacyProjectionJobResult {
21
+ databasePath: string;
22
+ job: Pick<JobInfo, "id" | "type" | "status" | "retryCount" | "maxRetries" | "createdAt" | "startedAt" | "completedAt">;
23
+ retired: boolean;
24
+ }
25
+ /**
26
+ * Retire one exact pre-scheduler projection job after proving that no attempt
27
+ * owns it. This is deliberately not a general job cancellation API.
28
+ */
29
+ export declare function retireLegacyProjectionJob(options: RetireLegacyProjectionJobOptions): Promise<RetireLegacyProjectionJobResult>;
@@ -1,4 +1,4 @@
1
- import { type PilotConfig, type PilotPreset } from "./schema";
1
+ import { type AnchorKind, type CohortConfig, type PilotConfig, type CanonicalBundleId, type UserConfig } from "./schema";
2
2
  export type ExternalStatus = "unknown" | "ready" | "failed";
3
3
  export type SnapshotStatus = "present" | "missing";
4
4
  export interface ObservedUserStatus {
@@ -11,19 +11,95 @@ export interface ResolvedCohort {
11
11
  id: string;
12
12
  members: string[];
13
13
  brainVersionOverride?: string;
14
- presetOverride?: PilotPreset;
14
+ bundlesOverride?: CanonicalBundleId[];
15
+ addOverride?: string[];
16
+ removeOverride?: string[];
15
17
  aiApiKeyOverride?: string;
18
+ gitSyncTokenOverride?: string;
19
+ }
20
+ export interface ResolvedAnchorProfileSocialLink {
21
+ platform: "github" | "instagram" | "linkedin" | "email" | "website";
22
+ url: string;
23
+ label?: string;
24
+ }
25
+ export interface ResolvedAnchorProfile {
26
+ name: string;
27
+ description?: string;
28
+ website?: string;
29
+ email?: string;
30
+ story?: string;
31
+ socialLinks?: ResolvedAnchorProfileSocialLink[];
32
+ }
33
+ export interface ResolvedSetupDelivery {
34
+ delivery: "email";
35
+ email: string;
36
+ }
37
+ export interface ResolvedAtprotoJetstreamConfig {
38
+ enabled?: boolean | undefined;
39
+ endpoint?: string | undefined;
40
+ replayWindowSeconds?: number | undefined;
41
+ denyDids?: string[] | undefined;
42
+ denyDomains?: string[] | undefined;
43
+ skillKeywords?: string[] | undefined;
44
+ queueLimit?: number | undefined;
45
+ concurrency?: number | undefined;
46
+ perDidCooldownSeconds?: number | undefined;
47
+ fetchBudgetPerMinute?: number | undefined;
48
+ newAgentsPerHour?: number | undefined;
49
+ pendingCandidateCeiling?: number | undefined;
50
+ staleCandidateRetentionDays?: number | undefined;
51
+ requestTimeoutMs?: number | undefined;
52
+ maxResponseBytes?: number | undefined;
53
+ maxRedirects?: number | undefined;
54
+ retryAttempts?: number | undefined;
55
+ heartbeatIntervalHours?: number | undefined;
56
+ }
57
+ export interface ResolvedAtprotoConfig {
58
+ identifier: string;
59
+ /** Owner account DID served at /.well-known/atproto-did for handle verification. */
60
+ accountDid?: string | undefined;
61
+ /** Whether this account publishes the canonical ai.rizom.brain.* schemas. */
62
+ lexiconAuthority?: boolean | undefined;
63
+ /** Per-brain bounded Jetstream canary configuration. */
64
+ jetstream?: ResolvedAtprotoJetstreamConfig | undefined;
65
+ }
66
+ export interface ResolvedPlaybooksConfig {
67
+ onboarding?: boolean | undefined;
68
+ }
69
+ export interface ResolvedSiteOverride {
70
+ package: string;
71
+ version?: string | undefined;
72
+ theme?: string | undefined;
73
+ themeVersion?: string | undefined;
16
74
  }
17
75
  export interface ResolvedUserIdentity {
18
76
  handle: string;
19
77
  cohort: string;
20
78
  brainVersion: string;
21
- model: "rover";
22
- preset: PilotPreset;
79
+ bundleContract: PilotConfig["bundleContract"];
80
+ bundles: CanonicalBundleId[];
81
+ add: string[];
82
+ remove: string[];
23
83
  domain: string;
84
+ cloudflareZoneId?: string | undefined;
24
85
  contentRepo: string;
86
+ profileKind?: string | undefined;
87
+ anchorKind?: AnchorKind | undefined;
88
+ embeddingEnabled?: boolean | undefined;
89
+ plugins?: UserConfig["plugins"];
90
+ spaces?: string[] | undefined;
91
+ topicExtractionEnabled?: boolean | undefined;
92
+ skillDerivationEnabled?: boolean | undefined;
93
+ swotDerivationEnabled?: boolean | undefined;
94
+ siteOverride?: ResolvedSiteOverride;
25
95
  discordEnabled: boolean;
96
+ discordAnchorUserId?: string;
26
97
  effectiveAiApiKey: string;
98
+ effectiveGitSyncToken: string;
99
+ setup?: ResolvedSetupDelivery;
100
+ atproto?: ResolvedAtprotoConfig;
101
+ playbooks?: ResolvedPlaybooksConfig;
102
+ anchorProfile: ResolvedAnchorProfile;
27
103
  snapshotStatus: SnapshotStatus;
28
104
  }
29
105
  export interface ResolvedUser extends ResolvedUserIdentity {
@@ -40,7 +116,13 @@ export interface PilotRegistry {
40
116
  cohorts: ResolvedCohort[];
41
117
  users: ResolvedUser[];
42
118
  }
43
- declare class PilotRegistryError extends Error {
119
+ export interface LoadedCohortFile {
120
+ id: string;
121
+ data: CohortConfig;
44
122
  }
45
123
  export declare function loadPilotRegistry(rootDir: string, options?: LoadPilotRegistryOptions): Promise<PilotRegistry>;
46
- export { PilotRegistryError };
124
+ /**
125
+ * Resolve a user's desired state from the user → cohort → pilot cascade.
126
+ * Pure: the snapshot status is filesystem state and is added by the loader.
127
+ */
128
+ export declare function resolveUserIdentity(user: UserConfig, cohort: LoadedCohortFile, pilot: PilotConfig): Omit<ResolvedUserIdentity, "snapshotStatus">;
@@ -1,4 +1,4 @@
1
- import type { FetchLike } from "@brains/utils/origin-ca";
1
+ import type { FetchLike } from "@brains/utils/fetch-like";
2
2
  import type { ObservedUserStatus, ResolvedUserIdentity } from "./load-registry";
3
3
  export interface LookupResult {
4
4
  address: string;
@@ -1,2 +1,2 @@
1
- import { type UserRunner } from "./reconcile-lib";
2
- export declare function onboardUser(rootDir: string, handle: string, runner?: UserRunner): Promise<void>;
1
+ import { type UserRunner, type ContentRepoSyncOptions } from "./reconcile-lib";
2
+ export declare function onboardUser(rootDir: string, handle: string, runner?: UserRunner, contentRepoOptions?: ContentRepoSyncOptions): Promise<void>;
@@ -1,11 +1,3 @@
1
- export interface ParsedArgs {
2
- command: string;
3
- args: string[];
4
- flags: {
5
- help?: boolean | undefined;
6
- version?: boolean | undefined;
7
- dryRun?: boolean | undefined;
8
- pushTo?: string | undefined;
9
- };
10
- }
1
+ import { type ParsedCliArgs } from "@brains/deploy-support/cli-kit";
2
+ export type ParsedArgs = ParsedCliArgs;
11
3
  export declare function parseArgs(argv: string[]): ParsedArgs;
@@ -0,0 +1,9 @@
1
+ export interface PreviewDomainOptions {
2
+ sharedDomain?: string | undefined;
3
+ }
4
+ /**
5
+ * Public operator-facing wrapper around the runtime's preview-domain rule.
6
+ * Keeping deploy resolution on this function prevents DNS, proxy, and runtime
7
+ * metadata from drifting onto different host shapes.
8
+ */
9
+ export declare function derivePreviewDomain(domain: string, options?: PreviewDomainOptions): string;
@@ -1,2 +1,2 @@
1
- import { type UserRunner } from "./reconcile-lib";
2
- export declare function reconcileAll(rootDir: string, runner?: UserRunner): Promise<void>;
1
+ import { type UserRunner, type ContentRepoSyncOptions } from "./reconcile-lib";
2
+ export declare function reconcileAll(rootDir: string, runner?: UserRunner, contentRepoOptions?: ContentRepoSyncOptions): Promise<void>;
@@ -1,2 +1,2 @@
1
- import { type UserRunner } from "./reconcile-lib";
2
- export declare function reconcileCohort(rootDir: string, cohortId: string, runner?: UserRunner): Promise<void>;
1
+ import { type UserRunner, type ContentRepoSyncOptions } from "./reconcile-lib";
2
+ export declare function reconcileCohort(rootDir: string, cohortId: string, runner?: UserRunner, contentRepoOptions?: ContentRepoSyncOptions): Promise<void>;
@@ -0,0 +1,9 @@
1
+ export interface ReconcileDryRunResult {
2
+ firstPassChangedFiles: string[];
3
+ secondPassChangedFiles: string[];
4
+ }
5
+ /**
6
+ * Reconcile an isolated copy twice with external content-repo access disabled.
7
+ * The source repository is never written.
8
+ */
9
+ export declare function dryRunReconcileAll(rootDir: string): Promise<ReconcileDryRunResult>;
@@ -1,7 +1,9 @@
1
+ import { type ContentRepoSyncOptions } from "./content-repo";
1
2
  import { type PilotRegistry, type ResolvedUser } from "./load-registry";
2
3
  import type { UserRunner } from "./user-runner";
3
- export type { UserRunResult, UserRunner } from "./user-runner";
4
- export declare function runUsers(rootDir: string, registry: PilotRegistry, users: ResolvedUser[], runner?: UserRunner): Promise<void>;
4
+ export type { ContentRepoSyncOptions } from "./content-repo";
5
+ export type { ContentRepoFile, UserRunResult, UserRunner } from "./user-runner";
6
+ export declare function runUsers(rootDir: string, registry: PilotRegistry, users: ResolvedUser[], runner?: UserRunner, contentRepoOptions?: ContentRepoSyncOptions): Promise<void>;
5
7
  export declare function findUser(rootDir: string, handle: string): Promise<{
6
8
  registry: PilotRegistry;
7
9
  user: ResolvedUser;
@@ -1,10 +1,14 @@
1
- import type { FetchLike } from "@brains/utils/origin-ca";
2
- import type { LoadPilotRegistryOptions } from "./load-registry";
1
+ import type { FetchLike } from "@brains/utils/fetch-like";
2
+ import { type CommandDefinition, type FlagDefinitions, type ParsedCliArgs } from "@brains/deploy-support/cli-kit";
3
+ import { type LoadPilotRegistryOptions } from "./load-registry";
3
4
  import { type LookupHost } from "./observed-status";
4
- import type { ParsedArgs } from "./parse-args";
5
- import { type RunCommand as OpsRunCommand } from "./run-subprocess";
5
+ import { type RunCommand as OpsRunCommand } from "@brains/deploy-support/run-subprocess";
6
6
  import { type SshKeygen } from "./ssh-key-bootstrap";
7
+ import type { PilotOffboardDriver } from "./user-offboard";
7
8
  import type { UserRunner } from "./user-runner";
9
+ import type { cleanupDirectorySyncStress, runDeployedDirectorySyncStress, verifyDirectorySyncStressAccess } from "./directory-sync-stress-system";
10
+ import type { cleanupHealthWatchdogSmoke, runHealthWatchdogSmoke } from "./health-watchdog-smoke";
11
+ import type { retireLegacyProjectionJob } from "./legacy-projection-job-recovery";
8
12
  export interface CommandResult {
9
13
  success: boolean;
10
14
  message?: string;
@@ -15,8 +19,20 @@ export interface CommandDependencies extends LoadPilotRegistryOptions {
15
19
  logger?: ((message: string) => void) | undefined;
16
20
  fetchImpl?: FetchLike | undefined;
17
21
  lookupHost?: LookupHost | undefined;
18
- secretRunCommand?: OpsRunCommand | undefined;
22
+ verificationRetryAttempts?: number | undefined;
23
+ verificationRetryDelayMs?: number | undefined;
24
+ sleep?: ((delayMs: number) => Promise<void>) | undefined;
19
25
  bootstrapRunCommand?: OpsRunCommand | undefined;
26
+ imageLockRunCommand?: OpsRunCommand | undefined;
20
27
  sshKeygen?: SshKeygen | undefined;
28
+ directorySyncStressRunner?: typeof runDeployedDirectorySyncStress | undefined;
29
+ directorySyncStressAccessRunner?: typeof verifyDirectorySyncStressAccess | undefined;
30
+ directorySyncStressCleanupRunner?: typeof cleanupDirectorySyncStress | undefined;
31
+ healthWatchdogSmokeRunner?: typeof runHealthWatchdogSmoke | undefined;
32
+ healthWatchdogSmokeCleanupRunner?: typeof cleanupHealthWatchdogSmoke | undefined;
33
+ legacyProjectionJobRecoveryRunner?: typeof retireLegacyProjectionJob | undefined;
34
+ pilotOffboardDriver?: PilotOffboardDriver | undefined;
21
35
  }
22
- export declare function runCommand(parsed: ParsedArgs, dependencies?: CommandDependencies): Promise<CommandResult>;
36
+ export declare const globalFlags: FlagDefinitions;
37
+ export declare const commands: readonly CommandDefinition<CommandDependencies, CommandResult>[];
38
+ export declare function runCommand(parsed: ParsedCliArgs, dependencies?: CommandDependencies): Promise<CommandResult>;
@@ -0,0 +1,12 @@
1
+ import type { RequiredImage } from "./image-types";
2
+ import { type RunCommand } from "@brains/deploy-support/run-subprocess";
3
+ /** Operator-owned build inputs, not generated per-user deploy output. */
4
+ export declare function runtimeImageLockDirectory(image: RequiredImage): string;
5
+ /** Fail before publishing when a required build has no reviewed, matching inputs. */
6
+ export declare function assertRuntimeImageLock(rootDir: string, image: RequiredImage): Promise<void>;
7
+ /**
8
+ * Resolve once for operator review; CI and Docker only consume the frozen result.
9
+ * Existing entries are never refreshed or overwritten. Failed new entries retain
10
+ * their incomplete marker and diagnostic files and cannot be used by a build.
11
+ */
12
+ export declare function lockRuntimeImage(rootDir: string, image: RequiredImage, run?: RunCommand): Promise<"created" | "existing">;
package/dist/schema.d.ts CHANGED
@@ -1,86 +1,164 @@
1
- import { z } from "@brains/utils";
2
- export declare const presetSchema: z.ZodEnum<["core", "default", "pro"]>;
1
+ import { z } from "@brains/utils/zod";
3
2
  export declare const exactVersionSchema: z.ZodString;
4
3
  export declare const handleSchema: z.ZodString;
5
4
  export declare const secretNameSchema: z.ZodString;
5
+ export declare const agePublicKeySchema: z.ZodString;
6
+ export declare const CAPABILITY_BUNDLE_CONTRACT: "capability-bundles-v1";
7
+ export declare const canonicalBundleIdSchema: z.ZodEnum<{
8
+ core: "core";
9
+ media: "media";
10
+ automation: "automation";
11
+ web: "web";
12
+ chat: "chat";
13
+ site: "site";
14
+ publishing: "publishing";
15
+ federation: "federation";
16
+ team: "team";
17
+ }>;
18
+ export type CanonicalBundleId = z.output<typeof canonicalBundleIdSchema>;
19
+ /**
20
+ * The profile kinds the runtime's profile plugin registers. A user config
21
+ * selecting anything else composes a brain that fails at boot, so reject it
22
+ * at parse time. Kept in lockstep with @brains/profile BUILT_IN_PROFILE_KINDS
23
+ * by a test. Collective/organization brains use "organization".
24
+ */
25
+ export declare const PROFILE_KINDS: readonly ["professional", "team", "organization"];
26
+ export declare const profileKindSchema: z.ZodEnum<{
27
+ professional: "professional";
28
+ team: "team";
29
+ organization: "organization";
30
+ }>;
31
+ /**
32
+ * Who owns the brain in its auth service. "person" (the runtime default) makes
33
+ * the first passkey holder a permanent owner; "team" and "organization" make
34
+ * the brain collectively owned, so admins can be replaced. Kept in lockstep
35
+ * with @brains/auth-service AUTH_BRAIN_ANCHOR_CONFIG_KINDS by a test.
36
+ */
37
+ export declare const ANCHOR_KINDS: readonly ["person", "team", "organization"];
38
+ export declare const anchorKindSchema: z.ZodEnum<{
39
+ person: "person";
40
+ team: "team";
41
+ organization: "organization";
42
+ }>;
43
+ export type AnchorKind = z.output<typeof anchorKindSchema>;
44
+ declare const canonicalBundlesSchema: z.ZodArray<typeof canonicalBundleIdSchema>;
45
+ declare const memberIdsSchema: z.ZodArray<z.ZodString>;
46
+ /** Sole active desired-state contract for the canonical brain. */
6
47
  export declare const pilotSchema: z.ZodObject<{
7
- schemaVersion: z.ZodLiteral<1>;
8
48
  brainVersion: z.ZodString;
9
- model: z.ZodLiteral<"rover">;
49
+ bundleContract: z.ZodLiteral<typeof CAPABILITY_BUNDLE_CONTRACT>;
50
+ bundles: typeof canonicalBundlesSchema;
51
+ add: z.ZodOptional<typeof memberIdsSchema>;
52
+ remove: z.ZodOptional<typeof memberIdsSchema>;
10
53
  githubOrg: z.ZodString;
11
54
  contentRepoPrefix: z.ZodString;
12
55
  domainSuffix: z.ZodString;
13
- preset: z.ZodEnum<["core", "default", "pro"]>;
14
56
  aiApiKey: z.ZodString;
15
- }, "strict", z.ZodTypeAny, {
16
- schemaVersion: 1;
17
- brainVersion: string;
18
- model: "rover";
19
- githubOrg: string;
20
- contentRepoPrefix: string;
21
- domainSuffix: string;
22
- preset: "default" | "core" | "pro";
23
- aiApiKey: string;
24
- }, {
25
- schemaVersion: 1;
26
- brainVersion: string;
27
- model: "rover";
28
- githubOrg: string;
29
- contentRepoPrefix: string;
30
- domainSuffix: string;
31
- preset: "default" | "core" | "pro";
32
- aiApiKey: string;
57
+ gitSyncToken: z.ZodString;
58
+ contentRepoAdminToken: z.ZodString;
59
+ agePublicKey: z.ZodString;
60
+ }, z.core.$strict>;
61
+ export type PilotConfig = z.output<typeof pilotSchema>;
62
+ export declare const cohortSchema: z.ZodObject<{
63
+ members: z.ZodArray<z.ZodString>;
64
+ brainVersionOverride: z.ZodOptional<z.ZodString>;
65
+ bundlesOverride: z.ZodOptional<typeof canonicalBundlesSchema>;
66
+ addOverride: z.ZodOptional<typeof memberIdsSchema>;
67
+ removeOverride: z.ZodOptional<typeof memberIdsSchema>;
68
+ aiApiKeyOverride: z.ZodOptional<z.ZodString>;
69
+ gitSyncTokenOverride: z.ZodOptional<z.ZodString>;
70
+ }, z.core.$strict>;
71
+ export type CohortConfig = z.output<typeof cohortSchema>;
72
+ declare const anchorProfileSocialLinkSchema: z.ZodObject<{
73
+ platform: z.ZodEnum<{
74
+ github: "github";
75
+ instagram: "instagram";
76
+ linkedin: "linkedin";
77
+ email: "email";
78
+ website: "website";
79
+ }>;
80
+ url: z.ZodString;
81
+ label: z.ZodOptional<z.ZodString>;
82
+ }>;
83
+ declare const anchorProfileSchema: z.ZodObject<{
84
+ name: z.ZodOptional<z.ZodString>;
85
+ description: z.ZodOptional<z.ZodString>;
86
+ website: z.ZodOptional<z.ZodString>;
87
+ email: z.ZodOptional<z.ZodString>;
88
+ story: z.ZodOptional<z.ZodString>;
89
+ socialLinks: z.ZodOptional<z.ZodArray<typeof anchorProfileSocialLinkSchema>>;
33
90
  }>;
91
+ declare const setupDeliverySchema: z.ZodObject<{
92
+ delivery: z.ZodLiteral<"email">;
93
+ email: z.ZodString;
94
+ }>;
95
+ declare const atprotoJetstreamSchema: z.ZodObject<{
96
+ enabled: z.ZodOptional<z.ZodBoolean>;
97
+ endpoint: z.ZodOptional<z.ZodString>;
98
+ replayWindowSeconds: z.ZodOptional<z.ZodNumber>;
99
+ denyDids: z.ZodOptional<z.ZodArray<z.ZodString>>;
100
+ denyDomains: z.ZodOptional<z.ZodArray<z.ZodString>>;
101
+ skillKeywords: z.ZodOptional<z.ZodArray<z.ZodString>>;
102
+ queueLimit: z.ZodOptional<z.ZodNumber>;
103
+ concurrency: z.ZodOptional<z.ZodNumber>;
104
+ perDidCooldownSeconds: z.ZodOptional<z.ZodNumber>;
105
+ fetchBudgetPerMinute: z.ZodOptional<z.ZodNumber>;
106
+ newAgentsPerHour: z.ZodOptional<z.ZodNumber>;
107
+ pendingCandidateCeiling: z.ZodOptional<z.ZodNumber>;
108
+ staleCandidateRetentionDays: z.ZodOptional<z.ZodNumber>;
109
+ requestTimeoutMs: z.ZodOptional<z.ZodNumber>;
110
+ maxResponseBytes: z.ZodOptional<z.ZodNumber>;
111
+ maxRedirects: z.ZodOptional<z.ZodNumber>;
112
+ retryAttempts: z.ZodOptional<z.ZodNumber>;
113
+ heartbeatIntervalHours: z.ZodOptional<z.ZodNumber>;
114
+ }>;
115
+ declare const atprotoSchema: z.ZodObject<{
116
+ identifier: z.ZodString;
117
+ accountDid: z.ZodOptional<z.ZodString>;
118
+ lexiconAuthority: z.ZodOptional<z.ZodBoolean>;
119
+ jetstream: z.ZodOptional<typeof atprotoJetstreamSchema>;
120
+ }>;
121
+ export declare const siteOverrideSchema: z.ZodObject<{
122
+ package: z.ZodString;
123
+ version: z.ZodOptional<z.ZodString>;
124
+ theme: z.ZodOptional<z.ZodString>;
125
+ themeVersion: z.ZodOptional<z.ZodString>;
126
+ }, z.core.$strict>;
127
+ export type SiteOverrideConfig = z.output<typeof siteOverrideSchema>;
128
+ declare const playbooksSchema: z.ZodObject<{
129
+ onboarding: z.ZodOptional<z.ZodBoolean>;
130
+ }>;
131
+ /** Config transport shape; plugin-owned schemas validate fields in the app. */
132
+ declare const userPluginsSchema: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>;
34
133
  export declare const userSchema: z.ZodObject<{
35
134
  handle: z.ZodString;
36
135
  discord: z.ZodObject<{
37
136
  enabled: z.ZodBoolean;
38
- }, "strict", z.ZodTypeAny, {
39
- enabled: boolean;
40
- }, {
41
- enabled: boolean;
137
+ anchorUserId: z.ZodOptional<z.ZodString>;
42
138
  }>;
43
139
  aiApiKeyOverride: z.ZodOptional<z.ZodString>;
44
- }, "strict", z.ZodTypeAny, {
45
- handle: string;
46
- discord: {
47
- enabled: boolean;
48
- };
49
- aiApiKeyOverride?: string | undefined;
50
- }, {
51
- handle: string;
52
- discord: {
53
- enabled: boolean;
54
- };
55
- aiApiKeyOverride?: string | undefined;
56
- }>;
57
- export declare const cohortSchema: z.ZodEffects<z.ZodObject<{
58
- members: z.ZodArray<z.ZodString, "many">;
59
- brainVersionOverride: z.ZodOptional<z.ZodString>;
60
- presetOverride: z.ZodOptional<z.ZodEnum<["core", "default", "pro"]>>;
61
- aiApiKeyOverride: z.ZodOptional<z.ZodString>;
62
- }, "strict", z.ZodTypeAny, {
63
- members: string[];
64
- aiApiKeyOverride?: string | undefined;
65
- brainVersionOverride?: string | undefined;
66
- presetOverride?: "default" | "core" | "pro" | undefined;
67
- }, {
68
- members: string[];
69
- aiApiKeyOverride?: string | undefined;
70
- brainVersionOverride?: string | undefined;
71
- presetOverride?: "default" | "core" | "pro" | undefined;
72
- }>, {
73
- members: string[];
74
- aiApiKeyOverride?: string | undefined;
75
- brainVersionOverride?: string | undefined;
76
- presetOverride?: "default" | "core" | "pro" | undefined;
77
- }, {
78
- members: string[];
79
- aiApiKeyOverride?: string | undefined;
80
- brainVersionOverride?: string | undefined;
81
- presetOverride?: "default" | "core" | "pro" | undefined;
140
+ gitSyncTokenOverride: z.ZodOptional<z.ZodString>;
141
+ domainOverride: z.ZodOptional<z.ZodString>;
142
+ cloudflareZoneId: z.ZodOptional<z.ZodString>;
143
+ contentRepoOverride: z.ZodOptional<z.ZodString>;
144
+ profileKind: z.ZodOptional<typeof profileKindSchema>;
145
+ anchorKind: z.ZodOptional<typeof anchorKindSchema>;
146
+ plugins: z.ZodOptional<typeof userPluginsSchema>;
147
+ spaces: z.ZodOptional<z.ZodArray<z.ZodString>>;
148
+ embeddingEnabled: z.ZodOptional<z.ZodBoolean>;
149
+ topicExtractionEnabled: z.ZodOptional<z.ZodBoolean>;
150
+ skillDerivationEnabled: z.ZodOptional<z.ZodBoolean>;
151
+ swotDerivationEnabled: z.ZodOptional<z.ZodBoolean>;
152
+ addOverride: z.ZodOptional<z.ZodArray<z.ZodString>>;
153
+ removeOverride: z.ZodOptional<z.ZodArray<z.ZodString>>;
154
+ siteOverride: z.ZodOptional<typeof siteOverrideSchema>;
155
+ setup: z.ZodOptional<typeof setupDeliverySchema>;
156
+ atproto: z.ZodOptional<typeof atprotoSchema>;
157
+ playbooks: z.ZodOptional<typeof playbooksSchema>;
158
+ anchorProfile: z.ZodOptional<typeof anchorProfileSchema>;
82
159
  }>;
83
- export type PilotConfig = z.infer<typeof pilotSchema>;
84
- export type UserConfig = z.infer<typeof userSchema>;
85
- export type CohortConfig = z.infer<typeof cohortSchema>;
86
- export type PilotPreset = z.infer<typeof presetSchema>;
160
+ export type PilotConfigInput = z.input<typeof pilotSchema>;
161
+ export type UserConfig = z.output<typeof userSchema>;
162
+ export type UserConfigInput = z.input<typeof userSchema>;
163
+ export type CohortConfigInput = z.input<typeof cohortSchema>;
164
+ export {};
@@ -0,0 +1,26 @@
1
+ import { z } from "@brains/utils/zod";
2
+ declare const encryptedUserSecretsSchema: z.ZodObject<{
3
+ gitSyncToken: z.ZodOptional<z.ZodString>;
4
+ discordBotToken: z.ZodOptional<z.ZodString>;
5
+ discordPublicKey: z.ZodOptional<z.ZodString>;
6
+ discordApplicationId: z.ZodOptional<z.ZodString>;
7
+ aiApiKey: z.ZodOptional<z.ZodString>;
8
+ atprotoAppPassword: z.ZodOptional<z.ZodString>;
9
+ certificatePem: z.ZodOptional<z.ZodString>;
10
+ privateKeyPem: z.ZodOptional<z.ZodString>;
11
+ }>;
12
+ export type EncryptedUserSecrets = z.output<typeof encryptedUserSecretsSchema>;
13
+ export interface SecretsEncryptOptions {
14
+ env?: NodeJS.ProcessEnv | undefined;
15
+ logger?: ((message: string) => void) | undefined;
16
+ dryRun?: boolean | undefined;
17
+ }
18
+ export interface SecretsEncryptResult {
19
+ encryptedPath: string;
20
+ plaintextPath: string;
21
+ deletedPlaintext: boolean;
22
+ encryptedKeys: Array<keyof EncryptedUserSecrets>;
23
+ dryRun?: boolean | undefined;
24
+ }
25
+ export declare function encryptPilotSecrets(rootDir: string, handle: string, options?: SecretsEncryptOptions): Promise<SecretsEncryptResult>;
26
+ export {};
@@ -1,4 +1,4 @@
1
- import { type RunCommand } from "./run-subprocess";
1
+ import { type RunCommand } from "@brains/deploy-support/run-subprocess";
2
2
  export interface SecretsPushOptions {
3
3
  env?: NodeJS.ProcessEnv | undefined;
4
4
  logger?: ((message: string) => void) | undefined;
@@ -10,4 +10,4 @@ export interface SecretsPushResult {
10
10
  skippedKeys: string[];
11
11
  dryRun?: boolean | undefined;
12
12
  }
13
- export declare function pushPilotSecrets(rootDir: string, handle: string, options?: SecretsPushOptions): Promise<SecretsPushResult>;
13
+ export declare function pushPilotSecrets(rootDir: string, options?: SecretsPushOptions): Promise<SecretsPushResult>;
@@ -1,26 +1 @@
1
- import { type FetchLike } from "@brains/utils/origin-ca";
2
- import { type RunCommand } from "./run-subprocess";
3
- export interface SshKeyBootstrapOptions {
4
- env?: NodeJS.ProcessEnv | undefined;
5
- fetchImpl?: FetchLike | undefined;
6
- logger?: (message: string) => void;
7
- pushTo?: string | undefined;
8
- runCommand?: RunCommand | undefined;
9
- sshKeygen?: SshKeygen | undefined;
10
- }
11
- export interface SshKeyBootstrapResult {
12
- createdHetznerKey: boolean;
13
- createdLocalKey: boolean;
14
- privateKeyPath: string;
15
- publicKeyPath: string;
16
- sshKeyName: string;
17
- }
18
- export interface SshKeygen {
19
- createEd25519KeyPair: (privateKeyPath: string, comment: string) => void;
20
- derivePublicKey: (privateKeyPath: string) => string;
21
- }
22
- export declare function runPilotSshKeyBootstrap(rootDir: string, options?: SshKeyBootstrapOptions): Promise<{
23
- success: boolean;
24
- message?: string;
25
- }>;
26
- export declare function bootstrapPilotSshKey(rootDir: string, options?: SshKeyBootstrapOptions): Promise<SshKeyBootstrapResult>;
1
+ export { bootstrapSshKey as bootstrapPilotSshKey, runSshKeyBootstrap as runPilotSshKeyBootstrap, type SshKeyBootstrapOptions, type SshKeyBootstrapResult, type SshKeygen, } from "@brains/deploy-support/ssh-key-bootstrap";
@@ -0,0 +1,25 @@
1
+ import { z } from "@brains/utils/zod";
2
+ import { type CapabilityBundleReview } from "./capability-bundle-migration";
3
+ import { siteOverrideSchema } from "./schema";
4
+ export interface StagedCrossover {
5
+ outputDir: string;
6
+ changedFiles: string[];
7
+ }
8
+ declare const reviewedSitePinsSchema: z.ZodObject<{
9
+ sites: z.ZodRecord<z.ZodString, typeof siteOverrideSchema>;
10
+ }, z.core.$strict>;
11
+ type ReviewedSitePinManifest = z.output<typeof reviewedSitePinsSchema>;
12
+ export type ReviewedSitePins = ReviewedSitePinManifest["sites"];
13
+ export interface StageLegacyCrossoverOptions {
14
+ sitePins?: ReviewedSitePins | undefined;
15
+ bundleReview?: CapabilityBundleReview | undefined;
16
+ }
17
+ export declare function parseReviewedSitePins(input: string): ReviewedSitePins;
18
+ export declare function loadReviewedSitePins(filePath: string): Promise<ReviewedSitePins>;
19
+ export declare function loadCapabilityBundleReview(filePath: string): Promise<CapabilityBundleReview>;
20
+ /**
21
+ * Build a complete review copy without mutating the source repository.
22
+ * This is offline migration tooling; active desired-state loading is canonical-only.
23
+ */
24
+ export declare function stageLegacyCrossover(sourceDir: string, outputDir: string, options?: StageLegacyCrossoverOptions): Promise<StagedCrossover>;
25
+ export {};
@@ -0,0 +1,14 @@
1
+ export interface StressCommandOptions {
2
+ cwd?: string;
3
+ env?: NodeJS.ProcessEnv;
4
+ stdin?: string;
5
+ }
6
+ export interface StressCommandResult {
7
+ exitCode: number;
8
+ stdout: string;
9
+ stderr: string;
10
+ }
11
+ export type StressCommandRunner = (command: string, args: readonly string[], options?: StressCommandOptions) => Promise<StressCommandResult>;
12
+ export declare const runStressCommand: StressCommandRunner;
13
+ export declare function requireCommand(runner: StressCommandRunner, command: string, args: readonly string[], options?: StressCommandOptions): Promise<StressCommandResult>;
14
+ export declare function commandError(command: string, args: readonly string[], result: StressCommandResult): Error;