Agent AI zawsze powie »zaimplementowane« — dlaczego potrzebujesz macierzy trace
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.