Technical Debt durch any managen: Governance statt Einzelaktionen
AI generated
<T>
type
TypeScript · Technical Debt · Governance
Technical Debt durch any managen
Governance statt punktueller Aufräumaktionen

Technical Debt durch any-Nutzung verschwindet nicht durch einen einmaligen Aufräumtag, sondern wächst leise weiter, solange kein System dahinter steht. CI-Budgets, Ticket-Pflicht für Ausnahmen, klare Ownership und regelmäßiges Reporting machen aus any-Technical-Debt ein messbares, steuerbares Governance-Thema statt eines schlechten Gewissens im Team.

17 Min. LesezeitCI-Budget · Ticket-Pflicht · Ownership · ReportingTypeScript 5.x · ESLint · type-coverage

1. Warum any-Technical-Debt ein Governance-Thema ist

Technical Debt durch any wird in vielen Teams als individuelles Problem behandelt: Ein Entwickler findet eine Stelle mit any, ersetzt sie bei Gelegenheit, und das Thema gilt als erledigt. Dieser Ansatz scheitert systematisch, weil neue any-Vorkommen genauso schnell entstehen, wie alte verschwinden, solange kein übergeordnetes System die Entstehung kontrolliert.

Ein Governance-Ansatz behandelt any-Technical-Debt wie finanzielle Schulden: mit einem gemessenen Bestand, einem Budget, das nicht wachsen darf, und einer klaren Verantwortlichkeit für die Rückzahlung. Das verschiebt die Frage von wer hat Zeit, das aufzuräumen zu wie stellen wir sicher, dass der Bestand nicht weiter wächst, was ein grundlegend anderes Problem ist.

Der Unterschied wird besonders bei wachsenden Codebasen sichtbar. Ein Team ohne Governance verliert langsam den Überblick, wie viel any tatsächlich im Projekt steckt, während ein Team mit Governance jederzeit eine genaue Zahl nennen kann und weiß, in welchem Modul sich Technical Debt konzentriert.

2. any-Vorkommen systematisch messen statt schätzen

Jedes Governance-System beginnt mit einer verlässlichen Messung. Ein einfacher grep nach any liefert Falsch-Positive, etwa in Kommentaren oder Strings, weshalb sich spezialisierte Werkzeuge wie type-coverage besser eignen, um den tatsächlichen Anteil typsicherer Ausdrücke in der Codebasis zu berechnen. Diese Zahl bildet die Baseline, gegen die jede zukünftige Änderung gemessen wird.

Wichtig ist, die Messung nach Modul aufzuschlüsseln, statt nur eine globale Zahl zu berichten. Ein Governance-System, das weiß, dass 80 Prozent der any-Vorkommen in einem einzigen Legacy-Modul konzentriert sind, kann gezielter priorisieren als eines, das nur eine undifferenzierte Gesamtzahl kennt.


#!/usr/bin/env bash
# any-debt-report.sh — measure any-related technical debt per module
set -euo pipefail

echo "[REPORT] Overall type coverage:"
npx type-coverage --detail=false

