@@ -8137,10 +8137,89 @@ Explain in lighterTypesRejected why the previous tier could not observe it. Choo
81378137
81388138 New-TestPatch - Files $generatedFiles
81398139
8140+ # A task timeout kills this process outright, so the guard above -
8141+ # which only survives the fix phase *failing* - cannot help: run 15089945
8142+ # reproduced its issue, verified it, cleared the negative control and
8143+ # picked a winning fix, then timed out before this manifest existed. The
8144+ # publisher then said "No replication candidate manifest was produced;
8145+ # nothing to validate." 7 of the 8 timeouts in the cached corpus had
8146+ # already passed verification, which makes this the most expensive way
8147+ # the pipeline loses work.
8148+ #
8149+ # Writing the manifest once before the fix phase and again after leaves a
8150+ # valid reproduction-only candidate on disk the whole time the fix panel
8151+ # runs. The artifact upload is succeededOrFailed, so it survives, and the
8152+ # manifest already models a fix-less candidate (fixFiles = @()).
8153+ $writeCandidateManifest = {
8154+ param ([bool ]$Announce )
8155+ # Replacing newlines after truncation left a trailing space, and the gate
8156+ # rejects an untrimmed manifest step, so build 15030804 reproduced its issue
8157+ # and was discarded for whitespace. Collapse and trim after the replacement.
8158+ $reproductionSteps = @ ($testProposal.reproductionSteps | ForEach-Object {
8159+ ([regex ]::Replace(
8160+ ((ConvertTo-ReplicationSafeLog $_ 300 ) -replace ' \r|\n' , ' ' ),
8161+ ' \s+' ,
8162+ ' ' )).Trim()
8163+ } | Where-Object { -not [string ]::IsNullOrWhiteSpace($_ ) } | Select-Object - First 10 )
8164+ [ordered ]@ {
8165+ schemaVersion = 1
8166+ issueNumber = $IssueNumber
8167+ platform = $Platform
8168+ baseSha = $BaseSha.ToLowerInvariant ()
8169+ status = ' reproduced'
8170+ blocked = $null
8171+ selectedDevice = [ordered ]@ {
8172+ id = $selectedDeviceId
8173+ name = $DeviceName
8174+ osVersion = $DeviceOSVersion
8175+ }
8176+ attempts = [ordered ]@ {
8177+ sandbox = $sandboxAttempts
8178+ automatedTest = $testAttempts
8179+ }
8180+ reproductionSteps = $reproductionSteps
8181+ expectedBehavior = ConvertTo-ReplicationSafeLog ([string ]$testProposal.expectedBehavior ) 500
8182+ observedBehavior = ConvertTo-ReplicationSafeLog ([string ]$testProposal.observedBehavior ) 500
8183+ testType = [string ]$testProposal.testType
8184+ testFilter = [string ]$testProposal.testFilter
8185+ testClassName = [string ]$verifierMetadata.ClassName
8186+ testMethodName = [string ]$verifierMetadata.MethodName
8187+ expectedFailureSignature = [string ]$testProposal.expectedFailureSignature
8188+ files = $generatedFiles
8189+ sandboxFiles = [ordered ]@ {
8190+ xaml = ' sandbox/MainPage.xaml'
8191+ codeBehind = ' sandbox/MainPage.xaml.cs'
8192+ appiumPlan = ' sandbox/appium-plan.json'
8193+ }
8194+ reproductionResult = ' reproduction-result.json'
8195+ evidenceManifest = ' evidence/evidence.json'
8196+ verificationResult = ' verification/verification-result.json'
8197+ negativeControl = $negativeControl
8198+ patch = ' test.patch'
8199+ fixFiles = if ($fixOutcome ) { @ ($fixOutcome.Files ) } else { @ () }
8200+ fixPatch = if ($fixOutcome ) { ' fix.patch' } else { $null }
8201+ fixRootCause = if ($fixOutcome ) { $fixOutcome.RootCause } else { $null }
8202+ fixApproach = if ($fixOutcome ) { $fixOutcome.Approach } else { $null }
8203+ fixRejectedApproaches = if ($fixOutcome ) { @ ($fixOutcome.RejectedApproaches ) } else { @ () }
8204+ } | ConvertTo-Json - Depth 10 | Set-Content - LiteralPath $candidatePath - Encoding utf8NoBOM
8205+
8206+ if ($Announce ) {
8207+ Write-Host " ISSUE REPLICATION CANDIDATE READY: $candidatePath "
8208+ } else {
8209+ Write-Host " ISSUE REPLICATION CANDIDATE STAGED: $candidatePath "
8210+ }
8211+ }
8212+
8213+
8214+ # Stage the reproduction before the fix phase can time out. This writes the
8215+ # same manifest the run would publish with no fix, so a process killed
8216+ # during the panel leaves exactly what a fix-less run leaves.
8217+ $fixOutcome = $null
8218+ & $writeCandidateManifest $false
8219+
81408220 # The reproduction is certified at this point and its patch is already
81418221 # written, so nothing the fix phase does can reach it. Any failure inside
81428222 # returns $null and publishes the reproduction alone.
8143- $fixOutcome = $null
81448223 if ($negativeControl ) {
81458224 try {
81468225 $fixOutcome = Invoke-ReplicationFixPhase `
@@ -8162,58 +8241,7 @@ Explain in lighterTypesRejected why the previous tier could not observe it. Choo
81628241 Remove-Item - LiteralPath $fixPatchPath - Force - ErrorAction SilentlyContinue
81638242 }
81648243
8165- # Replacing newlines after truncation left a trailing space, and the gate
8166- # rejects an untrimmed manifest step, so build 15030804 reproduced its issue
8167- # and was discarded for whitespace. Collapse and trim after the replacement.
8168- $reproductionSteps = @ ($testProposal.reproductionSteps | ForEach-Object {
8169- ([regex ]::Replace(
8170- ((ConvertTo-ReplicationSafeLog $_ 300 ) -replace ' \r|\n' , ' ' ),
8171- ' \s+' ,
8172- ' ' )).Trim()
8173- } | Where-Object { -not [string ]::IsNullOrWhiteSpace($_ ) } | Select-Object - First 10 )
8174- [ordered ]@ {
8175- schemaVersion = 1
8176- issueNumber = $IssueNumber
8177- platform = $Platform
8178- baseSha = $BaseSha.ToLowerInvariant ()
8179- status = ' reproduced'
8180- blocked = $null
8181- selectedDevice = [ordered ]@ {
8182- id = $selectedDeviceId
8183- name = $DeviceName
8184- osVersion = $DeviceOSVersion
8185- }
8186- attempts = [ordered ]@ {
8187- sandbox = $sandboxAttempts
8188- automatedTest = $testAttempts
8189- }
8190- reproductionSteps = $reproductionSteps
8191- expectedBehavior = ConvertTo-ReplicationSafeLog ([string ]$testProposal.expectedBehavior ) 500
8192- observedBehavior = ConvertTo-ReplicationSafeLog ([string ]$testProposal.observedBehavior ) 500
8193- testType = [string ]$testProposal.testType
8194- testFilter = [string ]$testProposal.testFilter
8195- testClassName = [string ]$verifierMetadata.ClassName
8196- testMethodName = [string ]$verifierMetadata.MethodName
8197- expectedFailureSignature = [string ]$testProposal.expectedFailureSignature
8198- files = $generatedFiles
8199- sandboxFiles = [ordered ]@ {
8200- xaml = ' sandbox/MainPage.xaml'
8201- codeBehind = ' sandbox/MainPage.xaml.cs'
8202- appiumPlan = ' sandbox/appium-plan.json'
8203- }
8204- reproductionResult = ' reproduction-result.json'
8205- evidenceManifest = ' evidence/evidence.json'
8206- verificationResult = ' verification/verification-result.json'
8207- negativeControl = $negativeControl
8208- patch = ' test.patch'
8209- fixFiles = if ($fixOutcome ) { @ ($fixOutcome.Files ) } else { @ () }
8210- fixPatch = if ($fixOutcome ) { ' fix.patch' } else { $null }
8211- fixRootCause = if ($fixOutcome ) { $fixOutcome.RootCause } else { $null }
8212- fixApproach = if ($fixOutcome ) { $fixOutcome.Approach } else { $null }
8213- fixRejectedApproaches = if ($fixOutcome ) { @ ($fixOutcome.RejectedApproaches ) } else { @ () }
8214- } | ConvertTo-Json - Depth 10 | Set-Content - LiteralPath $candidatePath - Encoding utf8NoBOM
8215-
8216- Write-Host " ISSUE REPLICATION CANDIDATE READY: $candidatePath "
8244+ & $writeCandidateManifest $true
82178245}
82188246catch {
82198247 $rawReason = [string ]$_.Exception.Message
0 commit comments