Skip to content

Commit 69209bf

Browse files
Merge branch 'main' into dependabot/pip/pip-590e9db7b9
2 parents c015337 + 5af43db commit 69209bf

16 files changed

Lines changed: 11197 additions & 3 deletions

rag-agentic-dashboard/data/agi-regulator-resilient.json

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

rag-agentic-dashboard/data/ent-agi-ref-impl.json

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

rag-agentic-dashboard/data/gsifi-aims-blueprint.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1609,4 +1609,4 @@
16091609
"/m12"
16101610
]
16111611
}
1612-
}
1612+
}

rag-agentic-dashboard/data/inst-agi-master.json

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

rag-agentic-dashboard/gen-agi-regulator-resilient-html.py

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

rag-agentic-dashboard/gen-agi-regulator-resilient.py

Lines changed: 1487 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
#!/usr/bin/env python3
2+
"""
3+
WP-040 — HTML dashboard renderer for the Enterprise AGI/ASI Governance Master
4+
Reference & Implementation Blueprint.
5+
6+
Reads data/ent-agi-ref-impl.json and writes public/ent-agi-ref-impl.html.
7+
"""
8+
import html
9+
import json
10+
from pathlib import Path
11+
12+
ROOT = Path(__file__).parent
13+
SRC = ROOT / "data" / "ent-agi-ref-impl.json"
14+
OUT = ROOT / "public" / "ent-agi-ref-impl.html"
15+
16+
MODULE_ORDER = [
17+
"M1_governance", "M2_regulatory", "M3_architecture", "M4_sectorMrm",
18+
"M5_safety", "M6_global", "M7_sentinel", "M8_workflowai",
19+
"M9_eaip", "M10_hub", "M11_kpis", "M12_incident",
20+
"M13_roadmap", "M14_audience",
21+
]
22+
23+
24+
def esc(v):
25+
if v is None:
26+
return ""
27+
if isinstance(v, (dict, list)):
28+
return html.escape(json.dumps(v, indent=2, ensure_ascii=False))
29+
return html.escape(str(v))
30+
31+
32+
def render_value(v):
33+
if isinstance(v, list):
34+
if not v:
35+
return "<em>—</em>"
36+
if all(isinstance(x, str) for x in v):
37+
return "<ul>" + "".join(f"<li>{esc(x)}</li>" for x in v) + "</ul>"
38+
return "<ul>" + "".join(f"<li><pre class='inline'>{esc(x)}</pre></li>" for x in v) + "</ul>"
39+
if isinstance(v, dict):
40+
rows = "".join(f"<tr><th>{esc(k)}</th><td>{render_value(val)}</td></tr>"
41+
for k, val in v.items())
42+
return f"<table class='kv'>{rows}</table>"
43+
return esc(v)
44+
45+
46+
def render_section(s):
47+
sid = s.get("id", "")
48+
title = s.get("title", "")
49+
parts = [f"<div class='section' id='{esc(sid)}'>"
50+
f"<h4>{esc(sid)}{esc(title)}</h4>"]
51+
for k, v in s.items():
52+
if k in ("id", "title"):
53+
continue
54+
parts.append(f"<div class='field'><div class='fk'>{esc(k)}</div>"
55+
f"<div class='fv'>{render_value(v)}</div></div>")
56+
parts.append("</div>")
57+
return "".join(parts)
58+
59+
60+
def render_module(m):
61+
mid = m.get("id", "")
62+
title = m.get("title", "")
63+
summary = m.get("summary", "")
64+
sections = m.get("sections", [])
65+
body = "".join(render_section(s) for s in sections)
66+
return (f"<section class='module' id='{esc(mid)}'>"
67+
f"<h2>{esc(title)}</h2>"
68+
f"<p class='summary'>{esc(summary)}</p>{body}</section>")
69+
70+
71+
def main():
72+
data = json.loads(SRC.read_text())
73+
meta = data.get("meta", {})
74+
es = data.get("executiveSummary", {})
75+
76+
n_modules = sum(1 for k in MODULE_ORDER if k in data)
77+
n_sections = sum(len(data[k].get("sections", [])) for k in MODULE_ORDER if k in data)
78+
n_schemas = len(data.get("schemas", {}))
79+
n_code = len(data.get("codeExamples", []))
80+
n_cases = len(data.get("caseStudies", []))
81+
n_routes = len(data.get("apiEndpoints", []))
82+
83+
toc_items = "".join(
84+
f"<li><a href='#{esc(data[k]['id'])}'>{esc(data[k]['id'])} — "
85+
f"{esc(data[k]['title'].split(' — ', 1)[-1] if ' — ' in data[k]['title'] else data[k]['title'])}</a></li>"
86+
for k in MODULE_ORDER if k in data
87+
)
88+
modules_html = "".join(render_module(data[k]) for k in MODULE_ORDER if k in data)
89+
90+
schemas_html = "".join(
91+
f"<div class='card'><h4>{esc(name)}</h4>"
92+
f"<p>{esc(spec.get('title', ''))}</p>"
93+
f"<pre>{esc(spec.get('fields', []))}</pre></div>"
94+
for name, spec in data.get("schemas", {}).items()
95+
)
96+
code_html = "".join(
97+
f"<tr><td>{esc(c.get('id'))}</td><td>{esc(c.get('title'))}</td>"
98+
f"<td>{esc(c.get('language'))}</td><td>{esc(c.get('lines'))}</td></tr>"
99+
for c in data.get("codeExamples", [])
100+
)
101+
cases_html = "".join(
102+
f"<tr><td>{esc(c.get('id'))}</td><td>{esc(c.get('title'))}</td>"
103+
f"<td>{esc(c.get('outcome'))}</td></tr>"
104+
for c in data.get("caseStudies", [])
105+
)
106+
routes_html = "".join(f"<li><code>{esc(r)}</code></li>" for r in data.get("apiEndpoints", []))
107+
reg_html = "".join(f"<li>{esc(r)}</li>" for r in meta.get("regulatoryAlignment", []))
108+
builds_html = "".join(f"<li>{esc(r)}</li>" for r in meta.get("buildsOn", []))
109+
aud_html = "".join(f"<li>{esc(a)}</li>" for a in meta.get("audience", []))
110+
outcomes_html = "".join(f"<li>{esc(o)}</li>" for o in es.get("keyOutcomes", []))
111+
principles_html = "".join(f"<li>{esc(p)}</li>" for p in es.get("designPrinciples", []))
112+
113+
page = f"""<!DOCTYPE html>
114+
<html lang="en">
115+
<head>
116+
<meta charset="UTF-8">
117+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
118+
<title>{esc(meta.get('docRef'))}{esc(meta.get('title'))}</title>
119+
<style>
120+
*{{box-sizing:border-box}}
121+
body{{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;margin:0;padding:0;background:#0b1220;color:#e8edf5;line-height:1.5}}
122+
header{{background:linear-gradient(135deg,#0a2540 0%,#1a365d 100%);padding:32px 24px;border-bottom:3px solid #4f8af0}}
123+
h1{{margin:0 0 8px 0;font-size:1.85rem}}
124+
h2{{color:#7eb6ff;border-bottom:1px solid #2a3a5a;padding-bottom:6px;margin-top:32px}}
125+
h3{{color:#b9d3ff}}
126+
h4{{color:#c8dcff;margin:14px 0 6px 0}}
127+
.container{{max-width:1280px;margin:0 auto;padding:24px}}
128+
.badges{{margin-top:12px}}
129+
.badge{{display:inline-block;background:#1a365d;color:#cfe0ff;padding:4px 10px;border-radius:14px;font-size:0.78rem;margin:3px 4px 0 0;border:1px solid #4f8af0}}
130+
.kpi-grid{{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;margin-top:16px}}
131+
.kpi-card{{background:#142037;border:1px solid #2a3a5a;border-radius:8px;padding:14px;text-align:center}}
132+
.kpi-num{{font-size:1.6rem;font-weight:700;color:#7eb6ff}}
133+
.kpi-label{{font-size:0.82rem;color:#a8b9d4;margin-top:4px}}
134+
.toc{{background:#142037;border:1px solid #2a3a5a;padding:16px 20px;border-radius:8px;margin:16px 0}}
135+
.toc ul{{margin:6px 0 0 0;padding-left:20px;columns:2}}
136+
.toc a{{color:#7eb6ff;text-decoration:none}}
137+
.toc a:hover{{text-decoration:underline}}
138+
.module{{background:#0f1a2e;border:1px solid #2a3a5a;border-radius:10px;padding:20px;margin:18px 0}}
139+
.section{{background:#142037;border-left:3px solid #4f8af0;border-radius:6px;padding:12px 14px;margin:10px 0}}
140+
.summary{{font-style:italic;color:#a8b9d4}}
141+
.field{{margin:8px 0}}
142+
.fk{{font-weight:600;color:#b9d3ff;font-size:0.86rem;text-transform:uppercase;letter-spacing:0.3px}}
143+
.fv{{margin-top:4px}}
144+
table{{border-collapse:collapse;width:100%;margin:8px 0}}
145+
table.kv th{{text-align:left;background:#1a2944;color:#cfe0ff;font-weight:600;padding:6px 10px;border:1px solid #2a3a5a;width:30%;vertical-align:top}}
146+
table.kv td{{padding:6px 10px;border:1px solid #2a3a5a;background:#0f1a2e;vertical-align:top}}
147+
table.std{{margin-top:10px}}
148+
table.std th, table.std td{{padding:8px 10px;border:1px solid #2a3a5a;text-align:left;background:#0f1a2e}}
149+
table.std th{{background:#1a2944;color:#cfe0ff}}
150+
ul{{margin:4px 0 4px 0;padding-left:20px}}
151+
pre{{background:#0a1426;border:1px solid #2a3a5a;padding:8px;border-radius:6px;overflow:auto;font-size:0.82rem;color:#cfe0ff}}
152+
pre.inline{{display:inline-block;padding:2px 6px;margin:0;font-size:0.8rem}}
153+
code{{background:#0a1426;padding:1px 6px;border-radius:4px;color:#7eb6ff;font-size:0.82rem}}
154+
.cards{{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:12px}}
155+
.card{{background:#142037;border:1px solid #2a3a5a;border-radius:8px;padding:12px}}
156+
.routes{{columns:2;list-style:none;padding-left:0}}
157+
.routes li{{margin:2px 0;break-inside:avoid}}
158+
footer{{text-align:center;padding:24px;color:#6b7a99;font-size:0.85rem;border-top:1px solid #2a3a5a;margin-top:32px}}
159+
</style>
160+
</head>
161+
<body>
162+
<header>
163+
<div class="container">
164+
<h1>{esc(meta.get('title'))}</h1>
165+
<p style="color:#cfe0ff;margin:6px 0 0 0">{esc(meta.get('subtitle'))}</p>
166+
<div class="badges">
167+
<span class="badge">{esc(meta.get('docRef'))}</span>
168+
<span class="badge">v{esc(meta.get('version'))}</span>
169+
<span class="badge">{esc(meta.get('horizon'))}</span>
170+
<span class="badge">{esc(meta.get('classification'))}</span>
171+
</div>
172+
<div class="badges" style="margin-top:8px">
173+
<span class="badge">EU AI Act 2026</span>
174+
<span class="badge">NIST AI RMF 1.0</span>
175+
<span class="badge">ISO/IEC 42001</span>
176+
<span class="badge">GDPR</span>
177+
<span class="badge">SR 11-7</span>
178+
<span class="badge">Basel III/IV</span>
179+
<span class="badge">PRA / FCA / MAS / HKMA</span>
180+
<span class="badge">US EO 14110</span>
181+
<span class="badge">SLSA L3 + Sigstore</span>
182+
</div>
183+
</div>
184+
</header>
185+
186+
<div class="container">
187+
188+
<div class="kpi-grid">
189+
<div class="kpi-card"><div class="kpi-num">{n_modules}</div><div class="kpi-label">Modules</div></div>
190+
<div class="kpi-card"><div class="kpi-num">{n_sections}</div><div class="kpi-label">Sections</div></div>
191+
<div class="kpi-card"><div class="kpi-num">8</div><div class="kpi-label">Architectural Planes</div></div>
192+
<div class="kpi-card"><div class="kpi-num">320</div><div class="kpi-label">Controls</div></div>
193+
<div class="kpi-card"><div class="kpi-num">18</div><div class="kpi-label">KPIs</div></div>
194+
<div class="kpi-card"><div class="kpi-num">{n_schemas}</div><div class="kpi-label">JSON Schemas</div></div>
195+
<div class="kpi-card"><div class="kpi-num">{n_code}</div><div class="kpi-label">Code Examples</div></div>
196+
<div class="kpi-card"><div class="kpi-num">{n_cases}</div><div class="kpi-label">Case Studies</div></div>
197+
<div class="kpi-card"><div class="kpi-num">{n_routes}</div><div class="kpi-label">API Routes</div></div>
198+
</div>
199+
200+
<h2>Executive Summary</h2>
201+
<div class="card">
202+
<h3>Purpose</h3>
203+
<p>{esc(es.get('purpose'))}</p>
204+
<h3>Scope</h3>
205+
<p>{esc(es.get('scope'))}</p>
206+
<h3>Design Principles</h3>
207+
<ul>{principles_html}</ul>
208+
<h3>Key Outcomes</h3>
209+
<ul>{outcomes_html}</ul>
210+
<h3>Board Narrative</h3>
211+
<p>{esc(es.get('boardNarrative'))}</p>
212+
</div>
213+
214+
<h2>Builds On (Workpackage Lineage)</h2>
215+
<ul>{builds_html}</ul>
216+
217+
<h2>Document Metadata</h2>
218+
<table class="kv">
219+
<tr><th>Owner</th><td>{esc(meta.get('owner'))}</td></tr>
220+
<tr><th>Audience</th><td><ul>{aud_html}</ul></td></tr>
221+
<tr><th>Subject System</th><td>{render_value(meta.get('subjectSystem') or {})}</td></tr>
222+
<tr><th>Deliverable Inventory</th><td>{render_value(meta.get('deliverableInventory') or {})}</td></tr>
223+
</table>
224+
225+
<h2>Regulatory Alignment</h2>
226+
<ul>{reg_html}</ul>
227+
228+
<h2>Table of Contents</h2>
229+
<div class="toc"><ul>{toc_items}</ul></div>
230+
231+
{modules_html}
232+
233+
<h2>JSON Schemas ({n_schemas})</h2>
234+
<div class="cards">{schemas_html}</div>
235+
236+
<h2>Code Examples ({n_code})</h2>
237+
<table class="std">
238+
<thead><tr><th>ID</th><th>Title</th><th>Language</th><th>Lines</th></tr></thead>
239+
<tbody>{code_html}</tbody>
240+
</table>
241+
242+
<h2>Case Studies ({n_cases})</h2>
243+
<table class="std">
244+
<thead><tr><th>ID</th><th>Title</th><th>Outcome</th></tr></thead>
245+
<tbody>{cases_html}</tbody>
246+
</table>
247+
248+
<h2>API Endpoints ({n_routes})</h2>
249+
<ul class="routes">{routes_html}</ul>
250+
251+
<footer>
252+
{esc(meta.get('docRef'))} v{esc(meta.get('version'))} · {esc(meta.get('horizon'))}<br>
253+
Builds on WP-035 + WP-036 + WP-037 + WP-038 + WP-039
254+
</footer>
255+
256+
</div>
257+
</body>
258+
</html>
259+
"""
260+
261+
OUT.parent.mkdir(parents=True, exist_ok=True)
262+
OUT.write_text(page)
263+
size_kb = OUT.stat().st_size / 1024
264+
print(f"[OK] Generated {OUT} ({size_kb:.1f} KB)")
265+
print(f" modules={n_modules} sections={n_sections} schemas={n_schemas} "
266+
f"code={n_code} cases={n_cases} routes={n_routes}")
267+
268+
269+
if __name__ == "__main__":
270+
main()

0 commit comments

Comments
 (0)