mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-22 10:25:20 -06:00
1da74794b6
* fix(release): define immutable release plan contract * fix(release): harden immutable plan authority * fix(release): tighten release plan authority * fix(release): share plugin publication authority * fix(release): verify plan authority remotely * fix(release): track ClawHub publication authorities * fix(release): trust remote tooling tag identity * fix(release): close plugin publication authority * fix(release): align npm authority selection * fix(release): bind plans to validation intent * fix(release): require qualification cadence * fix(release): reject lossy canonical values * fix(release): narrow qualification cadence * fix(release): bind plan parser dependency * fix(release): add tagless diagnostic plans * fix(release): attest release plan parser tree * fix(release): isolate verified plan parser snapshot * fix(release): verify plan tooling before execution
57 lines
2.5 KiB
JavaScript
57 lines
2.5 KiB
JavaScript
const RELEASE_VALIDATION_INTENTS = Object.freeze({
|
|
"release-beta": Object.freeze({ profile: "beta", publishable: true, soak: false }),
|
|
"release-stable": Object.freeze({ profile: "stable", publishable: true, soak: true }),
|
|
"main-daily": Object.freeze({ profile: "beta", publishable: false, soak: false }),
|
|
"main-weekly": Object.freeze({ profile: "full", publishable: false, soak: true }),
|
|
"diagnostic-full": Object.freeze({ profile: "full", publishable: false, soak: true }),
|
|
});
|
|
|
|
const PURPOSE_INTENTS = Object.freeze({
|
|
"beta-publish": Object.freeze(["release-beta"]),
|
|
"stable-publish": Object.freeze(["release-stable"]),
|
|
diagnostic: Object.freeze(["diagnostic-full"]),
|
|
"postpublish-confidence": Object.freeze(["diagnostic-full"]),
|
|
"main-qualification": Object.freeze(["main-daily", "main-weekly"]),
|
|
});
|
|
|
|
function displayValue(value) {
|
|
return typeof value === "string" ? value : JSON.stringify(value);
|
|
}
|
|
|
|
export function resolveReleaseValidationIntent(intent, assertions = {}) {
|
|
if (typeof intent !== "string" || !Object.hasOwn(RELEASE_VALIDATION_INTENTS, intent)) {
|
|
throw new Error(`unsupported release validation intent: ${displayValue(intent)}`);
|
|
}
|
|
const policy = RELEASE_VALIDATION_INTENTS[intent];
|
|
if (assertions.profile !== undefined && assertions.profile !== policy.profile) {
|
|
throw new Error(
|
|
`release validation intent ${intent} profile assertion conflicts: expected ${policy.profile}, got ${displayValue(assertions.profile)}`,
|
|
);
|
|
}
|
|
if (assertions.soak !== undefined && assertions.soak !== policy.soak) {
|
|
throw new Error(
|
|
`release validation intent ${intent} soak assertion conflicts: expected ${policy.soak}, got ${displayValue(assertions.soak)}`,
|
|
);
|
|
}
|
|
return { intent, ...policy };
|
|
}
|
|
|
|
export function releaseValidationIntentForPurpose(purpose, requestedIntent) {
|
|
if (typeof purpose !== "string" || !Object.hasOwn(PURPOSE_INTENTS, purpose)) {
|
|
throw new Error(`unsupported release plan purpose: ${displayValue(purpose)}`);
|
|
}
|
|
const allowedIntents = PURPOSE_INTENTS[purpose];
|
|
if (requestedIntent === undefined) {
|
|
if (allowedIntents.length !== 1) {
|
|
throw new Error(`release plan purpose ${purpose} requires an explicit validation intent`);
|
|
}
|
|
return allowedIntents[0];
|
|
}
|
|
if (typeof requestedIntent !== "string" || !allowedIntents.includes(requestedIntent)) {
|
|
throw new Error(
|
|
`release plan purpose ${purpose} does not allow validation intent: ${displayValue(requestedIntent)}`,
|
|
);
|
|
}
|
|
return requestedIntent;
|
|
}
|