CRA Annex I Part I (2)(e)/(2)(l)/(2)(i) had no clean OWASP target (rejected:
"Mapping ueber NIST/BSI erforderlich"). Their NIST home, curated + accepted:
(2)(e) Integritaet -> SI-7 (Software/Firmware/Information Integrity)
(2)(l) Sichere Updates -> SI-2 (Flaw Remediation)
(2)(i) Angriffsflaeche -> CM-7 (Least Functionality)
New mapping_type=primary_implementation = the single canonical control per
obligation (stronger than implements/supports); related controls (SC-3(3),
RA-5, AC-6, SI-16, ...) follow later as supports.
Evidence is framework-AGNOSTIC: SI-7/SI-2/CM-7 reuse the shared evidence_type
catalog (config_export/test_report/repo_scan) - same types carry CRA, NIST,
ISO 27001, IEC 62443, BSI. (framework,control) is only the link, not the type.
obligation_id left empty: the Obligation Registry assigns it (exported via
controls_for_obligation_mapping.json), then we adopt. go test ./internal/ucca green.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Consumes the cross-session contract obligations/obligation_join_keys.json (47
obligation_ids). Interim bridge = citation_unit (our source_norm <-> registry
citation_units), to be hardened to the stable obligation_id (field now optional
on ControlMapping).
ComputeObligationCoverage joins the 47 registry obligations to our accepted
control mappings: covered=2 (user_authentication_required, firmware_software_
authentication), mapped_rejected=3 ((2)(e) -> our OWASP mappings rejected,
route via NIST/BSI), uncovered=42. This coverage signal is the feedback to the
Obligation session for what to cut/refine next.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- DROP confidence from the persisted mapping: a curated mapping is a
professional statement, not an AI guess (retriever score -> rationale only).
- ADD mapping_status (candidate|accepted|rejected|superseded) — the review state.
- ADD audit trail (reviewed_by/review_date/review_reason); accepted/rejected
fail-closed without it.
- EXTEND mapping_type: + implements, + contradicts.
- Advisor truth = mapping_status=accepted (acceptedOnly filter).
- migrate the 18 CRA->OWASP rows to mapping_status=candidate.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Versioned JSONL store + Go model for Regulation->Control mappings, per the
A-decision: the retriever only PROPOSES candidates; the curated mapping is the
audited truth the Advisor uses at runtime, never re-invented per query.
- ControlMapping struct (source_norm/source_role/target_framework/target_control/
mapping_type/confidence/provenance/rationale/version)
- enum validation (rule layer), fail-closed loader, forward+reverse index,
curated-only filter (IsCurated)
- seed: 2 retriever_candidate rows CRA Annex I -> OWASP ASVS (not yet curated)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>