Files

153 lines
5.8 KiB
PowerShell
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<#
.SYNOPSIS
Verify that a code-review report carries an anti-fake spot-check (fail-closed).
.DESCRIPTION
Enforces the "three-piece suite" item 3 (anti-fake spot check) defined in
project-review/SKILL.md Step 8.8: whole-project / feature review reports
MUST contain a "防伪抽验" field in their coverage section, and it must NOT
be "未执行" (i.e. the main agent must have sampled re-read semantic units
from the sub-agent batches). A missing field means the review never ran
the anti-fake spot check and the report would otherwise look green with no
anti-fake guarantee.
Scope handling: only whole-project and feature reviews are gated (they use
the sub-agent deep-read pipeline); change-level reviews skip.
Exit codes: 0 = spot check present and non-zero; 1 = blocking violation
(missing spot check or reported as 未执行 / zero units).
.PARAMETER Repo
Repository root. Defaults to the current directory.
.PARAMETER Report
Optional relative path (under docs/reviews/) to a specific report file.
Defaults to the newest *.md report in docs/reviews/.
.EXAMPLE
powershell -File verify-spot-check.ps1 -Repo D:\AuraSpace
powershell -File verify-spot-check.ps1 -Repo D:\AuraSpace -Report full-project-review-2026-08-18-144500.md
#>
param(
[string]$Repo = "",
[string]$Report = ""
)
$ErrorActionPreference = "Stop"
function Write-Step([string]$msg) { Write-Host " $msg" -ForegroundColor DarkGray }
function Write-Ok([string]$msg) { Write-Host " [OK] $msg" -ForegroundColor Green }
function Write-Bad([string]$msg) { Write-Host " [!!] $msg" -ForegroundColor Red }
function Write-Warn([string]$msg) { Write-Host " [!] $msg" -ForegroundColor Yellow }
# Resolve repo root ---------------------------------------------------------
if ([string]::IsNullOrWhiteSpace($Repo)) { $Repo = (Get-Location).Path }
$root = (Resolve-Path -LiteralPath $Repo).Path
$reviewsDir = Join-Path $root "docs\reviews"
Write-Host "verify-spot-check: repo = $root"
Write-Host ""
# Locate the report --------------------------------------------------------
$reportPath = ""
if (-not [string]::IsNullOrWhiteSpace($Report)) {
$reportPath = Join-Path $reviewsDir $Report
if (-not (Test-Path -LiteralPath $reportPath)) {
Write-Bad "report not found: $reportPath"
exit 1
}
} else {
if (-not (Test-Path -LiteralPath $reviewsDir)) {
Write-Warn "docs/reviews/ does not exist - no report to verify"
Write-Host "RESULT: PASS (no report)" -ForegroundColor Green
exit 0
}
$reportPath = Get-ChildItem -LiteralPath $reviewsDir -File |
Where-Object { $_.Extension -eq ".md" } |
Sort-Object LastWriteTime -Descending |
Select-Object -First 1 -ExpandProperty FullName
if (-not $reportPath) {
Write-Warn "no .md report in docs/reviews/ - nothing to verify"
Write-Host "RESULT: PASS (no report)" -ForegroundColor Green
exit 0
}
}
Write-Step "checking report: $reportPath"
# Parse scope from header (line like: 档位:standard · 范围:whole-project · 基线:...)
$content = [System.IO.File]::ReadAllText($reportPath, [System.Text.Encoding]::UTF8)
$scope = ""
$scopeLine = ($content -split "`n" | Where-Object { $_ -match "范围" } | Select-Object -First 1)
if ($scopeLine -and $scopeLine -match "范围\**[:]\s*([^\s·*]+)") {
$scope = $Matches[1].Trim()
}
# Scope gate: only change-level reviews are skipped. whole-project / feature
# AND any custom scope value (e.g. scope="evm") that still produced a coverage
# section must be checked for the anti-fake spot check.
if ($scope -eq "change-level") {
Write-Warn "scope = '$scope' is not gated on anti-fake spot check (change-level only)"
Write-Host "RESULT: PASS (scope not gated)" -ForegroundColor Green
exit 0
}
Write-Step "scope = '$scope' (gated)"
# Parse ## 覆盖度 section
$covSection = ""
$lines = $content -split "`r?`n"
for ($i = 0; $i -lt $lines.Count; $i++) {
if ($lines[$i] -match "^##\s*\**覆盖度\**") {
$j = $i + 1
$buf = @()
while ($j -lt $lines.Count -and -not ($lines[$j] -match "^##\s")) {
$buf += $lines[$j]; $j++
}
$covSection = $buf -join "`n"
break
}
}
if (-not $covSection) {
Write-Bad "no coverage section found - anti-fake spot check cannot be verified"
exit 1
}
# Anti-fake spot check field present?
$spotLine = ($covSection -split "`n" | Where-Object { $_ -match "防伪抽验" } | Select-Object -First 1)
if (-not $spotLine) {
Write-Bad "coverage section has NO anti-fake spot-check field - Step 5.5 spot check was not run (or spot_check not passed to generate_report_tool)"
Write-Step "coverage section:"
foreach ($l in ($covSection -split "`n" | Where-Object { $_.Trim() })) { Write-Step " $($l.Trim())" }
exit 1
}
# "未执行" marker means spot check never ran
if ($spotLine -match "未执行") {
Write-Bad "anti-fake spot check = NOT RUN (no semantic-unit re-read sampled)"
Write-Step $spotLine.Trim()
exit 1
}
# Present and non-zero: extract sampled counts (防伪抽验:抽样 X 文件 / Y 单元 / Z 组,假读 N ✅)
if ($spotLine -match "抽样\s*(\d+)\s*文件\s*/\s*(\d+)\s*单元") {
$filesSampled = [int]$Matches[1]
$unitsSampled = [int]$Matches[2]
if ($unitsSampled -le 0) {
Write-Bad "anti-fake spot check reported but 0 units sampled"
Write-Step $spotLine.Trim()
exit 1
}
Write-Ok "anti-fake spot check = $filesSampled files / $unitsSampled units sampled"
if ($spotLine -match "假读\s*(\d+)") {
$fake = [int]$Matches[1]
if ($fake -gt 0) {
Write-Warn "fake reads detected: $fake - confirm affected groups were re-read"
}
}
Write-Host "RESULT: PASS - anti-fake spot check verified" -ForegroundColor Green
exit 0
}
Write-Bad "unable to parse anti-fake spot-check counts from: $($spotLine.Trim())"
exit 1