Use when session-end potrzebuje sprawdzić retencję tematów narracyjnych (L2) z articulation bank, lub gdy Jakub prosi "zadaj mi pytania z banku", "sprawdź mnie z X tematów", "poćwiczmy retencję", "symulacja rozmowy", "dress rehearsal". Nie używaj dla tematów L3 (praktyczne checkpointy z roadmap) ani do wyjaśniania nowego konceptu (score 0).
Wybierasz pytania z articulation bank i prowadzisz quiz. To jest reużywalny komponent — wywoływany przez session-end (default 2 pytania) lub ad-hoc przez Jakuba ("2 pytania z banku", "5 pytań z M4 na dress rehearsal").
count=5 i zignoruj filtr due (dress rehearsal to symulacja pokrycia tematów, nie retencja)NIE używaj dla:
fullstack-roadmap.md — to weryfikuje się przez kod, nie quizRead na docs/articulation-bank.md. Pamiętaj strukturę wpisu:
### Topic name (Mx)
**Score:** X/5 | **Last tested:** YYYY-MM-DD | **Next review:** YYYY-MM-DD (interval: Nd)
Historia:
- YYYY-MM-DD (tag): X/5 — opis (Xd → Yd)
Do domknięcia:
- specific gap 1
Edge case: jeśli bank jest pusty lub ma <N due candidates → pomiń skill i zwróć: "Bank ma X due candidates — za mało na pełny articulation check. Sesja zostaje bez retention quizu.". Session-end loguje jako "Articulation check: N/A — insufficient due candidates".
Pomiń:
**Score:** 0, **Last tested:** never) — czekają na task briefing, nie quiznext_review > today) — są w środku cyklu spacing, nie ma sensu testować wcześniejZostają due candidates — każdy ma next_review ≤ today (czyli days_overdue ≥ 0).
days_overdue = today - next_review malejąco — najbardziej spóźnione pierwsze.
Tie-break: niższy grade pierwszy (słabsze tematy przed mocnymi przy tym samym overdue).
Nie ma już osobnego sortowania po score/milestone — formula SRS i days_overdue same dają zdrowe kolejkowanie.
Dress rehearsal override: gdy Jakub wyraźnie prosi o symulację rozmowy (args: "dress-rehearsal 5"), filter (not-due) jest wyłączony — wtedy kandydatami są wszystkie non-score-0 entries, posortowane pure grade ascending (słabe pierwsze, jak na prawdziwej rozmowie).
N default = 2 (session-end). Argument liczby nadpisuje.
N > |due candidates| → ogranicz do dostępnych. Powiedz Jakubowi: "Dostępnych X due pytań (mniej niż zapytano N) — lecę z X".Ten sam protokół dla każdego pytania:
Wyślij TYLKO pytanie, czekaj na odpowiedź. Pytanie musi być specyficzne i targetować "Do domknięcia" z banku. NIE generyczne pytania typu "wytłumacz X".
Format:
**Pytanie [1/N]:** [specyficzne pytanie targetujące braki]
_(z banku: [topic name] | score: X/5 | interval: Nd | overdue: Dd)_
Nie przerywaj, nie podpowiadaj przed odpowiedzią.
Patrz "Do domknięcia" w banku. Zadaj pytania pogłębiające:
Max 2 dopytania — więcej to scaffolding który zawyża grade.
Próg to ściśle <3.5. Grade = 3.5 → BEZ re-recall. Grade = 3.4 → re-recall.
"OK, powiedz mi to jeszcze raz uwzględniając to co pominąłeś."
Czekaj na pełną odpowiedź. Grade zostaje — re-recall wbudowuje feedback w encoding, nie zmienia oceny pierwszej produkcji (Roediger & Karpicke, 2006).
prev_interval = z pola "interval: Nd" w banku (0 jeśli pierwszy test)
days_elapsed = today - last_tested (0 jeśli pierwszy test)
base = max(prev_interval, days_elapsed)
IF grade ≤ 2:
new_interval = 1
ELIF grade == 3:
new_interval = max(3, round(base × 1.2))
ELIF grade >= 3.5 AND grade <= 4:
new_interval = max(5, round(base × 2.0))
ELIF grade >= 4.5:
new_interval = max(10, round(base × 2.5))
new_next_review = today + new_interval (w dniach)
Zaokrąglanie: zaokrąglij base × multiplier do najbliższego integera. round(7 × 2.0) = 14, round(5 × 1.2) = 6.
Pierwszy test (wpis świeżo utworzony w mid-session protokole z session-end, lub migracja entries bez poprzedniego intervalu): prev_interval = 0, days_elapsed = 0 → działają tylko minimum values (1/3/5/10).
L3 anchor (jeśli pole jest unknown)Sprawdź obecną wartość L3 anchor: we wpisie tematu. Jeśli unknown → klasyfikuj przed Edit'em banku:
src/path:N, użyj jej. Skip kroku 2.docs/sessions/*.md, grep nazwy tematu lub keywordów. Jeśli znajdziesz konkretny anchor → użyj.[topic name] jest gdzieś zaimplementowany w IRONLOG? Podaj ścieżkę (np. src/auth/auth.service.ts:45), albo none jeśli to czysta narracja bez kodu."none — zapisz L3 anchor: none. Temat narracyjny bez praktyki w kodzie (świadoma decyzja).Score ≥ 3.5 AND nowa wartość = none — to OK (narracja opanowana, bez problemu).Score ≥ 3.5 AND nowa wartość = unknown (Jakub nie wie) — to cargo cult retention risk. W summary kroku 6 dodaj rekomendację: BRIDGE NEEDED: [topic name] → dopisz (bridge) task w M<X>. Sam task pisze session-end (kroku 3a bridge writer), nie articulation-check. Anchor zostaje unknown do czasu gdy session-end napisze bridge task i Jakub go zaimplementuje.Skip tej sekcji gdy L3 anchor ma już konkretną ścieżkę albo none — klasyfikacja zrobiona wcześniej.
Sprawdź warunki notatki lapse przed zapisem linii historii:
prev_interval ≥ 20d AND grade ≤ 2 → dodaj suffix LAPSE po [prev_interval]d spacingprev_interval ≥ 20d AND days_overdue > prev_interval AND grade < 3 → dodaj suffix LAPSE po [days_overdue]d overdueNie ma żadnego efektu na formułę — to tylko oznaczenie w historii dla retrospektywy. Reset do intervalu 1d wynika z grade ≤ 2 w kroku 5.6.
Każde pytanie = jedno wywołanie Edit tool z wieloliniowym old_string → new_string. Atomic update — bank nigdy nie trafia w niespójny stan.
Wzorzec Edit:
old_string:
### [Topic name] (Mx)
**Score:** [OLD_SCORE]/5 | **Last tested:** [OLD_DATE] | **Next review:** [OLD_NEXT_REVIEW] (interval: [OLD_INTERVAL]d)
**L3 anchor:** [OLD_ANCHOR]
Historia:
- [pierwsza linia historii]
new_string:
### [Topic name] (Mx)
**Score:** [NEW_SCORE]/5 | **Last tested:** [TODAY] | **Next review:** [NEW_NEXT_REVIEW] (interval: [NEW_INTERVAL]d)
**L3 anchor:** [NEW_ANCHOR]
Historia:
- [TODAY] (articulation-check): [NEW_SCORE]/5 — [co trafne, co brakowało, 1 zdanie] ([OLD_INTERVAL]d → [NEW_INTERVAL]d)[optional lapse suffix]
- [pierwsza linia historii]
Unikalny ### [Topic name] (Mx) header + linia "Score" + linia "L3 anchor" + pierwsza linia historii dają jednoznaczny match. Edit aktualizuje Score/Last tested/Next review/interval/L3 anchor + dodaje linię historii w jednym call. Atomowe.
Migracja wpisu bez L3 anchor: — gdy old_string nie zawiera tej linii (stary wpis sprzed wprowadzenia pola), użyj wzorca bez linii L3 anchor w old_string i z linią L3 anchor w new_string. Pierwszy kontakt = lazy migration. [NEW_ANCHOR] wtedy pochodzi z kroku 5.7a.
Drugi Edit (opcjonalny) — update "Do domknięcia":
To jest intencjonalne: 3.5 = "solid mid+ answer" = gotowy do rozmowy.
Po ostatnim pytaniu — krótkie podsumowanie (max 5 linii):
**Articulation check — wyniki:**
- [Topic 1]: [NEW_GRADE]/5 (poprzednio [OLD_GRADE]) — interval [OLD_INT]d → [NEW_INT]d | anchor: [NEW_ANCHOR]
- [Topic 2]: [NEW_GRADE]/5 (poprzednio [OLD_GRADE]) — interval [OLD_INT]d → [NEW_INT]d | anchor: [NEW_ANCHOR]
Lapse notatki dzisiaj: [lista lub "brak"]
Nowe słabości (Do domknięcia added): [konkrety lub "brak"]
Bridge needed: [lista tematów ze score ≥3.5 i anchor unknown — session-end ma napisać bridge task w odpowiednim milestone, lub "brak"]
Session-end kopiuje to do session logu.
next_review ≤ today. Wszystko inne odpada naturalnie.5): 5 pytań zamiast 2M4): tylko tematy z danego milestone (dalej due only)JWT): tylko tematy zawierające frazę w nazwie5 M4): 5 pytań z M4dress-rehearsal: filtr due off, priority pure grade ascending (symulacja rozmowy)fullstack-roadmap.md — to robi session-end dla L3 checkpointów