fix(release): make August 1 handoff reproducible

This commit is contained in:
key
2026-07-29 12:25:20 +08:00
parent 6e2b6025c1
commit fee80877de
5 changed files with 161 additions and 11 deletions
+40 -7
View File
@@ -122,12 +122,30 @@ $goNoGoCandidates = @(Get-ChildItem -LiteralPath (Join-Path $projectRoot 'docs')
if ($goNoGoCandidates.Count -ne 1) {
throw "Expected one Android Go/No-Go document, found $($goNoGoCandidates.Count)."
}
$businessSignoffCandidates = @(
Get-ChildItem -LiteralPath (Join-Path $projectRoot 'docs') -File -Filter '*20260729.md' |
Where-Object {
$candidateText = Get-Content -Raw -Encoding UTF8 -LiteralPath $_.FullName
$candidateText.Contains('direct_president') -and
$candidateText.Contains('direct_finance') -and
$candidateText.Contains('direct_hr') -and
$candidateText.Contains('direct_audit') -and
$candidateText.Contains('direct_operations')
}
)
if ($businessSignoffCandidates.Count -ne 1) {
throw "Expected one August 1 business-content and five-channel sign-off document, found $($businessSignoffCandidates.Count)."
}
$businessSignoffPath = $businessSignoffCandidates[0].FullName
$operationSources = [ordered]@{
'operations/release-backend.sh' = Join-Path $projectRoot 'scripts\release-backend.sh'
'operations/release-preflight.sh' = Join-Path $projectRoot 'scripts\release-preflight.sh'
'operations/verify-aug1-production-api-readonly.sh' = Join-Path $projectRoot 'scripts\verify-aug1-production-api-readonly.sh'
'operations/verify-aug1-authenticated-production.sh' = Join-Path $projectRoot 'scripts\verify-aug1-authenticated-production.sh'
'operations/verify-aug1-content-candidates.mjs' = Join-Path $projectRoot 'scripts\verify-aug1-content-candidates.mjs'
'operations/capture-android-acceptance.ps1' = Join-Path $projectRoot 'scripts\capture-android-acceptance.ps1'
'operations/go-no-go.md' = $goNoGoCandidates[0].FullName
'operations/business-content-and-five-channel-signoff.md' = $businessSignoffPath
}
foreach ($source in $operationSources.Values) {
Require-File $source
@@ -147,7 +165,7 @@ Write-Output "apk_sha256=$apkSha256"
Write-Output "backend_sha256=$backendSha256"
Write-Output "content_sha256=$contentSha256"
Write-Output "package_path=$packagePath"
Write-Output 'package_entries=14'
Write-Output 'package_entries=17'
if ($PlanOnly) {
exit 0
}
@@ -207,6 +225,10 @@ try {
'',
'Run the GET-only API probe before and after release, and capture read-only Android evidence after each manual step. Neither replaces Android device acceptance or formal business sign-off.',
'',
'Recheck the bundled disabled content candidates with `node operations/verify-aug1-content-candidates.mjs aug1-life-advisor-content-candidates-v0.1.json`. Complete `operations/business-content-and-five-channel-signoff.md` before enabling content or binding handlers.',
'',
'The fixed-code authenticated smoke is bundled as `operations/verify-aug1-authenticated-production.sh`. It requires the explicit `--execute` flag, selects an existing eligible APP identity without printing it, never enables or sends real SMS, and does not submit business records.',
'',
'This package does not authorize production deployment, service restart, database change, Git push or public distribution.'
) -join [Environment]::NewLine
Write-Utf8 -Path (Join-Path $stagingDirectory 'README.md') -Content ($readme + [Environment]::NewLine)
@@ -238,7 +260,9 @@ try {
'- Formally publishable scenarios: 0',
'- Formally sourced standard answers: 0',
'',
'Candidates are for business review only. Do not import, enable or count them toward August 1 acceptance until formal sources and item-level sign-off are complete.'
'Candidates are for business review only. Do not import, enable or count them toward August 1 acceptance until formal sources and item-level sign-off are complete.',
'',
'Run `node operations/verify-aug1-content-candidates.mjs aug1-life-advisor-content-candidates-v0.1.json` after extraction, then use `operations/business-content-and-five-channel-signoff.md` for item-level review and handler assignment.'
) -join [Environment]::NewLine
Write-Utf8 -Path (Join-Path $stagingDirectory 'content-review-readme.md') -Content ($contentReview + [Environment]::NewLine)
@@ -307,8 +331,8 @@ try {
$allFiles = Get-ChildItem -LiteralPath $stagingDirectory -Recurse -File |
Sort-Object { $_.FullName.Substring($stagingDirectory.Length + 1) }
if ($allFiles.Count -ne 14) {
throw "Release package expected 14 files, found $($allFiles.Count)."
if ($allFiles.Count -ne 17) {
throw "Release package expected 17 files, found $($allFiles.Count)."
}
foreach ($file in $allFiles) {
$file.LastWriteTimeUtc = $entryTimestamp.UtcDateTime
@@ -345,11 +369,20 @@ try {
$verificationArchive = [IO.Compression.ZipFile]::OpenRead($partialPackagePath)
try {
if ($verificationArchive.Entries.Count -ne 14) {
throw "ZIP verification expected 14 entries, found $($verificationArchive.Entries.Count)."
if ($verificationArchive.Entries.Count -ne 17) {
throw "ZIP verification expected 17 entries, found $($verificationArchive.Entries.Count)."
}
$entryNames = @($verificationArchive.Entries | ForEach-Object { $_.FullName })
foreach ($requiredEntry in @($apkName, $backendName, 'release-manifest.json', 'SHA256SUMS.txt', 'operations/release-backend.sh')) {
foreach ($requiredEntry in @(
$apkName,
$backendName,
'release-manifest.json',
'SHA256SUMS.txt',
'operations/release-backend.sh',
'operations/verify-aug1-authenticated-production.sh',
'operations/verify-aug1-content-candidates.mjs',
'operations/business-content-and-five-channel-signoff.md'
)) {
if ($entryNames -notcontains $requiredEntry) {
throw "ZIP verification is missing $requiredEntry"
}