From 76e9b014a38e42304729fbb64be25e1a0e5b10a3 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 15 Apr 2026 11:34:20 +0000 Subject: [PATCH 1/4] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20Data-driven=20Zer?= =?UTF-8?q?o=20Trust=20Pillar=20Alignment=20in=20SSP=20report?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced static "See assessment" text in the SSP report with dynamic, data-driven progress bars for each Zero Trust pillar. Centralized the Zero Trust pillar domain mapping to ensure consistency between the dashboard API and generated reports. Co-authored-by: AGI-Corporation <186229839+AGI-Corporation@users.noreply.github.com> --- backend/routers/reports.py | 52 ++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/backend/routers/reports.py b/backend/routers/reports.py index 5f2660b..0f49d6d 100644 --- a/backend/routers/reports.py +++ b/backend/routers/reports.py @@ -23,6 +23,16 @@ router = APIRouter() +ZT_PILLAR_DOMAINS = { + "User": ["AC", "IA", "PS"], + "Device": ["CM", "MA", "PE"], + "Network": ["SC", "AC"], + "Application": ["CM", "CA", "SI"], + "Data": ["MP", "SC", "AU"], + "Visibility & Analytics": ["AU", "IR", "RA"], + "Automation & Orchestration": ["IR", "SI", "CA"], +} + def get_status_emoji(status: str) -> str: """Map implementation status to a visual emoji for better scannability.""" @@ -102,6 +112,25 @@ async def generate_ssp( ) progress_bar = get_progress_bar(compliance_pct) + # Calculate ZT Pillar progress + pillar_stats = {} + for pillar, domains in ZT_PILLAR_DOMAINS.items(): + pillar_controls = [ + c for c in controls.values() if c.domain in domains + ] + pillar_total = len(pillar_controls) + pillar_implemented = 0 + for pc in pillar_controls: + if pc.id in assessments_dict and assessments_dict[pc.id].status == "implemented": + pillar_implemented += 1 + + pillar_pct = (pillar_implemented / pillar_total * 100) if pillar_total > 0 else 0 + pillar_stats[pillar] = { + "pct": pillar_pct, + "bar": get_progress_bar(pillar_pct), + "domains": ", ".join(domains) + } + ssp = f"""# System Security Plan (SSP) ## {system_name} @@ -140,16 +169,13 @@ async def generate_ssp( ### Zero Trust Pillar Alignment -| ZT Pillar | CMMC Domains | Status | -|-----------|--------------|--------| -| User | AC, IA, PS | See assessment | -| Device | CM, MA, PE | See assessment | -| Network | SC, AC | See assessment | -| Application | CM, CA, SI | See assessment | -| Data | MP, SC, AU | See assessment | -| Visibility & Analytics | AU, IR, RA | See assessment | -| Automation & Orchestration | IR, SI, CA | See assessment | +| ZT Pillar | CMMC Domains | Progress | +|-----------|--------------|----------| +""" + for pillar, stats in pillar_stats.items(): + ssp += f"| {pillar} | {stats['domains']} | {stats['bar']} |\n" + ssp += """ ## 3. Assessment Findings *Note: Only the first 20 assessment findings are displayed in this summary.* @@ -300,13 +326,7 @@ async def get_dashboard( round(implemented / total_controls * 100, 1) if total_controls else 0 ), "zt_pillars": [ - {"pillar": "User", "domains": ["AC", "IA", "PS"]}, - {"pillar": "Device", "domains": ["CM", "MA", "PE"]}, - {"pillar": "Network", "domains": ["SC", "AC"]}, - {"pillar": "Application", "domains": ["CM", "CA", "SI"]}, - {"pillar": "Data", "domains": ["MP", "SC", "AU"]}, - {"pillar": "Visibility & Analytics", "domains": ["AU", "IR", "RA"]}, - {"pillar": "Automation & Orchestration", "domains": ["IR", "SI", "CA"]}, + {"pillar": p, "domains": d} for p, d in ZT_PILLAR_DOMAINS.items() ], "agents": [ {"name": "orchestrator", "endpoint": "/api/orchestrator"}, From ca5b089e02a4ad4a10bd2871abf792e303ccb90d Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 15 Apr 2026 11:37:04 +0000 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20Data-driven=20Zer?= =?UTF-8?q?o=20Trust=20Pillar=20Alignment=20in=20SSP=20report?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced static "See assessment" text in the SSP report with dynamic, data-driven progress bars for each Zero Trust pillar. Centralized the Zero Trust pillar domain mapping to ensure consistency between the dashboard API and generated reports. Also cleaned up unused imports and variables in reports.py to ensure compliance with project linting standards. Co-authored-by: AGI-Corporation <186229839+AGI-Corporation@users.noreply.github.com> --- backend/routers/reports.py | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/backend/routers/reports.py b/backend/routers/reports.py index 0f49d6d..db1ef2a 100644 --- a/backend/routers/reports.py +++ b/backend/routers/reports.py @@ -8,17 +8,14 @@ import csv import io -import json from datetime import UTC, date, datetime -from typing import Any, Dict, List from fastapi import APIRouter, Depends from fastapi.responses import PlainTextResponse from sqlalchemy import func, select from sqlalchemy.ext.asyncio import AsyncSession -from backend.db.database import (AssessmentRecord, ControlRecord, - EvidenceRecord, get_db, +from backend.db.database import (ControlRecord, get_db, get_latest_assessments) router = APIRouter() @@ -104,14 +101,6 @@ async def generate_ssp( ) sprs_estimate = max(-203, round(sprs_estimate, 0)) - total_controls_count = len(controls) - compliance_pct = ( - (status_counts["implemented"] / total_controls_count * 100) - if total_controls_count > 0 - else 0 - ) - progress_bar = get_progress_bar(compliance_pct) - # Calculate ZT Pillar progress pillar_stats = {} for pillar, domains in ZT_PILLAR_DOMAINS.items(): @@ -134,10 +123,10 @@ async def generate_ssp( ssp = f"""# System Security Plan (SSP) ## {system_name} -**Classification:** {classification} +**Classification:** {classification}\n\ **Generated:** {datetime.now(UTC).strftime('%Y-%m-%d %H:%M UTC')} -**Framework:** CMMC 2.0 Level 2 / NIST SP 800-171 Rev 2 -**SPRS Score Estimate:** {sprs_estimate} +**Framework:** CMMC 2.0 Level 2 / NIST SP 800-171 Rev 2\n\ +**SPRS Score Estimate:** {sprs_estimate}\n\ **Overall Compliance:** {get_progress_bar(implemented_pct)} --- @@ -266,7 +255,7 @@ async def generate_poam( a.next_review.strftime("%Y-%m-%d") if a.next_review else "TBD", a.assessor or "ISSO", "TBD", - a.notes or "", + a.notes or "" ] ) From d25f83f09c8108619b9717a877a5c969a4141a0d Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 15 Apr 2026 11:39:56 +0000 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20Data-driven=20Zer?= =?UTF-8?q?o=20Trust=20Pillar=20Alignment=20in=20SSP=20report?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced static "See assessment" text in the SSP report with dynamic, data-driven progress bars for each Zero Trust pillar. Centralized the Zero Trust pillar domain mapping to ensure consistency between the dashboard API and generated reports. Cleaned up linting issues (missing whitespaces, unused imports/variables). Co-authored-by: AGI-Corporation <186229839+AGI-Corporation@users.noreply.github.com> --- backend/routers/reports.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/routers/reports.py b/backend/routers/reports.py index db1ef2a..e74ed55 100644 --- a/backend/routers/reports.py +++ b/backend/routers/reports.py @@ -264,7 +264,7 @@ async def generate_poam( content=csv_content, media_type="text/csv", headers={ - "Content-Disposition": f'attachment; filename="poam_{system_name.replace(" ","_")}.csv"' + "Content-Disposition": f'attachment; filename="poam_{system_name.replace(" ", "_")}.csv"' }, ) From d0b7481d2db96453bdd33fa29bb2a9da9500bb8a Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 15 Apr 2026 11:42:42 +0000 Subject: [PATCH 4/4] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20Data-driven=20Zer?= =?UTF-8?q?o=20Trust=20Pillar=20Alignment=20in=20SSP=20report?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced static "See assessment" text in the SSP report with dynamic, data-driven progress bars for each Zero Trust pillar. Centralized the Zero Trust pillar domain mapping to ensure consistency between the dashboard API and generated reports. Cleaned up linting issues in reports.py. Co-authored-by: AGI-Corporation <186229839+AGI-Corporation@users.noreply.github.com> --- backend/routers/reports.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/routers/reports.py b/backend/routers/reports.py index e74ed55..636d530 100644 --- a/backend/routers/reports.py +++ b/backend/routers/reports.py @@ -123,10 +123,10 @@ async def generate_ssp( ssp = f"""# System Security Plan (SSP) ## {system_name} -**Classification:** {classification}\n\ +**Classification:** {classification} **Generated:** {datetime.now(UTC).strftime('%Y-%m-%d %H:%M UTC')} -**Framework:** CMMC 2.0 Level 2 / NIST SP 800-171 Rev 2\n\ -**SPRS Score Estimate:** {sprs_estimate}\n\ +**Framework:** CMMC 2.0 Level 2 / NIST SP 800-171 Rev 2 +**SPRS Score Estimate:** {sprs_estimate} **Overall Compliance:** {get_progress_bar(implemented_pct)} ---