dorfteich/docs/vs-nfd/30-issue-adr-auftrag.md
Claude Opus 5 fd07f716f6
All checks were successful
CI / Lint, typecheck, test (pull_request) Successful in 4m42s
CI / Build container images (pull_request) Successful in 1m11s
CI / Auth e2e pack (pull_request) Successful in 7m47s
CI / Import/export fidelity gate (pull_request) Successful in 55s
CD / Build and push images (push) Successful in 18s
CD / Deploy to Test (push) Successful in 14s
CD / Smoke tests against Test (push) Successful in 1m16s
CD / Promote to Int (push) Successful in 11s
CI / Lint, typecheck, test (push) Successful in 4m50s
CI / Build container images (push) Has been skipped
CI / Auth e2e pack (push) Successful in 7m38s
CI / Import/export fidelity gate (push) Successful in 56s
docs: VS-NfD readiness planning (ist-aufnahme, plan, ADRs 0019-0026, issue drafts)
Add docs/vs-nfd/: the analysis brief, the as-is assessment (42 findings,
all verified against the code), the prioritized action plan rev. 2 with
issue references written back to every checkbox, the two-stage issue/ADR
brief, and the full reviewed draft used to create the forge state.

Add eight proposed ADRs 0019-0026 covering the VS-NfD architecture
decisions: no security base functions (par. 52 VSA anchor), HKDF token
key separation, external authentication, page classification, read-access
audit trail (variant A), reproducible offline deployment, plugin trust
model, and backup target restriction.

Forge state created alongside this commit: 11 labels, milestones M24-M31,
issues #188-#236 (docs-only change, no code touched).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0168Ph5uBmHm8X28CSVpbpnJ
2026-07-30 01:48:05 +02:00

195 lines
8.8 KiB
Markdown
Raw 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.

