The Cloud Security Alliance published a research note this month with a number that should make every engineering manager uncomfortable: 81% of organizations surveyed had no complete visibility into where AI-generated code lives in their production systems.
Not "limited visibility." Complete absence.
Every one of those teams uses Copilot, Cursor, Claude Code, or one of a dozen other AI coding tools. Code is being generated at speed. It's landing in commits, getting merged, and running in production. But the teams cannot answer a basic audit question: which lines in src/routes/auth.py were written by an AI?
This is not a hypothetical governance problem. It's a production security problem.
Why git blame doesn't solve this
git blame returns a username and a commit SHA. It was designed to answer "who wrote this line" in a world where humans wrote all code.
AI coding tools broke that assumption without replacing the tooling. When a developer accepts a Copilot suggestion, the commit author is the developer. When Claude Code generates a 60-line authentication function in an agentic session, the commit author is still the developer. The AI is invisible in the commit history.
The provenance metadata -- which model, which prompt, what the AI was asked to do -- exists for exactly one window: the moment of generation. The AI tool has it. The moment the developer moves on, it's gone. Commit by commit, sprint by sprint, that metadata accumulates into an unattributed window that grows backward through your git history.
What March 2026 showed us
Georgia Tech's Vibe Security Radar tracked 35 CVEs in March 2026 alone that were directly attributable to AI-generated code. Researchers estimate the true count is 5 to 10 times higher, because most vulnerabilities are never traced back to an AI tool -- you need the generation record to do that, and almost no team has one.
Separately, Pillar Security disclosed a "Rules File Backdoor" class of attack: hidden unicode characters in Cursor .cursorrules files and Copilot config files that silently steer the model to inject malicious code during generation. The generated code looks normal. The review sees nothing unusual. The AI did exactly what it was secretly instructed to do.
If you can't distinguish AI-generated lines from human-written lines, you can't contain this attack class. The blast radius is "everything an AI tool touched" -- and without provenance records, you don't know what that is.
How LineageLens closes the gap
LineageLens sits as a proxy between your AI coding tool and the upstream model API. Every edit event -- tool_use blocks from Claude, apply_patch DSL from Codex CLI, functionCall from Gemini -- gets captured as a provenance record with model, prompt, file path, timestamp, risk category, and a confidence score.
Those records get mapped back onto current file contents by the blame engine. The matching algorithm is whitespace-normalized contiguous block matching (newest record wins, exactly like git blame), with a fuzzy per-line fallback for blocks that were edited after insertion.
The output for a single file:
-- lineagelens blame - src/routes/auth.py
AI claude-opus-4-8 2026-06-10 42 | def authenticate_user(token: str):
AI claude-opus-4-8 2026-06-10 43 | payload = jwt.decode(token, SECRET, algorithms=["HS256"])
AI? claude-opus-4-8 2026-06-10 44 | return db.query(User).filter_by(id=payload["sub"]).first()
45 |
46 | def logout(session_id: str):
AI means exact contiguous match (high confidence). AI? means the line was in the original AI insertion but has been edited since. Lines with no marker are attributed to human authorship.
For a whole repository, the Risk Discovery command is one line:
lineagelens report . \
--url https://lineagelens.internal \
--token "$JWT" \
--workspace my-team \
--review-status unreviewed \
--category auth
This walks every non-binary file in the repo, matches live content against provenance records, filters to records with no associated human review, and filters further to the auth risk category. The output is a ranked table: which files have the most unreviewed AI-generated auth code, right now, in the live tree.
-- lineagelens report - my-repo -- filter: unreviewed, auth
src/routes/auth.py ████████████████░░░░ 80.5% 53/66 lines
src/middleware/jwt.py ██████████░░░░░░░░░░ 51.2% 23/45 lines
src/utils/tokens.py ████░░░░░░░░░░░░░░░░ 18.3% 9/49 lines
Repo total: 85/160 lines AI-attributed (53.1%) across 3 of 89 scanned -- filter: unreviewed, auth
The "currently running" half is verified by the blame engine running against live file contents, not git history. The "never reviewed" half is the reviewStatus filter against the provenance record store.
The --json flag for CI
Scriptable output with --json:
PERCENT=$(lineagelens --json report . \
--review-status unreviewed --category auth | jq '.stats.percent')
if (( $(echo "$PERCENT > 50" | bc -l) )); then
echo "::error::Repo has ${PERCENT}% unreviewed AI auth code -- block merge"
exit 1
fi
The install path
The CLI works on every tier, including the Base tier (free VS Code extension, no backend required). For the --review-status and --category filters, you need backend mode.
pip install lineagelens-cli
# Base mode: export from the VS Code extension first
lineagelens report . --input captures.json
# Backend mode: Risk Discovery with filters
lineagelens report . \
--url https://your-lineagelens-instance \
--token "$JWT" \
--workspace your-workspace \
--review-status unreviewed \
--category auth
The practical question
81% of teams don't have this answer. Most won't know until an incident forces the archaeology. The archaeology is slow, incomplete, and almost always comes back inconclusive -- because the generation records are gone.
If a CVE was traced to an AI-generated line in your auth path tomorrow, how would you reconstruct what was generated, by which model, with what prompt context, and whether any human reviewed it before it shipped? If the answer is "we'd look at git blame and the PR comments," you're working with evidence that was never designed to answer that question.
Star us on GitHub: github.com/lineagelens
Try the CLI: pip install lineagelens-cli
More on the architecture: lineage-website.vercel.app
What's the highest-risk unreviewed AI code you've found in your own codebase? Auth paths, payment handlers, or something weirder -- drop it in the comments.
Top comments (0)