Diff review (intent verification):
Before running gate or tests, verify the diff matches the intent. This catches cases where the code change is structurally valid but doesn't match what was planned.
Collect the context:
git diff --cached --stat
git diff --cached
Load the gauntlet entry for this target (from gauntlet.ndjson) and the sync plan entry (from sync.json → executionOrder.find(e => e.phase === currentPhase)).
Check all of the following:
D1. Scope — only planned files touched:
Compare staged file paths against sync.json → executionOrder.find(e => e.phase === currentPhase).targets and their known file paths (from gauntlet entries). Flag any file NOT associated with the current target or phase.
- File in a completely different domain → DIFF FAIL
- File is a direct dependency of the target (consumer or import) → OK (expected ripple)
- Test file for the target → OK
D2. Intent match — diff aligns with gauntlet recommendation:
First, check if this target is a dead-code target (present in titan-state.json → roles.deadSymbols). If so, the expected recommendation is "remove dead code" — skip gauntlet entry lookup (dead-code targets have no gauntlet.ndjson entry) and verify the diff shows only deletions (no new functions or logic added). If the diff contains non-trivial additions for a dead-code target → DIFF FAIL.
Otherwise, read the gauntlet entry's recommendation field and violations list. Verify the diff addresses them:
- If recommendation says "split" → diff should show new functions extracted, original simplified
- If recommendation says "remove dead code" → diff should show deletions, not additions
- If violation was "complexity > threshold" → diff should reduce complexity, not just move code around
- If the diff does something entirely different from the recommendation → DIFF FAIL
D3. Commit message accuracy:
Compare the planned commit message from sync.json against what the diff actually does.
- Message says "remove dead code" but diff adds new functions → DIFF WARN
- Message says "extract X from Y" but diff only modifies Y without creating X → DIFF FAIL
D4. Deletion audit:
If the diff deletes code (lines removed > 10), identify deleted symbols by comparing the pre-change file against removed lines:
D4_PRE_EXT="${changed_file##*.}"
D4_PRE_TMP=$(mktemp "/tmp/titan-d4-pre-XXXXXX.${D4_PRE_EXT}")
git show HEAD:<changed-file> > "$D4_PRE_TMP"
codegraph where --file "$D4_PRE_TMP" -T --json 2>/dev/null
rm -f "$D4_PRE_TMP"
Cross-reference with git diff --cached -- <changed-file> to find symbols whose definitions appear only in removed lines (lines starting with -). For each deleted symbol:
codegraph fn-impact <deleted-symbol> -T --json 2>/dev/null
If the deleted symbol has active callers not updated in this diff → DIFF FAIL: "Deleted still has callers not updated in this commit."
D5. Leftover check:
If the gauntlet recommendation mentioned specific symbols to remove/refactor, verify they were actually addressed:
- Dead symbols listed for removal but still present in the diff → DIFF WARN: "Gauntlet listed
<symbol> for removal but it was not deleted."
- Functions marked for decomposition but original is unchanged → DIFF WARN: "Gauntlet recommended decomposing
<symbol> but original function was not simplified."
- If all recommended symbols were addressed → DIFF PASS (implicit — no warnings emitted)
On DIFF FAIL:
git reset HEAD -- $(git diff --cached --name-only)
git checkout -- $(git diff --name-only)
Add to execution.failedTargets with reason starting with "diff-review: ". Continue to next target.
On DIFF WARN: Log the warning but proceed to gate. Include the warning in the gate-log entry.