CommunityCodierung & Entwicklunggithub.com

Beobachtbarkeit und Instrumentierung

Instrumentiert Code, sodass das Verhalten in der Produktion sichtbar und diagnostizierbar ist. Verwenden Sie dies beim Hinzufügen von Logging, Metriken, Tracing oder Alerting. Verwenden Sie es beim Ausliefern jeder Funktion, die in der Produktion läuft und bei der Sie Nachweise benötigen, dass sie funktioniert. Verwenden Sie es, wenn Produktionsprobleme gemeldet werden, Sie aber anhand der verfügbaren Daten nicht sagen können, was passiert ist.

Was ist Beobachtbarkeit und Instrumentierung?

Diese Fertigkeit ist ein umfassender Leitfaden für Entwickler, um Systeme beobachtbar zu machen. Sie definiert Beobachtbarkeit als die Fähigkeit, von außen zu beantworten, "Was macht das System und warum?", mithilfe von Telemetriedaten, die der Code ausstößt. Der Prozess betont die Instrumentierung als integralen Bestandteil der Entwicklung (ähnlich wie Tests) und nicht als nachträglichen Einfall. Er beginnt damit, die Fragen eines Bereitschaftsingenieurs zu definieren, bevor Code geschrieben wird, und wählt dann die richtigen Signale (strukturierte Logs, Metriken über RED/USE, verteiltes Tracing mit OpenTelemetry) aus, um diese Fragen zu beantworten. Zu den wichtigsten Praktiken gehören die Verwendung stabiler Ereignisnamen und Korrelations-IDs in strukturierten Logs, die Vermeidung von hoher Kardinalität in Metrik-Labels, die symptom-basierte Alarmierung (nicht ursachen-basiert) und die Überprüfung der Telemetrie selbst, bevor die Arbeit als abgeschlossen betrachtet wird. Die Fertigkeit ist für jede Umgebung relevant, in der Node.js-Code (oder ähnliche Stacks) in Produktion läuft, und unterstützt gängige Plattformen wie Express, OpenTelemetry und Prometheus. Sie umreißt klare Anti-Patterns (wie die Verwendung von console.log, durchschnittlicher Latenz oder ursachen-basierten Alarmen) und bietet eine Checkliste zur Überprüfung der korrekten Instrumentierung.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/addyosmani/agent-skills/tree/main/skills/observability-and-instrumentation

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Was macht Beobachtbarkeit und Instrumentierung?

Überblick

Code, den Sie nicht beobachten können, ist Code, den Sie nicht betreiben können. Beobachtbarkeit ist die Fähigkeit, von außen die Frage "Was macht das System und warum?" zu beantworten, und zwar mithilfe der Telemetriedaten, die der Code ausstößt. Instrumentierung ist kein nachträglicher Zusatz nach dem Start – sie wird zeitgleich mit der Funktion geschrieben, genauso wie Tests. Wenn eine Funktion ohne Telemetrie ausgeliefert wird, wird der erste von einem Benutzer gemeldete Fehler zur Archäologie anstatt zu einer Abfrage.

Wann zu verwenden

  • Bei der Entwicklung jeder Funktion, die in Produktion laufen wird
  • Beim Hinzufügen eines neuen Dienstes, Endpunkts, Hintergrundjobs oder einer externen Integration
  • Ein Produktionsvorfall hat zu lange gedauert, um diagnostiziert zu werden ("wir konnten nicht sagen, was passiert ist")
  • Beim Einrichten oder Überprüfen von Alarmierungsregeln
  • Bei der Überprüfung eines PRs, der E/A, Wiederholungen, Warteschlangen oder dienstübergreifende Aufrufe hinzufügt

