#!/usr/bin/env python3 """ Generate PDF 2: Talas — Project Evidence (Software + Infrastructure) For NGI Zero Commons Fund application attachment. Demonstrates delivery capacity and project maturity. """ from fpdf import FPDF import os BASE = "/home/senke/Documents/TG__Talas_Group" OUT = f"{BASE}/09_MODELE_ECONOMIQUE/Subventions/talas-project-evidence.pdf" FONT_DIR = "/usr/share/fonts/liberation-sans-fonts" class TalasPDF(FPDF): def __init__(self): super().__init__() self.add_font("Sans", "", f"{FONT_DIR}/LiberationSans-Regular.ttf") self.add_font("Sans", "B", f"{FONT_DIR}/LiberationSans-Bold.ttf") self.add_font("Sans", "I", f"{FONT_DIR}/LiberationSans-Italic.ttf") self.add_font("Sans", "BI", f"{FONT_DIR}/LiberationSans-BoldItalic.ttf") def header(self): self.set_font("Sans", "B", 9) self.set_text_color(100, 100, 100) self.cell(0, 5, "Talas — NGI Zero Commons Fund Application — Attachment 2", align="R") self.ln(8) def footer(self): self.set_y(-15) self.set_font("Sans", "I", 8) self.set_text_color(150, 150, 150) self.cell(0, 10, f"Page {self.page_no()}/{{nb}}", align="C") def section_title(self, title): self.set_font("Sans", "B", 13) self.set_text_color(30, 30, 30) self.cell(0, 10, title, new_x="LMARGIN", new_y="NEXT") self.set_draw_color(60, 60, 60) self.line(self.l_margin, self.get_y(), self.w - self.r_margin, self.get_y()) self.ln(4) def sub_title(self, title): self.set_font("Sans", "B", 11) self.set_text_color(50, 50, 50) self.cell(0, 8, title, new_x="LMARGIN", new_y="NEXT") self.ln(1) def body_text(self, text): self.set_font("Sans", "", 10) self.set_text_color(40, 40, 40) self.multi_cell(0, 5, text) self.ln(2) def metric_row(self, label, value, detail=""): self.set_font("Sans", "B", 10) self.set_text_color(40, 40, 40) self.cell(55, 6, label) self.set_font("Sans", "", 10) self.set_text_color(30, 100, 30) self.cell(35, 6, value) self.set_text_color(120, 120, 120) self.set_font("Sans", "I", 9) self.cell(0, 6, detail, new_x="LMARGIN", new_y="NEXT") def bullet(self, text, indent=10): x = self.get_x() self.set_font("Sans", "", 9) self.set_text_color(40, 40, 40) self.cell(indent, 5, "\u2022") self.multi_cell(self.w - self.r_margin - self.l_margin - indent, 5, text) self.ln(1) def main(): pdf = TalasPDF() pdf.alias_nb_pages() pdf.set_auto_page_break(auto=True, margin=20) # ========================================================= # PAGE 1 — Software delivery evidence # ========================================================= pdf.add_page() # Title pdf.set_font("Sans", "B", 20) pdf.set_text_color(20, 20, 20) pdf.cell(0, 12, "Talas — Project Maturity Evidence", align="C", new_x="LMARGIN", new_y="NEXT") pdf.set_font("Sans", "", 11) pdf.set_text_color(80, 80, 80) pdf.cell(0, 7, "Demonstrating delivery capacity — March 2026", align="C", new_x="LMARGIN", new_y="NEXT") pdf.ln(4) pdf.body_text( "This document demonstrates the applicant's capacity to deliver on the proposed " "grant milestones. While this grant focuses on open hardware, the Veza software " "platform and self-hosted infrastructure provide concrete evidence of sustained, " "high-quality engineering output by a solo developer." ) # --- Veza Platform --- pdf.section_title("1. Veza Platform — Software Delivery Metrics") pdf.sub_title("Development Velocity") pdf.metric_row("Total commits (90 days):", "974", "~10.8 commits/day") pdf.metric_row("Total commits (30 days):", "162", "~5.4 commits/day") pdf.metric_row("Releases shipped:", "38+", "over 5 months") pdf.metric_row("CI/CD workflows:", "28", "GitHub Actions") pdf.metric_row("CI cache hit rate:", "80%", "optimised build pipeline") pdf.ln(3) pdf.sub_title("Backend (Go)") pdf.metric_row("API endpoints:", "102", "REST API handlers") pdf.metric_row("Database migrations:", "147", "PostgreSQL schema versions") pdf.metric_row("Test pass rate:", "100%", "104 tests") pdf.metric_row("Code coverage:", "82.3%", "measured by go test -cover") pdf.metric_row("Go version:", "1.24", "latest stable") pdf.ln(3) pdf.sub_title("Stream Server (Rust)") pdf.bullet("HLS audio transcoding (FFmpeg integration)") pdf.bullet("WebSocket real-time chat") pdf.bullet("Symphonia audio codec library for native decoding") pdf.bullet("Axum + Tokio async runtime") pdf.ln(2) pdf.sub_title("Frontend (React/TypeScript)") pdf.metric_row("Feature modules:", "35", "") pdf.metric_row("Languages:", "3", "EN / FR / ES") pdf.metric_row("ESLint status:", "0 errors", "63 acceptable warnings") pdf.ln(3) # --- Security --- pdf.section_title("2. Security Posture") pdf.body_text( "Security-first approach informed by the applicant's academic background " "(Bachelor + Master in Cybersecurity, EPITA & OTERIA)." ) pdf.sub_title("External Penetration Test (October 2025)") pdf.metric_row("Findings identified:", "36", "") pdf.metric_row("Findings remediated:", "36/36", "100% remediation rate") pdf.metric_row("Static analysis:", "staticcheck", "integrated in CI") pdf.metric_row("Secret scanning:", "gitleaks", "automated in pipeline") pdf.metric_row("Dependency audit:", "automated", "CI/CD integration") pdf.ln(3) pdf.sub_title("Security Features Implemented") security_features = [ "JWT RS256 token authentication", "WebAuthn / passkeys (passwordless login)", "Two-factor authentication (TOTP)", "GDPR-compliant data export and deletion", "Content Security Policy + security headers", "Coraza WAF with OWASP Core Rule Set", "Rate limiting and brute-force protection", ] for feat in security_features: pdf.bullet(feat) # ========================================================= # PAGE 2 — Infrastructure + Legal + Summary # ========================================================= pdf.add_page() pdf.section_title("3. Self-Hosted Infrastructure") pdf.body_text( "The entire Talas/Veza stack runs on self-owned hardware — no cloud vendor " "dependency. This demonstrates both technical capability and commitment to " "infrastructure sovereignty." ) pdf.sub_title("Hardware") pdf.metric_row("Servers:", "2x Dell R720", "rack-mounted") pdf.metric_row("RAM:", "768 GB total", "384 GB per server") pdf.metric_row("CPU:", "64 cores total", "dual Xeon per server") pdf.metric_row("Network:", "10 GbE", "inter-server link") pdf.metric_row("Storage:", "16 HDDs per server (32 total)", "ZFS pools, ~100 spare HDDs in reserve") pdf.metric_row("Monthly cost:", "~135 EUR", "electricity only") pdf.ln(3) pdf.sub_title("Automation & Monitoring") pdf.metric_row("Ansible roles:", "48", "full infrastructure-as-code") pdf.metric_row("Deployment:", "Blue-green", "zero-downtime via HAProxy") pdf.metric_row("Monitoring:", "Prometheus + Grafana", "metrics & dashboards") pdf.metric_row("Logging:", "Loki", "centralised log aggregation") pdf.metric_row("Security:", "Coraza WAF", "OWASP CRS integration") pdf.metric_row("VPN:", "WireGuard", "secure management access") pdf.ln(5) # --- Legal --- pdf.section_title("4. Legal & Business Readiness") pdf.body_text( "Company formation (French micro-entreprise) is planned. The following legal " "documentation is already prepared:" ) legal_items = [ "GDPR compliance documentation (privacy policy, data processing records)", "Terms of use (CGU) and terms of sale (CGV) — drafted", "Warranty and return policy — drafted", "Legal notices (mentions legales) — drafted", "Trademark registration guide — prepared", "Foundation structure plan — Purpose Trust model (Patagonia-inspired)", "Ethical fiscal optimisation strategy — documented", "Business plan with per-unit cost analysis (76 EUR cost / 120-180 EUR target price)", ] for item in legal_items: pdf.bullet(item) pdf.ln(3) # --- Licenses --- pdf.section_title("5. Open Source Licenses") pdf.set_font("Sans", "B", 10) pdf.set_fill_color(240, 240, 240) pdf.cell(60, 7, "Component", border=1, fill=True) pdf.cell(50, 7, "License", border=1, fill=True) pdf.cell(60, 7, "Status", border=1, fill=True, new_x="LMARGIN", new_y="NEXT") pdf.set_font("Sans", "", 10) licenses = [ ("Microphone hardware", "CERN-OHL-W-2.0", "Design complete, publication pending"), ("Veza backend (Go)", "AGPL-3.0", "Production-ready"), ("Veza stream server (Rust)", "AGPL-3.0", "Production-ready"), ("Veza frontend (React)", "AGPL-3.0", "Production-ready"), ("Calibration toolkit", "AGPL-3.0", "Planned (grant Milestone 1)"), ("Documentation", "CC-BY-SA-4.0", "Planned (grant Milestone 2)"), ] for comp, lic, status in licenses: pdf.cell(60, 6, comp, border=1) pdf.cell(50, 6, lic, border=1) pdf.cell(60, 6, status, border=1, new_x="LMARGIN", new_y="NEXT") pdf.ln(6) # --- Summary --- pdf.section_title("6. Summary") pdf.body_text( "This project demonstrates sustained, high-quality delivery by a solo developer " "with formal cybersecurity training (EPITA + OTERIA). The applicant has shipped " "38 releases of a production-grade platform, passed an external security audit " "with 100% remediation, built and manages a self-hosted infrastructure with 48 " "Ansible roles, and designed a functional microphone prototype with 2 custom PCBs." ) pdf.body_text( "The grant request (12,000 EUR) funds a focused, concrete deliverable: " "transforming the existing microphone prototype into a reproducible open-hardware " "commons with professional measurements, verified documentation, and independent " "build validation." ) # ========================================================= # Output # ========================================================= pdf.output(OUT) print(f"PDF generated: {OUT}") print(f"Pages: {pdf.pages_count}") if __name__ == "__main__": main()