Skip to content

Commit fdcc926

Browse files
Merge pull request #13 from OneFineStarstuff/genspark_ai_developer
Genspark ai developer
2 parents 44f91fa + e0b9110 commit fdcc926

27 files changed

Lines changed: 616 additions & 5 deletions

File tree

next-app/app/api/chat/stream/route.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,18 @@ function* fakeStream(text: string) {
88
}
99
}
1010

11+
import { preFilter, steerPrompt, postModerate } from '@/lib/safety/pipeline';
12+
1113
function streamForMessage(message: string) {
1214
const ctrl = new AbortController();
1315
const stream = new ReadableStream<Uint8Array>({
1416
async start(controller) {
1517
try {
16-
const reply = `Echo: ${message}`;
17-
const meta = { layer: 'surface', model: 'mock', version: '0.0.1', latencyMs: 42 };
18+
const pre = preFilter(message);
19+
const safePrompt = steerPrompt(message);
20+
const reply = `Echo: ${safePrompt}`;
21+
const post = postModerate(reply);
22+
const meta = { layer: 'surface', model: 'mock', version: '0.0.1', latencyMs: 42, pre, post };
1823
controller.enqueue(encode(`event: meta\ndata: ${JSON.stringify(meta)}\n\n`));
1924
for (const chunk of fakeStream(reply)) {
2025
await new Promise(r => setTimeout(r, 10));

next-app/app/api/consent/route.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { NextRequest } from 'next/server';
2+
import { appendConsentEvent, exportConsent } from '@/lib/privacy/consentLedger';
3+
4+
export const runtime = 'nodejs';
5+
6+
export async function POST(req: NextRequest) {
7+
const { userId = 'demo', sessionId, action } = await req.json();
8+
if (!['persist_on','persist_off','export'].includes(action)) return new Response('bad action', { status: 400 });
9+
const ev = await appendConsentEvent({ userId, sessionId, action, ts: new Date().toISOString() as any });
10+
return Response.json(ev);
11+
}
12+
13+
export async function GET(req: NextRequest) {
14+
const { searchParams } = new URL(req.url);
15+
const userId = searchParams.get('userId') ?? 'demo';
16+
const data = await exportConsent(userId);
17+
return Response.json(data);
18+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export const runtime = 'nodejs';
2+
export async function GET() {
3+
// Mock time-series risk per layer: core/operational/context
4+
const now = Date.now();
5+
const series = ['core','operational','context'].map((k, i) => ({
6+
key: k,
7+
points: Array.from({ length: 12 }, (_, j) => ({ t: now - (11 - j) * 3600_000, v: clamp(0, 100, 30 + i*20 + Math.sin(j/2+i)*15 + Math.random()*10) }))
8+
}));
9+
return Response.json({ series });
10+
}
11+
function clamp(min:number,max:number,v:number){return Math.max(min,Math.min(max,v));}

next-app/app/chat/page.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export default function ChatPage() {
4949

5050
return (
5151
<div className="space-y-4">
52-
<h1 className="text-2xl font-semibold">Chat</h1>
52+
<h1 className="text-2xl font-semibold">Chat <span className="text-xs align-middle text-slate-500">(ephemeral by default)</span></h1>
5353
<div className="rounded border bg-white p-3">
5454
<div className="space-y-3" role="log" aria-live="polite">
5555
{messages.map((m, i) => (
@@ -63,10 +63,11 @@ export default function ChatPage() {
6363
</div>
6464
))}
6565
</div>
66-
<div className="mt-3 flex gap-2">
66+
<div className="mt-3 flex flex-wrap items-center gap-2">
6767
<input value={input} onChange={e=>setInput(e.target.value)} className="flex-1 rounded border px-3 py-2" placeholder="Type a message..." />
6868
<button onClick={send} disabled={streaming} className="rounded bg-amber-600 px-4 py-2 text-white disabled:opacity-50">Send</button>
6969
{fallback && <span className="text-xs text-slate-500">Fallback in use</span>}
70+
<a href="/api/consent?userId=demo" target="_blank" className="text-xs text-amber-700 underline">Export consent ledger</a>
7071
</div>
7172
</div>
7273
</div>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { readFileSync } from 'fs';
2+
import path from 'path';
3+
export const dynamic = 'force-static';
4+
export default function Page() {
5+
const md = readFileSync(path.join(process.cwd(), 'next-app', 'docs', 'governance-terms-mapping.md'), 'utf8');
6+
return <pre className="whitespace-pre-wrap text-sm">{md}</pre>;
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { readFileSync } from 'fs';
2+
import path from 'path';
3+
export const dynamic = 'force-static';
4+
export default function Page() {
5+
const md = readFileSync(path.join(process.cwd(), 'next-app', 'docs', 'readiness-checklist.md'), 'utf8');
6+
return <pre className="whitespace-pre-wrap text-sm">{md}</pre>;
7+
}

next-app/app/docs/roadmap/page.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { readFileSync } from 'fs';
2+
import path from 'path';
3+
export const dynamic = 'force-static';
4+
export default function Page() {
5+
const md = readFileSync(path.join(process.cwd(), 'next-app', 'docs', 'roadmap.md'), 'utf8');
6+
return <pre className="whitespace-pre-wrap text-sm">{md}</pre>;
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { readFileSync } from 'fs';
2+
import path from 'path';
3+
export const dynamic = 'force-static';
4+
export default function Page() {
5+
const md = readFileSync(path.join(process.cwd(), 'next-app', 'docs', 'strategy-map.md'), 'utf8');
6+
return <pre className="whitespace-pre-wrap text-sm">{md}</pre>;
7+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import { readFileSync } from 'fs';
2+
import path from 'path';
3+
4+
export const metadata = { title: 'Governance Capability Matrix' } as const;
5+
export const dynamic = 'force-static';
6+
7+
type Dimension = {
8+
id: string;
9+
name: string;
10+
phase: string;
11+
score: number; // 0-5
12+
evidence: string[];
13+
gaps: string[];
14+
remediation: string[];
15+
links?: Record<string, string>;
16+
};
17+
18+
type Maturity = { dimensions: Dimension[] };
19+
20+
function gateText(score: number) {
21+
if (score < 2) return { label: 'Do not advance', color: '#dc2626', note: 'Address gaps before proceeding' };
22+
if (score < 4) return { label: 'Proceed with guardrails', color: '#f59e0b', note: 'Monitor and document mitigations' };
23+
return { label: 'Clear to advance', color: '#16a34a', note: 'Maintain controls and evidence' };
24+
}
25+
26+
function scoreColor(score: number) {
27+
if (score <= 1) return '#b91c1c';
28+
if (score === 2) return '#e11d48';
29+
if (score === 3) return '#f59e0b';
30+
if (score === 4) return '#10b981';
31+
return '#059669';
32+
}
33+
34+
export default function Page() {
35+
const file = path.join(process.cwd(), 'next-app', 'data', 'maturity.json');
36+
const data: Maturity = JSON.parse(readFileSync(file, 'utf8'));
37+
return (
38+
<main className="space-y-4">
39+
<h1 className="text-2xl font-semibold">Governance Capability Matrix</h1>
40+
<p className="text-sm text-slate-600">Scores (0–5), evidence, gaps, remediation and gating guidance per dimension.</p>
41+
42+
<div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
43+
{data.dimensions.map((d) => {
44+
const gate = gateText(d.score);
45+
return (
46+
<section key={d.id} className="rounded border bg-white p-4 shadow-sm">
47+
<header className="mb-2 flex items-center justify-between">
48+
<div>
49+
<div className="text-base font-semibold text-slate-800">{d.name}</div>
50+
<div className="text-xs text-slate-500">Phase: {d.phase}</div>
51+
</div>
52+
<div className="text-right">
53+
<span className="inline-flex items-center gap-1 rounded border px-2 py-0.5 text-xs" style={{ borderColor: scoreColor(d.score), color: scoreColor(d.score) }}>
54+
Score <strong className="ml-1">{d.score}</strong>
55+
</span>
56+
<div className="mt-1 text-xs" style={{ color: gate.color }}>{gate.label}</div>
57+
</div>
58+
</header>
59+
60+
{d.evidence?.length ? (
61+
<div className="mb-2">
62+
<div className="mb-1 text-xs font-semibold text-slate-700">Evidence</div>
63+
<ul className="list-disc pl-5 text-sm text-slate-700">
64+
{d.evidence.map((e, i) => (<li key={i}>{e}</li>))}
65+
</ul>
66+
</div>
67+
) : null}
68+
69+
{d.gaps?.length ? (
70+
<div className="mb-2">
71+
<div className="mb-1 text-xs font-semibold text-slate-700">Gaps</div>
72+
<ul className="list-disc pl-5 text-sm text-slate-700">
73+
{d.gaps.map((g, i) => (<li key={i}>{g}</li>))}
74+
</ul>
75+
<div className="mt-2 rounded bg-red-50 p-2 text-xs text-red-700">{gate.note}</div>
76+
</div>
77+
) : null}
78+
79+
{d.remediation?.length ? (
80+
<div className="mb-2">
81+
<div className="mb-1 text-xs font-semibold text-slate-700">Remediation</div>
82+
<ul className="list-disc pl-5 text-sm text-slate-700">
83+
{d.remediation.map((r, i) => (<li key={i}>{r}</li>))}
84+
</ul>
85+
</div>
86+
) : null}
87+
88+
{d.links && Object.keys(d.links).length > 0 ? (
89+
<div className="mt-3 flex flex-wrap gap-2 text-xs">
90+
{Object.entries(d.links).map(([k, v]) => (
91+
<a key={k} href={v} className="rounded border border-amber-300 bg-amber-50 px-2 py-1 text-amber-800 underline">
92+
{k}
93+
</a>
94+
))}
95+
</div>
96+
) : null}
97+
</section>
98+
);
99+
})}
100+
</div>
101+
</main>
102+
);
103+
}

next-app/app/governance/page.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import Link from 'next/link';
2+
3+
export const metadata = { title: 'Governance Cockpit' };
4+
export default function GovernancePage() {
5+
return (
6+
<main className="space-y-4">
7+
<h1 className="text-2xl font-semibold">Governance Cockpit</h1>
8+
<p className="text-sm text-slate-600">Board-ready artifact hub with live roadmap, mappings, and templates.</p>
9+
<ul className="list-disc pl-6 text-amber-800">
10+
<li><Link href="/docs/roadmap" className="underline">Roadmap (capacity-aware)</Link></li>
11+
<li><Link href="/docs/governance-terms-mapping" className="underline">Integrated 18‑Point Mapping</Link></li>
12+
<li><Link href="/docs/readiness-checklist" className="underline">Implementation Readiness Checklist</Link></li>
13+
<li><Link href="/templates/artefact-templates" className="underline">Governance Artefact Templates</Link></li>
14+
<li><Link href="/governance/maturity" className="underline">Governance Capability Matrix</Link></li>
15+
<li><Link href="/risk" className="underline">Interactive Risk & Governance Demos</Link></li>
16+
</ul>
17+
</main>
18+
);
19+
}

0 commit comments

Comments
 (0)