NICHT für:

  • Die Diagnose eines gerade stattfindenden Fehlers – verwenden Sie die Fertigkeit debugging-and-error-recovery (Beobachtbarkeit ist das, was diese Fertigkeit beim nächsten Mal schnell macht)
  • Profiling und Optimierung gemessener Langsamkeit – verwenden Sie die Fertigkeit performance-optimization
  • Checklisten für die Überwachung am Starttag und Rollback-Auslöser – siehe die Fertigkeit shipping-and-launch; diese Fertigkeit deckt die Instrumentierung ab, die diese speist

Prozess

1. Definieren Sie "funktioniert", bevor Sie instrumentieren

Telemetrie ohne eine Frage ist Rauschen. Bevor Sie eine Instrumentierung hinzufügen, schreiben Sie 2–4 Fragen auf, die ein Bereitschaftsingenieur zu dieser Funktion stellen wird:

FUNKTION: Zahlungswiederholung beim Checkout
FRAGEN, DIE DER BEREITSCHAFTSINGENIEUR STELLEN WIRD:
1. Welcher Anteil der Zahlungen ist beim ersten Versuch erfolgreich im Vergleich zu nach einer Wiederholung?
2. Wenn eine Zahlung endgültig fehlschlägt, warum? (Anbieterfehler? Zeitüberschreitung? Validierung?)
3. Ist der Zahlungsanbieter langsamer als üblich?
→ Jedes Signal unten muss helfen, eine dieser Fragen zu beantworten.

Wenn Sie die Fragen nicht nennen können, sind Sie nicht bereit zu instrumentieren – Sie werden alles protokollieren und nichts lernen.

2. Wählen Sie das richtige Signal für jede Frage

SignalBeantwortetKostenprofilBeispiel
Strukturiertes Log"Was ist in diesem speziellen Fall passiert?"Pro Ereignis; wächst mit dem Datenverkehrpayment_failed mit Anbieterfehlercode
Metrik"Wie oft / wie schnell, im Aggregat?"Fest pro Serie; billig abzufragenp99-Latenz von Anbieteraufrufen
Trace"Wo ging Zeit zwischen Diensten verloren?"Pro Anfrage; normalerweise gesampeltEin langsamer Checkout, aufgeschlüsselt nach Hop

Faustregel: Metriken sagen Ihnen, dass etwas falsch ist, Traces sagen Ihnen wo, Logs sagen Ihnen warum.

3. Strukturiertes Logging

Protokollieren Sie Ereignisse, keine Prosa. Jede Log-Zeile ist ein JSON-Objekt mit einem stabilen Ereignisnamen und maschinenlesbaren Feldern:

// SCHLECHT: String-Interpolation — nicht abfragbar, inkonsistent
logger.info(`Zahlung ${id} fehlgeschlagen für Benutzer ${userId} nach ${n} Wiederholungen`);

// GUT: stabiler Ereignisname + strukturierte Felder
logger.warn({
  event: 'payment_failed',
  paymentId: id,
  provider: 'stripe',
  errorCode: err.code,
  attempt: n,
}, 'zahlung fehlgeschlagen');

Log-Level — verwenden Sie sie konsistent:

LevelBedeutungAktion des Bereitschaftsingenieurs
errorInvariante verletzt; jemand muss möglicherweise handelnUntersuchen
warnBeeinträchtigt, aber behandelt (Wiederholung erfolgreich, Fallback verwendet)Trends beobachten
infoBedeutendes Geschäftsereignis (Bestellung aufgegeben, Job beendet)Keine
debugDiagnostisches DetailStandardmäßig in Produktion ausgeschaltet

Korrelations-IDs sind obligatorisch. Generieren (oder akzeptieren) Sie eine Anforderungs-ID an der Systemgrenze und hängen Sie sie an jede Log-Zeile, jeden Span und jeden ausgehenden Aufruf an. Ohne sie können Sie eine einzelne Anfrage aus verschachtelten Logs nicht rekonstruieren:

// Express: Child-Logger pro Anfrage, ID wird nachgelagert weitergegeben
app.use((req, res, next) => {
  req.id = req.headers['x-request-id'] ?? crypto.randomUUID();
  req.log = logger.child({ requestId: req.id });
  res.setHeader('x-request-id', req.id);
  next();
});

