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 eligibilityNative rule eligibility
')
- [void]$html.Append('' + (& $encode $Report.AssessmentBasis) + '
' + (& $encode ($Report.Summary | ConvertTo-Json -Depth 6)) + '
Corpus SHA256: ' + (& $encode $Report.Corpus.Sha256) + '
| Rule | State | Reasons |
')
- foreach ($row in $Report.Results) { [void]$html.Append('| ' + (& $encode ($row.Title + ' [' + $row.Id + ']')) + ' | ' + (& $encode $row.State) + ' | ' + (& $encode ((@($row.Reasons) + @($row.ScopeExclusion)) -join '; ')) + ' |
') }
+ [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) + '
| Rule | State | Reasons and recorded evidence scope |
')
+ foreach ($row in $Report.Results) {
+ [void]$html.Append('| ' + (& $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(' |
')
+ }
[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('