From c3687d081552b21254202873bd7ff38c4da76ddf Mon Sep 17 00:00:00 2001 From: Nicolas Guzman Date: Wed, 27 May 2026 12:03:37 +0100 Subject: [PATCH 1/4] Add debug context viewer, document/framework popups, and misc fixes - Per-page debug button showing relevant Norma context section - Clickable document rows with full markdown summary popup - Clickable framework cards with full content viewer popup - Delete button for uploaded documents (framework + custom) - Unified overview section for description and risk classification pages - Evidence questions data with human-readable labels and framework grouping - UNDP Human Rights Assessment framework content - Fix document upload route ordering (422 bug) - Fix nginx upload size limit (client_max_body_size 50m) - Fix api.delete handling of 204 responses - Enforce summary section ordering in pipeline prompt - Strip markdown separators from LLM-generated output - Word count and page estimate in viewer dialogs - i18n translations for all new UI text (en/es/fr/de) Closes #28 Co-Authored-By: Claude Opus 4.6 --- backend/app/agents/norma.py | 146 ++- backend/app/api/routes/chat.py | 127 +- backend/app/api/routes/documents.py | 118 +- backend/app/api/routes/frameworks.py | 1 + backend/app/api/routes/health.py | 6 +- backend/app/data/__init__.py | 0 backend/app/data/evidence_questions.py | 1041 +++++++++++++++++ .../01_summary.md | 179 +++ backend/app/schemas/framework.py | 1 + frontend/nginx.conf | 1 + frontend/src/components/app-sidebar.tsx | 4 +- .../src/components/debug-context-dialog.tsx | 99 ++ frontend/src/components/page-header.tsx | 10 +- frontend/src/hooks/use-debug.ts | 22 + frontend/src/lib/api.ts | 2 + frontend/src/locales/de/common.json | 2 +- frontend/src/locales/de/components.json | 3 +- frontend/src/locales/de/pages.json | 6 +- frontend/src/locales/en/common.json | 2 +- frontend/src/locales/en/components.json | 3 +- frontend/src/locales/en/pages.json | 6 +- frontend/src/locales/es/common.json | 2 +- frontend/src/locales/es/components.json | 3 +- frontend/src/locales/es/pages.json | 6 +- frontend/src/locales/fr/common.json | 2 +- frontend/src/locales/fr/components.json | 3 +- frontend/src/locales/fr/pages.json | 6 +- frontend/src/pages/chat.tsx | 17 +- frontend/src/pages/description.tsx | 10 +- frontend/src/pages/documents.tsx | 166 ++- frontend/src/pages/frameworks.tsx | 63 +- frontend/src/pages/github.tsx | 4 +- frontend/src/pages/integrations.tsx | 2 +- frontend/src/pages/reporting.tsx | 9 +- frontend/src/pages/risk-classification.tsx | 2 + frontend/src/pages/settings.tsx | 2 +- pipelines/app/tasks/github_processor.py | 22 +- 37 files changed, 1934 insertions(+), 164 deletions(-) create mode 100644 backend/app/data/__init__.py create mode 100644 backend/app/data/evidence_questions.py create mode 100644 backend/app/data/knowledge/undp_human_rights_assessment/01_summary.md create mode 100644 frontend/src/components/debug-context-dialog.tsx create mode 100644 frontend/src/hooks/use-debug.ts diff --git a/backend/app/agents/norma.py b/backend/app/agents/norma.py index 0056375..d872ade 100644 --- a/backend/app/agents/norma.py +++ b/backend/app/agents/norma.py @@ -5,6 +5,81 @@ from app.core.config import settings from app.core.llm import get_language_name +QUESTION_LABELS = { + "q1": "Does the system infer from inputs to generate outputs?", + "q2": "Does the system operate with some level of autonomy?", + "q3": "Does the system perform any prohibited practices?", + "q4": "Is the system covered by EU product safety legislation?", + "q5": "Does the product require third-party conformity assessment?", + "q6": "Primary domain of the system's intended use", + "q7": "Does the system evaluate individual natural persons?", + "q8": "Does the system perform profiling of personal data?", + "q9": "Does the system exclusively perform narrow/procedural tasks?", + "q10": "Can persons under 18 access the system or be affected by its outputs?", + "q11": "Does the training data include special categories of personal data?", + "q12": "What level of human oversight does the system support?", + "q13": "Does the system involve remote biometric identification?", + "q14": "Is the system deployed by or on behalf of a public authority?", + "q15": "Does the system interact directly with people?", + "q16": "Does the system generate synthetic content?", + "q17": "Can the system be used to create deepfakes?", +} + +AREA_LABELS = { + "cybersecurity": "Cybersecurity", + "documentation": "Documentation", + "qms": "Quality Management System", + "incidents": "Incidents", + "risk-management": "Risk Management", + "data-governance": "Data Governance", + "accuracy": "Accuracy", + "records": "Records", + "robustness": "Robustness", + "oversight": "Oversight", + "transparency": "Transparency", + "surveillance": "Surveillance", + "undp-zero-question": "UNDP Zero Question", + "undp-org-readiness": "UNDP Organisational Readiness", + "undp-planning": "UNDP Planning", + "undp-rights-mapping": "UNDP Rights Mapping", + "undp-data-diligence": "UNDP Data Diligence", + "undp-risk-analysis": "UNDP Risk Analysis", + "undp-risk-management": "UNDP Risk Management", + "undp-monitoring": "UNDP Monitoring", + "undp-framework-alignment": "UNDP Framework Alignment", + "env-energy-carbon": "Energy & Carbon", + "env-hardware": "Hardware", + "env-data-management": "Data Management", + "env-model-efficiency": "Model Efficiency", + "env-lifecycle": "Lifecycle", + "env-monitoring": "Environmental Monitoring", +} + + +def _downshift_headings(text: str) -> str: + import re + + text = re.sub(r"^-{3,}\s*$", "", text, flags=re.MULTILINE) + return re.sub(r"^(#{1,5}) ", lambda m: "#" + m.group(1) + " ", text, flags=re.MULTILINE) + + +def _format_evidence_key(item_key: str) -> str: + import re + + from app.data.evidence_questions import EVIDENCE_QUESTIONS + + match = re.match(r"^(.+)-([A-Z]+-\d+)-(\d+)$", item_key) + if not match: + return item_key + area_id, item_code, q_idx = match.groups() + area_name = AREA_LABELS.get(area_id, area_id.replace("-", " ").title()) + question = EVIDENCE_QUESTIONS.get(item_key, "") + label = f"{area_name} — {item_code} (Q{int(q_idx) + 1})" + if question: + label += f": {question}" + return label + + SYSTEM_INSTRUCTION_TEMPLATE = """\ You are Norma, an AI compliance assistant. You help users understand and comply with \ regulatory frameworks, human rights standards, and environmental requirements for AI systems. @@ -47,12 +122,45 @@ def _language_rule(language: str) -> str: ) +def _group_evidence_by_framework( + evidence: list[dict], +) -> list[tuple[str, int, list[dict]]]: + from app.data.evidence_questions import EVIDENCE_ORDER, EVIDENCE_QUESTIONS + + totals: dict[str, int] = {"EU AI Act": 0, "UNDP Human Rights Due Diligence": 0, "Environmental Impact": 0} + for key in EVIDENCE_QUESTIONS: + if key.startswith("undp-"): + totals["UNDP Human Rights Due Diligence"] += 1 + elif key.startswith("env-"): + totals["Environmental Impact"] += 1 + else: + totals["EU AI Act"] += 1 + + groups: dict[str, list[dict]] = {} + for ev in evidence: + key = ev["item_key"] + if key.startswith("undp-"): + framework = "UNDP Human Rights Due Diligence" + elif key.startswith("env-"): + framework = "Environmental Impact" + else: + framework = "EU AI Act" + groups.setdefault(framework, []).append(ev) + + for items in groups.values(): + items.sort(key=lambda ev: EVIDENCE_ORDER.get(ev["item_key"], 999999)) + + order = ["EU AI Act", "UNDP Human Rights Due Diligence", "Environmental Impact"] + return [(title, totals[title], groups.get(title, [])) for title in order] + + def build_system_prompt( *, framework_contents: list[dict], project_context: dict | None = None, document_summaries: list[dict] | None = None, github_summary: str | None = None, + github_architecture: str | None = None, language: str = "en", ) -> str: parts: list[str] = [] @@ -79,21 +187,39 @@ def build_system_prompt( if project_context.get("questionnaire_answers"): parts.append("\n**Questionnaire Answers:**\n") for key, val in project_context["questionnaire_answers"].items(): - parts.append(f"- {key}: {val}\n") + label = QUESTION_LABELS.get(key, key) + if isinstance(val, list): + val = ", ".join(val) + parts.append(f"- **{label}** — {val}\n") if document_summaries: - parts.append("\n## Uploaded Document Summaries\n") + parts.append("\n## Uploaded Document Context\n") for doc in document_summaries: - parts.append(f"### {doc['name']}\n{doc['summary']}\n") - - if github_summary: - parts.append("\n## GitHub Repository & Task Context\n") - parts.append(github_summary) + parts.append(f"### {doc['name']}\n{_downshift_headings(doc['summary'])}\n") + + if github_summary or github_architecture: + parts.append("\n## Codebase & Task Context\n") + if github_summary: + parts.append(_downshift_headings(github_summary)) + if github_architecture: + import re + + summary_text = github_summary or "" + matches = re.findall(r"^(#{1,5})\s+(\d+)\.", summary_text, re.MULTILINE) + next_num = max((int(n) for _, n in matches), default=0) + 1 + prefix = "#" + (matches[0][0] if matches else "##") + parts.append(f"\n{prefix} {next_num}. Architecture\n") + parts.append(github_architecture) if project_context and project_context.get("reporting_evidence"): - parts.append("\n## Reporting Evidence\n") - for ev in project_context["reporting_evidence"]: - parts.append(f"- **{ev['item_key']}:** {ev['comment']}\n") + parts.append("\n## Reporting Evidence Context\n") + grouped = _group_evidence_by_framework(project_context["reporting_evidence"]) + for framework_title, total, items in grouped: + filled = [ev for ev in items if ev.get("comment", "").strip()] + parts.append(f"\n### {framework_title} ({len(filled)} out of {total} questions answered)\n") + for ev in filled: + label = _format_evidence_key(ev["item_key"]) + parts.append(f"- **{label}:** {ev['comment']}\n") context = "\n".join(parts) if parts else "No project context available." return SYSTEM_INSTRUCTION_TEMPLATE.format( diff --git a/backend/app/api/routes/chat.py b/backend/app/api/routes/chat.py index 0f376fa..9aacf21 100644 --- a/backend/app/api/routes/chat.py +++ b/backend/app/api/routes/chat.py @@ -10,7 +10,14 @@ from google.genai.types import Content, Part from sqlalchemy.orm import Session -from app.agents.norma import build_system_prompt, create_norma_agent +from app.agents.norma import ( + QUESTION_LABELS, + _downshift_headings, + _format_evidence_key, + _group_evidence_by_framework, + build_system_prompt, + create_norma_agent, +) from app.api.dependencies import get_current_user from app.core.database import SessionLocal, get_db from app.models.chat import ChatMessage, ChatSession @@ -100,16 +107,134 @@ def _assemble_context(project: Project, db: Session, language: str = "en") -> st integration = db.query(Integration).filter(Integration.project_id == project.id).first() github_summary = integration.summary if integration else None + github_architecture = integration.architecture_mermaid if integration else None return build_system_prompt( framework_contents=framework_contents, project_context=project_context, document_summaries=document_summaries if document_summaries else None, github_summary=github_summary, + github_architecture=github_architecture, language=language, ) +def _build_section(project: Project, db: Session, section: str) -> str | None: + if section == "overview": + lines = [ + "## Current Project Context\n", + f"**Project:** {project.name}\n", + ] + if project.description: + lines.append(f"**Description:** {project.description}\n") + if project.intended_purpose: + lines.append(f"**Intended Purpose:** {project.intended_purpose}\n") + if project.intended_users: + lines.append(f"**Intended Users:** {project.intended_users}\n") + if project.deployment_context: + lines.append(f"**Deployment Context:** {project.deployment_context}\n") + lines.append("\n### EU AI Act Risk Classification\n") + lines.append(f"**Risk Classification:** {project.risk_classification or 'Not set'}\n") + if project.questionnaire_answers: + lines.append("**Questionnaire Answers:**\n") + for key, val in project.questionnaire_answers.items(): + label = QUESTION_LABELS.get(key, key) + if isinstance(val, list): + val = ", ".join(val) + lines.append(f"- **{label}** — {val}\n") + return "\n".join(lines) + + if section == "frameworks": + frameworks = db.query(Framework).all() + if not frameworks: + return None + lines = ["## Compliance Frameworks\n"] + for fw in frameworks: + lines.append(f"### {fw.name}\n{fw.description}\n") + if fw.content: + lines.append(f"\n{fw.content}\n") + return "\n".join(lines) + + if section == "documents": + frameworks = db.query(Framework).all() + all_docs = db.query(Document).filter(Document.project_id == project.id).all() + custom_docs = db.query(CustomDocument).filter(CustomDocument.project_id == project.id).all() + lines = ["## Uploaded Document Context\n"] + for fw in frameworks: + fw_docs = [d for d in all_docs if d.definition.framework_id == fw.id] + summarised = [d for d in fw_docs if d.summary] + lines.append(f"\n### {fw.name} ({len(summarised)} out of {len(fw_docs)} documents uploaded)\n") + if summarised: + for doc in summarised: + lines.append(f"- **{doc.definition.name}:** {_downshift_headings(doc.summary)}\n") + else: + lines.append("No documents uploaded for this framework.\n") + custom_summarised = [c for c in custom_docs if c.summary] + lines.append( + f"\n### Additional Documents ({len(custom_summarised)} out of {len(custom_docs)} documents uploaded)\n" + ) + if custom_summarised: + for cdoc in custom_summarised: + lines.append(f"- **{cdoc.file_name}:** {_downshift_headings(cdoc.summary)}\n") + else: + lines.append("No additional documents uploaded.\n") + return "\n".join(lines) + + if section == "reporting": + evidence = db.query(ReportingEvidence).filter(ReportingEvidence.project_id == project.id).all() + evidence_dicts = [{"item_key": ev.item_key, "comment": ev.comment} for ev in evidence] + lines = ["## Reporting Evidence Context\n"] + grouped = _group_evidence_by_framework(evidence_dicts) + for framework_title, total, items in grouped: + filled = [ev for ev in items if ev.get("comment", "").strip()] + lines.append(f"\n### {framework_title} ({len(filled)} out of {total} questions answered)\n") + for ev in filled: + label = _format_evidence_key(ev["item_key"]) + lines.append(f"- **{label}:** {ev['comment']}\n") + return "\n".join(lines) + + if section == "github": + integration = db.query(Integration).filter(Integration.project_id == project.id).first() + if not integration: + return None + if not integration.summary and not integration.architecture_mermaid: + return None + parts = ["## Codebase & Task Context\n"] + if integration.summary: + parts.append(_downshift_headings(integration.summary)) + if integration.architecture_mermaid: + import re + + summary_text = integration.summary or "" + matches = re.findall(r"^(#{1,5})\s+(\d+)\.", summary_text, re.MULTILINE) + next_num = max((int(n) for _, n in matches), default=0) + 1 + prefix = "#" + (matches[0][0] if matches else "##") + parts.append(f"\n{prefix} {next_num}. Architecture\n") + parts.append(integration.architecture_mermaid) + return "\n".join(parts) + + return None + + +@router.get("/context") +def get_context( + project_id: uuid.UUID, + section: str = "full", + db: Session = Depends(get_db), + current_user: User = Depends(get_current_user), +): + project = db.query(Project).filter(Project.id == project_id, Project.owner_id == current_user.id).first() + if not project: + raise HTTPException(status_code=404, detail="Project not found") + + if section == "full": + context = _assemble_context(project, db, language=current_user.language_preference or "en") + else: + context = _build_section(project, db, section) + + return {"context": context} + + @router.post("/sessions", response_model=ChatSessionResponse, status_code=201) def create_session( body: ChatSessionCreate, diff --git a/backend/app/api/routes/documents.py b/backend/app/api/routes/documents.py index a799eb7..c3bf47f 100644 --- a/backend/app/api/routes/documents.py +++ b/backend/app/api/routes/documents.py @@ -73,52 +73,6 @@ def list_documents( return [_to_response(d) for d in docs] -@router.post("/{document_id}/upload", response_model=DocumentResponse) -async def upload_document( - project_id: uuid.UUID, - document_id: uuid.UUID, - file: UploadFile, - db: Session = Depends(get_db), - current_user: User = Depends(get_current_user), -): - project = _get_project(project_id, current_user, db) - doc = db.query(Document).filter(Document.id == document_id, Document.project_id == project.id).first() - if not doc: - raise HTTPException(status_code=404, detail="Document not found") - - upload_dir = UPLOAD_DIR / str(project.id) - upload_dir.mkdir(parents=True, exist_ok=True) - - file_ext = Path(file.filename).suffix if file.filename else "" - stored_name = f"{document_id}{file_ext}" - file_path = upload_dir / stored_name - - content = await file.read() - file_path.write_bytes(content) - - doc.file_path = str(file_path) - doc.file_name = file.filename - doc.uploaded_at = datetime.now(UTC) - db.commit() - db.refresh(doc) - - try: - async with httpx.AsyncClient() as client: - await client.post( - f"{settings.pipelines_url}/api/documents/process", - json={ - "document_id": str(doc.id), - "file_path": str(file_path), - "language": current_user.language_preference or "en", - }, - timeout=300, - ) - except Exception: - pass - - return _to_response(doc) - - @router.get("/custom", response_model=list[CustomDocumentResponse]) def list_custom_documents( project_id: uuid.UUID, @@ -208,3 +162,75 @@ def delete_custom_document( db.delete(doc) db.commit() + + +@router.delete("/{document_id}/upload", response_model=DocumentResponse) +def remove_uploaded_document( + project_id: uuid.UUID, + document_id: uuid.UUID, + db: Session = Depends(get_db), + current_user: User = Depends(get_current_user), +): + project = _get_project(project_id, current_user, db) + doc = db.query(Document).filter(Document.id == document_id, Document.project_id == project.id).first() + if not doc: + raise HTTPException(status_code=404, detail="Document not found") + + if doc.file_path: + file_path = Path(doc.file_path) + if file_path.exists(): + file_path.unlink() + + doc.file_path = None + doc.file_name = None + doc.summary = None + doc.uploaded_at = None + db.commit() + db.refresh(doc) + return _to_response(doc) + + +@router.post("/{document_id}/upload", response_model=DocumentResponse) +async def upload_document( + project_id: uuid.UUID, + document_id: uuid.UUID, + file: UploadFile, + db: Session = Depends(get_db), + current_user: User = Depends(get_current_user), +): + project = _get_project(project_id, current_user, db) + doc = db.query(Document).filter(Document.id == document_id, Document.project_id == project.id).first() + if not doc: + raise HTTPException(status_code=404, detail="Document not found") + + upload_dir = UPLOAD_DIR / str(project.id) + upload_dir.mkdir(parents=True, exist_ok=True) + + file_ext = Path(file.filename).suffix if file.filename else "" + stored_name = f"{document_id}{file_ext}" + file_path = upload_dir / stored_name + + content = await file.read() + file_path.write_bytes(content) + + doc.file_path = str(file_path) + doc.file_name = file.filename + doc.uploaded_at = datetime.now(UTC) + db.commit() + db.refresh(doc) + + try: + async with httpx.AsyncClient() as client: + await client.post( + f"{settings.pipelines_url}/api/documents/process", + json={ + "document_id": str(doc.id), + "file_path": str(file_path), + "language": current_user.language_preference or "en", + }, + timeout=300, + ) + except Exception: + pass + + return _to_response(doc) diff --git a/backend/app/api/routes/frameworks.py b/backend/app/api/routes/frameworks.py index 5aa2bd8..9c1d8e0 100644 --- a/backend/app/api/routes/frameworks.py +++ b/backend/app/api/routes/frameworks.py @@ -19,6 +19,7 @@ def _to_response(fw: Framework) -> dict: "description": fw.description, "category": fw.category, "status": fw.status, + "content": fw.content, "document_count": len(fw.document_definitions), "created_at": fw.created_at, } diff --git a/backend/app/api/routes/health.py b/backend/app/api/routes/health.py index 01da035..220c76a 100644 --- a/backend/app/api/routes/health.py +++ b/backend/app/api/routes/health.py @@ -1,8 +1,10 @@ from fastapi import APIRouter -router = APIRouter(tags=["health"]) +from app.core.config import settings + +router = APIRouter(prefix="/api", tags=["health"]) @router.get("/health") def health_check(): - return {"status": "ok"} + return {"status": "ok", "debug": settings.debug} diff --git a/backend/app/data/__init__.py b/backend/app/data/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/app/data/evidence_questions.py b/backend/app/data/evidence_questions.py new file mode 100644 index 0000000..d6f5881 --- /dev/null +++ b/backend/app/data/evidence_questions.py @@ -0,0 +1,1041 @@ +# ruff: noqa: E501 +EVIDENCE_QUESTIONS: dict[str, str] = { + "cybersecurity-CYB-01-0": "Are there controls to prevent malicious manipulation of the training dataset or AI knowledge bases?", + "cybersecurity-CYB-01-1": "Is the integrity and provenance of data injected during fine-tuning or RAG verified?", + "cybersecurity-CYB-02-0": "Is the AI system subjected to stress tests to evaluate its resistance to inputs designed to induce errors (adversarial attacks)?", + "cybersecurity-CYB-02-1": "Are there safeguards to maintain performance against malicious variations?", + "cybersecurity-CYB-03-0": "Does the system have input and output guardrails to neutralise malicious prompt injections that alter the model's purpose?", + "cybersecurity-CYB-04-0": "Are there physical, logical, and cryptographic security measures to protect model weights and parameters against unauthorised access, preventing extraction or inversion?", + "cybersecurity-CYB-05-0": "Have controls (DLP, output filters) been implemented to mitigate the risk of the model revealing confidential information, intellectual property, or PII in its responses?", + "cybersecurity-CYB-06-0": "Are third-party libraries (Python), containers, and imported AI components continuously scanned and validated for vulnerabilities to prevent supply chain injections?", + "cybersecurity-CYB-07-0": "Are robust identity and access management (IAM) systems employed, with role segregation and fine-grained access control (FGAC) over artifacts, vector databases, and model APIs?", + "cybersecurity-CYB-08-0": "Is the AI development, training, and execution environment protected behind strict firewalls and perimeter controls (isolated networks, proxies, WAF) to prevent external intrusions?", + "cybersecurity-CYB-09-0": "Does the AI system have automatic immutable logging capabilities for events, accesses, commands, and API usage, and are these integrated with a SIEM / Security Operations Centre (SOC)?", + "cybersecurity-CYB-10-0": "Are training data, RAG knowledge bases, model weights, and prompts/responses encrypted in transit and at rest using strong cryptographic standards (AES-256, TLS 1.3)?", + "cybersecurity-CYB-11-0": "Is continuous vulnerability analysis, patch management, and security posture auditing (CSPM) carried out on cloud APIs, containers, and AI model endpoints?", + "documentation-MG01-0": "Has a documentation strategy been defined from the early design phases of the AI system to provide appropriate coverage?", + "documentation-MG01-1": "Does the plan include clear milestones and responsible parties to ensure traceability of the technical documentation process?", + "documentation-MG02-0": "Is there an established calendar for reviewing and updating technical documentation?", + "documentation-MG02-1": "Does the update plan account for regulatory, technical, or operational context changes that will produce additional updates?", + "documentation-MG03-0": "Have version control and change traceability mechanisms been defined to ensure coherence between the system and its technical documentation?", + "documentation-MG03-1": "Does the procedure guarantee immediate documentation update when the system is modified?", + "documentation-MG04-0": "Has an internal communication plan been designed to share key documentation content across implicated areas?", + "documentation-MG04-1": "Has it been verified that all areas understand the purpose of technical documentation in relation to their functions?", + "documentation-MG05-0": "Has a technical documentation responsible been formally named with cross-functional authority to coordinate its preparation and supervision?", + "documentation-MG05-1": "Does the responsible have the resources and knowledge necessary to carry out this task effectively?", + "documentation-MG06-0": "Have specific documentation responsible parties been assigned for each key area (data, security, risks, etc.)?", + "documentation-MG06-1": "Do the designated responsible parties have the technical competencies to correctly document their domain?", + "documentation-MG07-0": "Is there a single, secure, and accessible repository for storing technical documentation?", + "documentation-MG07-1": "Does the document management system allow version control, access permissions, and audits?", + "documentation-MG08-0": "Has it been verified that all responsible parties have adequate access to the document management system?", + "documentation-MG08-1": "Are there differentiated access policies based on roles and responsibilities?", + "documentation-MG09-0": "Have security and backup measures (backups, redundancy, etc.) been implemented to preserve technical documentation integrity?", + "documentation-MG09-1": "Are periodic audits conducted to verify these mechanisms are active and functioning correctly?", + "documentation-MG10-0": "Do deployment responsible parties have clear, direct access to the necessary instructions and documentation?", + "documentation-MG10-1": "Is it periodically validated that said documentation is updated, comprehensible, and complete from an operational standpoint?", + "documentation-MG11-0": "Is there a procedure for periodically updating AI system deployment instructions?", + "documentation-MG11-1": "Are deployment responsible parties notified when instructions have been modified or updated?", + "documentation-MG12-0": "Have evaluation frequency and criteria been defined for auditing technical documentation?", + "documentation-MG12-1": "Do audits include verifications of traceability, currency, and accessibility of the documentation?", + "documentation-MG13-0": "Has an identification of relevant harmonised standards been carried out?", + "documentation-MG13-1": "Is periodic monitoring conducted of normative changes that could affect system compliance?", + "documentation-MG14-0": "Has the possibility of applying recognised quality certifications been evaluated?", + "documentation-MG14-1": "Is there evidence of compliance with the criteria required by these quality seals?", + "documentation-MG15-0": "Does the repository ensure secure and durable storage for at least 10 years?", + "documentation-MG15-1": "Does the system allow immediate access by competent national authorities when required?", + "documentation-MG16-0": "Has QMS documentation been included in the official conservation repository?", + "documentation-MG16-1": "Is its availability assured for at least 10 years and its accessibility for competent authorities?", + "documentation-MG17-0": "Are notified body approvals and change evidence conserved in a centralised, secure repository?", + "documentation-MG17-1": "Does the plan contemplate conservation for at least 10 years?", + "documentation-MG18-0": "Does the system contemplate conservation of decisions and documents issued by notified bodies?", + "documentation-MG18-1": "Is conservation and access assured for at least 10 years in an adequate repository?", + "documentation-MG19-0": "Is the declaration of conformity archived in a repository that ensures availability and conservation for at least 10 years?", + "documentation-MG20-0": "Have regular audits of the documentation conservation mechanism been established?", + "documentation-MG20-1": "Is correct functioning and compliance with conservation obligations verified?", + "documentation-MG21-0": "Does the conservation mechanism guarantee continued access to technical documentation even if the provider ceases activity?", + "documentation-MG21-1": "Have legal and technical measures been taken to ensure this future availability?", + "documentation-MG22-0": "Does the documentation clearly include the system's purpose, provider name, and corresponding version?", + "documentation-MG22-1": "Is traceability between previous and current versions indicated?", + "documentation-MG23-0": "Has it been adequately documented how the system communicates or can interoperate with other external systems?", + "documentation-MG23-1": "Have compatibility requirements for ensuring interoperability also been documented?", + "documentation-MG24-0": "Does the documentation record the versions used and procedures required for updates or patches?", + "documentation-MG24-1": "Is the planned update policy indicated to maintain system security and functionality?", + "documentation-MG25-0": "Is the form of distribution and deployment detailed (e.g., as API, download, embedded software)?", + "documentation-MG25-1": "Is clear documentation provided for each modality of putting the system into service?", + "documentation-MG26-0": "Has the type of hardware necessary or recommended for correct system functioning been documented?", + "documentation-MG26-1": "Are possible limitations or incompatibilities with certain hardware specified?", + "documentation-MG27-0": "Are visual elements such as product images, marking, or internal configuration included where applicable?", + "documentation-MG27-1": "Are illustrations correctly associated with relevant technical descriptions?", + "documentation-MG28-0": "Does the documentation contain a comprehensible and sufficient description of the user interface directed at the system operator?", + "documentation-MG28-1": "Have visual examples or diagrams been included to familiarise the deployer with the interface?", + "documentation-MG29-0": "Are practical and updated instructions included to facilitate system implementation by the operator?", + "documentation-MG29-1": "Do instructions contemplate possible errors during deployment and corresponding corrective actions?", + "documentation-MG30-0": "Have third-party tools and models used in development been documented, along with their integration or modification?", + "documentation-MG30-1": "Have risks derived from using third-party tools or models been evaluated and documented?", + "documentation-MG31-0": "Have all technical design elements been clearly and accessibly documented, including algorithms used?", + "documentation-MG31-1": "Does the documentation record technical concessions made and how they affect system performance or security?", + "documentation-MG32-0": "Does the documentation include a comprehensible schema of system architecture and component interaction?", + "documentation-MG32-1": "Are computational resources employed and platforms used in each development phase described?", + "documentation-MG33-0": "Have data and methodologies used in training, testing, and validation been documented?", + "documentation-MG33-1": "Is there evidence of data quality control and labelling/cleaning processes performed?", + "documentation-MG34-0": "Have measures enabling human oversight of the system during use been evaluated?", + "documentation-MG34-1": "Does the documentation include tools or mechanisms designed for users to correctly interpret results?", + "documentation-MG35-0": "Have planned changes that could apply to the system and their technical impact been documented?", + "documentation-MG35-1": "Are validation procedures specified to guarantee these changes don't compromise system conformity?", + "documentation-MG36-0": "Does the documentation contain clear evidence of tests performed, results, and signed records?", + "documentation-MG36-1": "Have specific tests been included to verify effects of planned updates or modifications?", + "documentation-MG37-0": "Are the protection measures applied to guarantee AI system cybersecurity detailed?", + "documentation-MG37-1": "Does the documentation include vulnerability assessments and security incident management mechanisms?", + "documentation-MG38-0": "Are possible adverse outcomes and risks associated with the system adequately identified and documented?", + "documentation-MG38-1": "Does the documentation include mechanisms to mitigate and supervise these risks throughout the lifecycle?", + "documentation-MG39-0": "Have the deployer's functions and responsibilities regarding system supervision been clearly specified?", + "documentation-MG39-1": "Has the necessary training or qualification been described for this profile to correctly interpret results?", + "documentation-MG40-0": "Does the documentation justify the performance parameters established and their alignment with system purpose?", + "documentation-MG40-1": "Have these parameters been validated in documented tests?", + "documentation-MG41-0": "Has a risk management system been documented that complies with Article 9?", + "documentation-MG41-1": "Is it specified how this system is updated given relevant changes in the AI system lifecycle?", + "documentation-MG42-0": "Has the history of relevant changes the system has undergone from design to current version been recorded?", + "documentation-MG42-1": "Is the impact of each change on safety, accuracy, or regulatory compliance indicated?", + "documentation-MG43-0": "Does the documentation clearly specify which harmonised standards or technical standards have been followed?", + "documentation-MG43-1": "Have the solutions adopted been adequately justified where harmonised standards haven't been applied?", + "documentation-MG44-0": "Has a valid copy of the system's declaration of conformity been included in the documentation?", + "documentation-MG44-1": "Is it verified that said declaration is signed by the authorised provider and explicitly references Article 47?", + "documentation-MG45-0": "Has a system for evaluating AI system performance after commercial deployment been defined?", + "documentation-MG45-1": "Does the post-market surveillance plan contemplate information collection mechanisms, audits, and continuous improvements?", + "qms-QMS-01-0": "Is there a defined regulatory compliance strategy to ensure the system complies with the AI Regulation?", + "qms-QMS-01-1": "Does it establish compliance milestones?", + "qms-QMS-02-0": "Are systematic techniques, procedures, and actions defined for system design, design control, and design verification?", + "qms-QMS-03-0": "Are systematic techniques, procedures, and actions defined for development, quality control, and quality assurance?", + "qms-QMS-04-0": "Are examination, testing, and validation procedures in place before, during, and after development?", + "qms-QMS-04-1": "Are metrics and thresholds documented?", + "qms-QMS-05-0": "Have the technical specifications and standards that will apply to the system been documented?", + "qms-QMS-06-0": "Are there documented systems and procedures for data management (acquisition, collection, analysis, labelling, storage, filtering, and retention)?", + "qms-QMS-07-0": "Has the risk management system been integrated into the quality management system?", + "qms-QMS-08-0": "Has the configuration, application, and maintenance of a post-market monitoring system been established?", + "qms-QMS-09-0": "Have procedures been defined for the notification of serious incidents and defective functioning?", + "qms-QMS-10-0": "Are there procedures for handling communication with competent national authorities and other relevant bodies?", + "qms-QMS-11-0": "Are there systems and procedures for the maintenance of records (logs and technical documentation)?", + "qms-QMS-12-0": "Does the QMS include procedures for resource management, including security-of-supply related measures?", + "qms-QMS-13-0": "Has an accountability framework been established defining responsibilities of development, deployment, and management teams?", + "qms-QMS-14-0": "Is the quality management system proportionate to the organisation's size and the AI system's risks?", + "qms-QMS-15-0": "Are there statistical validations and algorithmic testing procedures to prevent overfitting and ensure correct weight adjustment during training?", + "qms-QMS-16-0": "Is there a formal procedure for managing substantial modifications to the AI system, including the need for a new conformity assessment?", + "incidents-M-INC-01-0": "Provider: Within the QMS, procedures associated with notification of a serious incident.", + "incidents-M-INC-01-1": "Deployer: Within the QMS, procedures associated with notification of a serious incident.", + "incidents-M-INC-02-0": "Provider: Document with the contact responsible for the Market Surveillance Authority.", + "incidents-M-INC-02-1": "Deployer: Document with the contact responsible for the Market Surveillance Authority.", + "incidents-M-INC-03-0": "Provider: Prepare a user manual for the channel that enables management of requests and incidents between deployer and provider.", + "incidents-M-INC-03-1": "Deployer: Access to the user manual for the channel that enables management of requests and incidents between deployer and provider.", + "incidents-M-INC-04-0": "Provider: Prepare the document explaining the AI system's category according to those defined in the Regulation.", + "incidents-M-INC-04-1": "Deployer: Access to the document explaining the AI system's category according to the Regulation.", + "incidents-M-INC-05-0": "Provider: Document certifying knowledge about the fundamental rights of the European Union.", + "incidents-M-INC-05-1": "Deployer: Document certifying knowledge about the fundamental rights of the European Union.", + "risk-management-MG01-0": "Has a risk management system been defined for high-risk AI systems throughout the entire lifecycle?", + "risk-management-MG01-1": "Have the elements of the organisation's internal and external context around high-risk AI systems been identified and documented?", + "risk-management-MG01-2": "Has leadership and commitment to risk management been formalised (policies, procedures, resources, authority, accountability)?", + "risk-management-MG02-0": "Has the risk appetite been defined and constantly updated (in relation to the risk the AI system may pose to health, safety, and fundamental rights)?", + "risk-management-MG03-0": "Have all AI system components been identified, inventoried, and documented (key actors, data, tools, etc.)?", + "risk-management-MG04-0": "Have all risks associated with AI systems been identified, inventoried, and documented (especially those that could affect health, safety, and fundamental rights)?", + "risk-management-MG05-0": "Have all identified risks been analysed and evaluated (assigning probability of occurrence and impact)?", + "risk-management-MG06-0": "Have possible risks related to the use or impact of the AI system on minors under 18 been considered (identification, analysis, evaluation, and implementation of treatment measures)?", + "risk-management-MG07-0": "Have mechanisms been defined and implemented for communication and consultation around the risk management system for high-risk AI systems?", + "risk-management-MG08-0": "Have possible risks related to the post-market surveillance system been considered (identification, analysis, evaluation, and implementation of treatment measures)?", + "risk-management-MG09-0": "Have risk treatment options been defined and prioritised based on effectiveness and feasibility criteria?", + "risk-management-MG09-1": "Have adequate mitigation measures and safeguards been evaluated for each identified risk?", + "risk-management-MG10-0": "Have all risk treatment options been determined for managing the identified, analysed, and evaluated risks?", + "risk-management-MG11-0": "If defined, has the risk management system been implemented throughout the entire lifecycle?", + "risk-management-MG11-1": "If implemented, is the risk management system continuously maintained throughout the entire lifecycle?", + "risk-management-MG11-2": "Has the implementation of defined treatment measures been planned?", + "risk-management-MG12-0": "Has a continuous monitoring and improvement process been defined and implemented around the risk management system?", + "risk-management-MG12-1": "Have testing procedures been established to guarantee the system fulfils its purpose (intended use)?", + "risk-management-MG12-2": "Have testing procedures been established to guarantee high-risk AI system requirements are met?", + "risk-management-MG12-3": "Have tests in real conditions been defined and implemented?", + "risk-management-MG13-0": "Have review and monitoring periods for the risk management system been established?", + "risk-management-MG14-0": "If defined, has the risk management system been documented throughout the lifecycle?", + "risk-management-MG14-1": "Have residual risks after treatment measure implementation been documented for communication to deployers?", + "risk-management-MG14-2": "Has the entire risk management process been documented?", + "data-governance-MG01-0": "Has all information necessary for AI system development and use been identified?", + "data-governance-MG01-1": "Has the necessary information been documented?", + "data-governance-MG02-0": "Have data sources been identified?", + "data-governance-MG02-1": "Has a data collection process been established?", + "data-governance-MG03-0": "Have data quality dimensions to evaluate been defined?", + "data-governance-MG04-0": "Have specific quality controls been defined for each identified dimension?", + "data-governance-MG05-0": "Have the defined quality controls been implemented?", + "data-governance-MG05-1": "Have the results of implemented quality controls been verified?", + "data-governance-MG06-0": "Have quality control results been reported?", + "data-governance-MG06-1": "Have deviations detected in quality controls been documented?", + "data-governance-MG07-0": "Have improvement plans been developed based on quality results?", + "data-governance-MG07-1": "Have implemented improvement measures been documented?", + "data-governance-MG08-0": "Have data been transformed to adapt them to AI system needs?", + "data-governance-MG09-0": "Have data from different sources been aggregated?", + "data-governance-MG09-1": "Have data aggregation processes been documented?", + "data-governance-MG10-0": "Is adequate data sampling performed?", + "data-governance-MG11-0": "After initial data collection and treatment, have additional data needs or characteristics been identified?", + "data-governance-MG11-1": "Has dimensionality augmentation or reduction been considered to create features or discard redundant ones?", + "data-governance-MG12-0": "Have data been enriched and expanded?", + "data-governance-MG13-0": "Have identifying labels been assigned to collected data?", + "data-governance-MG13-1": "Have automatic data labelling tools been used? Has the process been supervised by human oversight?", + "data-governance-MG14-0": "Has the potential bias that collected data may present been analysed and evaluated?", + "data-governance-MG15-0": "Has a bias been identified in the data?", + "data-governance-MG15-1": "If affirmative, has analysis and evaluation been done to determine the need for treatment measures?", + "data-governance-MG16-0": "Have treatment measures for identified and evaluated biases been implemented?", + "data-governance-MG17-0": "If data will be transferred in the last phase of the data lifecycle, has a report been generated with full detail of the transfer process?", + "data-governance-MG18-0": "Has it been verified that no user or actor involved in AI system development still requires data access?", + "data-governance-MG18-1": "Has it been verified that the data deletion process won't violate any legal, contractual, or retention obligation?", + "data-governance-MG18-2": "Has it been verified that data will be deleted from all storage locations?", + "data-governance-MG18-3": "Has it been evaluated whether there is any possibility of partial or total data restoration from the AI system trained with this data?", + "data-governance-MG18-4": "Has it been checked whether the data has cultural, social, or historical importance?", + "data-governance-MG18-5": "Has a report been generated with full detail of the data deletion process?", + "accuracy-MG01-0": "In selecting accuracy metrics and their values, has the system's intended purpose been considered?", + "accuracy-MG01-1": "Has the correspondence between each selected metric and the system's intended use been documented traceably?", + "accuracy-MG01-2": "Has it been validated that chosen metrics correctly reflect expected performance in real application contexts?", + "accuracy-MG02-0": "Is the selection of accuracy metrics motivated by mitigation of risks identified in the risk plan, and has said motivation been documented?", + "accuracy-MG02-1": "Have tests been performed to study correlation between detected risks and selected metrics that specifically address them?", + "accuracy-MG02-2": "Have metrics that help control risks with greatest impact on health, safety, and fundamental rights been prioritised?", + "accuracy-MG03-0": "Has the impact of data preprocessing been considered, recording preprocessing operations and their relation to accuracy metrics results?", + "accuracy-MG03-1": "Has the impact of data quality improvement on system accuracy been considered?", + "accuracy-MG03-2": "Has the impact of feature engineering operations on system accuracy been documented and considered?", + "accuracy-MG04-0": "Has the impact of overfitting on accuracy been considered and recorded, along with measures taken to avoid it?", + "accuracy-MG04-1": "Have cross-validation mechanisms or other methods been implemented to prevent overfitting?", + "accuracy-MG04-2": "Have key indicators been recorded to detect signs of overfitting during training and evaluation?", + "accuracy-MG05-0": "Have criteria been defined for choosing baseline models and their relevance at each lifecycle phase?", + "accuracy-MG05-1": "Is model accuracy systematically compared throughout the lifecycle with associated baseline models?", + "accuracy-MG06-0": "Does the AI output include a measure of certainty or confidence level that accompanies model outputs?", + "accuracy-MG06-1": "Is comprehensible information about certainty level provided to end users in critical contexts?", + "accuracy-MG06-2": "Have confidence thresholds been defined that trigger specific alerts or recommendations?", + "accuracy-MG07-0": "Have cumulative unit, stress, and integration tests been performed during the AI system development process in relation to accuracy measurement?", + "accuracy-MG07-1": "Are test results and derived actions documented?", + "accuracy-MG07-2": "Have boundary or failure conditions been defined?", + "accuracy-MG08-0": "Is accuracy metrics information updated and centralised, with access for all implicated actors?", + "accuracy-MG08-1": "Has a versioning or traceability system been implemented?", + "accuracy-MG08-2": "Is there a formal procedure to communicate updates?", + "accuracy-MG09-0": "Has the system's objective function been selected according to its intended purpose?", + "accuracy-MG09-1": "Have risks found in the risk analysis been considered and how system accuracy influences them?", + "accuracy-MG10-0": "Does the system have a mechanism (graphical interface, alarm, etc.) that allows the user to monitor accuracy status?", + "accuracy-MG10-1": "Is the mechanism's functioning appropriately documented?", + "accuracy-MG10-2": "Have users been trained to correctly interpret the information?", + "accuracy-MG11-0": "Does the system have a mechanism that stores all accuracies reported to the user in a history?", + "accuracy-MG11-1": "Can the accuracy history be queried by date, model version, or usage context?", + "accuracy-MG11-2": "Is the accuracy history used to improve the model or adjust the confidence threshold?", + "accuracy-MG12-0": "During the process of selecting accuracy metric(s) and objective function(s), have statistical significance tests been performed to justify the choices?", + "accuracy-MG12-1": "Are the test results documented?", + "accuracy-MG12-2": "Have minimum significance criteria been defined?", + "accuracy-MG13-0": "Have benchmarks been performed during the design process considering intended purpose in relation to the model or model family used?", + "accuracy-MG13-1": "Is the use of benchmarks justified, prioritising publicly recognised ones where pertinent?", + "accuracy-MG13-2": "For benchmarks against manual measures or historical data, is the internal benchmark justified and its significance explained?", + "accuracy-MG13-3": "Is it documented how comparisons were made and their results?", + "accuracy-MG14-0": "Do the system's user instructions include all pertinent accuracy levels and metrics?", + "accuracy-MG14-1": "Are metrics presented in an accessible and comprehensible format for non-technical users?", + "records-MG01-0": "Has a process been developed to analyse the needs motivating record generation and establish the information to be collected?", + "records-MG01-1": "Has a process been developed to evaluate the needs motivating record generation?", + "records-MG01-2": "Have the needs motivating record generation been adequately identified?", + "records-MG02-0": "Have the specific objectives of logging been identified?", + "records-MG02-1": "Has it been clearly identified what is expected to be achieved with its collection?", + "records-MG03-0": "Has the log scope been defined as the information to be recorded and the time during which said log will be maintained?", + "records-MG03-1": "Have retention and deletion periods been determined considering information disposition needs and applicable regulations such as GDPR?", + "records-MG03-2": "Have pre-existing special needs from financial sector-specific regulations been considered?", + "records-MG04-0": "Have the logs necessary to guarantee collection of information determined in the risk management system implementation process been generated?", + "records-MG04-1": "Have risk management system controls with associated evidence been considered for obtaining logs?", + "records-MG05-0": "Have the logs necessary to guarantee collection of information determined in the post-market surveillance system implementation process been generated?", + "records-MG05-1": "Have the frequencies for collecting these records been adequately documented and implemented?", + "records-MG06-0": "Have the logs necessary to guarantee collection of information determined for implementing human oversight mechanisms been generated?", + "records-MG06-1": "Has the need for these records and how to interpret their results for contribution to the human oversight process been adequately documented?", + "records-MG07-0": "Has a log capture process been implemented to guarantee information is collected according to criteria established in the design phase?", + "records-MG07-1": "Have tests been conducted to validate these procedures?", + "records-MG07-2": "Have stress tests been performed on the log capture system to guarantee functioning without incidents even during high demand?", + "records-MG08-0": "Have adequate storage media and protection materials been selected and implemented to guarantee log security and availability?", + "records-MG08-1": "Have storage media supervision and review periods been established?", + "records-MG09-0": "Have adequate cybersecurity measures been selected and implemented to guarantee log security and availability?", + "records-MG09-1": "Have cybersecurity and access control supervision and review periods been established?", + "records-MG10-0": "Are training and capacity-building processes developed for personnel involved in log management?", + "records-MG10-1": "Are these training needs contemplated in the Article 4 AI Literacy response?", + "records-MG11-0": "Has the impact of other applicable regulations or laws that could affect the log generation process been analysed and evaluated?", + "records-MG11-1": "Specifically, has the impact of data protection regulation (GDPR) on the log generation process been analysed and evaluated?", + "records-MG12-0": "Have supervision periods for storage media, cybersecurity measures, and access controls been established?", + "records-MG12-1": "Have review periods for storage media, cybersecurity measures, and access controls been established?", + "records-MG13-0": "Has a continuous monitoring and improvement process for the log management system been established?", + "records-MG13-1": "In the established process, are possible errors monitored and identified, and are recorded data evaluated for implementation and continuous improvement of proposed solutions?", + "records-MG14-0": "Has a process been defined and implemented that guarantees adequate technical documentation of the implemented log management system?", + "records-MG14-1": "Have logs been contemplated in documentation not only specifically about logs, but also in other documents where they appear collaterally (e.g., risk management, human oversight, post-market surveillance)?", + "records-MG15-0": "Does the system comply with Accuracy, Robustness, and Cybersecurity measures oriented to provide Transparency about its functioning?", + "records-MG16-0": "Does the system comply with Record-Keeping measures oriented to provide Transparency about its functioning?", + "robustness-MG01-0": "Has adequate training of personnel involved in development and implementation been ensured on key aspects of AI system robustness?", + "robustness-MG02-0": "Have robustness properties and metrics and the requirements they must meet been established according to intended purpose and risk analysis, with evidence?", + "robustness-MG03-0": "During system design, have recognised characteristics for measuring robustness been identified and their separability (possibility of being measured separately) identified?", + "robustness-MG04-0": "Do the different environments through which the system evolves in its lifecycle (development, integration, pre-production, production) have equivalent characteristics according to defined robustness objectives?", + "robustness-MG05-0": "Has verification and validation of chosen metrics been performed in hardware environments that exactly replicate the final capabilities the AI system will have access to?", + "robustness-MG06-0": "Have various robustness metrics related to performance (FLOPS, efficiency, FLOPY, Latency, etc.) been defined for the system on the hardware established for its functioning?", + "robustness-MG07-0": "Is there an experiment plan to demonstrate system robustness based on at least one of the following methods: statistical, formal, empirical, or practical tests?", + "robustness-MG08-0": "Is there evidence of said experiments performed, their analysis and interpretation, and their impact on AI system robustness parameters?", + "robustness-MG09-0": "Have procedures and technical measures been defined to monitor robustness, such as system interfaces showing selected robustness metrics in aggregate and historical views and operation records?", + "robustness-MG10-0": "Are there alert mechanisms when system robustness is not within established parameters?", + "robustness-MG11-0": "Have specific committees or teams been established to proactively evaluate inconsistencies or possible failures in system robustness?", + "robustness-MG12-0": "Are there automatic mechanisms designed and implemented to guarantee system recovery in case of failure?", + "robustness-MG13-0": "Have specific tools or procedures been implemented to guarantee geographic redundancy, adequate version management, and system scalability?", + "robustness-MG14-0": "For systems that continue learning, are all established metrics (including accuracy and cybersecurity) monitored to determine if the system remains within design parameters?", + "robustness-MG15-0": "Have monitoring and control plans been established, with action measures for model degradation based on model deviation, concept drift, data drift, etc.?", + "robustness-MG16-0": "Are interactions, interoperability, and feedback received during the lifecycle formally registered, especially in continuously learning systems, to ensure traceability and improve robustness?", + "oversight-MG01-0": "Does the AI system have an associated risk management system per Article 9?", + "oversight-MG01-1": "Does the system have an associated data governance model per Article 10?", + "oversight-MG01-2": "Does the system have Technical Documentation per Article 11?", + "oversight-MG01-3": "Does the system have Records management per Article 12?", + "oversight-MG01-4": "Does the system have Transparency mechanisms per Article 13?", + "oversight-MG01-5": "Does the system have Accuracy mechanisms per Article 15?", + "oversight-MG01-6": "Does the system have Robustness mechanisms per Article 15?", + "oversight-MG01-7": "Does the system have Cybersecurity mechanisms per Article 15?", + "oversight-MG02-0": "Does the system have an interface to manage its risk management system per Article 9?", + "oversight-MG02-1": "Does the system have an interface to manage its data governance model per Article 10?", + "oversight-MG02-2": "Does the system have an interface to manage its Technical Documentation?", + "oversight-MG02-3": "Does the system have an interface to manage Records information?", + "oversight-MG02-4": "Does the system have an interface to manage Transparency?", + "oversight-MG02-5": "Does the system have an interface to manage Accuracy?", + "oversight-MG02-6": "Does the system have an interface to manage Robustness?", + "oversight-MG02-7": "Does the system have an interface to manage Cybersecurity?", + "oversight-MG03-0": "Has a governance model been established that applies during construction and use, including at minimum an organisational structure, procedures, and training for its use?", + "oversight-MG03-1": "For remote biometric identification systems: Does the governance model include validation of identification separately by at least two natural persons with the necessary competence, training, and authority?", + "oversight-MG04-0": 'Does the system provide "forced error" functionality or equivalent to avoid automation bias?', + "oversight-MG05-0": "In the system's governance model, has the system's level of autonomy been contemplated, detailing the moment in the process at which the responsible person(s) intervene?", + "oversight-MG05-1": "Does the system have agile mechanisms for the responsible person to interrupt its functioning?", + "oversight-MG06-0": "Does the system have an associated risk management plan?", + "oversight-MG07-0": "Does the system have Transparency management mechanisms that allow its correct supervision?", + "oversight-MG08-0": "Does the system comply with Record-Keeping measures oriented to provide Transparency about its functioning?", + "transparency-MG01-0": "Is the system accompanied by a channel that enables online management of requests and incidents?", + "transparency-MG01-1": "Does the governance model have a clear provider contact point available to deployers?", + "transparency-MG02-0": "Does the system cover transparency-related requirements applicable to its supported use cases?", + "transparency-MG02-1": "Does the system provide detailed information about its functional scope, also specifying possible risks from unintended uses?", + "transparency-MG03-0": "Does the system provide information about foreseeable circumstances where it could be used for purposes other than intended?", + "transparency-MG03-1": "Is the system accompanied by a risk plan for such uses?", + "transparency-MG03-2": "Does the system have an associated procedure to supervise that such uses don't occur during operation?", + "transparency-MG04-0": "Does the system identify data sources used both for its learning and its utilisation, also providing the meaning, utility, and implication of using said sources and data?", + "transparency-MG04-1": "Is the system accompanied by tools that enable detailed exploratory data analysis (EDA) of said sources?", + "transparency-MG05-0": "Does the system provide technical mechanisms that facilitate understanding of its global reasoning mechanism?", + "transparency-MG05-1": "Does the system provide technical mechanisms that facilitate understanding of its actions on a subset of information with similar characteristics to guarantee functioning homogeneity?", + "transparency-MG05-2": "Does the system provide technical mechanisms that facilitate understanding of each individual action?", + "transparency-MG06-0": "Does the system provide mechanisms that facilitate understanding of its global reasoning in language understandable by all actors who interact with the system throughout its lifecycle?", + "transparency-MG06-1": "Does the system provide mechanisms that facilitate understanding of its actions on information subsets in understandable language?", + "transparency-MG06-2": "Does the system provide mechanisms that facilitate understanding of individual system actions in understandable language?", + "transparency-MG07-0": "Can the AI system's technical complexity be blocking for Transparency needs in any circumstance?", + "transparency-MG07-1": "For black-box models: Does the provider supply tools that enable Transparency about the system?", + "transparency-MG08-0": "Does the system provide metrics on data, the model, result quality, and AI system performance, specifying minimum acceptable values below which retraining or execution stoppage is necessary?", + "transparency-MG08-1": "Is the system accompanied by a continuous integration system (MLOps) that identifies how metric changes affect different versions/releases?", + "transparency-MG09-0": "Does the system have pertinent technical mechanisms to prevent it from providing sensitive information (confidential information, or information revealing relevant business process details that could risk its functioning)?", + "transparency-MG10-0": "Does the system provide tools that identify and analyse correlations, as well as explicitly undesired ones that could hinder system Transparency or impact its accuracy?", + "transparency-MG11-0": "Does the system provide technical mechanisms that enable obtaining counterfactuals to facilitate understanding?", + "transparency-MG12-0": "Is the system accompanied by a medium (web/wiki/doc page) that compiles information about it, oriented to facilitate Transparency about its functioning, accessible to persons with any level of responsibility over it?", + "transparency-MG13-0": "Does the system have an associated risk management plan?", + "transparency-MG14-0": "Does the system comply with Human Oversight measures?", + "transparency-MG15-0": "Does the system comply with Accuracy, Robustness, and Cybersecurity measures oriented to provide Transparency?", + "transparency-MG16-0": "Does the system comply with Record-Keeping measures oriented to provide Transparency?", + "surveillance-MG01-0": "Have all relevant risks associated with the production environment and system use been exhaustively identified and documented?", + "surveillance-MG01-1": "Does the surveillance system design integrate specific measures addressing each identified risk?", + "surveillance-MG02-0": "Have key indicators been defined that comprehensively cover critical aspects of the operational environment (intelligent system, infrastructure, cybersecurity, users)?", + "surveillance-MG02-1": "Is the selection of indicators based on relevance criteria and environment criticality, with due documented justification?", + "surveillance-MG02-2": "Has indicator efficacy and pertinence been validated in real or simulated scenario tests?", + "surveillance-MG03-0": "Have normality scales or acceptable value ranges been set for each indicator, based on historical analysis and expected scenarios?", + "surveillance-MG03-1": "Is the determination of these scales adequately justified and aligned with real operational conditions?", + "surveillance-MG03-2": "Is there a mechanism to periodically update scales based on environment evolution or new collected data?", + "surveillance-MG04-0": "Does the system incorporate a real-time alert mechanism that continuously monitors key indicators?", + "surveillance-MG04-1": "Have critical thresholds been configured that, when exceeded, trigger immediate alerts to responsible parties?", + "surveillance-MG04-2": "Have tests been performed in both simulated and real environments to guarantee reliability and speed of alert activation?", + "surveillance-MG05-0": "Has a controlled deployment process for the surveillance system in the production environment been planned and documented?", + "surveillance-MG05-1": "Has the surveillance system been deployed in production?", + "surveillance-MG06-0": "Have tests been executed in the production environment to validate the operability and robustness of the surveillance system?", + "surveillance-MG07-0": "Is there a formal policy that contemplates both continuous monitoring and periodic reviews of the surveillance system?", + "surveillance-MG07-1": "Are roles and responsibilities related to surveillance clearly defined and supported by management?", + "surveillance-MG07-2": "Is the policy reviewed and updated regularly to adapt to environmental changes or new risks?", + "surveillance-MG08-0": "Have possible anomalous scenarios that could compromise the surveillance system's performance been identified and documented?", + "surveillance-MG08-1": "Are there contingency plans and specific measures to manage each of these scenarios?", + "surveillance-MG09-0": "Has a leader or responsible for post-market surveillance management been designated with necessary authority?", + "surveillance-MG09-1": "Is senior management commitment reflected in resource allocation and internal communication?", + "surveillance-MG09-2": "Is there surveillance plan documentation that evidences leadership and coordination of surveillance activities?", + "surveillance-MG10-0": "Has a specific, duly trained team been formed to respond to alerts and incidents detected by the surveillance system?", + "surveillance-MG10-1": "Are the response team's roles and responsibilities clearly defined and communicated?", + "surveillance-MG11-0": "Is there a formal and documented response protocol detailing actions to follow upon incident detection?", + "surveillance-MG11-1": "Has the incident report template been generated?", + "surveillance-MG12-0": "Have training needs been identified for all personnel involved in post-market surveillance?", + "surveillance-MG12-1": "Are training exercises and response simulations conducted to evaluate effectiveness and improve team coordination?", + "surveillance-MG13-0": "Have regular periods been defined and documented for reviewing the functioning and effectiveness of the surveillance system?", + "undp-zero-question-ZQ-01-0": "Has it been assessed whether an AI-based solution is actually necessary, or whether non-algorithmic alternatives could achieve the same goal? (CRITICAL)", + "undp-zero-question-ZQ-02-0": "Has the rationale for choosing an AI-based approach over alternatives been documented?", + "undp-zero-question-ZQ-03-0": "Has a SWOT analysis (Strengths, Weaknesses, Opportunities, Threats) of the AI approach vs. alternatives been conducted?", + "undp-zero-question-ZQ-04-0": "Has it been confirmed that the AI solution does not pursue an objective that is inherently incompatible with fundamental rights?", + "undp-org-readiness-OR-01-0": "Does the organisation have a documented human rights policy covering AI design, development, and deployment?", + "undp-org-readiness-OR-02-0": "Does leadership actively support and resource human rights due diligence for AI initiatives?", + "undp-org-readiness-OR-03-0": "Do dedicated channels exist for employees to report potential human rights issues related to AI systems?", + "undp-org-readiness-OR-04-0": "Does the organisation regularly review and update policies to address emerging AI-related human rights issues?", + "undp-org-readiness-OR-06-0": "Does the organisation engage stakeholders (including affected communities) for input and feedback during the AI lifecycle?", + "undp-org-readiness-OR-07-0": "Does the organisation allocate sufficient resources for training, risk assessments, and stakeholder engagement?", + "undp-org-readiness-OR-08-0": "Does the organisation prioritise transparency and communication with the public about AI use?", + "undp-org-readiness-OR-09-0": "Does the management team have comprehensive understanding of human rights implications of AI?", + "undp-org-readiness-OR-10-0": "Do employees receive regular training on human rights and ethical considerations in AI?", + "undp-org-readiness-OR-11-0": "Are designated staff or teams responsible for monitoring and addressing human rights issues in AI projects?", + "undp-org-readiness-OR-13-0": "Are employees protected from retaliation when raising human rights concerns about AI?", + "undp-org-readiness-OR-14-0": "Does a process exist for incorporating stakeholder feedback into AI practices?", + "undp-org-readiness-OR-17-0": "Does the organisation participate in industry groups or forums on human rights and AI?", + "undp-org-readiness-OR-18-0": "Does the organisation regularly assess and address AI-related human rights skill gaps?", + "undp-org-readiness-OR-19-0": "Does a systematic human rights impact assessment process exist for all AI projects? (CRITICAL)", + "undp-org-readiness-OR-20-0": "Do procedures exist to evaluate human rights impacts of third-party AI systems integrated or utilised? (CRITICAL)", + "undp-org-readiness-OR-21-0": "Is a systematic risk identification process in place, including testing for reliability, accuracy, and resilience?", + "undp-org-readiness-OR-22-0": "Are stakeholders (including affected communities) engaged in the AI deployment process?", + "undp-org-readiness-OR-23-0": "Do all AI projects undergo human rights and data protection impact assessment before deployment? (CRITICAL)", + "undp-org-readiness-OR-24-0": "Are data security and privacy protocols established for all AI-related processes?", + "undp-org-readiness-OR-25-0": "Are processes regularly updated to incorporate new regulations and standards?", + "undp-org-readiness-OR-26-0": "Is an oversight process established to monitor AI system performance and compliance with human rights standards? (CRITICAL)", + "undp-org-readiness-OR-27-0": "Does the organisation have ability to mitigate and minimise negative effects from AI system failures?", + "undp-org-readiness-OR-28-0": "Is a redress mechanism in place for individuals adversely affected by AI systems? (CRITICAL)", + "undp-planning-PS-02-0": "Have the main technical characteristics of the system been documented (type of AI model, architecture)?", + "undp-planning-PS-03-0": "Have all countries/jurisdictions where the system will be deployed been identified?", + "undp-planning-PS-04-0": "Have all types of data processed (personal, non-personal, special categories) for training and operation been identified? (CRITICAL)", + "undp-planning-PS-05-0": "Have all data flows been mapped — from collection through processing to storage and deletion?", + "undp-planning-PS-06-0": "Have all individuals or groups potentially affected by the AI system been identified? (CRITICAL)", + "undp-planning-PS-07-0": "Has it been assessed whether affected groups include vulnerable individuals or groups (children, minorities, persons with disabilities, etc.)?", + "undp-planning-PS-08-0": "Have all duty-bearers been identified — who is involved in design, provision, and deployment, and what is their role? (CRITICAL)", + "undp-planning-PS-10-0": "Have existing policies and procedures for assessing human rights impacts (including stakeholder engagement) been documented?", + "undp-planning-PS-11-0": "Have any prior impact assessments been documented (e.g., Data Protection Impact Assessment, sector-specific assessments)?", + "undp-planning-PS-12-0": "Have all groups or communities potentially affected by the AI system (including during development) been identified? (CRITICAL)", + "undp-planning-PS-13-0": "Have all relevant stakeholders to involve been identified (civil society, international organisations, experts, industry associations, journalists)?", + "undp-planning-PS-14-0": "Have additional duty-bearers beyond the AI provider and deployer been identified (national authorities, government agencies)?", + "undp-planning-PS-15-0": "Has it been assessed whether business partners and suppliers (subcontractors of AI systems and datasets) have been involved in the assessment? (CRITICAL)", + "undp-planning-PS-16-0": "Has the AI provider conducted a supply chain assessment for potential human rights impacts from suppliers/contractors? (CRITICAL)", + "undp-planning-PS-17-0": "Has the AI provider promoted human rights standards or audits among suppliers?", + "undp-planning-PS-18-0": "Do the AI provider and developers publicly communicate potential human rights impacts of the AI system?", + "undp-planning-PS-19-0": "Do the AI provider and developers provide training on human rights standards to management and procurement staff?", + "undp-rights-mapping-HRM-01-0": "Have all human rights potentially affected by the AI system been identified, using the comprehensive rights checklist? (CRITICAL)", + "undp-rights-mapping-HRM-06-0": "Has the potential impact on freedom from inhuman/degrading treatment been assessed?", + "undp-rights-mapping-HRM-09-0": "Has the potential impact on freedom of thought, conscience, and religion been assessed?", + "undp-rights-mapping-HRM-13-0": "Has the potential impact on the right to freedom of association been assessed?", + "undp-rights-mapping-HRM-15-0": "Has the potential impact on the right to adequate standard of living (including health) been assessed?", + "undp-rights-mapping-HRM-18-0": "Has the potential impact on the right to take part in cultural, artistic, scientific life been assessed?", + "undp-rights-mapping-HRM-21-0": "Has the potential impact on the rights of religious, ethnic, or linguistic minorities been assessed?", + "undp-rights-mapping-HRM-24-0": "Has the potential impact on the right to recognition before the law been assessed?", + "undp-rights-mapping-HRM-25-0": "Has the potential impact on the right to equality before the law been assessed?", + "undp-rights-mapping-HRM-33-0": "Has the potential impact on the right to take part in public affairs been assessed?", + "undp-rights-mapping-HRM-34-0": "Have all applicable international/regional legal instruments for human rights protection in deployment jurisdictions been identified?", + "undp-rights-mapping-HRM-36-0": "Has the most relevant case law and legal provisions in the field of human rights been identified?", + "undp-data-diligence-DD-01-0": "Is the origin of primary training data documented (collected, purchased, scraped)? (CRITICAL)", + "undp-data-diligence-DD-03-0": "Have steps been taken to ensure data represents the diversity of the affected population (gender, race, age, disability, location)?", + "undp-data-diligence-DD-04-0": "Have known limitations or potential biases in the dataset been identified and documented?", + "undp-data-diligence-DD-05-0": "Is personal/sensitive data handled and protected appropriately throughout the lifecycle?", + "undp-data-diligence-DD-06-0": "Are data labelling processes documented, including potential sources of subjective bias?", + "undp-data-diligence-DD-07-0": "Is the specific goal/objective of the AI training documented (clarifies intended function vs. potential misuse)?", + "undp-data-diligence-DD-08-0": "Were fairness criteria/metrics used during training and evaluation (documented which ones)?", + "undp-data-diligence-DD-09-0": "Are known limitations, failure modes, and performance boundaries of the trained model documented?", + "undp-data-diligence-DD-10-0": "Is the type of AI model documented with rationale for selection (predictive, generative, etc.)?", + "undp-data-diligence-DD-12-0": "Are performance results available broken down by relevant subgroups (age, gender, race, ethnicity, disability)? (CRITICAL)", + "undp-data-diligence-DD-14-0": "Are features available for explaining specific AI decisions/outputs (explainability)? (CRITICAL)", + "undp-data-diligence-DD-17-0": "Does a process exist for addressing feedback, complaints, or identified problems? (CRITICAL)", + "undp-data-diligence-DD-18-0": "Has input testing been performed (edge cases — informal language, unusual names, extreme values)?", + "undp-data-diligence-DD-19-0": "Has bias probing been performed (identical prompts with different demographic personas)?", + "undp-data-diligence-DD-20-0": "Has functionality testing been performed (does the system reliably do what it claims)?", + "undp-data-diligence-DD-21-0": "Has an accessibility check been performed (screen reader compatibility, alternative input methods)?", + "undp-data-diligence-DD-22-0": "Has an output review been performed (checked for hallucinations, factual errors, biased/harmful content)?", + "undp-risk-analysis-RA-01-0": "Has the probability of adverse outcomes been assessed for each affected right (Low / Medium / High / Very High)?", + "undp-risk-analysis-RA-02-0": "Has exposure been assessed — the proportion of identified rights-holders potentially affected (Low / Medium / High / Very High)?", + "undp-risk-analysis-RA-03-0": "Has overall likelihood been calculated using the Probability x Exposure matrix?", + "undp-risk-analysis-RA-04-0": "Has gravity of prejudice been assessed — considering intensity, consequences, importance of the violated right, group-specific impact, and vulnerability (Low / Medium / High / Very High)?", + "undp-risk-analysis-RA-05-0": "Has the effort to overcome adverse effects been assessed — reversibility and difficulty of remedy (Low / Medium / High / Very High)?", + "undp-risk-analysis-RA-07-0": "Has the risk index been calculated for each affected right (Likelihood x Severity matrix)? (CRITICAL)", + "undp-risk-analysis-RA-08-0": "Has a radial graph or equivalent visualisation been created showing impact across all affected rights?", + "undp-risk-analysis-RA-09-0": "Has each right been assessed independently — no cumulative index combining impacts across rights?", + "undp-risk-analysis-RA-10-0": "Have factors that may exclude risk been evaluated (legal limitations justifying certain impacts)?", + "undp-risk-analysis-RA-11-0": "Has a balancing test been applied where conflicting rights exist (only after individual impact assessment)?", + "undp-risk-analysis-RA-12-0": "Have potential benefits been analysed in terms of enhancing or safeguarding other protected rights?", + "undp-risk-management-RMG-01-0": "Have specific measures been identified to prevent or mitigate each risk rated Medium, High, or Very High? (CRITICAL)", + "undp-risk-management-RMG-02-0": "Are measures contextualised to the specific AI system, its characteristics, and deployment context?", + "undp-risk-management-RMG-06-0": "After implementing mitigation measures, has residual risk been re-assessed for each affected right? (CRITICAL)", + "undp-risk-management-RMG-11-0": "If residual risk remains High or Very High, have additional measures or project redesign been considered?", + "undp-risk-management-RMG-12-0": "Is a complete record maintained of all risk assessment decisions, scoring rationales, and matrix choices? (CRITICAL)", + "undp-risk-management-RMG-15-0": "Are mitigation measures and their expected effectiveness documented?", + "undp-monitoring-MI-01-0": "Has a monitoring plan been established for post-deployment performance of the AI system? (CRITICAL)", + "undp-monitoring-MI-02-0": "Has a schedule been set for periodic re-assessment (circular iterative approach)?", + "undp-monitoring-MI-04-0": "Have feedback channels been established for affected individuals to report harm? (CRITICAL)", + "undp-monitoring-MI-05-0": "Is an effective remedy/redress mechanism operational for individuals adversely affected? (CRITICAL)", + "undp-monitoring-MI-06-0": "Have triggers been defined for when a full re-assessment is required (e.g., significant system update, change in deployment context, new regulatory requirements, reported incidents)?", + "undp-monitoring-MI-07-0": "Is there a process for incorporating new regulations and standards as they emerge?", + "undp-monitoring-MI-08-0": "Do the results of monitoring feed back into the risk assessment and mitigation cycle?", + "undp-framework-alignment-FA-01-0": "UNGPs Pillar I — Is there awareness of state obligations in jurisdictions of deployment?", + "undp-framework-alignment-FA-02-0": "UNGPs Pillar II — Has the organisation conducted human rights due diligence across the AI lifecycle?", + "undp-framework-alignment-FA-03-0": "UNGPs Pillar III — Are effective grievance mechanisms in place for affected individuals?", + "undp-framework-alignment-FA-04-0": "OECD — Does the AI system benefit society broadly and not exacerbate inequalities?", + "undp-framework-alignment-FA-05-0": "OECD — Has an assessment of potential discrimination and inequitable outcomes been completed?", + "undp-framework-alignment-FA-06-0": "OECD — Is there documentation of how the AI works, its limitations, and how it makes decisions?", + "undp-framework-alignment-FA-07-0": "OECD — Have failure modes, security vulnerabilities, and reliability been assessed?", + "undp-framework-alignment-FA-08-0": "OECD — Have clear responsibilities and oversight mechanisms been established?", + "undp-framework-alignment-FA-09-0": "Has the AI system risk classification been determined (Unacceptable / High / Limited / Minimal risk)? (CRITICAL)", + "undp-framework-alignment-FA-10-0": "If high-risk: Has a Fundamental Rights Impact Assessment (FRIA) been conducted as required under Article 27?", + "undp-framework-alignment-FA-12-0": "Have transparency obligations been met (users informed they are interacting with AI where applicable)?", + "undp-framework-alignment-FA-16-0": "Has the AI system been assessed for impact on human rights, democracy, and rule of law?", + "env-energy-carbon-EC-01-0": "Has the total energy consumption for model training been measured and documented (in kWh)?", + "env-energy-carbon-EC-01-1": "Is the energy source mix (renewable vs. fossil) for training infrastructure known and recorded?", + "env-energy-carbon-EC-02-0": "Is ongoing energy consumption during inference monitored and reported?", + "env-energy-carbon-EC-02-1": "Are energy-per-query or energy-per-request metrics tracked for production workloads?", + "env-energy-carbon-EC-03-0": "Has the carbon footprint of the AI system been estimated using a recognised methodology (e.g., GHG Protocol, ML CO₂ Impact)?", + "env-energy-carbon-EC-03-1": "Are Scope 1, 2, and 3 emissions considered in the carbon assessment?", + "env-energy-carbon-EC-04-0": "Are there documented targets for reducing the carbon footprint of the AI system over time?", + "env-energy-carbon-EC-04-1": "Is progress against carbon reduction targets reviewed at defined intervals?", + "env-energy-carbon-EC-05-0": "What percentage of energy consumed by the AI system comes from renewable sources?", + "env-energy-carbon-EC-05-1": "Are there commitments or plans to increase renewable energy usage for AI workloads?", + "env-energy-carbon-EC-06-0": "If carbon offsetting is used, are the offsets verified and from credible programmes?", + "env-hardware-HW-01-0": "Has the environmental impact of hardware choices (GPU/TPU type, server specifications) been considered during procurement?", + "env-hardware-HW-01-1": "Are energy-efficient hardware options prioritised where performance requirements allow?", + "env-hardware-HW-02-0": "Are hardware utilisation rates monitored to minimise idle resource consumption?", + "env-hardware-HW-02-1": "Are workload scheduling strategies (e.g., batch processing, off-peak scheduling) used to improve efficiency?", + "env-hardware-HW-03-0": "Are hardware refresh cycles planned to balance performance needs with environmental impact?", + "env-hardware-HW-03-1": "Is hardware reuse, refurbishment, or donation considered before disposal?", + "env-hardware-HW-04-0": "Is end-of-life hardware disposed of through certified e-waste recycling programmes?", + "env-hardware-HW-04-1": "Are hazardous materials in hardware components tracked and managed according to regulations?", + "env-hardware-HW-05-0": "Are hardware suppliers assessed for their environmental practices and sustainability commitments?", + "env-data-management-DM-01-0": "Are data storage practices optimised to minimise energy consumption (e.g., tiered storage, compression, deduplication)?", + "env-data-management-DM-01-1": "Is there a data retention policy that ensures unnecessary data is deleted to reduce storage footprint?", + "env-data-management-DM-02-0": "Are data transfer volumes minimised through edge processing, caching, or data locality strategies?", + "env-data-management-DM-02-1": "Is the environmental cost of large-scale data transfers (e.g., cross-region, cross-cloud) considered?", + "env-data-management-DM-03-0": "Are data centres selected based on environmental criteria such as PUE, water usage effectiveness, and renewable energy sourcing?", + "env-data-management-DM-03-1": "Is the geographical location of data centres chosen to optimise for cooler climates or renewable energy availability?", + "env-data-management-DM-04-0": "Is the water usage of cooling systems for AI workloads measured and documented?", + "env-data-management-DM-04-1": "Are water-efficient cooling technologies employed where feasible?", + "env-model-efficiency-ME-01-0": "Is the model size (parameter count) justified relative to the task requirements?", + "env-model-efficiency-ME-01-1": "Have smaller or more efficient model architectures been evaluated before selecting the final model?", + "env-model-efficiency-ME-02-0": "Are efficient training techniques used (e.g., transfer learning, mixed-precision training, early stopping)?", + "env-model-efficiency-ME-02-1": "Is the number of training runs and hyperparameter searches documented and justified?", + "env-model-efficiency-ME-03-0": "Are inference optimisation techniques applied (e.g., quantisation, pruning, distillation, caching)?", + "env-model-efficiency-ME-03-1": "Is the trade-off between model accuracy and computational cost explicitly evaluated?", + "env-model-efficiency-ME-04-0": "Is the retraining schedule justified based on performance degradation metrics rather than fixed intervals?", + "env-model-efficiency-ME-04-1": "Are incremental or fine-tuning approaches used instead of full retraining where possible?", + "env-model-efficiency-ME-05-0": "Are environmental efficiency metrics (e.g., accuracy-per-watt, throughput-per-kWh) tracked alongside performance metrics?", + "env-lifecycle-LC-01-0": "Has a lifecycle assessment been conducted covering the environmental impact from development through deployment to decommissioning?", + "env-lifecycle-LC-01-1": "Are embodied emissions from hardware manufacturing included in the lifecycle assessment?", + "env-lifecycle-LC-02-0": "Is there a documented plan for environmentally responsible decommissioning of the AI system and its infrastructure?", + "env-lifecycle-LC-02-1": "Does the decommissioning plan address data deletion, hardware disposal, and service wind-down?", + "env-lifecycle-LC-03-0": "Are cloud providers and third-party vendors assessed for their environmental commitments and reporting?", + "env-lifecycle-LC-03-1": "Do service-level agreements include environmental performance criteria?", + "env-lifecycle-LC-04-0": "Are circular economy principles (reuse, repair, recycle) applied to AI infrastructure and hardware?", + "env-monitoring-EM-01-0": "Are environmental key performance indicators (KPIs) defined for the AI system (e.g., energy per inference, total carbon, water usage)?", + "env-monitoring-EM-01-1": "Are KPIs reviewed and updated at regular intervals?", + "env-monitoring-EM-02-0": "Is environmental impact data reported to internal stakeholders and, where applicable, to external bodies?", + "env-monitoring-EM-02-1": "Does environmental reporting follow a recognised standard or framework (e.g., GRI, CDP, TCFD)?", + "env-monitoring-EM-03-0": "Is there a documented process for identifying and implementing environmental improvements based on monitoring data?", + "env-monitoring-EM-03-1": "Are lessons learned from environmental incidents or performance shortfalls systematically captured?", + "env-monitoring-EM-04-0": "Does the organisation track and comply with applicable environmental regulations related to AI and data centre operations?", + "env-monitoring-EM-05-0": "Are AI-specific environmental targets aligned with the organisation’s broader sustainability goals and commitments (e.g., net-zero pledges)?", +} + + +EVIDENCE_ORDER: dict[str, int] = { + "cybersecurity-CYB-01-0": 0, + "cybersecurity-CYB-01-1": 1, + "cybersecurity-CYB-02-0": 2, + "cybersecurity-CYB-02-1": 3, + "cybersecurity-CYB-03-0": 4, + "cybersecurity-CYB-04-0": 5, + "cybersecurity-CYB-05-0": 6, + "cybersecurity-CYB-06-0": 7, + "cybersecurity-CYB-07-0": 8, + "cybersecurity-CYB-08-0": 9, + "cybersecurity-CYB-09-0": 10, + "cybersecurity-CYB-10-0": 11, + "cybersecurity-CYB-11-0": 12, + "documentation-MG01-0": 13, + "documentation-MG01-1": 14, + "documentation-MG02-0": 15, + "documentation-MG02-1": 16, + "documentation-MG03-0": 17, + "documentation-MG03-1": 18, + "documentation-MG04-0": 19, + "documentation-MG04-1": 20, + "documentation-MG05-0": 21, + "documentation-MG05-1": 22, + "documentation-MG06-0": 23, + "documentation-MG06-1": 24, + "documentation-MG07-0": 25, + "documentation-MG07-1": 26, + "documentation-MG08-0": 27, + "documentation-MG08-1": 28, + "documentation-MG09-0": 29, + "documentation-MG09-1": 30, + "documentation-MG10-0": 31, + "documentation-MG10-1": 32, + "documentation-MG11-0": 33, + "documentation-MG11-1": 34, + "documentation-MG12-0": 35, + "documentation-MG12-1": 36, + "documentation-MG13-0": 37, + "documentation-MG13-1": 38, + "documentation-MG14-0": 39, + "documentation-MG14-1": 40, + "documentation-MG15-0": 41, + "documentation-MG15-1": 42, + "documentation-MG16-0": 43, + "documentation-MG16-1": 44, + "documentation-MG17-0": 45, + "documentation-MG17-1": 46, + "documentation-MG18-0": 47, + "documentation-MG18-1": 48, + "documentation-MG19-0": 49, + "documentation-MG20-0": 50, + "documentation-MG20-1": 51, + "documentation-MG21-0": 52, + "documentation-MG21-1": 53, + "documentation-MG22-0": 54, + "documentation-MG22-1": 55, + "documentation-MG23-0": 56, + "documentation-MG23-1": 57, + "documentation-MG24-0": 58, + "documentation-MG24-1": 59, + "documentation-MG25-0": 60, + "documentation-MG25-1": 61, + "documentation-MG26-0": 62, + "documentation-MG26-1": 63, + "documentation-MG27-0": 64, + "documentation-MG27-1": 65, + "documentation-MG28-0": 66, + "documentation-MG28-1": 67, + "documentation-MG29-0": 68, + "documentation-MG29-1": 69, + "documentation-MG30-0": 70, + "documentation-MG30-1": 71, + "documentation-MG31-0": 72, + "documentation-MG31-1": 73, + "documentation-MG32-0": 74, + "documentation-MG32-1": 75, + "documentation-MG33-0": 76, + "documentation-MG33-1": 77, + "documentation-MG34-0": 78, + "documentation-MG34-1": 79, + "documentation-MG35-0": 80, + "documentation-MG35-1": 81, + "documentation-MG36-0": 82, + "documentation-MG36-1": 83, + "documentation-MG37-0": 84, + "documentation-MG37-1": 85, + "documentation-MG38-0": 86, + "documentation-MG38-1": 87, + "documentation-MG39-0": 88, + "documentation-MG39-1": 89, + "documentation-MG40-0": 90, + "documentation-MG40-1": 91, + "documentation-MG41-0": 92, + "documentation-MG41-1": 93, + "documentation-MG42-0": 94, + "documentation-MG42-1": 95, + "documentation-MG43-0": 96, + "documentation-MG43-1": 97, + "documentation-MG44-0": 98, + "documentation-MG44-1": 99, + "documentation-MG45-0": 100, + "documentation-MG45-1": 101, + "qms-QMS-01-0": 102, + "qms-QMS-01-1": 103, + "qms-QMS-02-0": 104, + "qms-QMS-03-0": 105, + "qms-QMS-04-0": 106, + "qms-QMS-04-1": 107, + "qms-QMS-05-0": 108, + "qms-QMS-06-0": 109, + "qms-QMS-07-0": 110, + "qms-QMS-08-0": 111, + "qms-QMS-09-0": 112, + "qms-QMS-10-0": 113, + "qms-QMS-11-0": 114, + "qms-QMS-12-0": 115, + "qms-QMS-13-0": 116, + "qms-QMS-14-0": 117, + "qms-QMS-15-0": 118, + "qms-QMS-16-0": 119, + "incidents-M-INC-01-0": 120, + "incidents-M-INC-01-1": 121, + "incidents-M-INC-02-0": 122, + "incidents-M-INC-02-1": 123, + "incidents-M-INC-03-0": 124, + "incidents-M-INC-03-1": 125, + "incidents-M-INC-04-0": 126, + "incidents-M-INC-04-1": 127, + "incidents-M-INC-05-0": 128, + "incidents-M-INC-05-1": 129, + "risk-management-MG01-0": 130, + "risk-management-MG01-1": 131, + "risk-management-MG01-2": 132, + "risk-management-MG02-0": 133, + "risk-management-MG03-0": 134, + "risk-management-MG04-0": 135, + "risk-management-MG05-0": 136, + "risk-management-MG06-0": 137, + "risk-management-MG07-0": 138, + "risk-management-MG08-0": 139, + "risk-management-MG09-0": 140, + "risk-management-MG09-1": 141, + "risk-management-MG10-0": 142, + "risk-management-MG11-0": 143, + "risk-management-MG11-1": 144, + "risk-management-MG11-2": 145, + "risk-management-MG12-0": 146, + "risk-management-MG12-1": 147, + "risk-management-MG12-2": 148, + "risk-management-MG12-3": 149, + "risk-management-MG13-0": 150, + "risk-management-MG14-0": 151, + "risk-management-MG14-1": 152, + "risk-management-MG14-2": 153, + "data-governance-MG01-0": 154, + "data-governance-MG01-1": 155, + "data-governance-MG02-0": 156, + "data-governance-MG02-1": 157, + "data-governance-MG03-0": 158, + "data-governance-MG04-0": 159, + "data-governance-MG05-0": 160, + "data-governance-MG05-1": 161, + "data-governance-MG06-0": 162, + "data-governance-MG06-1": 163, + "data-governance-MG07-0": 164, + "data-governance-MG07-1": 165, + "data-governance-MG08-0": 166, + "data-governance-MG09-0": 167, + "data-governance-MG09-1": 168, + "data-governance-MG10-0": 169, + "data-governance-MG11-0": 170, + "data-governance-MG11-1": 171, + "data-governance-MG12-0": 172, + "data-governance-MG13-0": 173, + "data-governance-MG13-1": 174, + "data-governance-MG14-0": 175, + "data-governance-MG15-0": 176, + "data-governance-MG15-1": 177, + "data-governance-MG16-0": 178, + "data-governance-MG17-0": 179, + "data-governance-MG18-0": 180, + "data-governance-MG18-1": 181, + "data-governance-MG18-2": 182, + "data-governance-MG18-3": 183, + "data-governance-MG18-4": 184, + "data-governance-MG18-5": 185, + "accuracy-MG01-0": 186, + "accuracy-MG01-1": 187, + "accuracy-MG01-2": 188, + "accuracy-MG02-0": 189, + "accuracy-MG02-1": 190, + "accuracy-MG02-2": 191, + "accuracy-MG03-0": 192, + "accuracy-MG03-1": 193, + "accuracy-MG03-2": 194, + "accuracy-MG04-0": 195, + "accuracy-MG04-1": 196, + "accuracy-MG04-2": 197, + "accuracy-MG05-0": 198, + "accuracy-MG05-1": 199, + "accuracy-MG06-0": 200, + "accuracy-MG06-1": 201, + "accuracy-MG06-2": 202, + "accuracy-MG07-0": 203, + "accuracy-MG07-1": 204, + "accuracy-MG07-2": 205, + "accuracy-MG08-0": 206, + "accuracy-MG08-1": 207, + "accuracy-MG08-2": 208, + "accuracy-MG09-0": 209, + "accuracy-MG09-1": 210, + "accuracy-MG10-0": 211, + "accuracy-MG10-1": 212, + "accuracy-MG10-2": 213, + "accuracy-MG11-0": 214, + "accuracy-MG11-1": 215, + "accuracy-MG11-2": 216, + "accuracy-MG12-0": 217, + "accuracy-MG12-1": 218, + "accuracy-MG12-2": 219, + "accuracy-MG13-0": 220, + "accuracy-MG13-1": 221, + "accuracy-MG13-2": 222, + "accuracy-MG13-3": 223, + "accuracy-MG14-0": 224, + "accuracy-MG14-1": 225, + "records-MG01-0": 226, + "records-MG01-1": 227, + "records-MG01-2": 228, + "records-MG02-0": 229, + "records-MG02-1": 230, + "records-MG03-0": 231, + "records-MG03-1": 232, + "records-MG03-2": 233, + "records-MG04-0": 234, + "records-MG04-1": 235, + "records-MG05-0": 236, + "records-MG05-1": 237, + "records-MG06-0": 238, + "records-MG06-1": 239, + "records-MG07-0": 240, + "records-MG07-1": 241, + "records-MG07-2": 242, + "records-MG08-0": 243, + "records-MG08-1": 244, + "records-MG09-0": 245, + "records-MG09-1": 246, + "records-MG10-0": 247, + "records-MG10-1": 248, + "records-MG11-0": 249, + "records-MG11-1": 250, + "records-MG12-0": 251, + "records-MG12-1": 252, + "records-MG13-0": 253, + "records-MG13-1": 254, + "records-MG14-0": 255, + "records-MG14-1": 256, + "records-MG15-0": 257, + "records-MG16-0": 258, + "robustness-MG01-0": 259, + "robustness-MG02-0": 260, + "robustness-MG03-0": 261, + "robustness-MG04-0": 262, + "robustness-MG05-0": 263, + "robustness-MG06-0": 264, + "robustness-MG07-0": 265, + "robustness-MG08-0": 266, + "robustness-MG09-0": 267, + "robustness-MG10-0": 268, + "robustness-MG11-0": 269, + "robustness-MG12-0": 270, + "robustness-MG13-0": 271, + "robustness-MG14-0": 272, + "robustness-MG15-0": 273, + "robustness-MG16-0": 274, + "oversight-MG01-0": 275, + "oversight-MG01-1": 276, + "oversight-MG01-2": 277, + "oversight-MG01-3": 278, + "oversight-MG01-4": 279, + "oversight-MG01-5": 280, + "oversight-MG01-6": 281, + "oversight-MG01-7": 282, + "oversight-MG02-0": 283, + "oversight-MG02-1": 284, + "oversight-MG02-2": 285, + "oversight-MG02-3": 286, + "oversight-MG02-4": 287, + "oversight-MG02-5": 288, + "oversight-MG02-6": 289, + "oversight-MG02-7": 290, + "oversight-MG03-0": 291, + "oversight-MG03-1": 292, + "oversight-MG04-0": 293, + "oversight-MG05-0": 294, + "oversight-MG05-1": 295, + "oversight-MG06-0": 296, + "oversight-MG07-0": 297, + "oversight-MG08-0": 298, + "transparency-MG01-0": 299, + "transparency-MG01-1": 300, + "transparency-MG02-0": 301, + "transparency-MG02-1": 302, + "transparency-MG03-0": 303, + "transparency-MG03-1": 304, + "transparency-MG03-2": 305, + "transparency-MG04-0": 306, + "transparency-MG04-1": 307, + "transparency-MG05-0": 308, + "transparency-MG05-1": 309, + "transparency-MG05-2": 310, + "transparency-MG06-0": 311, + "transparency-MG06-1": 312, + "transparency-MG06-2": 313, + "transparency-MG07-0": 314, + "transparency-MG07-1": 315, + "transparency-MG08-0": 316, + "transparency-MG08-1": 317, + "transparency-MG09-0": 318, + "transparency-MG10-0": 319, + "transparency-MG11-0": 320, + "transparency-MG12-0": 321, + "transparency-MG13-0": 322, + "transparency-MG14-0": 323, + "transparency-MG15-0": 324, + "transparency-MG16-0": 325, + "surveillance-MG01-0": 326, + "surveillance-MG01-1": 327, + "surveillance-MG02-0": 328, + "surveillance-MG02-1": 329, + "surveillance-MG02-2": 330, + "surveillance-MG03-0": 331, + "surveillance-MG03-1": 332, + "surveillance-MG03-2": 333, + "surveillance-MG04-0": 334, + "surveillance-MG04-1": 335, + "surveillance-MG04-2": 336, + "surveillance-MG05-0": 337, + "surveillance-MG05-1": 338, + "surveillance-MG06-0": 339, + "surveillance-MG07-0": 340, + "surveillance-MG07-1": 341, + "surveillance-MG07-2": 342, + "surveillance-MG08-0": 343, + "surveillance-MG08-1": 344, + "surveillance-MG09-0": 345, + "surveillance-MG09-1": 346, + "surveillance-MG09-2": 347, + "surveillance-MG10-0": 348, + "surveillance-MG10-1": 349, + "surveillance-MG11-0": 350, + "surveillance-MG11-1": 351, + "surveillance-MG12-0": 352, + "surveillance-MG12-1": 353, + "surveillance-MG13-0": 354, + "undp-zero-question-ZQ-01-0": 355, + "undp-zero-question-ZQ-02-0": 356, + "undp-zero-question-ZQ-03-0": 357, + "undp-zero-question-ZQ-04-0": 358, + "undp-org-readiness-OR-01-0": 359, + "undp-org-readiness-OR-02-0": 360, + "undp-org-readiness-OR-03-0": 361, + "undp-org-readiness-OR-04-0": 362, + "undp-org-readiness-OR-06-0": 363, + "undp-org-readiness-OR-07-0": 364, + "undp-org-readiness-OR-08-0": 365, + "undp-org-readiness-OR-09-0": 366, + "undp-org-readiness-OR-10-0": 367, + "undp-org-readiness-OR-11-0": 368, + "undp-org-readiness-OR-13-0": 369, + "undp-org-readiness-OR-14-0": 370, + "undp-org-readiness-OR-17-0": 371, + "undp-org-readiness-OR-18-0": 372, + "undp-org-readiness-OR-19-0": 373, + "undp-org-readiness-OR-20-0": 374, + "undp-org-readiness-OR-21-0": 375, + "undp-org-readiness-OR-22-0": 376, + "undp-org-readiness-OR-23-0": 377, + "undp-org-readiness-OR-24-0": 378, + "undp-org-readiness-OR-25-0": 379, + "undp-org-readiness-OR-26-0": 380, + "undp-org-readiness-OR-27-0": 381, + "undp-org-readiness-OR-28-0": 382, + "undp-planning-PS-02-0": 383, + "undp-planning-PS-03-0": 384, + "undp-planning-PS-04-0": 385, + "undp-planning-PS-05-0": 386, + "undp-planning-PS-06-0": 387, + "undp-planning-PS-07-0": 388, + "undp-planning-PS-08-0": 389, + "undp-planning-PS-10-0": 390, + "undp-planning-PS-11-0": 391, + "undp-planning-PS-12-0": 392, + "undp-planning-PS-13-0": 393, + "undp-planning-PS-14-0": 394, + "undp-planning-PS-15-0": 395, + "undp-planning-PS-16-0": 396, + "undp-planning-PS-17-0": 397, + "undp-planning-PS-18-0": 398, + "undp-planning-PS-19-0": 399, + "undp-rights-mapping-HRM-01-0": 400, + "undp-rights-mapping-HRM-06-0": 401, + "undp-rights-mapping-HRM-09-0": 402, + "undp-rights-mapping-HRM-13-0": 403, + "undp-rights-mapping-HRM-15-0": 404, + "undp-rights-mapping-HRM-18-0": 405, + "undp-rights-mapping-HRM-21-0": 406, + "undp-rights-mapping-HRM-24-0": 407, + "undp-rights-mapping-HRM-25-0": 408, + "undp-rights-mapping-HRM-33-0": 409, + "undp-rights-mapping-HRM-34-0": 410, + "undp-rights-mapping-HRM-36-0": 411, + "undp-data-diligence-DD-01-0": 412, + "undp-data-diligence-DD-03-0": 413, + "undp-data-diligence-DD-04-0": 414, + "undp-data-diligence-DD-05-0": 415, + "undp-data-diligence-DD-06-0": 416, + "undp-data-diligence-DD-07-0": 417, + "undp-data-diligence-DD-08-0": 418, + "undp-data-diligence-DD-09-0": 419, + "undp-data-diligence-DD-10-0": 420, + "undp-data-diligence-DD-12-0": 421, + "undp-data-diligence-DD-14-0": 422, + "undp-data-diligence-DD-17-0": 423, + "undp-data-diligence-DD-18-0": 424, + "undp-data-diligence-DD-19-0": 425, + "undp-data-diligence-DD-20-0": 426, + "undp-data-diligence-DD-21-0": 427, + "undp-data-diligence-DD-22-0": 428, + "undp-risk-analysis-RA-01-0": 429, + "undp-risk-analysis-RA-02-0": 430, + "undp-risk-analysis-RA-03-0": 431, + "undp-risk-analysis-RA-04-0": 432, + "undp-risk-analysis-RA-05-0": 433, + "undp-risk-analysis-RA-07-0": 434, + "undp-risk-analysis-RA-08-0": 435, + "undp-risk-analysis-RA-09-0": 436, + "undp-risk-analysis-RA-10-0": 437, + "undp-risk-analysis-RA-11-0": 438, + "undp-risk-analysis-RA-12-0": 439, + "undp-risk-management-RMG-01-0": 440, + "undp-risk-management-RMG-02-0": 441, + "undp-risk-management-RMG-06-0": 442, + "undp-risk-management-RMG-11-0": 443, + "undp-risk-management-RMG-12-0": 444, + "undp-risk-management-RMG-15-0": 445, + "undp-monitoring-MI-01-0": 446, + "undp-monitoring-MI-02-0": 447, + "undp-monitoring-MI-04-0": 448, + "undp-monitoring-MI-05-0": 449, + "undp-monitoring-MI-06-0": 450, + "undp-monitoring-MI-07-0": 451, + "undp-monitoring-MI-08-0": 452, + "undp-framework-alignment-FA-01-0": 453, + "undp-framework-alignment-FA-02-0": 454, + "undp-framework-alignment-FA-03-0": 455, + "undp-framework-alignment-FA-04-0": 456, + "undp-framework-alignment-FA-05-0": 457, + "undp-framework-alignment-FA-06-0": 458, + "undp-framework-alignment-FA-07-0": 459, + "undp-framework-alignment-FA-08-0": 460, + "undp-framework-alignment-FA-09-0": 461, + "undp-framework-alignment-FA-10-0": 462, + "undp-framework-alignment-FA-12-0": 463, + "undp-framework-alignment-FA-16-0": 464, + "env-energy-carbon-EC-01-0": 465, + "env-energy-carbon-EC-01-1": 466, + "env-energy-carbon-EC-02-0": 467, + "env-energy-carbon-EC-02-1": 468, + "env-energy-carbon-EC-03-0": 469, + "env-energy-carbon-EC-03-1": 470, + "env-energy-carbon-EC-04-0": 471, + "env-energy-carbon-EC-04-1": 472, + "env-energy-carbon-EC-05-0": 473, + "env-energy-carbon-EC-05-1": 474, + "env-energy-carbon-EC-06-0": 475, + "env-hardware-HW-01-0": 476, + "env-hardware-HW-01-1": 477, + "env-hardware-HW-02-0": 478, + "env-hardware-HW-02-1": 479, + "env-hardware-HW-03-0": 480, + "env-hardware-HW-03-1": 481, + "env-hardware-HW-04-0": 482, + "env-hardware-HW-04-1": 483, + "env-hardware-HW-05-0": 484, + "env-data-management-DM-01-0": 485, + "env-data-management-DM-01-1": 486, + "env-data-management-DM-02-0": 487, + "env-data-management-DM-02-1": 488, + "env-data-management-DM-03-0": 489, + "env-data-management-DM-03-1": 490, + "env-data-management-DM-04-0": 491, + "env-data-management-DM-04-1": 492, + "env-model-efficiency-ME-01-0": 493, + "env-model-efficiency-ME-01-1": 494, + "env-model-efficiency-ME-02-0": 495, + "env-model-efficiency-ME-02-1": 496, + "env-model-efficiency-ME-03-0": 497, + "env-model-efficiency-ME-03-1": 498, + "env-model-efficiency-ME-04-0": 499, + "env-model-efficiency-ME-04-1": 500, + "env-model-efficiency-ME-05-0": 501, + "env-lifecycle-LC-01-0": 502, + "env-lifecycle-LC-01-1": 503, + "env-lifecycle-LC-02-0": 504, + "env-lifecycle-LC-02-1": 505, + "env-lifecycle-LC-03-0": 506, + "env-lifecycle-LC-03-1": 507, + "env-lifecycle-LC-04-0": 508, + "env-monitoring-EM-01-0": 509, + "env-monitoring-EM-01-1": 510, + "env-monitoring-EM-02-0": 511, + "env-monitoring-EM-02-1": 512, + "env-monitoring-EM-03-0": 513, + "env-monitoring-EM-03-1": 514, + "env-monitoring-EM-04-0": 515, + "env-monitoring-EM-05-0": 516, +} diff --git a/backend/app/data/knowledge/undp_human_rights_assessment/01_summary.md b/backend/app/data/knowledge/undp_human_rights_assessment/01_summary.md new file mode 100644 index 0000000..f138186 --- /dev/null +++ b/backend/app/data/knowledge/undp_human_rights_assessment/01_summary.md @@ -0,0 +1,179 @@ +# UNDP AI Human Rights Impact Assessment (HRIA) Toolkit — In-Depth Summary + +**Document:** *Human Rights Impact of AI Assessment Toolkit* +**Publisher:** United Nations Development Programme (UNDP), Istanbul Regional Hub +**Date:** December 2025 (initial release) +**Scope:** International — with particular focus on Eastern Europe, Caucasus, Central Asia, and Western Balkans + +## 1. Purpose and Context + +The toolkit was created to address a critical gap: the rapid adoption of AI across governments and businesses is outpacing the development of human rights safeguards. Across the regions covered, governments are deploying AI for e-government, legal automation, "Smart City" surveillance, and predictive policing — often without adequate legal frameworks. The toolkit provides a **structured, practical methodology** for any organisation to proactively identify, assess, and mitigate the human rights risks of AI systems throughout their entire lifecycle, from design to deployment and ongoing monitoring. + +It is grounded in international human rights law standards, including: +- **UN Guiding Principles on Business and Human Rights (UNGPs)** — the three pillars of Protect, Respect, and Remedy +- **OECD AI Principles** — inclusive growth, human-centred values, transparency, robustness, accountability +- **EU AI Act** — the risk-based regulatory framework for AI systems +- **Council of Europe Framework Convention on AI and Human Rights** (May 2024) + +## 2. Target Audience + +The toolkit is specifically designed for **non-technical stakeholders** who need to engage with AI systems but lack deep technical knowledge: +- Human rights experts +- Policymakers +- Corporate compliance officers +- National Human Rights Institution (NHRI) staff +- Project managers and developers involved in AI projects +- Civil society organisations + +## 3. Three-Part Structure + +### Part 1: Technical Manual for AI Human Rights Impact Assessment + +**Purpose:** Demystify AI for human rights practitioners by explaining core concepts in accessible terms and identifying where human rights risks emerge. + +**Key content areas:** + +**Section 2 — Core AI Concepts:** Explains AI, Machine Learning, Neural Networks/Deep Learning, Generative AI, and Predictive Analytics. Each is paired with human rights risk examples (e.g., credit scoring perpetuating bias, facial recognition misidentifying people of colour, deepfakes spreading disinformation). + +**Section 3 — The AI Lifecycle ("Plumbing"):** Maps human rights risks at each stage: +- **Data Collection:** Risks of non-representative data leading to discrimination; privacy violations from scraping without consent; GDPR Article 7 implications +- **Data Preparation:** Bias amplification through subjective labelling; historically biased labels reinforcing systemic discrimination +- **Data Management:** Insecure pipelines risking data breaches; lack of documentation hindering oversight +- **Model Training:** Training process encoding historical discrimination into model logic; resource concentration limiting AI development to large entities; overfitting leading to unreliable real-world performance +- **Model Evaluation:** Overall accuracy masking poor performance for specific subgroups (e.g., facial recognition 99% accurate overall but failing for women of colour); need for disaggregated fairness metrics +- **Deployment & Monitoring:** Contextual harms from inappropriate deployment; automation bias from humans uncritically accepting AI outputs; need for meaningful human oversight and right to remedy; model drift causing harm over time +- **Transparency & Documentation:** Need for explainable AI (XAI); Model Cards for standardised documentation; accountability requires clear records of data sources, design choices, and evaluation results + +**Section 4 — Preliminary Technical Probing (Pre-HRIA):** Provides practical, no-coding-required techniques for initial assessment: +- **Key questions for developers/vendors** organised by: Data, Training, Model & Performance, Transparency & Deployment +- **Probing techniques:** Input testing (edge cases), bias probing (identical prompts with different demographic personas), functionality testing, accessibility checks, output review (hallucinations, biased content) +- **Four scenario-based applications:** AI grading systems, corporate LLM chatbot procurement, public citizen enquiry AI, AI hiring tools + +**Case Study — Dutch SyRI System:** Detailed analysis of the Dutch welfare fraud prediction system that was struck down by the Hague District Court in February 2020 for violating: +1. Right to privacy (ECHR Article 8) — mass, indiscriminate linking of personal data +2. Transparency and due process — secret algorithm, citizens could not know why they were flagged +3. Discrimination — exclusively deployed in low-income, immigrant-heavy neighbourhoods + +The case study demonstrates how applying the toolkit's framework could have identified these violations before judicial intervention. + +**Section 5 — Alignment with International Frameworks:** Maps the HRIA methodology to UNGPs (three pillars), OECD AI Principles (five principles), and the EU AI Act (risk-based approach with mandatory FRIA for high-risk systems). + +### Part 2: Readiness Assessment + +**Purpose:** A structured self-evaluation questionnaire enabling organisations to assess their capacity and preparedness for conducting HRIAs of AI systems. + +**Scoring system:** 1-5 scale per question: +- 1 = Initial Stage (limited awareness/informal approaches) +- 2 = Developing Stage (basic practices, not formalised) +- 3 = Established Stage (formal practices, may not be comprehensive) +- 4 = Advanced Stage (comprehensive practices, regular implementation) +- 5 = Leading Stage (exemplary practices, continuous improvement) + +**Three assessment dimensions (10 questions each):** + +**Policy & Culture:** Covers whether the organisation prioritises human rights in AI projects, has documented policies, leadership support, open environment for reporting concerns, stakeholder engagement, and transparency. + +**People & Expertise:** Covers management understanding, employee training, designated staff/teams, external collaboration, whistleblower protection, feedback processes, legal expertise, resources, industry participation, and skills gap assessment. + +**Processes Assessment:** Covers AI strategy, third-party AI assessment procedures, systematic risk identification, stakeholder engagement in deployment, pre-deployment HRIA/DPIA, data security protocols, regulatory updates, oversight processes, failure mitigation, and redress mechanisms. + +**Score interpretation:** +- 1.0–1.9: Initial Stage — urgent action needed +- 2.0–2.9: Developing Stage — basic practices need formalisation +- 3.0–3.9: Established Stage — strengthen comprehensiveness +- 4.0–4.9: Advanced Stage — maintain and refine +- 5.0: Leading Stage — exemplary, focus on continuous improvement + +**Recommendations triggered by scores below 3.5** in any dimension, with urgent recommendations if overall score is below 2.5. + +### Part 3: AI Human Rights Impact Assessment Model + +**Purpose:** Provide a comprehensive, expert-based methodology and model template for conducting systematic HRIAs of AI systems. + +**Key design principles:** +- **Ex ante approach** — assess before deployment, not after harm occurs; adopt a "by-design" approach +- **Rights-based focus on risk assessment** — human rights are not traded off against economic benefits; they hold a prominent role, with restrictions justified only by equally relevant competing interests +- **Circular iterative structure** — aligned with ISO 31000 risk management; planning/scoping, risk analysis, risk treatment, monitoring phases repeat as conditions change +- **Expert-based** — requires multidisciplinary expertise combining human rights law, AI design, and contextual societal understanding +- **Context-specific** — cannot be fully automated; parameters must be adapted to the specific AI system, its use, and deployment context + +**The "zero question":** Before any assessment, ask whether an AI-based solution is even necessary — could the same goal be achieved through non-algorithmic alternatives? + +**Phase 1 — Planning & Scoping (Awareness-Raising Questionnaire):** +Structured around four sections: +- **Section A:** Description and analysis of the AI system (purpose, characteristics, deployment countries, data types, rights-holders, duty-bearers) +- **Section B:** Human rights context — identification of potentially affected rights, applicable legal instruments, relevant courts/bodies, key case law. Includes a comprehensive checklist of rights across categories: Dignity/Personality/Autonomy, Economic/Social/Cultural, Vulnerable Groups, Justice, Political +- **Section C:** Controls already in place (existing policies, prior impact assessments) +- **Section D:** Stakeholder engagement and Human Rights Due Diligence (affected communities, civil society, experts, supply chain assessment, public communication, training) + +**Phase 2 — Data Collection and Risk Analysis (Assessment Tool):** +Risk quantification follows four steps: +1. **Analysis of the level of impact** on potentially affected rights +2. **Identification of appropriate measures** to prevent/mitigate risk +3. **Implementation** of such measures +4. **Monitoring** to revise assessment as conditions change + +**Risk measurement methodology:** +- **Likelihood** = Probability of adverse outcomes x Exposure (proportion of rights-holders affected) +- **Severity** = Gravity of prejudice (intensity, consequences, importance of the right, group-specific impacts, vulnerability) x Effort to overcome/reverse adverse effects +- Both dimensions assessed using **4x4 qualitative risk matrices** (Low, Medium, High, Very High) +- **Overall risk index** per right = Likelihood x Severity, visualised via radial graphs + +**Key methodological guidelines from best practices analysis:** +- Use common risk management circular approach +- Avoid cumulative assessment of impacts on different rights (assess each right independently) +- Avoid splitting impacted rights into different components (prevents double-counting) +- Use transparent, consistent scoring with ordinal variables +- Use matrices with clear, justified scaling criteria +- Relationship between risk components must be consistent with fundamental rights framework +- Consider the **balancing test** for conflicting rights and potential benefits only after individual impact assessment + +**Factors that may exclude risk:** Legal limitations on certain rights (e.g., mandatory data processing characteristics) that justify certain impacts as acceptable. + +**Phase 3 — Risk Management:** +- Measures must prevent or mitigate any risk to fundamental rights +- Further rounds of assessment conducted on **residual risk** after mitigation measures +- Mitigation measures are context-dependent and cannot be provided as a generic list + +**Case Study — Medical AI for Cancer Treatment Prediction:** +A fully worked example applying the entire HRIA model to an AI system predicting chemotherapy treatment response using medical images. Demonstrates: +- Planning & scoping (system description, data flows, rights-holders, stakeholders) +- Risk analysis for three rights: data protection/privacy, non-discrimination, right to physical and mental health +- Risk matrices showing how likelihood and severity combine +- Risk management measures (expanding training datasets, informing professionals of limitations) +- Residual risk assessment after mitigation + +## 4. Annex I — Potential Impacts of AI on Human Rights + +Comprehensive reference table mapping 20+ internationally recognised human rights to concrete examples of AI impacts, including: +- **Self-determination:** Political manipulation, nudging, exploitative data collection +- **Right to life:** Autonomous weapons, fatal product defects, border control +- **Freedom from torture:** AI optimising interrogation schedules +- **Liberty and security:** Voice simulation for fraud +- **Freedom of movement:** Border control, smart mobility surveillance +- **Due process:** Algorithmic expulsion assessments +- **Fair trial:** AI in judicial decision-making, predictive policing +- **Privacy:** Emotion detection, mass surveillance, data collection without legal basis +- **Freedom of thought/conscience:** Content moderation, child-interacting AI +- **Freedom of expression:** Content moderation, disinformation +- **Freedom from propaganda/hatred:** Online propaganda amplification +- **Freedom of assembly:** Facial recognition at protests +- **Freedom of association:** Social media surveillance +- **Child protection:** AI in recommendation systems, CSAM generation +- **Public participation:** Surveillance chilling political participation, e-voting AI +- **Non-discrimination:** Biometric identification bias, hiring algorithms, credit scoring +- **Minorities' rights:** LLM underrepresentation and stereotyping +- **Right to work:** AI recruitment, task allocation, performance monitoring +- **Social security:** Eligibility evaluation biases +- **Right to health:** Diagnostic tools, triage systems +- **Right to education:** AI-based admissions and performance prediction +- **Cultural/IP rights:** Training on copyrighted material, generative AI infringement + +## 5. Key Takeaways + +1. HRIA for AI is **not optional** — it is increasingly mandated by law (EU AI Act, Council of Europe Framework Convention) and expected by international standards (UNGPs, OECD) +2. The assessment must be **conducted before deployment** (ex ante), not reactively after harm +3. It requires **expert-led, multidisciplinary analysis** — not a checkbox exercise +4. The process is **circular and iterative** — reassessment is required as technology, context, and regulations evolve +5. Each right must be assessed **independently** — no cumulative indices that trade off one right against another +6. The toolkit is designed as a **living document** that will be updated as the field develops diff --git a/backend/app/schemas/framework.py b/backend/app/schemas/framework.py index a3a65c3..dd130b9 100644 --- a/backend/app/schemas/framework.py +++ b/backend/app/schemas/framework.py @@ -12,5 +12,6 @@ class FrameworkResponse(BaseModel): description: str category: str status: str + content: str document_count: int created_at: datetime diff --git a/frontend/nginx.conf b/frontend/nginx.conf index 87f465d..11fa6e2 100644 --- a/frontend/nginx.conf +++ b/frontend/nginx.conf @@ -11,6 +11,7 @@ server { resolver 127.0.0.11 valid=30s; set $backend http://backend:8000; proxy_pass $backend; + client_max_body_size 50m; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; diff --git a/frontend/src/components/app-sidebar.tsx b/frontend/src/components/app-sidebar.tsx index 6a69133..ee4456a 100644 --- a/frontend/src/components/app-sidebar.tsx +++ b/frontend/src/components/app-sidebar.tsx @@ -315,10 +315,10 @@ export function AppSidebar() { navigate('/github')} - tooltip={t('sidebar.github')} + tooltip={t('sidebar.githubPage')} > - {t('sidebar.github')} + {t('sidebar.githubPage')} diff --git a/frontend/src/components/debug-context-dialog.tsx b/frontend/src/components/debug-context-dialog.tsx new file mode 100644 index 0000000..7b51781 --- /dev/null +++ b/frontend/src/components/debug-context-dialog.tsx @@ -0,0 +1,99 @@ +import { useCallback, useEffect, useState } from 'react'; +import Markdown from 'react-markdown'; +import { Bug, Loader2 } from 'lucide-react'; +import { Button } from '@/components/ui/button'; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogTrigger, +} from '@/components/ui/dialog'; +import { ScrollArea } from '@/components/ui/scroll-area'; +import { useDebug } from '@/hooks/use-debug'; +import { useProject } from '@/hooks/use-project'; +import { api } from '@/lib/api'; + +interface DebugContextDialogProps { + section?: string; + refreshKey?: string | number; +} + +export function DebugContextDialog({ section = 'full', refreshKey }: DebugContextDialogProps) { + const debug = useDebug(); + const { currentProject } = useProject(); + const [open, setOpen] = useState(false); + const [context, setContext] = useState(null); + const [loading, setLoading] = useState(false); + + const fetchContext = useCallback(async () => { + if (!currentProject || !section) { + setContext(null); + return; + } + setLoading(true); + try { + const data = await api.get<{ context: string | null }>( + `/chat/context?project_id=${currentProject.id}§ion=${section}`, + ); + setContext(data.context); + } catch { + setContext('Failed to load context.'); + } finally { + setLoading(false); + } + }, [currentProject, section]); + + useEffect(() => { + if (open) fetchContext(); + }, [open, fetchContext, refreshKey]); + + const wordCount = context ? context.split(/\s+/).filter(Boolean).length : 0; + const pageEstimate = Math.ceil(wordCount / 250); + + if (!debug) return null; + + return ( + + + } + > + + Debug + + + + + Norma Context Debug + {context && !loading && ( + + {wordCount.toLocaleString()} words · ~{pageEstimate}{' '} + {pageEstimate === 1 ? 'page' : 'pages'} + + )} + + + + {loading ? ( +
+ +
+ ) : context ? ( +
+ {context} +
+ ) : ( +

+ This page does not contribute to Norma's context. +

+ )} +
+
+
+ ); +} diff --git a/frontend/src/components/page-header.tsx b/frontend/src/components/page-header.tsx index aab235f..8f75cb1 100644 --- a/frontend/src/components/page-header.tsx +++ b/frontend/src/components/page-header.tsx @@ -1,16 +1,22 @@ import { SidebarTrigger } from '@/components/ui/sidebar'; +import { DebugContextDialog } from '@/components/debug-context-dialog'; interface PageHeaderProps { title: string; children?: React.ReactNode; + debugSection?: string; + debugRefreshKey?: string | number; } -export function PageHeader({ title, children }: PageHeaderProps) { +export function PageHeader({ title, children, debugSection, debugRefreshKey }: PageHeaderProps) { return (

{title}

- {children &&
{children}
} +
+ {children} + +
); } diff --git a/frontend/src/hooks/use-debug.ts b/frontend/src/hooks/use-debug.ts new file mode 100644 index 0000000..c9627ab --- /dev/null +++ b/frontend/src/hooks/use-debug.ts @@ -0,0 +1,22 @@ +import { useEffect, useState } from 'react'; + +let cachedDebug: boolean | null = null; + +export function useDebug() { + const [debug, setDebug] = useState(cachedDebug ?? false); + + useEffect(() => { + if (cachedDebug !== null) return; + fetch('/api/health') + .then((r) => r.json()) + .then((data) => { + cachedDebug = data.debug ?? false; + setDebug(cachedDebug as boolean); + }) + .catch(() => { + cachedDebug = false; + }); + }, []); + + return debug; +} diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts index 0d71c2e..e3bba86 100644 --- a/frontend/src/lib/api.ts +++ b/frontend/src/lib/api.ts @@ -37,6 +37,7 @@ export interface Framework { description: string; category: string; status: 'active' | 'draft' | 'inactive'; + content: string; document_count: number; created_at: string; } @@ -167,6 +168,7 @@ async function apiFetch(path: string, options?: RequestInit): Promise { throw new Error(message); } + if (res.status === 204) return undefined as T; return res.json(); } diff --git a/frontend/src/locales/de/common.json b/frontend/src/locales/de/common.json index c160219..07e8edb 100644 --- a/frontend/src/locales/de/common.json +++ b/frontend/src/locales/de/common.json @@ -50,7 +50,7 @@ "general": "Allgemein", "project": "Projekt", "configuration": "Konfiguration", - "github": "GitHub" + "github": "Codebase" }, "risk": { "unacceptable": "Unannehmbares Risiko", diff --git a/frontend/src/locales/de/components.json b/frontend/src/locales/de/components.json index a564e31..2d5bd2b 100644 --- a/frontend/src/locales/de/components.json +++ b/frontend/src/locales/de/components.json @@ -10,7 +10,8 @@ "reporting": "Berichterstattung", "integrations": "Integrationen", "frameworks": "Frameworks", - "github": "GitHub", + "github": "Codebase", + "githubPage": "GitHub", "overview": "Übersicht", "riskClassification": "Risikoklassifizierung", "additionalDocuments": "Zusätzliche Dokumente" diff --git a/frontend/src/locales/de/pages.json b/frontend/src/locales/de/pages.json index aed4d49..a6bb6f2 100644 --- a/frontend/src/locales/de/pages.json +++ b/frontend/src/locales/de/pages.json @@ -59,7 +59,8 @@ "additional": "Zusätzliche", "uploadedCount": "{{count}} von {{total}} hochgeladen", "noAdditionalDocs": "Noch keine zusätzlichen Dokumente hochgeladen. Laden Sie ein beliebiges PDF hoch, um es in Ihren Projektkontext aufzunehmen.", - "deleteDocument": "Dokument löschen" + "deleteDocument": "Dokument löschen", + "noSummaryAvailable": "Dieses Dokument wurde noch nicht verarbeitet. Die Zusammenfassung wird hier angezeigt, sobald die Verarbeitung abgeschlossen ist." }, "reporting": { "title": "Berichterstattung", @@ -101,6 +102,7 @@ "githubDesc": "Verbinden Sie ein GitHub-Repository, um Aufgaben zu synchronisieren und die Architektur zu analysieren." }, "frameworks": { - "title": "Frameworks" + "title": "Frameworks", + "noContent": "Der Inhalt dieses Frameworks wurde noch nicht geladen. Der Fragebogen und die Berichtsabschnitte sind über die Seiten zur Risikoklassifizierung und Berichterstattung verfügbar." } } diff --git a/frontend/src/locales/en/common.json b/frontend/src/locales/en/common.json index 65f7a6e..d47e540 100644 --- a/frontend/src/locales/en/common.json +++ b/frontend/src/locales/en/common.json @@ -50,7 +50,7 @@ "general": "General", "project": "Project", "configuration": "Configuration", - "github": "GitHub" + "github": "Codebase" }, "risk": { "unacceptable": "Unacceptable Risk", diff --git a/frontend/src/locales/en/components.json b/frontend/src/locales/en/components.json index 1a3bdc4..b2afd60 100644 --- a/frontend/src/locales/en/components.json +++ b/frontend/src/locales/en/components.json @@ -10,7 +10,8 @@ "reporting": "Reporting", "integrations": "Integrations", "frameworks": "Frameworks", - "github": "GitHub", + "github": "Codebase", + "githubPage": "GitHub", "overview": "Overview", "riskClassification": "Risk Classification", "additionalDocuments": "Additional Documents" diff --git a/frontend/src/locales/en/pages.json b/frontend/src/locales/en/pages.json index 5b72a61..b9187b1 100644 --- a/frontend/src/locales/en/pages.json +++ b/frontend/src/locales/en/pages.json @@ -59,7 +59,8 @@ "additional": "Additional", "uploadedCount": "{{count}} of {{total}} uploaded", "noAdditionalDocs": "No additional documents uploaded yet. Upload any PDF to include it in your project context.", - "deleteDocument": "Delete document" + "deleteDocument": "Delete document", + "noSummaryAvailable": "This document has not been processed yet. The summary will appear here once processing is complete." }, "reporting": { "title": "Reporting", @@ -101,6 +102,7 @@ "githubDesc": "Connect a GitHub repository to sync tasks and analyse architecture." }, "frameworks": { - "title": "Frameworks" + "title": "Frameworks", + "noContent": "The content for this framework has not been loaded yet. The questionnaire and reporting sections are available through the risk classification and reporting pages." } } diff --git a/frontend/src/locales/es/common.json b/frontend/src/locales/es/common.json index 07933d1..5a57d72 100644 --- a/frontend/src/locales/es/common.json +++ b/frontend/src/locales/es/common.json @@ -50,7 +50,7 @@ "general": "General", "project": "Proyecto", "configuration": "Configuración", - "github": "GitHub" + "github": "Codebase" }, "risk": { "unacceptable": "Riesgo inaceptable", diff --git a/frontend/src/locales/es/components.json b/frontend/src/locales/es/components.json index 61156cb..c8f4276 100644 --- a/frontend/src/locales/es/components.json +++ b/frontend/src/locales/es/components.json @@ -10,7 +10,8 @@ "reporting": "Informes", "integrations": "Integraciones", "frameworks": "Marcos normativos", - "github": "GitHub", + "github": "Codebase", + "githubPage": "GitHub", "overview": "Vista general", "riskClassification": "Clasificación de riesgo", "additionalDocuments": "Documentos adicionales" diff --git a/frontend/src/locales/es/pages.json b/frontend/src/locales/es/pages.json index aa34eec..ff36002 100644 --- a/frontend/src/locales/es/pages.json +++ b/frontend/src/locales/es/pages.json @@ -59,7 +59,8 @@ "additional": "Adicionales", "uploadedCount": "{{count}} de {{total}} subidos", "noAdditionalDocs": "Aún no se han subido documentos adicionales. Suba cualquier PDF para incluirlo en el contexto de su proyecto.", - "deleteDocument": "Eliminar documento" + "deleteDocument": "Eliminar documento", + "noSummaryAvailable": "Este documento aún no ha sido procesado. El resumen aparecerá aquí una vez completado el procesamiento." }, "reporting": { "title": "Informes", @@ -101,6 +102,7 @@ "githubDesc": "Conecte un repositorio de GitHub para sincronizar tareas y analizar la arquitectura." }, "frameworks": { - "title": "Marcos normativos" + "title": "Marcos normativos", + "noContent": "El contenido de este marco aún no ha sido cargado. El cuestionario y las secciones de informes están disponibles a través de las páginas de clasificación de riesgos e informes." } } diff --git a/frontend/src/locales/fr/common.json b/frontend/src/locales/fr/common.json index 51ee073..b317213 100644 --- a/frontend/src/locales/fr/common.json +++ b/frontend/src/locales/fr/common.json @@ -50,7 +50,7 @@ "general": "Général", "project": "Projet", "configuration": "Configuration", - "github": "GitHub" + "github": "Codebase" }, "risk": { "unacceptable": "Risque inacceptable", diff --git a/frontend/src/locales/fr/components.json b/frontend/src/locales/fr/components.json index 7e76879..0fdd82e 100644 --- a/frontend/src/locales/fr/components.json +++ b/frontend/src/locales/fr/components.json @@ -10,7 +10,8 @@ "reporting": "Rapports", "integrations": "Intégrations", "frameworks": "Référentiels", - "github": "GitHub", + "github": "Codebase", + "githubPage": "GitHub", "overview": "Vue d'ensemble", "riskClassification": "Classification des risques", "additionalDocuments": "Documents supplémentaires" diff --git a/frontend/src/locales/fr/pages.json b/frontend/src/locales/fr/pages.json index da6940d..0a79c27 100644 --- a/frontend/src/locales/fr/pages.json +++ b/frontend/src/locales/fr/pages.json @@ -59,7 +59,8 @@ "additional": "Supplémentaires", "uploadedCount": "{{count}} sur {{total}} téléversés", "noAdditionalDocs": "Aucun document supplémentaire n'a encore été téléversé. Téléversez un PDF pour l'inclure dans le contexte de votre projet.", - "deleteDocument": "Supprimer le document" + "deleteDocument": "Supprimer le document", + "noSummaryAvailable": "Ce document n'a pas encore été traité. Le résumé apparaîtra ici une fois le traitement terminé." }, "reporting": { "title": "Rapports", @@ -101,6 +102,7 @@ "githubDesc": "Connectez un dépôt GitHub pour synchroniser les tâches et analyser l'architecture." }, "frameworks": { - "title": "Référentiels" + "title": "Référentiels", + "noContent": "Le contenu de ce référentiel n'a pas encore été chargé. Le questionnaire et les sections de rapports sont accessibles via les pages de classification des risques et de rapports." } } diff --git a/frontend/src/pages/chat.tsx b/frontend/src/pages/chat.tsx index dbf80e2..9413a46 100644 --- a/frontend/src/pages/chat.tsx +++ b/frontend/src/pages/chat.tsx @@ -4,6 +4,7 @@ import { useTranslation } from 'react-i18next'; import Markdown from 'react-markdown'; import { MessageSquare, Send, SquarePen } from 'lucide-react'; import { Button } from '@/components/ui/button'; +import { DebugContextDialog } from '@/components/debug-context-dialog'; import { ScrollArea } from '@/components/ui/scroll-area'; import { SidebarTrigger } from '@/components/ui/sidebar'; import { useProject } from '@/hooks/use-project'; @@ -200,15 +201,13 @@ export function ChatPage() {

{t('chat.title')}

- +
+ + +
diff --git a/frontend/src/pages/description.tsx b/frontend/src/pages/description.tsx index bfb3523..d49c913 100644 --- a/frontend/src/pages/description.tsx +++ b/frontend/src/pages/description.tsx @@ -23,7 +23,10 @@ export function DescriptionPage() { if (!currentProject) { return (
- ' + t('description.overview')}> + ' + t('description.overview')} + debugSection="overview" + >
@@ -35,7 +38,10 @@ export function DescriptionPage() { return (
- ' + t('description.overview')}> + ' + t('description.overview')} + debugSection="overview" + > diff --git a/frontend/src/pages/documents.tsx b/frontend/src/pages/documents.tsx index c4ea57f..f728503 100644 --- a/frontend/src/pages/documents.tsx +++ b/frontend/src/pages/documents.tsx @@ -2,9 +2,17 @@ import { useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useNavigate, useParams } from 'react-router-dom'; import { CheckCircle2, Circle, FileText, Loader2, Trash2, Upload } from 'lucide-react'; +import Markdown from 'react-markdown'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, +} from '@/components/ui/dialog'; +import { ScrollArea } from '@/components/ui/scroll-area'; import { Table, TableBody, @@ -36,6 +44,7 @@ export function DocumentsPage() { const [uploadingId, setUploadingId] = useState(null); const [customUploading, setCustomUploading] = useState(false); const [deletingId, setDeletingId] = useState(null); + const [viewDoc, setViewDoc] = useState<{ name: string; summary: string | null } | null>(null); const redirected = useRef(false); useEffect(() => { @@ -115,6 +124,21 @@ export function DocumentsPage() { } }; + const handleRemoveUpload = async (docId: string) => { + if (!currentProject) return; + setDeletingId(docId); + try { + const updated = await api.delete( + `/projects/${currentProject.id}/documents/${docId}/upload`, + ); + setDocuments((prev) => prev.map((d) => (d.id === docId ? updated : d))); + } catch { + // ignore + } finally { + setDeletingId(null); + } + }; + const handleCustomDelete = async (docId: string) => { if (!currentProject) return; setDeletingId(docId); @@ -130,7 +154,7 @@ export function DocumentsPage() { return (
- + {currentFramework ? ( 0 ? (
- +
{t('common:table.document')} - {t('common:table.uploaded')} + {t('common:table.uploaded')} {customDocs.map((doc) => ( - + + setViewDoc({ name: doc.file_name, summary: doc.summary }) + } + >
@@ -190,19 +220,22 @@ export function DocumentsPage() { {doc.file_name} {doc.summary && (

- {doc.summary} + {doc.summary.replace(/[#*_~`>\-]/g, '').replace(/\s+/g, ' ').trim()}

)}
- + {new Date(doc.uploaded_at).toLocaleDateString()} - +
+
{t('common:table.document')} - + {filteredDocs.map((doc) => ( - + { + if (doc.uploaded) + setViewDoc({ + name: t(`documentDefinitions.${slugify(doc.name)}.name`, { + ns: 'data', + defaultValue: doc.name, + }), + summary: doc.summary, + }); + }} + > {doc.uploaded ? ( @@ -272,37 +318,60 @@ export function DocumentsPage() { )} -

- {t(`documentDefinitions.${slugify(doc.name)}.description`, { - ns: 'data', - defaultValue: doc.description, - })} +

+ {doc.summary + ? doc.summary.replace(/[#*_~`>\-]/g, '').replace(/\s+/g, ' ').trim() + : t(`documentDefinitions.${slugify(doc.name)}.description`, { + ns: 'data', + defaultValue: doc.description, + })}

- +
+ + {doc.uploaded && ( + + )} +
))} @@ -320,6 +389,25 @@ export function DocumentsPage() { )} + + !open && setViewDoc(null)}> + + + {viewDoc?.name} + + + {viewDoc?.summary ? ( +
+ {viewDoc.summary.replace(/^-{3,}\s*$/gm, '')} +
+ ) : ( +

+ {t('documents.noSummaryAvailable')} +

+ )} +
+
+
); } diff --git a/frontend/src/pages/frameworks.tsx b/frontend/src/pages/frameworks.tsx index de60aa4..1ad5778 100644 --- a/frontend/src/pages/frameworks.tsx +++ b/frontend/src/pages/frameworks.tsx @@ -1,16 +1,17 @@ import { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Plus, Scale } from 'lucide-react'; +import Markdown from 'react-markdown'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { Card, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Dialog, DialogContent, - DialogDescription, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; +import { ScrollArea } from '@/components/ui/scroll-area'; import { PageHeader } from '@/components/page-header'; import { api, type Framework } from '@/lib/api'; @@ -34,7 +35,7 @@ export function FrameworksPage() { return (
- +
@@ -78,28 +79,42 @@ export function FrameworksPage() {
setSelected(null)}> - - {selected && ( - <> - -
- {selected.name} - - {t(`common:status.${selected.status}`)} - -
- {selected.category} -
-
-

{selected.description}

-
- -
-
- - )} + + {selected && (() => { + const text = [selected.description, selected.content].filter(Boolean).join(' '); + const wordCount = text.split(/\s+/).filter(Boolean).length; + const pageEstimate = Math.ceil(wordCount / 250); + return ( + <> + + + {selected.name} + + {t(`common:status.${selected.status}`)} + + {wordCount > 0 && ( + + {wordCount.toLocaleString()} words · ~{pageEstimate}{' '} + {pageEstimate === 1 ? 'page' : 'pages'} + + )} + + + +

{selected.description}

+ {selected.content ? ( +
+ {selected.content} +
+ ) : ( +

+ {t('frameworks.noContent')} +

+ )} +
+ + ); + })()}
diff --git a/frontend/src/pages/github.tsx b/frontend/src/pages/github.tsx index 723ca07..4e0c6de 100644 --- a/frontend/src/pages/github.tsx +++ b/frontend/src/pages/github.tsx @@ -302,7 +302,7 @@ export function GitHubPage() { if (loading && !integration) { return (
- +
@@ -312,7 +312,7 @@ export function GitHubPage() { return (
- + diff --git a/frontend/src/pages/integrations.tsx b/frontend/src/pages/integrations.tsx index 2af7d09..9844453 100644 --- a/frontend/src/pages/integrations.tsx +++ b/frontend/src/pages/integrations.tsx @@ -38,7 +38,7 @@ export function IntegrationsPage() { return (
- +
diff --git a/frontend/src/pages/reporting.tsx b/frontend/src/pages/reporting.tsx index b77d9fa..fa670ff 100644 --- a/frontend/src/pages/reporting.tsx +++ b/frontend/src/pages/reporting.tsx @@ -61,8 +61,15 @@ export function ReportingPage() { .catch(() => {}); }, [currentProject]); + const [debugRefreshKey, setDebugRefreshKey] = useState(0); + const debugRefreshTimer = useRef>(undefined); + const handleCommentChange = useCallback((key: string, value: string) => { setComments((prev) => ({ ...prev, [key]: value })); + if (debugRefreshTimer.current) clearTimeout(debugRefreshTimer.current); + debugRefreshTimer.current = setTimeout(() => { + setDebugRefreshKey((k) => k + 1); + }, 1500); }, []); const handleValidate = useCallback( @@ -126,7 +133,7 @@ export function ReportingPage() { return (
- + {currentFramework && ( ' + t('sidebar.riskClassification', { ns: 'components' }) } @@ -60,6 +61,7 @@ export function RiskClassificationPage() { return (
' + t('sidebar.riskClassification', { ns: 'components' }) } diff --git a/frontend/src/pages/settings.tsx b/frontend/src/pages/settings.tsx index a0190a1..21aca8f 100644 --- a/frontend/src/pages/settings.tsx +++ b/frontend/src/pages/settings.tsx @@ -43,7 +43,7 @@ export function SettingsPage() { return (
- +
diff --git a/pipelines/app/tasks/github_processor.py b/pipelines/app/tasks/github_processor.py index 6190573..4ec76c3 100644 --- a/pipelines/app/tasks/github_processor.py +++ b/pipelines/app/tasks/github_processor.py @@ -11,13 +11,23 @@ You are a technical project analyst. Below is information gathered from a GitHub repository: \ a list of tasks/issues from the project board and key source files from the codebase. -Produce a structured summary covering: -1. **Project overview**: What this codebase does, its purpose and domain. -2. **Tech stack**: Languages, frameworks, key dependencies. -3. **Task status overview**: How many tasks are open vs closed, key themes, current priorities. -4. **Key observations**: Architecture decisions, patterns, or risks relevant to compliance analysis. +Produce a structured summary using EXACTLY these four sections in this order: +## 1. Project Overview +What this codebase does, its purpose and domain. -Keep the summary concise (under 1000 words). Use markdown formatting. +## 2. Tech Stack +Languages, frameworks, key dependencies. + +## 3. Tasks +List EVERY task/issue individually. For each task, include its number, title, \ +status (open/closed), and a one-sentence description of what it covers. Group by status \ +(open first, then closed). Do not summarise or group tasks by theme — list each one explicitly. + +## 4. Key Observations +Architecture decisions, patterns, or risks relevant to compliance analysis. + +Use these exact section headings (## 1. Project Overview, ## 2. Tech Stack, ## 3. Tasks, ## 4. Key Observations). \ +Do not add, remove, rename, or reorder sections. {language_rule} --- From 1b558349a3031bf77158ba0c40e1c4140557a502 Mon Sep 17 00:00:00 2001 From: Nicolas Guzman Date: Wed, 27 May 2026 12:46:44 +0100 Subject: [PATCH 2/4] Fix frontend lint errors: setState in effect and useless escape Co-Authored-By: Claude Opus 4.6 --- .../src/components/debug-context-dialog.tsx | 40 +++++++++---------- frontend/src/pages/documents.tsx | 4 +- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/frontend/src/components/debug-context-dialog.tsx b/frontend/src/components/debug-context-dialog.tsx index 7b51781..aa40199 100644 --- a/frontend/src/components/debug-context-dialog.tsx +++ b/frontend/src/components/debug-context-dialog.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useState } from 'react'; +import { useEffect, useState } from 'react'; import Markdown from 'react-markdown'; import { Bug, Loader2 } from 'lucide-react'; import { Button } from '@/components/ui/button'; @@ -26,27 +26,27 @@ export function DebugContextDialog({ section = 'full', refreshKey }: DebugContex const [context, setContext] = useState(null); const [loading, setLoading] = useState(false); - const fetchContext = useCallback(async () => { - if (!currentProject || !section) { - setContext(null); - return; - } + useEffect(() => { + if (!open || !currentProject || !section) return; + let cancelled = false; setLoading(true); - try { - const data = await api.get<{ context: string | null }>( + api + .get<{ context: string | null }>( `/chat/context?project_id=${currentProject.id}§ion=${section}`, - ); - setContext(data.context); - } catch { - setContext('Failed to load context.'); - } finally { - setLoading(false); - } - }, [currentProject, section]); - - useEffect(() => { - if (open) fetchContext(); - }, [open, fetchContext, refreshKey]); + ) + .then((data) => { + if (!cancelled) setContext(data.context); + }) + .catch(() => { + if (!cancelled) setContext('Failed to load context.'); + }) + .finally(() => { + if (!cancelled) setLoading(false); + }); + return () => { + cancelled = true; + }; + }, [open, currentProject, section, refreshKey]); const wordCount = context ? context.split(/\s+/).filter(Boolean).length : 0; const pageEstimate = Math.ceil(wordCount / 250); diff --git a/frontend/src/pages/documents.tsx b/frontend/src/pages/documents.tsx index f728503..8ac027b 100644 --- a/frontend/src/pages/documents.tsx +++ b/frontend/src/pages/documents.tsx @@ -220,7 +220,7 @@ export function DocumentsPage() { {doc.file_name} {doc.summary && (

- {doc.summary.replace(/[#*_~`>\-]/g, '').replace(/\s+/g, ' ').trim()} + {doc.summary.replace(/[#*_~`>-]/g, '').replace(/\s+/g, ' ').trim()}

)}
@@ -320,7 +320,7 @@ export function DocumentsPage() {

{doc.summary - ? doc.summary.replace(/[#*_~`>\-]/g, '').replace(/\s+/g, ' ').trim() + ? doc.summary.replace(/[#*_~`>-]/g, '').replace(/\s+/g, ' ').trim() : t(`documentDefinitions.${slugify(doc.name)}.description`, { ns: 'data', defaultValue: doc.description, From c402d99119ea4359fbfc7a1ce6f05cb725c4fc9e Mon Sep 17 00:00:00 2001 From: Nicolas Guzman Date: Wed, 27 May 2026 13:03:04 +0100 Subject: [PATCH 3/4] Fix setState-in-effect lint error and mermaid label rendering Restructure debug-context-dialog to avoid synchronous setState in useEffect by wrapping in Promise chain. Fix mermaid cleanLabel to unwrap parenthesised node definitions before stripping. Co-Authored-By: Claude Opus 4.6 --- .../src/components/debug-context-dialog.tsx | 40 ++++++++++--------- frontend/src/pages/github.tsx | 7 +++- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/frontend/src/components/debug-context-dialog.tsx b/frontend/src/components/debug-context-dialog.tsx index aa40199..cc7353c 100644 --- a/frontend/src/components/debug-context-dialog.tsx +++ b/frontend/src/components/debug-context-dialog.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import Markdown from 'react-markdown'; import { Bug, Loader2 } from 'lucide-react'; import { Button } from '@/components/ui/button'; @@ -25,27 +25,32 @@ export function DebugContextDialog({ section = 'full', refreshKey }: DebugContex const [open, setOpen] = useState(false); const [context, setContext] = useState(null); const [loading, setLoading] = useState(false); + const requestRef = useRef(0); useEffect(() => { if (!open || !currentProject || !section) return; - let cancelled = false; - setLoading(true); - api - .get<{ context: string | null }>( - `/chat/context?project_id=${currentProject.id}§ion=${section}`, - ) + const id = ++requestRef.current; + // Fetch context; setState calls are in async callbacks to satisfy lint rules + Promise.resolve() + .then(() => { + setContext(null); + setLoading(true); + return api.get<{ context: string | null }>( + `/chat/context?project_id=${currentProject.id}§ion=${section}`, + ); + }) .then((data) => { - if (!cancelled) setContext(data.context); + if (requestRef.current === id) { + setContext(data.context); + setLoading(false); + } }) .catch(() => { - if (!cancelled) setContext('Failed to load context.'); - }) - .finally(() => { - if (!cancelled) setLoading(false); + if (requestRef.current === id) { + setContext('Failed to load context.'); + setLoading(false); + } }); - return () => { - cancelled = true; - }; }, [open, currentProject, section, refreshKey]); const wordCount = context ? context.split(/\s+/).filter(Boolean).length : 0; @@ -57,10 +62,7 @@ export function DebugContextDialog({ section = 'full', refreshKey }: DebugContex

+

{doc.summary - ? doc.summary.replace(/[#*_~`>-]/g, '').replace(/\s+/g, ' ').trim() + ? doc.summary + .replace(/[#*_~`>-]/g, '') + .replace(/\s+/g, ' ') + .trim() : t(`documentDefinitions.${slugify(doc.name)}.description`, { ns: 'data', defaultValue: doc.description, diff --git a/frontend/src/pages/frameworks.tsx b/frontend/src/pages/frameworks.tsx index 1ad5778..3504f40 100644 --- a/frontend/src/pages/frameworks.tsx +++ b/frontend/src/pages/frameworks.tsx @@ -5,12 +5,7 @@ import Markdown from 'react-markdown'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { Card, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; -import { - Dialog, - DialogContent, - DialogHeader, - DialogTitle, -} from '@/components/ui/dialog'; +import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'; import { ScrollArea } from '@/components/ui/scroll-area'; import { PageHeader } from '@/components/page-header'; import { api, type Framework } from '@/lib/api'; @@ -80,41 +75,42 @@ export function FrameworksPage() {

setSelected(null)}> - {selected && (() => { - const text = [selected.description, selected.content].filter(Boolean).join(' '); - const wordCount = text.split(/\s+/).filter(Boolean).length; - const pageEstimate = Math.ceil(wordCount / 250); - return ( - <> - - - {selected.name} - - {t(`common:status.${selected.status}`)} - - {wordCount > 0 && ( - - {wordCount.toLocaleString()} words · ~{pageEstimate}{' '} - {pageEstimate === 1 ? 'page' : 'pages'} - + {selected && + (() => { + const text = [selected.description, selected.content].filter(Boolean).join(' '); + const wordCount = text.split(/\s+/).filter(Boolean).length; + const pageEstimate = Math.ceil(wordCount / 250); + return ( + <> + + + {selected.name} + + {t(`common:status.${selected.status}`)} + + {wordCount > 0 && ( + + {wordCount.toLocaleString()} words · ~{pageEstimate}{' '} + {pageEstimate === 1 ? 'page' : 'pages'} + + )} + + + +

{selected.description}

+ {selected.content ? ( +
+ {selected.content} +
+ ) : ( +

+ {t('frameworks.noContent')} +

)} -
-
- -

{selected.description}

- {selected.content ? ( -
- {selected.content} -
- ) : ( -

- {t('frameworks.noContent')} -

- )} -
- - ); - })()} + + + ); + })()}