Wenn mehrere Einstiegspunkte in ein Log schreiben, benennen Sie den Einstiegspunkt. Eine Korrelations-ID identifiziert einen Durchlauf; sie sagt nicht, welcher Codepfad ihn gestartet hat. Derselbe Job, der von einem Scheduler, einem Replay-Endpunkt und einem manuellen CLI-Aufruf erreicht wird, erzeugt austauschbare Zeilen in einer Senke. Die Zuordnung einer Zeile fällt daher auf die Eliminierung zurück – Querlesen des Scheduler-Verlaufs, der Prozesstabelle, eines Deployment-Logs – und diese Argumentation gilt nur, solange diese externen Aufzeichnungen zufällig noch existieren. Stempeln Sie den Einstiegspunkt dort ab, wo der Durchlauf beginnt, neben der Korrelations-ID, und geben Sie beide auf die gleiche Weise weiter:

// Ein Helfer für jeden Einstiegspunkt: Der eigene Logger des Durchlaufs trägt beide Felder.
// `entryPoint`, nicht `source` — ECS reserviert `source.*` für Netzwerkfelder.
export const runLog = (entryPoint: 'scheduler' | 'replay_endpoint' | 'cli', runId: string) =>
  logger.child({ entryPoint, requestId: runId });

// scheduler tick        -> runLog('scheduler', crypto.randomUUID())
// POST /jobs/:id/replay -> runLog('replay_endpoint', req.id)
// CLI invocation        -> runLog('cli', process.env.RUN_ID ?? crypto.randomUUID())

Beide Felder müssen dieselben Grenzen überschreiten wie die Korrelations-ID – Warteschlangen-Metadaten, HTTP-Header – oder ein Worker leitet den Einstiegspunkt ab und rät. Ein Feld, das lediglich mit einem Einstiegspunkt korreliert, ist ein Hinweis, keine Zuordnung: Alles, was den Job aufrufen kann, kann ihn reproduzieren.

Protokollieren Sie niemals Geheimnisse, Token, Passwörter oder vollständige personenbezogene Daten (PII). Dies ist eine harte Regel aus der Fertigkeit security-and-hardening – Telemetriepipelines sind ein klassischer Datenleckpfad. Erlauben Sie Felder auf eine Whitelist; protokollieren Sie keine vollständigen Anforderungskörper.

4. Metriken

Instrumentieren Sie für anforderungsgesteuerte Dienste RED auf jedem Endpunkt und jeder externen Abhängigkeit: Rate (Anfragen/s), Errors (Fehlerrate), Duration (Latenz-Histogramm, nicht Durchschnitt). Verwenden Sie für Ressourcen (Warteschlangen, Pools, Hosts) USE: Utilization (Auslastung), Saturation (Sättigung), Errors (Fehler).

Wie beim Tracing ist der anbieterneutrale Weg die OpenTelemetry-Metriken-API (gleiches SDK und gleicher Kontext wie Schritt 5). Das folgende Beispiel verwendet prom-client von Prometheus – eine gängige Backend-Wahl, nicht die einzige; die RED-/USE- und Kardinalitätsregeln sind in beiden Fällen identisch.

import { Histogram } from 'prom-client';

const httpDuration = new Histogram({
  name: 'http_request_duration_seconds',
  help: 'HTTP-Anfragedauer',
  labelNames: ['method', 'route', 'status_class'],  // '2xx', nicht '200'
  buckets: [0.05, 0.1, 0.25, 0.5, 1, 2.5, 5],
});

Kardinalität ist die Fehlerart. Jede eindeutige Label-Kombination ist eine separate Zeitreihe. Labels müssen aus kleinen, festen Mengen stammen (Routenvorlage, Statusklasse, Anbietername). Verwenden Sie niemals Benutzer-IDs, rohe URLs, Fehlermeldungen oder andere unbegrenzte Werte als Labels – diese gehören in Logs und Traces.

