Dev Espresso #2 – Dokumentacja, która nie gnije (AI‑przyspieszona higiena)

Dev Espresso #2 – Dokumentacja, która nie gnije (AI‑przyspieszona higiena)

Dariusz Luber
Dariusz Luber
📺

Wolisz wideo?

Przejdź do sekcji wideo

Video i ten wpis uzupełniają się nawzajem, dlatego dla najlepszego efektu skorzystaj z obu źródeł 😊

Pozbaw AI aktualnego kontekstu – dostaniesz wątpliwej jakości rezultaty. Nakarm je zwięzłymi, aktualnymi dokumentami – staje się .

Idea w skrócie

Lekka, stale odświeżana dokumentacja (PRD, decision records, README / service docs) to warstwa kompresji informacji dla ludzi i modeli. Nie chodzi o objętość – tylko o artefakty wysokiej jakości, które łatwo zdiffować, zaktualizować i można im zaufać.

Dlaczego dokumentacja się starzeje (i wprowadza w błąd AI)

Powody starzenia się dokumentacji:

  • Utrata właściciela (autor odchodzi – "intent fog")
  • "Ciche zmiany architektury" / Architecture Drift (kod ewoluuje, opis w dokumentacji się nie zmienia)
  • Dryf metryk / założeń (SLO, skala, ograniczenia techniczne)
  • Cmentarzyska markdown (za długie → nikt nie czyta → szybka degradacja)

Efekt: zespół i model halucynują, bo jest zdezaktualizowany / brakujący kontekst.

Minimalny zestaw dokumentów

Świadomie utrzymuj bardzo mały zakres dokumentów:

  • PRD (Problem, Users, Constraints, Success Metrics, Open Questions do domknięcia przed akceptacją)
  • Decision record (krótka notatka o trade‑offie – możesz zostawić ang. nazwę) → promuj do ADR tylko jeśli będą one trwałe + mają wpływ na architekturę / koszt utrzymania
  • Service -> README (jak uruchomić, odpowiedzialności, kluczowe zmienne środowiskowe - ENV vars, linki)
  • Aktualizacje delta przez diff - zamiast przepisywać wszystko od nowa, poproś AI o minimalny update na podstawie zmiany w kodzie

AI Assist – dobre vs złe przykłady promptów

Dobre: drafty, wyszukiwanie luk (gap finding), wykrywanie starzenia (rot detection), wyliczanie alternatyw i ryzyk.

Złe: wymyślanie celów biznesowych, zmyślone metryki, przepisywanie intencji bez weryfikacji.

Strażnik do promptów:

"Do not speculate beyond code or provided text. If unsure, list clarification questions."

Pamiętajcie aby pisać promty po angielsku - modele działają lepiej w tym języku.

Practical Workflow (End‑to‑End)

Zamiast biernie „pisać dokumentację” potraktuj ją jako powtarzalną pętlę:

flowchart TD
  A[Idea / Feature Seed] --> B[PRD Skeleton]
  B --> C[Constraints & Metrics Added]
  C --> D[Implementation Options]
  D --> E[Decision Note]
  E --> F[ADR Candidate]
  C --> G[Build / Code Changes]
  G --> H[Diff Scan]
  H --> I[Doc Refresh]
  I --> B
  classDef node fill:#222,stroke:#555,color:#fff;
  class A,B,C,D,E,F,G,H,I node;

Step 1: PRD Skeleton

Prompt: “Generate a concise PRD skeleton for a feature that <GOAL>. Include: Problem, Users, Use Cases, Non‑Goals, Constraints, Success Metrics, Open Questions. Do not speculate beyond provided text.”

Uzupełnij ręcznie realne ograniczenia (SLO, zakres danych). Niepewne pola oznacz TBD – AI nie może ich wymyślać.

Step 2: Gap & Risk Scan

Prompt: “Given this draft PRD, list 3–5 missing constraints or metrics. If data absent, respond with clarifying questions.”

Step 3: Implementation Options

Prompt: “Using this PRD excerpt, propose 3 implementation approaches; compare performance, complexity, risk; flag assumptions.”

Ty wybierasz – model jedynie podsuwa katalog opcji.

Step 4: Capture a Decision Record

Prompt seed: “From this commit message + diff, draft a 6‑line decision record: Context, Decision, Alternatives (2), Consequences (one +, one -), Follow‑Up. Do not fabricate unstated rationale.”

Step 5: Diff‑Driven Refresh

Prompt: “Old README section + diff summary. Suggest minimal updated replacement. Avoid marketing; reflect code truth only. If uncertain, output questions.”

Step 6: Rot / Drift Detection

Prompt: “Here is PRD v1 and latest diff summaries. List sections likely outdated + clarifying questions. Don’t guess new values.”

AI Update Loop (Diagram)

