Skip to content

Commit 283d3ac

Browse files
committed
Refactor docs delivery, improve accessibility, and expand CI checks
1 parent 120f5b3 commit 283d3ac

19 files changed

Lines changed: 497 additions & 314 deletions

.github/workflows/ci.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,19 @@ jobs:
2020
- run: npm ci
2121

2222
- name: Lint
23-
run: npx eslint src/
23+
run: npm run lint
2424

2525
- name: Format check
26-
run: npx prettier --check src/
26+
run: npm run format:check
2727

2828
- name: Dependency audit
2929
run: npm audit --audit-level=high
3030

31+
- name: Test
32+
run: npm run test
33+
34+
- name: Docs build
35+
run: npm run docs
36+
3137
- name: Build
3238
run: npm run build

.github/workflows/deploy.yml

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,23 +41,8 @@ jobs:
4141
env:
4242
VITE_BASE_PATH: ${{ steps.base.outputs.path }}
4343

44-
- name: Install Asciidoctor
45-
run: sudo gem install asciidoctor --no-document
46-
4744
- name: Render AsciiDoc documentation
48-
run: |
49-
mkdir -p dist/docs
50-
asciidoctor \
51-
-a icons=font \
52-
-a source-highlighter=highlight.js \
53-
-a linkcss! \
54-
-a toc=left \
55-
-a toclevels=3 \
56-
-a sectanchors \
57-
-a sectlinks \
58-
-D dist/docs \
59-
docs/risk-radar.adoc \
60-
docs/risk-radar-en.adoc
45+
run: npm run docs
6146

6247
- name: Upload artifact
6348
uses: actions/upload-pages-artifact@v3

README.adoc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ npm run preview
4444

4545
Output in `dist/`.
4646

47+
=== Keyboard E2E Tests
48+
49+
[source,bash]
50+
----
51+
npm install -D @playwright/test
52+
npx playwright install
53+
npm run test:e2e
54+
----
55+
4756
== GitHub Pages Deployment
4857

4958
The included GitHub Action (`.github/workflows/deploy.yml`) handles everything automatically:

