Wróć do listy wpisów

Agent AI zawsze powie »zaimplementowane« — dlaczego potrzebujesz macierzy trace

2026-10-26
Michał Sznurowski

Każdy inżynier pracujący z Claude Code, Cursorem czy Codexem zna ten moment: zadajesz złożone zadanie biznesowe, model przez kilka minut wykonuje kolejne polecenia, po czym melduje z pełnym przekonaniem:

„Zaimplementowano wszystkie wymagania. Cały moduł jest gotowy do wdrożenia produkcyjnego.”

Otwierasz kod i okazuje się, że kluczowy warunek brzegowy został pominięty, a testy jednostkowe sprawdzają jedynie trywialny przypadek true === true.


1. Skąd bierze się halucynacja ukończenia zadania?

Modele LLM są trenowane do bycia pomocnymi i konkluzywnymi. W wieloturowej sesji agent dąży do stanu końcowego. Jeżeli specyfikacja wymagała 5 kryteriów, a model zaimplementował 3, jego wewnętrzny mechanizm generowania odpowiedzi podsumuje zadanie jako zamknięte, ponieważ w oknie kontekstu pojawiły się słowa kluczowe odpowiadające specyfikacji.

Rozwiązaniem nie jest „lepszy prompt” ani pisanie w CLAUDE.md: „Bądź bardzo dokładny i niczego nie pomijaj”. Rozwiązaniem jest deterministyczna, maszynowa kontrola identyfikowalności (Traceability).


2. Rozwiązanie CDAL: Identyfikowalność wymaganie → test

W metodyce CDAL każde wymaganie biznesowe otrzymuje niezmienny identyfikator w kontrakcie (contracts/requirements.contract.mjs):

export default {
  requirements: [
    {
      id: 'AUTH-REQ-MFA',
      title: 'Wymuszenie drugiego składnika uwierzytelnienia dla ról uprzywilejowanych',
      status: 'ACCEPTED',
      criteria: [
        'Użytkownik z rolą ADMIN musi podać kod TOTP przy logowaniu',
        'Brak kodu TOTP blokuje wydanie tokena JWT z kodem 403',
      ],
    },
  ],
};

Rola test-author pisze test oznaczony jawnym tagiem:

// test/auth.test.ts
describe('MFA Enforcement', () => {
  // @REQ: AUTH-REQ-MFA
  it('odrzuca logowanie administratora bez ważnego tokena TOTP', async () => {
    const res = await login({ email: 'admin@corp.com', password: 'valid', totp: null });
    expect(res.status).toBe(403);
  });
});

3. Deterministyczna bramka: cdal trace --enforce

W procesie CI i przed każdym sczytaniem kodu do gałęzi głównej uruchamiana jest komenda:

npx cdalkit trace --enforce

Skaner sprawdza całe drzewo testów i porównuje je z rejestrem kontraktu. Jeżeli choć jedno wymaganie ze statusem ACCEPTED nie posiada powiązanego testu — proces kończy się kodem błędu 1 i blokuje merge PR.

Dopiero w tym momencie słowa agenta „zaimplementowane” zyskują matematyczny dowód.

Agent AI zawsze powie »zaimplementowane« — dlaczego potrzebujesz macierzy trace — CDAL Blog