Skip to content

Commit e0ff2f2

Browse files
Merge branch 'main' into dependabot/pip/pip-590e9db7b9
2 parents 1a0fdd5 + 952bdfb commit e0ff2f2

9 files changed

Lines changed: 8926 additions & 0 deletions

rag-agentic-dashboard/data/ent-agi-gov-master.json

Lines changed: 1739 additions & 0 deletions
Large diffs are not rendered by default.

rag-agentic-dashboard/data/wfap-gemini-impl.json

Lines changed: 1628 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 360 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,360 @@
1+
#!/usr/bin/env python3
2+
"""
3+
ENT-AGI-GOV-MASTER-WP-035 — HTML Dashboard Renderer
4+
Generates: public/ent-agi-gov-master.html
5+
"""
6+
7+
import json
8+
import html as htmllib
9+
from pathlib import Path
10+
11+
HERE = Path(__file__).parent
12+
SRC = HERE / "data" / "ent-agi-gov-master.json"
13+
OUT = HERE / "public" / "ent-agi-gov-master.html"
14+
15+
MODULE_ORDER = [
16+
"M1_pillars",
17+
"M2_regulatory",
18+
"M3_architectures",
19+
"M4_safety",
20+
"M5_civilizational",
21+
"M6_financialMrm",
22+
"M7_kafkaGac",
23+
"M8_roadmap",
24+
]
25+
26+
27+
def esc(v):
28+
if v is None:
29+
return ""
30+
if isinstance(v, bool):
31+
return "true" if v else "false"
32+
return htmllib.escape(str(v))
33+
34+
35+
def kv_table(d):
36+
rows = "".join(
37+
f"<tr><td class='k'>{esc(k)}</td><td class='v'>{render_value(v)}</td></tr>"
38+
for k, v in d.items()
39+
)
40+
return f"<table class='kv'>{rows}</table>"
41+
42+
43+
def render_value(v):
44+
if isinstance(v, dict):
45+
return kv_table(v)
46+
if isinstance(v, list):
47+
if not v:
48+
return "<em>—</em>"
49+
if all(isinstance(x, (str, int, float, bool)) for x in v):
50+
return "<ul>" + "".join(f"<li>{esc(x)}</li>" for x in v) + "</ul>"
51+
if all(isinstance(x, dict) for x in v):
52+
keys = []
53+
for d in v:
54+
for k in d.keys():
55+
if k not in keys:
56+
keys.append(k)
57+
head = "".join(f"<th>{esc(k)}</th>" for k in keys)
58+
body = ""
59+
for d in v:
60+
body += "<tr>" + "".join(
61+
f"<td>{render_value(d.get(k, ''))}</td>" for k in keys
62+
) + "</tr>"
63+
return (
64+
f"<table class='grid'><thead><tr>{head}</tr></thead>"
65+
f"<tbody>{body}</tbody></table>"
66+
)
67+
return "<ul>" + "".join(f"<li>{render_value(x)}</li>" for x in v) + "</ul>"
68+
return esc(v)
69+
70+
71+
def render_section(sec):
72+
sid = sec.get("id", "")
73+
title = sec.get("title", "")
74+
html = [f"<div class='section' id='{esc(sid)}'>"]
75+
html.append(f"<h3>{esc(sid)} · {esc(title)}</h3>")
76+
for key, val in sec.items():
77+
if key in ("id", "title"):
78+
continue
79+
html.append(
80+
f"<div class='sub'><h4>{esc(key)}</h4>{render_value(val)}</div>"
81+
)
82+
html.append("</div>")
83+
return "\n".join(html)
84+
85+
86+
def render_module(mod):
87+
mid = mod.get("id", "")
88+
title = mod.get("title", "")
89+
summary = mod.get("summary", "")
90+
sections = mod.get("sections", []) or []
91+
html = [f"<section class='module' id='{esc(mid)}'>"]
92+
html.append(f"<h2>{esc(mid)} · {esc(title)}</h2>")
93+
if summary:
94+
html.append(f"<p class='summary'>{esc(summary)}</p>")
95+
for sec in sections:
96+
html.append(render_section(sec))
97+
html.append("</section>")
98+
return "\n".join(html)
99+
100+
101+
def main():
102+
data = json.loads(SRC.read_text(encoding="utf-8"))
103+
meta = data["meta"]
104+
exec_sum = data["executiveSummary"]
105+
106+
modules = [data[k] for k in MODULE_ORDER if k in data]
107+
108+
toc_items = "".join(
109+
f"<li><a href='#{esc(m['id'])}'>{esc(m['id'])} · {esc(m['title'].split('—')[-1].strip()[:46])}</a></li>"
110+
for m in modules
111+
)
112+
toc_items += (
113+
"<li><a href='#schemas'>Schemas</a></li>"
114+
"<li><a href='#code-examples'>Code Examples</a></li>"
115+
"<li><a href='#case-studies'>Case Studies</a></li>"
116+
"<li><a href='#regulatory-matrix'>Regulatory Alignment</a></li>"
117+
"<li><a href='#api'>API Endpoints</a></li>"
118+
)
119+
120+
modules_html = "\n".join(render_module(m) for m in modules)
121+
122+
schemas_html = ""
123+
for name, sch in data.get("schemas", {}).items():
124+
schemas_html += (
125+
f"<details><summary>{esc(name)}</summary>"
126+
f"<pre><code>{esc(json.dumps(sch, indent=2))}</code></pre></details>"
127+
)
128+
129+
code_html = ""
130+
for name, code in data.get("codeExamples", {}).items():
131+
code_html += (
132+
f"<details><summary>{esc(name)}</summary>"
133+
f"<pre><code>{esc(code)}</code></pre></details>"
134+
)
135+
136+
cs_html = ""
137+
for cs in data.get("caseStudies", []):
138+
outcomes = cs.get("outcomes", {})
139+
outcomes_html = (
140+
kv_table(outcomes) if isinstance(outcomes, dict)
141+
else render_value(outcomes)
142+
)
143+
cs_html += (
144+
f"<div class='case'><h3>{esc(cs.get('id',''))} · {esc(cs.get('title',''))}</h3>"
145+
f"<p><strong>Sector:</strong> {esc(cs.get('sector',''))}</p>"
146+
f"<p>{esc(cs.get('summary',''))}</p>"
147+
f"<div class='sub'><h4>Outcomes</h4>{outcomes_html}</div>"
148+
"</div>"
149+
)
150+
151+
reg = meta.get("regulatoryAlignment", [])
152+
if isinstance(reg, list):
153+
reg_html = "<ul>" + "".join(f"<li>{esc(r)}</li>" for r in reg) + "</ul>"
154+
else:
155+
reg_html = esc(reg)
156+
157+
audience = meta.get("audience", [])
158+
audience_html = (
159+
"<ul>" + "".join(f"<li>{esc(a)}</li>" for a in audience) + "</ul>"
160+
if isinstance(audience, list) else esc(audience)
161+
)
162+
163+
horizon = meta.get("horizonMilestones", {})
164+
horizon_html = kv_table(horizon) if isinstance(horizon, dict) else esc(horizon)
165+
166+
inv = meta.get("deliverableInventory", {})
167+
inv_html = kv_table(inv) if isinstance(inv, dict) else esc(inv)
168+
169+
api = data.get("apiEndpoints", {"prefix": "/api/ent-agi-gov-master", "routes": []})
170+
api_items = "".join(
171+
f"<li><code>{esc(api['prefix'])}{esc(r)}</code></li>"
172+
for r in api.get("routes", [])
173+
)
174+
175+
n_modules = len(modules)
176+
total_sections = sum(len(m.get("sections", []) or []) for m in modules)
177+
n_schemas = len(data.get("schemas", {}))
178+
n_code = len(data.get("codeExamples", {}))
179+
n_cs = len(data.get("caseStudies", []))
180+
n_routes = len(api.get("routes", []))
181+
182+
page = f"""<!doctype html>
183+
<html lang="en">
184+
<head>
185+
<meta charset="utf-8" />
186+
<meta name="viewport" content="width=device-width,initial-scale=1" />
187+
<title>{esc(meta.get('docRef',''))}{esc(meta.get('title',''))}</title>
188+
<meta name="description" content="{esc(meta.get('subtitle',''))}" />
189+
<style>
190+
:root {{
191+
--bg:#070b1a; --panel:#0f1734; --panel2:#121d40; --fg:#eaf0fb; --muted:#8aa0c2;
192+
--accent:#7cc6ff; --accent2:#b693ff; --accent3:#ff9ec7; --line:#1d2a52;
193+
--ok:#58f0a7; --warn:#ffcb6b; --crit:#ff7a7a;
194+
}}
195+
* {{ box-sizing:border-box; }}
196+
body {{ margin:0; background:var(--bg); color:var(--fg);
197+
font:14px/1.55 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Inter,sans-serif; }}
198+
header.hero {{ padding:34px 38px;
199+
background:linear-gradient(135deg,#1a2566,#0a1235 55%,#070b1a);
200+
border-bottom:1px solid var(--line); }}
201+
header.hero .doc-ref {{ color:var(--accent3); font-size:12px; letter-spacing:1px;
202+
text-transform:uppercase; margin-bottom:6px; }}
203+
header.hero h1 {{ margin:0 0 10px; font-size:25px; letter-spacing:.2px; }}
204+
header.hero .subtitle {{ color:var(--muted); max-width:1100px; }}
205+
header.hero .badges {{ margin-top:16px; display:flex; gap:8px; flex-wrap:wrap; }}
206+
header.hero .badge {{ background:#19255a; color:var(--accent); padding:5px 12px;
207+
border-radius:999px; font-size:12px; border:1px solid var(--line); }}
208+
header.hero .badge.warn {{ color:var(--warn); border-color:#5a3f1a; background:#2a1f0d; }}
209+
header.hero .badge.ok {{ color:var(--ok); border-color:#1a4a31; background:#0c2a1c; }}
210+
header.hero .kpis {{ margin-top:18px; display:flex; gap:18px; flex-wrap:wrap; }}
211+
header.hero .kpi {{ background:#0d1532; border:1px solid var(--line); border-radius:10px;
212+
padding:10px 14px; min-width:130px; }}
213+
header.hero .kpi .v {{ font-size:20px; color:var(--accent2); font-weight:600; }}
214+
header.hero .kpi .l {{ font-size:11px; color:var(--muted); text-transform:uppercase;
215+
letter-spacing:.6px; }}
216+
nav.toc {{ position:sticky; top:0; background:#070b1aee; backdrop-filter:blur(8px);
217+
border-bottom:1px solid var(--line); padding:10px 20px; z-index:5; }}
218+
nav.toc ul {{ list-style:none; margin:0; padding:0; display:flex; flex-wrap:wrap; gap:6px; }}
219+
nav.toc li a {{ color:var(--accent); text-decoration:none; padding:4px 10px;
220+
border:1px solid var(--line); border-radius:6px; font-size:12px; }}
221+
nav.toc li a:hover {{ background:#141e44; }}
222+
main {{ padding:24px 36px 80px; max-width:1340px; }}
223+
section.module {{ background:var(--panel); border:1px solid var(--line);
224+
border-radius:12px; padding:22px 24px; margin:20px 0; }}
225+
section.module h2 {{ margin:0 0 8px; color:var(--accent2); font-size:18px; }}
226+
section.module .summary {{ color:var(--muted); margin:0 0 16px; }}
227+
.section {{ border-top:1px dashed var(--line); padding-top:14px; margin-top:14px; }}
228+
.section h3 {{ margin:0 0 8px; font-size:15px; color:var(--accent); }}
229+
.section .sub {{ margin:10px 0; }}
230+
.section .sub h4 {{ margin:0 0 6px; font-size:12px; color:var(--muted);
231+
text-transform:uppercase; letter-spacing:.5px; }}
232+
table.kv, table.grid {{ width:100%; border-collapse:collapse; font-size:13px;
233+
background:#0d1532; border:1px solid var(--line);
234+
border-radius:6px; overflow:hidden; }}
235+
table.kv td, table.grid td, table.grid th {{ padding:6px 10px;
236+
border-bottom:1px solid var(--line);
237+
vertical-align:top; text-align:left; }}
238+
table.kv td.k {{ color:var(--muted); width:30%; white-space:nowrap; }}
239+
table.grid th {{ background:#162248; color:var(--accent); font-weight:600; }}
240+
ul {{ margin:6px 0 6px 20px; padding:0; }}
241+
code {{ background:#0d1532; padding:1px 5px; border-radius:4px; color:var(--accent); }}
242+
pre {{ background:#0d1532; padding:12px; border-radius:6px; overflow:auto;
243+
border:1px solid var(--line); font-size:12px; }}
244+
details {{ background:#0d1532; border:1px solid var(--line); border-radius:6px;
245+
padding:8px 12px; margin:8px 0; }}
246+
details summary {{ cursor:pointer; color:var(--accent); }}
247+
.case {{ border-top:1px dashed var(--line); padding-top:14px; margin-top:14px; }}
248+
.case h3 {{ margin:0 0 8px; color:var(--accent3); font-size:15px; }}
249+
footer {{ color:var(--muted); border-top:1px solid var(--line);
250+
padding:16px 36px; font-size:12px; }}
251+
</style>
252+
</head>
253+
<body>
254+
<header class="hero">
255+
<div class="doc-ref">{esc(meta.get('docRef',''))} · {esc(meta.get('classification',''))}</div>
256+
<h1>{esc(meta.get('title',''))}</h1>
257+
<p class="subtitle">{esc(meta.get('subtitle',''))}</p>
258+
<div class="badges">
259+
<span class="badge">Version {esc(meta.get('version',''))}</span>
260+
<span class="badge">Date {esc(meta.get('date',''))}</span>
261+
<span class="badge">Horizon {esc(meta.get('horizon',''))}</span>
262+
<span class="badge warn">EU AI Act</span>
263+
<span class="badge warn">SR 11-7 Tier 1</span>
264+
<span class="badge">NIST AI RMF 1.0</span>
265+
<span class="badge">ISO/IEC 42001</span>
266+
<span class="badge ok">Basel III/IV · ICAAP</span>
267+
<span class="badge ok">FCRA / ECOA</span>
268+
</div>
269+
<div class="kpis">
270+
<div class="kpi"><div class="v">{n_modules}</div><div class="l">Modules</div></div>
271+
<div class="kpi"><div class="v">{total_sections}</div><div class="l">Sections</div></div>
272+
<div class="kpi"><div class="v">7</div><div class="l">Pillars (G1-G7)</div></div>
273+
<div class="kpi"><div class="v">16</div><div class="l">Regulatory Axes</div></div>
274+
<div class="kpi"><div class="v">9</div><div class="l">Reference Architectures</div></div>
275+
<div class="kpi"><div class="v">8</div><div class="l">Safety Protocols</div></div>
276+
<div class="kpi"><div class="v">{n_schemas}</div><div class="l">Schemas</div></div>
277+
<div class="kpi"><div class="v">{n_code}</div><div class="l">Code Examples</div></div>
278+
<div class="kpi"><div class="v">{n_cs}</div><div class="l">Case Studies</div></div>
279+
<div class="kpi"><div class="v">{n_routes}</div><div class="l">API Routes</div></div>
280+
</div>
281+
</header>
282+
<nav class="toc"><ul>{toc_items}</ul></nav>
283+
<main>
284+
<section class="module" id="exec">
285+
<h2>Executive Summary</h2>
286+
{kv_table(exec_sum)}
287+
</section>
288+
289+
<section class="module" id="meta">
290+
<h2>Document Metadata</h2>
291+
{kv_table({k: v for k, v in meta.items()
292+
if k not in ('audience', 'regulatoryAlignment',
293+
'horizonMilestones', 'deliverableInventory')})}
294+
<div class="section" id="audience">
295+
<h3>Audience</h3>
296+
{audience_html}
297+
</div>
298+
<div class="section" id="horizon">
299+
<h3>Horizon Milestones (2026-2030)</h3>
300+
{horizon_html}
301+
</div>
302+
<div class="section" id="inventory">
303+
<h3>Deliverable Inventory</h3>
304+
{inv_html}
305+
</div>
306+
</section>
307+
308+
{modules_html}
309+
310+
<section class="module" id="regulatory-matrix">
311+
<h2>Regulatory Alignment (Headline)</h2>
312+
<p class="summary">Master crosswalk lives in <code>M2 — Regulatory Alignment Matrix</code>; the headline list of 16 axes:</p>
313+
{reg_html}
314+
</section>
315+
316+
<section class="module" id="schemas">
317+
<h2>JSON Schemas</h2>
318+
<p class="summary">{n_schemas} schemas covering governance artefacts, compute registry, model risk records, fairness reports, policy decisions, treaty disclosures.</p>
319+
{schemas_html}
320+
</section>
321+
322+
<section class="module" id="code-examples">
323+
<h2>Code Examples</h2>
324+
<p class="summary">{n_code} reference implementations: OPA/Rego policies, Terraform GaC modules, Merkle WORM audit, CI/CD pipeline, governance sidecar, fairness gate, kinetic kill-switch, regulator report templates.</p>
325+
{code_html}
326+
</section>
327+
328+
<section class="module" id="case-studies">
329+
<h2>Case Studies</h2>
330+
<p class="summary">{n_cs} reference deployments across G-SIFI, Fortune 500, Global 2000, asset management, frontier AI lab, and sovereign-cloud government tiers.</p>
331+
{cs_html}
332+
</section>
333+
334+
<section class="module" id="api">
335+
<h2>API Endpoints</h2>
336+
<p class="summary">Prefix: <code>{esc(api.get('prefix',''))}</code> · Total planned: {n_routes}</p>
337+
<ul>{api_items}</ul>
338+
</section>
339+
</main>
340+
<footer>
341+
© {esc(meta.get('docRef',''))} v{esc(meta.get('version',''))} ·
342+
{esc(meta.get('date',''))} · {esc(meta.get('classification',''))} ·
343+
Owner: {esc(meta.get('owner',''))}
344+
</footer>
345+
</body>
346+
</html>
347+
"""
348+
OUT.parent.mkdir(parents=True, exist_ok=True)
349+
OUT.write_text(page, encoding="utf-8")
350+
size_kb = OUT.stat().st_size // 1024
351+
print(f"Wrote {OUT} ({size_kb} KB)")
352+
print(
353+
f"Modules: {n_modules} | Sections: {total_sections} | "
354+
f"Schemas: {n_schemas} | Code: {n_code} | Cases: {n_cs} | "
355+
f"Routes: {n_routes}"
356+
)
357+
358+
359+
if __name__ == "__main__":
360+
main()

0 commit comments

Comments
 (0)