$ErrorActionPreference = 'Stop' $decode = { param([string]$value) [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($value)) } $root = (Resolve-Path '.').Path $requiredPaths = @( (& $decode 'ZG9jcy9kZXNpZ24='), (& $decode 'ZG9jcy9kZXNpZ24v6KeG6KeJ6K6+6K6h5Lqk5o6l5omL5YaMLm1k'), (& $decode 'ZG9jcy9kZXNpZ24v6KeG6KeJ6K+B5o2u57Si5byVLm1k'), (& $decode 'ZG9jcy9kZXNpZ24vRDFf5a6J5Y2T6KeG6KeJ6KeE6IyD5LiO6aG16Z2i5aOzLm1k'), (& $decode 'ZG9jcy9kZXNpZ24vUDAwX+mhtemdoue7k+aehOS4jui1hOS6p+a4heWNlS5tZA==') ) foreach ($path in $requiredPaths) { if (-not (Test-Path $path)) { throw "required handoff path missing: $path" } } if (-not (Test-Path '.gitignore')) { throw '.gitignore is required' } $ignore = Get-Content -Raw -Encoding UTF8 '.gitignore' foreach ($pattern in @('/tmp/', '/unpackage/', '/docs/superpowers/specs/design/', '/tmp-g01-icon-audit.png')) { if (-not $ignore.Contains($pattern)) { throw "missing ignore pattern: $pattern" } } if (Test-Path 'docs/superpowers/specs/design') { throw 'misplaced design archive remains inside repository' } $screens = Get-ChildItem 'docs/design/screens' -File -Recurse $screenBytes = ($screens | Measure-Object Length -Sum).Sum if ($screens.Count -gt 35) { throw "too many handoff screenshots: $($screens.Count)" } if ($screenBytes -gt 20MB) { throw "handoff screenshots exceed 20MB: $([math]::Round($screenBytes / 1MB, 2))MB" } $indexPath = (& $decode 'ZG9jcy9kZXNpZ24v6KeG6KeJ6K+B5o2u57Si5byVLm1k') $index = Get-Content -Raw -Encoding UTF8 $indexPath $links = [regex]::Matches($index, '\[[^\]]+\]\(([^)]+)\)') foreach ($link in $links) { $target = Join-Path (Split-Path $indexPath) $link.Groups[1].Value if (-not (Test-Path $target)) { throw "broken evidence link: $($link.Groups[1].Value)" } } Write-Output "REPOSITORY-HANDOFF-SIZE-CONTRACT PASS files=$($screens.Count) mb=$([math]::Round($screenBytes / 1MB, 2)) links=$($links.Count)"