flowchart TD
  A[Existing Doc + Code Diff] --> B[Rot / Gap Prompt]
  B --> C[AI Suggestions]
  C --> D[Human Prune & Verify]
  D --> E[Commit Minimal Delta]
  E --> F[Periodic Re-Scan]
  F --> B
  style A fill:#222,stroke:#555,color:#fff
  style B fill:#222,stroke:#555,color:#fff
  style C fill:#222,stroke:#555,color:#fff
  style D fill:#222,stroke:#555,color:#fff
  style E fill:#222,stroke:#555,color:#fff
  style F fill:#222,stroke:#555,color:#fff

Decision Record vs PRD vs ADR

Artefakt Kiedy Żywotność Głębia
Decision Record Pojawiający się trade‑off Często przejściowy Krótki kontekst + wybór
PRD Przed / wczesny build Ewoluuje → Accepted → Archived Ramy funkcjonalne
ADR Wysoko‑impactowa decyzja architektoniczna Długa (może być superseded) Problem→Decision→Alternatives→Consequences

Heurystyka żeby podnieść DR do ADR: (Impact × Irreversibility × Cost of Misstep) >= ustalony próg zespołu.

Przykłady

To tylko przykłady – nie zakładaj, że to zawsze „dobre decyzje” 😅. Chodzi o strukturę.

Decision Record (Business / Product)

# Decision Record: Limit MVP Export Window to 7 Days
Date: 2025-09-22
Status: Proposed
Owner: Product (John Doe)
Decision Type: Scope Constraint

## Context
Early customers requested “full history” exports. Engineering estimates show a full-history path adds ~3 weeks (index tuning + batching infra) and risks missing the planned launch window. 80% of audit/support use cases reference only the last few days of activity.

## Decision
Ship MVP with a fixed 7-day export window; defer full-history & scheduling to post-MVP iteration.

## Alternatives Considered
1. Full History in MVP – Higher perceived value, but +3 weeks delay + higher infra cost.
2. 30-Day Window – Slightly broader utility, still needs extra indexes; adds ~1 week.
3. On-Demand “Extended Export” Ticket – Keeps scope small but reintroduces manual engineer time.

## Rationale
Maximizes time-to-value while covering majority of real support/audit cases; avoids premature scaling.

## Consequences
Positive: szybsze wdrożenie; niższy koszt infrastruktury na start; prostsze monitorowanie.
Negative: część zaawansowanych użytkowników i tak zgłosi prośby o starsze dane; możliwe poczucie „ograniczenia”.

## Mitigations
- Tooltip: “Need older data? Contact support (full export coming soon).”
- Trackuj zgłoszenia o >7 dni (support tag `export:extended-request`).

## Success Signals
- 90% of export usage completes without support escalation.
- <10% of export-related tickets ask for >7 days in first month.

## Follow-Up (Post-MVP Triggers)
Rozszerz do ruchomego 30‑dniowego okna gdy: (a) >10% tygodniowych próśb przekracza 7 dni LUB (b) pojawia się ryzyko churnu związane z ograniczeniem.

## Open Questions
1. Should billing plans gate longer retention windows?
2. Do we need an approval flow for exports >7 days (compliance)?

PRD Snippet

# PRD: Lightweight Activity Export
Date: 2025-09-22
Status: Draft
Owner: (TBD)

## Problem
Admins and Support need a quick way to extract recent user activity for audits and issue investigation. Today they run ad-hoc SQL or wait on engineering.

## Goal (1 Sentence)
Provide a self-service CSV export of recent activity that is fast, bounded in size, and safe to run frequently.

## Users / Primary Actor
- Primary: Admin
- Secondary: Support Engineer

## Scope (MVP)
- Export last 7 days of activity events (create/update/login)
- Download as CSV via UI button
- Optional filter by user email

## Out of Scope (MVP)
- Full historical exports (>7 days)
- Scheduled / recurring delivery
- PDF or JSON output
- Additional PII masking beyond existing model

## Functional Requirements
1. User clicks “Export Activity” → download starts within 1 second.
2. Optional email filter reduces result set before generation.
3. If result set exceeds limit, show message (no silent truncation).
4. Log each export (who, when, filter, row count).

## Non-Functional / Constraints
- Performance: P95 end-to-end ≤ 3s for typical (≤10k rows) export.
- Size: Max 25k rows OR ~50MB (whichever first).
- Frequency: ≤1 export / minute / user (rate limited).
- Load: Must not block primary write path (use read replica or background job).
- Security: Roles allowed = Admin, Support.

## Success Metrics
- 80% reduction in manual SQL export requests (baseline TBD → track after 30 days).
- 90% of exports complete <3s P95.
- <1% failed exports / week.

## Telemetry
- Log: duration_ms, row_count, filter_applied, success|failure_reason.
- Alert if P95 >3s for 3 consecutive days.

