Harden live release-manifest readiness checks

This commit is contained in:
axiomlogicnexus 2026-06-24 23:01:36 +00:00
parent fbb623ea2e
commit 58cb19955b
4 changed files with 339 additions and 1 deletions

View file

@ -37,7 +37,8 @@ Before using these templates:
from the local repo to stage the current committed `website/` tree into a VPS
temp checkout, boot it on the host-safe staging port, verify the real
`/health`, `/api/auth/health`, `/api/releases/manifest`, and root shell
surfaces, and clean the temp lane back up on success; add
surfaces, fail if the live anonymous release-manifest drifted from the
rendered launch authority, and clean the temp lane back up on success; add
`--archive-source worktree` when the proof should use the in-progress local
worktree rather than committed `HEAD`
- after staging proof or for direct root-owned rollout, you can now also run

View file

@ -69,6 +69,27 @@ function isHttpsUrl(url) {
return url?.protocol === 'https:'
}
const RELEASE_MANIFEST_PLATFORM_EXPECTATIONS = [
{
platformKey: 'windows',
envPrefix: 'WINDOWS',
legacyFrontendUrlKey: 'VITE_WINDOWS_DOWNLOAD_URL',
label: 'Windows',
},
{
platformKey: 'macos',
envPrefix: 'MACOS',
legacyFrontendUrlKey: 'VITE_MAC_DOWNLOAD_URL',
label: 'macOS',
},
{
platformKey: 'linux',
envPrefix: 'LINUX',
legacyFrontendUrlKey: 'VITE_LINUX_DOWNLOAD_URL',
label: 'Linux',
},
]
function createBucket() {
return {
failures: [],
@ -202,6 +223,189 @@ function resolveEnvCandidate(frontendEnv, serverEnv, frontendKey, serverKey) {
}
}
function readEnvFirst(frontendEnv, serverEnv, frontendKey, serverKey = frontendKey) {
return normalizeTrimmed(frontendEnv[frontendKey] || serverEnv[serverKey])
}
function readServerOnly(serverEnv, key) {
return normalizeTrimmed(serverEnv[key])
}
function readOptionalInteger(serverEnv, key) {
const rawValue = readServerOnly(serverEnv, key)
if (!rawValue) {
return null
}
const value = Number(rawValue)
if (!Number.isFinite(value) || value < 0) {
return null
}
return Math.trunc(value)
}
function formatRuntimeComparableValue(value) {
if (value === null || value === undefined) {
return '(blank)'
}
if (typeof value === 'boolean') {
return value ? 'true' : 'false'
}
if (typeof value === 'number') {
return Number.isFinite(value) ? String(value) : '(blank)'
}
const trimmed = normalizeTrimmed(value)
return trimmed || '(blank)'
}
function compareRuntimeComparableValues(expected, actual) {
return formatRuntimeComparableValue(expected) === formatRuntimeComparableValue(actual)
}
function pushLiveManifestDriftFailure(failures, label, expected, actual) {
failures.push(
`${label} drifted from configured launch authority (expected ${formatRuntimeComparableValue(expected)}, got ${formatRuntimeComparableValue(actual)}).`,
)
}
function appendLiveReleaseManifestDriftChecks({
failures,
frontendEnv,
serverEnv,
liveReleaseManifest,
}) {
const manifest = liveReleaseManifest?.manifest
if (!manifest) {
return
}
const topLevelExpectations = [
{
label: 'Live release manifest support email',
expected: readEnvFirst(frontendEnv, serverEnv, 'VITE_SUPPORT_EMAIL', 'SUPPORT_EMAIL') || 'hello@hypertwist.app',
actual: manifest.support_email,
},
{
label: 'Live release manifest public docs URL',
expected: readEnvFirst(frontendEnv, serverEnv, 'VITE_PUBLIC_DOCS_URL', 'PUBLIC_DOCS_URL'),
actual: manifest.public_docs_url,
},
{
label: 'Live release manifest release-notes URL',
expected: readEnvFirst(frontendEnv, serverEnv, 'VITE_RELEASE_NOTES_URL', 'RELEASE_NOTES_URL'),
actual: manifest.release_notes_url,
},
{
label: 'Live release manifest corresponding-source URL',
expected: readEnvFirst(frontendEnv, serverEnv, 'VITE_MPL_SOURCE_URL', 'MPL_SOURCE_URL'),
actual: manifest.corresponding_source_url,
},
{
label: 'Live release manifest open-source repo URL',
expected: readEnvFirst(frontendEnv, serverEnv, 'VITE_OPEN_SOURCE_REPO_URL', 'OPEN_SOURCE_REPO_URL'),
actual: manifest.open_source_repo_url,
},
{
label: 'Live release manifest operator checkout URL',
expected: readEnvFirst(frontendEnv, serverEnv, 'VITE_PADDLE_CHECKOUT_URL_OPERATOR'),
actual: manifest.commerce?.operator_checkout_url,
},
{
label: 'Live release manifest studio checkout URL',
expected: readEnvFirst(frontendEnv, serverEnv, 'VITE_PADDLE_CHECKOUT_URL_STUDIO'),
actual: manifest.commerce?.studio_checkout_url,
},
{
label: 'Live release manifest operator price string',
expected: readEnvFirst(frontendEnv, serverEnv, 'VITE_PLAN_PRICE_OPERATOR') || 'Launch pricing via Paddle',
actual: manifest.commerce?.plan_price_operator,
},
{
label: 'Live release manifest studio price string',
expected: readEnvFirst(frontendEnv, serverEnv, 'VITE_PLAN_PRICE_STUDIO') || 'Contact for launch readiness',
actual: manifest.commerce?.plan_price_studio,
},
]
for (const expectation of topLevelExpectations) {
if (!compareRuntimeComparableValues(expectation.expected, expectation.actual)) {
pushLiveManifestDriftFailure(failures, expectation.label, expectation.expected, expectation.actual)
}
}
const platforms = Array.isArray(manifest.platforms) ? manifest.platforms : []
const globalVersion = readServerOnly(serverEnv, 'RELEASE_MANIFEST_VERSION')
const globalChannel = readServerOnly(serverEnv, 'RELEASE_MANIFEST_CHANNEL') || 'preview'
for (const definition of RELEASE_MANIFEST_PLATFORM_EXPECTATIONS) {
const platform = platforms.find((entry) => entry?.platform_key === definition.platformKey)
if (!platform) {
failures.push(`Live release manifest is missing the ${definition.label} platform entry.`)
continue
}
const configuredCandidate = resolveEnvCandidate(
frontendEnv,
serverEnv,
definition.legacyFrontendUrlKey,
`${definition.envPrefix}_DOWNLOAD_URL`,
)
const expectedConfigured = Boolean(normalizeTrimmed(configuredCandidate.value))
const platformExpectations = [
{
label: `Live release manifest ${definition.label} configured posture`,
expected: expectedConfigured,
actual: platform.configured === true,
},
{
label: `Live release manifest ${definition.label} release channel`,
expected: readServerOnly(serverEnv, `${definition.envPrefix}_RELEASE_CHANNEL`) || globalChannel,
actual: platform.channel,
},
{
label: `Live release manifest ${definition.label} release version`,
expected: readServerOnly(serverEnv, `${definition.envPrefix}_RELEASE_VERSION`) || globalVersion,
actual: platform.version,
},
{
label: `Live release manifest ${definition.label} release build ID`,
expected: readServerOnly(serverEnv, `${definition.envPrefix}_RELEASE_BUILD_ID`),
actual: platform.build_id,
},
{
label: `Live release manifest ${definition.label} published-at timestamp`,
expected: readServerOnly(serverEnv, `${definition.envPrefix}_RELEASE_PUBLISHED_AT`),
actual: platform.published_at,
},
{
label: `Live release manifest ${definition.label} release file name`,
expected: readServerOnly(serverEnv, `${definition.envPrefix}_RELEASE_FILE_NAME`),
actual: platform.file_name,
},
{
label: `Live release manifest ${definition.label} release file size`,
expected: readOptionalInteger(serverEnv, `${definition.envPrefix}_RELEASE_FILE_SIZE_BYTES`),
actual: platform.file_size_bytes,
},
{
label: `Live release manifest ${definition.label} release checksum`,
expected: readServerOnly(serverEnv, `${definition.envPrefix}_RELEASE_SHA256`),
actual: platform.checksum_sha256,
},
]
for (const expectation of platformExpectations) {
if (!compareRuntimeComparableValues(expectation.expected, expectation.actual)) {
pushLiveManifestDriftFailure(failures, expectation.label, expectation.expected, expectation.actual)
}
}
}
}
function requireAbsoluteUrlCandidate(bucket, label, value) {
if (!requireNonEmpty(bucket, label, value)) {
return null
@ -571,6 +775,13 @@ export function buildRuntimeReadinessReport({
if (liveReleaseManifest.manifest?.viewer?.authenticated !== false || liveReleaseManifest.manifest?.viewer?.canDownload !== false) {
failures.push('Live public release manifest viewer posture is not anonymous/non-downloadable.')
}
appendLiveReleaseManifestDriftChecks({
failures,
frontendEnv,
serverEnv,
liveReleaseManifest,
})
} else if (!liveReleaseManifestAttempted) {
warnings.push('Live release manifest was not checked; public download-lane runtime posture was evaluated from env posture only.')
}

View file

@ -416,6 +416,126 @@ describe('buildRuntimeReadinessReport', () => {
expect(report.failures).toContain('Live website root is missing the first-party HyperTwist shell marker.')
expect(report.failures).toContain('Live website root is missing the expected #root app mount.')
})
it('fails when the live release manifest drifts from the configured launch authority', () => {
const report = buildRuntimeReadinessReport({
frontendEnv: {
VITE_SUPPORT_EMAIL: 'ops@hypertwist.app',
VITE_PUBLIC_DOCS_URL: 'https://docs.hypertwist.app',
VITE_RELEASE_NOTES_URL: 'https://notes.hypertwist.app',
VITE_SUPERTOKENS_API_DOMAIN: 'https://hypertwist.app',
VITE_SUPERTOKENS_WEBSITE_DOMAIN: 'https://hypertwist.app',
VITE_AUTH_API_BASE_URL: 'https://hypertwist.app',
VITE_PADDLE_CHECKOUT_URL_OPERATOR: 'https://buy.paddle.com/operator-live',
VITE_PADDLE_CHECKOUT_URL_STUDIO: 'https://buy.paddle.com/studio-live',
VITE_PLAN_PRICE_OPERATOR: '$19 / month',
VITE_PLAN_PRICE_STUDIO: '$99 / month',
VITE_MPL_SOURCE_URL: 'https://hypertwist.app/open-source/source.zip',
VITE_OPEN_SOURCE_REPO_URL: 'https://git.scriptoriumai.io/scriptoriumadmin/hypertwist',
VITE_WINDOWS_DOWNLOAD_URL: 'https://downloads.hypertwist.app/windows.exe',
},
serverEnv: {
API_DOMAIN: 'https://hypertwist.app',
WEBSITE_DOMAIN: 'https://hypertwist.app',
SUPERTOKENS_CORE_URI: 'https://auth-core.internal',
COOKIE_SECURE: 'true',
PADDLE_WEBHOOK_SECRET: 'secret',
PADDLE_PRICE_PLAN_MAP: '{"pri_operator":"operator"}',
RELEASE_MANIFEST_VERSION: '1.0.0',
RELEASE_MANIFEST_CHANNEL: 'candidate',
WINDOWS_RELEASE_BUILD_ID: 'win64-1000',
WINDOWS_RELEASE_SHA256: 'abc123',
WINDOWS_RELEASE_FILE_SIZE_BYTES: '1048576',
},
liveHealth: {
supertokens: { ready: true },
fallback: { active: false },
runtime: {
public_origin_ready: true,
mode: 'public',
errors: [],
warnings: [],
},
billing: {
webhookSecretConfigured: true,
productPlanMapConfigured: false,
pricePlanMapConfigured: true,
},
},
liveReleaseManifest: {
ok: true,
manifest: {
support_email: 'hello@hypertwist.app',
public_docs_url: 'https://old-docs.hypertwist.app',
release_notes_url: 'https://notes.hypertwist.app',
corresponding_source_url: 'https://hypertwist.app/open-source/source.zip',
open_source_repo_url: 'https://git.scriptoriumai.io/scriptoriumadmin/hypertwist',
commerce: {
operator_checkout_url: 'https://buy.paddle.com/operator-old',
studio_checkout_url: 'https://buy.paddle.com/studio-live',
plan_price_operator: '$29 / month',
plan_price_studio: '$99 / month',
},
viewer: {
authenticated: false,
canDownload: false,
},
platforms: [
{
platform_key: 'windows',
configured: false,
channel: 'preview',
version: '0.9.0',
build_id: 'old-build',
published_at: null,
file_name: null,
file_size_bytes: 512,
checksum_sha256: 'stale',
download_url: null,
},
{
platform_key: 'macos',
configured: false,
channel: 'preview',
version: null,
build_id: null,
published_at: null,
file_name: null,
file_size_bytes: null,
checksum_sha256: null,
download_url: null,
},
{
platform_key: 'linux',
configured: false,
channel: 'preview',
version: null,
build_id: null,
published_at: null,
file_name: null,
file_size_bytes: null,
checksum_sha256: null,
download_url: null,
},
],
},
},
liveReleaseManifestAttempted: true,
liveHealthAttempted: true,
})
expect(report.ok).toBe(false)
expect(report.failures).toContain('Live release manifest support email drifted from configured launch authority (expected ops@hypertwist.app, got hello@hypertwist.app).')
expect(report.failures).toContain('Live release manifest public docs URL drifted from configured launch authority (expected https://docs.hypertwist.app, got https://old-docs.hypertwist.app).')
expect(report.failures).toContain('Live release manifest operator checkout URL drifted from configured launch authority (expected https://buy.paddle.com/operator-live, got https://buy.paddle.com/operator-old).')
expect(report.failures).toContain('Live release manifest operator price string drifted from configured launch authority (expected $19 / month, got $29 / month).')
expect(report.failures).toContain('Live release manifest Windows configured posture drifted from configured launch authority (expected true, got false).')
expect(report.failures).toContain('Live release manifest Windows release channel drifted from configured launch authority (expected candidate, got preview).')
expect(report.failures).toContain('Live release manifest Windows release version drifted from configured launch authority (expected 1.0.0, got 0.9.0).')
expect(report.failures).toContain('Live release manifest Windows release build ID drifted from configured launch authority (expected win64-1000, got old-build).')
expect(report.failures).toContain('Live release manifest Windows release file size drifted from configured launch authority (expected 1048576, got 512).')
expect(report.failures).toContain('Live release manifest Windows release checksum drifted from configured launch authority (expected abc123, got stale).')
})
})
describe('deriveHealthBaseUrl', () => {

View file

@ -178,6 +178,12 @@ That means the verifier can now fail explicitly when `hypertwist.app` is still
serving the earlier placeholder rollout page instead of the real same-origin
website/auth-server deployment.
The same verifier now also compares the live anonymous release-manifest payload
against the currently configured launch authority for support/docs/source,
checkout/price, and per-platform release metadata, so a stale host env or
partially rolled deploy fails as configuration drift instead of passing on
structural safety alone.
Live same-origin status on `2026-06-22`:
- the root-owned cutover now has `https://hypertwist.app` serving the