echo "[REPORT] any-density by module:"
worst_module=""
worst_density="0"
for dir in src/*/; do
  module=$(basename "$dir")
  count=$(grep -r --include="*.ts" -o '\bany\b' "$dir" | wc -l)
  lines=$(find "$dir" -name "*.ts" -exec cat {} + | wc -l)
  density=$(awk -v c="$count" -v l="$lines" 'BEGIN { printf "%.2f", (l > 0 ? c / l * 100 : 0) }')
  echo "  $module: $count occurrences, ${density}% density"
  if (( $(echo "$density > $worst_density" | bc -l) )); then
    worst_module="$module"
    worst_density="$density"
  fi
done

echo "[REPORT] Highest density module: $worst_module (${worst_density}%)"
echo "[REPORT] Use this to prioritize ownership assignment, see section 5"

3. Ein any-Budget in der CI-Pipeline durchsetzen

Sobald eine verlässliche Baseline existiert, lässt sich Technical Debt technisch begrenzen: Ein CI-Check vergleicht die aktuelle any-Anzahl mit der Baseline und lässt den Build fehlschlagen, sobald die Zahl steigt. Das verhindert, dass sich neue Technical Debt unbemerkt in jeden Pull Request einschleicht, während bestehende Debt nicht sofort behoben werden muss.

Dieses Budget-Prinzip funktioniert psychologisch anders als eine reine Empfehlung. Ein Entwickler, der einen fehlschlagenden Build sieht, wird aktiv nach einer typsicheren Alternative suchen, während eine bloße Warnung im Review häufig übersehen oder ignoriert wird. Governance bedeutet hier, dass die Pipeline zur Instanz wird, die das Budget verteidigt, nicht ein einzelner Reviewer.


#!/usr/bin/env bash
# any-budget-gate.sh — fail CI if any-count exceeds the agreed baseline
set -euo pipefail

BASELINE_FILE=".any-budget"
current=$(grep -r --include="*.ts" -o '\bany\b' src | wc -l)
baseline=$(cat "$BASELINE_FILE")

echo "[BUDGET] Current any count: $current"
echo "[BUDGET] Agreed baseline: $baseline"

if (( current > baseline )); then
  echo "[FAIL] any budget exceeded by $((current - baseline)) occurrences" >&2
  echo "[FAIL] add a ticket-referenced exception or remove the new any usage" >&2
  exit 1
fi

if (( current < baseline )); then
  echo "$current" > "$BASELINE_FILE"
  echo "[OK] baseline improved, new budget: $current"
fi

4. Ticket-Pflicht für jede neue Ausnahme

Ein any-Budget allein verhindert Wachstum, erklärt aber nicht, warum eine Ausnahme entstanden ist. Governance verlangt zusätzlich, dass jede neue any-Nutzung mit einem Ticket verknüpft wird, das den Grund, die geplante Behebung und ein Zieldatum dokumentiert. Ohne diese Kopplung bleibt Technical Debt unsichtbar, sobald das Budget einmal genehmigt wurde.

In der Praxis lässt sich diese Pflicht direkt in ESLint abbilden: Eine Custom-Regel erzwingt, dass jede any-Zeile einen Kommentar mit einem Ticket-Verweis in einem festen Format trägt. Das macht die Ausnahme durchsuchbar und ermöglicht, alle offenen any-Tickets gesammelt im Backlog zu priorisieren, statt sie über die gesamte Codebasis verteilt zu suchen.


// Governance rule enforced by a custom ESLint rule: any needs a ticket

// ALLOWED — matches the required pattern TICKET-<number>, EXPIRES-<date>
// TICKET-4821, EXPIRES-2026-10-01: vendor SDK types land in Q4
function parseVendorResponse(raw: any): VendorResponse {
  return raw as VendorResponse;
}

// REJECTED by CI — no ticket reference, no expiry date
function parseLegacyResponse(raw: any): LegacyResponse {
  return raw as LegacyResponse;
}

// REJECTED by CI — ticket present but no expiry date, still incomplete
// TICKET-5012
function parsePartnerResponse(raw: any): PartnerResponse {
  return raw as PartnerResponse;
}

interface VendorResponse { status: string }
interface LegacyResponse { status: string }
interface PartnerResponse { status: string }

5. Ownership: Wer verantwortet welchen any-Bereich

Technical Debt ohne klare Ownership wird zu niemandes Verantwortung und bleibt deshalb liegen. Governance bedeutet, jedem Modul mit hoher any-Dichte ein Team oder eine Person als Owner zuzuweisen, ähnlich wie eine CODEOWNERS-Datei den Code-Review regelt. Diese Ownership sollte nicht als Bestrafung verstanden werden, sondern als klare Verantwortung mit entsprechendem Zeitbudget.

Ein wirksames Governance-Modell koppelt Ownership mit einem festen Anteil der Sprint-Kapazität, etwa zehn Prozent für Technical-Debt-Reduktion im eigenen Modul. Das verhindert, dass any-Abbau immer der ersten Priorität eines neuen Features weichen muss und dadurch faktisch nie stattfindet.


# .github/ANY-DEBT-OWNERS — extends CODEOWNERS with debt-reduction duty
# format: <path>  <owning team>  <sprint capacity share>

src/legacy-checkout/    @team-payments   10%
src/reporting-export/   @team-analytics  5%
src/admin-tools/        @team-platform   5%

# reviewed and re-assigned quarterly in the architecture sync,
# capacity share feeds directly into each team's sprint planning

6. Eskalation und Priorisierung im Backlog

Nicht jede any-Ausnahme verdient dieselbe Priorität. Governance braucht ein Eskalationsmodell, das any-Debt nach Risiko einstuft: any in einer Kernfunktion mit häufigen Änderungen verdient höhere Priorität als any in einem selten berührten Randmodul. Diese Einstufung sollte auf denselben Kennzahlen basieren wie die Messung selbst, etwa Änderungsfrequenz und Bug-Historie des betroffenen Codes.

Ein einfaches, aber wirksames Instrument ist ein automatisierter Reminder, sobald ein Ticket mit any-Ausnahme sein Zieldatum überschreitet. Das verhindert, dass eine geplante, zeitlich befristete Ausnahme stillschweigend zu einer dauerhaften wird, weil niemand mehr an das ursprüngliche Zieldatum erinnert wird.

7. Reporting an Team und Stakeholder

Governance verlangt Transparenz nach innen und außen. Ein monatlicher Bericht, der die any-Gesamtzahl, die Verteilung nach Modul und die Anzahl abgelaufener Ausnahmen zusammenfasst, macht Technical Debt für das Management genauso greifbar wie für das Entwicklungsteam. Das erleichtert es, Zeitbudget für Abbau zu rechtfertigen, weil der Fortschritt in Zahlen sichtbar ist.

Wichtig ist, dieses Reporting nicht als Anklage zu gestalten, sondern als gemeinsamen Fortschrittsbericht. Ein Team, das sieht, dass die any-Zahl über mehrere Monate sinkt, erlebt Governance als wirksames System, nicht als zusätzliche Bürokratie, die nur Arbeit ohne sichtbaren Nutzen erzeugt.


{
  "//": "monthly-any-debt-report.json — generated summary for stakeholders",
  "period": "2026-07",
  "totalAnyCount": 214,
  "previousMonth": 251,
  "budgetLimit": 220,
  "expiredExceptions": 3,
  "topModulesByDensity": [
    { "module": "legacy-checkout", "count": 89, "owner": "team-payments" },
    { "module": "reporting-export", "count": 41, "owner": "team-analytics" }
  ],
  "trend": {
    "threeMonthAverage": 238,
    "direction": "declining",
    "onTrackForQuarterlyGoal": true
  },
  "openTicketsNearingDeadline": 2
}

8. Die Kulturfalle: Warum Cleanup-Sprints allein scheitern

Viele Teams versuchen, any-Technical-Debt mit einem einmaligen Cleanup-Sprint zu lösen. Kurzfristig sinkt die Zahl, doch ohne Budget und Ticket-Pflicht steigt sie in den folgenden Monaten wieder auf das alte Niveau, weil die eigentliche Ursache, die Genehmigung neuer any-Nutzung ohne Kontrolle, unverändert bleibt. Ein Cleanup-Sprint behandelt das Symptom, nicht das System dahinter.

Governance unterscheidet sich davon, weil sie die Entstehung neuer Technical Debt kontrolliert, nicht nur den bestehenden Bestand abbaut. Ein Team, das ausschließlich aufräumt, ohne die Zuflüsse zu begrenzen, befindet sich in einer Endlosschleife, die auf Dauer mehr Frustration als Fortschritt erzeugt.

9. Ad-hoc-Cleanup versus Governance im Vergleich

Der Unterschied zwischen punktuellem Aufräumen und einem echten Governance-System für any-Technical-Debt zeigt sich am deutlichsten über mehrere Monate hinweg betrachtet.

AspektAd-hoc-CleanupGovernance-SystemEffekt
MessungGefühlter Eindrucktype-coverage pro Modul, regelmäßigObjektive Baseline für Entscheidungen
Neue any-NutzungUnkontrolliert genehmigtCI-Budget verhindert WachstumBestand wächst nicht unbemerkt weiter
AusnahmenOhne DokumentationTicket-Pflicht mit ZieldatumNachvollziehbar und priorisierbar
VerantwortungNiemand konkret zuständigOwnership pro Modul mit ZeitbudgetAbbau findet tatsächlich statt
Langfristiger EffektZurück auf altes Niveau nach MonatenStetiger Rückgang über ZeitNachhaltige statt kurzfristige Wirkung

10. Zusammenfassung

Technical Debt durch any lässt sich nicht mit einem einmaligen Cleanup-Sprint dauerhaft lösen, weil ohne Kontrolle über neue Ausnahmen die alte Menge innerhalb weniger Monate wieder erreicht wird. Ein Governance-System aus verlässlicher Messung, CI-Budget, Ticket-Pflicht und klarer Ownership behandelt die Ursache statt nur das Symptom.

Regelmäßiges Reporting an Team und Stakeholder macht Fortschritt sichtbar und rechtfertigt das nötige Zeitbudget für kontinuierlichen Abbau. Teams, die any-Technical-Debt so behandeln wie finanzielle Schulden, mit Budget, Zinsen und Rückzahlungsplan, gewinnen langfristig deutlich mehr Kontrolle über ihre Typqualität als Teams, die auf punktuelle Aufräumaktionen setzen.

Technical Debt durch any managen, das Wichtigste auf einen Blick

Messen statt schätzen

type-coverage pro Modul liefert eine objektive Baseline für jede Governance-Entscheidung.

Budget statt Empfehlung

Ein CI-Gate, das bei wachsender any-Zahl fehlschlägt, wirkt zuverlässiger als jede Bitte im Review.

Ticket-Pflicht

Jede Ausnahme braucht ein Ticket mit Grund und Zieldatum, sonst wird sie faktisch dauerhaft.

Ownership und Reporting

Klare Verantwortung pro Modul und regelmäßige Berichte machen Abbau nachhaltig statt einmalig.

11. FAQ: Technical Debt durch any managen

1Warum reicht ein einmaliger Cleanup-Sprint gegen any-Technical-Debt nicht aus?
Weil ohne Kontrolle über neue Ausnahmen die any-Zahl innerhalb weniger Monate wieder auf das alte Niveau steigt. Nur ein Budget in der CI-Pipeline verhindert dauerhaftes Wachstum.
2Wie misst man any-Technical-Debt zuverlässig?
Mit Werkzeugen wie type-coverage statt mit einfachem grep, weil grep auch Kommentare und Strings fälschlich mitzählt und keine verlässliche Baseline liefert.
3Was gehört in ein any-Budget-Gate in der CI?
Ein Vergleich der aktuellen any-Anzahl gegen eine gespeicherte Baseline, der den Build fehlschlagen lässt, sobald die Zahl steigt, und die Baseline automatisch verbessert, wenn sie sinkt.
4Muss jede any-Nutzung ein Ticket haben?
Ja, jede neue Ausnahme sollte einen Grund, ein Zieldatum und eine verantwortliche Person dokumentieren, sonst verschwindet der Kontext nach wenigen Wochen.
5Wer sollte für any-lastige Module verantwortlich sein?
Ein Team oder eine Person mit festem Zeitbudget für Abbau, ähnlich einer CODEOWNERS-Zuordnung, damit Verantwortung nicht diffus im gesamten Team verteilt bleibt.
6Wie priorisiert man, welche any-Stellen zuerst behoben werden?
Nach Risiko: any in häufig geänderten Kernfunktionen verdient höhere Priorität als any in selten berührten Randmodulen.
7Wie oft sollte über any-Technical-Debt berichtet werden?
Monatlich reicht in den meisten Teams, mit Gesamtzahl, Verteilung nach Modul und Anzahl abgelaufener Ausnahmen als festen Bestandteilen.
8Ist ein any-Budget von null realistisch?
Selten sofort. Ein realistisches Ziel ist ein stetig sinkendes Budget über mehrere Quartale, nicht ein sofortiges Verbot ohne Übergangsphase.
9Was tun, wenn ein Ticket sein Zieldatum überschreitet?
Ein automatisierter Reminder eskaliert das Ticket in den aktiven Sprint-Backlog, damit die Ausnahme nicht stillschweigend dauerhaft wird.
10Lohnt sich Governance auch in kleinen Teams?
Ja, gerade dort verhindert ein einfaches Budget und eine Ticket-Pflicht, dass any-Nutzung unbemerkt zur Gewohnheit wird, bevor das Team überhaupt merkt, wie groß der Bestand geworden ist.