## Edge Cases
- No matching rows → return header-only CSV.
- Rate limit hit → return clear retry-after message.
- Over limit → instruct user to narrow date or email filter.

## Risks
- Performance degradation if run on primary DB.
- Memory spike if whole CSV buffered in memory.
- Abuse via repeated wide exports.

## Open Questions
1. Exact event types in scope? (login, password reset, etc.)
2. Is 7-day window configurable per environment?
3. Need masking for any sensitive columns?
4. Should we paginate instead of rejecting when exceeding limit?

## Follow-Up (Post-MVP)
- Scheduled weekly export
- JSON / NDJSON variant
- Multi-tenant scoping filter

ADR Example

# Architecture Decision Record: Incremental Cursor-Based Exports
Date: 2025-09-22
Status: Accepted (MVP implementation pending)

## Context
Activity events table ~20M rows, growing ~1.2M / month. Export feature (see PRD) requires P95 ≤3s for typical admin exports (≤10k recent rows). Full table scans already exceed 3s on staging benchmarks.

## Decision
Adopt incremental cursor-based export (store last exported high-water mark per admin request + bounded window) instead of ad-hoc full scans each time.

## Alternatives Considered
1. Full Scan + Filter per Request – Simple, but >3s now and grows unbounded with table size.
2. Cached Daily Snapshot – Fast reads but introduces staleness (up to 24h) and added storage + invalidation complexity.
3. Streaming Query with Client-Side Throttle – Would still traverse large cold ranges; operational complexity not justified.

## Consequences
Positive:
- Predictable latency (bounded delta set)
- Low I/O vs full historical traversal
- Natural hook for future incremental scheduling
Negative / Risks:
- Cursor invalidation if retention window changes
- Need to handle deleted/rewritten rows gracefully
- Slight state management overhead (persistent cursor store)

## Verification / Metrics
- Benchmark: Export 5k & 10k recent rows P95 < 2s in staging.
- Alert if cursor lag (oldest un-exported record age) > 2h.
- Log: cursor_start_ts, cursor_end_ts, row_count, duration_ms.

## Rollback Plan
Fallback to on-demand filtered scan (limited to 25k rows) if cursor logic fails or produces gaps (feature flag controlled).

## Follow-Up
- Reassess approach when row volume > 40M or retention policy changes.
- Evaluate adding snapshot compression if daily export adoption spikes.

## Notes
No PII expansion introduced; security posture unchanged.

## Glossary (Quick)
- P95 (95th Percentile Latency): 95% of measured requests finish at or below this time; focuses on near-worst typical performance rather than average.
- PII (Personally Identifiable Information): Data that can identify a person (e.g., email, name, IP when combined). Mentioned here to confirm the decision does not expand exposure surface.

Aktualizowanie bez bólu

Traktuj dokumentację tak jak kod:

  • Małe zmiany / commity (“docs: refresh env var section after cache layer change”)
  • Linkuj zmiany → PRD / decision records
  • Okresowe sprawdzenie pod kątem starych treści: “Which sections reference removed modules / outdated metrics?”
  • Preferuj małe przyrostowe poprawki zamiast pełnego przepisywania

Verification Prompts

  • “Compare this README update to the diff: any claims not traceable to code?”
  • “List 5 failure modes not covered in this PRD; mark which need monitoring.”
  • “Which metrics might be vanity vs actionable?”

Anti‑Rot Checklist (szybka lista)

  • PRD ma jawne Success Metrics + Open Questions
  • Ostatni diff przejrzany pod kątem zmian w doc
  • Każda istotna decyzja złapana (decision record / ADR)
  • Usunięto sekcje przestarzałe zamiast tylko dopisywać
  • Każdy artefakt < 5 min czytania (albo split)

Codzienna mikro‑praktyka

Wybierz jedną zaległą sekcję. Podaj diff + fragment AI. Poproś o minimalny update. Przejrzyj, przytnij, commit. Max 10 minut. Cotygodniowo → żywe repo.

Hands‑On Challenge

W mniej niż 60 minut:

  1. Draft PRD skeleton.
  2. Dodaj realne constraints & success metrics (nawet jako TBD).
  3. Odśwież jedną starą sekcję README via diff prompt.
  4. Utwórz jeden decision record.
  5. Commit: docs: bootstrap discovery layer.

Call To Action

Uruchom tę pętlę. Policz ile luk (gaps) wykryło AI vs Ty. Ustal 10‑min tygodniowy przegląd pod kątem starzenia się dokumentacji - w przyszłości ustaw pod do CI.

Zapisz najbardziej zaskakujące przestarzałe założenie – to dowód, że proces działa.

“Fresh docs → sharper AI → faster you.”


Ten wpis był pomocny? Postaw mi kawę, abym miał energię do tworzenia kolejnych treści.

Postaw mi kawę