Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 0 additions & 89 deletions packages/onboarding/src/provision.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@ import {
DEFAULT_WORKFLOWS,
reconcileSeedGrants,
seedTenant,
publishCorbitsToolsRegistry,
isCorbitsToolsRegistrySeeded,
type ModelSource,
type ToolRegistryPublisher,
type WorkflowPusher,
isLiveDeploymentStatus,
} from "@corbits/seeding";
Expand Down Expand Up @@ -107,7 +105,6 @@ export type ProvisionArgs = {
displayName?: string;
operatorTenantId?: string;
seedModel?: ModelSource;
publishToolRegistry?: ToolRegistryPublisher;
pushWorkflow: WorkflowPusher;
log: (line: string) => void;
/** The closed-by-default access-policy gate. Absent means this hub
Expand Down Expand Up @@ -230,33 +227,6 @@ export async function isFullySeeded(
return isCorbitsToolsRegistrySeeded(api, cookies, tenantId);
}

async function publishRootToolRegistry(args: {
api: ApiCall;
cookies: string[];
hubUrl: string;
tenantId: string;
publishToolRegistry?: ToolRegistryPublisher;
log: (line: string) => void;
}): Promise<void> {
const publishToolRegistry =
args.publishToolRegistry ?? publishCorbitsToolsRegistry;
try {
await publishToolRegistry({
api: args.api,
cookies: args.cookies,
hubUrl: args.hubUrl,
tenantId: args.tenantId,
log: args.log,
});
} catch (cause) {
throw new ProvisionError(
"tool_registry_publish_failed",
`personal root bench ${args.tenantId} could not publish corbits-tools before seeding: ${cause instanceof Error ? cause.message : String(cause)}`,
"transient",
);
}
}

/**
* The honest partial-seed report `ensureSeeded` reads after catching a
* sidecar-unavailable deploy failure (CL-6264): which default workflows
Expand Down Expand Up @@ -333,39 +303,6 @@ export async function provisionPersonalTenantIfNeeded(
tenantResponse.data,
"tenant response",
);
if (ownTenant.parentId === undefined || ownTenant.parentId === null) {
await publishRootToolRegistry({
api: args.api,
cookies: args.cookies,
hubUrl: args.hubUrl,
tenantId: own.tenantId,
...(args.publishToolRegistry !== undefined
? { publishToolRegistry: args.publishToolRegistry }
: {}),
log: args.log,
});
} else if (
!(await isCorbitsToolsRegistrySeeded(
args.api,
args.cookies,
own.tenantId,
))
) {
// A parented bench inherits `corbits-tools`. When that inherited
// registry is missing or dangling-empty, republish locally the
// same way grant reconcile fills missing grants on every sign-in.
await publishRootToolRegistry({
api: args.api,
cookies: args.cookies,
hubUrl: args.hubUrl,
tenantId: own.tenantId,
...(args.publishToolRegistry !== undefined
? { publishToolRegistry: args.publishToolRegistry }
: {}),
log: args.log,
});
}

const fullySeeded = await isFullySeeded(
args.api,
args.cookies,
Expand Down Expand Up @@ -503,32 +440,6 @@ export async function provisionPersonalTenantIfNeeded(
);
}

if (tenant.parentId === undefined || tenant.parentId === null) {
await publishRootToolRegistry({
api: args.api,
cookies: args.cookies,
hubUrl: args.hubUrl,
tenantId: tenant.id,
...(args.publishToolRegistry !== undefined
? { publishToolRegistry: args.publishToolRegistry }
: {}),
log: args.log,
});
} else if (
!(await isCorbitsToolsRegistrySeeded(args.api, args.cookies, tenant.id))
) {
await publishRootToolRegistry({
api: args.api,
cookies: args.cookies,
hubUrl: args.hubUrl,
tenantId: tenant.id,
...(args.publishToolRegistry !== undefined
? { publishToolRegistry: args.publishToolRegistry }
: {}),
log: args.log,
});
}

if (!args.seedModel) {
const seedSkipReason =
"no hub-owned seed model credential is configured (ANTHROPIC_API_KEY); the bench was provisioned without the default workflow set";
Expand Down
41 changes: 2 additions & 39 deletions packages/onboarding/test/provision.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ const noopPush: WorkflowPusher = async () => ({
outcome: "pushed" as const,
commitSha: "a".repeat(40),
});
const noopPublishToolRegistry = async () => undefined;

const TOOLS_ASSET_ID = "ast_corbits_tools";
const SEEDED_MEMORY_TARBALL = {
filename: "corbits-memory-tools-0.0.4.tgz",
Expand Down Expand Up @@ -344,7 +342,6 @@ describe("provisionPersonalTenantIfNeeded", () => {
userId: "user_1",
userEmail: "alice@example.com",
userEmailVerified: true,
publishToolRegistry: noopPublishToolRegistry,
pushWorkflow: noopPush,
log: collector().log,
});
Expand Down Expand Up @@ -404,7 +401,6 @@ describe("provisionPersonalTenantIfNeeded", () => {
userEmail: "alice@example.com",
userEmailVerified: true,
displayName: "Alice's Lab",
publishToolRegistry: noopPublishToolRegistry,
pushWorkflow: noopPush,
log: collector().log,
});
Expand Down Expand Up @@ -440,7 +436,6 @@ describe("provisionPersonalTenantIfNeeded", () => {
userEmail: "alice@example.com",
userEmailVerified: true,
displayName: "Alice's Lab",
publishToolRegistry: noopPublishToolRegistry,
pushWorkflow: noopPush,
log: collector().log,
}),
Expand All @@ -450,7 +445,6 @@ describe("provisionPersonalTenantIfNeeded", () => {
test("zero principals with no seed model: provisions the bench and reports the seed skip loudly", async () => {
let principalsCalls = 0;
const { lines, log } = collector();
const publishedTenants: string[] = [];
const api: ApiCall = async (method, path, body) => {
if (method === "GET" && path === "/api/me/principals") {
principalsCalls += 1;
Expand Down Expand Up @@ -512,17 +506,13 @@ describe("provisionPersonalTenantIfNeeded", () => {
userEmail: "alice@example.com",
userEmailVerified: true,
displayName: "Alice's Lab",
publishToolRegistry: async ({ tenantId }) => {
publishedTenants.push(tenantId);
},
pushWorkflow: noopPush,
log,
});

expect(result.kind).toBe("provisioned");
if (result.kind !== "provisioned") throw new Error("unreachable");
expect(result.seeded).toBe(false);
expect(publishedTenants).toEqual([TENANT_ID]);
expect(result.seedSkipReason).toContain("ANTHROPIC_API_KEY");
expect(lines.some((line) => line.includes("ANTHROPIC_API_KEY"))).toBe(true);
});
Expand Down Expand Up @@ -553,7 +543,6 @@ describe("provisionPersonalTenantIfNeeded", () => {
userId: "user_1",
userEmail: "alice@example.com",
userEmailVerified: true,
publishToolRegistry: noopPublishToolRegistry,
pushWorkflow: noopPush,
log,
});
Expand All @@ -577,7 +566,6 @@ describe("provisionPersonalTenantIfNeeded", () => {
displayName: "Alice's Lab",
operatorTenantId: "ten_operator",
seedModel: MODEL,
publishToolRegistry: noopPublishToolRegistry,
pushWorkflow: noopPush,
log,
});
Expand All @@ -591,10 +579,9 @@ describe("provisionPersonalTenantIfNeeded", () => {
expect(tarballPuts).toEqual([]);
});

test("an unparented personal root bench publishes corbits-tools before seeding", async () => {
test("an unparented personal root bench does not publish corbits-tools; provision only deploys workflows", async () => {
const { api, tarballPuts } = firstLoginSeedHub({});
const { log } = collector();
const publishedTenants: string[] = [];
const result = await provisionPersonalTenantIfNeeded({
api,
cookies: ["session=abc"],
Expand All @@ -604,9 +591,6 @@ describe("provisionPersonalTenantIfNeeded", () => {
userEmailVerified: true,
displayName: "Alice's Lab",
seedModel: MODEL,
publishToolRegistry: async ({ tenantId }) => {
publishedTenants.push(tenantId);
},
pushWorkflow: noopPush,
log,
});
Expand All @@ -617,7 +601,6 @@ describe("provisionPersonalTenantIfNeeded", () => {
tenantSlug: TENANT_SLUG,
seeded: true,
});
expect(publishedTenants).toEqual([TENANT_ID]);
expect(tarballPuts).toEqual([]);
});

Expand Down Expand Up @@ -853,7 +836,6 @@ describe("provisionPersonalTenantIfNeeded", () => {
userEmailVerified: true,
displayName: "Alice's Lab",
seedModel: MODEL,
publishToolRegistry: noopPublishToolRegistry,
pushWorkflow: noopPush,
log: collector().log,
});
Expand All @@ -869,7 +851,6 @@ describe("provisionPersonalTenantIfNeeded", () => {
userEmail: "alice@example.com",
userEmailVerified: true,
seedModel: MODEL,
publishToolRegistry: noopPublishToolRegistry,
pushWorkflow: noopPush,
log,
});
Expand Down Expand Up @@ -905,7 +886,6 @@ describe("provisionPersonalTenantIfNeeded", () => {
),
);
const grantsPosted: { resource: string; action: string }[] = [];
const publishedTenants: string[] = [];
const api: ApiCall = async (method, path, body) => {
const registry = corbitsToolsRegistryResponse(method, path, TENANT_ID, [
SEEDED_MEMORY_TARBALL,
Expand Down Expand Up @@ -1021,9 +1001,6 @@ describe("provisionPersonalTenantIfNeeded", () => {
userEmail: "alice@example.com",
userEmailVerified: true,
// No seedModel needed: nothing left to seed on the workflow side.
publishToolRegistry: async ({ tenantId }) => {
publishedTenants.push(tenantId);
},
pushWorkflow: noopPush,
log: collector().log,
});
Expand All @@ -1033,7 +1010,6 @@ describe("provisionPersonalTenantIfNeeded", () => {
seeded: true,
tenantId: "ten_new",
});
expect(publishedTenants).toEqual([TENANT_ID]);
// Exactly the one grant this tenant was missing — no more, no less.
expect(grantsPosted).toEqual([missingGrant]);
});
Expand Down Expand Up @@ -1133,7 +1109,6 @@ describe("provisionPersonalTenantIfNeeded", () => {
userId: "user_1",
userEmail: "alice@example.com",
userEmailVerified: true,
publishToolRegistry: noopPublishToolRegistry,
pushWorkflow: noopPush,
log: collector().log,
});
Expand All @@ -1151,7 +1126,6 @@ describe("provisionPersonalTenantIfNeeded", () => {
// not depend on a seed credential that may never exist. Seeding itself is
// skipped (nothing to seed with); the user is not stranded in a loop.
let assetListCalls = 0;
const publishedTenants: string[] = [];
const api: ApiCall = async (method, path) => {
const registry = corbitsToolsRegistryResponse(
method,
Expand Down Expand Up @@ -1235,9 +1209,6 @@ describe("provisionPersonalTenantIfNeeded", () => {
userEmail: "alice@example.com",
userEmailVerified: true,
// No seedModel — hub without ANTHROPIC_API_KEY.
publishToolRegistry: async ({ tenantId }) => {
publishedTenants.push(tenantId);
},
pushWorkflow: noopPush,
log: collector().log,
});
Expand All @@ -1250,7 +1221,6 @@ describe("provisionPersonalTenantIfNeeded", () => {
seeded: false,
tenantId: "ten_new",
});
expect(publishedTenants).toEqual([TENANT_ID]);
// Completeness was checked (tenant-local assets listed) even without a
// seed model — membership recovery does not short-circuit before that.
expect(assetListCalls).toBe(1);
Expand Down Expand Up @@ -1479,7 +1449,6 @@ describe("provisionPersonalTenantIfNeeded", () => {
userEmail: "alice@example.com",
userEmailVerified: true,
seedModel: MODEL,
publishToolRegistry: noopPublishToolRegistry,
pushWorkflow: noopPush,
log: collector().log,
});
Expand Down Expand Up @@ -1742,7 +1711,6 @@ describe("provisionPersonalTenantIfNeeded", () => {
userEmail: "alice@example.com",
userEmailVerified: true,
seedModel: MODEL,
publishToolRegistry: noopPublishToolRegistry,
pushWorkflow: noopPush,
log: collector().log,
});
Expand Down Expand Up @@ -1856,8 +1824,7 @@ describe("provisionPersonalTenantIfNeeded", () => {
expect(await isFullySeeded(api, ["session=abc"], TENANT_ID)).toBe(true);
});

test("sign-in republishes an empty inherited corbits-tools registry", async () => {
const publishedTenants: string[] = [];
test("sign-in does not republish an empty inherited corbits-tools registry", async () => {
const api: ApiCall = async (method, path) => {
const registry = corbitsToolsRegistryResponse(
method,
Expand Down Expand Up @@ -1958,14 +1925,10 @@ describe("provisionPersonalTenantIfNeeded", () => {
userId: "user_1",
userEmail: "alice@example.com",
userEmailVerified: true,
publishToolRegistry: async ({ tenantId }) => {
publishedTenants.push(tenantId);
},
pushWorkflow: noopPush,
log: collector().log,
});

expect(publishedTenants).toEqual([TENANT_ID]);
expect(result).toEqual({
kind: "existing-member",
seeded: false,
Expand Down
Loading