From a06c64af48096320c1be3c352ab5c76c011d2324 Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Sun, 14 Jun 2026 11:04:24 +0200 Subject: [PATCH] feat(cra): route secure-dev breadth to code_security (atom-grain) Both network_security and code_security are now atom-grain. Per-sub_topic use_case routing: secure_development -> code_security (best for secure-dev findings), everything else -> network_security. Findings carry breadth_use_case so the source context (which atom corpus) is visible under the best-practice depth. Co-Authored-By: Claude Opus 4.7 --- .../cra/_components/CRACyberView.tsx | 3 ++- .../sdk/iace/[projectId]/cra/_hooks/useCRA.ts | 1 + .../iace/[projectId]/cra/_hooks/useCRADemo.ts | 3 ++- .../services/cra_use_case_controls.py | 26 +++++++++++++++---- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/admin-compliance/app/sdk/iace/[projectId]/cra/_components/CRACyberView.tsx b/admin-compliance/app/sdk/iace/[projectId]/cra/_components/CRACyberView.tsx index 27c23749..4a7e5e96 100644 --- a/admin-compliance/app/sdk/iace/[projectId]/cra/_components/CRACyberView.tsx +++ b/admin-compliance/app/sdk/iace/[projectId]/cra/_components/CRACyberView.tsx @@ -130,7 +130,8 @@ function FindingsTable({ findings }: { findings: CRAFinding[] }) { {f.regulatory_breadth && f.regulatory_breadth.length > 0 && (

- Regulatorische Breite{f.sub_topic ? ` โ€” ${f.sub_topic}` : ''} (NIST/ENISA/ISO-Quellen) + Regulatorische Breite{f.sub_topic ? ` โ€” ${f.sub_topic}` : ''} + {f.breadth_use_case ? ` ยท ${f.breadth_use_case}` : ''} (NIST/OWASP/ENISA-Quellen)

    {f.regulatory_breadth.map((c) => ( diff --git a/admin-compliance/app/sdk/iace/[projectId]/cra/_hooks/useCRA.ts b/admin-compliance/app/sdk/iace/[projectId]/cra/_hooks/useCRA.ts index 040c4a83..86469f8e 100644 --- a/admin-compliance/app/sdk/iace/[projectId]/cra/_hooks/useCRA.ts +++ b/admin-compliance/app/sdk/iace/[projectId]/cra/_hooks/useCRA.ts @@ -58,6 +58,7 @@ function merge(live: any): CRADemo { measures: m.measures || [], evidence_type: m.evidence_type, sub_topic: m.sub_topic, + breadth_use_case: m.breadth_use_case, regulatory_breadth: m.regulatory_breadth || [], priority_tier: m.priority_tier, priority_score: m.priority_score, diff --git a/admin-compliance/app/sdk/iace/[projectId]/cra/_hooks/useCRADemo.ts b/admin-compliance/app/sdk/iace/[projectId]/cra/_hooks/useCRADemo.ts index 25cc685f..82ce7cca 100644 --- a/admin-compliance/app/sdk/iace/[projectId]/cra/_hooks/useCRADemo.ts +++ b/admin-compliance/app/sdk/iace/[projectId]/cra/_hooks/useCRADemo.ts @@ -28,8 +28,9 @@ export interface CRAFinding { risk_level: string measures: string[] evidence_type?: string // code | process | hybrid | document โ€” drives the remediation-class badge - // network_security regulatory breadth (atom-grain shared Controls-API), live only + // regulatory breadth (atom-grain shared Controls-API: network_security / code_security), live only sub_topic?: string + breadth_use_case?: string regulatory_breadth?: { control_id: string; title: string; source_regulation: string; severity?: string }[] // priority layer (set live by the backend prioritizer; optional in the static fallback) priority_tier?: string diff --git a/backend-compliance/compliance/services/cra_use_case_controls.py b/backend-compliance/compliance/services/cra_use_case_controls.py index 29cf1a78..16637e81 100644 --- a/backend-compliance/compliance/services/cra_use_case_controls.py +++ b/backend-compliance/compliance/services/cra_use_case_controls.py @@ -38,10 +38,22 @@ _REQ_TO_SUBTOPIC = { } +# Which atom-grain use_case is most relevant per sub_topic. Both network_security +# and code_security are atom-grain; secure-dev is best served by code_security. +_SUBTOPIC_TO_USECASE = { + "secure_development": "code_security", +} +_DEFAULT_USECASE = "network_security" + + def subtopic_for(req_id: str): return _REQ_TO_SUBTOPIC.get(req_id) +def usecase_for(sub_topic: str) -> str: + return _SUBTOPIC_TO_USECASE.get(sub_topic, _DEFAULT_USECASE) + + def enrich_findings_with_breadth(mapped: list, db, limit: int = 5) -> None: """Attach `sub_topic` + `regulatory_breadth` (atom controls) to each finding. @@ -55,15 +67,19 @@ def enrich_findings_with_breadth(mapped: list, db, limit: int = 5) -> None: m["sub_topic"] = st if not st: m["regulatory_breadth"] = [] + m["breadth_use_case"] = None continue - if st not in cache: + uc = usecase_for(st) + m["breadth_use_case"] = uc + key = (uc, st) + if key not in cache: try: - res = svc.controls_for_use_case("network_security", sub_topic=st, limit=limit) - cache[st] = [ + res = svc.controls_for_use_case(uc, sub_topic=st, limit=limit) + cache[key] = [ {"control_id": c.get("control_id"), "title": c.get("title"), "source_regulation": c.get("source_regulation"), "severity": c.get("severity")} for c in res.get("controls", []) ] except Exception: - cache[st] = [] - m["regulatory_breadth"] = cache[st] + cache[key] = [] + m["regulatory_breadth"] = cache[key]