Files
stack/packages/mosaic/src/commands/brain-provision.ts
T
2026-08-05 17:19:51 -05:00

272 lines
8.4 KiB
TypeScript

import { existsSync } from 'node:fs';
import { parseRequestedOwner, resolveProviderDurableOwner } from './brain-owner-resolver.js';
import {
createBrainSkeleton,
deriveBrainTarget,
discoverBrainMigration,
ensureBrainRootPrivate,
migrateBrainState,
type MigrationResult,
type MigrationOwnerResolution,
type MigrationPublishEntry,
} from './brain-store.js';
import {
collectBrainDoctorReport,
collectBrainRefusalControl,
publishBrainPaths,
type CommandRequest,
type CommandResult,
type CommandRunner,
} from './brain-store-runtime.js';
import type { OwnerFetch } from './brain-owner-resolver.js';
export interface ProvisionResult {
readonly status: 'provisioned' | 'blocked' | 'failed';
readonly reasonCode: string;
readonly findings: readonly {
readonly code: string;
readonly reasonCode: string | null;
}[];
readonly owner: Pick<MigrationOwnerResolution, 'verdict' | 'reasonCode'> | null;
readonly migration: Pick<MigrationResult, 'status' | 'reported'> | null;
}
function commandEnv(identity: string): Readonly<Record<string, string>> {
return { MOSAIC_GIT_IDENTITY: identity, GIT_TERMINAL_PROMPT: '0' };
}
function findingView(
findings: readonly { readonly code: string; readonly reasonCode: string | null }[],
): readonly { readonly code: string; readonly reasonCode: string | null }[] {
return findings.map((finding): { readonly code: string; readonly reasonCode: string | null } => ({
code: finding.code,
reasonCode: finding.reasonCode,
}));
}
function blocked(
reasonCode: string,
findings: readonly { readonly code: string; readonly reasonCode: string | null }[],
owner: MigrationOwnerResolution | null = null,
migration: MigrationResult | null = null,
): ProvisionResult {
return {
status: 'blocked',
reasonCode,
findings: findingView(findings),
owner: owner === null ? null : { verdict: owner.verdict, reasonCode: owner.reasonCode },
migration:
migration === null ? null : { status: migration.status, reported: migration.reported },
};
}
function failed(
reasonCode: string,
findings: readonly { readonly code: string; readonly reasonCode: string | null }[],
owner: MigrationOwnerResolution | null = null,
migration: MigrationResult | null = null,
): ProvisionResult {
return {
...blocked(reasonCode, findings, owner, migration),
status: 'failed',
};
}
export async function provisionBrain(
input: {
readonly estateRegistrySource: string;
readonly ownerPolicySource: string;
readonly targetGitUrl: string;
readonly requestedOwner: string;
readonly identity: string;
readonly refusalIdentity: string;
readonly root: string;
readonly sourceRoot: string;
readonly seat: string;
readonly lane: string;
readonly laneActive: boolean;
},
dependencies: {
readonly run: CommandRunner;
readonly fetch: OwnerFetch;
readonly absentControlName: () => string;
readonly approveMigrationContent?: (path: string, content: Uint8Array) => boolean;
},
): Promise<ProvisionResult> {
const brainNamespace = parseRequestedOwner(input.requestedOwner);
if (brainNamespace === null) return blocked('owner-name-invalid', []);
const target = deriveBrainTarget(input.estateRegistrySource, input.targetGitUrl, brainNamespace);
if (existsSync(input.root)) {
try {
ensureBrainRootPrivate(input.root);
} catch {
return blocked('brain-root-permissions-unsafe', []);
}
}
const doctorInput = {
registrySource: input.estateRegistrySource,
targetGitUrl: input.targetGitUrl,
brainNamespace,
identity: input.identity,
root: input.root,
};
let report = collectBrainDoctorReport(doctorInput, dependencies.run);
if (report.access.outcome !== 'ok') {
return blocked('credential-postcondition-failed', report.findings);
}
const refusalControl = collectBrainRefusalControl(
{
registrySource: input.estateRegistrySource,
targetGitUrl: input.targetGitUrl,
brainNamespace,
refusalIdentity: input.refusalIdentity,
},
dependencies.run,
);
if (!refusalControl.observed) {
return blocked('refusal-control-failed', [
...report.findings,
{
code: 'brain-refusal-control-indeterminate',
reasonCode: refusalControl.reasonCode,
},
]);
}
const owner = await resolveProviderDurableOwner(
{
estateRegistrySource: input.estateRegistrySource,
ownerPolicySource: input.ownerPolicySource,
host: target.host,
requestedOwner: input.requestedOwner,
},
{
fetch: dependencies.fetch,
absentControlName: dependencies.absentControlName,
},
);
if (owner.verdict !== 'resolved') {
const plan = discoverBrainMigration(
{
sourceRoot: input.sourceRoot,
brainRoot: input.root,
seat: input.seat,
lane: input.lane,
laneActive: input.laneActive,
},
(): MigrationOwnerResolution => owner,
);
const migration = migrateBrainState(
plan,
(): never => {
throw new Error('blocked owner cannot publish');
},
input.root,
);
return blocked(owner.reasonCode, report.findings, owner, migration);
}
if (report.findings.some((finding): boolean => finding.code === 'brain-clone-missing')) {
try {
ensureBrainRootPrivate(input.root);
} catch {
return failed('brain-root-permissions-unsafe', report.findings);
}
const clone: CommandRequest = {
program: 'git',
args: ['clone', '--branch', 'main', '--single-branch', target.cloneUrl, input.root],
env: commandEnv(input.identity),
};
const cloneResult: CommandResult = dependencies.run(clone);
if (cloneResult.status !== 0) return failed('brain-clone-failed', report.findings);
try {
ensureBrainRootPrivate(input.root);
} catch {
return failed('brain-root-permissions-unsafe', report.findings);
}
report = collectBrainDoctorReport(doctorInput, dependencies.run);
}
const blockingCloneFindings = report.findings.filter(
(finding): boolean =>
finding.code === 'brain-clone-missing' ||
finding.code === 'brain-not-git-repository' ||
finding.code === 'brain-remote-mismatch' ||
finding.code === 'brain-branch-mismatch' ||
finding.code === 'brain-uncommitted-state' ||
finding.code === 'brain-git-state-indeterminate' ||
finding.code === 'brain-root-permissions-unsafe' ||
finding.code.startsWith('brain-write-access-'),
);
if (blockingCloneFindings.length > 0) {
return blocked('brain-postcondition-failed', report.findings);
}
let skeletonEntries: readonly MigrationPublishEntry[];
try {
const skeleton = createBrainSkeleton(input.root);
skeletonEntries = skeleton.publicationEntries;
} catch {
return failed('brain-skeleton-failed', report.findings);
}
if (skeletonEntries.length > 0) {
try {
const evidence = publishBrainPaths(
{
root: input.root,
identity: input.identity,
entries: skeletonEntries,
message: 'chore: seed durable brain layout',
},
dependencies.run,
);
if (!evidence.reachable) return failed('brain-skeleton-not-reachable', report.findings);
} catch {
return failed('brain-skeleton-publish-failed', report.findings);
}
}
const plan = discoverBrainMigration(
{
sourceRoot: input.sourceRoot,
brainRoot: input.root,
seat: input.seat,
lane: input.lane,
laneActive: input.laneActive,
},
(): MigrationOwnerResolution => owner,
dependencies.approveMigrationContent,
);
const migration = migrateBrainState(
plan,
(brainRoot: string, entries: readonly MigrationPublishEntry[]) =>
publishBrainPaths(
{
root: brainRoot,
identity: input.identity,
entries,
message: `migrate: archive ${input.lane} working memory`,
},
dependencies.run,
),
input.root,
);
if (migration.status === 'failed') {
return failed('brain-migration-publish-failed', report.findings, owner, migration);
}
report = collectBrainDoctorReport(doctorInput, dependencies.run);
if (report.findings.length > 0) {
return blocked('brain-final-postcondition-failed', report.findings, owner, migration);
}
return {
status: 'provisioned',
reasonCode: 'brain-provisioned',
findings: [],
owner: { verdict: owner.verdict, reasonCode: owner.reasonCode },
migration: { status: migration.status, reported: migration.reported },
};
}