11#!/usr/bin/env python3
2- """Decadal Roadmap for Enterprise AGI/ASI Governance (2026-2035) HTML renderer."""
2+ """Decadal Roadmap for Enterprise AGI/ASI Governance (2026-2035) renderer."""
33
44import html
55import json
@@ -42,24 +42,30 @@ def render_list(items):
4242
4343 reg_parts = []
4444 for key , val in data ["regulatoryMapping" ].items ():
45- reg_parts .append (f"<tr><th>{ esc (key .replace ('_' , ' ' ))} </th><td>{ esc (val )} </td></tr>" )
45+ k_disp = key .replace ("_" , " " )
46+ row = f"<tr><th>{ esc (k_disp )} </th><td>{ esc (val )} </td></tr>"
47+ reg_parts .append (row )
4648 reg_html = "\n " .join (reg_parts )
4749
4850 spec_parts = []
4951 for key , val in data ["technicalSpecs" ].items ():
50- spec_parts .append (f"""
52+ label = esc (key .replace ("Plane" , " Plane" ).title ())
53+ spec = f"""
5154 <div class="spec-item">
52- <span class="spec-label">{ esc ( key . replace ( 'Plane' , ' Plane' ). title ()) } </span>
55+ <span class="spec-label">{ label } </span>
5356 { esc (val )}
54- </div>""" )
57+ </div>"""
58+ spec_parts .append (spec )
5559 spec_html = "\n " .join (spec_parts )
5660
57- tags_html = " " .join (
58- [
59- f'<span class="tag" style="background:rgba(255,255,255,0.2);color:white;">{ esc (f )} </span>'
60- for f in data ["metadata" ]["frameworks" ]
61- ]
62- )
61+ tags_list = []
62+ for framework in data ["metadata" ]["frameworks" ]:
63+ tag = (
64+ '<span class="tag" style="background:rgba(255,255,255,0.2);'
65+ f'color:white;">{ esc (framework )} </span>'
66+ )
67+ tags_list .append (tag )
68+ tags_html = " " .join (tags_list )
6369
6470 full_content = f"""
6571<!DOCTYPE html>
@@ -69,35 +75,55 @@ def render_list(items):
6975 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7076 <title>{ esc (data ['metadata' ]['title' ])} </title>
7177 <style>
72- body {{ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; line-height: 1.6;
73- color: #333; max-width: 1000px; margin: 0 auto; padding: 2rem; background: #f5f7f9; }}
74- header {{ background: #1a365d; color: white; padding: 2rem; border-radius: 8px; margin-bottom: 2rem;
78+ body {{ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI",
79+ Roboto, sans-serif; line-height: 1.6;
80+ color: #333; max-width: 1000px; margin: 0 auto;
81+ padding: 2rem; background: #f5f7f9; }}
82+ header {{ background: #1a365d; color: white; padding: 2rem;
83+ border-radius: 8px; margin-bottom: 2rem;
7584 box-shadow: 0 4px 6px rgba(0,0,0,0.1); }}
7685 h1 {{ margin: 0; font-size: 2rem; }}
77- h2 {{ color: #2c5282; border-bottom: 2px solid #e2e8f0; padding-bottom: 0.5rem; margin-top: 2rem; }}
78- .card {{ background: white; padding: 1.5rem; border-radius: 8px; margin-bottom: 1.5rem;
86+ h2 {{ color: #2c5282; border-bottom: 2px solid #e2e8f0;
87+ padding-bottom: 0.5rem; margin-top: 2rem; }}
88+ .card {{ background: white; padding: 1.5rem; border-radius: 8px;
89+ margin-bottom: 1.5rem;
7990 box-shadow: 0 2px 4px rgba(0,0,0,0.05); }}
80- .phase-header {{ display: flex; justify-content: space-between; align-items: center; background: #edf2f7;
81- padding: 0.75rem 1rem; border-radius: 6px; margin-bottom: 1rem; }}
82- .phase-title {{ font-weight: bold; font-size: 1.2rem; color: #2d3748; }}
83- .phase-period {{ font-family: monospace; background: #2d3748; color: white; padding: 0.2rem 0.6rem;
91+ .phase-header {{ display: flex; justify-content: space-between;
92+ align-items: center; background: #edf2f7;
93+ padding: 0.75rem 1rem; border-radius: 6px;
94+ margin-bottom: 1rem; }}
95+ .phase-title {{ font-weight: bold; font-size: 1.2rem;
96+ color: #2d3748; }}
97+ .phase-period {{ font-family: monospace; background: #2d3748;
98+ color: white; padding: 0.2rem 0.6rem;
8499 border-radius: 4px; }}
85100 table {{ width: 100%; border-collapse: collapse; margin: 1rem 0; }}
86- th, td {{ text-align: left; padding: 0.75rem; border-bottom: 1px solid #e2e8f0; }}
87- th {{ background: #f8fafc; color: #4a5568; font-weight: 600; width: 30%; }}
88- .tag {{ display: inline-block; background: #ebf8ff; color: #2b6cb0; padding: 0.2rem 0.5rem; border-radius: 4px;
89- font-size: 0.85rem; margin-right: 0.5rem; margin-bottom: 0.5rem; }}
90- .spec-grid {{ display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1rem; }}
91- .spec-item {{ background: #fffaf0; border-left: 4px solid #ed8936; padding: 1rem; border-radius: 4px; }}
92- .spec-label {{ font-weight: bold; color: #7b341e; display: block; margin-bottom: 0.25rem; }}
93- footer {{ margin-top: 3rem; text-align: center; color: #718096; font-size: 0.9rem;
94- border-top: 1px solid #e2e8f0; padding-top: 1rem; }}
101+ th, td {{ text-align: left; padding: 0.75rem;
102+ border-bottom: 1px solid #e2e8f0; }}
103+ th {{ background: #f8fafc; color: #4a5568; font-weight: 600;
104+ width: 30%; }}
105+ .tag {{ display: inline-block; background: #ebf8ff; color: #2b6cb0;
106+ padding: 0.2rem 0.5rem; border-radius: 4px;
107+ font-size: 0.85rem; margin-right: 0.5rem;
108+ margin-bottom: 0.5rem; }}
109+ .spec-grid {{ display: grid;
110+ grid-template-columns: repeat(auto-fit,\
111+ minmax(250px, 1fr));
112+ gap: 1rem; }}
113+ .spec-item {{ background: #fffaf0; border-left: 4px solid #ed8936;
114+ padding: 1rem; border-radius: 4px; }}
115+ .spec-label {{ font-weight: bold; color: #7b341e; display: block;
116+ margin-bottom: 0.25rem; }}
117+ footer {{ margin-top: 3rem; text-align: center; color: #718096;
118+ font-size: 0.9rem; border-top: 1px solid #e2e8f0;
119+ padding-top: 1rem; }}
95120 </style>
96121</head>
97122<body>
98123 <header>
99124 <h1>{ esc (data ['metadata' ]['title' ])} </h1>
100- <p>Target: { esc (data ['metadata' ]['target' ])} | Version: { esc (data ['metadata' ]['version' ])} </p>
125+ <p>Target: { esc (data ['metadata' ]['target' ])} |
126+ Version: { esc (data ['metadata' ]['version' ])} </p>
101127 <div>
102128 { tags_html }
103129 </div>
@@ -125,7 +151,8 @@ def render_list(items):
125151 </section>
126152
127153 <footer>
128- Generated by Sentinel AI Governance Stack v2.4 | © 2026-2035 Omni-Sentinel Mesh
154+ Generated by Sentinel AI Governance Stack v2.4 |
155+ © 2026-2035 Omni-Sentinel Mesh
129156 </footer>
130157</body>
131158</html>
0 commit comments