e2e/keyboard-navigation.spec.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { expect, test } from "@playwright/test";
2+
3+
test.describe("Mitigation accordion keyboard navigation", () => {
4+
test("toggles a mitigation section with Enter", async ({ page }) => {
5+
await page.goto("/");
6+
7+
const tierOneToggle = page.locator("button[aria-controls='tier-1-measures']");
8+
await expect(tierOneToggle).toHaveAttribute("aria-expanded", "false");
9+
10+
await tierOneToggle.focus();
11+
await page.keyboard.press("Enter");
12+
await expect(tierOneToggle).toHaveAttribute("aria-expanded", "true");
13+
await expect(page.locator("#tier-1-measures")).toBeVisible();
14+
});
15+
16+
test("toggles a mitigation section with Space", async ({ page }) => {
17+
await page.goto("/");
18+
19+
const tierOneToggle = page.locator("button[aria-controls='tier-1-measures']");
20+
await tierOneToggle.focus();
21+
22+
await page.keyboard.press("Space");
23+
await expect(tierOneToggle).toHaveAttribute("aria-expanded", "true");
24+
25+
await page.keyboard.press("Space");
26+
await expect(tierOneToggle).toHaveAttribute("aria-expanded", "false");
27+
});
28+
});

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
"dev": "vite",
88
"build": "vite build",
99
"preview": "vite preview",
10-
"docs": "asciidoctor -a icons=font -a source-highlighter=highlight.js -a linkcss -a stylesheet=asciidoctor.css -D dist/docs docs/risk-radar.adoc docs/risk-radar-en.adoc",
10+
"docs": "node scripts/render-docs.mjs",
11+
"lint": "eslint src/",
12+
"format:check": "prettier --check src/",
13+
"test": "node --test src/**/*.test.js",
14+
"test:e2e": "playwright test",
1115
"prepare": "husky"
1216
},
1317
"dependencies": {

playwright.config.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { defineConfig } from "@playwright/test";
2+
3+
export default defineConfig({
4+
testDir: "./e2e",
5+
use: {
6+
baseURL: "http://127.0.0.1:4173",
7+
headless: true,
8+
},
9+
webServer: {
10+
command: "npm run dev -- --host 127.0.0.1 --port 4173",
11+
url: "http://127.0.0.1:4173",
12+
reuseExistingServer: true,
13+
timeout: 120000,
14+
},
15+
});

public/docs/sidebar-de.json

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"title": "Dokumentation",
3+
"sections": [
4+
{
5+
"id": "disclaimer",
6+
"title": "Hinweis",
7+
"html": "<div class=\"paragraph\">\n<p>Dieses Tool bietet eine <strong>allgemeine Orientierungshilfe</strong> zur Risikoeinschätzung von AI-generiertem Code. Die vorgeschlagenen Tier-Einstufungen und Maßnahmen ersetzen keine individuelle Sicherheitsbewertung und sind nicht für jeden Kontext gleichermaßen geeignet.</p>\n</div>\n<div class=\"paragraph\">\n<p>Jede Organisation sollte die Dimensionen, Schwellwerte und Maßnahmen an ihre eigenen Anforderungen, regulatorischen Rahmenbedingungen und Risikobereitschaft anpassen. Der gesamte Quellcode ist <a href=\"https://github.com/LLM-Coding/vibe-coding-risk-radar\">Open Source (MIT)</a> — Anpassungen sind ausdrücklich erwünscht.</p>\n</div>\n<div class=\"paragraph\">\n<p>Feedback, Verbesserungsvorschläge und Fehlerberichte bitte als <a href=\"https://github.com/LLM-Coding/vibe-coding-risk-radar/issues\">GitHub Issue</a> oder direkt an <a href=\"https://www.linkedin.com/in/rdmueller\">Ralf D. Müller</a>.</p>\n</div>"
8+
},
9+
{
10+
"id": "intro",
11+
"title": "Warum dieses Framework?",
12+
"html": "<div class=\"paragraph\">\n<p>LLM-generierter Code enthält in ca. 45% der Fälle Sicherheitslücken (<a href=\"https://www.veracode.com/blog/ai-generated-code-security-risks/\">Veracode, 2025</a>). Gleichzeitig schreiben LLMs bereits über 30% des neuen Codes bei Google und Microsoft. Das Problem: Nicht jeder Code ist gleich riskant. CSS-Styling für eine Landingpage ohne Review zu deployen ist etwas grundlegend anderes als ein Auth-Modul für eine Fintech-App.</p>\n</div>\n<div class=\"paragraph\">\n<p>Dieses Framework bietet eine <a href=\"https://github.com/LLM-Coding/Semantic-Anchors?tab=readme-ov-file#262-mece-principle\">MECE</a>-Risikokategorisierung (Mutually Exclusive, Collectively Exhaustive), die auf etablierten Safety-Standards (<a href=\"https://www.perforce.com/blog/qac/what-iec-61508-safety-integrity-levels-sils\">IEC 61508</a>, <a href=\"https://en.wikipedia.org/wiki/DO-178C\">DO-178C</a>, <a href=\"https://en.wikipedia.org/wiki/ISO_26262\">ISO 26262</a>) aufbaut und sie auf Vibe-Coding anwendet.</p>\n</div>"
13+
},
14+
{
15+
"id": "dims",
16+
"title": "Die fünf Dimensionen",
17+
"html": "<div class=\"paragraph\">\n<p>Das Gesamtrisiko ergibt sich aus dem Maximum über fünf unabhängige Dimensionen — analog zum \"highest applicable SIL\" aus <a href=\"https://www.perforce.com/blog/qac/what-iec-61508-safety-integrity-levels-sils\">IEC 61508</a>:</p>\n</div>\n<div class=\"paragraph\">\n<p><strong>1. Code-Typ</strong> — Stärkster Prädiktor. Auth/Crypto-Code an der Spitze, da LLMs systematisch MFA, HSTS und Session-Management auslassen. SQL-Injection bleibt häufig, weil LLMs String-Konkatenation statt parametrisierter Queries nutzen.</p>\n</div>\n<div class=\"paragraph\">\n<p><strong>2. Sprachsicherheit</strong> — Memory-unsafe Sprachen (C/C++) erzeugen einen Boden-Risiko-Level. <a href=\"https://www.chromium.org/Home/chromium-security/memory-safety/\">Microsoft/Google berichten</a>, dass ~70% ihrer Sicherheitslücken aus Memory-Safety-Problemen stammen.</p>\n</div>\n<div class=\"paragraph\">\n<p><strong>3. Deployment-Kontext</strong> — Wo der Code läuft bestimmt, wer betroffen ist. Safety-critical (Avionik, Medizin) erfordert nach <a href=\"https://en.wikipedia.org/wiki/DO-178C\">DO-178C</a> DAL A MC/DC-Coverage und unabhängige Verifikation.</p>\n</div>\n<div class=\"paragraph\">\n<p><strong>4. Datensensibilität</strong> — Regulatorische Exposition: PHI (HIPAA), PCI-Daten, sensible PII. <a href=\"https://www.kaspersky.com/blog/vibe-coding-2025-risks/54584/\">LLM-Code implementiert routinemäßig nicht</a> die erforderlichen Audit-Trails.</p>\n</div>\n<div class=\"paragraph\">\n<p><strong>5. Blast Radius</strong> — Reichweite und Reversibilität eines Schadens. Von kosmetischen Bugs bis Leib &amp; Leben.</p>\n</div>"
18+
},
19+
{
20+
"id": "tiers",
21+
"title": "Die vier Risiko-Tiers",
22+
"html": "<div class=\"paragraph\">\n<p><strong>Tier 1 — Minimal:</strong> Persönliche Scripts, Prototypen, UI-Styling. Nur automatische Gates nötig. Kein Human Review erforderlich.</p>\n</div>\n<div class=\"paragraph\">\n<p><strong>Tier 2 — Moderat:</strong> Interne Tools, unkritische Business-Logik, Test-Code. Stichproben-Review (~20%) plus erweiterte automatische Analyse.</p>\n</div>\n<div class=\"paragraph\">\n<p><strong>Tier 3 — Hoch:</strong> Public-facing APIs, Payment-Processing, PII-Handling, Auth-Flows. Pflicht-Review durch Senior Engineers plus Defense-in-Depth.</p>\n</div>\n<div class=\"paragraph\">\n<p><strong>Tier 4 — Kritisch:</strong> Flugsteuerung, autonomes Fahren, Medizingeräte, Nuklearsysteme. AI-Generierung fragwürdig; falls eingesetzt, unabhängige Re-Verifikation erforderlich.</p>\n</div>"
23+
},
24+
{
25+
"id": "failures",
26+
"title": "LLM-spezifische Fehlerarten",
27+
"html": "<div class=\"paragraph\">\n<p>LLM-Code scheitert qualitativ anders als menschlicher Code:</p>\n</div>\n<div class=\"paragraph\">\n<p><strong>Plausibel aber subtil falsch</strong> — Kompiliert, besteht oberflächliche Reviews, enthält aber fundamentale Fehler. <a href=\"https://www.businesswire.com/news/home/20251217666881/en/CodeRabbits-State-of-AI-vs-Human-Code-Generation-Report-Finds-That-AI-Written-Code-Produces-1.7x-More-Issues-Than-Human-Code\">CodeRabbit</a> fand 1,7× mehr Issues pro PR in AI-Code vs. menschlichem Code.</p>\n</div>\n<div class=\"paragraph\">\n<p><strong>Halluzinierte Packages (Slopsquatting)</strong> — <a href=\"https://www.helpnetsecurity.com/2025/04/14/package-hallucination-slopsquatting-malicious-code/\">~20% der empfohlenen Packages existieren nicht</a>. Angreifer können diese Namen registrieren. \"huggingface-cli\" wurde <a href=\"https://www.infosecurity-magazine.com/news/ai-hallucinations-slopsquatting/\">über 30.000 mal installiert</a>.</p>\n</div>\n<div class=\"paragraph\">\n<p><strong>Automation Complacency</strong> — Entwickler mit AI-Assistenten produzieren mehr Vulnerabilities und glauben gleichzeitig, sichereren Code zu schreiben (<a href=\"https://arxiv.org/abs/2211.03622\">Stanford, Perry et al. 2022</a>). <a href=\"https://devclass.com/2025/02/20/ai-is-eroding-code-quality-states-new-in-depth-report/\">Code-Review-Beteiligung sinkt um 30%</a>.</p>\n</div>"
28+
},
29+
{
30+
"id": "mitigations",
31+
"title": "Mitigationsstrategie",
32+
"html": "<div class=\"paragraph\">\n<p>Da Human Review nicht mit dem Volumen von AI-generiertem Code skaliert, setzt das Framework auf Defense-in-Depth mit drei Maßnahmentypen:</p>\n</div>\n<div class=\"paragraph\">\n<p><strong>Deterministisch</strong> (blau) — Garantierte Erkennung innerhalb ihres Scopes. Type Checker, Linter, SAST, Sandboxing. Kein False-Negative-Risiko innerhalb der abgedeckten Patterns.</p>\n</div>\n<div class=\"paragraph\">\n<p><strong>Probabilistisch</strong> (lila) — Findet vieles, aber nicht alles. AI Code Review, Property-Based Testing, Fuzzing. Erhöht die Erkennungsrate, bietet aber keine Garantie.</p>\n</div>\n<div class=\"paragraph\">\n<p><strong>Organisatorisch</strong> (orange) — Braucht Menschen, skaliert am schlechtesten. Deshalb erst ab Tier 2/3 eingeplant, und dort gezielt auf die riskantesten Änderungen fokussiert.</p>\n</div>"
33+
},
34+
{
35+
"id": "references",
36+
"title": "Referenzen & Standards",
37+
"html": "<div class=\"paragraph\">\n<p><strong>Safety Standards:</strong> <a href=\"https://www.perforce.com/blog/qac/what-iec-61508-safety-integrity-levels-sils\">IEC 61508</a> (SIL), <a href=\"https://en.wikipedia.org/wiki/DO-178C\">DO-178C</a> (DAL), <a href=\"https://en.wikipedia.org/wiki/ISO_26262\">ISO 26262</a> (ASIL), <a href=\"https://www.euaiact.com/key-issue/3\">EU AI Act</a></p>\n</div>\n<div class=\"paragraph\">\n<p><strong>Frameworks:</strong> <a href=\"https://unit42.paloaltonetworks.com/securing-vibe-coding-tools/\">Palo Alto Unit 42 SHIELD</a>, <a href=\"https://www.aikido.dev/blog/vibe-coding-security\">Aikido VCAL</a>, <a href=\"https://cloudsecurityalliance.org/blog/2025/04/09/secure-vibe-coding-guide\">Cloud Security Alliance Secure Vibe Coding Guide</a>, <a href=\"https://saif.google/secure-ai-framework\">Google SAIF</a></p>\n</div>\n<div class=\"paragraph\">\n<p><strong>Empirische Daten:</strong> <a href=\"https://www.veracode.com/blog/ai-generated-code-security-risks/\">Veracode</a> (45% Vulnerability-Rate), <a href=\"https://www.businesswire.com/news/home/20251217666881/en/CodeRabbits-State-of-AI-vs-Human-Code-Generation-Report-Finds-That-AI-Written-Code-Produces-1.7x-More-Issues-Than-Human-Code\">CodeRabbit</a> (1,7× mehr Issues), <a href=\"https://baxbench.com/\">BaxBench</a> (62% fehlerhafte Backends), <a href=\"https://devclass.com/2025/02/20/ai-is-eroding-code-quality-states-new-in-depth-report/\">GitClear</a> (30% weniger Reviews), <a href=\"https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/\">METR RCT</a> (19% langsamer mit AI)</p>\n</div>\n<div class=\"paragraph\">\n<p><strong>Tooling:</strong> Semgrep, CodeQL, SonarQube, GitGuardian, Firecracker, Deno Sandbox, Fuzz4All, Hypothesis</p>\n</div>"
38+
},
39+
{
40+
"id": "skills",
41+
"title": "Claude Code Skills",
42+
"html": "<div class=\"paragraph\">\n<p>Dieses Framework bietet zwei <a href=\"https://code.claude.com/docs/en/skills\">Claude Code Skills</a>, die direkt in Ihrem Projekt arbeiten:</p>\n</div>\n<div class=\"paragraph\">\n<p><strong>/risk-assess</strong> — Analysiert Ihr Repository automatisch, erkennt Module (Monorepo, Frontend/Backend etc.), scannt Code-Patterns und fragt gezielt nach Dimensionen, die nicht auto-detektiert werden können. Schreibt eine strukturierte Risikobewertung pro Modul in Ihre <code>CLAUDE.md</code>.</p>\n</div>\n<div class=\"paragraph\">\n<p><strong>/risk-mitigate</strong> — Liest die Risikobewertung aus <code>CLAUDE.md</code>, erkennt bereits vorhandene Maßnahmen (Linter, CI, SAST etc.) und hilft fehlende Mitigations Schritt für Schritt umzusetzen — von Tool-Installation bis CI-Konfiguration.</p>\n</div>\n<div class=\"adr-admonition\">\n<p><strong>⚠️ Risk-Assessments sind Architekturentscheidungen</strong></p>\n<p>Tier-Klassifizierungen und Mitigation-Strategien sollten als <a href=\"https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions\" target=\"_blank\" rel=\"noopener\">Architecture Decision Records (ADR nach Nygard)</a> dokumentiert werden.</p>\n<p><code>/risk-assess</code> bietet automatische ADR-Generierung an (optional). Der ADR wird in <code>docs/adr/</code> gespeichert und — falls vorhanden — in arc42 Kapitel 9 referenziert. <code>/risk-mitigate</code> aktualisiert den ADR mit dem Umsetzungsstatus der Maßnahmen.</p>\n<p><strong>Warum ADRs?</strong> Transparenz (warum wurde Tier X gewählt?), Nachvollziehbarkeit (wer hat wann entschieden?), Reviewbarkeit (Team kann vor Umsetzung diskutieren).</p>\n</div>\n<div class=\"paragraph\">\n<p><strong>Installation — Plugin (empfohlen):</strong></p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code>/plugin marketplace add LLM-Coding/vibe-coding-risk-radar\n/plugin install risk-radar-skills@vibe-coding-risk-radar</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p><strong>Installation — manuell:</strong></p>\n</div>\n<div class=\"listingblock\">\n<div class=\"content\">\n<pre class=\"highlight\"><code>curl -sL https://raw.githubusercontent.com/LLM-Coding/vibe-coding-risk-radar/main/install-skills.sh | bash</code></pre>\n</div>\n</div>\n<div class=\"paragraph\">\n<p>Quellcode der Skills: <a href=\"https://github.com/LLM-Coding/vibe-coding-risk-radar/tree/main/.claude/skills\">GitHub</a></p>\n</div>"
43+
}
44+
]
45+
}

0 commit comments

Comments
 (0)