fix(ucca): Cross-Reg 0070 — beide Regelwerk-Domaenen im Router-Top-K (Known Defects 0)
CI / detect-changes (pull_request) Successful in 13s
CI / branch-name (pull_request) Successful in 1s
CI / guardrail-integrity (pull_request) Successful in 9s
CI / secret-scan (pull_request) Successful in 10s
CI / dep-audit (pull_request) Failing after 56s
CI / sbom-scan (pull_request) Failing after 59s
CI / build-sha-integrity (pull_request) Successful in 5s
CI / validate-canonical-controls (pull_request) Successful in 3s
CI / test-python-document-crawler (pull_request) Successful in 15s
CI / test-python-dsms-gateway (pull_request) Successful in 13s
CI / loc-budget (pull_request) Successful in 23s
CI / go-lint (pull_request) Failing after 51s
CI / python-lint (pull_request) Failing after 18s
CI / nodejs-lint (pull_request) Failing after 1m8s
CI / nodejs-build (pull_request) Successful in 3m6s
CI / test-go (pull_request) Successful in 1m3s
CI / iace-gt-coverage (pull_request) Successful in 18s
CI / test-python-backend (pull_request) Successful in 28s
CI / detect-changes (pull_request) Successful in 13s
CI / branch-name (pull_request) Successful in 1s
CI / guardrail-integrity (pull_request) Successful in 9s
CI / secret-scan (pull_request) Successful in 10s
CI / dep-audit (pull_request) Failing after 56s
CI / sbom-scan (pull_request) Failing after 59s
CI / build-sha-integrity (pull_request) Successful in 5s
CI / validate-canonical-controls (pull_request) Successful in 3s
CI / test-python-document-crawler (pull_request) Successful in 15s
CI / test-python-dsms-gateway (pull_request) Successful in 13s
CI / loc-budget (pull_request) Successful in 23s
CI / go-lint (pull_request) Failing after 51s
CI / python-lint (pull_request) Failing after 18s
CI / nodejs-lint (pull_request) Failing after 1m8s
CI / nodejs-build (pull_request) Successful in 3m6s
CI / test-go (pull_request) Successful in 1m3s
CI / iace-gt-coverage (pull_request) Successful in 18s
CI / test-python-backend (pull_request) Successful in 28s
Der einzige offene Retrieval-Haertefall: eine Query mit >=2 genannten Regelwerken
("CRA und Maschinenverordnung") lieferte nur die keyword-dominante Domaene (CRA),
MaschVO fiel raus. Drei zusammenwirkende Ursachen, alle behoben:
1. CodeValues-Mismatch: MaschVO heisst je Collection anders (Slice MASCHVO ·
gesetze MVO · ce MACHINERY/MASCHINENVO), der Catalog hatte nur ["MASCHVO","MaschVO"]
→ Filter fand MaschVO nur in der Slice. Jetzt alle Varianten als CodeValues.
2. Per-Collection-Truncation: der Router gab perColl=3 → searchMultiRegulation holte
3+3=6, schnitt auf 3 → konnte eine Domaene je Collection verlieren. Multi-Reg-Queries
bekommen jetzt perColl = 3*len(regs).
3. Router-Score-Merge starvte die nicht-dominante Domaene. Neue balanceByRegulation()
gruppiert den gemergten Pool per Regelwerk (exakter regulation_code-Match) und nimmt
round-robin ueber die genannten Domaenen → jede Domaene mit Treffern ist im Top-K.
Generisch ueber jede genannte Menge; Single-Domain-Pfad unveraendert.
Validierung: Go-Unit (balanceByRegulation: dominante CRA verdraengt MaschVO NICHT mehr);
0070-e2e gegen dev (Retrieve() → [CRA MVO CRA MVO CRA MVO CRA MASCHINENVO] = beide
Domaenen, vorher nur CRA); CB-100-Stichprobe REGR 0 (Gain-Profil unveraendert).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -49,6 +49,38 @@ func TestRouterSliceSelection(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBalanceByRegulation(t *testing.T) {
|
||||
regs := []detectedRegulation{
|
||||
{Canonical: "CRA", CodeValues: []string{"CRA"}},
|
||||
{Canonical: "MaschVO", CodeValues: []string{"MASCHVO", "MVO", "MACHINERY"}},
|
||||
}
|
||||
// CRA dominates by score; without balancing the top-4 would be all CRA + NIST.
|
||||
pool := []LegalSearchResult{
|
||||
{RegulationCode: "CRA", Score: 0.99},
|
||||
{RegulationCode: "CRA", Score: 0.98},
|
||||
{RegulationCode: "CRA", Score: 0.97},
|
||||
{RegulationCode: "NIST", Score: 0.96},
|
||||
{RegulationCode: "MACHINERY", Score: 0.70},
|
||||
{RegulationCode: "MVO", Score: 0.65},
|
||||
}
|
||||
out := balanceByRegulation(pool, regs, 4)
|
||||
var hasCRA, hasMasch bool
|
||||
for _, r := range out {
|
||||
switch r.RegulationCode {
|
||||
case "CRA":
|
||||
hasCRA = true
|
||||
case "MACHINERY", "MVO":
|
||||
hasMasch = true
|
||||
}
|
||||
}
|
||||
if !hasCRA || !hasMasch {
|
||||
t.Errorf("both named domains must be represented: CRA=%v MaschVO=%v out=%v", hasCRA, hasMasch, out)
|
||||
}
|
||||
if out[0].RegulationCode != "CRA" || !(out[1].RegulationCode == "MACHINERY" || out[1].RegulationCode == "MVO") {
|
||||
t.Errorf("round-robin should alternate domains, got %s then %s", out[0].RegulationCode, out[1].RegulationCode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDedupResults(t *testing.T) {
|
||||
in := []LegalSearchResult{
|
||||
{RegulationCode: "EDPB WP248", ArticleLabel: "III.B", Text: "lorem", Score: 0.7},
|
||||
|
||||
Reference in New Issue
Block a user