From d6da8f82c880d7974febb646ffabbb62e9baa089 Mon Sep 17 00:00:00 2001 From: Shirofune-Security <43838376+Shirofune-Security@users.noreply.github.com> Date: Sat, 19 Sep 2026 07:25:44 +0900 Subject: [PATCH] Retain recorded eligibility evidence scope in HTML reports --- modules/RuleEligibility.psm1 | 10 ++++++++-- tests/RuleEligibility.Tests.ps1 | 10 ++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/modules/RuleEligibility.psm1 b/modules/RuleEligibility.psm1 index cb2d42fe..5efc018d 100644 --- a/modules/RuleEligibility.psm1 +++ b/modules/RuleEligibility.psm1 @@ -386,8 +386,14 @@ function Export-WelaRuleEligibility { $encode = { param($value) [Net.WebUtility]::HtmlEncode([string]$value) } $html = New-Object Text.StringBuilder [void]$html.Append('WELA native rule eligibility

Native rule eligibility

') - [void]$html.Append('

' + (& $encode $Report.AssessmentBasis) + '

' + (& $encode ($Report.Summary | ConvertTo-Json -Depth 6)) + '

Corpus SHA256: ' + (& $encode $Report.Corpus.Sha256) + '

') - foreach ($row in $Report.Results) { [void]$html.Append('') } + [void]$html.Append('

' + (& $encode $Report.AssessmentBasis) + '

' + (& $encode ($Report.Summary | ConvertTo-Json -Depth 6)) + '

Requested context

' + (& $encode ($Report.RequestedContext | ConvertTo-Json -Depth 6)) + '

Corpus SHA256: ' + (& $encode $Report.Corpus.Sha256) + '

RuleStateReasons
' + (& $encode ($row.Title + ' [' + $row.Id + ']')) + '' + (& $encode $row.State) + '' + (& $encode ((@($row.Reasons) + @($row.ScopeExclusion)) -join '; ')) + '
') + foreach ($row in $Report.Results) { + [void]$html.Append('') + } [void]$html.Append('
RuleStateReasons and recorded evidence scope
' + (& $encode ($row.Title + ' [' + $row.Id + ']')) + '' + (& $encode $row.State) + '' + (& $encode ((@($row.Reasons) + @($row.ScopeExclusion)) -join '; '))) + if ($row.State -eq 'Ready') { + [void]$html.Append('

Evidence as of UTC: ' + (& $encode $row.EvidenceAsOfUtc) + '

Recorded context (not the current host):

' + (& $encode ($row.EvidenceContext | ConvertTo-Json -Depth 6)) + '
') + } + [void]$html.Append('
') $html.ToString() | Set-Content -LiteralPath $HtmlPath -Encoding UTF8 -ErrorAction Stop } diff --git a/tests/RuleEligibility.Tests.ps1 b/tests/RuleEligibility.Tests.ps1 index b86136df..0fdfd648 100644 --- a/tests/RuleEligibility.Tests.ps1 +++ b/tests/RuleEligibility.Tests.ps1 @@ -87,6 +87,16 @@ try { Reset-Evidence;$r=Report -Evidence Assert ($r.Summary.Ready -eq 1 -and $r.Results[0].State -eq 'Ready') ('Coherent complete synthetic evidence demonstrates the importer gates: '+($r.Results[0].Reasons -join '; ')) Assert ($r.Results[0].EvidenceContext.computer -eq 'lab.example.test' -and $r.AssessmentBasis -like '*not a current-host*') 'Imported Ready states retain their recorded host/time and explicit limitations.' + $evidenceHtml=Join-Path $root 'evidence.html' + Export-WelaRuleEligibility -Report $r -HtmlPath $evidenceHtml + $exported=[IO.File]::ReadAllText($evidenceHtml) + foreach ($required in @('Requested context','lab.example.test','Client','26100','fixture-1','domainJoined','installedRoles','fixture-backend','backendVersion','2026-09-19T10:04:00Z')) { + Assert ($exported.Contains($required)) "Shared HTML must retain evidence scope: $required" + } + $r.Results[0].EvidenceContext.computer='' + Export-WelaRuleEligibility -Report $r -HtmlPath $evidenceHtml + $exported=[IO.File]::ReadAllText($evidenceHtml) + Assert (-not $exported.Contains('