Close scratch iteration 008 and enforce full surface audits

This commit is contained in:
master
2026-03-13 11:00:12 +02:00
parent fe35801cc5
commit c9a30331ce
11 changed files with 534 additions and 32 deletions

View File

@@ -19,6 +19,54 @@ $webRoot = Join-Path $repoRoot 'src/Web/StellaOps.Web'
$sprintRoot = Join-Path $repoRoot 'docs/implplan'
$outputRoot = Join-Path $webRoot 'output'
function New-LogCapturePath {
param(
[Parameter(Mandatory = $true)]
[string]$Suffix
)
return Join-Path ([System.IO.Path]::GetTempPath()) ("stellaops-{0}{1}" -f ([System.Guid]::NewGuid().ToString('N')), $Suffix)
}
function Write-LogCaptureDelta {
param(
[Parameter(Mandatory = $true)]
[string]$Path,
[Parameter(Mandatory = $true)]
[ref]$LineIndex
)
if (-not (Test-Path $Path)) {
return
}
$lines = @(Get-Content $Path -ErrorAction SilentlyContinue)
if ($lines.Count -le $LineIndex.Value) {
return
}
for ($i = $LineIndex.Value; $i -lt $lines.Count; $i++) {
$lines[$i] | Out-Host
}
$LineIndex.Value = $lines.Count
}
function Format-ProcessArgument {
param(
[Parameter(Mandatory = $true)]
[AllowEmptyString()]
[string]$Value
)
if ($Value -notmatch '[\s"]') {
return $Value
}
return '"' + ($Value -replace '(\\*)"', '$1$1\"' -replace '(\\+)$', '$1$1') + '"'
}
function Invoke-External {
param(
[Parameter(Mandatory = $true)]
@@ -30,25 +78,57 @@ function Invoke-External {
)
Push-Location $WorkingDirectory
$stdoutPath = New-LogCapturePath -Suffix '.stdout.log'
$stderrPath = New-LogCapturePath -Suffix '.stderr.log'
try {
$resolvedFilePath = $FilePath
if (Test-Path $FilePath) {
$resolvedFilePath = (Resolve-Path $FilePath).Path
}
$startFilePath = $resolvedFilePath
$startArgumentList = @($ArgumentList)
if ([System.IO.Path]::GetExtension($resolvedFilePath).Equals('.ps1', [System.StringComparison]::OrdinalIgnoreCase)) {
$powershellPath = (Get-Command powershell.exe -ErrorAction Stop).Source
& $powershellPath -NoLogo -NoProfile -ExecutionPolicy Bypass -File $resolvedFilePath @ArgumentList 2>&1 | Out-Host
}
else {
& $resolvedFilePath @ArgumentList 2>&1 | Out-Host
$startFilePath = $powershellPath
$startArgumentList = @('-NoLogo', '-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', $resolvedFilePath) + @($ArgumentList)
}
if ($LASTEXITCODE -ne 0) {
$formattedArgumentList = @($startArgumentList | ForEach-Object { Format-ProcessArgument -Value $_ })
$process = Start-Process `
-FilePath $startFilePath `
-ArgumentList $formattedArgumentList `
-WorkingDirectory $WorkingDirectory `
-RedirectStandardOutput $stdoutPath `
-RedirectStandardError $stderrPath `
-PassThru
$stdoutIndex = 0
$stderrIndex = 0
while (-not $process.HasExited) {
Write-LogCaptureDelta -Path $stdoutPath -LineIndex ([ref]$stdoutIndex)
Write-LogCaptureDelta -Path $stderrPath -LineIndex ([ref]$stderrIndex)
Start-Sleep -Milliseconds 500
$process.Refresh()
}
Write-LogCaptureDelta -Path $stdoutPath -LineIndex ([ref]$stdoutIndex)
Write-LogCaptureDelta -Path $stderrPath -LineIndex ([ref]$stderrIndex)
if ($process.ExitCode -ne 0) {
throw "Command failed: $resolvedFilePath $($ArgumentList -join ' ')"
}
}
finally {
foreach ($capturePath in @($stdoutPath, $stderrPath)) {
if (Test-Path $capturePath) {
Remove-Item $capturePath -Force -ErrorAction SilentlyContinue
}
}
Pop-Location
}
}
@@ -198,10 +278,11 @@ function Render-SprintFile {
$null = $lines.Add('')
$null = $lines.Add('## Topic & Scope')
$null = $lines.Add('- Wipe Stella-owned runtime state again and rerun the documented setup path from zero state.')
$null = $lines.Add('- Re-enter the application as a first-time user after bootstrap and rerun the full route, page, and page-action audit with Playwright.')
$null = $lines.Add('- Re-enter the application as a first-time user after bootstrap and rerun the full route, page-load, and page-action audit with Playwright.')
$null = $lines.Add('- Recheck changed or newly discovered surfaces and convert any new manual findings into retained Playwright scenarios before the iteration is considered complete.')
$null = $lines.Add('- Group any newly exposed defects before fixing so the next commit closes a full iteration rather than a single page slice.')
$null = $lines.Add('- Working directory: `.`.')
$null = $lines.Add('- Expected evidence: wipe proof, setup convergence proof, fresh Playwright route/action evidence, grouped defect list, fixes, and retest results.')
$null = $lines.Add('- Expected evidence: wipe proof, setup convergence proof, fresh Playwright route/page/action evidence, retained scenario coverage for new findings, grouped defect list, fixes, and retest results.')
$null = $lines.Add('')
$null = $lines.Add('## Dependencies & Concurrency')
$null = $lines.Add("- Depends on local commit ``$($State.BaselineCommit)`` as the clean baseline for the next scratch cycle.")
@@ -232,23 +313,23 @@ function Render-SprintFile {
$null = $lines.Add("Dependency: PLATFORM-SCRATCH-ITER$($State.Iteration)-001")
$null = $lines.Add('Owners: QA')
$null = $lines.Add('Task description:')
$null = $lines.Add('- After scratch setup converges, rerun the canonical route sweep plus the full action audit suite and enumerate every newly exposed issue before repair work begins.')
$null = $lines.Add('- After scratch setup converges, rerun the canonical route sweep plus the full route/page/action audit suite, including changed-surface and route-ownership checks, and enumerate every newly exposed issue before repair work begins.')
$null = $lines.Add('')
$null = $lines.Add('Completion criteria:')
$null = $lines.Add("- [$(Get-CheckboxMark -Value $State.Criteria21)] Fresh route sweep evidence is captured on the rebuilt stack.")
$null = $lines.Add("- [$(Get-CheckboxMark -Value $State.Criteria22)] Fresh action sweep evidence is captured across the current aggregate suite.")
$null = $lines.Add("- [$(Get-CheckboxMark -Value $State.Criteria23)] Newly exposed defects are grouped before any fix commit is prepared.")
$null = $lines.Add("- [$(Get-CheckboxMark -Value $State.Criteria22)] Fresh route/page/action evidence is captured across the full aggregate suite, including changed-surface and ownership checks.")
$null = $lines.Add("- [$(Get-CheckboxMark -Value $State.Criteria23)] Newly exposed defects are grouped and any new manual findings are queued into retained Playwright scenarios before any fix commit is prepared.")
$null = $lines.Add('')
$null = $lines.Add("### PLATFORM-SCRATCH-ITER$($State.Iteration)-003 - Repair the grouped defects exposed by the fresh audit")
$null = $lines.Add("Status: $($State.Status3)")
$null = $lines.Add("Dependency: PLATFORM-SCRATCH-ITER$($State.Iteration)-002")
$null = $lines.Add('Owners: 3rd line support, Architect, Developer')
$null = $lines.Add('Task description:')
$null = $lines.Add('- Diagnose the grouped failures exposed by the fresh audit, choose the clean product/architecture-conformant fix, implement it, and rerun the affected verification slices plus the aggregate audit before committing.')
$null = $lines.Add('- Diagnose the grouped failures exposed by the fresh audit, choose the clean product/architecture-conformant fix, implement it, add retained Playwright coverage for the new behavior when needed, and rerun the affected verification slices plus the aggregate audit before committing.')
$null = $lines.Add('')
$null = $lines.Add('Completion criteria:')
$null = $lines.Add("- [$(Get-CheckboxMark -Value $State.Criteria31)] Root causes are recorded for the grouped failures.")
$null = $lines.Add("- [$(Get-CheckboxMark -Value $State.Criteria32)] Fixes land with focused regression coverage where practical.")
$null = $lines.Add("- [$(Get-CheckboxMark -Value $State.Criteria32)] Fixes land with focused regression coverage and retained Playwright scenario updates where practical.")
$null = $lines.Add("- [$(Get-CheckboxMark -Value $State.Criteria33)] The rebuilt stack is retested before the iteration commit.")
$null = $lines.Add('')
$null = $lines.Add('## Execution Log')
@@ -300,18 +381,27 @@ function Remove-PlaywrightOutput {
}
}
function Get-WorktreeChanges {
return @((git status --short --untracked-files=all) | Where-Object { $_ })
}
$batchId = if ($StartingBatchId -gt 0) { $StartingBatchId } else { Get-HighestBatchId -SprintImplId $ImplId }
for ($iteration = $StartIteration; $iteration -le $EndIteration; $iteration++) {
$batchId++
$preExistingWorktreeChanges = Get-WorktreeChanges
$baselineCommit = (git rev-parse --short=9 HEAD).Trim()
$sprintPath = Join-Path $sprintRoot ("SPRINT_{0}_{1:D3}_Platform_scratch_iteration_{2:D3}_full_route_action_audit.md" -f $ImplId, $batchId, $iteration)
$state = New-SprintState -Iteration $iteration -BatchId $batchId -BaselineCommit $baselineCommit
$state.Decisions.Add('Decision: each scratch iteration remains a full wipe -> setup -> route/action audit -> grouped remediation loop; if the audit comes back clean, that still counts as a completed iteration because the full loop was executed.')
$state.Decisions.Add('Decision: each scratch iteration remains a full wipe -> setup -> route/page/action audit -> grouped remediation loop; if the audit comes back clean, that still counts as a completed iteration because the full loop was executed.')
$state.Decisions.Add('Decision: changed or newly discovered user flows must be converted into retained Playwright coverage before the next scratch iteration starts so the audit surface expands instead of rediscovering the same gaps manually.')
$state.Decisions.Add('Risk: scratch rebuilds remain expensive, so verification stays Playwright-first with focused test/build slices rather than indiscriminate full-solution test runs.')
$state.NextCheckpoints.Add('Finish the Stella-only wipe and capture the next zero-state setup outcome.')
$state.NextCheckpoints.Add('Run the full Playwright audit on the rebuilt stack before diagnosing any new fixes.')
$state.NextCheckpoints.Add('Run the full Playwright route/page/action audit, including changed-surface and ownership checks, on the rebuilt stack before diagnosing any new fixes.')
Add-SprintLog -State $state -Update "Sprint created for the next scratch iteration after local commit ``$baselineCommit`` closed the previous clean baseline." -Owner 'QA'
if ($preExistingWorktreeChanges.Count -gt 0) {
Add-SprintLog -State $state -Update "Detected ``$($preExistingWorktreeChanges.Count)`` pre-existing worktree change(s) before the iteration started. Automatic sprint-only commit will be skipped so the final commit can stay grouped with the active fixes." -Owner 'QA / Developer'
}
Write-SprintState -State $state -Path $sprintPath
Remove-StellaRuntime
@@ -351,7 +441,7 @@ for ($iteration = $StartIteration; $iteration -le $EndIteration; $iteration++) {
$auditOk = ($passedSuites -eq [int]$auditReport.suiteCount) -and ($failedSuites -eq 0) -and ([int]$auditReport.retriedSuiteCount -eq 0) -and ([int]$auditReport.stabilizedAfterRetryCount -eq 0)
$state.Criteria22 = $true
$state.Criteria23 = $true
Add-SprintLog -State $state -Update "The aggregate audit finished with ``$passedSuites/$($auditReport.suiteCount)`` suites passed, ``$failedSuites`` failed suites, ``$($auditReport.retriedSuiteCount)`` retried suites, and ``$($auditReport.stabilizedAfterRetryCount)`` stabilized-after-retry suites." -Owner 'QA'
Add-SprintLog -State $state -Update "The aggregate audit finished with ``$passedSuites/$($auditReport.suiteCount)`` suites passed, ``$failedSuites`` failed suites, ``$($auditReport.retriedSuiteCount)`` retried suites, and ``$($auditReport.stabilizedAfterRetryCount)`` stabilized-after-retry suites across the retained route/page/action coverage set." -Owner 'QA'
if (-not $auditOk) {
$state.Status2 = 'DONE'
$state.Status3 = 'DOING'
@@ -372,13 +462,19 @@ for ($iteration = $StartIteration; $iteration -le $EndIteration; $iteration++) {
$state.Criteria31 = $true
$state.Criteria32 = $true
$state.Criteria33 = $true
Add-SprintLog -State $state -Update 'No stable product defects surfaced on the rebuilt stack. The route/page/action audit completed cleanly without retries, so the iteration closes as a fully verified clean scratch pass.' -Owner 'QA / Architect / Developer'
Add-SprintLog -State $state -Update 'No stable product defects surfaced on the rebuilt stack. The retained route/page/action audit completed cleanly without retries, so the iteration closes as a fully verified clean scratch pass.' -Owner 'QA / Architect / Developer'
$state.NextCheckpoints.Clear()
$state.NextCheckpoints.Add('Start the next scratch iteration from another Stella-only wipe and documented setup rerun.')
$state.NextCheckpoints.Add('Repeat the full Playwright route/page/action audit on the next rebuilt stack before considering any new fixes.')
$state.NextCheckpoints.Add('Repeat the full Playwright route/page/action audit, including changed-surface and retained-scenario coverage, on the next rebuilt stack before considering any new fixes.')
Write-SprintState -State $state -Path $sprintPath
Remove-PlaywrightOutput
if ($preExistingWorktreeChanges.Count -gt 0) {
Add-SprintLog -State $state -Update 'Skipped the automatic sprint-only commit because the worktree was already dirty before this scratch iteration began. Manual grouped commit is required.' -Owner 'QA / Developer'
Write-SprintState -State $state -Path $sprintPath
continue
}
Invoke-External -FilePath 'git' -ArgumentList @('add', '--', $sprintPath) -WorkingDirectory $repoRoot
Invoke-External -FilePath 'git' -ArgumentList @('commit', '-m', ("Record clean scratch setup iteration {0:D3}" -f $iteration)) -WorkingDirectory $repoRoot
}