v1.10 · /sdd trace

Machine-verifiable traceability — Intent ↔ SPEC ↔ Code ↔ Tests

Since v1.10, the Drift Lock is no longer only a human ritual: it is measured algorithmically. Four annotations in the code, a matrix generated by npx aiad-sdd trace, and a GitHub Action that blocks any PR with a gap — the Intent ↔ SPEC ↔ Code ↔ Tests chain becomes verifiable by a machine.

From human ritual to algorithmic measurement

The Drift Lock already required code and SPEC to be synchronised in the same PR — but that check rested on the rigour of the Product Engineer. Machine-verifiable traceability makes it objectifiable: every application code file declares the SPEC it serves, every SPEC points to its parent Intent, every test covers an identified SPEC. A missing annotation is not a cosmetic detail — it is a latent drift that gets detected at commit time, not in production.

The four annotations

The 4 machine-verifiable annotations
TagFormatCardinality
@intentINTENT-NNN0..1
@specSPEC-NNN-N-slug1..n — mandatory on all application code
@verified-byrelative path to a test0..n
@governanceAIAD-RGPD,AIAD-AI-ACT,…0..1

The canonical example in JSDoc:

/**
 * @intent INTENT-042
 * @spec SPEC-042-1-flow-auth
 * @verified-by tests/auth/oidc.test.ts
 * @governance AIAD-RGPD
 */

Annotations are accepted in JSDoc, in // and # comments, and in Python docstrings """…""" — the scanner is language-agnostic. Only @spec is mandatory: 100% of application code files must carry at least one (pure infrastructure files can be explicitly whitelisted). A test can be linked to a SPEC through either of two mechanisms: an @spec annotation on the test side, or a @verified-by on the code side.

Generating the matrix: npx aiad-sdd trace

npx aiad-sdd trace                  # Markdown + JSON + HTML in .aiad/metrics/traceability/
npx aiad-sdd trace --json           # Raw JSON on stdout (CI)
npx aiad-sdd trace --fail-on-gap    # Exit 1 if a blocking gap is detected (CI)

The scan cross-references the code annotations with .aiad/intents/ and .aiad/specs/ and produces two matrices. The Forward matrix (Intent → SPEC → Code → Tests, one row per SPEC) verifies that every validated intent is implemented and tested. The Backward matrix (Tests → Code → SPEC → Intent, one row per test) flushes out tests without a parent SPEC — which either get annotated, or have their nature documented (exploratory, benchmark). Each snapshot is persisted in .aiad/metrics/traceability/, which makes it possible to measure adoption over time.

The three families of gaps

Classification of traceability gaps
FamilyGapDefault severity
OrphanIntent with no linked SPECHigh
SPEC referenced by the code but absent from .aiad/specs/Blocking
Intent referenced by the code but absent from .aiad/intents/Blocking
Unimplementedready/in-progress/done SPEC with no annotated code at allBlocking
UntracedApplication code without @specMedium (depending on scope)
Annotated code with no test at allHigh

When the scan cannot conclude — unreadable file, annotation pointing to a non-existent SPEC, corrupted index — the verdict is UNKNOWN, never a silent OK: that is the fail-closed JNSP policy, and --fail-on-gap treats UNKNOWN as a GAP.

The sdd-trace.yml GitHub Action

Blocking in PR

The GitHub Action .github/workflows/sdd-trace.yml invokes aiad-sdd trace --fail-on-gap on every pull request. A blocking gap — phantom SPEC, phantom Intent, validated SPEC with no code — fails the pipeline. Drift does not get merged.

Remediation is always actionable: Intent without a SPEC → /sdd spec or archive the Intent; validated SPEC without code → implement (and annotate) or move the SPEC back to draft; orphan code → create the missing SPEC or fix the ID; annotated code without a test → add a test annotated with @spec or a @verified-by.

The traceability skill

The logic is carried by the traceability skill, invoked by /sdd trace, /sdd drift-check, /sdd validate, /sdd audit and the pre-commit hook — in addition to the GitHub Action. The drift-detection skill composes it without duplicating its logic: a gap detected by the matrix fails the drift-check. It is the culmination of SDD Mode's skill composition: a single annotation convention, read everywhere, from the editor to the CI.

Beyond drift control, this trace is a piece of evidence: it links every line of code to an identified human intent and to a delegated scope. See the trace as evidence on the Agent autonomy page.