# Übergabe-Auftrag: Maßnahmenplan → ADRs, Issues, Meilensteine
> Ablage: `docs/vs-nfd/30-issue-adr-auftrag.md`
> Aufruf in Claude Code: _„Arbeite `docs/vs-nfd/30-issue-adr-auftrag.md` ab."_
---
## Kontext
`docs/vs-nfd/20-massnahmenplan.md` enthält den priorisierten Maßnahmenplan für
die VS-NfD-Ertüchtigung, abgeleitet aus `docs/vs-nfd/10-ist-aufnahme.md`.
Ziel des Vorhabens: Dorfteich soll in einer nach VSA freigegebenen Umgebung
einer Bundesbehörde (VS-NfD) betrieben werden können, **ohne eigene
BSI-Zulassung**.
Dieser Auftrag überführt den Plan in die Projektkonventionen: ADRs für
Architekturentscheidungen, Issues für Arbeitspakete, Meilensteine als Bündel.
## Entscheidungen für diesen Auftrag
| Punkt | Vorgabe |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| Sprache ADRs + Issues | **Englisch** (Repo-Konvention). Deutsche Rechtsbegriffe bleiben unübersetzt: VS-NfD, Verschlusssache, VSA, Geheimschutz. |
| Codeänderungen | **Keine.** Diese Session erzeugt nur Doku, Issues und Meilensteine. |
| Anlegen im Forge | **Erst nach Freigabe.** Siehe Zweistufigkeit unten. |
## Zweistufiges Vorgehen (verbindlich)
**Stufe 1 — Entwurf zur Review.** Erzeuge `docs/vs-nfd/31-issue-entwurf.md`
mit allen geplanten Meilensteinen, Issues und ADRs im Volltext. Nichts im
Forge anlegen. Am Ende der Stufe: kurze Zusammenfassung, wie viele
Meilensteine/Issues/ADRs entstehen würden, und Rückfrage an Stefan.
**Stufe 2 — nach ausdrücklicher Freigabe.** ADR-Dateien schreiben, Labels,
Meilensteine und Issues anlegen, Issue-Nummern in den Maßnahmenplan
zurückschreiben.
Grund: ~30 Issues über eine API anzulegen ist mühsam zu korrigieren.
## Forge ermitteln, nicht raten
Bestimme aus `git remote -v` und den verfügbaren CLIs (`gh`, `glab`, `tea`,
`forgejo-cli`), gegen welche Plattform gearbeitet wird. Prüfe, ob eine
Authentifizierung besteht (`gh auth status` o. ä.). Falls unklar oder keine
CLI verfügbar: **Stufe 1 vollständig ausführen und dann fragen** — nicht mit
`curl` gegen eine geratene API-URL improvisieren.
---
## Meilensteine
Dependency-sortiert, nicht phasen-sortiert. Titel und Reihenfolge übernehmen:
| # | Meilenstein | Inhalt aus Plan | Aufwand |
| --- | ----------------------------------- | ------------------------------------------------------------------------------------------- | -------- |
| M1 | `VS-NfD: security quick wins` | Phase 2 ohne die drei nachgezogenen Punkte | 1518 AT |
| M2 | `VS-NfD: hardening & supply chain` | P2 nachgezogen: Attachment-Hashes, Plugin-Abschaltung, Ereigniskatalog, SBOM, Image-Digests | 710 AT |
| M3 | `VS-NfD: classification metadata` | P1-2 vollständig | 1418 AT |
| M4 | `VS-NfD: external authentication` | P1-1 vollständig | 1012 AT |
| M5 | `VS-NfD: offline/airgap deployment` | P1-3 vollständig | 810 AT |
| M6 | `VS-NfD: read-access audit trail` | Phase 3, Variante A | 810 AT |
| M7 | `VS-NfD: compliance documentation` | Phase 5 | 1520 AT |
| M8 | `VS-NfD: backlog` | Phase 4 (Plugin-Hash-Pinning) | 810 AT |
Abhängigkeiten in die Meilenstein-Beschreibung schreiben:
M6 setzt M3 voraus. M2 (Image-Digests) sollte vor M5 liegen. M7 läuft
parallel und beginnt früh — die Abgrenzungserklärung ist nicht von
Implementierung abhängig.
## Labels
Anlegen, falls nicht vorhanden:
`vs-nfd` · `vs-nfd:blocker` · `effort:S` · `effort:M` · `effort:L` ·
`area:auth` · `area:export` · `area:storage` · `area:supply-chain` ·
`area:docs`
---
## Issue-Vorlage
Ein Issue pro Checkbox-Zeile des Maßnahmenplans. Unterpunkte mit eigenem
Aufwand (z. B. die Ausgabekanäle in P1-2) werden **eigene Issues**, nicht
Checklisten in einem Sammel-Issue — sie sind unabhängig abschließbar.
```markdown
**Title:** [VS-NfD] <imperative, concise>
**Plan reference:** `docs/vs-nfd/20-massnahmenplan.md`<P1-1 / P2-3 / >
**ADR:** <ADR-00XX or "n/a">
**Effort:** <S | M | L> (<n> AT)
**Depends on:** <#issue or "—">
## Context
Why this matters for VS-NfD operation. One or two sentences.
Where relevant, reference the §52 VSA principle: the application must not
implement security base functions itself.
## Current state
Findings from `10-ist-aufnahme.md`, with file paths. Do not invent paths —
copy only what the Ist-Aufnahme actually cites, and drop line numbers that
were not verified there.
## Acceptance criteria
- [ ] verifiable, testable statements
- [ ] including the required test
- [ ] including the documentation touched (operations manual / hardening guide)
## Out of scope
What explicitly does not belong here.
```
Regeln:
- **Keine erfundenen Fundorte.** Nur Pfade aus der Ist-Aufnahme übernehmen.
Wo diese keine verifizierte Zeilennummer nennt, ohne Zeilennummer zitieren.
- Jedes Issue nennt die Dokumentation, die es mitzieht. Nicht dokumentierte
Funktionen sind für dieses Vorhaben wertlos.
- Aufwandsangaben aus dem Plan übernehmen, nicht neu schätzen.
---
## ADRs
Nächste freie Nummer aus `docs/adr/` (o. ä.) ermitteln — vorhanden sind u. a.
0007 (UserIdentity/provider) und 0016 (self-hosted fonts). Bestehendes
Dateinamens- und Statusschema übernehmen.
Anzulegen, in dieser Reihenfolge:
**A. `No security base functions in the application (§52 VSA)`** — Ankerdokument
Entscheidung: Die Anwendung erbringt keine Sicherheitsgrundfunktion i.S.v.
§52 VSA. Verschlüsselung, Datenträgerschutz, Netzabschluss und
Authentisierung liegen bei der Plattform des Betreibers. Konsequenz: kein
eigenes MFA, keine Inhalts- oder Backup-Verschlüsselung, keine neuen
Krypto-Primitive. Begründung: hält die Anwendung außerhalb der
Zulassungspflicht nach §51 VSA.
_Dieses ADR ist zugleich der Rohentwurf der Abgrenzungserklärung aus M7 —
entsprechend sorgfältig schreiben._
**B. `Token crypto: HKDF key separation and vetted JWT library`**
Zweckgebundene Subkeys statt gemeinsamem `COLLAB_TOKEN_SECRET`; Ersatz des
Eigenbau-HMAC-JWT durch `jose`. Dual-Verify-Fenster für langlebige
Unsubscribe-Tokens dokumentieren.
**C. `External authentication via OIDC; local passwords optional`**
Erweitert ADR 0007. Enthält die Entscheidung für einen harten Schalter
`auth.local.enabled = false` und die Alternativpfade Proxy-Header / mTLS.
**D. `Classification as first-class page metadata`**
Warum ein eigenes Enum-Feld an `Page` und **nicht** Labels: Labels sind
pond-scoped, nutzerbearbeitbar und vererben nicht. Enthält außerdem die
zentrale Betriebsentscheidung: **Trennung der Einstufungsniveaus erfolgt
außerhalb der Anwendung** (eine Instanz je Niveau), die Kennzeichnung
innerhalb. Die anwendungsseitige ACL ist Ordnung, nicht Schutzmechanismus.
**E. `Read-access audit trail limited to classified content`**
Variante A. Begründung: Ereignisvolumen bei Yjs-Sync, saubere Zweckbindung,
Entschärfung der Mitbestimmungsfrage beim Betreiber.
**F. `Reproducible offline deployment`**
Image-Digest-Pinning, interne Registry, Offline-Update-Pfad.
**G. `Plugin trust model`**
Kurzfristig harte Abschaltbarkeit; Hash-Pinning statt Code-Signierung, weil
ohne juristische Person keine Signaturidentität verfügbar ist.
**H. `Backup target restriction`**
Allowlist für Backup-Ziele; keine anwendungsseitige Verschlüsselung
(folgt aus A).
Jedes ADR verlinkt am Ende die umsetzenden Issues; jedes Issue verlinkt sein ADR.
---
## Rückschreiben in den Plan
Nach Stufe 2: In `20-massnahmenplan.md` hinter jeder Checkbox die Issue-Nummer
ergänzen (`· #142`) und je Phase den Meilenstein nennen. Der Plan bleibt der
Index, der Forge hält den Zustand.
## Verifikation
- [ ] Jede Checkbox-Zeile des Plans hat genau ein Issue (oder ist als
bewusst zusammengefasst begründet)
- [ ] Jedes Issue hat Meilenstein, Effort-Label, Area-Label und
Akzeptanzkriterien
- [ ] Jedes Issue mit Architekturbezug verweist auf ein ADR
- [ ] Alle zitierten Pfade existieren (`ls`/`grep` stichprobenartig prüfen)
- [ ] Summe der AT je Meilenstein stimmt mit der Tabelle oben überein
- [ ] `git status`: außer `docs/` nichts geändert