Files
tessera-ctl/.planning/quick/260921-9ie-windows-35-biome-json-fuer-biome-2-5-0-r/260921-9ie-PLAN.md
T
schalli 551d25075f docs(quick-260921-9ie): Biome lauffaehig, Lint-Tor scharf (WINDOWS #35)
Plan, Zusammenfassung und Verifikation zum Quick-Vorgang 260921-9ie,
Registereintrag #35 geschlossen, STATE.md nachgezogen.

Nachgewiesen: pnpm lint fuehrt 5 von 5 Workspace-Aufgaben aus (vorher
"No tasks were executed") und endet auf dem Bestand mit Exit 0; eine
Wegwerfdatei mit debugger laesst denselben Aufruf mit Exit 1 und
noDebugger-Befund scheitern. Repo-weit 0 parse-Fehler, 0 Fehler.
Die Regelgruppe security bleibt unangetastet auf error.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TPPB4ApQxzSU1rwV2Ffj9J
2026-09-21 07:13:20 +02:00

267 lines
24 KiB
Markdown

---
phase: quick-260921-9ie
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
- biome.json
- apps/api/package.json
- apps/web/package.json
- apps/desktop/package.json
- packages/shared/package.json
- packages/module-sdk/package.json
- turbo.json
- docs/anleitung-entwicklung.md
- .planning/WINDOWS.md
autonomous: true
requirements: [WINDOWS-35]
estimate:
tokens: 35000
raw_tokens: 35000
tasks: 3
confidence: low
must_haves:
truths:
- "Biome bricht nicht mehr mit einem Konfigurationsfehler ab: ein Aufruf von biome lint laeuft durch und liefert einen echten Befund-Bericht statt der Abbruchmeldung."
- "NestJS-Parameter-Dekoratoren werden geparst: apps/api hat null parse-Fehler (vorher 238 in 19 Dateien)."
- "pnpm lint fuehrt echte Pruefungen aus: turbo meldet 5 ausgefuehrte Aufgaben statt 'No tasks were executed'."
- "pnpm lint endet auf dem unveraenderten Bestand mit Exit 0."
- "pnpm lint endet mit Exit 1, sobald ein echter Regelverstoss im Quellcode steht — das Gate hat Biss."
- "Die Regelgruppe security bleibt auf error; keine Sicherheitsregel wurde stummgeschaltet."
- "Kein Quellcode wurde umformatiert: der Diff enthaelt ausschliesslich Konfiguration, Paket-Skripte und Dokumentation."
artifacts:
- biome.json
- apps/api/package.json
- apps/web/package.json
- apps/desktop/package.json
- packages/shared/package.json
- packages/module-sdk/package.json
- turbo.json
- docs/anleitung-entwicklung.md
key_links:
- "package.json (root) Skript lint -> turbo.json Aufgabe lint -> lint-Skript je Workspace -> biome lint -> biome.json im Wurzelverzeichnis"
- ".gitea/workflows/ci.yml Schritt 'Lint' ruft pnpm lint — ab jetzt mit echtem Pruefumfang"
- "turbo.json globalDependencies enthaelt biome.json, damit eine Konfigurationsaenderung den Lint-Cache verwirft"
---
<objective>
Biome ist im Bestand nicht lauffaehig und der CI-Schritt „Lint" ist ein Leerlauf, der gruen meldet. Dieser Plan repariert beides und weist das Ergebnis mit echten Messungen nach.
Purpose: Der Eintrag #35 im Maengelregister beschreibt ein Pruef-Tor, das nichts prueft. Solange `biome.json` einen in Biome 2.5.0 unbekannten Schluessel traegt und keine einzige App ein `lint`-Skript hat, laeuft jeder Lauf entweder in einen Konfigurationsfehler oder an allem vorbei. Ein Tor ohne Biss ist schaedlicher als gar keines, weil es Sicherheit vortaeuscht.
Output: Eine fuer Biome 2.5.0 gueltige `biome.json`, ein `lint`-Skript in allen fuenf Workspaces, ein Cache-Bezug in `turbo.json` und eine nachgezogene Entwickler-Anleitung. `pnpm lint` ist danach gruen auf dem Bestand und wird rot, sobald ein echter Fehler dazukommt.
## Gemessener Ausgangsstand (2026-09-21, vor dem Umbau)
Alles Folgende wurde in der Planung am laufenden Projekt gemessen, nicht aus dem Registereintrag uebernommen:
- `biome.json` traegt `organizeImports` auf oberster Ebene — Biome 2.5.0 kennt den Schluessel dort nicht und bricht jeden Aufruf ab.
- `biome migrate --write` auf einer Kopie liefert die verbindliche Zielform: `assist.actions.source.organizeImports` mit Wert `"on"`, und `linter.rules.recommended: true` wird zu `linter.rules.preset: "recommended"`. Der zweite Teil steht **nicht** im Registereintrag, ist aber Teil der Migration.
- Der Schalter `javascript.parser.unsafeParameterDecoratorsEnabled` senkt die parse-Fehler in `apps/api` von **238 in 19 Dateien** auf **30 in 1 Datei**. Der Registereintrag nennt „17 allein in user.controller.ts" — das ist in zwei Punkten falsch: der Pfad lautet `apps/api/src/user/user.controller.ts` (Einzahl `user`, nicht `users`), und die tatsaechliche Wirkung ist um ein Vielfaches groesser.
- Die verbleibenden 30 parse-Fehler liegen in `apps/api/src/tenders/__fixtures__/cosinex-search.html`, dazu 2 in `apps/web/src/app/globals.css` (Tailwind-4-At-Regeln, die Biomes CSS-Parser nicht kennt).
- Anfuehrungszeichen: 854 Importzeilen in `apps/api`, 642 in `apps/web` benutzen einfache Anfuehrungszeichen, **null** benutzen doppelte. `quoteStyle: "single"` ist damit belegt, nicht geraten.
- `turbo lint` meldet heute „No tasks were executed" bei Exit 0 — der Leerlauf ist reproduziert.
## Entscheidung: Zweig (b), mit Begruendung aus der Messung
Die Vorgabe liess zwei Zweige zu. Gemessen wurde:
| Aufruf | Exit | Fehler | Warnungen |
|---|---|---|---|
| `biome check .` | 1 | 760 | 2594 |
| `biome lint .` | 1 | 275 | 2594 |
| `biome format .` | 1 | 319 | — |
Zweig (a) scheidet damit aus: die Befunde sind **nicht** blosse Warnungen, der Lauf faellt auch als reines `lint` durch. Also Zweig (b), in drei praezisen Schritten statt eines pauschalen Rundumschlags:
1. **Das Skript ruft `biome lint`, nicht `biome check`.** Das nimmt die 319 Formatierungsbefunde und die Importsortierung aus dem Tor heraus — genau die Befunde, die einen projektweiten Umbau erzwingen wuerden. Die Formatierungs-Einstellungen bleiben in der Datei gueltig und wirken weiter fuer `biome format --write` und den Editor.
2. **Zwei Dateien werden von Biome ausgenommen.** `apps/api/src/tenders/__fixtures__/cosinex-search.html` ist eine abgespeicherte Fremdseite als Testvorlage, kein eigener Quellcode; das Verzeichnis `__fixtures__` enthaelt ausschliesslich Datendateien (html, zip, xml) und keine einzige TypeScript-Datei. `apps/web/src/app/globals.css` scheitert an Tailwind-4-Syntax, die Biome nicht kennt.
3. **Gezielte Herabstufungen statt Quellcode-Umbau.** Von den 275 Fehlern sind 32 parse-Fehler (durch Schritt 2 erledigt) und 243 echte Regelverstoesse — 217 davon in `apps/web`, 25 in `apps/api`, 1 in `apps/desktop`. Verteilung: Barrierefreiheit 184, `suspicious` 33, `correctness/useExhaustiveDependencies` 20, `security/noScriptUrl` 6.
**Sicherheitsrelevanter Befund, der die Herabstufung begrenzt:** alle 6 Treffer der Regel `lint/security/noScriptUrl` liegen ausnahmslos in der ausgenommenen HTML-Testvorlage, in keiner einzigen echten Quelldatei. Die Gruppe `security` wird deshalb **nicht** herabgestuft und bleibt auf `error`. Es wird keine Sicherheitsregel stummgeschaltet — die 6 Treffer verschwinden, weil die Fremdseite nicht mehr geprueft wird, nicht weil die Regel entschaerft wurde.
Die uebrigen Regeln werden auf `warn` gesetzt, nicht abgeschaltet: sie bleiben im Bericht sichtbar und bilden den Rueckstand, den der Registereintrag ohnehin als eigenen Durchlauf vorsieht. Nach dem Umbau: **0 Fehler, 2826 Warnungen, Exit 0** — und Exit 1, sobald ein echter Fehler dazukommt (in der Planung mit einer Wegwerfdatei gegengeprueft).
</objective>
<execution_context>
@~/.claude/gsd-core/workflows/execute-plan.md
@~/.claude/gsd-core/templates/summary.md
</execution_context>
<context>
@.planning/STATE.md
@CLAUDE.md
@biome.json
@turbo.json
@package.json
@apps/api/package.json
@apps/web/package.json
@.gitea/workflows/ci.yml
</context>
<tasks>
<task type="tracer">
<name>Task 1: biome.json reparieren und die Kette bis pnpm lint an apps/api nachweisen</name>
<files>biome.json, apps/api/package.json</files>
<read_first>biome.json, apps/api/package.json, turbo.json, package.json</read_first>
<action>
Schreibe `biome.json` im Wurzelverzeichnis neu. Der Schluessel `$schema` und der komplette `formatter`-Block (enabled true, indentStyle space, indentWidth 2, lineWidth 100) bleiben unveraendert stehen. Entferne den Schluessel `organizeImports` von der obersten Ebene und setze stattdessen `assist.actions.source.organizeImports` auf den Wert `"on"` — das ist wortgleich die Ausgabe von `biome migrate --write`, nicht geraten. Ersetze im selben Zug `linter.rules.recommended: true` durch `linter.rules.preset: "recommended"`; auch das gehoert zur Migration und wird sonst uebersehen. `linter.enabled` bleibt true.
Ergaenze einen `javascript`-Block mit zwei Unterschluesseln: `parser.unsafeParameterDecoratorsEnabled` auf true, damit NestJS-Parameter-Dekoratoren ueberhaupt geparst werden, und `formatter.quoteStyle` auf `"single"`, belegt durch 1496 einfach-gequotete Importzeilen gegen null doppelt-gequotete.
Ergaenze einen `vcs`-Block mit enabled true, clientKind `"git"` und useIgnoreFile true, damit `.gitignore` gilt und Biome nicht in node_modules, .next, dist oder target laeuft. Wichtig: dieser Block funktioniert nur, solange die Konfigurationsdatei im selben Verzeichnis wie `.gitignore` liegt, also im Wurzelverzeichnis — bei einem Aufruf mit abweichendem Konfigurationspfad bricht Biome mit einem Datei-nicht-gefunden-Fehler ab.
Ergaenze `files.includes` mit genau drei Eintraegen in dieser Reihenfolge: dem Alles-Muster, einem verneinenden Muster fuer beliebig tief liegende `__fixtures__`-Verzeichnisse, und einem verneinenden Muster fuer den Pfad `apps/web/src/app/globals.css`. Verneinende Muster tragen in Biome 2.x ein vorangestelltes Ausrufezeichen.
Ergaenze unter `linter.rules` die Herabstufungen: die Gruppe `a11y` bekommt direkt den Wert `"warn"` (Gruppen nehmen laut mitgeliefertem Schema eine Schweregrad-Zeichenkette entgegen), unter `correctness` bekommt `useExhaustiveDependencies` den Wert `"warn"`, und unter `suspicious` bekommen `noArrayIndexKey`, `noAssignInExpressions`, `noControlCharactersInRegex`, `noDoubleEquals` und `useIterableCallbackReturn` je den Wert `"warn"`. Die Gruppe `security` wird nicht aufgefuehrt und behaelt damit den voreingestellten Schweregrad error — das ist Absicht und darf nicht „der Vollstaendigkeit halber" mit herabgestuft werden.
Trage anschliessend in `apps/api/package.json` unter `scripts` einen Eintrag `lint` mit dem Wert `biome lint .` ein. Aendere sonst nichts an der Datei — insbesondere keine Abhaengigkeiten und keine Versionen, Biome 2.5.0 liegt bereits im Lockfile.
Fass in diesem Schritt keine einzige Quelldatei an. Wenn nach dem Umbau `git status` irgendetwas ausserhalb der beiden genannten Dateien zeigt, ist etwas schiefgelaufen.
</action>
<verify>
<automated>
cd /home/vicolab/projects/tessera-ctl
# 1. Konfiguration ist fuer Biome 2.5.0 gueltig und der alte Schluessel ist weg
node -e "const c=require('./biome.json'); if(c.organizeImports!==undefined) throw new Error('Schluessel liegt noch auf oberster Ebene'); if(c.assist.actions.source.organizeImports!=='on') throw new Error('assist fehlt'); if(c.linter.rules.preset!=='recommended') throw new Error('preset fehlt'); if(c.javascript.parser.unsafeParameterDecoratorsEnabled!==true) throw new Error('Parser-Schalter fehlt'); if(c.javascript.formatter.quoteStyle!=='single') throw new Error('quoteStyle fehlt'); if(c.linter.rules.security!==undefined) throw new Error('security wurde angefasst'); console.log('config OK');"
# erwartet: "config OK", Exit 0
# 2. biome migrate meldet keinen Migrationsbedarf mehr
pnpm exec biome migrate 2>&1 | grep -q "configuration needs migration" && { echo "FEHLER: noch migrationsbeduerftig"; exit 1; } || echo "migrate sauber"
# erwartet: "migrate sauber"
# 3. Null parse-Fehler repo-weit (vorher 238 allein in apps/api)
pnpm exec biome lint . --reporter=json --max-diagnostics=20000 > /tmp/biome_probe.json 2>/dev/null
node -e "const d=require('/tmp/biome_probe.json').diagnostics||[]; const p=d.filter(x=>x.category==='parse'); const e=d.filter(x=>x.severity==='error'); console.log('parse:',p.length,'errors:',e.length); if(p.length||e.length) process.exit(1);"
# erwartet: "parse: 0 errors: 0", Exit 0
# 4. Die Kette traegt: apps/api laeuft ueber turbo und ist gruen
pnpm exec turbo lint --force --filter=@tessera/api 2>&1 | tail -5
# erwartet: "1 successful, 1 total", Exit 0
# 5. Kein Quellcode angefasst (git-Status zuerst festhalten, damit ein Fehler von git nicht verschluckt wird)
git status --porcelain > /tmp/gsd_status.txt || { echo "FEHLER: git status fehlgeschlagen"; exit 1; }
FREMD=$(grep -vE "^ M \.planning/STATE\.md$" /tmp/gsd_status.txt | grep -vE "biome\.json|apps/api/package\.json|^\?\? \.planning/quick/" || true)
test -z "$FREMD" || { echo "FEHLER: fremde Aenderungen:"; echo "$FREMD"; exit 1; }
echo "Diff sauber"
</automated>
</verify>
<done>`biome.json` ist fuer Biome 2.5.0 gueltig, `biome migrate` meldet keinen Bedarf mehr, repo-weit null parse-Fehler und null Fehler, `turbo lint --filter=@tessera/api` fuehrt eine echte Aufgabe aus und endet mit Exit 0, und der Diff enthaelt ausser den beiden Zieldateien nichts.</done>
</task>
<task type="auto">
<name>Task 2: lint-Skript in den restlichen vier Workspaces und Cache-Bezug in turbo.json</name>
<files>apps/web/package.json, apps/desktop/package.json, packages/shared/package.json, packages/module-sdk/package.json, turbo.json</files>
<read_first>apps/web/package.json, apps/desktop/package.json, packages/shared/package.json, packages/module-sdk/package.json, turbo.json</read_first>
<action>
Trage in `apps/web/package.json`, `apps/desktop/package.json`, `packages/shared/package.json` und `packages/module-sdk/package.json` jeweils unter `scripts` einen Eintrag `lint` mit dem Wert `biome lint .` ein — dieselbe Zeile wie in Task 1 bei `apps/api`. Alle vier wurden in der Planung einzeln gemessen und laufen mit der reparierten Konfiguration gruen durch (Exit 0). Sonst nichts an den Dateien aendern.
Ergaenze in `turbo.json` auf oberster Ebene, neben dem vorhandenen `tasks`-Objekt, den Schluessel `globalDependencies` mit `biome.json` als einzigem Eintrag. Ohne diesen Bezug liegt die Konfigurationsdatei ausserhalb jedes Workspace-Verzeichnisses, und turbo wuerde nach einer Aenderung an den Regeln weiterhin zwischengespeicherte Lint-Ergebnisse ausliefern — also erneut ein Tor, das gruen meldet, ohne geprueft zu haben. Genau diese Klasse von Fehler ist der Anlass des Vorgangs. Die bestehende `lint`-Aufgabe unter `tasks` bleibt unveraendert.
Weise danach zwei Dinge nach, die zusammen den eigentlichen Mangel schliessen: dass `pnpm lint` fuenf echte Aufgaben ausfuehrt statt keiner, und dass der Lauf rot wird, sobald ein echter Regelverstoss im Baum liegt. Lege fuer die Gegenprobe eine Wegwerfdatei unter `apps/api/src` an, die eine `debugger`-Anweisung und einen losen Gleichheitsvergleich enthaelt, lass den Lauf darauf scheitern und **entferne die Datei danach wieder**. Der Lauf fuer die Gegenprobe braucht `--force`, sonst kann der turbo-Cache das Ergebnis verdecken.
</action>
<verify>
<automated>
cd /home/vicolab/projects/tessera-ctl
# 1. Alle fuenf Workspaces haben ein lint-Skript
node -e "const fs=require('fs'); const ps=['apps/api','apps/web','apps/desktop','packages/shared','packages/module-sdk']; const miss=ps.filter(p=>!(JSON.parse(fs.readFileSync(p+'/package.json','utf8')).scripts||{}).lint); if(miss.length) throw new Error('ohne lint-Skript: '+miss); console.log('5/5 Workspaces haben lint');"
# erwartet: "5/5 Workspaces haben lint"
# 2. turbo kennt biome.json als globale Abhaengigkeit
node -e "const t=require('./turbo.json'); if(!(t.globalDependencies||[]).includes('biome.json')) throw new Error('globalDependencies fehlt'); console.log('globalDependencies OK');"
# erwartet: "globalDependencies OK"
# 3. pnpm lint fuehrt echte Aufgaben aus und ist gruen (vorher: "No tasks were executed")
pnpm exec turbo lint --force 2>&1 | tail -6
# erwartet: "5 successful, 5 total", Exit 0, KEIN "No tasks were executed"
# 4. GEGENPROBE — das Tor muss beissen
printf 'export function probe(x: number) {\n debugger;\n return x == null;\n}\n' > apps/api/src/__gate_probe__.ts
pnpm exec turbo lint --force --filter=@tessera/api > /tmp/bite.txt 2>&1; BITE=$?
rm -f apps/api/src/__gate_probe__.ts
echo "Gegenprobe Exit=$BITE (erwartet 1)"; grep -c "noDebugger" /tmp/bite.txt
test "$BITE" -eq 1 || { echo "FEHLER: Tor beisst nicht"; exit 1; }
# 5. Wegwerfdatei ist wieder weg und nach dem gruenen Lauf ist alles sauber
test ! -f apps/api/src/__gate_probe__.ts && echo "Probe entfernt"
pnpm exec turbo lint --force 2>&1 | tail -3
# erwartet: erneut "5 successful, 5 total", Exit 0
</automated>
</verify>
<done>Alle fuenf Workspaces tragen ein `lint`-Skript, `turbo.json` bezieht `biome.json` als globale Abhaengigkeit ein, `pnpm lint` meldet 5 von 5 ausgefuehrten Aufgaben mit Exit 0, und die Gegenprobe mit einem absichtlichen Verstoss liefert Exit 1 samt `noDebugger`-Befund. Die Wegwerfdatei ist entfernt, der abschliessende Lauf wieder gruen.</done>
</task>
<task type="auto">
<name>Task 3: Entwickler-Anleitung nachziehen und Registereintrag #35 schliessen</name>
<files>docs/anleitung-entwicklung.md, .planning/WINDOWS.md</files>
<read_first>docs/anleitung-entwicklung.md</read_first>
<action>
In `docs/anleitung-entwicklung.md` beschreibt der Absatz ab Zeile 61 Biome als aktives Werkzeug und nennt dabei die Importsortierung. Die Aussage stimmt weiterhin, ist aber unvollstaendig, weil bis jetzt gar nichts geprueft wurde. Ergaenze den Absatz um drei Punkte in ganzen Saetzen und in derselben Tonlage wie der umgebende Text: dass `pnpm lint` seit diesem Vorgang je Workspace `biome lint .` ausfuehrt und der CI-Schritt damit echt prueft; dass das Tor auf Fehler blockiert, waehrend Stilhinweise als Warnungen erscheinen, ohne den Lauf zu stoppen; und dass derzeit rund 2800 solcher Warnungen offen sind — ueberwiegend aus der Regelfamilie um den Typ `any` sowie Barrierefreiheits-Hinweise in `apps/web` —, die bewusst als eigener Durchlauf stehen bleiben und nicht Teil dieses Vorgangs waren.
Erwaehne dabei ausdruecklich, dass `pnpm lint` nicht formatiert und nicht auf Formatierung besteht: fuer Formatierung gibt es `biome format --write`, das getrennt und absichtlich von Hand angestossen wird. Dieser Satz verhindert, dass jemand spaeter das Skript auf `biome check` umstellt und damit ungewollt einen projektweiten Umbau ausloest.
Schliesse danach den Registereintrag ueber das Werkzeug, nicht durch Handarbeit an der Tabelle — der Befehl zieht die Zaehler im Kopf der Datei mit. Nutze dafuer den `windows fixed`-Unterbefehl von gsd-tools mit der Kennung 35.
</action>
<verify>
<automated>
cd /home/vicolab/projects/tessera-ctl
# 1. Anleitung nennt den neuen Zustand
grep -qE "pnpm lint" docs/anleitung-entwicklung.md && grep -qiE "warnung" docs/anleitung-entwicklung.md && echo "Anleitung ergaenzt"
# erwartet: "Anleitung ergaenzt"
# 2. Registereintrag 35 steht auf fixed und traegt ein Loesedatum
node -e "const fs=require('fs'); const row=fs.readFileSync('.planning/WINDOWS.md','utf8').split('\n').find(l=>l.startsWith('| 35 |')); const c=row.split('|').map(s=>s.trim()); if(c[7]!=='fixed') throw new Error('Status ist: '+c[7]); if(!c[10]) throw new Error('resolved_at fehlt'); console.log('#35 fixed am',c[10]);"
# erwartet: "#35 fixed am <Zeitstempel>", Exit 0
# 3. Abschliessender Gesamtnachweis — das Tor laeuft, prueft und ist gruen
pnpm exec turbo lint --force 2>&1 | tail -4
# erwartet: "5 successful, 5 total", Exit 0
</automated>
</verify>
<done>Die Entwickler-Anleitung beschreibt den tatsaechlichen Zustand samt offenem Warnungs-Rueckstand und der Trennung von Pruefen und Formatieren; Eintrag #35 im Maengelregister steht auf `fixed` mit Loesedatum; der abschliessende Gesamtlauf ist gruen.</done>
</task>
</tasks>
<threat_model>
## Trust Boundaries
| Boundary | Description |
|----------|-------------|
| Entwickler-Arbeitsplatz → CI-Runner | `biome.json` und die `lint`-Skripte bestimmen, was der CI-Schritt „Lint" in `.gitea/workflows/ci.yml` tatsaechlich ausfuehrt. Beide wandern per Commit in die Pipeline. |
| Quellcode → Lint-Tor | Das Tor entscheidet, welche Befunde einen Lauf blockieren und welche nur berichtet werden. Eine Herabstufung hier wirkt auf jeden spaeteren Beitrag. |
## STRIDE Threat Register
| Threat ID | Category | Component | Severity | Disposition | Mitigation Plan |
|-----------|----------|-----------|----------|-------------|-----------------|
| T-35-01 | Tampering | `biome.json` → `linter.rules` | high | mitigate | Eine pauschale Herabstufung koennte echte Sicherheitsregeln stummschalten. Die Gruppe `security` wird in Task 1 ausdruecklich **nicht** aufgefuehrt und behaelt `error`. Belegt: die 6 gemessenen `lint/security/noScriptUrl`-Treffer liegen ausnahmslos in der ausgenommenen HTML-Testvorlage, in keiner echten Quelldatei. Task 1 Verify prueft maschinell, dass `linter.rules.security` nicht gesetzt ist. |
| T-35-02 | Tampering | `biome.json` → `files.includes` | medium | mitigate | Das verneinende Muster fuer `__fixtures__` koennte kuenftig echten Quellcode der Pruefung entziehen. Gemessen: das einzige solche Verzeichnis enthaelt ausschliesslich Datendateien (html, zip, xml) und keine einzige TypeScript-Datei. Der Ausschluss bleibt auf dieses Muster plus eine namentlich genannte CSS-Datei begrenzt; kein Verzeichnis unter `src` wird pauschal ausgenommen. |
| T-35-03 | Tampering | falsch-gruenes Tor (`lint`-Skripte, `turbo.json`) | high | mitigate | Der eigentliche Mangel aus #35 ist ein Tor, das gruen meldet, ohne zu pruefen. Ein falsch geschriebenes Skript oder ein stale Cache wuerde ihn wiederholen. Zwei Gegenmassnahmen: `globalDependencies` verwirft den Cache bei Regelaenderungen, und Task 2 Verify baut einen absichtlichen Verstoss ein und verlangt Exit 1 samt `noDebugger`-Befund. |
| T-35-04 | Denial of Service | `.gitea/workflows/ci.yml` Schritt „Lint" | medium | accept | Der Schritt kann ab jetzt rot werden und die Pipeline anhalten. Das ist der Zweck des Vorgangs, nicht ein Nebenschaden. Angenommen, weil der Ausgangszustand — ein Tor ohne Biss — das groessere Risiko traegt; das Tor ist auf dem aktuellen Bestand nachweislich gruen, blockiert also niemanden ohne Anlass. |
| T-35-SC | Tampering | Paketinstallationen (npm/pnpm) | — | n/a | Dieser Plan installiert kein Paket und hebt keine Version an; Biome 2.5.0 liegt bereits im Lockfile und in `node_modules`. Es gibt keinen Paketmanager-Installationsschritt, das Package-Legitimacy-Gate greift hier nicht. Ausdruecklich festgehalten statt stillschweigend ausgelassen. |
</threat_model>
<verification>
Gesamtnachweis nach allen drei Tasks, vom Wurzelverzeichnis aus:
1. `pnpm exec biome migrate` meldet keinen Migrationsbedarf → Konfiguration ist fuer 2.5.0 gueltig.
2. `pnpm exec biome lint . --reporter=json --max-diagnostics=20000` → null Eintraege mit `category` `parse` und null mit `severity` `error`.
3. `pnpm exec turbo lint --force` → „5 successful, 5 total", Exit 0, und die Zeile „No tasks were executed" taucht nicht mehr auf.
4. Gegenprobe: Wegwerfdatei mit `debugger` unter `apps/api/src` → `pnpm exec turbo lint --force --filter=@tessera/api` endet mit Exit 1; Datei danach entfernt, Lauf wieder gruen.
5. `linter.rules.security` ist in `biome.json` nicht gesetzt → Sicherheitsregeln blieben auf `error`.
6. `git diff --stat` zeigt ausschliesslich die neun in `files_modified` gelisteten Dateien — keine Quelldatei wurde umformatiert.
7. Eintrag 35 in `.planning/WINDOWS.md` steht auf `fixed` mit gefuelltem `resolved_at`.
</verification>
<success_criteria>
- `pnpm lint` fuehrt in allen fuenf Workspaces eine echte Biome-Pruefung aus und endet auf dem unveraenderten Bestand mit Exit 0.
- Ein absichtlich eingebauter Regelverstoss laesst denselben Aufruf mit Exit 1 scheitern.
- Biome bricht nirgends mehr mit einem Konfigurationsfehler ab; repo-weit null parse-Fehler (vorher 238 allein in `apps/api`).
- Die Regelgruppe `security` ist unveraendert auf `error`; keine Sicherheitsregel wurde entschaerft.
- Kein Quellcode wurde umformatiert und keine Paketversion angehoben.
- Der offene Warnungs-Rueckstand (rund 2800, ueberwiegend `any`-Familie und Barrierefreiheit) ist in der Entwickler-Anleitung als bewusst offener Punkt festgehalten.
- Eintrag #35 im Maengelregister ist geschlossen.
</success_criteria>
<output>
Create `.planning/quick/260921-9ie-windows-35-biome-json-fuer-biome-2-5-0-r/260921-9ie-SUMMARY.md` when done.
Halte in der Zusammenfassung ausdruecklich fest: (1) dass Zweig (b) gewaehlt wurde, mit den gemessenen Exit-Codes und Befundzahlen als Begruendung; (2) dass die Regelgruppe `security` unangetastet blieb und warum die 6 `noScriptUrl`-Treffer trotzdem verschwinden; (3) dass die beiden Zahlenangaben im Registereintrag #35 („17 Fehler in `users/user.controller.ts`") von der Messung abweichen — der Pfad lautet `apps/api/src/user/user.controller.ts` und die tatsaechliche Wirkung des Parser-Schalters betrug 238 parse-Fehler in 19 Dateien; (4) den verbleibenden Warnungs-Rueckstand als benannten, offenen Folgepunkt.
</output>