mirror of
https://github.com/garrytan/gstack.git
synced 2026-10-03 18:06:54 +02:00
style(cso): format lib/cso TypeScript with pinned Prettier
Mechanical reformat only. Minified transpile output is byte-identical for 21 of 22 files; witness.ts differs only in three regex flag orders (/mi -> /im), which JavaScript canonicalizes. Source-text assertions over lib/cso now compare whitespace-insensitively with the same tokens.
This commit is contained in:
1 parent
dcaea52800
commit
d93d61f7ba
27 files changed
+17942
-4164
No files matched your search
+215
-59
@@ -13,10 +13,23 @@ interface RuntimeQualificationProvenance {
|
||||
provenanceDigest: string;
|
||||
verifiedProvenance: true;
|
||||
}
|
||||
export type RuntimeQualification = RuntimeQualificationProvenance & (
|
||||
| { kind: 'application'; containmentPassed: true; coldStartPassed: true; positiveNegativeAssertionsPassed: true; heldOutRepairPassed: true }
|
||||
| { kind: 'postgresql'; containmentPassed: true; coldStartPassed: true; multiDatabasePassed: true; readinessPassed: true }
|
||||
);
|
||||
export type RuntimeQualification = RuntimeQualificationProvenance &
|
||||
(
|
||||
| {
|
||||
kind: 'application';
|
||||
containmentPassed: true;
|
||||
coldStartPassed: true;
|
||||
positiveNegativeAssertionsPassed: true;
|
||||
heldOutRepairPassed: true;
|
||||
}
|
||||
| {
|
||||
kind: 'postgresql';
|
||||
containmentPassed: true;
|
||||
coldStartPassed: true;
|
||||
multiDatabasePassed: true;
|
||||
readinessPassed: true;
|
||||
}
|
||||
);
|
||||
export interface QualifiedRuntime {
|
||||
id: string;
|
||||
stack: CsoStack | 'postgresql';
|
||||
@@ -76,46 +89,96 @@ function versionsKey(versions: Record<string, string>): string {
|
||||
return JSON.stringify(Object.entries(versions).sort(([a], [b]) => a.localeCompare(b)));
|
||||
}
|
||||
|
||||
function validateRuntimeIdentity(value: { id: string; stack: string; platform: string; versions: Record<string, string> }): void {
|
||||
function validateRuntimeIdentity(value: {
|
||||
id: string;
|
||||
stack: string;
|
||||
platform: string;
|
||||
versions: Record<string, string>;
|
||||
}): void {
|
||||
if (typeof value.id !== 'string' || !ID.test(value.id)) throw new Error('INVALID_RUNTIME_ID');
|
||||
if (!STACKS.includes(value.stack as typeof STACKS[number]) || !PLATFORMS.includes(value.platform as RuntimePlatform)) throw new Error('UNSUPPORTED_RUNTIME_PLATFORM');
|
||||
if (!value.versions || typeof value.versions !== 'object' || Array.isArray(value.versions) || !Object.keys(value.versions).length ||
|
||||
Object.values(value.versions).some(version => typeof version !== 'string' || !/^[0-9][a-zA-Z0-9.+_-]*$/.test(version))) throw new Error('UNPINNED_RUNTIME_VERSION');
|
||||
if (Object.keys(value.versions).sort().join(',') !== [...REQUIRED[value.stack]].sort().join(',')) throw new Error('MISSING_RUNTIME_TOOL_VERSION');
|
||||
if (['node', 'bun', 'python', 'rails'].includes(value.stack) && value.versions['cso-preparation'] !== '1.0.0') throw new Error('INCOMPATIBLE_PREPARATION_HELPER');
|
||||
if (
|
||||
!STACKS.includes(value.stack as (typeof STACKS)[number]) ||
|
||||
!PLATFORMS.includes(value.platform as RuntimePlatform)
|
||||
)
|
||||
throw new Error('UNSUPPORTED_RUNTIME_PLATFORM');
|
||||
if (
|
||||
!value.versions ||
|
||||
typeof value.versions !== 'object' ||
|
||||
Array.isArray(value.versions) ||
|
||||
!Object.keys(value.versions).length ||
|
||||
Object.values(value.versions).some(
|
||||
(version) => typeof version !== 'string' || !/^[0-9][a-zA-Z0-9.+_-]*$/.test(version),
|
||||
)
|
||||
)
|
||||
throw new Error('UNPINNED_RUNTIME_VERSION');
|
||||
if (Object.keys(value.versions).sort().join(',') !== [...REQUIRED[value.stack]].sort().join(','))
|
||||
throw new Error('MISSING_RUNTIME_TOOL_VERSION');
|
||||
if (
|
||||
['node', 'bun', 'python', 'rails'].includes(value.stack) &&
|
||||
value.versions['cso-preparation'] !== '1.0.0'
|
||||
)
|
||||
throw new Error('INCOMPATIBLE_PREPARATION_HELPER');
|
||||
}
|
||||
|
||||
export function validateRuntimeCatalog(value: unknown): asserts value is RuntimeCatalog {
|
||||
const catalog = value as RuntimeCatalog;
|
||||
if (!catalog || catalog.schemaVersion !== 1 || catalog.helperAbi !== CSO_HELPER_ABI ||
|
||||
typeof catalog.revision !== 'string' || !BUILD_REVISION.test(catalog.revision) || !Array.isArray(catalog.runtimes)) throw new Error('INCOMPATIBLE_RUNTIME_CATALOG');
|
||||
if (catalog.previousRevision !== null && (typeof catalog.previousRevision !== 'string' || !BUILD_REVISION.test(catalog.previousRevision))) throw new Error('INVALID_RUNTIME_CATALOG');
|
||||
if (
|
||||
!catalog ||
|
||||
catalog.schemaVersion !== 1 ||
|
||||
catalog.helperAbi !== CSO_HELPER_ABI ||
|
||||
typeof catalog.revision !== 'string' ||
|
||||
!BUILD_REVISION.test(catalog.revision) ||
|
||||
!Array.isArray(catalog.runtimes)
|
||||
)
|
||||
throw new Error('INCOMPATIBLE_RUNTIME_CATALOG');
|
||||
if (
|
||||
catalog.previousRevision !== null &&
|
||||
(typeof catalog.previousRevision !== 'string' || !BUILD_REVISION.test(catalog.previousRevision))
|
||||
)
|
||||
throw new Error('INVALID_RUNTIME_CATALOG');
|
||||
|
||||
if (!Array.isArray(catalog.profiles) || catalog.profiles.length !== STACKS.length * PLATFORMS.length ||
|
||||
typeof catalog.buildRevision !== 'string' || !BUILD_REVISION.test(catalog.buildRevision)) throw new Error('INVALID_REVIEWED_RUNTIME_PROFILES');
|
||||
const profiles = new Map<string, ReviewedRuntimeProfile>(), profileIdentities = new Set<string>();
|
||||
if (
|
||||
!Array.isArray(catalog.profiles) ||
|
||||
catalog.profiles.length !== STACKS.length * PLATFORMS.length ||
|
||||
typeof catalog.buildRevision !== 'string' ||
|
||||
!BUILD_REVISION.test(catalog.buildRevision)
|
||||
)
|
||||
throw new Error('INVALID_REVIEWED_RUNTIME_PROFILES');
|
||||
const profiles = new Map<string, ReviewedRuntimeProfile>(),
|
||||
profileIdentities = new Set<string>();
|
||||
for (const profile of catalog.profiles) {
|
||||
validateRuntimeIdentity(profile);
|
||||
const identity = `${profile.stack}:${profile.platform}`;
|
||||
if (profiles.has(profile.id) || profileIdentities.has(identity) || profile.state !== 'build_reviewed' ||
|
||||
!Number.isFinite(Date.parse(profile.reviewedAt))) throw new Error('INVALID_REVIEWED_RUNTIME_PROFILE');
|
||||
profiles.set(profile.id, profile); profileIdentities.add(identity);
|
||||
}
|
||||
for (const stack of STACKS) for (const platform of PLATFORMS) {
|
||||
if (!profileIdentities.has(`${stack}:${platform}`)) throw new Error('INCOMPLETE_REVIEWED_RUNTIME_MATRIX');
|
||||
if (
|
||||
profiles.has(profile.id) ||
|
||||
profileIdentities.has(identity) ||
|
||||
profile.state !== 'build_reviewed' ||
|
||||
!Number.isFinite(Date.parse(profile.reviewedAt))
|
||||
)
|
||||
throw new Error('INVALID_REVIEWED_RUNTIME_PROFILE');
|
||||
profiles.set(profile.id, profile);
|
||||
profileIdentities.add(identity);
|
||||
}
|
||||
for (const stack of STACKS)
|
||||
for (const platform of PLATFORMS) {
|
||||
if (!profileIdentities.has(`${stack}:${platform}`))
|
||||
throw new Error('INCOMPLETE_REVIEWED_RUNTIME_MATRIX');
|
||||
}
|
||||
if (catalog.promotion !== undefined) {
|
||||
if (!/^[a-f0-9]{40}$/.test(catalog.promotion.sourceCommit) ||
|
||||
if (
|
||||
!/^[a-f0-9]{40}$/.test(catalog.promotion.sourceCommit) ||
|
||||
!QUALIFICATION_WORKFLOW.test(catalog.promotion.workflow) ||
|
||||
!DIGEST.test(catalog.promotion.evidenceDigest) ||
|
||||
!DIGEST.test(catalog.promotion.qualificationEvidenceDigest) ||
|
||||
Object.keys(catalog.promotion).sort().join(',') !==
|
||||
['evidenceDigest', 'qualificationEvidenceDigest', 'sourceCommit', 'workflow'].sort().join(',')) {
|
||||
['evidenceDigest', 'qualificationEvidenceDigest', 'sourceCommit', 'workflow'].sort().join(',')
|
||||
) {
|
||||
throw new Error('INVALID_RUNTIME_PROMOTION');
|
||||
}
|
||||
}
|
||||
|
||||
if (catalog.runtimes.length !== 0 && catalog.runtimes.length !== STACKS.length * PLATFORMS.length) throw new Error('INCOMPLETE_QUALIFIED_RUNTIME_MATRIX');
|
||||
if (catalog.runtimes.length !== 0 && catalog.runtimes.length !== STACKS.length * PLATFORMS.length)
|
||||
throw new Error('INCOMPLETE_QUALIFIED_RUNTIME_MATRIX');
|
||||
const ids = new Set<string>();
|
||||
const runtimeIdentities = new Set<string>();
|
||||
for (const runtime of catalog.runtimes) {
|
||||
@@ -124,35 +187,94 @@ export function validateRuntimeCatalog(value: unknown): asserts value is Runtime
|
||||
validateRuntimeIdentity(runtime);
|
||||
const identity = `${runtime.stack}:${runtime.platform}`;
|
||||
if (ids.has(runtime.id) || runtimeIdentities.has(identity)) throw new Error('INVALID_RUNTIME_ID');
|
||||
ids.add(runtime.id); runtimeIdentities.add(identity);
|
||||
ids.add(runtime.id);
|
||||
runtimeIdentities.add(identity);
|
||||
const arch = runtime.platform === 'linux/amd64' ? 'amd64' : 'arm64';
|
||||
const expectedImage = new RegExp(`^ghcr\\.io/garrytan/gstack/cso-staging/${runtime.stack}-${arch}@sha256:[a-f0-9]{64}$`);
|
||||
if (runtime.state !== 'qualified' || !IMAGE.test(runtime.image) || !expectedImage.test(runtime.image) || runtime.entrypoint !== '/opt/cso/entrypoint' ||
|
||||
runtime.helperAbi !== CSO_HELPER_ABI || runtime.policyVersion !== 'cso-isolation-v1') throw new Error('UNQUALIFIED_RUNTIME');
|
||||
const expectedImage = new RegExp(
|
||||
`^ghcr\\.io/garrytan/gstack/cso-staging/${runtime.stack}-${arch}@sha256:[a-f0-9]{64}$`,
|
||||
);
|
||||
if (
|
||||
runtime.state !== 'qualified' ||
|
||||
!IMAGE.test(runtime.image) ||
|
||||
!expectedImage.test(runtime.image) ||
|
||||
runtime.entrypoint !== '/opt/cso/entrypoint' ||
|
||||
runtime.helperAbi !== CSO_HELPER_ABI ||
|
||||
runtime.policyVersion !== 'cso-isolation-v1'
|
||||
)
|
||||
throw new Error('UNQUALIFIED_RUNTIME');
|
||||
const reviewed = profiles.get(runtime.id);
|
||||
if (!reviewed || reviewed.stack !== runtime.stack || reviewed.platform !== runtime.platform ||
|
||||
versionsKey(reviewed.versions) !== versionsKey(runtime.versions)) throw new Error('RUNTIME_BUILD_PROFILE_MISMATCH');
|
||||
if (!qualification || !/^[a-f0-9]{40}$/.test(qualification.sourceCommit) ||
|
||||
if (
|
||||
!reviewed ||
|
||||
reviewed.stack !== runtime.stack ||
|
||||
reviewed.platform !== runtime.platform ||
|
||||
versionsKey(reviewed.versions) !== versionsKey(runtime.versions)
|
||||
)
|
||||
throw new Error('RUNTIME_BUILD_PROFILE_MISMATCH');
|
||||
if (
|
||||
!qualification ||
|
||||
!/^[a-f0-9]{40}$/.test(qualification.sourceCommit) ||
|
||||
!QUALIFICATION_WORKFLOW.test(qualification.workflow) ||
|
||||
!DIGEST.test(qualification.sbomDigest) || !DIGEST.test(qualification.provenanceDigest) || qualification.verifiedProvenance !== true ||
|
||||
!Number.isFinite(Date.parse(runtime.qualifiedAt))) throw new Error('MISSING_RUNTIME_QUALIFICATION');
|
||||
!DIGEST.test(qualification.sbomDigest) ||
|
||||
!DIGEST.test(qualification.provenanceDigest) ||
|
||||
qualification.verifiedProvenance !== true ||
|
||||
!Number.isFinite(Date.parse(runtime.qualifiedAt))
|
||||
)
|
||||
throw new Error('MISSING_RUNTIME_QUALIFICATION');
|
||||
const keys = Object.keys(qualification).sort();
|
||||
const common = ['kind', 'sourceCommit', 'workflow', 'sbomDigest', 'provenanceDigest', 'verifiedProvenance'];
|
||||
const common = [
|
||||
'kind',
|
||||
'sourceCommit',
|
||||
'workflow',
|
||||
'sbomDigest',
|
||||
'provenanceDigest',
|
||||
'verifiedProvenance',
|
||||
];
|
||||
if (['node', 'bun', 'python', 'rails'].includes(runtime.stack)) {
|
||||
if (qualification.kind !== 'application' || qualification.containmentPassed !== true || qualification.coldStartPassed !== true ||
|
||||
qualification.positiveNegativeAssertionsPassed !== true || qualification.heldOutRepairPassed !== true ||
|
||||
keys.join(',') !== [...common, 'containmentPassed', 'coldStartPassed', 'positiveNegativeAssertionsPassed', 'heldOutRepairPassed'].sort().join(',')) throw new Error('MISSING_APPLICATION_QUALIFICATION');
|
||||
if (
|
||||
qualification.kind !== 'application' ||
|
||||
qualification.containmentPassed !== true ||
|
||||
qualification.coldStartPassed !== true ||
|
||||
qualification.positiveNegativeAssertionsPassed !== true ||
|
||||
qualification.heldOutRepairPassed !== true ||
|
||||
keys.join(',') !==
|
||||
[
|
||||
...common,
|
||||
'containmentPassed',
|
||||
'coldStartPassed',
|
||||
'positiveNegativeAssertionsPassed',
|
||||
'heldOutRepairPassed',
|
||||
]
|
||||
.sort()
|
||||
.join(',')
|
||||
)
|
||||
throw new Error('MISSING_APPLICATION_QUALIFICATION');
|
||||
} else {
|
||||
if (qualification.kind !== 'postgresql' || qualification.containmentPassed !== true || qualification.coldStartPassed !== true ||
|
||||
qualification.multiDatabasePassed !== true || qualification.readinessPassed !== true ||
|
||||
keys.join(',') !== [...common, 'containmentPassed', 'coldStartPassed', 'multiDatabasePassed', 'readinessPassed'].sort().join(',')) throw new Error('MISSING_POSTGRESQL_QUALIFICATION');
|
||||
if (
|
||||
qualification.kind !== 'postgresql' ||
|
||||
qualification.containmentPassed !== true ||
|
||||
qualification.coldStartPassed !== true ||
|
||||
qualification.multiDatabasePassed !== true ||
|
||||
qualification.readinessPassed !== true ||
|
||||
keys.join(',') !==
|
||||
[...common, 'containmentPassed', 'coldStartPassed', 'multiDatabasePassed', 'readinessPassed']
|
||||
.sort()
|
||||
.join(',')
|
||||
)
|
||||
throw new Error('MISSING_POSTGRESQL_QUALIFICATION');
|
||||
}
|
||||
}
|
||||
if (catalog.runtimes.length > 0) {
|
||||
for (const identity of profileIdentities) if (!runtimeIdentities.has(identity)) throw new Error('INCOMPLETE_QUALIFIED_RUNTIME_MATRIX');
|
||||
for (const identity of profileIdentities)
|
||||
if (!runtimeIdentities.has(identity)) throw new Error('INCOMPLETE_QUALIFIED_RUNTIME_MATRIX');
|
||||
if (!catalog.promotion) throw new Error('MISSING_RUNTIME_PROMOTION');
|
||||
if (catalog.runtimes.some(runtime => runtime.qualification.sourceCommit !== catalog.promotion!.sourceCommit ||
|
||||
runtime.qualification.workflow !== catalog.promotion!.workflow)) throw new Error('RUNTIME_PROMOTION_MISMATCH');
|
||||
if (
|
||||
catalog.runtimes.some(
|
||||
(runtime) =>
|
||||
runtime.qualification.sourceCommit !== catalog.promotion!.sourceCommit ||
|
||||
runtime.qualification.workflow !== catalog.promotion!.workflow,
|
||||
)
|
||||
)
|
||||
throw new Error('RUNTIME_PROMOTION_MISMATCH');
|
||||
if (catalog.promotion.evidenceDigest !== `sha256:${sha256(canonical(catalog.runtimes))}`) {
|
||||
throw new Error('RUNTIME_PROMOTION_EVIDENCE_MISMATCH');
|
||||
}
|
||||
@@ -163,38 +285,72 @@ export const RUNTIME_CATALOG = committedCatalog as RuntimeCatalog;
|
||||
validateRuntimeCatalog(RUNTIME_CATALOG);
|
||||
|
||||
export function assertRuntimeCompatible(plan: PreparationPlan, runtime: QualifiedRuntime): void {
|
||||
if (plan.schemaVersion !== 1 || plan.status !== 'ready' || runtime.stack !== plan.stack) throw new CsoError('INCOMPATIBLE_INPUT', `Prepared ${plan.stack} source cannot run in ${runtime.stack} runtime ${runtime.id}`);
|
||||
if (plan.schemaVersion !== 1 || plan.status !== 'ready' || runtime.stack !== plan.stack)
|
||||
throw new CsoError(
|
||||
'INCOMPATIBLE_INPUT',
|
||||
`Prepared ${plan.stack} source cannot run in ${runtime.stack} runtime ${runtime.id}`,
|
||||
);
|
||||
for (const [declared, rawRange] of Object.entries(plan.runtimeRequirements)) {
|
||||
if (!rawRange) continue;
|
||||
let tool = declared, range = rawRange;
|
||||
let tool = declared,
|
||||
range = rawRange;
|
||||
if (declared === 'packageManager') {
|
||||
const match = rawRange.match(/^([a-z][a-z0-9_-]*)@(.+)$/i);
|
||||
if (!match) throw new CsoError('PREREQUISITE', 'Package manager declaration must bind a named version range');
|
||||
tool = match[1]; range = match[2];
|
||||
if (!match)
|
||||
throw new CsoError('PREREQUISITE', 'Package manager declaration must bind a named version range');
|
||||
tool = match[1];
|
||||
range = match[2];
|
||||
}
|
||||
const version = runtime.versions[tool];
|
||||
if (!version) throw new CsoError('PREREQUISITE', `Qualified runtime ${runtime.id} does not declare a real ${tool} release`);
|
||||
if (!version)
|
||||
throw new CsoError(
|
||||
'PREREQUISITE',
|
||||
`Qualified runtime ${runtime.id} does not declare a real ${tool} release`,
|
||||
);
|
||||
let satisfies = false;
|
||||
try { satisfies = Bun.semver.satisfies(version.replace(/^v/, ''), range); } catch {}
|
||||
if (!satisfies) throw new CsoError('PREREQUISITE', `Qualified ${tool} ${version} does not satisfy source requirement ${range}`);
|
||||
try {
|
||||
satisfies = Bun.semver.satisfies(version.replace(/^v/, ''), range);
|
||||
} catch {}
|
||||
if (!satisfies)
|
||||
throw new CsoError(
|
||||
'PREREQUISITE',
|
||||
`Qualified ${tool} ${version} does not satisfy source requirement ${range}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function selectRuntime(profile: string, platform: RuntimePlatform, catalog: RuntimeCatalog = RUNTIME_CATALOG): QualifiedRuntime {
|
||||
export function selectRuntime(
|
||||
profile: string,
|
||||
platform: RuntimePlatform,
|
||||
catalog: RuntimeCatalog = RUNTIME_CATALOG,
|
||||
): QualifiedRuntime {
|
||||
validateRuntimeCatalog(catalog);
|
||||
const matches = catalog.runtimes.filter(runtime => runtime.platform === platform && (runtime.id === profile || runtime.stack === profile));
|
||||
const matches = catalog.runtimes.filter(
|
||||
(runtime) => runtime.platform === platform && (runtime.id === profile || runtime.stack === profile),
|
||||
);
|
||||
if (matches.length === 0) {
|
||||
const reviewed = catalog.profiles?.filter(item => item.platform === platform && (item.id === profile || item.stack === profile)) ?? [];
|
||||
const detail = reviewed.length === 1 ? ` Reviewed build profile ${reviewed[0].id} is awaiting a qualified image promotion.` : '';
|
||||
throw new Error(`MISSING_QUALIFIED_RUNTIME: ${profile} on ${platform}; build, qualify, and review a digest catalog before target execution.${detail}`);
|
||||
const reviewed =
|
||||
catalog.profiles?.filter(
|
||||
(item) => item.platform === platform && (item.id === profile || item.stack === profile),
|
||||
) ?? [];
|
||||
const detail =
|
||||
reviewed.length === 1
|
||||
? ` Reviewed build profile ${reviewed[0].id} is awaiting a qualified image promotion.`
|
||||
: '';
|
||||
throw new Error(
|
||||
`MISSING_QUALIFIED_RUNTIME: ${profile} on ${platform}; build, qualify, and review a digest catalog before target execution.${detail}`,
|
||||
);
|
||||
}
|
||||
if (matches.length !== 1) throw new Error(`AMBIGUOUS_RUNTIME: select an exact qualified runtime id for ${profile}.`);
|
||||
if (matches.length !== 1)
|
||||
throw new Error(`AMBIGUOUS_RUNTIME: select an exact qualified runtime id for ${profile}.`);
|
||||
return matches[0];
|
||||
}
|
||||
|
||||
/** Rollback only pairs the previous catalog with a compatible helper; reports have their own schema. */
|
||||
export function rollbackCatalog(current: RuntimeCatalog, previous: RuntimeCatalog): RuntimeCatalog {
|
||||
validateRuntimeCatalog(current); validateRuntimeCatalog(previous);
|
||||
if (current.previousRevision !== previous.revision || current.helperAbi !== previous.helperAbi) throw new Error('INCOMPATIBLE_RUNTIME_ROLLBACK');
|
||||
validateRuntimeCatalog(current);
|
||||
validateRuntimeCatalog(previous);
|
||||
if (current.previousRevision !== previous.revision || current.helperAbi !== previous.helperAbi)
|
||||
throw new Error('INCOMPATIBLE_RUNTIME_ROLLBACK');
|
||||
return previous;
|
||||
}
|
||||
Reference in new issue
Block a user