# ADR-107: Staleness Auto-Recompile in Quality Gate

**Date:** 2026-03-15 | **Status:** ACCEPTED

## Context

After `graq learn`, the knowledge graph (graqle.json) is updated but the compiled intelligence
(`.graqle/intelligence/`) becomes stale. CLAUDE.md shows an old risk map. The pre-commit hook
(`graq verify`) verifies against outdated intelligence, potentially missing new modules/edges.

Users must manually run `graq compile` after every `graq learn`. This breaks the governance loop:
```
learn → graph grows → STALE intelligence → commit passes with outdated checks
```

## Decision

Add staleness detection to `graq verify` (Option B: lazy recompile at commit time).

**Mechanism:**
1. `graq verify` compares `mtime(graqle.json)` vs `mtime(.graqle/intelligence/module_index.json)`
2. If graph is newer than intelligence → auto-trigger `compile_intelligence(root, inject=True)`
3. Record the auto-recompile in `.graqle/learning_log.json` via `LearningTracker`
4. Continue with normal verification against freshly-compiled intelligence

**Why Option B over Option A (post-learn hook):**
- Zero overhead during rapid `graq learn` iterations (batch learning doesn't trigger N compiles)
- Only compiles when it matters (at commit time, when intelligence must be fresh)
- Pre-commit hook is already the enforcement point — natural extension

**Learning Tracker:**
Every learning event (node add, edge discovery, recompile) is logged to
`.graqle/learning_log.json` with domain classification. The Studio dashboard reads this
to show learning counts, skill activation stats, and recompile history.

## Implementation

- `graqle/intelligence/verify.py`: `_check_staleness_and_recompile()` added before verification
- `graqle/intelligence/learning_tracker.py`: `LearningTracker` class with event recording
- `graqle/studio/routes/learning.py`: 4 API endpoints for dashboard metrics
- Frontend: `/dashboard/learning` page with stats, domain bars, activation memory, event log

## Consequences

**Positive:**
- Governance loop is self-healing: learn → commit → auto-recompile → fresh CLAUDE.md
- Zero manual intervention required after `graq learn`
- Dashboard shows learning progress, creating engagement loop
- Recompile cost is amortized (only at commit time, not per-learn)

**Negative:**
- First commit after bulk learning is slower (full recompile: 3-10s)
- If compile fails, commit still proceeds (fail-open design)
- Learning log grows unbounded — capped at 200 events (rolling window)

**Trade-offs:**
- Fail-open on recompile failure: prioritizes developer velocity over perfect enforcement
- 200-event cap may lose old events — but recent history is most valuable for dashboard
