Files
craftvia/docs/PROMPT-lane-framework-iso27001.md
msolarczekandClaude Opus 5 c8e6f30a27
CI / build-and-check (push) Canceled after 0s
CI / audit (push) Canceled after 0s
CI / sbom (push) Canceled after 0s
Basis: Certvia dev@a48c5fb als Fundament für Craftvia
Unveränderter Stand von certvia/dev (a48c5fb) plus Craftvia-Spezifikation
und Brandbook unter docs/craftvia/. ISMS-Module werden im Folgecommit entfernt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 11:05:39 +02:00

152 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Kickoff-Prompt — Framework-Dimension: ISO 27001 neben TISAX
Du übernimmst den **Anwendungsumbau** für die Mehr-Framework-Fähigkeit. Die **Inhaltsseite ist fertig**: `seed/isms-vorlagenpaket-v2` trägt seit Branch `feature/iso27001-framework-mapping` **zwei Framework-Mappings auf einem Dokumentensatz** — `mapping.json` (VDA ISA, 321 Anforderungen) und `mapping-iso.json` (ISO/IEC 27001:2022, 120 Anforderungen). Die Anwendung kennt das zweite Mapping nicht: `parsePackageFiles` liest `mapping.json` fest verdrahtet.
**Pflichtlektüre vor der ersten Zeile Code:** `docs/UEBERGABE-framework-iso27001.md` — insbesondere **§1 „Die vier Fallen"**. Hintergrund und Begründung der Entscheidung: `docs/FRAMEWORK-MAPPING-ISO27001.md`. Gesamtarchitektur: `docs/KONZEPT-framework-iso27001.md` (D4 und Lane 2 sind dort per Nachtrag korrigiert).
## Repo & Branch
- **origin:** `git.certvia.de/msolarczek/certvia`; zweiter Remote `local-gitea`.
- **Basis ist `feature/iso27001-framework-mapping`**, nicht `dev` — dort liegt die Vorarbeit (Commits `492d315`, `bbde804`, `7769908`, `b28d0f0`).
- AP1 auf `feature/framework-core`, PR gegen den Basis-Branch. AP2–AP5 danach je eigener Branch, parallelisierbar.
## Nicht anfassen
- **`seed/isms-vorlagenpaket-v2/**`** — generiert. Inhaltliche Änderungen laufen ausschließlich über `_iso_crosswalk.json` / `_iso_sections.json` + `python3 _generate_iso.py`, nie direkt in den Markdown-Dateien (der Generator überschreibt sentinel-begrenzte Blöcke).
- **Die TISAX-Logik verhaltensgleich lassen:** `src/lib/maturity.ts`, `src/lib/scope-filter.ts`, `src/server/assessment-level.ts`, `src/lib/control-titles.ts`, `src/lib/export/vda-isa*.ts`. Wenn du sie hinter eine `FrameworkStrategy` ziehst, muss das Verhalten identisch bleiben.
## Vier Invarianten — hier geht es sonst schief
1. **`reconcilePackage` archiviert fremde Anforderungen.** `prisma/import-policies.ts:368-371` setzt `archivedAt` auf jede `PolicyRequirement`, deren `reqId` nicht im importierten Paket steht. Ein ISO-Import in einen TISAX-Mandanten legt damit **alle 321 VDA-ISA-Anforderungen still** — und umgekehrt. Lösung: `PolicyRequirement.framework` ergänzen (Backfill `TISAX`) und den Archivierungslauf auf `where: { tenantId, framework }` einschränken. Für Dokumente, Variablen, Baseline und Nachweisregister gilt das **nicht** — die sind geteilt und identisch, sie dürfen genau einmal je Mandant abgeglichen werden.
2. **Zwei Unique-Constraints brechen.** `PolicyTemplateVersion.version @unique` (`prisma/schema.prisma:1639`) → `@@unique([framework, version])`, sonst kollidieren ISO 2.1 und TISAX 2.1. `PolicyPackageState.tenantId @unique` (`:1614`) → `@@unique([tenantId, framework])`, sonst merkt sich ein Mandant nur eine Paketversion.
3. **TISAX darf sich nicht verändern.** Messlatte ist `python3 seed/isms-vorlagenpaket-v2/_render_diff.py HEAD` → 0 Abweichungen.
4. **Den Fail-Safe in `src/lib/policy-render.ts` nicht entfernen.** `buildContext` belegt fehlende Framework-Flags vor (`FLAG_FW_TISAX = true`, `FLAG_FW_ISO27001 = false`), damit Bestandsmandanten vor dem Paket-Re-Import keine leeren Anforderungsblöcke sehen.
## AP1 — Framework-Dimension *(Fundament, blockiert alles)*
**Schema, additiv:**
```prisma
enum Framework { ISO_27001 TISAX }
model TenantFramework {
id String @id @default(cuid())
tenantId String @map("tenant_id")
framework Framework
isPrimary Boolean @default(false) @map("is_primary")
config Json? // z. B. { tisaxLevel: "AL3" } bzw. { certScope }
createdAt DateTime @default(now()) @map("created_at")
@@unique([tenantId, framework])
@@index([tenantId])
@@map("tenant_frameworks")
}
```
Dazu `PolicyRequirement.framework`, `PolicyTemplateVersion.framework`, `PolicyPackageState.framework`. Backfill aller Bestandsdaten auf `TISAX`. `TenantFramework` gehört in **`TENANT_MODELS`** (`src/server/db.ts:81`) und braucht eine **RLS-Policy in der Migration**.
**Code:**
| Datei | Änderung |
|---|---|
| `prisma/import-policies.ts` | `parsePackageFiles(seedDir, mappingFile = "mapping.json")`; Requirements framework-scoped reconcilen |
| `prisma/template-store.ts:147` | `resolvePackageForTenant(prisma, tenantId, seedDir, framework)`; `loadPublishedPackage(prisma, locale, framework)`; `getAvailableVersion` ebenso |
| `scripts/sync-policy-templates.ts:23` | über **Frameworks × Sprachen** iterieren |
Die vier Aufrufer bekommen den Parameter durchgereicht: `src/server/provision.ts:139`, `src/server/actions/policy-package.ts:28`, `src/server/actions/admin.ts`, `src/app/(app)/policies/updates/page.tsx:44`. **Das Seed-Verzeichnis bleibt für beide Frameworks dasselbe** — die fünf `SEED_DIR`-Konstanten ändern sich nicht, nur der Mapping-Dateiname.
**DoD:** Bestandsmandanten laufen unverändert als TISAX; ein Mandant lässt sich mit `["ISO_27001"]`, `["TISAX"]` oder beiden provisionieren; bei Doppel-Framework koexistieren 321 + 120 Anforderungen und **keine** ist fälschlich archiviert.
## AP2 — Provisionierung und Flags *(klein, direkt nach AP1)*
`ProvisionOpts` (`src/server/provision.ts:37`) um `frameworks: Framework[]`. `provisionTenant` schreibt die `TenantFramework`-Zeilen, importiert je Framework das passende Mapping und setzt die Sichtbarkeits-Flags als `PolicyVariable`: nur TISAX → `true/false`, nur ISO → `false/true`, beides → `true/true`.
**Reihenfolge beachten:** `reconcilePackage` erhält nutzergepflegte Variablenwerte und überschreibt sie nicht — die Flags also **nach** dem Import setzen, sonst bleibt der Schema-Default stehen und ein ISO-Mandant sieht die VDA-ISA-Sicht. `tisaxLevel` bleibt auf `TenantSettings`, ist aber TISAX-scoped; bei einem reinen ISO-Mandanten keine AL-Flags setzen.
**DoD:** Frisch provisionierter ISO-Mandant öffnet `/policies` und sieht je Abschnitt `*Anforderungsbezug:* ISO/IEC 27001 …` plus die 19 ISO-only-Abschnitte; keine VDA-ISA-Anforderungen.
## AP3 — SoA-Modul *(das fehlende ISO-Kernartefakt)*
Der Modul-Key `soa` (`src/lib/modules.ts:19`) zeigt auf `/soa`, **die Route existiert nicht**; die heutige Logik liegt als Wizard-Schritt in `src/server/actions/soa.ts` und ist ein VDA-ISA-Reifegrad-Assessment (0–3), nicht die ISO-Anwendbarkeitserklärung.
```prisma
model SoaEntry {
id String @id @default(cuid())
tenantId String @map("tenant_id")
framework Framework
control String // "A.5.15"
applicable Boolean @default(true)
justification String // Begründung Einbeziehung ODER Ausschluss
source String? // Risiko-ID / gesetzliche / vertragliche Anforderung
implementationStatus String @default("geplant") // umgesetzt | teilweise | geplant
ownerId String? @map("owner_id")
policyCode String? @map("policy_code")
evidenceId String? @map("evidence_id")
@@unique([tenantId, framework, control])
@@index([tenantId])
@@map("soa_entries")
}
```
`applicable`, `justification`, `implementationStatus` und die Ausschlussbegründung sind **normative Pflichtangaben** (ISO/IEC 27001:2022, 6.1.3 d) — ohne sie ist die SoA im Zertifizierungsaudit angreifbar. Vorbefüllung aus `mapping-iso.json` (93 Controls); das Feld `condition` steuert die Default-Anwendbarkeit. Fachliche Vorlage für Aufbau und Spalten: `seed/isms-vorlagenpaket-v2/Statement-of-Applicability-ISO.md`.
**DoD:** SoA vollständig pflegbar und als PDF/XLSX exportierbar; ein Control ohne Begründung wird als unvollständig markiert.
## AP4 — Kennzahlen, Managementbewertung, Korrekturmaßnahmen
| Klausel | Modell | Inhalt |
|---|---|---|
| 9.1 | `Kpi` / `KpiValue` | Kennzahl, Datenquelle, Zielwert, Turnus, Verantwortlicher, Messwerte je Periode |
| 9.3 | `ManagementReview` | Datum, Eingaben nach 9.3.2, Ergebnisse nach 9.3.3, Beschlüsse mit Verantwortlichem und Termin |
| 10.2 | `Nonconformity` + `CorrectiveAction` | Herkunft, Sofortkorrektur, Ursachenanalyse, Maßnahme, Wirksamkeitsbewertung |
Aufsetzen auf Vorhandenes: `Task.recurrence` (RRULE), `Task.remindAt`, `Task.effectiveUntil` (Wirksamkeitsintervall, gekoppelt an `Evidence.validUntil`), `TaskParticipant` (RACI), `AuditLog`. Datenquellen für Kennzahlen liegen bereits im Tool: Aufgabenfristen und Überfälligkeit, Incident-SLA und Meldefristen (`src/lib/incident-deadlines.ts`), Reifegrade je Control, Maßnahmenstatus. Die Feldinhalte stehen fachlich in R03 der Bibliothek (`ISO-MS-MESSUNG`, `ISO-MS-MGMTREVIEW`, `ISO-MS-CAPA`).
**DoD:** Kennzahlenblatt mit Zielwerten über zwei Perioden auswertbar; Management-Review entlang der 9.3.2-Agenda protokollierbar; ein Maßnahmenfall inklusive dokumentierter Wirksamkeitsprüfung abschließbar.
## AP5 — Dokumentenlenkung *(klein, hohe Auditwirkung)*
- `PolicyDocument.reviewCycle` + `nextReviewAt` — heute führt nur `ManagedRegister` einen `reviewCycle`; A.5.1 verlangt die Überprüfung „in geplanten Abständen".
- `PolicyAcknowledgement { tenantId, policyDocumentId, version, userId, acknowledgedAt }` — Lesebestätigung, in `SPEC.md` §4.6 vorgesehen und bis heute nicht gebaut. Zugleich der einfachste Nachweis für Klausel 7.3 und Control A.6.3.
- Änderungshistorie je Dokumentversion — aus `AuditLog` (Vorher/Nachher) ableitbar oder eigene Tabelle.
**DoD:** Übersicht „Prüfung fällig"; Auswertung der Lesebestätigungen je Richtlinienversion; Dokumenthistorie über mindestens zwei Versionen sichtbar.
## Validierungs-Gate vor jedem PR
```bash
npx tsc --noEmit && npm run lint && npm run build
cd seed/isms-vorlagenpaket-v2
python3 _verify.py # TISAX-Sicht → OK
python3 _verify_iso.py # ISO-Sicht → OK (0 Befunde)
python3 _render_diff.py HEAD # TISAX-Regression → 0 Abweichungen
```
Zusätzlich beachten:
- **Migrationsflow Prisma 7** (`docs/HANDOVER-DEV.md:100`): `migrate diff --from-config-datasource … --to-schema … --script`, danach den **RLS-DO-Block manuell** an die `migration.sql` anhängen, dann `migrate deploy`.
- **`scripts/check-module-guards.ts`** läuft als `prebuild`-Gate: jede neue Datei unter `src/server/actions/` dort eintragen (Modul-Key oder `EXEMPT`), sonst schlägt der Build fehl.
- Bei paralleler Lane-Entwicklung teilen sich die Worktrees dieselbe lokale Postgres-DB: beim Erzeugen einer Migration nur die **eigenen** DDL-Blöcke übernehmen, Fremd-Drops von Hand entfernen.
## Definition of Done (gesamt)
| Prüfung | Erwartung |
|---|---|
| Bestandsmandant (TISAX) nach Deploy | Readiness und Exporte identisch zum Snapshot vor dem Umbau |
| Import ISO in Mandant mit TISAX | 120 neue Anforderungen, **0 archivierte** ISA-Anforderungen |
| Import ISO, Umsetzungstexte | 120 von 120 gefüllt |
| Dokumente bei Doppel-Framework | 39 Dokumente, **nicht** doppelt |
| Parallelbetrieb im Dokument | beide Anforderungssichten unter einem gemeinsamen Umsetzungstext |
| Gate | tsc, lint, build, beide `_verify*`, `_render_diff` grün |
`parsePackageFiles` ist reine Dateiarbeit und ohne Datenbank testbar; für den Mandanten-Import gibt es `reconcilePackage(..., { dryRun: true })` — Änderungsreport ohne Schreibzugriff, geeignet als Freigabebedingung.
## Reihenfolge und Aufwand
```
AP1 Framework-Dimension 4–6 PT ← blockiert alles
├─ AP2 Provisionierung 1–2 PT
├─ AP3 SoA-Modul 5–8 PT
├─ AP4 Managementkl. 5–8 PT
└─ AP5 Dok.-Lenkung 2–3 PT
```
AP3–AP5 sind nach AP1 parallelisierbar. **Feature-Flag:** ISO bleibt laut Entscheidung D7 hinter einem Plattform-Schalter, bis AP3 abgenommen ist.
## Nicht dein Scope
Diese Punkte gehören dem ISB bzw. der Redaktion: Nachweisregister um Zeilen für Kennzahlenblatt, Management-Review-Protokoll und Maßnahmenregister ergänzen; VA-15 trennen und ein Verfahren für Korrekturmaßnahmen ergänzen (**Nummer ab VA-21**, VA-20 ist belegt); `REVIEW_CYCLE` an den 33 Bestandsstellen auf die getrennten Zyklus-Variablen umstellen; ISB-Freigabe der 19 neuen Abschnittstexte.