Revert evaluation harness change for multiple articles per domain

The harness intentionally evaluates one paired article per domain. Keep it
as designed; how the retention pairs join privacy evaluation is left to the
maintainers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jeremy Vyska 2026-09-30 15:49:13 +02:00
parent 07a171386d
commit f9333addcd
3 changed files with 15 additions and 44 deletions

View file

@ -2,7 +2,7 @@
The evaluation is convention-driven. The harness discovers every `<layer>/skills/review/al-<domain>-review.md` leaf across the enabled `microsoft`, `community`, and `custom` layers. Duplicate domains resolve with `custom > community > microsoft` precedence. For each selected leaf, the harness finds paired knowledge across the same layers, applies the same precedence to duplicate article slugs, selects the first article (by filename) with both `.bad.al` and `.good.al` companions, and derives the expected positive and clean control automatically. Adding a conforming leaf requires no scoring-contract edit. The evaluation is convention-driven. The harness discovers every `<layer>/skills/review/al-<domain>-review.md` leaf across the enabled `microsoft`, `community`, and `custom` layers. Duplicate domains resolve with `custom > community > microsoft` precedence. For each selected leaf, the harness finds paired knowledge across the same layers, applies the same precedence to duplicate article slugs, selects the first article (by filename) with both `.bad.al` and `.good.al` companions, and derives the expected positive and clean control automatically. Adding a conforming leaf requires no scoring-contract edit.
`review-fixtures.json` contains only global thresholds and optional exceptional overrides. An override may select a different article, add context, or list `additionalArticles` whose sample pairs become extra positive and clean cases for that domain, when the generic convention cannot express a scenario. It should remain empty in the normal case. `review-fixtures.json` contains only global thresholds and optional exceptional overrides. An override may select a different article or add context when the generic convention cannot express a scenario. It should remain empty in the normal case.
Model-facing preparation hashes case IDs, neutralizes `Good`/`Bad` object-name tokens, and removes full-line sample comments so neither the article slug, domain, nor expected outcome reveals the answer. Model-facing preparation hashes case IDs, neutralizes `Good`/`Bad` object-name tokens, and removes full-line sample comments so neither the article slug, domain, nor expected outcome reveals the answer.

View file

@ -23,11 +23,7 @@
"article": "use-isempty-for-existence-check" "article": "use-isempty-for-existence-check"
}, },
"privacy": { "privacy": {
"article": "no-pii-in-telemetry-message-string", "article": "no-pii-in-telemetry-message-string"
"additionalArticles": [
"register-owned-log-tables-for-retention-policies",
"ship-a-default-retention-policy-setup"
]
}, },
"style": { "style": {
"article": "label-comment-explains-placeholders" "article": "label-comment-explains-placeholders"

View file

@ -4,7 +4,7 @@
.DESCRIPTION .DESCRIPTION
CI uses the static validation path to prove every registered AL review leaf CI uses the static validation path to prove every registered AL review leaf
has at least one positive and one clean control, every fixture/reference exists, and has one positive and one clean control, every fixture/reference exists, and
the manifest remains internally consistent. the manifest remains internally consistent.
For an actual model run, -PrepareDirectory copies inputs to neutral names and For an actual model run, -PrepareDirectory copies inputs to neutral names and
@ -226,49 +226,24 @@ foreach ($domain in $leafDomains) {
continue continue
} }
# The primary article keeps the domain-level case IDs; additionalArticles add $articlePath = [string]$selectedArticle.ArticlePath
# further paired cases keyed by slug so existing case hashes stay stable. $sampleDirectory = (Split-Path -Parent $articlePath).Replace('\', '/')
$selections = [System.Collections.Generic.List[object]]::new()
$selections.Add([pscustomobject]@{ Article = $selectedArticle; IdPrefix = $domain }) | Out-Null
if ($override -and ($override.PSObject.Properties.Name -contains 'additionalArticles')) {
foreach ($additionalName in @($override.additionalArticles)) {
$additionalName = [string]$additionalName
if ($additionalName.EndsWith('.md')) {
$additionalName = [System.IO.Path]::GetFileNameWithoutExtension($additionalName)
}
if (@($selections | Where-Object { $_.Article.BaseName -eq $additionalName }).Count) {
$problems.Add("${domain}: additional article is already selected: $additionalName.md") | Out-Null
continue
}
$additionalArticle = $articles | Where-Object BaseName -eq $additionalName | Select-Object -First 1
if (-not $additionalArticle) {
$problems.Add("${domain}: additional article does not exist or lacks .good.al and .bad.al companion samples: $additionalName.md") | Out-Null
continue
}
$selections.Add([pscustomobject]@{ Article = $additionalArticle; IdPrefix = "$domain-$additionalName" }) | Out-Null
}
}
$context = if ($override -and ($override.PSObject.Properties.Name -contains 'context')) { $context = if ($override -and ($override.PSObject.Properties.Name -contains 'context')) {
[string]$override.context [string]$override.context
} else { } else {
$null $null
} }
foreach ($selection in $selections) { foreach ($kind in 'bad', 'good') {
$articlePath = [string]$selection.Article.ArticlePath $case = [pscustomobject]@{
$sampleDirectory = (Split-Path -Parent $articlePath).Replace('\', '/') id = "$domain-$kind"
foreach ($kind in 'bad', 'good') { domain = $domain
$case = [pscustomobject]@{ input = "$sampleDirectory/$($selectedArticle.BaseName).$kind.al"
id = "$($selection.IdPrefix)-$kind" expected = if ($kind -eq 'bad') { @($articlePath) } else { @() }
domain = $domain
input = "$sampleDirectory/$($selection.Article.BaseName).$kind.al"
expected = if ($kind -eq 'bad') { @($articlePath) } else { @() }
}
if ($context) {
$case | Add-Member -NotePropertyName context -NotePropertyValue $context
}
$caseList.Add($case) | Out-Null
} }
if ($context) {
$case | Add-Member -NotePropertyName context -NotePropertyValue $context
}
$caseList.Add($case) | Out-Null
} }
} }
$cases = @($caseList) $cases = @($caseList)