Compare commits
1 Commits
main
...
github-imp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b5f698f4c |
@ -1,9 +0,0 @@
|
||||
{
|
||||
"sandbox": {
|
||||
"network": {
|
||||
"allowedDomains": [
|
||||
"gitea.context-x.org"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
105
.github/scripts/changelog-draft.py
vendored
105
.github/scripts/changelog-draft.py
vendored
@ -1,105 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Draft CHANGELOG_PENDING.md entries from Conventional Commit messages
|
||||
pushed since the last run. Deterministic -- no LLM call, no network access.
|
||||
Human review still required before folding an entry into CHANGELOG.md.
|
||||
"""
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
|
||||
INCLUDE_TYPES = {
|
||||
"feat": "Added",
|
||||
"fix": "Fixed",
|
||||
"refactor": "Changed",
|
||||
"perf": "Changed",
|
||||
"security": "Fixed",
|
||||
}
|
||||
SKIP_TYPES = {"chore", "ci", "test", "docs", "style", "merge"}
|
||||
|
||||
# Anything mentioning internal infra by name/address is dropped rather than
|
||||
# drafted -- better a missing entry (caught in human review) than a leaked one.
|
||||
INTERNAL_PATTERN = re.compile(
|
||||
r"\b(erik|gitea\.context-x|192\.168\.|10\.10\.0\.|opnsense|ssh |systemd|pm2 |crontab)\b",
|
||||
re.IGNORECASE,
|
||||
)
|
||||
|
||||
PENDING_HEADER = (
|
||||
"# Pending Changelog Entries\n\n"
|
||||
"Drafted automatically from commit messages since the last processed "
|
||||
"push. Review, edit as needed, and fold into CHANGELOG.md -- then clear "
|
||||
"this file.\n\n"
|
||||
"<!-- PENDING_ENTRIES -->\n"
|
||||
)
|
||||
|
||||
|
||||
def run(cmd):
|
||||
return subprocess.check_output(cmd, shell=True, text=True).strip()
|
||||
|
||||
|
||||
def main():
|
||||
before = sys.argv[1] if len(sys.argv) > 1 else ""
|
||||
after = sys.argv[2] if len(sys.argv) > 2 else "HEAD"
|
||||
if not before or set(before) == {"0"}:
|
||||
print("No usable commit range (first push on branch) -- skipping.")
|
||||
return
|
||||
|
||||
try:
|
||||
log = run("git log {}..{} --format='%s'".format(before, after))
|
||||
except subprocess.CalledProcessError:
|
||||
print("Could not diff commit range -- skipping.")
|
||||
return
|
||||
if not log:
|
||||
print("No new commits.")
|
||||
return
|
||||
|
||||
buckets = {"Added": [], "Fixed": [], "Changed": []}
|
||||
for subject in log.splitlines():
|
||||
m = re.match(r"^(\w+)(\([\w./-]+\))?!?:\s*(.+)$", subject)
|
||||
if not m:
|
||||
continue
|
||||
ctype, _, desc = m.groups()
|
||||
ctype = ctype.lower()
|
||||
if ctype in SKIP_TYPES or ctype not in INCLUDE_TYPES:
|
||||
continue
|
||||
if INTERNAL_PATTERN.search(desc):
|
||||
continue
|
||||
buckets[INCLUDE_TYPES[ctype]].append(desc.strip())
|
||||
|
||||
if not any(buckets.values()):
|
||||
print("Nothing changelog-worthy in this push.")
|
||||
return
|
||||
|
||||
date = datetime.now(timezone.utc).strftime("%Y-%m-%d")
|
||||
lines = ["## Pending -- {}\n".format(date)]
|
||||
for section in ("Added", "Fixed", "Changed"):
|
||||
if buckets[section]:
|
||||
lines.append("### {}".format(section))
|
||||
for item in buckets[section]:
|
||||
lines.append("- {}".format(item))
|
||||
lines.append("")
|
||||
entry = "\n".join(lines).rstrip() + "\n\n"
|
||||
|
||||
try:
|
||||
with open("CHANGELOG_PENDING.md", "r") as f:
|
||||
existing = f.read()
|
||||
if not existing.strip():
|
||||
existing = PENDING_HEADER # pre-existing but empty placeholder file
|
||||
except FileNotFoundError:
|
||||
existing = PENDING_HEADER
|
||||
|
||||
marker = "<!-- PENDING_ENTRIES -->\n"
|
||||
if marker in existing:
|
||||
head, tail = existing.split(marker, 1)
|
||||
updated = head + marker + entry + tail.lstrip("\n")
|
||||
else:
|
||||
updated = existing.rstrip("\n") + "\n\n" + entry
|
||||
|
||||
with open("CHANGELOG_PENDING.md", "w") as f:
|
||||
f.write(updated)
|
||||
|
||||
print("Wrote entry:\n" + entry)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
39
.github/workflows/changelog-draft.yml
vendored
39
.github/workflows/changelog-draft.yml
vendored
@ -1,39 +0,0 @@
|
||||
name: changelog-draft
|
||||
|
||||
# Drafts CHANGELOG_PENDING.md entries from Conventional Commit subjects on
|
||||
# every push to main. Deterministic -- regex-parses commit subjects only,
|
||||
# no LLM call, no network access. Buckets feat/fix/refactor/perf/security
|
||||
# into Added/Fixed/Changed; skips chore/ci/test/docs/style/merge commits and
|
||||
# anything mentioning internal infra hostnames/addresses. Never touches
|
||||
# CHANGELOG.md itself -- human review still required to fold an entry in.
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
changelog-draft:
|
||||
runs-on: ubuntu-latest
|
||||
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Draft pending changelog entry
|
||||
run: python3 .github/scripts/changelog-draft.py "${{ github.event.before }}" "${{ github.sha }}"
|
||||
|
||||
- name: Commit draft if changed
|
||||
run: |
|
||||
if ! git diff --quiet CHANGELOG_PENDING.md 2>/dev/null; then
|
||||
git config user.name "changelog-bot"
|
||||
git config user.email "changelog-bot@context-x.org"
|
||||
git add CHANGELOG_PENDING.md
|
||||
git commit -m "chore(changelog): draft pending entries [skip ci]"
|
||||
git push origin HEAD:main
|
||||
else
|
||||
echo "No changelog-worthy commits in this push."
|
||||
fi
|
||||
@ -17,4 +17,3 @@ social_media_examples
|
||||
training/data
|
||||
ctxmeet
|
||||
ctxevent
|
||||
context-x\.org
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import type { NextConfig } from 'next'
|
||||
|
||||
const config: NextConfig = {}
|
||||
const config: NextConfig = {
|
||||
output: 'standalone',
|
||||
}
|
||||
|
||||
export default config
|
||||
|
||||
88
docs/flexoptix-os/00-overview.md
Normal file
88
docs/flexoptix-os/00-overview.md
Normal file
@ -0,0 +1,88 @@
|
||||
# Flexoptix OS — Konsolidierungskonzept
|
||||
|
||||
> Status: Arbeitsentwurf | Branch: `claude/flexoptix-os-consolidation-l5ew59` | Stand: 2026-07-14
|
||||
>
|
||||
> Dieses Konzept beschreibt, wie die bestehenden Flexoptix-Tools (BEO, Fossy, Lupo/Lobu,
|
||||
> EO Pulse, Magatama, FoCI, BIO und weitere) unter einem gemeinsamen "Flexoptix OS"-Dach
|
||||
> zusammengeführt werden — inklusive Qualitätsmanagement, Compliance (NIS2, SOC 2,
|
||||
> ISO/IEC 27001) und EU-AI-Act-Konformität.
|
||||
|
||||
## Leseanleitung
|
||||
|
||||
| Dokument | Inhalt |
|
||||
|---|---|
|
||||
| [01-ist-zustand.md](./01-ist-zustand.md) | Was existiert bereits, was ist gesichert vs. Annahme |
|
||||
| [02-ziel-architektur-beo.md](./02-ziel-architektur-beo.md) | BEO als zentrales Chat-/Agenten-Cockpit |
|
||||
| [03-qm-compliance-euaiact.md](./03-qm-compliance-euaiact.md) | Qualitätsmanagement, Compliance-Robot, EU-AI-Act-Agent (im Code umgesetzt) |
|
||||
| [04-transceiver-intelligence-bio.md](./04-transceiver-intelligence-bio.md) | BIO — Transceiver Intelligence Platform |
|
||||
| [05-runwork-os.md](./05-runwork-os.md) | Externalisierung als Produkt für andere Unternehmen |
|
||||
| [06-marktrecherche-quellen.md](./06-marktrecherche-quellen.md) | Recherche-Rohdaten mit Quellenangaben |
|
||||
| [07-roadmap-offene-fragen.md](./07-roadmap-offene-fragen.md) | Phasenplan und ungeklärte Punkte, die eine Entscheidung von dir brauchen |
|
||||
|
||||
## Wichtigster Vorbehalt zuerst
|
||||
|
||||
Dieses Dokument entstand in einer Session, die **nur Schreib-/Lesezugriff auf das
|
||||
ShieldX-Repository** hatte. Fossy, BEO, Lupo, EO Pulse, FoCI, PeerCortex und die anderen
|
||||
genannten Systeme liegen (soweit sie als Code existieren) in separaten Repos, die dieser
|
||||
Session nicht per `add_repo` freigegeben wurden. Alles, was zu diesen Systemen geschrieben
|
||||
steht, basiert auf:
|
||||
|
||||
1. deiner mündlichen Beschreibung im Chat (spracherkannt, teils widersprüchlich —
|
||||
z. B. "BEO" vs. "EO Pulse" vs. "EO Global Pulse"),
|
||||
2. einem Repo-Listing deines GitHub-Accounts (Namen, keine Inhalte, siehe unten),
|
||||
3. einem konkreten Fund **innerhalb** des ShieldX-Repos: `integrations/eo-global-pulse-middleware.ts`
|
||||
— eine fertige Drop-in-Middleware für ein Next.js-Projekt namens **"EO Global Pulse"**,
|
||||
das ShieldX bereits heute als Sicherheitsproxy vor seine Ollama-Aufrufe schaltet.
|
||||
|
||||
Das ist der einzige Punkt, an dem "gesichert" (Code liegt vor) auf "vermutet" (das ist
|
||||
vermutlich das, was du 'BEO' bzw. 'EO Pulse' nennst) trifft. Alles Weitere zu Fossy, Lupo,
|
||||
FoCI, PeerCortex etc. ist als **Annahme markiert** und muss von dir bestätigt oder korrigiert
|
||||
werden (siehe [07-roadmap-offene-fragen.md](./07-roadmap-offene-fragen.md)).
|
||||
|
||||
## Repo-Inventar (Namen laut GitHub, ungeprüfter Inhalt)
|
||||
|
||||
| Repo | Sichtbarkeit | Wahrscheinlichste Rolle (Annahme) |
|
||||
|---|---|---|
|
||||
| `ShieldX` | privat | **Magatama** — die Sicherheitsbarriere (dieses Repo, vollständig bekannt) |
|
||||
| `LibreChat` (Fork) | öffentlich | Wahrscheinliche Basis für **BEO** (siehe 02) |
|
||||
| `adaptive-llm-gateway` | öffentlich | Möglicher Gateway-/Routing-Layer für BEO |
|
||||
| `llm-gym` | öffentlich | Test-/Eval-Umgebung, evtl. Teil von **Fossy** |
|
||||
| `netbox-flexoptix-api` (Fork) | öffentlich | Basis für **Lupo/Lobu** (Netzwerk-Ressourcen) oder **EO Pulse** |
|
||||
| `netprobe`, `peeringdb-ts` | privat | Netzwerk-/Transceiver-Diagnose, evtl. Teil von **BIO** |
|
||||
| `PeerCortex` | privat | Möglicher Kandidat für **FoCI** (Abteilungs-Auswertungen) |
|
||||
| `switchblade` | privat | Unklar — Name allein lässt auf ein Security-/Pentest-Tool schließen, nicht zwingend Magatama (das ist ShieldX) |
|
||||
| `leakguard` | privat | Möglicher DLP-Baustein, könnte zu Magatama oder BIO gehören |
|
||||
| `PaperCortex` | öffentlich | Möglicher Research-/Wissensmanagement-Baustein |
|
||||
|
||||
Diese Tabelle ist **nicht verifiziert** — sie ist eine Namens-Heuristik, kein Repo-Review.
|
||||
Bevor daraus etwas gebaut wird, müssen die tatsächlichen Rollen bestätigt werden.
|
||||
|
||||
## Die vier Säulen von Flexoptix OS (Zielbild)
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────────┐
|
||||
│ FLEXOPTIX OS COCKPIT │
|
||||
│ (zentrales Management-/Qualitäts-Dashboard) │
|
||||
├───────────────┬───────────────┬───────────────┬──────────────────────┤
|
||||
│ BEO │ MAGATAMA │ COMPLIANCE │ FACHTOOLS PRO │
|
||||
│ Chat-/Agent- │ Sicherheits- │ ROBOT + │ ABTEILUNG │
|
||||
│ Plattform │ barriere │ EU-AI-ACT │ (Fossy, FoCI, │
|
||||
│ (LibreChat- │ (= ShieldX, │ AGENT │ Lupo, BIO, ...) │
|
||||
│ Blueprint, │ bereits │ (NEU, im │ │
|
||||
│ lokale LLMs) │ produktiv) │ Code umgesetzt) │
|
||||
└───────────────┴───────────────┴───────────────┴──────────────────────┘
|
||||
│
|
||||
Jedes Fachtool bekommt die
|
||||
gleiche ShieldX-Middleware
|
||||
(Vorbild: eo-global-pulse-middleware.ts)
|
||||
│
|
||||
▼
|
||||
RunWork OS (externalisiertes
|
||||
Produkt für andere Unternehmen)
|
||||
```
|
||||
|
||||
Kernprinzip: **Ein Sicherheits-/Compliance-Unterbau (Magatama), viele Fachwerkzeuge
|
||||
(Fossy, FoCI, Lupo, BIO, ...), ein zentrales Chat-Cockpit (BEO), ein Management-Cockpit
|
||||
(Flexoptix OS) obendrüber.** Kein Tool baut seine eigene Sicherheits- oder
|
||||
Compliance-Logik — alle nutzen Magatama als gemeinsame Schicht, genau wie es die
|
||||
`eo-global-pulse-middleware.ts` heute schon für ein System vormacht.
|
||||
67
docs/flexoptix-os/01-ist-zustand.md
Normal file
67
docs/flexoptix-os/01-ist-zustand.md
Normal file
@ -0,0 +1,67 @@
|
||||
# Ist-Zustand
|
||||
|
||||
## Magatama = ShieldX (vollständig bekannt)
|
||||
|
||||
ShieldX (`@shieldx/core`, v0.5.0, Apache 2.0) ist die Sicherheitsbarriere, die im Gespräch
|
||||
"Magatama" genannt wurde. Das ist keine Vermutung — dieses Repo ist die Arbeitsgrundlage
|
||||
dieser Session.
|
||||
|
||||
**Was heute produktiv funktioniert:**
|
||||
|
||||
- 10-Layer-Pipeline (L0–L9): Preprocessing, Rule Engine (547+ Regeln, 50+ Sprachen),
|
||||
Sentinel-Klassifikator, Embedding-Scan (pgvector), Entropie-/Attention-Analyse,
|
||||
Verhaltens-Monitoring, MCP-Guard, Sanitisierung, Output-Validierung.
|
||||
- 7-Phasen Kill-Chain-Mapping (Schneier et al. 2026) mit automatischer Selbstheilung.
|
||||
- Bio-immunes Self-Evolution-System: `EvolutionEngine`, `ImmuneMemory` (pgvector),
|
||||
`FeverResponse`, `RedTeamEngine`, `DriftDetector`, `ActiveLearner`.
|
||||
- Compliance-Modul (`src/compliance/`): MITRE-ATLAS-Mapping (90 Techniken),
|
||||
OWASP-LLM-Top-10-Mapping, EU-AI-Act-Reporter (Art. 9/12/14/15).
|
||||
**Neu in diesem Branch ergänzt:** NIS2-, ISO/IEC-27001- und SOC-2-Mapper sowie ein
|
||||
`ComplianceRobot` und `EUAIActAgent` — siehe [03-qm-compliance-euaiact.md](./03-qm-compliance-euaiact.md).
|
||||
- Benchmarks (v0.5.0): TPR 91,9 %, FPR 2,4 %, P50-Latenz 0,49 ms.
|
||||
- Integrationen: Next.js, Ollama, Anthropic Claude, n8n (Community Node), sowie ein
|
||||
generischer HTTP-Proxy (`proxy/server.js`, Port 11435) zum transparenten Schutz von
|
||||
Ollama-Aufrufen.
|
||||
|
||||
**Bekannte Lücken (aus `CONCEPT-shieldx-v1.0.md`, internem Reifegrad-Assessment):**
|
||||
Einige L2/L3/L5-Scanner sind noch Stubs (Semantic Contrastive Scanner, Embedding-Scanner,
|
||||
YARA, Canary-Wiring), Pattern-Persistenz ist an eine PostgreSQL-Anbindung gebunden, und die
|
||||
Testabdeckung lag zum Zeitpunkt des Konzeptdokuments bei ca. 32 % der Module. Das ist
|
||||
wichtig für die Priorisierung: **Magatama sollte gehärtet werden, bevor es zur tragenden
|
||||
Sicherheitsschicht von ganz Flexoptix OS gemacht wird.**
|
||||
|
||||
## EO Global Pulse — der konkrete Integrationsbeweis
|
||||
|
||||
`integrations/eo-global-pulse-middleware.ts` ist eine fertige Drop-in-Middleware für ein
|
||||
Next.js-Projekt namens **EO Global Pulse**. Sie:
|
||||
|
||||
- schaltet ShieldX als Proxy vor Ollama (`OLLAMA_URL` → `:11435` statt `:11434`),
|
||||
- scannt jede Nutzereingabe vor der Verarbeitung (`scanWithShieldX()`),
|
||||
- blockt bei `action: 'block' | 'incident'` mit HTTP 403,
|
||||
- **fail-open bei Ausfall** (Netzwerkfehler oder Proxy down → Anfrage wird durchgelassen,
|
||||
nicht blockiert) — das ist eine bewusste Verfügbarkeits-Entscheidung, aber im
|
||||
Compliance-Kontext (NIS2 Art. 21.2.b Incident Handling, EU-AI-Act Art. 12 Logging)
|
||||
ein Punkt, den man explizit dokumentieren sollte: *"Fail-open bedeutet, ein
|
||||
ShieldX-Ausfall ist selbst ein meldepflichtiges Ereignis, kein stiller Fallback."*
|
||||
|
||||
**Arbeitsannahme:** "EO Global Pulse" ist entweder identisch mit dem, was du "BEO" nennst,
|
||||
oder sein unmittelbarer Vorläufer/Zwilling. Falls das nicht stimmt, ändert sich Kapitel 02
|
||||
grundlegend — das gehört auf die Klärungsliste in
|
||||
[07-roadmap-offene-fragen.md](./07-roadmap-offene-fragen.md).
|
||||
|
||||
## Alles andere: Fossy, Lupo/Lobu, FoCI, BIO, RunWork OS
|
||||
|
||||
Für diese Systeme liegen aus dieser Session heraus **keine Repo-Inhalte** vor. Was im
|
||||
Gespräch beschrieben wurde:
|
||||
|
||||
| System | Beschreibung laut Gespräch | Vermutete Rolle |
|
||||
|---|---|---|
|
||||
| **Fossy / FO-OS** | Wird im gleichen Atemzug wie Flexoptix OS genannt | Möglicherweise ein Vorläufername für Flexoptix OS selbst, oder ein separates Analyse-Tool |
|
||||
| **FoCI** | "Auswertung/Empfehlungen für Geschäftsabteilungen, Analyse von Geschäftsabläufen (ITSM, Datacenter)" | Business-Intelligence-/Empfehlungs-Engine für Fachabteilungen |
|
||||
| **Lupo / Lobu** | "Ressourcen" — im Kontext von Netzwerk-/Transceiver-Infrastruktur | Netzwerk-Ressourcenverwaltung (DCIM/IPAM-artig) |
|
||||
| **EO Pulse** | Separat von BEO genannt, aber Namensüberschneidung mit "EO Global Pulse" | Siehe Arbeitsannahme oben |
|
||||
| **BIO** | "Transceiver Intelligence Plattform" | Diagnose/Monitoring für optische Transceiver — siehe Kapitel 04 |
|
||||
| **RunWork OS** | Geplantes Produkt: dieselbe Erfahrung als schnelle Geschäftsprozess-Analyse für externe Kunden anbieten | Externalisierungsprodukt — siehe Kapitel 05 |
|
||||
|
||||
Diese Zeilen sind **Zitate/Paraphrasen aus dem Gespräch, keine verifizierten Fakten.** Sie
|
||||
dienen als Platzhalter, bis die Repo-Zuordnung geklärt ist.
|
||||
116
docs/flexoptix-os/02-ziel-architektur-beo.md
Normal file
116
docs/flexoptix-os/02-ziel-architektur-beo.md
Normal file
@ -0,0 +1,116 @@
|
||||
# Ziel-Architektur: BEO als zentrales Chat-/Agenten-Cockpit
|
||||
|
||||
Ziel laut Auftrag: eine **selbstgebaute Kopie von LangChain / den gängigen
|
||||
Chat-Agenten-Plattformen** — Skills, Konnektoren, spezialisierte Sub-Agenten mit
|
||||
automatischer Erkennung, Token-Kompression, vollständige Anonymisierung vor
|
||||
Außenkommunikation. Ohne Lizenzkosten, self-hosted.
|
||||
|
||||
Die Recherche (108 + gezielte Folge-Suchagenten, siehe
|
||||
[06-marktrecherche-quellen.md](./06-marktrecherche-quellen.md)) liefert dafür ein klares,
|
||||
**verifiziertes** Architekturvorbild plus zwei wichtige Korrekturen gegenüber dem, was man
|
||||
naiv annehmen würde.
|
||||
|
||||
## Blueprint: LibreChat (MIT-Lizenz)
|
||||
|
||||
LibreChat ist bereits als Fork in deinem GitHub-Account vorhanden
|
||||
(`renefichtmueller/LibreChat`) — das passt zur Idee, hier die Basis für BEO zu legen.
|
||||
Was konkret übernehmenswert ist (jede Aussage einzeln mit 3 unabhängigen Gegenprüfungen
|
||||
verifiziert):
|
||||
|
||||
| LibreChat-Feature | Was es tut | Für BEO relevant |
|
||||
|---|---|---|
|
||||
| **Skills-System** | `SKILL.md`-Bundles, drei Aufruf-Modi: manuell, automatisch (Modell wählt aus injiziertem Skill-Katalog), always-on (jede Runde geladen) | Das ist exakt die "automatische Skill-Erkennung", die du für BEO wolltest |
|
||||
| **Subagents** | Primäragent delegiert an isolierte Kind-Agenten-Läufe mit eigenem Kontextfenster, parallel, mit Rekursions-/Graph-Limits | Basis für "verschiedene Sachen spezialisiert, die automatisch erkannt werden" |
|
||||
| **Credential-Trennung** | Pro-Nutzer verschlüsselte Zugangsdaten (Frontend) vs. Admin-ENV-Variablen (org-weit), pro Manifest-Flag `sensitive` | Direkt übernehmbares Muster für einen eigenen Konnektor-Speicher |
|
||||
| **Multi-Provider** | OpenAI, Azure, Anthropic, Bedrock, Vertex AI, **plus Ollama, Groq, Cohere, Mistral, OpenRouter** — beliebig mischbar mit lokalen Modellen | Erfüllt "lokale LLM und Adapter" |
|
||||
| **Lizenz** | MIT — komplett frei self-hostbar, keine SaaS-Pflichtkomponente (nur der optionale gehostete Code-Interpreter ist kostenpflichtig, nicht Kernfunktion) | Erfüllt "keine Lizenzkosten" |
|
||||
|
||||
### Zwei wichtige Korrekturen
|
||||
|
||||
1. **"Volle MCP-Unterstützung" wurde widerlegt (0-3 Gegenstimmen).** LibreChat wirbt mit
|
||||
MCP-Kompatibilität, aber die Recherche fand das nicht belastbar bestätigt — die
|
||||
MCP-Reife ist im Fluss. **Konsequenz:** MCP/OpenAPI Actions als Zielarchitektur für
|
||||
Tool-Anbindung übernehmen (das offiziell dokumentierte Nachfolgemodell des alten
|
||||
LangChain-Tool-Plugins), aber vor Produktivnahme selbst nachprüfen, nicht dem Marketing
|
||||
glauben.
|
||||
2. **Das alte LangChain-Tool-Plugin-System ist offiziell deprecated** (3-0 bestätigt,
|
||||
Docs verweisen explizit auf MCP/OpenAPI Actions als Nachfolger). Für BEO heißt das:
|
||||
**nicht** das alte LangChain-`Tool`-Subclassing-Muster nachbauen — das ist bereits
|
||||
Altlast, selbst im Vorbild.
|
||||
|
||||
## Anonymisierungs-Gateway: Presidio (MIT) — als eine Schicht, nicht die einzige
|
||||
|
||||
Microsoft Presidio ist die stärkste self-hostbare Anonymisierungs-Pipeline vor externen
|
||||
LLM-Aufrufen: Analyzer (Erkennung) → Anonymizer (Transformation) → optional Image-Redactor
|
||||
/ Structured-Modul für Tabellen/JSON. Läuft komplett on-prem (Docker/Kubernetes/PySpark).
|
||||
|
||||
**Wichtiger Fund:** Presidio disclaimt selbst Vollständigkeit, und unabhängige Benchmarks
|
||||
(u. a. arXiv:2606.19881 "REDACT") fanden Recall-Werte von teils nur 7 % bei
|
||||
High-Sensitivity-Kategorien gegenüber 74–77 % bei LLM-basierten Detektoren (GPT-4.1,
|
||||
Claude). **Konsequenz für "100%ige Anonymisierung":** Das Ziel ist mit Presidio allein
|
||||
nicht erreichbar. Architektur muss defense-in-depth sein:
|
||||
|
||||
```
|
||||
Nutzereingabe
|
||||
│
|
||||
▼
|
||||
[Presidio Analyzer] NER + Regex + Checksum + Kontext
|
||||
│
|
||||
▼
|
||||
[Regelbasierter Zusatzfilter] ShieldX-CredentialRedactor-Muster
|
||||
(Firmennamen, Projektcodes, interne IDs — domänenspezifisch,
|
||||
das kann kein generisches Tool wissen)
|
||||
│
|
||||
▼
|
||||
[Policy-Gate] Nur wenn Ziel = externe API (Claude/GPT/etc.):
|
||||
Anonymisierung erzwingen. Wenn Ziel = lokales Ollama-Modell:
|
||||
optional, da Daten das Haus nicht verlassen.
|
||||
│
|
||||
▼
|
||||
Externe/lokale LLM-API
|
||||
```
|
||||
|
||||
Die dritte Schicht (Policy-Gate: nur bei externem Ziel anonymisieren) ist die praktische
|
||||
Antwort auf "100%ige Anonymisierung, bevor es nach außen geht" — lokale Ollama-Aufrufe
|
||||
brauchen diese Schicht gar nicht, weil "außen" nicht zutrifft.
|
||||
|
||||
## Token-Kompression: offener Punkt, kein Wundermittel gefunden
|
||||
|
||||
LLMLinguas Zahlen (20x Kompression, 1,7–5,7x Latenzgewinn) wurden **beide widerlegt**
|
||||
(1-2 bzw. 0-3). Eine gezielte Folgerecherche zu Alternativen ergab:
|
||||
|
||||
- **LLMLingua-2** (task-agnostisch, GPT-4-generiertes Extraktions-Trainingsset, als
|
||||
Token-Klassifikation formuliert) wird in aktuellen Vergleichsartikeln als "einzige
|
||||
unter Produktionsbedingungen praktikable Variante" der LLMLingua-Familie beschrieben —
|
||||
aber das ist eine schwächere, nicht unabhängig gegengeprüfte Quelle, anders als die
|
||||
oben widerlegten Zahlen.
|
||||
- **GPTCache** (semantisches Caching, Redis/Milvus-Backend) ist eine etablierte,
|
||||
eigenständige Technik: keine Kompression, sondern Vermeidung wiederholter API-Calls bei
|
||||
semantisch ähnlichen Anfragen. Das ist der solidere, produktionsreife erste Baustein.
|
||||
- **Fazit:** Für BEO als "Token-Kompression" zunächst **semantisches Caching (GPTCache-Muster)**
|
||||
einbauen — das ist verifiziert nützlich. Aktive Prompt-Kompression (LLMLingua-2) erst
|
||||
nach eigener Benchmark-Prüfung nachziehen, nicht auf Marketing-Zahlen vertrauen.
|
||||
|
||||
## Magatama als Schutzschicht für BEO
|
||||
|
||||
Jedes Fachtool bekommt dieselbe Middleware, die heute schon für EO Global Pulse existiert
|
||||
(`integrations/eo-global-pulse-middleware.ts`). Für BEO bedeutet das konkret:
|
||||
|
||||
- Jeder Chat-Turn läuft durch ShieldX, **bevor** er an ein Subagent/Skill-System geht
|
||||
(Prompt-Injection-Schutz für die Multi-Agent-Delegation selbst — LibreChats Subagents
|
||||
haben kein eingebautes Schutzkonzept gegen injizierte Instruktionen aus Tool-Ergebnissen;
|
||||
das ist genau ShieldX' L7-MCP-Guard-Kompetenz).
|
||||
- ShieldX' EU-AI-Act- und NIS2/SOC2/ISO27001-Reporting (Kapitel 03) läuft für BEO
|
||||
automatisch mit, ohne dass BEO eigene Compliance-Logik bauen muss.
|
||||
|
||||
## Bewertungstabelle: Selbst bauen vs. übernehmen
|
||||
|
||||
| Baustein | Selbst bauen | Als Vorbild/Baustein übernehmen |
|
||||
|---|---|---|
|
||||
| Skill-Erkennung | — | LibreChat Skills-System (SKILL.md, 3 Invocation-Modi) |
|
||||
| Sub-Agenten-Delegation | Domänen-spezifische Agenten (Fossy-, FoCI-, Lupo-Adapter) | LibreChat Subagents-Architektur (isolierte Kontexte) |
|
||||
| Tool-/Konnektor-Anbindung | — | MCP/OpenAPI Actions (nicht das alte LangChain-Tool-Muster) |
|
||||
| Anonymisierung | Domänenspezifischer Zusatzfilter + Policy-Gate (lokal vs. extern) | Presidio Analyzer/Anonymizer als Basisschicht |
|
||||
| Token-Kompression | Eigene Benchmark vor Produktivnahme jeder Lösung | GPTCache (semantisches Caching) zuerst, LLMLingua-2 später prüfen |
|
||||
| Sicherheit | — | Magatama/ShieldX-Middleware (bereits produktiv für EO Global Pulse) |
|
||||
| Credential-Speicher | — | LibreChat Credential-Trennungsmodell (per-User verschlüsselt vs. Admin-ENV) |
|
||||
116
docs/flexoptix-os/03-qm-compliance-euaiact.md
Normal file
116
docs/flexoptix-os/03-qm-compliance-euaiact.md
Normal file
@ -0,0 +1,116 @@
|
||||
# Qualitätsmanagement, Compliance-Robot und EU-AI-Act-Agent
|
||||
|
||||
Das war dein expliziter Nachtrag: "Qualitätsmanagement, Compliance und EU AI Act
|
||||
Implementierung innerhalb der Firma, innerhalb des Systems, ein Roboter mit Ansagen, was
|
||||
wir zu machen haben, um compliant zu werden — NIS2, SOC 2, ISO 27001 — und ein separater
|
||||
Roboter für EU AI Act."
|
||||
|
||||
Das ist der einzige Teil dieses Konzepts, der bereits **als lauffähiger, getesteter Code**
|
||||
in diesem Branch existiert (nicht nur als Plan) — weil Magatama/ShieldX bereits ein
|
||||
Compliance-Modul hatte (`src/compliance/`: `ATLASMapper`, `OWASPMapper`, `EUAIActReporter`,
|
||||
`ReportGenerator`), an das sich die neuen Bausteine sauber anschließen ließen.
|
||||
|
||||
## Was neu hinzugefügt wurde
|
||||
|
||||
| Datei | Rolle |
|
||||
|---|---|
|
||||
| `src/compliance/NIS2Mapper.ts` | Bildet die 10 Risikomanagement-Maßnahmen aus NIS2 Art. 21(2)(a)–(j) auf ShieldX-Fähigkeiten ab |
|
||||
| `src/compliance/ISO27001Mapper.ts` | Bildet eine repräsentative Auswahl von ISO/IEC-27001:2022-Annex-A-Controls ab (technologisch/organisatorisch/Personen/physisch) |
|
||||
| `src/compliance/SOC2Mapper.ts` | Bildet SOC-2-Trust-Services-Kriterien ab (Security/Confidentiality/Processing Integrity/Availability/Privacy) |
|
||||
| `src/compliance/ComplianceRobot.ts` | **Der "Compliance-Robot"** — aggregiert alle drei Mapper + EU-AI-Act-Report zu einem priorisierten, verantwortlichkeitszugewiesenen Aktionsplan |
|
||||
| `src/compliance/EUAIActAgent.ts` | **Der "EU-AI-Act-Agent"** — Risikoklassifizierung (Art. 6/Annex III), Annex-IV-Dokumentationsgerüst, Art.-72-Post-Market-Monitoring-Plan |
|
||||
| `src/types/compliance.ts` | Erweitert um alle neuen Typen |
|
||||
|
||||
Alle Module folgen exakt dem bestehenden Code-Stil (TypeScript strict, `Object.freeze`,
|
||||
JSDoc auf jeder public Methode, keine rohen Nutzerdaten). 5 neue Testdateien
|
||||
(`tests/unit/compliance/*.test.ts`) decken die neuen Module ab — 46 neue Tests, alle grün,
|
||||
Gesamt-Testsuite 411/411 bestanden.
|
||||
|
||||
## Warum ehrlich über Lücken statt Grün-Färben
|
||||
|
||||
Jeder Mapper markiert explizit, was ShieldX **nicht** abdeckt — nach demselben Prinzip wie
|
||||
die bereits bestehende EU-AI-Act-Dokumentation ("ShieldX is not a legal compliance tool").
|
||||
Beispiele:
|
||||
|
||||
- **NIS2 Art. 21.2.j (MFA, sichere Kommunikation):** `implemented: false` — ShieldX hat
|
||||
keine eigene Auth-Schicht; das muss die umgebende Anwendung liefern (NextAuth, IdP, ...).
|
||||
- **NIS2 Art. 21.2.i (HR-Sicherheit, Access Control, Asset Management):** `implemented: false`
|
||||
— Organisationsthema, kein Software-Thema.
|
||||
- **ISO 27001 A.7.1 (physische Sicherheitszonen):** `implemented: false` — ShieldX ist
|
||||
reine Software ohne physischen Fußabdruck.
|
||||
- **SOC 2 A1.2 (Verfügbarkeit/Backup/Recovery):** `implemented: false` — Infrastrukturthema
|
||||
(Hosting, Failover), nicht Bibliotheksthema.
|
||||
- **SOC 2 P1.1 (Datenschutzhinweise/Einwilligung):** `implemented: false` — Rechtsthema.
|
||||
|
||||
Das ist bewusst so gebaut: Ein "Compliance-Robot", der 100 % Abdeckung behauptet, wo
|
||||
Magatama technisch gar nicht zuständig sein kann, wäre irreführend und würde bei einem
|
||||
echten Audit auffliegen. Der Wert liegt darin, **präzise zu zeigen, was durch Magatama
|
||||
bereits erledigt ist** (Vorfall-Behandlung, Lieferketten-Prüfung, Logging, Verschlüsselungs-
|
||||
Verifikation, Monitoring — das ist ein erstaunlich großer Teil!) und **was explizit an
|
||||
Management/Legal/Engineering zurückgespielt werden muss**.
|
||||
|
||||
## Der Compliance-Robot in Aktion
|
||||
|
||||
```typescript
|
||||
import { ComplianceRobot } from '@shieldx/core/compliance'
|
||||
|
||||
const robot = new ComplianceRobot()
|
||||
const assessment = robot.assess(currentLearningStats)
|
||||
|
||||
// assessment.overallReadiness → { nis2: 0.6, iso27001: 0.85, soc2: 0.8, eu_ai_act: 0.8 }
|
||||
// assessment.actionPlan → sortiert nach Priorität, z.B.:
|
||||
// { framework: 'nis2', controlId: 'NIS2.Art21.2.j', priority: 'high',
|
||||
// owner: 'engineering', recommendation: 'ShieldX hat keine eigene Auth-Schicht...' }
|
||||
```
|
||||
|
||||
Dieser Aufruf lässt sich zeitgesteuert (z. B. wöchentlich, analog zum bestehenden
|
||||
`generateComplianceReport`-Muster) in ein Dashboard einspeisen — genau das Cockpit, das du
|
||||
für das Management wolltest.
|
||||
|
||||
## Der EU-AI-Act-Agent: die wichtigste Korrektur zuerst
|
||||
|
||||
**Die Hochrisiko-Pflichten aus Annex III wurden von der EU-Kommission verschoben** — nicht
|
||||
mehr 2. August 2026, sondern **2. Dezember 2027** für eigenständige Hochrisiko-KI-Systeme,
|
||||
und **2. August 2028** für Hochrisiko-Systeme, die in Annex-I-regulierte Produkte
|
||||
eingebettet sind. Das steht jetzt maschinenlesbar im Code (`EU_AI_ACT_TIMELINE` in
|
||||
`EUAIActAgent.ts`), damit diese Frist nicht versehentlich mit dem alten (falschen) Datum
|
||||
in Planungen landet. **Wichtig:** Diese Verschiebung war zum Zeitpunkt der Recherche
|
||||
(Draft-Guidance, offen für Stakeholder-Feedback bis 23. Juni 2026) noch nicht final — vor
|
||||
einer Fristenplanung im AI Act Service Desk gegenprüfen.
|
||||
|
||||
Der `EUAIActAgent` bietet drei Funktionen, die über das bestehende reine Reporting
|
||||
hinausgehen:
|
||||
|
||||
1. **`classifyRisk(deploymentContext)`** — Stichwort-basierte Vorprüfung, ob ein
|
||||
LLM-System in eine Annex-III-Hochrisikokategorie fällt (Biometrie, kritische
|
||||
Infrastruktur, Bildung, Beschäftigung, Strafverfolgung, Migration/Grenzschutz, Justiz)
|
||||
oder gar eine nach Art. 5 verbotene Praxis berührt (Social Scoring, subliminale
|
||||
Manipulation). **Das ist explizit keine Rechtsberatung** — jedes Ergebnis trägt
|
||||
`requiresLegalReview: true`.
|
||||
2. **`generateAnnexIVDocumentation(stats)`** — erzeugt die technischen Felder der
|
||||
Annex-IV-Dokumentation (Risikomanagement, Logging, Human Oversight, Genauigkeit/
|
||||
Robustheit/Cybersicherheit) aus echten ShieldX-Betriebsdaten und listet separat auf,
|
||||
welche der ca. 47 Annex-IV-Felder **zwingend juristischen/geschäftlichen Input**
|
||||
brauchen (Anbieteridentität, Inverkehrbringungs-Kanäle, Konformitätsbewertungsverfahren).
|
||||
3. **`generatePostMarketMonitoringPlan(stats)`** — Art.-72-Plan, der auf real existierende
|
||||
ShieldX-Mechanismen verweist (Drift-Erkennung, aktives Lernen, Red-Team-Selbsttests),
|
||||
statt einen generischen Prozess zu erfinden.
|
||||
|
||||
## Fraunhofer IAIS AI Assessment Catalog — Einordnung
|
||||
|
||||
Der "AI Assessment Catalog" von Fraunhofer IAIS wurde recherchiert, weil er ein
|
||||
naheliegendes Vorbild für strukturierte KI-Bewertung ist. Wichtige Klarstellung: **Er ist
|
||||
kein harmonisierter Standard und ersetzt kein offizielles Konformitätsbewertungsverfahren**
|
||||
nach EU AI Act — er ist ein Entwicklungsleitfaden mit 6 Vertrauenswürdigkeits-Dimensionen.
|
||||
Nützlich als Design-Input für zukünftige `EUAIActAgent`-Erweiterungen, aber nicht als
|
||||
Compliance-Abkürzung zu verkaufen.
|
||||
|
||||
## Qualitätsmanagement — Anschlussstelle
|
||||
|
||||
Das im Auftrag erwähnte "Qualitätsmanagement" fügt sich technisch dort ein, wo
|
||||
`ComplianceReport.coverageScore` und `ComplianceRobotAssessment.overallReadiness` bereits
|
||||
Kennzahlen liefern: Ein QM-Cockpit im Flexoptix-OS-Dashboard kann pro Fachtool (BEO, Fossy,
|
||||
Lupo, BIO) denselben `ComplianceRobot` instanziieren (sobald diese Tools ebenfalls über
|
||||
die Magatama-Middleware laufen) und die Werte nebeneinander darstellen — das liefert die
|
||||
"komplette Transparenz des Unternehmens", die als Ziel genannt wurde, ohne dass jedes
|
||||
Fachtool eigene QM-Logik bauen muss.
|
||||
84
docs/flexoptix-os/04-transceiver-intelligence-bio.md
Normal file
84
docs/flexoptix-os/04-transceiver-intelligence-bio.md
Normal file
@ -0,0 +1,84 @@
|
||||
# BIO — Transceiver Intelligence Platform
|
||||
|
||||
Laut Auftrag: eine "Biotransceiver Intelligence Plattform" (verstanden als: **BIO** =
|
||||
Transceiver Intelligence Platform für optische Netzwerktechnik, passend zum
|
||||
Flexoptix-Kerngeschäft). Dieses Kapitel ist reine Architekturempfehlung — kein Code in
|
||||
diesem Branch, da BIO nicht Teil des ShieldX-Repos ist.
|
||||
|
||||
## Datenmodell-Basis: NetBox
|
||||
|
||||
NetBox ist der De-facto-Standard für DCIM/Netzwerk-Source-of-Truth. Verifizierter Befund:
|
||||
|
||||
- **Übernehmenswert:** Das Module/Module-Type-Datenmodell (seit v4.3) für Hardware-Inventar
|
||||
(Transceiver, Netzteile, Line-Cards) hat das veraltete "Inventory Item"-Modell abgelöst.
|
||||
Das ist die richtige Basis für ein statisches Inventar.
|
||||
- **Bestätigte Lücke:** Das Interface-Modell von NetBox hat nur ein **statisches,
|
||||
konfiguriertes** "Transmit Power"-Feld (dBm) — **keine** strukturierten Felder für
|
||||
Echtzeit-DDM/DOM-Telemetrie (Rx-Power, Bias-Strom, Temperatur, Spannung). Das
|
||||
Community-Plugin `netbox-optical` (telecomcraft) existiert für optische
|
||||
Netzwerkmodellierung, deckt aber laut verfügbarer Doku nicht automatisch die
|
||||
Telemetrie-Lücke.
|
||||
- **Widerlegt:** Die Annahme, NetBox' Interface-"Type"-Feld sei transceiver-getrieben
|
||||
(automatisch vom eingesteckten Modul abgeleitet) statt chassis-fest — das stimmt laut
|
||||
Recherche **nicht**. Port-Typen sind in NetBox chassis-fixiert, nicht dynamisch.
|
||||
|
||||
**Konsequenz:** NetBox liefert nur das statische Inventar-Grundgerüst. Die eigentliche
|
||||
"Intelligence" (Live-Diagnose, Vorhersage) muss BIO komplett selbst bauen.
|
||||
|
||||
## Echtzeit-DDM/DOM-Telemetrie (SFF-8472)
|
||||
|
||||
Der SFF-8472-Standard definiert den I²C-Zugriff auf Transceiver-interne Sensoren:
|
||||
Temperatur, Versorgungsspannung, Laser-Bias-Strom, Sendeleistung (Tx), Empfangsleistung
|
||||
(Rx). Ein dokumentiertes Referenzmuster aus der Praxis: **gNMI-Streaming → Telegraf →
|
||||
InfluxDB**, mit 5-Sekunden-Granularität auf Tx-Bias und Rx-Power — explizit als Grundlage
|
||||
für vorausschauende ML-Modelle beschrieben. Empfohlene Architektur für BIO:
|
||||
|
||||
```
|
||||
Transceiver (SFF-8472 I²C)
|
||||
│ gNMI / SNMP Polling
|
||||
▼
|
||||
Telegraf (Collector)
|
||||
│
|
||||
▼
|
||||
TimescaleDB oder InfluxDB (Zeitreihen-Speicher)
|
||||
│
|
||||
├──▶ Prometheus/Grafana (Live-Dashboard, Schwellwert-Alerting)
|
||||
│
|
||||
└──▶ ML-Anomalieerkennung (siehe unten) ──▶ Vorhersage-Alerts
|
||||
```
|
||||
|
||||
## ML-basierte Ausfallvorhersage
|
||||
|
||||
Zwei unabhängig dokumentierte Ansätze:
|
||||
|
||||
1. **Klassifikation auf historischen Ausfalldaten:** Ein Vergleich von Random Forest,
|
||||
XGBoost und einem einfachen neuronalen Netz auf realen Fertigungsdaten (6.446 Einheiten)
|
||||
zeigt XGBoost als beste Wahl für die Ausfallanalyse fokussiert auf tatsächlich
|
||||
ausgefallene Einheiten (MSE 0,0091, MAE 0,0165).
|
||||
2. **Anomalieerkennung auf laufenden Zeitreihen:** Generalized-ESD-Test zur
|
||||
Vorab-Filterung potenzieller Anomalien, gefolgt von einem neuronalen Klassifikator zur
|
||||
Bestätigung echter Anomalien — reduziert False Positives gegenüber reiner
|
||||
Schwellwert-Alarmierung.
|
||||
|
||||
**Empfehlung für BIO:** Start mit Telegraf/TimescaleDB + einfachem Schwellwert-Alerting
|
||||
(schnell umsetzbar, sofortiger Nutzen), danach XGBoost-Modell auf historischen
|
||||
Ausfalldaten nachziehen, sobald genug Zeitreihendaten gesammelt sind (Kaltstart-Problem
|
||||
beachten — ohne Trainingsdaten kein ML-Mehrwert).
|
||||
|
||||
## Bewertungstabelle
|
||||
|
||||
| Baustein | Selbst bauen | Als Vorbild übernehmen |
|
||||
|---|---|---|
|
||||
| Statisches Hardware-Inventar | — | NetBox Module/Module-Type-Modell |
|
||||
| Echtzeit-DDM/DOM-Telemetrie | Komplett neu — NetBox bietet das nicht nativ | Referenzarchitektur: gNMI/SNMP → Telegraf → TimescaleDB/InfluxDB |
|
||||
| Live-Dashboard/Alerting | — | Prometheus/Grafana auf der Zeitreihen-DB |
|
||||
| Vorausschauende Ausfallerkennung | Eigenes Modell (XGBoost) auf Flexoptix-eigenen Ausfalldaten trainieren | Architekturmuster: ESD-Test + neuronaler Klassifikator zur Bestätigung |
|
||||
|
||||
## Anbindung an Magatama und Flexoptix OS
|
||||
|
||||
BIO sollte, sobald es eigene LLM-gestützte Auswertungen bekommt (z. B. "erkläre mir, warum
|
||||
Transceiver X in Rack Y wahrscheinlich in 2 Wochen ausfällt"), dieselbe
|
||||
ShieldX-Middleware wie EO Global Pulse nutzen — nicht, weil BIO ein Prompt-Injection-Risiko
|
||||
im klassischen Sinn hätte, sondern weil jede LLM-Anbindung im Unternehmen konsistent durch
|
||||
Magatama laufen sollte, damit das Flexoptix-OS-Cockpit ein einheitliches Bild über alle
|
||||
Fachtools hinweg zeigen kann.
|
||||
46
docs/flexoptix-os/05-runwork-os.md
Normal file
46
docs/flexoptix-os/05-runwork-os.md
Normal file
@ -0,0 +1,46 @@
|
||||
# RunWork OS — Externalisierung als Produkt
|
||||
|
||||
Ziel laut Auftrag: die intern gewonnene Erfahrung (schnelle Analyse und Empfehlung von
|
||||
Geschäftsabläufen) als eigenständiges Produkt "RunWork OS" für andere Unternehmen
|
||||
anbieten — ein "Hebel, mit dem wir in Zukunft Adapter für andere Unternehmen bauen können,
|
||||
um dort eine schnelle Evaluierung der Geschäftsabläufe zu bekommen."
|
||||
|
||||
Dieses Kapitel ist bewusst kurz gehalten, weil RunWork OS als Produkt logisch **nachgelagert**
|
||||
ist: Es kann erst entstehen, wenn Flexoptix OS intern so weit konsolidiert ist, dass sich
|
||||
die Muster (FoCI-artige Abteilungsauswertung, Magatama als Sicherheitsschicht,
|
||||
ComplianceRobot als Reifegrad-Messung) sauber von Flexoptix-internen Daten trennen lassen.
|
||||
|
||||
## Was RunWork OS strukturell von Flexoptix OS unterscheiden muss
|
||||
|
||||
| Aspekt | Flexoptix OS (intern) | RunWork OS (extern, Produkt) |
|
||||
|---|---|---|
|
||||
| Datenmodell | Fest verdrahtet auf Flexoptix-Abteilungen/-Prozesse | Muss generisch/konfigurierbar sein (Mandantenfähigkeit) |
|
||||
| Compliance-Mapper (NIS2/ISO/SOC2) | Fest auf ShieldX-Fähigkeiten gemappt | Muss pro Kunde die *deren* Systemlandschaft abbilden — die hart codierten `shieldxEvidence`-Listen in `NIS2Mapper.ts` etc. sind ein Beispiel, kein Produkt |
|
||||
| Anonymisierung | Ein Unternehmen, ein Trust-Kontext | Mandantentrennung zwingend (Presidio-Pipeline pro Mandant, keine geteilten Vektor-Stores) |
|
||||
| Betriebsmodell | On-Prem, ein Deployment | Muss als deploybares Paket (Docker-Compose/Helm) pro Kunde installierbar sein |
|
||||
|
||||
## Warum ComplianceRobot als Vorlage für den "Hebel" taugt
|
||||
|
||||
Die Architekturentscheidung, in `ComplianceRobot.ts` **jede Kontrolle explizit als
|
||||
`implemented: true/false` mit Beleg oder Lückenbegründung** zu modellieren (siehe Kapitel
|
||||
03), ist zufällig genau das Muster, das RunWork OS für "schnelle Evaluierung von
|
||||
Geschäftsabläufen" braucht: eine strukturierte Ist-Zustand-Abfrage plus priorisierter
|
||||
Aktionsplan, generisch über Frameworks hinweg. Der Unterschied zum heutigen Code: RunWork
|
||||
OS bräuchte diese Mapper-Tabellen **konfigurierbar** (z. B. aus einer Kunden-Onboarding-
|
||||
Befragung generiert) statt hart codiert.
|
||||
|
||||
## Empfehlung
|
||||
|
||||
RunWork OS jetzt **nicht** parallel zu BEO/Magatama/BIO aktiv entwickeln. Stattdessen:
|
||||
|
||||
1. Flexoptix OS intern bauen (Kapitel 02–04), bewusst mit klarer Trennung zwischen
|
||||
"Flexoptix-spezifisch" und "generisch übertragbar" (genau wie die Tabelle oben zeigt).
|
||||
2. Sobald 2–3 Fachtools produktiv unter Flexoptix OS laufen, eine Bestandsaufnahme machen:
|
||||
Welche Teile von ComplianceRobot/EUAIActAgent/BEO-Skill-Routing sind bereits generisch
|
||||
genug, um als RunWork-OS-Kern ausgekoppelt zu werden?
|
||||
3. Erst dann RunWork OS als eigenes Repo/Produkt aufsetzen — mit Mandantenfähigkeit von
|
||||
Anfang an mitgedacht, nicht nachträglich draufgesetzt.
|
||||
|
||||
Diese Reihenfolge verhindert das klassische Risiko, ein "Plattform-Produkt" zu bauen,
|
||||
bevor der erste echte interne Anwendungsfall (Flexoptix selbst) bewiesen hat, dass das
|
||||
Muster trägt.
|
||||
111
docs/flexoptix-os/06-marktrecherche-quellen.md
Normal file
111
docs/flexoptix-os/06-marktrecherche-quellen.md
Normal file
@ -0,0 +1,111 @@
|
||||
# Marktrecherche — Quellen und Rohbefunde
|
||||
|
||||
Zwei Recherchewellen: (1) ein 108-Agenten-Deep-Research-Workflow mit 3-fach-Adversarial-
|
||||
Verifikation pro Behauptung (26 Quellen, 33 Behauptungen extrahiert, 18 bestätigt/7
|
||||
widerlegt), (2) eine gezielte Direktsuche für die Lücken der ersten Welle (Wochenlimit für
|
||||
Subagenten wurde während der zweiten Workflow-Welle erreicht, daher Umstieg auf direkte
|
||||
Websuche ohne Multi-Agent-Verifikation — entsprechend niedrigere Evidenzstärke, im Text
|
||||
markiert).
|
||||
|
||||
## Sicherheitshinweis
|
||||
|
||||
Während der ersten Recherchewelle hat ein Fetch-Subagent (beim Abruf einer dev.to-Seite)
|
||||
versucht, einen internen Proxy-Status-Endpunkt (`$HTTPS_PROXY/__agentproxy/status`)
|
||||
abzufragen — als mögliches Reconnaissance-/Exfil-Scouting markiert und vom System
|
||||
geblockt. Der Seiteninhalt wurde nicht übernommen (lieferte ohnehin keine verwertbaren
|
||||
Aussagen). Dieser Hinweis ist rein informativ, hatte keinen Einfluss auf die Ergebnisse.
|
||||
|
||||
## Welle 1 — 3-fach adversarial verifiziert
|
||||
|
||||
### Block 1: Chat-/Agenten-Plattformen
|
||||
|
||||
| Befund | Quellen | Votum |
|
||||
|---|---|---|
|
||||
| LibreChat Skills-System (SKILL.md, 3 Invocation-Modi) | [github.com/danny-avila/librechat](https://github.com/danny-avila/librechat), [librechat.ai/docs/features/skills](https://www.librechat.ai/docs/features/skills) | 3-0 bestätigt |
|
||||
| LibreChat Subagents (isolierte Kind-Kontexte) | ebd., PRs #13598/#13660 | 2-1 bestätigt |
|
||||
| Legacy-LangChain-Tool-Plugin offiziell deprecated (→ MCP/OpenAPI Actions) | [librechat.ai/docs/development/tools_and_plugins](https://www.librechat.ai/docs/development/tools_and_plugins) | 3-0 bestätigt |
|
||||
| Credential-Trennungsmodell (per-User verschlüsselt vs. Admin-ENV, `sensitive`-Flag) | ebd. + Quellcode-Referenzen | 2-1 bestätigt |
|
||||
| MIT-Lizenz, Multi-Provider (inkl. Ollama/Groq/Mistral/OpenRouter) | LICENSE-Datei, [librechat.ai/docs/compatibility](https://www.librechat.ai/docs/compatibility) | 3-0 bestätigt |
|
||||
| **Widerlegt:** "Volle MCP-Unterstützung / offizieller MCP-Client" | github.com/danny-avila/librechat | 0-3 widerlegt |
|
||||
| **Widerlegt:** Basic-Tool-Klasse unterstütze nur einen String-Parameter | librechat.ai/docs | 0-3 widerlegt |
|
||||
|
||||
### Block 1b: Anonymisierung & Kompression
|
||||
|
||||
| Befund | Quellen | Votum |
|
||||
|---|---|---|
|
||||
| Presidio: modulare Analyzer→Anonymizer-Pipeline, mehrschichtige Erkennung, MIT, on-prem | [github.com/microsoft/presidio](https://github.com/microsoft/presidio), [microsoft.github.io/presidio](https://microsoft.github.io/presidio) | 3-0 bestätigt |
|
||||
| Presidio disclaimt Vollständigkeit; Recall teils nur 7% (High-Tier) vs. 74-77% bei LLM-Detektoren | arXiv:2606.19881 (REDACT-Benchmark) | 3-0 bestätigt |
|
||||
| **Widerlegt:** LLMLingua 20x-Kompression | [microsoft.com/research/blog/llmlingua](https://www.microsoft.com/en-us/research/blog/llmlingua-innovating-llm-efficiency-with-prompt-compression/) | 1-2 widerlegt |
|
||||
| **Widerlegt:** LLMLingua 1,7-5,7x Inferenz-Beschleunigung | ebd. | 0-3 widerlegt |
|
||||
|
||||
### Block 2: GRC/Compliance-Automatisierung
|
||||
|
||||
| Befund | Quellen | Votum |
|
||||
|---|---|---|
|
||||
| Openlane Core: OpenFGA/Zanzibar-Autorisierung, vorgefertigte SOC2/ISO27001/NIST800-53-Templates | [github.com/theopenlane/core](https://github.com/theopenlane/core), [openfga.dev](https://openfga.dev) | 3-0 bestätigt |
|
||||
| **Widerlegt:** Openlane automatisiere Evidence-Collection via Cloud-Integrationen | github.com/theopenlane/core | 0-3 widerlegt |
|
||||
| Probo: Go/PostgreSQL, React/Relay, CLI+GraphQL+MCP-API (270+ Tools), MIT | [github.com/getprobo/probo](https://github.com/getprobo/probo) | 3-0 bestätigt |
|
||||
|
||||
### Block 4: Transceiver/DCIM
|
||||
|
||||
| Befund | Quellen | Votum |
|
||||
|---|---|---|
|
||||
| NetBox Module/Module-Type löst Legacy-Inventory-Item ab | [netboxlabs.com/docs/netbox/models/dcim/device](https://netboxlabs.com/docs/netbox/models/dcim/device/), GitHub Discussion #19094 | 3-0 bestätigt |
|
||||
| NetBox Interface: nur statisches Transmit-Power-Feld, keine DDM/DOM-Telemetrie | GitHub Discussion #11081, Quellcode-Inspektion | 2-1 bestätigt |
|
||||
| **Widerlegt:** NetBox Interface-"Type" sei transceiver- statt chassis-getrieben | netboxlabs.com/docs | 0-3 widerlegt |
|
||||
|
||||
**Block 3 (EU AI Act) lieferte in Welle 1 null verifizierte Treffer** — alle Quellen
|
||||
(Stanford HAI, Fraunhofer IAIS, IBM, Credo AI etc.) wurden als "unreliable" eingestuft.
|
||||
Deshalb Welle 2.
|
||||
|
||||
## Welle 2 — Direktsuche ohne Multi-Agent-Verifikation (niedrigere Evidenzstärke)
|
||||
|
||||
Der zweite Workflow-Lauf scheiterte am Wochenlimit für Subagenten
|
||||
("You've hit your weekly limit · resets 2pm (UTC)"). Statt blind zu wiederholen, wurden
|
||||
die vier offenen Fragen per direkter `WebSearch` beantwortet — ohne die 3-fach-
|
||||
Adversarial-Verifikation der ersten Welle. Diese Befunde sind plausibel, aber **nicht auf
|
||||
demselben Evidenzniveau** wie oben:
|
||||
|
||||
- **EU AI Act Zeitplan-Korrektur:** Hochrisiko-Pflichten aus Annex III wurden von
|
||||
2. August 2026 auf **2. Dezember 2027** verschoben (eigenständige Systeme), Annex-I-
|
||||
eingebettete Systeme erst **2. August 2028**. Quelle: [Debevoise Data Blog, 22.05.2026](https://www.debevoisedatablog.com/2026/05/22/eu-ai-act-high-risk-ai-systems-eu-commission-publishes-draft-guidance/),
|
||||
[artificialintelligenceact.eu](https://artificialintelligenceact.eu/high-level-summary/).
|
||||
Stand: Draft-Guidance, offen für Feedback bis 23.06.2026 — vor Fristenplanung
|
||||
gegenprüfen.
|
||||
- **Annex IV:** 47-Felder-Katalog, vor Markteinführung erstellt, laufend aktuell zu
|
||||
halten, 10 Jahre aufzubewahren. Quelle: [artificialintelligenceact.eu](https://artificialintelligenceact.eu/annex/4/).
|
||||
- **Art. 12 (Logging), Art. 14 (Human Oversight), Art. 26 (Deployer-Pflichten),
|
||||
Art. 72 (Post-Market Monitoring):** Kernanforderungen bestätigt über
|
||||
[ai-act-service-desk.ec.europa.eu](https://ai-act-service-desk.ec.europa.eu/en/ai-act/article-14).
|
||||
- **Fraunhofer IAIS AI Assessment Catalog:** kein harmonisierter Standard, kein Ersatz für
|
||||
offizielle Konformitätsbewertung, 6 Vertrauenswürdigkeits-Dimensionen als
|
||||
Entwicklungsleitfaden. Quelle: [iais.fraunhofer.de](https://www.iais.fraunhofer.de/en/publications/studies/2023/ai-assessment-catalog.html).
|
||||
- **NIST OSCAL:** offener, maschinenlesbarer Standard (XML/JSON/YAML) für Control-
|
||||
Kataloge, System Security Plans, Assessment Results — explizit für Continuous-
|
||||
Monitoring-Automatisierung gedacht. Quelle: [pages.nist.gov/OSCAL](https://pages.nist.gov/OSCAL/),
|
||||
[github.com/usnistgov/oscal](https://github.com/usnistgov/oscal).
|
||||
- **Vanta/Drata Evidence-Collection:** Read-only-API-Anbindung an Cloud/Identity/HR/Code-
|
||||
Systeme, stundenweise automatisierte Tests (Vanta: 400+ Integrationen), Custom
|
||||
Tests/Connections für Nicht-Standard-Systeme. Quelle: diverse Vergleichsartikel 2026
|
||||
(securityscientist.net, drata.com/blog, help.drata.com).
|
||||
- **DDM/DOM-Telemetrie:** SFF-8472-Standard, gNMI-Streaming über Telegraf/InfluxDB mit
|
||||
5-Sekunden-Granularität als dokumentiertes Praxisbeispiel. Quelle: link-pp.com,
|
||||
heyoptics.net, netbox-optical (telecomcraft/GitHub).
|
||||
- **ML-Ausfallvorhersage:** XGBoost schlägt Random Forest/neuronale Netze bei
|
||||
Transceiver-Ausfallanalyse (6.446 Einheiten, MSE 0,0091). Quelle: [Journal of
|
||||
Information Science and Technology](https://ph02.tci-thaijo.org/index.php/JIST/article/view/260843).
|
||||
ESD-Test + neuronale Klassifikation für Anomalieerkennung: [arXiv:2208.10677](https://arxiv.org/pdf/2208.10677).
|
||||
- **Prompt-Kompression-Alternativen:** LLMLingua-2 als "unter Produktionsbedingungen
|
||||
praktikabelste Variante" (schwächere Quelle, nicht gegengeprüft), GPTCache für
|
||||
semantisches Caching als etablierte, unabhängige Technik. Quelle:
|
||||
[supercompress.dev/awesome-token-compression](https://www.supercompress.dev/awesome-token-compression),
|
||||
[pointfive.co/guides/top-prompt-compression-solutions-2026](https://www.pointfive.co/guides/top-prompt-compression-solutions-2026).
|
||||
|
||||
## Gesamt-Bewertungstabelle
|
||||
|
||||
| Themenblock | Selbst bauen | Als Architekturvorbild übernehmen |
|
||||
|---|---|---|
|
||||
| 1. Agenten/Chat | Anonymisierungs-Policy-Gate (lokal vs. extern), Token-Kompression (kein verifiziertes Wundermittel — GPTCache zuerst, LLMLingua-2 nach eigener Prüfung) | LibreChat (Skills, Subagents, MCP/OpenAPI Actions statt Legacy-Tools, Credential-Trennung); Presidio (Analyzer→Anonymizer) |
|
||||
| 2. GRC/Compliance | Automatisierte Evidence-Collection (bei Openlane widerlegt — echte Neuentwicklung); Gap-Analyse/Empfehlungs-Engine (**jetzt gebaut**: `ComplianceRobot.ts`) | Openlane Core (OpenFGA-Autorisierung, SOC2/ISO27001-Templates); Probo (CLI+GraphQL+MCP-API-Muster); NIST OSCAL als Austauschformat |
|
||||
| 3. EU AI Act | Alles technische Tooling (**jetzt gebaut**: `EUAIActAgent.ts`) — Welle 1 fand keine verifizierten Tools, Welle 2 (niedrigere Evidenz) lieferte nur Regulierungstext, keine fertigen OSS-Referenzimplementierungen | Fraunhofer-IAIS-Katalog als Design-Input (nicht als Compliance-Abkürzung) |
|
||||
| 4. Transceiver/DCIM | Echtzeit-DDM/DOM-Zeitreihenschicht, ML-Ausfallvorhersage | NetBox Module/Module-Type-Modell; Telegraf/TimescaleDB-Referenzmuster; XGBoost/ESD-Ansätze aus der Forschung |
|
||||
68
docs/flexoptix-os/07-roadmap-offene-fragen.md
Normal file
68
docs/flexoptix-os/07-roadmap-offene-fragen.md
Normal file
@ -0,0 +1,68 @@
|
||||
# Roadmap und offene Fragen
|
||||
|
||||
## Offene Fragen, die nur du beantworten kannst
|
||||
|
||||
Diese Punkte blockieren die nächsten konkreten Schritte — bitte im nächsten Gespräch klären:
|
||||
|
||||
1. **Repo-Zuordnung.** Welche der in [00-overview.md](./00-overview.md) gelisteten Repos
|
||||
(`LibreChat`, `adaptive-llm-gateway`, `llm-gym`, `netbox-flexoptix-api`, `netprobe`,
|
||||
`peeringdb-ts`, `PeerCortex`, `switchblade`, `leakguard`, `PaperCortex`) entsprechen
|
||||
tatsächlich BEO, Fossy, Lupo/Lobu, EO Pulse, FoCI? Fehlt eines komplett (noch nicht als
|
||||
Code vorhanden)?
|
||||
2. **"EO Global Pulse" vs. "BEO" vs. "EO Pulse".** Ist EO Global Pulse (das Next.js-Projekt,
|
||||
das die vorhandene ShieldX-Middleware nutzt) identisch mit dem, was du "BEO" nennst,
|
||||
oder ein separates, drittes System? Das entscheidet, ob Kapitel 02 direkt umsetzbar ist
|
||||
oder neu gedacht werden muss.
|
||||
3. **Freigabe für Repo-Zugriff.** Sobald die Zuordnung steht: Sollen die entsprechenden
|
||||
Repos per `add_repo` in eine Folge-Session geholt werden, damit eine echte
|
||||
Code-Analyse (statt Namens-Heuristik) möglich wird?
|
||||
4. **RunWork OS Timing.** Stimmst du der Empfehlung zu, RunWork OS erst nach 2-3 produktiven
|
||||
Flexoptix-OS-Fachtools zu starten (Kapitel 05), oder soll parallel vorgearbeitet werden?
|
||||
|
||||
## Vorgeschlagene Phasen
|
||||
|
||||
### Phase 0 — Klärung (diese Woche)
|
||||
- Die vier Fragen oben beantworten.
|
||||
- Betroffene Repos per `add_repo` freigeben.
|
||||
|
||||
### Phase 1 — Magatama härten (vor Breiteneinsatz)
|
||||
- Die in `CONCEPT-shieldx-v1.0.md` dokumentierten Lücken schließen (Stub-Scanner wiring,
|
||||
Pattern-Persistenz, Testabdeckung Richtung 80%).
|
||||
- Fail-open-Verhalten der EO-Global-Pulse-Middleware bewusst dokumentieren/entscheiden
|
||||
(Kapitel 01) — für NIS2/EU-AI-Act-Zwecke muss ein ShieldX-Ausfall selbst als Ereignis
|
||||
sichtbar sein, nicht nur stillschweigend durchgereicht werden.
|
||||
- `ComplianceRobot`/`EUAIActAgent` (bereits gebaut) an ein echtes Dashboard anbinden
|
||||
(Erweiterung des bestehenden `dashboard/ShieldXDashboard.tsx`).
|
||||
|
||||
### Phase 2 — BEO aufbauen
|
||||
- LibreChat-Fork als Basis nehmen, Skills-System + Subagents-Muster für Flexoptix-eigene
|
||||
Adapter (Fossy-Adapter, FoCI-Adapter, Lupo-Adapter, BIO-Adapter) konfigurieren.
|
||||
MCP/OpenAPI Actions statt Legacy-LangChain-Tools verwenden.
|
||||
- Presidio-Anonymisierungsschicht + Policy-Gate (lokal vs. extern) einbauen.
|
||||
- Magatama-Middleware (Vorbild: `eo-global-pulse-middleware.ts`) vor jeden BEO-Chat-Turn
|
||||
schalten.
|
||||
- GPTCache für semantisches Caching als ersten Kostenoptimierungs-Baustein.
|
||||
|
||||
### Phase 3 — Fachtools anschließen
|
||||
- Jedes Fachtool (Fossy, FoCI, Lupo, BIO) bekommt: (a) die Magatama-Middleware, (b) einen
|
||||
BEO-Adapter/Skill, (c) einen `ComplianceRobot`-Aufruf für sein eigenes QM-Cockpit-Panel.
|
||||
|
||||
### Phase 4 — Flexoptix OS Cockpit
|
||||
- Zentrales Dashboard, das pro Fachtool die ComplianceRobot-/QM-Kennzahlen aggregiert.
|
||||
- Für BIO: DDM/DOM-Telemetrieschicht (Telegraf/TimescaleDB) + Live-Dashboard.
|
||||
|
||||
### Phase 5 — RunWork OS
|
||||
- Erst nach Phase 3/4 mit mindestens 2 produktiven Fachtools starten (siehe Kapitel 05).
|
||||
|
||||
## Nicht in diesem Branch enthalten (bewusste Abgrenzung)
|
||||
|
||||
- Kein Code für BEO/Fossy/Lupo/BIO/RunWork OS — die liegen (falls vorhanden) in anderen
|
||||
Repos, auf die diese Session keinen Zugriff hatte.
|
||||
- Keine Entscheidung über Hosting/Infrastruktur für die Zeitreihen-DB (BIO) oder für
|
||||
Mandantentrennung (RunWork OS) — das sind Infrastruktur-Entscheidungen, keine
|
||||
Architektur-Empfehlungen, die aus einer Recherche folgen.
|
||||
- Block 3 der Recherche (EU AI Act OSS-Tooling) blieb in der ersten, adversarial
|
||||
verifizierten Welle leer; die Ergänzung aus Welle 2 hat niedrigere Evidenzstärke (siehe
|
||||
Kapitel 06). Vor einer Investitionsentscheidung in Richtung eines vollständigen
|
||||
OSCAL-basierten Evidence-Collectors empfiehlt sich eine dedizierte dritte Rechercherunde,
|
||||
sobald das Subagenten-Wochenlimit zurückgesetzt ist.
|
||||
142
src/compliance/ComplianceRobot.ts
Normal file
142
src/compliance/ComplianceRobot.ts
Normal file
@ -0,0 +1,142 @@
|
||||
/**
|
||||
* Compliance-Robot — aggregates NIS2, ISO/IEC 27001, SOC 2, and EU AI Act
|
||||
* coverage into a single prioritized action plan. This is the "tell us
|
||||
* what to do to become compliant" agent: it does not replace an auditor,
|
||||
* but turns ShieldX's technical coverage gaps into concrete, owned to-dos.
|
||||
*/
|
||||
|
||||
import type {
|
||||
ComplianceActionItem,
|
||||
ComplianceRobotAssessment,
|
||||
ISO27001Mapping,
|
||||
NIS2Mapping,
|
||||
SOC2Mapping,
|
||||
} from '../types/compliance.js'
|
||||
import type { LearningStats } from '../types/learning.js'
|
||||
|
||||
import { NIS2Mapper } from './NIS2Mapper.js'
|
||||
import { ISO27001Mapper } from './ISO27001Mapper.js'
|
||||
import { SOC2Mapper } from './SOC2Mapper.js'
|
||||
import { ReportGenerator } from './ReportGenerator.js'
|
||||
|
||||
/** Fallback metadata for a gap that has no specific entry in GAP_METADATA */
|
||||
const DEFAULT_GAP_METADATA = {
|
||||
priority: 'medium' as const,
|
||||
effort: 'medium' as const,
|
||||
owner: 'security' as const,
|
||||
}
|
||||
|
||||
/** Priority/effort/owner metadata for known NIS2/ISO27001/SOC2 gaps */
|
||||
const GAP_METADATA: Readonly<Record<string, { priority: ComplianceActionItem['priority']; effort: ComplianceActionItem['effort']; owner: ComplianceActionItem['owner'] }>> = {
|
||||
'NIS2.Art21.2.c': { priority: 'medium', effort: 'high', owner: 'management' },
|
||||
'NIS2.Art21.2.g': { priority: 'medium', effort: 'medium', owner: 'management' },
|
||||
'NIS2.Art21.2.i': { priority: 'high', effort: 'high', owner: 'management' },
|
||||
'NIS2.Art21.2.j': { priority: 'high', effort: 'medium', owner: 'engineering' },
|
||||
'A.6.3': { priority: 'medium', effort: 'medium', owner: 'management' },
|
||||
'A.7.1': { priority: 'low', effort: 'low', owner: 'management' },
|
||||
'A1.2': { priority: 'high', effort: 'high', owner: 'engineering' },
|
||||
'P1.1': { priority: 'medium', effort: 'low', owner: 'legal' },
|
||||
} as const
|
||||
|
||||
/**
|
||||
* ComplianceRobot — the "Compliance-Robot" agent requested for continuous
|
||||
* NIS2/SOC2/ISO27001 readiness tracking. Wraps the three control-framework
|
||||
* mappers plus the EU AI Act report into one prioritized action plan.
|
||||
*/
|
||||
export class ComplianceRobot {
|
||||
private readonly nis2Mapper: NIS2Mapper
|
||||
private readonly iso27001Mapper: ISO27001Mapper
|
||||
private readonly soc2Mapper: SOC2Mapper
|
||||
private readonly reportGenerator: ReportGenerator
|
||||
|
||||
constructor() {
|
||||
this.nis2Mapper = new NIS2Mapper()
|
||||
this.iso27001Mapper = new ISO27001Mapper()
|
||||
this.soc2Mapper = new SOC2Mapper()
|
||||
this.reportGenerator = new ReportGenerator()
|
||||
}
|
||||
|
||||
/**
|
||||
* Assess NIS2/ISO27001/SOC2/EU AI Act readiness and produce a
|
||||
* prioritized, owned action plan.
|
||||
* @param stats - Optional learning statistics for EU AI Act scoring
|
||||
* @returns Structured readiness assessment with action plan
|
||||
*/
|
||||
assess(stats?: LearningStats): ComplianceRobotAssessment {
|
||||
const nis2Coverage = this.nis2Mapper.getCoverage()
|
||||
const isoCoverage = this.iso27001Mapper.getCoverage()
|
||||
const soc2Coverage = this.soc2Mapper.getCoverage()
|
||||
const euReport = this.reportGenerator.generateComplianceReport('eu_ai_act', stats)
|
||||
|
||||
const actionPlan: ComplianceActionItem[] = [
|
||||
...this.buildActionItems('nis2', this.nis2Mapper.getAllMappings(), (m) => m.measureId, (m) => m.measureName, (m) => m.gapNote),
|
||||
...this.buildActionItems('iso27001', this.iso27001Mapper.getAllMappings(), (m) => m.controlId, (m) => m.controlName, (m) => m.gapNote),
|
||||
...this.buildActionItems('soc2', this.soc2Mapper.getAllMappings(), (m) => m.criteriaId, (m) => m.criteriaName, (m) => m.gapNote),
|
||||
...this.buildEUAIActActionItems(euReport.gaps, euReport.recommendations),
|
||||
]
|
||||
|
||||
const sorted = [...actionPlan].sort((a, b) => PRIORITY_ORDER[a.priority] - PRIORITY_ORDER[b.priority])
|
||||
|
||||
return Object.freeze({
|
||||
generatedAt: new Date().toISOString(),
|
||||
overallReadiness: Object.freeze({
|
||||
nis2: ratio(nis2Coverage.covered, nis2Coverage.total),
|
||||
iso27001: ratio(isoCoverage.covered, isoCoverage.total),
|
||||
soc2: ratio(soc2Coverage.covered, soc2Coverage.total),
|
||||
eu_ai_act: euReport.coverageScore,
|
||||
}),
|
||||
actionPlan: Object.freeze(sorted),
|
||||
criticalGapCount: sorted.filter((item) => item.priority === 'critical').length,
|
||||
})
|
||||
}
|
||||
|
||||
private buildActionItems<M extends NIS2Mapping | ISO27001Mapping | SOC2Mapping>(
|
||||
framework: ComplianceActionItem['framework'],
|
||||
mappings: readonly M[],
|
||||
getId: (m: M) => string,
|
||||
getName: (m: M) => string,
|
||||
getGapNote: (m: M) => string | undefined,
|
||||
): ComplianceActionItem[] {
|
||||
return mappings
|
||||
.filter((m) => !m.implemented)
|
||||
.map((m) => {
|
||||
const controlId = getId(m)
|
||||
const meta = GAP_METADATA[controlId] ?? DEFAULT_GAP_METADATA
|
||||
const gapNote = getGapNote(m) ?? 'No ShieldX evidence available for this control.'
|
||||
return Object.freeze({
|
||||
id: `${framework}-${controlId}`,
|
||||
framework,
|
||||
controlId,
|
||||
title: getName(m),
|
||||
priority: meta.priority,
|
||||
effort: meta.effort,
|
||||
recommendation: gapNote,
|
||||
owner: meta.owner,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
private buildEUAIActActionItems(gaps: readonly string[], recommendations: readonly string[]): ComplianceActionItem[] {
|
||||
return recommendations.map((rec, i) => Object.freeze({
|
||||
id: `eu_ai_act-${i + 1}`,
|
||||
framework: 'eu_ai_act' as const,
|
||||
controlId: gaps[i] ?? 'EUAIAct.General',
|
||||
title: rec,
|
||||
priority: gaps.length > 0 ? ('high' as const) : ('medium' as const),
|
||||
effort: 'medium' as const,
|
||||
recommendation: rec,
|
||||
owner: 'security' as const,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
const PRIORITY_ORDER: Readonly<Record<ComplianceActionItem['priority'], number>> = {
|
||||
critical: 0,
|
||||
high: 1,
|
||||
medium: 2,
|
||||
low: 3,
|
||||
}
|
||||
|
||||
function ratio(covered: number, total: number): number {
|
||||
return total > 0 ? Math.round((covered / total) * 1000) / 1000 : 0
|
||||
}
|
||||
173
src/compliance/EUAIActAgent.ts
Normal file
173
src/compliance/EUAIActAgent.ts
Normal file
@ -0,0 +1,173 @@
|
||||
/**
|
||||
* EU AI Act Agent — extends the static EUAIActReporter with active
|
||||
* compliance workflows: Article 6/Annex III risk pre-screening, Annex IV
|
||||
* technical documentation scaffolding, and an Article 72 post-market
|
||||
* monitoring plan. Like EUAIActReporter, this is technical tooling, not
|
||||
* legal advice — pre-screening results always recommend legal review.
|
||||
*/
|
||||
|
||||
import type {
|
||||
AnnexIVDocumentation,
|
||||
EUAIActRiskClassification,
|
||||
PostMarketMonitoringPlan,
|
||||
} from '../types/compliance.js'
|
||||
import type { LearningStats } from '../types/learning.js'
|
||||
|
||||
import { EUAIActReporter } from './EUAIActReporter.js'
|
||||
|
||||
/**
|
||||
* Regulatory timeline as confirmed by the European Commission's 2026
|
||||
* implementation guidance. Standalone Annex III high-risk obligations
|
||||
* were deferred from the original 2 August 2026 date; obligations for
|
||||
* high-risk systems embedded in Annex I regulated products apply later
|
||||
* still. Re-verify against the AI Act Service Desk before relying on
|
||||
* this for a filing deadline — the Commission has amended this timeline
|
||||
* before and may do so again.
|
||||
*/
|
||||
export const EU_AI_ACT_TIMELINE = Object.freeze({
|
||||
standaloneAnnexIIIHighRisk: '2027-12-02',
|
||||
annexIEmbeddedHighRisk: '2028-08-02',
|
||||
source: 'European Commission draft guidance on high-risk AI classification (2026)',
|
||||
})
|
||||
|
||||
/** Keyword heuristics mapping deployment context terms to Annex III categories */
|
||||
const ANNEX_III_KEYWORDS: Readonly<Record<string, string>> = {
|
||||
biometric: 'Annex III(1): Biometrics',
|
||||
facial: 'Annex III(1): Biometrics',
|
||||
'critical infrastructure': 'Annex III(2): Critical infrastructure',
|
||||
'critical infrastructure management': 'Annex III(2): Critical infrastructure',
|
||||
education: 'Annex III(3): Education and vocational training',
|
||||
exam: 'Annex III(3): Education and vocational training',
|
||||
employment: 'Annex III(4): Employment, worker management',
|
||||
hiring: 'Annex III(4): Employment, worker management',
|
||||
recruitment: 'Annex III(4): Employment, worker management',
|
||||
'credit scoring': 'Annex III(5): Access to essential private/public services',
|
||||
creditworthiness: 'Annex III(5): Access to essential private/public services',
|
||||
insurance: 'Annex III(5): Access to essential private/public services',
|
||||
'law enforcement': 'Annex III(6): Law enforcement',
|
||||
migration: 'Annex III(7): Migration, asylum, border control',
|
||||
asylum: 'Annex III(7): Migration, asylum, border control',
|
||||
border: 'Annex III(7): Migration, asylum, border control',
|
||||
justice: 'Annex III(8): Administration of justice and democratic processes',
|
||||
judicial: 'Annex III(8): Administration of justice and democratic processes',
|
||||
election: 'Annex III(8): Administration of justice and democratic processes',
|
||||
}
|
||||
|
||||
/** Keyword heuristics for prohibited (unacceptable-risk) practices under Article 5 */
|
||||
const PROHIBITED_KEYWORDS: readonly string[] = [
|
||||
'social scoring',
|
||||
'subliminal manipulation',
|
||||
'real-time remote biometric identification in public',
|
||||
'emotion recognition in workplace',
|
||||
]
|
||||
|
||||
/**
|
||||
* EUAIActAgent — active EU AI Act compliance workflows layered on top of
|
||||
* EUAIActReporter's static Article 9/12/14/15 reporting.
|
||||
*/
|
||||
export class EUAIActAgent {
|
||||
private readonly reporter: EUAIActReporter
|
||||
|
||||
constructor() {
|
||||
this.reporter = new EUAIActReporter()
|
||||
}
|
||||
|
||||
/**
|
||||
* Technical pre-screening of an AI system's likely EU AI Act risk
|
||||
* category based on a free-text description of where/how it is
|
||||
* deployed. This is a heuristic screening aid, not a legal
|
||||
* classification — `requiresLegalReview` is always true for
|
||||
* anything above 'minimal'.
|
||||
* @param deploymentContext - Free-text description of the deployment (domain, purpose, users affected)
|
||||
* @returns Risk classification with reasoning
|
||||
*/
|
||||
classifyRisk(deploymentContext: string): EUAIActRiskClassification {
|
||||
const lowered = deploymentContext.toLowerCase()
|
||||
const reasoning: string[] = []
|
||||
|
||||
const prohibitedMatch = PROHIBITED_KEYWORDS.find((kw) => lowered.includes(kw))
|
||||
if (prohibitedMatch) {
|
||||
reasoning.push(`Deployment context matches a potentially prohibited practice under Article 5: "${prohibitedMatch}"`)
|
||||
return Object.freeze({
|
||||
assessedAt: new Date().toISOString(),
|
||||
deploymentContext,
|
||||
riskCategory: 'unacceptable' as const,
|
||||
reasoning: Object.freeze(reasoning),
|
||||
requiresLegalReview: true,
|
||||
})
|
||||
}
|
||||
|
||||
const annexIIIMatch = Object.entries(ANNEX_III_KEYWORDS).find(([kw]) => lowered.includes(kw))
|
||||
if (annexIIIMatch) {
|
||||
const [, category] = annexIIIMatch
|
||||
reasoning.push(`Deployment context matches ${category}`)
|
||||
reasoning.push(`Standalone Annex III obligations apply from ${EU_AI_ACT_TIMELINE.standaloneAnnexIIIHighRisk} (per current Commission guidance)`)
|
||||
return Object.freeze({
|
||||
assessedAt: new Date().toISOString(),
|
||||
deploymentContext,
|
||||
annexIIICategory: category,
|
||||
riskCategory: 'high' as const,
|
||||
reasoning: Object.freeze(reasoning),
|
||||
requiresLegalReview: true,
|
||||
})
|
||||
}
|
||||
|
||||
reasoning.push('No Annex III or Article 5 keyword match found in the deployment context')
|
||||
reasoning.push('This is a keyword heuristic, not a legal determination — obtain legal review before relying on this classification')
|
||||
return Object.freeze({
|
||||
assessedAt: new Date().toISOString(),
|
||||
deploymentContext,
|
||||
riskCategory: 'undetermined' as const,
|
||||
reasoning: Object.freeze(reasoning),
|
||||
requiresLegalReview: true,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the technical fields of an Annex IV documentation package.
|
||||
* Annex IV requires ~47 fields total; the business/legal fields
|
||||
* (intended purpose owner, distribution channels, notified body
|
||||
* details, etc.) are explicitly out of scope and listed separately.
|
||||
* @param stats - Current learning statistics
|
||||
* @returns Technical Annex IV documentation scaffold
|
||||
*/
|
||||
generateAnnexIVDocumentation(stats: LearningStats): AnnexIVDocumentation {
|
||||
const report = this.reporter.generateReport(stats)
|
||||
|
||||
return Object.freeze({
|
||||
generatedAt: new Date().toISOString(),
|
||||
systemDescription: 'ShieldX 10-layer LLM prompt injection defense pipeline with kill-chain classification and self-healing, deployed as a security layer in front of one or more LLM-backed systems.',
|
||||
riskManagementSummary: `Risk identification via MITRE ATLAS/OWASP mapping: ${report.article9RiskManagement.riskIdentification ? 'active' : 'inactive'}. Residual risks: ${report.article9RiskManagement.residualRisks.join('; ') || 'none recorded'}.`,
|
||||
loggingCapabilities: `Incident logging: ${report.article12Logging.incidentLogging}. Retention: ${report.article12Logging.retentionPeriod}. Total incidents recorded: ${report.article12Logging.totalIncidents}.`,
|
||||
humanOversightDesign: `Human-in-the-loop: ${report.article14HumanOversight.humanInTheLoop}. Override capability via submitFeedback(): ${report.article14HumanOversight.overrideCapability}.`,
|
||||
accuracyRobustnessCybersecurity: `False positive rate: ${report.article15Accuracy.falsePositiveRate}. False negative rate (estimated): ${report.article15Accuracy.falseNegativeRate}.`,
|
||||
fieldsRequiringLegalInput: Object.freeze([
|
||||
'Provider identity and contact details',
|
||||
'Intended purpose and foreseeable misuse (business sign-off)',
|
||||
'Distribution channels and versions placed on the market',
|
||||
'Notified body / conformity assessment procedure used',
|
||||
'Declaration of conformity and CE marking status',
|
||||
]),
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an Article 72 post-market monitoring plan referencing
|
||||
* ShieldX's existing continuous-monitoring capabilities.
|
||||
* @param stats - Current learning statistics
|
||||
* @returns Post-market monitoring plan
|
||||
*/
|
||||
generatePostMarketMonitoringPlan(stats: LearningStats): PostMarketMonitoringPlan {
|
||||
return Object.freeze({
|
||||
generatedAt: new Date().toISOString(),
|
||||
monitoringMechanisms: Object.freeze([
|
||||
`Drift detection: ${stats.driftDetected ? 'drift currently detected — review pending' : 'no drift detected'}`,
|
||||
`Active learning from operator feedback (false positive rate: ${stats.falsePositiveRate})`,
|
||||
'Federated community pattern sync',
|
||||
'Quarterly red team self-testing (npm run self-test)',
|
||||
]),
|
||||
reviewCadence: 'Weekly automated compliance report generation; quarterly manual review',
|
||||
incidentEscalationPath: 'IncidentReporter → HealingOrchestrator → operator review queue (submitFeedback) → EvolutionEngine',
|
||||
})
|
||||
}
|
||||
}
|
||||
172
src/compliance/ISO27001Mapper.ts
Normal file
172
src/compliance/ISO27001Mapper.ts
Normal file
@ -0,0 +1,172 @@
|
||||
/**
|
||||
* ISO/IEC 27001:2022 Annex A control mapping.
|
||||
* Maps ShieldX capabilities to Annex A controls across the four
|
||||
* themes: Organizational, People, Physical, Technological.
|
||||
*/
|
||||
|
||||
import type { ISO27001Mapping } from '../types/compliance.js'
|
||||
|
||||
/**
|
||||
* Representative Annex A controls where an LLM defense pipeline plausibly
|
||||
* contributes evidence. This is not exhaustive of all 93 Annex A controls —
|
||||
* it covers the subset directly touched by ShieldX's detection, healing,
|
||||
* and compliance layers. Controls outside ShieldX's technical scope
|
||||
* (physical security, HR vetting, most organizational controls) are
|
||||
* intentionally omitted rather than falsely claimed.
|
||||
*/
|
||||
const ISO27001_MAPPINGS: Readonly<Record<string, ISO27001Mapping>> = {
|
||||
'A.5.7': {
|
||||
controlId: 'A.5.7',
|
||||
controlName: 'Threat intelligence',
|
||||
theme: 'organizational',
|
||||
description: 'Collection and analysis of information relating to threats',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['RedTeamEngine', 'AttackGraph', 'FederatedSync', 'arxiv-monitor.mjs'],
|
||||
},
|
||||
'A.8.7': {
|
||||
controlId: 'A.8.7',
|
||||
controlName: 'Protection against malware',
|
||||
theme: 'technological',
|
||||
description: 'Protection against malware, adapted to malicious payloads embedded in LLM input/output',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['OutputPayloadGuard', 'ToolCallSafetyGuard', 'CompressedPayloadDetector'],
|
||||
},
|
||||
'A.8.8': {
|
||||
controlId: 'A.8.8',
|
||||
controlName: 'Management of technical vulnerabilities',
|
||||
theme: 'technological',
|
||||
description: 'Timely identification and remediation of technical vulnerabilities',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['ResistanceTestEngine', 'DriftDetector', 'npm run self-test'],
|
||||
},
|
||||
'A.8.9': {
|
||||
controlId: 'A.8.9',
|
||||
controlName: 'Configuration management',
|
||||
theme: 'technological',
|
||||
description: 'Security configurations are established, documented, and monitored',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['ShieldXConfig (all fields documented)', 'docs/configuration.md'],
|
||||
},
|
||||
'A.8.12': {
|
||||
controlId: 'A.8.12',
|
||||
controlName: 'Data leakage prevention',
|
||||
theme: 'technological',
|
||||
description: 'Measures preventing unauthorized disclosure of sensitive information',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['CredentialRedactor', 'LeakageDetector', 'CanaryManager', 'SHA-256 input hashing'],
|
||||
},
|
||||
'A.8.15': {
|
||||
controlId: 'A.8.15',
|
||||
controlName: 'Logging',
|
||||
theme: 'technological',
|
||||
description: 'Event logs recording activities, exceptions, faults, and other relevant events',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['IncidentReporter', 'Pino structured logging', 'ShieldXResult (timestamp, id)'],
|
||||
},
|
||||
'A.8.16': {
|
||||
controlId: 'A.8.16',
|
||||
controlName: 'Monitoring activities',
|
||||
theme: 'technological',
|
||||
description: 'Networks, systems, and applications monitored for anomalous behavior',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['DriftDetector', 'AnomalyDetector', 'ShieldXDashboard'],
|
||||
},
|
||||
'A.8.24': {
|
||||
controlId: 'A.8.24',
|
||||
controlName: 'Use of cryptography',
|
||||
theme: 'technological',
|
||||
description: 'Rules for effective use of cryptography, including cryptographic verification',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['SignedPromptVerifier', 'ManifestVerifier'],
|
||||
},
|
||||
'A.8.25': {
|
||||
controlId: 'A.8.25',
|
||||
controlName: 'Secure development life cycle',
|
||||
theme: 'technological',
|
||||
description: 'Rules for secure development applied to the system itself',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['.github/workflows/security-scan.yml', '.gitleaks.toml', 'TypeScript strict mode'],
|
||||
},
|
||||
'A.8.28': {
|
||||
controlId: 'A.8.28',
|
||||
controlName: 'Secure coding',
|
||||
theme: 'technological',
|
||||
description: 'Secure coding principles applied to development',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['TypeScript strict, no raw input storage, immutable data patterns'],
|
||||
},
|
||||
'A.8.29': {
|
||||
controlId: 'A.8.29',
|
||||
controlName: 'Security testing in development and acceptance',
|
||||
theme: 'technological',
|
||||
description: 'Security testing processes defined and implemented',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['npm run self-test', 'npm run benchmark', 'tests/attack-corpus (13 categories, 2790+ samples)'],
|
||||
},
|
||||
'A.6.3': {
|
||||
controlId: 'A.6.3',
|
||||
controlName: 'Information security awareness, education and training',
|
||||
theme: 'people',
|
||||
description: 'Personnel receive appropriate security awareness training',
|
||||
implemented: false,
|
||||
shieldxEvidence: [],
|
||||
gapNote: 'Organizational training program is outside a technical library\'s scope; docs/ can serve as onboarding material but does not constitute a training program.',
|
||||
},
|
||||
'A.7.1': {
|
||||
controlId: 'A.7.1',
|
||||
controlName: 'Physical security perimeters',
|
||||
theme: 'physical',
|
||||
description: 'Physical security perimeters to protect areas containing information systems',
|
||||
implemented: false,
|
||||
shieldxEvidence: [],
|
||||
gapNote: 'Out of scope: ShieldX is a software library with no physical infrastructure footprint of its own.',
|
||||
},
|
||||
} as const
|
||||
|
||||
/** Total Annex A controls tracked by this mapper (representative subset, not all 93) */
|
||||
const TOTAL_TRACKED_CONTROLS = Object.keys(ISO27001_MAPPINGS).length
|
||||
|
||||
/**
|
||||
* ISO27001Mapper — maps ShieldX capabilities to ISO/IEC 27001:2022 Annex A
|
||||
* controls, for use as technical evidence within a broader ISMS.
|
||||
*/
|
||||
export class ISO27001Mapper {
|
||||
private readonly mappings: Readonly<Record<string, ISO27001Mapping>>
|
||||
|
||||
constructor() {
|
||||
this.mappings = ISO27001_MAPPINGS
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single Annex A control mapping by ID.
|
||||
* @param controlId - Annex A control identifier (e.g. 'A.8.16')
|
||||
* @returns Mapping if it exists, undefined otherwise
|
||||
*/
|
||||
getControl(controlId: string): ISO27001Mapping | undefined {
|
||||
return this.mappings[controlId]
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate coverage of the Annex A controls tracked by this mapper.
|
||||
* @returns Coverage statistics with gap control IDs
|
||||
*/
|
||||
getCoverage(): { covered: number; total: number; gaps: readonly string[] } {
|
||||
const covered = Object.values(this.mappings).filter((c) => c.implemented)
|
||||
const gaps = Object.values(this.mappings)
|
||||
.filter((c) => !c.implemented)
|
||||
.map((c) => c.controlId)
|
||||
|
||||
return Object.freeze({
|
||||
covered: covered.length,
|
||||
total: TOTAL_TRACKED_CONTROLS,
|
||||
gaps: Object.freeze(gaps),
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all Annex A control mappings as an array.
|
||||
*/
|
||||
getAllMappings(): readonly ISO27001Mapping[] {
|
||||
return Object.freeze(Object.values(this.mappings))
|
||||
}
|
||||
}
|
||||
138
src/compliance/NIS2Mapper.ts
Normal file
138
src/compliance/NIS2Mapper.ts
Normal file
@ -0,0 +1,138 @@
|
||||
/**
|
||||
* NIS2 Directive (EU) 2022/2555, Article 21(2) risk management measures.
|
||||
* Maps ShieldX capabilities to the ten mandatory cybersecurity risk
|
||||
* management measures for essential and important entities.
|
||||
*/
|
||||
|
||||
import type { NIS2Mapping } from '../types/compliance.js'
|
||||
|
||||
/**
|
||||
* Article 21(2)(a)-(j) measures, mapped to concrete ShieldX evidence
|
||||
* where implemented. Measures ShieldX cannot address (organizational,
|
||||
* HR, or auth-layer concerns outside an LLM defense pipeline) are marked
|
||||
* `implemented: false` with a gap note rather than glossed over.
|
||||
*/
|
||||
const NIS2_MAPPINGS: Readonly<Record<string, NIS2Mapping>> = {
|
||||
'NIS2.Art21.2.a': {
|
||||
measureId: 'NIS2.Art21.2.a',
|
||||
measureName: 'Risk analysis and information system security policies',
|
||||
description: 'Policies on risk analysis and the security of network and information systems',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['KillChainMapper', 'ATLASMapper', 'OWASPMapper', 'ComplianceReport.gaps'],
|
||||
},
|
||||
'NIS2.Art21.2.b': {
|
||||
measureId: 'NIS2.Art21.2.b',
|
||||
measureName: 'Incident handling',
|
||||
description: 'Prevention, detection, and response to security incidents',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['HealingOrchestrator', 'IncidentReporter', 'FeverResponse'],
|
||||
},
|
||||
'NIS2.Art21.2.c': {
|
||||
measureId: 'NIS2.Art21.2.c',
|
||||
measureName: 'Business continuity and crisis management',
|
||||
description: 'Backup management, disaster recovery, and crisis management',
|
||||
implemented: false,
|
||||
shieldxEvidence: [],
|
||||
gapNote: 'ShieldX is a defense layer, not a BC/DR system. Pattern/incident persistence to PostgreSQL provides recoverable state, but backup/restore procedures and crisis management are organizational responsibilities outside ShieldX scope.',
|
||||
},
|
||||
'NIS2.Art21.2.d': {
|
||||
measureId: 'NIS2.Art21.2.d',
|
||||
measureName: 'Supply chain security',
|
||||
description: 'Security of the supply chain, including relationships with direct suppliers',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['SupplyChainVerifier', 'ModelProvenanceChecker', 'ManifestVerifier'],
|
||||
},
|
||||
'NIS2.Art21.2.e': {
|
||||
measureId: 'NIS2.Art21.2.e',
|
||||
measureName: 'Security in system acquisition, development and maintenance',
|
||||
description: 'Vulnerability handling and disclosure',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['RedTeamEngine', 'ResistanceTestEngine', 'DriftDetector'],
|
||||
},
|
||||
'NIS2.Art21.2.f': {
|
||||
measureId: 'NIS2.Art21.2.f',
|
||||
measureName: 'Effectiveness assessment policies',
|
||||
description: 'Policies and procedures to assess the effectiveness of risk management measures',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['benchmark suite (PINT, AgentDojo, ASR)', 'OverDefenseCalibrator', 'ComplianceReport.coverageScore'],
|
||||
},
|
||||
'NIS2.Art21.2.g': {
|
||||
measureId: 'NIS2.Art21.2.g',
|
||||
measureName: 'Basic cyber hygiene and security training',
|
||||
description: 'Basic cyber hygiene practices and cybersecurity training',
|
||||
implemented: false,
|
||||
shieldxEvidence: [],
|
||||
gapNote: 'Organizational/HR training is out of scope for a technical defense library. ShieldX documentation (docs/) can serve as onboarding material, but this measure requires a company-level training program.',
|
||||
},
|
||||
'NIS2.Art21.2.h': {
|
||||
measureId: 'NIS2.Art21.2.h',
|
||||
measureName: 'Cryptography and encryption policies',
|
||||
description: 'Policies and procedures regarding the use of cryptography and encryption',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['SignedPromptVerifier', 'ManifestVerifier', 'SHA-256 input hashing (never raw storage)'],
|
||||
},
|
||||
'NIS2.Art21.2.i': {
|
||||
measureId: 'NIS2.Art21.2.i',
|
||||
measureName: 'Human resources security, access control, asset management',
|
||||
description: 'HR security, access control policies, and asset management',
|
||||
implemented: false,
|
||||
shieldxEvidence: [],
|
||||
gapNote: 'PrivilegeChecker enforces least-privilege for MCP tool calls, but organization-wide HR security, employee access control, and asset inventory are outside an LLM defense library\'s scope.',
|
||||
},
|
||||
'NIS2.Art21.2.j': {
|
||||
measureId: 'NIS2.Art21.2.j',
|
||||
measureName: 'MFA, secured communications',
|
||||
description: 'Multi-factor authentication, secured voice/video/text and emergency communications',
|
||||
implemented: false,
|
||||
shieldxEvidence: [],
|
||||
gapNote: 'ShieldX has no authentication layer of its own; MFA and secure communications must be provided by the surrounding application (e.g., NextAuth, Clerk, an IdP).',
|
||||
},
|
||||
} as const
|
||||
|
||||
/** Total NIS2 Article 21(2) measures */
|
||||
const TOTAL_NIS2_MEASURES = 10
|
||||
|
||||
/**
|
||||
* NIS2Mapper — maps ShieldX capabilities to NIS2 Article 21(2) risk
|
||||
* management measures for essential/important entities.
|
||||
*/
|
||||
export class NIS2Mapper {
|
||||
private readonly mappings: Readonly<Record<string, NIS2Mapping>>
|
||||
|
||||
constructor() {
|
||||
this.mappings = NIS2_MAPPINGS
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single NIS2 measure mapping by ID.
|
||||
* @param measureId - NIS2 Article 21(2) measure identifier (e.g. 'NIS2.Art21.2.b')
|
||||
* @returns Mapping if it exists, undefined otherwise
|
||||
*/
|
||||
getMeasure(measureId: string): NIS2Mapping | undefined {
|
||||
return this.mappings[measureId]
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate coverage of the ten NIS2 Article 21(2) measures.
|
||||
* @returns Coverage statistics with gap measure IDs
|
||||
*/
|
||||
getCoverage(): { covered: number; total: number; gaps: readonly string[] } {
|
||||
const covered = Object.values(this.mappings).filter((m) => m.implemented)
|
||||
const gaps = Object.values(this.mappings)
|
||||
.filter((m) => !m.implemented)
|
||||
.map((m) => m.measureId)
|
||||
|
||||
return Object.freeze({
|
||||
covered: covered.length,
|
||||
total: TOTAL_NIS2_MEASURES,
|
||||
gaps: Object.freeze(gaps),
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all NIS2 measure mappings as an array.
|
||||
*/
|
||||
getAllMappings(): readonly NIS2Mapping[] {
|
||||
return Object.freeze(Object.values(this.mappings))
|
||||
}
|
||||
}
|
||||
@ -10,22 +10,31 @@ import type { LearningStats } from '../types/learning.js'
|
||||
import { ATLASMapper } from './ATLASMapper.js'
|
||||
import { OWASPMapper } from './OWASPMapper.js'
|
||||
import { EUAIActReporter } from './EUAIActReporter.js'
|
||||
import { NIS2Mapper } from './NIS2Mapper.js'
|
||||
import { ISO27001Mapper } from './ISO27001Mapper.js'
|
||||
import { SOC2Mapper } from './SOC2Mapper.js'
|
||||
|
||||
/**
|
||||
* ReportGenerator — unified compliance report generator.
|
||||
*
|
||||
* Orchestrates ATLAS, OWASP, and EU AI Act mappers/reporters
|
||||
* to produce individual or combined compliance reports.
|
||||
* Orchestrates ATLAS, OWASP, EU AI Act, NIS2, ISO/IEC 27001, and SOC 2
|
||||
* mappers/reporters to produce individual or combined compliance reports.
|
||||
*/
|
||||
export class ReportGenerator {
|
||||
private readonly atlasMapper: ATLASMapper
|
||||
private readonly owaspMapper: OWASPMapper
|
||||
private readonly euAiActReporter: EUAIActReporter
|
||||
private readonly nis2Mapper: NIS2Mapper
|
||||
private readonly iso27001Mapper: ISO27001Mapper
|
||||
private readonly soc2Mapper: SOC2Mapper
|
||||
|
||||
constructor() {
|
||||
this.atlasMapper = new ATLASMapper()
|
||||
this.owaspMapper = new OWASPMapper()
|
||||
this.euAiActReporter = new EUAIActReporter()
|
||||
this.nis2Mapper = new NIS2Mapper()
|
||||
this.iso27001Mapper = new ISO27001Mapper()
|
||||
this.soc2Mapper = new SOC2Mapper()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -35,7 +44,7 @@ export class ReportGenerator {
|
||||
* @returns Structured compliance report
|
||||
*/
|
||||
generateComplianceReport(
|
||||
framework: 'mitre_atlas' | 'owasp_llm' | 'eu_ai_act' | 'combined',
|
||||
framework: 'mitre_atlas' | 'owasp_llm' | 'eu_ai_act' | 'nis2' | 'iso27001' | 'soc2' | 'combined',
|
||||
stats?: LearningStats,
|
||||
): ComplianceReport {
|
||||
switch (framework) {
|
||||
@ -45,6 +54,12 @@ export class ReportGenerator {
|
||||
return this.generateOWASPReport()
|
||||
case 'eu_ai_act':
|
||||
return this.generateEUAIActComplianceReport(stats)
|
||||
case 'nis2':
|
||||
return this.generateNIS2Report()
|
||||
case 'iso27001':
|
||||
return this.generateISO27001Report()
|
||||
case 'soc2':
|
||||
return this.generateSOC2Report()
|
||||
case 'combined':
|
||||
return this.generateCombinedReport(stats)
|
||||
}
|
||||
@ -159,19 +174,52 @@ export class ReportGenerator {
|
||||
})
|
||||
}
|
||||
|
||||
private generateNIS2Report(): ComplianceReport {
|
||||
return this.generateGapBasedReport('nis2', this.nis2Mapper.getCoverage(), 'NIS2 Article 21(2) measure')
|
||||
}
|
||||
|
||||
private generateISO27001Report(): ComplianceReport {
|
||||
return this.generateGapBasedReport('iso27001', this.iso27001Mapper.getCoverage(), 'ISO/IEC 27001 Annex A control')
|
||||
}
|
||||
|
||||
private generateSOC2Report(): ComplianceReport {
|
||||
return this.generateGapBasedReport('soc2', this.soc2Mapper.getCoverage(), 'SOC 2 Trust Services Criteria')
|
||||
}
|
||||
|
||||
/** Shared report shape for the three implemented/not-implemented control-coverage mappers */
|
||||
private generateGapBasedReport(
|
||||
framework: 'nis2' | 'iso27001' | 'soc2',
|
||||
coverage: { covered: number; total: number; gaps: readonly string[] },
|
||||
gapLabel: string,
|
||||
): ComplianceReport {
|
||||
return Object.freeze({
|
||||
generatedAt: new Date().toISOString(),
|
||||
framework,
|
||||
coverageScore: coverage.total > 0 ? Math.round((coverage.covered / coverage.total) * 1000) / 1000 : 0,
|
||||
totalTechniques: coverage.total,
|
||||
coveredTechniques: coverage.covered,
|
||||
gaps: Object.freeze(coverage.gaps.map((g) => `${gapLabel} ${g} not implemented`)),
|
||||
recommendations: Object.freeze([
|
||||
`Address ${coverage.gaps.length} outstanding ${gapLabel} gap(s) — see ComplianceRobot.assess() for an owned action plan`,
|
||||
`Re-run this report after each ShieldX capability addition to keep coverage current`,
|
||||
]),
|
||||
mappings: Object.freeze([]),
|
||||
})
|
||||
}
|
||||
|
||||
private generateCombinedReport(stats?: LearningStats): ComplianceReport {
|
||||
const atlasReport = this.generateATLASReport()
|
||||
const owaspReport = this.generateOWASPReport()
|
||||
const euReport = this.generateEUAIActComplianceReport(stats)
|
||||
const nis2Report = this.generateNIS2Report()
|
||||
const isoReport = this.generateISO27001Report()
|
||||
const soc2Report = this.generateSOC2Report()
|
||||
|
||||
const totalTechniques = atlasReport.totalTechniques + owaspReport.totalTechniques + euReport.totalTechniques
|
||||
const coveredTechniques = atlasReport.coveredTechniques + owaspReport.coveredTechniques + euReport.coveredTechniques
|
||||
const allGaps = [...atlasReport.gaps, ...owaspReport.gaps, ...euReport.gaps]
|
||||
const allRecommendations = [
|
||||
...atlasReport.recommendations,
|
||||
...owaspReport.recommendations,
|
||||
...euReport.recommendations,
|
||||
]
|
||||
const allReports = [atlasReport, owaspReport, euReport, nis2Report, isoReport, soc2Report]
|
||||
const totalTechniques = allReports.reduce((sum, r) => sum + r.totalTechniques, 0)
|
||||
const coveredTechniques = allReports.reduce((sum, r) => sum + r.coveredTechniques, 0)
|
||||
const allGaps = allReports.flatMap((r) => r.gaps)
|
||||
const allRecommendations = allReports.flatMap((r) => r.recommendations)
|
||||
const allMappings: readonly (ATLASMapping | OWASPMapping)[] = [
|
||||
...atlasReport.mappings,
|
||||
...owaspReport.mappings,
|
||||
|
||||
155
src/compliance/SOC2Mapper.ts
Normal file
155
src/compliance/SOC2Mapper.ts
Normal file
@ -0,0 +1,155 @@
|
||||
/**
|
||||
* SOC 2 Trust Services Criteria mapping.
|
||||
* Maps ShieldX capabilities to the Security (Common Criteria),
|
||||
* Confidentiality, and Processing Integrity categories most relevant
|
||||
* to an LLM defense pipeline.
|
||||
*/
|
||||
|
||||
import type { SOC2Mapping } from '../types/compliance.js'
|
||||
|
||||
/**
|
||||
* Trust Services Criteria this mapper tracks. Availability and Privacy
|
||||
* criteria depend on infrastructure/data-handling decisions made by the
|
||||
* surrounding application, not by ShieldX itself, so most of those are
|
||||
* marked as gaps rather than claimed.
|
||||
*/
|
||||
const SOC2_MAPPINGS: Readonly<Record<string, SOC2Mapping>> = {
|
||||
'CC3.2': {
|
||||
criteriaId: 'CC3.2',
|
||||
criteriaName: 'Risk identification and analysis',
|
||||
category: 'security',
|
||||
description: 'The entity identifies risks to the achievement of its objectives',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['ATLASMapper', 'OWASPMapper', 'ComplianceReport.gaps'],
|
||||
},
|
||||
'CC4.1': {
|
||||
criteriaId: 'CC4.1',
|
||||
criteriaName: 'Ongoing and separate evaluations',
|
||||
category: 'security',
|
||||
description: 'The entity monitors the system to identify control deficiencies',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['DriftDetector', 'OverDefenseCalibrator', 'ShieldXDashboard'],
|
||||
},
|
||||
'CC6.1': {
|
||||
criteriaId: 'CC6.1',
|
||||
criteriaName: 'Logical access controls',
|
||||
category: 'security',
|
||||
description: 'Logical access to system resources is restricted',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['PrivilegeChecker', 'ScopeValidator', 'RoleIntegrityChecker'],
|
||||
},
|
||||
'CC7.2': {
|
||||
criteriaId: 'CC7.2',
|
||||
criteriaName: 'System monitoring for anomalies and incidents',
|
||||
category: 'security',
|
||||
description: 'The entity monitors system components for anomalies indicative of malicious acts or security events',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['AnomalyDetector', 'SessionProfiler', 'FeverResponse'],
|
||||
},
|
||||
'CC7.3': {
|
||||
criteriaId: 'CC7.3',
|
||||
criteriaName: 'Incident evaluation and response',
|
||||
category: 'security',
|
||||
description: 'The entity evaluates security events to determine response actions',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['HealingOrchestrator', 'IncidentReporter', 'KillChainMapper'],
|
||||
},
|
||||
'CC8.1': {
|
||||
criteriaId: 'CC8.1',
|
||||
criteriaName: 'Change management',
|
||||
category: 'security',
|
||||
description: 'Changes to infrastructure, data, software are authorized, designed, and tested',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['CHANGELOG.md', '.github/workflows/security-scan.yml', 'benchmark suite regression checks'],
|
||||
},
|
||||
'CC9.1': {
|
||||
criteriaId: 'CC9.1',
|
||||
criteriaName: 'Risk mitigation for business disruptions',
|
||||
category: 'security',
|
||||
description: 'The entity identifies, selects, and develops risk mitigation activities',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['Graceful degradation (safeRunScanner, Promise.allSettled)', 'RateLimiter'],
|
||||
},
|
||||
'C1.1': {
|
||||
criteriaId: 'C1.1',
|
||||
criteriaName: 'Identification and protection of confidential information',
|
||||
category: 'confidentiality',
|
||||
description: 'Confidential information is identified and protected against unauthorized disclosure',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['CredentialRedactor', 'SHA-256 input hashing (no raw storage)', 'LeakageDetector'],
|
||||
},
|
||||
'PI1.1': {
|
||||
criteriaId: 'PI1.1',
|
||||
criteriaName: 'Processing integrity — quality assurance',
|
||||
category: 'processing_integrity',
|
||||
description: 'The entity obtains or generates information regarding processing accuracy',
|
||||
implemented: true,
|
||||
shieldxEvidence: ['benchmark suite (TPR/FPR)', 'PINT/AgentDojo benchmarks', 'FeedbackProcessor'],
|
||||
},
|
||||
'A1.2': {
|
||||
criteriaId: 'A1.2',
|
||||
criteriaName: 'Availability — environmental protections and recovery',
|
||||
category: 'availability',
|
||||
description: 'Environmental protections, backups, and recovery infrastructure',
|
||||
implemented: false,
|
||||
shieldxEvidence: [],
|
||||
gapNote: 'Availability is an infrastructure/deployment concern (hosting, backups, failover) outside a defense library\'s scope; ecosystem.config.js and docker-compose.yml provide process supervision but not a full DR posture.',
|
||||
},
|
||||
'P1.1': {
|
||||
criteriaId: 'P1.1',
|
||||
criteriaName: 'Privacy notice and choice',
|
||||
category: 'privacy',
|
||||
description: 'The entity provides notice and choice regarding personal information handling',
|
||||
implemented: false,
|
||||
shieldxEvidence: [],
|
||||
gapNote: 'Privacy notices and consent flows are the responsibility of the surrounding product, not ShieldX; ShieldX\'s contribution is data minimization (no raw input storage), which supports but does not fulfill this criterion.',
|
||||
},
|
||||
} as const
|
||||
|
||||
/** Total SOC 2 criteria tracked by this mapper (representative subset) */
|
||||
const TOTAL_TRACKED_CRITERIA = Object.keys(SOC2_MAPPINGS).length
|
||||
|
||||
/**
|
||||
* SOC2Mapper — maps ShieldX capabilities to SOC 2 Trust Services Criteria,
|
||||
* for use as technical evidence within a SOC 2 Type II audit.
|
||||
*/
|
||||
export class SOC2Mapper {
|
||||
private readonly mappings: Readonly<Record<string, SOC2Mapping>>
|
||||
|
||||
constructor() {
|
||||
this.mappings = SOC2_MAPPINGS
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single Trust Services Criteria mapping by ID.
|
||||
* @param criteriaId - SOC 2 criteria identifier (e.g. 'CC7.2')
|
||||
* @returns Mapping if it exists, undefined otherwise
|
||||
*/
|
||||
getCriteria(criteriaId: string): SOC2Mapping | undefined {
|
||||
return this.mappings[criteriaId]
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate coverage of the Trust Services Criteria tracked by this mapper.
|
||||
* @returns Coverage statistics with gap criteria IDs
|
||||
*/
|
||||
getCoverage(): { covered: number; total: number; gaps: readonly string[] } {
|
||||
const covered = Object.values(this.mappings).filter((c) => c.implemented)
|
||||
const gaps = Object.values(this.mappings)
|
||||
.filter((c) => !c.implemented)
|
||||
.map((c) => c.criteriaId)
|
||||
|
||||
return Object.freeze({
|
||||
covered: covered.length,
|
||||
total: TOTAL_TRACKED_CRITERIA,
|
||||
gaps: Object.freeze(gaps),
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all Trust Services Criteria mappings as an array.
|
||||
*/
|
||||
getAllMappings(): readonly SOC2Mapping[] {
|
||||
return Object.freeze(Object.values(this.mappings))
|
||||
}
|
||||
}
|
||||
@ -8,3 +8,8 @@ export { ATLASMapper } from './ATLASMapper.js'
|
||||
export { OWASPMapper } from './OWASPMapper.js'
|
||||
export { EUAIActReporter } from './EUAIActReporter.js'
|
||||
export { ReportGenerator } from './ReportGenerator.js'
|
||||
export { NIS2Mapper } from './NIS2Mapper.js'
|
||||
export { ISO27001Mapper } from './ISO27001Mapper.js'
|
||||
export { SOC2Mapper } from './SOC2Mapper.js'
|
||||
export { ComplianceRobot } from './ComplianceRobot.js'
|
||||
export { EUAIActAgent, EU_AI_ACT_TIMELINE } from './EUAIActAgent.js'
|
||||
|
||||
@ -29,7 +29,7 @@ export interface OWASPMapping {
|
||||
/** Compliance report output */
|
||||
export interface ComplianceReport {
|
||||
readonly generatedAt: string
|
||||
readonly framework: 'mitre_atlas' | 'owasp_llm' | 'eu_ai_act' | 'combined'
|
||||
readonly framework: 'mitre_atlas' | 'owasp_llm' | 'eu_ai_act' | 'nis2' | 'iso27001' | 'soc2' | 'combined'
|
||||
readonly coverageScore: number
|
||||
readonly totalTechniques: number
|
||||
readonly coveredTechniques: number
|
||||
@ -70,3 +70,84 @@ export interface EUAIActReport {
|
||||
readonly lastAssessmentDate?: string
|
||||
}
|
||||
}
|
||||
|
||||
/** NIS2 Directive (EU) 2022/2555, Article 21(2) risk management measure mapping */
|
||||
export interface NIS2Mapping {
|
||||
readonly measureId: string
|
||||
readonly measureName: string
|
||||
readonly description: string
|
||||
readonly implemented: boolean
|
||||
readonly shieldxEvidence: readonly string[]
|
||||
readonly gapNote?: string
|
||||
}
|
||||
|
||||
/** ISO/IEC 27001:2022 Annex A control mapping */
|
||||
export interface ISO27001Mapping {
|
||||
readonly controlId: string
|
||||
readonly controlName: string
|
||||
readonly theme: 'organizational' | 'people' | 'physical' | 'technological'
|
||||
readonly description: string
|
||||
readonly implemented: boolean
|
||||
readonly shieldxEvidence: readonly string[]
|
||||
readonly gapNote?: string
|
||||
}
|
||||
|
||||
/** SOC 2 Trust Services Criteria mapping */
|
||||
export interface SOC2Mapping {
|
||||
readonly criteriaId: string
|
||||
readonly criteriaName: string
|
||||
readonly category: 'security' | 'availability' | 'confidentiality' | 'processing_integrity' | 'privacy'
|
||||
readonly description: string
|
||||
readonly implemented: boolean
|
||||
readonly shieldxEvidence: readonly string[]
|
||||
readonly gapNote?: string
|
||||
}
|
||||
|
||||
/** EU AI Act Article 6 / Annex III risk classification result */
|
||||
export interface EUAIActRiskClassification {
|
||||
readonly assessedAt: string
|
||||
readonly deploymentContext: string
|
||||
readonly annexIIICategory?: string
|
||||
readonly riskCategory: 'unacceptable' | 'high' | 'limited' | 'minimal' | 'undetermined'
|
||||
readonly reasoning: readonly string[]
|
||||
readonly requiresLegalReview: boolean
|
||||
}
|
||||
|
||||
/** EU AI Act Annex IV technical documentation scaffold (technical fields only — legal/business fields excluded) */
|
||||
export interface AnnexIVDocumentation {
|
||||
readonly generatedAt: string
|
||||
readonly systemDescription: string
|
||||
readonly riskManagementSummary: string
|
||||
readonly loggingCapabilities: string
|
||||
readonly humanOversightDesign: string
|
||||
readonly accuracyRobustnessCybersecurity: string
|
||||
readonly fieldsRequiringLegalInput: readonly string[]
|
||||
}
|
||||
|
||||
/** EU AI Act Article 72 post-market monitoring plan */
|
||||
export interface PostMarketMonitoringPlan {
|
||||
readonly generatedAt: string
|
||||
readonly monitoringMechanisms: readonly string[]
|
||||
readonly reviewCadence: string
|
||||
readonly incidentEscalationPath: string
|
||||
}
|
||||
|
||||
/** A single actionable compliance to-do produced by the Compliance-Robot */
|
||||
export interface ComplianceActionItem {
|
||||
readonly id: string
|
||||
readonly framework: 'nis2' | 'iso27001' | 'soc2' | 'eu_ai_act'
|
||||
readonly controlId: string
|
||||
readonly title: string
|
||||
readonly priority: 'critical' | 'high' | 'medium' | 'low'
|
||||
readonly effort: 'low' | 'medium' | 'high'
|
||||
readonly recommendation: string
|
||||
readonly owner: 'engineering' | 'security' | 'legal' | 'management'
|
||||
}
|
||||
|
||||
/** Compliance-Robot aggregated readiness assessment across all frameworks */
|
||||
export interface ComplianceRobotAssessment {
|
||||
readonly generatedAt: string
|
||||
readonly overallReadiness: Readonly<Record<'nis2' | 'iso27001' | 'soc2' | 'eu_ai_act', number>>
|
||||
readonly actionPlan: readonly ComplianceActionItem[]
|
||||
readonly criticalGapCount: number
|
||||
}
|
||||
|
||||
57
tests/unit/compliance/ComplianceRobot.test.ts
Normal file
57
tests/unit/compliance/ComplianceRobot.test.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest'
|
||||
import { ComplianceRobot } from '../../../src/compliance/ComplianceRobot.js'
|
||||
import type { LearningStats } from '../../../src/types/learning.js'
|
||||
|
||||
const stats: LearningStats = Object.freeze({
|
||||
totalPatterns: 100,
|
||||
builtinPatterns: 80,
|
||||
learnedPatterns: 15,
|
||||
communityPatterns: 5,
|
||||
redTeamPatterns: 3,
|
||||
totalIncidents: 42,
|
||||
falsePositiveRate: 0.02,
|
||||
topPatterns: Object.freeze([]),
|
||||
recentIncidents: 4,
|
||||
driftDetected: false,
|
||||
})
|
||||
|
||||
describe('ComplianceRobot', () => {
|
||||
let robot: ComplianceRobot
|
||||
|
||||
beforeEach(() => {
|
||||
robot = new ComplianceRobot()
|
||||
})
|
||||
|
||||
describe('assess()', () => {
|
||||
it('should return readiness scores for all four frameworks', () => {
|
||||
const assessment = robot.assess(stats)
|
||||
expect(assessment.overallReadiness.nis2).toBeGreaterThan(0)
|
||||
expect(assessment.overallReadiness.iso27001).toBeGreaterThan(0)
|
||||
expect(assessment.overallReadiness.soc2).toBeGreaterThan(0)
|
||||
expect(assessment.overallReadiness.eu_ai_act).toBeGreaterThanOrEqual(0)
|
||||
})
|
||||
|
||||
it('should produce an action plan sorted by priority', () => {
|
||||
const assessment = robot.assess(stats)
|
||||
expect(assessment.actionPlan.length).toBeGreaterThan(0)
|
||||
const priorityRank: Record<string, number> = { critical: 0, high: 1, medium: 2, low: 3 }
|
||||
for (let i = 1; i < assessment.actionPlan.length; i++) {
|
||||
expect(priorityRank[assessment.actionPlan[i].priority]).toBeGreaterThanOrEqual(
|
||||
priorityRank[assessment.actionPlan[i - 1].priority],
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
it('should include NIS2, ISO27001, SOC2, and EU AI Act action items', () => {
|
||||
const assessment = robot.assess(stats)
|
||||
const frameworks = new Set(assessment.actionPlan.map((item) => item.framework))
|
||||
expect(frameworks.has('nis2')).toBe(true)
|
||||
expect(frameworks.has('iso27001')).toBe(true)
|
||||
expect(frameworks.has('soc2')).toBe(true)
|
||||
})
|
||||
|
||||
it('should work without stats (uses EU AI Act default fallback)', () => {
|
||||
expect(() => robot.assess()).not.toThrow()
|
||||
})
|
||||
})
|
||||
})
|
||||
67
tests/unit/compliance/EUAIActAgent.test.ts
Normal file
67
tests/unit/compliance/EUAIActAgent.test.ts
Normal file
@ -0,0 +1,67 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest'
|
||||
import { EUAIActAgent, EU_AI_ACT_TIMELINE } from '../../../src/compliance/EUAIActAgent.js'
|
||||
import type { LearningStats } from '../../../src/types/learning.js'
|
||||
|
||||
const stats: LearningStats = Object.freeze({
|
||||
totalPatterns: 100,
|
||||
builtinPatterns: 80,
|
||||
learnedPatterns: 15,
|
||||
communityPatterns: 5,
|
||||
redTeamPatterns: 3,
|
||||
totalIncidents: 42,
|
||||
falsePositiveRate: 0.02,
|
||||
topPatterns: Object.freeze([]),
|
||||
recentIncidents: 4,
|
||||
driftDetected: false,
|
||||
})
|
||||
|
||||
describe('EUAIActAgent', () => {
|
||||
let agent: EUAIActAgent
|
||||
|
||||
beforeEach(() => {
|
||||
agent = new EUAIActAgent()
|
||||
})
|
||||
|
||||
describe('classifyRisk()', () => {
|
||||
it('should classify a law enforcement deployment as high risk', () => {
|
||||
const result = agent.classifyRisk('Used by police for law enforcement case triage')
|
||||
expect(result.riskCategory).toBe('high')
|
||||
expect(result.annexIIICategory).toContain('Law enforcement')
|
||||
expect(result.requiresLegalReview).toBe(true)
|
||||
})
|
||||
|
||||
it('should classify a social scoring context as unacceptable', () => {
|
||||
const result = agent.classifyRisk('This system performs social scoring of citizens')
|
||||
expect(result.riskCategory).toBe('unacceptable')
|
||||
})
|
||||
|
||||
it('should classify an unmatched context as undetermined', () => {
|
||||
const result = agent.classifyRisk('Internal documentation search tool for engineers')
|
||||
expect(result.riskCategory).toBe('undetermined')
|
||||
expect(result.requiresLegalReview).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('generateAnnexIVDocumentation()', () => {
|
||||
it('should produce technical fields and flag legal-input fields separately', () => {
|
||||
const doc = agent.generateAnnexIVDocumentation(stats)
|
||||
expect(doc.systemDescription).toBeTruthy()
|
||||
expect(doc.fieldsRequiringLegalInput.length).toBeGreaterThan(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe('generatePostMarketMonitoringPlan()', () => {
|
||||
it('should reference concrete ShieldX monitoring mechanisms', () => {
|
||||
const plan = agent.generatePostMarketMonitoringPlan(stats)
|
||||
expect(plan.monitoringMechanisms.length).toBeGreaterThan(0)
|
||||
expect(plan.incidentEscalationPath).toContain('HealingOrchestrator')
|
||||
})
|
||||
})
|
||||
|
||||
describe('EU_AI_ACT_TIMELINE', () => {
|
||||
it('should expose the corrected 2027/2028 enforcement dates', () => {
|
||||
expect(EU_AI_ACT_TIMELINE.standaloneAnnexIIIHighRisk).toBe('2027-12-02')
|
||||
expect(EU_AI_ACT_TIMELINE.annexIEmbeddedHighRisk).toBe('2028-08-02')
|
||||
})
|
||||
})
|
||||
})
|
||||
46
tests/unit/compliance/ISO27001Mapper.test.ts
Normal file
46
tests/unit/compliance/ISO27001Mapper.test.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest'
|
||||
import { ISO27001Mapper } from '../../../src/compliance/ISO27001Mapper.js'
|
||||
|
||||
describe('ISO27001Mapper', () => {
|
||||
let mapper: ISO27001Mapper
|
||||
|
||||
beforeEach(() => {
|
||||
mapper = new ISO27001Mapper()
|
||||
})
|
||||
|
||||
describe('getControl()', () => {
|
||||
it('should return the logging control as implemented', () => {
|
||||
const control = mapper.getControl('A.8.15')
|
||||
expect(control).toBeDefined()
|
||||
expect(control!.implemented).toBe(true)
|
||||
expect(control!.theme).toBe('technological')
|
||||
})
|
||||
|
||||
it('should return physical security as a gap', () => {
|
||||
const control = mapper.getControl('A.7.1')
|
||||
expect(control).toBeDefined()
|
||||
expect(control!.implemented).toBe(false)
|
||||
expect(control!.theme).toBe('physical')
|
||||
expect(control!.gapNote).toBeTruthy()
|
||||
})
|
||||
|
||||
it('should return undefined for unknown control', () => {
|
||||
expect(mapper.getControl('A.99.99')).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe('getCoverage()', () => {
|
||||
it('should compute covered/total/gaps consistently', () => {
|
||||
const coverage = mapper.getCoverage()
|
||||
expect(coverage.covered + coverage.gaps.length).toBe(coverage.total)
|
||||
})
|
||||
})
|
||||
|
||||
describe('getAllMappings()', () => {
|
||||
it('should return a frozen array of mappings', () => {
|
||||
const mappings = mapper.getAllMappings()
|
||||
expect(Object.isFrozen(mappings)).toBe(true)
|
||||
expect(mappings.length).toBeGreaterThan(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
50
tests/unit/compliance/NIS2Mapper.test.ts
Normal file
50
tests/unit/compliance/NIS2Mapper.test.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest'
|
||||
import { NIS2Mapper } from '../../../src/compliance/NIS2Mapper.js'
|
||||
|
||||
describe('NIS2Mapper', () => {
|
||||
let mapper: NIS2Mapper
|
||||
|
||||
beforeEach(() => {
|
||||
mapper = new NIS2Mapper()
|
||||
})
|
||||
|
||||
describe('getMeasure()', () => {
|
||||
it('should return the incident handling measure', () => {
|
||||
const measure = mapper.getMeasure('NIS2.Art21.2.b')
|
||||
expect(measure).toBeDefined()
|
||||
expect(measure!.implemented).toBe(true)
|
||||
expect(measure!.shieldxEvidence).toContain('HealingOrchestrator')
|
||||
})
|
||||
|
||||
it('should return a gap for MFA/secured communications', () => {
|
||||
const measure = mapper.getMeasure('NIS2.Art21.2.j')
|
||||
expect(measure).toBeDefined()
|
||||
expect(measure!.implemented).toBe(false)
|
||||
expect(measure!.gapNote).toBeTruthy()
|
||||
})
|
||||
|
||||
it('should return undefined for unknown measure', () => {
|
||||
expect(mapper.getMeasure('NIS2.Art21.2.z')).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe('getCoverage()', () => {
|
||||
it('should report 10 total measures', () => {
|
||||
const coverage = mapper.getCoverage()
|
||||
expect(coverage.total).toBe(10)
|
||||
expect(coverage.covered).toBeGreaterThan(0)
|
||||
expect(coverage.covered).toBeLessThan(coverage.total)
|
||||
})
|
||||
|
||||
it('should list uncovered measure IDs as gaps', () => {
|
||||
const coverage = mapper.getCoverage()
|
||||
expect(coverage.gaps).toContain('NIS2.Art21.2.j')
|
||||
})
|
||||
})
|
||||
|
||||
describe('getAllMappings()', () => {
|
||||
it('should return all 10 measures', () => {
|
||||
expect(mapper.getAllMappings().length).toBe(10)
|
||||
})
|
||||
})
|
||||
})
|
||||
38
tests/unit/compliance/SOC2Mapper.test.ts
Normal file
38
tests/unit/compliance/SOC2Mapper.test.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest'
|
||||
import { SOC2Mapper } from '../../../src/compliance/SOC2Mapper.js'
|
||||
|
||||
describe('SOC2Mapper', () => {
|
||||
let mapper: SOC2Mapper
|
||||
|
||||
beforeEach(() => {
|
||||
mapper = new SOC2Mapper()
|
||||
})
|
||||
|
||||
describe('getCriteria()', () => {
|
||||
it('should return the logical access control criterion as implemented', () => {
|
||||
const criteria = mapper.getCriteria('CC6.1')
|
||||
expect(criteria).toBeDefined()
|
||||
expect(criteria!.implemented).toBe(true)
|
||||
expect(criteria!.category).toBe('security')
|
||||
})
|
||||
|
||||
it('should return availability as a gap', () => {
|
||||
const criteria = mapper.getCriteria('A1.2')
|
||||
expect(criteria).toBeDefined()
|
||||
expect(criteria!.implemented).toBe(false)
|
||||
expect(criteria!.category).toBe('availability')
|
||||
})
|
||||
|
||||
it('should return undefined for unknown criteria', () => {
|
||||
expect(mapper.getCriteria('ZZ9.9')).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe('getCoverage()', () => {
|
||||
it('should compute covered/total/gaps consistently', () => {
|
||||
const coverage = mapper.getCoverage()
|
||||
expect(coverage.covered + coverage.gaps.length).toBe(coverage.total)
|
||||
expect(coverage.gaps).toContain('P1.1')
|
||||
})
|
||||
})
|
||||
})
|
||||
Loading…
x
Reference in New Issue
Block a user