OK als Label:    route="/api/tasks/:id"   status_class="5xx"   provider="stripe"
NIEMALS ein Label:  user_id, email, request_id, vollständige URL, Fehlermeldungstext

Verfolgen Sie niemals Durchschnitte, immer Perzentile: Ein Durchschnitt verbirgt die 1 % der Benutzer, die eine schlechte Zeit haben. Verwenden Sie Histogramme und lesen Sie p50/p95/p99.

5. Verteiltes Tracing

Verwenden Sie OpenTelemetry – es ist der anbieterneutrale Standard, und die Auto-Instrumentierung deckt HTTP, gRPC und gängige DB-Clients mit nahezu null Code ab:

// tracing.ts — muss vor allem anderen importiert werden
import { NodeSDK } from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';

const sdk = new NodeSDK({
  serviceName: 'checkout-service',
  instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();

Fügen Sie manuelle Spans nur um sinnvolle interne Arbeitseinheiten herum hinzu (z. B. applyDiscounts, chargeProvider) und hängen Sie die Attribute an, nach denen der Bereitschaftsdienst filtern wird. Geben Sie den Kontext über jede asynchrone Grenze hinweg weiter – HTTP-Header, Warteschlangen-Metadaten – oder der Trace stirbt an der Lücke. Samplen Sie standardmäßig kopfgesteuert mit einer niedrigen Rate; behalten Sie 100 % der Fehler bei, wenn Ihr Backend Tail-Sampling unterstützt.

6. Alarmierung

Alarmieren Sie auf Symptome, die Benutzer spüren, nicht auf Ursachen:

SYMPTOM (seitenwürdig):           URSACHE (Dashboard, keine Seite):
Fehlerrate > 1 % für 5 Min        CPU bei 85 %
p99-Latenz > 2s                   ein Pod neu gestartet
Warteschlangenalter > 10 Min      Festplatte bei 70 %

Ursachenbasierte Alarme lösen aus, wenn nichts falsch ist, und übersehen Fehler, die Sie nicht vorhergesehen haben. Symptombasierte Alarme lösen genau dann aus, wenn Benutzer beeinträchtigt sind, unabhängig von der Ursache.

Regeln für jeden Alarm, den Sie erstellen:

  1. Er muss umsetzbar sein. Wenn die Antwort "ignorieren, es heilt sich selbst" ist, löschen Sie den Alarm.
  2. Er verlinkt auf ein Runbook – selbst drei Zeilen: was es bedeutet, erste auszuführende Abfrage, Eskalationspfad.
  3. Er hat einen Schwellenwert und eine Dauer, die durch das SLO oder durch historische Daten gerechtfertigt sind, nicht durch eine Vermutung.
  4. Verwenden Sie nur zwei Schweregrade: Seite (benutzerorientiert, jetzt handeln) und Ticket (Beeinträchtigung, diese Woche handeln). Eine dritte Stufe wird zu Rauschen, das Menschen darin trainiert, alles zu ignorieren.

Runbooks schreiben

Regel 2 oben erfordert, dass jeder Alarm auf ein Runbook verlinkt. Die Aufgabe eines Runbooks ist es, drei Fragen zu beantworten, ohne dass der Leser nachdenken muss: Was passiert, was zuerst überprüft werden soll und wen man anrufen soll, wenn das das Problem nicht löst. Speichern Sie es in docs/runbooks/ benannt nach dem Alarm.

Minimal lebensfähiges Runbook (drei Zeilen):

# Runbook: Hohe Fehlerrate auf /api/tasks
**Bedeutet:** DB-Verbindungspool wahrscheinlich erschöpft oder ein fehlerhaftes Deployment.
**Erste Überprüfung:** `SELECT count(*) FROM pg_stat_activity WHERE backend_type = 'client backend';`
  — wenn Anzahl > Pool-Limit, siehe Schritt 2. (Ersetzen Sie dies durch das Äquivalent für Ihre Datenbank.)
**Eskalation an:** #db-oncall oder Engineering-Bereitschaftsrotation.

Wann über drei Zeilen hinaus erweitern: Fügen Sie Schritte nur hinzu, wenn die erste Überprüfung allein nicht ausreicht, um zu entscheiden. Ein Runbook mit fünf Schritten, das die drei häufigsten Ursachen abdeckt, ist besser als ein Dokument mit zwanzig Schritten, das jeden Randfall abdeckt und nur überflogen wird.

Halten Sie Runbooks aktuell. Aktualisieren Sie das Runbook als Teil des Abschlusses jedes Vorfalls, in dem es verwendet wurde – ein veraltetes Runbook schafft falsches Vertrauen. Wenn ein Schritt falsch war oder fehlte, korrigieren Sie ihn, bevor Sie den Vorfall als abgeschlossen markieren.

7. Überprüfen Sie die Telemetrie selbst

Instrumentierung ist Code; sie kann falsch sein. Bevor Sie die Arbeit als erledigt bezeichnen, lösen Sie die Pfade aus und sehen Sie sich die tatsächliche Ausgabe an:

  • Erzwingen Sie einen Fehler im Staging → finden Sie ihn in den Logs anhand der requestId, bestätigen Sie, dass die Felder strukturiert sind (nicht [object Object])
  • Senden Sie Testverkehr → bestätigen Sie, dass Metrikreihen mit den erwarteten Labels und sinnvollen Werten erscheinen
  • Verfolgen Sie eine Anfrage dienstübergreifend in der Tracing-Benutzeroberfläche → keine unterbrochenen Spans
  • Lösen Sie jeden neuen Alarm einmal aus (senken Sie den Schwellenwert vorübergehend) → bestätigen Sie, dass er den richtigen Kanal erreicht und der Runbook-Link funktioniert

Häufige Rechtfertigungen

RechtfertigungRealität
"Ich füge Logging hinzu, nachdem es funktioniert""Nachher" wird zu "nach dem ersten Vorfall", was der teuerste Moment ist, um festzustellen, dass Sie blind sind. Instrumentieren Sie, während Sie bauen.
"Mehr Logs = mehr Beobachtbarkeit"Unstrukturiertes Rauschen macht Vorfälle langsamer, nicht schneller. Drei abfragbare Ereignisse schlagen dreihundert Prosa-Zeilen.
"console.log ist für den Anfang in Ordnung"Unstrukturierte Ausgabe kann nicht gefiltert, korreliert oder alarmiert werden. Der strukturierte Logger kostet einmal fünf zusätzliche Minuten.
"Wir können uns die Dashboards einfach ansehen, wenn etwas kaputt geht"Dashboards, die ohne definierte Fragen erstellt wurden, zeigen Ihnen alles außer der Antwort. Beginnen Sie mit Fragen des Bereitschaftsdienstes.
"Alarmieren Sie auf alles Wichtige, wir passen es später an"Ein lauter Pager trainiert Leute, ihn zu ignorieren. Die Anpassung findet nie statt; der verpasste echte Alarm schon.
"Benutzer-ID als Metrik-Label erleichtert das Debugging"Es bringt auch Ihr Metrik-Backend zum Absturz. Lookups mit hoher Kardinalität gehören in Logs und Traces.
"Tracing ist übertrieben für unsere zwei Dienste"Zwei Dienste bedeuten bereits dienstübergreifende Latenzfragen, die Logs nicht beantworten können. Auto-Instrumentierung macht die Kosten trivial.

Rote Flaggen

  • Ein Funktions-PR mit Wiederholungen, Warteschlangen oder externen Aufrufen und null neuer Telemetrie
  • Log-Zeilen, die durch String-Interpolation anstelle von strukturierten Feldern erstellt wurden
  • Keine Korrelations-/Anfrage-ID – jede Log-Zeile ist eine Waise
  • Ein Log-Stream, der von einem Scheduler, einem Webhook und manuellen Ausführungen gespeist wird, ohne ein Feld, das benennt, welcher die Zeile produziert hat
  • Metriken, die mit Benutzer-IDs, rohen URLs oder Fehlermeldungstext gekennzeichnet sind (Kardinalitätsbombe)
  • Latenz als Durchschnitt ohne Perzentile verfolgt
  • Alarme, die täglich auslösen und ohne Aktion bestätigt werden
  • Alarme auf Ursachen (CPU, Speicher), die Menschen anpiepsen, während die benutzerorientierte Fehlerrate unbeaufsichtigt bleibt
  • Geheimnisse, Token oder vollständige Anforderungskörper, die in Logs erscheinen
  • "Es funktioniert auf meinem Rechner" als einziger Beweis dafür, dass eine Produktionsfunktion gesund ist

Überprüfung

Nach der Instrumentierung einer Funktion bestätigen Sie:

  • Die Bereitschaftsfragen für diese Funktion sind aufgeschrieben, und jedes Signal ist einer zugeordnet
  • Die gesamte Log-Ausgabe ist strukturiert (JSON), mit stabilen Ereignisnamen und einer Korrelations-ID auf jeder Zeile
  • Jede Log-Senke, die von mehr als einem Einstiegspunkt beschrieben wird, trägt ein Einstiegspunkt-Feld, das dort gesetzt wird, wo der Durchlauf beginnt, und mit der Korrelations-ID weitergegeben wird, anstatt nachgelagert abgeleitet zu werden
  • Keine Geheimnisse, Token oder ungeschwärzte personenbezogene Daten in irgendeiner Log-Zeile (Stichprobenartige Überprüfung der tatsächlichen Ausgabe)
  • RED-Metriken existieren für jeden neuen Endpunkt und jede externe Abhängigkeit mit begrenzten Label-Sets
  • Latenz ist ein Histogramm; p95/p99 sind abfragbar
  • Eine einzelne Anfrage kann in der Tracing-Benutzeroberfläche durchgängig verfolgt werden, ohne unterbrochene Spans
  • Jeder neue Alarm ist symptom-basiert, hat einen Runbook-Link und wurde einmal testweise ausgelöst
  • Ein induzierter Fehler im Staging wurde allein durch Telemetrie lokalisiert, ohne den Quellcode zu lesen

Für die Kurzversion dieser Liste, einschließlich des Instrumentierungs-Gates vor dem Start, siehe ../../references/observability-checklist.md.

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

addyosmani/agent-skills

Builds production-quality, accessible, responsive user-facing UIs. Use when building or modifying interfaces and pages, creating components, implementing layouts, meeting WCAG accessibility requirements, managing state, or when the output needs to look and feel production-quality rather than AI-generated.

addyosmani/agent-skills

Prepares production launches. Use when preparing to deploy to production, or when asking what needs to be in place before shipping. Use when you need a pre-launch checklist, when setting up monitoring, when planning a staged rollout, or when you need a rollback strategy.

addyosmani/agent-skills

Guides stable API and interface design. Use when designing APIs, module boundaries, or any public interface. Use when creating REST or GraphQL endpoints, defining type contracts between modules, or establishing boundaries between frontend and backend.

addyosmani/browser-testing-with-devtools

Tests in real browsers via Chrome DevTools MCP. Use when building or debugging anything that runs in a browser. Use when you need to inspect the DOM, capture console errors, analyze network requests, profile performance, or verify visual output with real runtime data. Requires the chrome-devtools MCP server to be configured.

addyosmani/ci-cd-and-automation

Automates CI/CD pipeline setup. Use when setting up or modifying build and deployment pipelines. Use when you need to automate quality gates, configure test runners in CI, or establish deployment strategies.

addyosmani/code-review-and-quality

Conducts multi-axis code review. Use before merging any change. Use when reviewing code written by yourself, another agent, or a human. Use when you need to assess code quality across multiple dimensions before it enters the main branch.

addyosmani/code-simplification

Simplifies code for clarity. Use when refactoring code for clarity without changing behavior. Use when code works but is harder to read, maintain, or extend than it should be. Use when reviewing code that has accumulated unnecessary complexity.

addyosmani/constraint-driven-development

Establishes a project's quality bar as a written contract and stops agents quietly lowering it. Interviews the user on which dimensions matter, supplies sane default thresholds when they have no number in mind, records everything in CONSTRAINTS.md, and watches the diff for a weakened bar — new @ts-ignore or eslint-disable suppressions, skipped or deleted tests, assertions stripped out, unimplemented stubs, thresholds edited down. Use when no quality bar is written down, when the user says "set up constraints" or "define our standards", when the user wants dimensions they care about — accessibility, web performance, coverage — set up as enforced constraints, when an agent keeps silencing checks or skipping tests to get to green, when you need a coverage or performance threshold and don't know what number to pick, or when an agent writes more code than anyone will read.

addyosmani/debugging-and-error-recovery

Guides systematic root-cause debugging. Use when tests fail, builds break, behavior doesn't match expectations, or you encounter any unexpected error. Use when you need a systematic approach to finding and fixing the root cause rather than guessing.

addyosmani/deprecation-and-migration

Manages deprecation and migration. Use when removing old systems, APIs, or features. Use when migrating users from one implementation to another. Use when deciding whether to maintain or sunset existing code.

addyosmani/documentation-and-adrs

Records decisions and documentation. Use when making architectural decisions, changing public APIs, shipping features, or when you need to record context that future engineers and agents will need to understand the codebase.

addyosmani/doubt-driven-development

Subjects every non-trivial decision to a fresh-context adversarial review before it stands. Use when correctness matters more than speed, when working in unfamiliar code, when stakes are high (production, security-sensitive logic, irreversible operations), or any time a confident output would be cheaper to verify now than to debug later.

addyosmani/git-workflow-and-versioning

Structures git workflow practices. Use when making any code change. Use when committing, branching, resolving conflicts, or when you need to organize work across multiple parallel streams.

addyosmani/idea-refine

Refines raw ideas into sharp, actionable concepts through structured divergent and convergent thinking. Use when an idea is still vague, when you need to stress-test assumptions before committing to a plan, or when you want to expand options before converging on one. Triggers on "ideate", "refine this idea", or "stress-test my plan".

addyosmani/incremental-implementation

Delivers changes incrementally. Use when implementing any feature or change that touches more than one file. Use when you're about to write a large amount of code at once, or when a task feels too big to land in one step.

addyosmani/interview-me

Extracts what the user actually wants instead of what they think they should want. Achieves this through one-question-at-a-time interview until ~95% confidence about the underlying intent. Use when an ask is underspecified ("build me X" without "for whom" or "why now"), when the user explicitly invokes ("interview me", "grill me", "are we sure?", "stress-test my thinking"), or when you catch yourself silently filling in ambiguous requirements before any plan, spec, or code exists.

addyosmani/performance-optimization

Optimizes application performance. Use when performance requirements exist, when you suspect performance regressions, or when Core Web Vitals or load times need improvement. Use when profiling reveals bottlenecks that need fixing.

addyosmani/planning-and-task-breakdown

Breaks work into ordered tasks. Use when you have a spec or clear requirements and need to break work into implementable tasks. Use when a task feels too large to start, when you need to estimate scope, or when parallel work is possible.

addyosmani/security-and-hardening

Hardens code against vulnerabilities. Use when handling user input, authentication, data storage, or external integrations. Use when building any feature that accepts untrusted data, manages user sessions, or interacts with third-party services.

addyosmani/source-driven-development

Grounds every implementation decision in official documentation. Use when you want authoritative, source-cited code free from outdated patterns. Use when building with any framework or library where correctness matters.

Verwandte Skills