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
|
training/data
|
||||||
ctxmeet
|
ctxmeet
|
||||||
ctxevent
|
ctxevent
|
||||||
context-x\.org
|
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
import type { NextConfig } from 'next'
|
import type { NextConfig } from 'next'
|
||||||
|
|
||||||
const config: NextConfig = {}
|
const config: NextConfig = {
|
||||||
|
output: 'standalone',
|
||||||
|
}
|
||||||
|
|
||||||
export default config
|
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 { ATLASMapper } from './ATLASMapper.js'
|
||||||
import { OWASPMapper } from './OWASPMapper.js'
|
import { OWASPMapper } from './OWASPMapper.js'
|
||||||
import { EUAIActReporter } from './EUAIActReporter.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.
|
* ReportGenerator — unified compliance report generator.
|
||||||
*
|
*
|
||||||
* Orchestrates ATLAS, OWASP, and EU AI Act mappers/reporters
|
* Orchestrates ATLAS, OWASP, EU AI Act, NIS2, ISO/IEC 27001, and SOC 2
|
||||||
* to produce individual or combined compliance reports.
|
* mappers/reporters to produce individual or combined compliance reports.
|
||||||
*/
|
*/
|
||||||
export class ReportGenerator {
|
export class ReportGenerator {
|
||||||
private readonly atlasMapper: ATLASMapper
|
private readonly atlasMapper: ATLASMapper
|
||||||
private readonly owaspMapper: OWASPMapper
|
private readonly owaspMapper: OWASPMapper
|
||||||
private readonly euAiActReporter: EUAIActReporter
|
private readonly euAiActReporter: EUAIActReporter
|
||||||
|
private readonly nis2Mapper: NIS2Mapper
|
||||||
|
private readonly iso27001Mapper: ISO27001Mapper
|
||||||
|
private readonly soc2Mapper: SOC2Mapper
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.atlasMapper = new ATLASMapper()
|
this.atlasMapper = new ATLASMapper()
|
||||||
this.owaspMapper = new OWASPMapper()
|
this.owaspMapper = new OWASPMapper()
|
||||||
this.euAiActReporter = new EUAIActReporter()
|
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
|
* @returns Structured compliance report
|
||||||
*/
|
*/
|
||||||
generateComplianceReport(
|
generateComplianceReport(
|
||||||
framework: 'mitre_atlas' | 'owasp_llm' | 'eu_ai_act' | 'combined',
|
framework: 'mitre_atlas' | 'owasp_llm' | 'eu_ai_act' | 'nis2' | 'iso27001' | 'soc2' | 'combined',
|
||||||
stats?: LearningStats,
|
stats?: LearningStats,
|
||||||
): ComplianceReport {
|
): ComplianceReport {
|
||||||
switch (framework) {
|
switch (framework) {
|
||||||
@ -45,6 +54,12 @@ export class ReportGenerator {
|
|||||||
return this.generateOWASPReport()
|
return this.generateOWASPReport()
|
||||||
case 'eu_ai_act':
|
case 'eu_ai_act':
|
||||||
return this.generateEUAIActComplianceReport(stats)
|
return this.generateEUAIActComplianceReport(stats)
|
||||||
|
case 'nis2':
|
||||||
|
return this.generateNIS2Report()
|
||||||
|
case 'iso27001':
|
||||||
|
return this.generateISO27001Report()
|
||||||
|
case 'soc2':
|
||||||
|
return this.generateSOC2Report()
|
||||||
case 'combined':
|
case 'combined':
|
||||||
return this.generateCombinedReport(stats)
|
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 {
|
private generateCombinedReport(stats?: LearningStats): ComplianceReport {
|
||||||
const atlasReport = this.generateATLASReport()
|
const atlasReport = this.generateATLASReport()
|
||||||
const owaspReport = this.generateOWASPReport()
|
const owaspReport = this.generateOWASPReport()
|
||||||
const euReport = this.generateEUAIActComplianceReport(stats)
|
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 allReports = [atlasReport, owaspReport, euReport, nis2Report, isoReport, soc2Report]
|
||||||
const coveredTechniques = atlasReport.coveredTechniques + owaspReport.coveredTechniques + euReport.coveredTechniques
|
const totalTechniques = allReports.reduce((sum, r) => sum + r.totalTechniques, 0)
|
||||||
const allGaps = [...atlasReport.gaps, ...owaspReport.gaps, ...euReport.gaps]
|
const coveredTechniques = allReports.reduce((sum, r) => sum + r.coveredTechniques, 0)
|
||||||
const allRecommendations = [
|
const allGaps = allReports.flatMap((r) => r.gaps)
|
||||||
...atlasReport.recommendations,
|
const allRecommendations = allReports.flatMap((r) => r.recommendations)
|
||||||
...owaspReport.recommendations,
|
|
||||||
...euReport.recommendations,
|
|
||||||
]
|
|
||||||
const allMappings: readonly (ATLASMapping | OWASPMapping)[] = [
|
const allMappings: readonly (ATLASMapping | OWASPMapping)[] = [
|
||||||
...atlasReport.mappings,
|
...atlasReport.mappings,
|
||||||
...owaspReport.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 { OWASPMapper } from './OWASPMapper.js'
|
||||||
export { EUAIActReporter } from './EUAIActReporter.js'
|
export { EUAIActReporter } from './EUAIActReporter.js'
|
||||||
export { ReportGenerator } from './ReportGenerator.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 */
|
/** Compliance report output */
|
||||||
export interface ComplianceReport {
|
export interface ComplianceReport {
|
||||||
readonly generatedAt: string
|
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 coverageScore: number
|
||||||
readonly totalTechniques: number
|
readonly totalTechniques: number
|
||||||
readonly coveredTechniques: number
|
readonly coveredTechniques: number
|
||||||
@ -70,3 +70,84 @@ export interface EUAIActReport {
|
|||||||
readonly lastAssessmentDate?: string
|
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