Add tenant apply resource checklist
Refine tenant-apply dry runs with per-resource status entries so databases, worker jails, and datasets are reported as explicit future-create candidates instead of only appearing inside summary sections. --- Build: pass | Tests: pass — 31 passed (1 file)
This commit is contained in:
parent
d3ae1f3ade
commit
daf29fa332
5 changed files with 79 additions and 0 deletions
|
|
@ -298,3 +298,9 @@ Preflight for a future live apply should at minimum verify:
|
|||
- tenant resources are still disjoint from shared platform resources
|
||||
- tenant resources are still disjoint from other tenants
|
||||
- no blocked manual step is being silently skipped
|
||||
|
||||
The dry-run apply surface should also report a per-resource checklist:
|
||||
|
||||
- `would-create` for tenant-owned resources a future live apply could create
|
||||
- `exists-in-contract` for resources already satisfied declaratively
|
||||
- `blocked` for anything a future live apply must not touch yet
|
||||
|
|
|
|||
|
|
@ -202,6 +202,8 @@ Also updated:
|
|||
declarative model and what still blocks any automatic apply
|
||||
- explicit policy buckets for future automatic candidates, manual-only
|
||||
steps, and permanent out-of-scope actions
|
||||
- a per-resource checklist showing `would-create`, `exists-in-contract`, or
|
||||
`blocked` status for databases, datasets, and worker jails
|
||||
|
||||
## Recommended first code tasks
|
||||
|
||||
|
|
|
|||
|
|
@ -167,6 +167,16 @@ function printApplyPlan(
|
|||
console.log(`Allowed databases: ${plan.allowedResources.databases.join(', ')}`);
|
||||
console.log(`Allowed worker jails: ${plan.allowedResources.workerJails.join(', ')}`);
|
||||
console.log(`Allowed datasets: ${plan.allowedResources.datasets.join(', ') || '(none)'}`);
|
||||
console.log('Resource checklist:');
|
||||
for (const entry of plan.resourceChecklist.databases) {
|
||||
console.log(`- [${entry.status}] database ${entry.name}: ${entry.detail}`);
|
||||
}
|
||||
for (const entry of plan.resourceChecklist.workerJails) {
|
||||
console.log(`- [${entry.status}] worker-jail ${entry.name}: ${entry.detail}`);
|
||||
}
|
||||
for (const entry of plan.resourceChecklist.datasets) {
|
||||
console.log(`- [${entry.status}] dataset ${entry.name}: ${entry.detail}`);
|
||||
}
|
||||
console.log('Action policy:');
|
||||
for (const action of plan.actionPolicy.automaticCandidates) {
|
||||
console.log(`- [future-auto] ${action.name}: ${action.resources.join(', ') || '(none)'}`);
|
||||
|
|
|
|||
|
|
@ -115,6 +115,30 @@ describe('tenant-registry', () => {
|
|||
expect.objectContaining({ name: 'Shared platform resources' }),
|
||||
]),
|
||||
);
|
||||
expect(plan.resourceChecklist.databases).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
name: 'mevy_brain',
|
||||
status: 'would-create',
|
||||
}),
|
||||
]),
|
||||
);
|
||||
expect(plan.resourceChecklist.workerJails).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
name: 'mevy_ctrl_worker',
|
||||
status: 'would-create',
|
||||
}),
|
||||
]),
|
||||
);
|
||||
expect(plan.resourceChecklist.datasets).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
name: 'zroot/mevy-ai',
|
||||
status: 'would-create',
|
||||
}),
|
||||
]),
|
||||
);
|
||||
expect(plan.manualSteps).toContain(
|
||||
'No live resources are created by this workflow today.',
|
||||
);
|
||||
|
|
|
|||
|
|
@ -139,6 +139,23 @@ export interface TenantApplyPlan {
|
|||
tenant: TenantRecord;
|
||||
registryPath: string;
|
||||
readyForAutomaticApply: boolean;
|
||||
resourceChecklist: {
|
||||
databases: Array<{
|
||||
name: string;
|
||||
status: 'would-create' | 'exists-in-contract' | 'blocked';
|
||||
detail: string;
|
||||
}>;
|
||||
workerJails: Array<{
|
||||
name: string;
|
||||
status: 'would-create' | 'exists-in-contract' | 'blocked';
|
||||
detail: string;
|
||||
}>;
|
||||
datasets: Array<{
|
||||
name: string;
|
||||
status: 'would-create' | 'exists-in-contract' | 'blocked';
|
||||
detail: string;
|
||||
}>;
|
||||
};
|
||||
actionPolicy: {
|
||||
automaticCandidates: Array<{
|
||||
name: string;
|
||||
|
|
@ -697,6 +714,26 @@ export function planTenantApply(
|
|||
tenant,
|
||||
registryPath,
|
||||
readyForAutomaticApply: false,
|
||||
resourceChecklist: {
|
||||
databases: Object.values(tenant.databases).map((name) => ({
|
||||
name,
|
||||
status: 'would-create',
|
||||
detail:
|
||||
'Future live apply could create this tenant-owned database, but no host mutation exists yet.',
|
||||
})),
|
||||
workerJails: tenant.workerJails.map((name) => ({
|
||||
name,
|
||||
status: 'would-create',
|
||||
detail:
|
||||
'Future live apply could provision this tenant-owned worker jail, subject to host-level review.',
|
||||
})),
|
||||
datasets: tenant.datasets.map((name) => ({
|
||||
name,
|
||||
status: 'would-create',
|
||||
detail:
|
||||
'Future live apply could create this tenant-owned dataset without touching shared platform datasets.',
|
||||
})),
|
||||
},
|
||||
actionPolicy: {
|
||||
automaticCandidates: [
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue