{"slug": "co-authored-by-copilot-is-not-an-audit-trail-here-s-what-one-actually-looks-like", "title": "\"Co-authored-by: Copilot\" Is Not an Audit Trail — Here's What One Actually Looks Like", "summary": "Microsoft faced backlash after VS Code 1.117 silently added 'Co-authored-by: Copilot' to all commit messages by default, even when AI had not generated code. The company reverted the change and apologized, but the incident exposed the inadequacy of git trailers for AI governance. A developer introduced LineageLens, a provenance schema that captures detailed AI code insertion metadata including timestamps, model parameters, prompts, and diff content.", "body_md": "In late April 2026, Microsoft shipped VS Code 1.117. Buried in the release was a change: the `github.copilot.chat.generateCommitMessage.addCoAuthoring`\n\nsetting was flipped from `off`\n\nto `all`\n\nby default. That meant \"Co-authored-by: Copilot [copilot@github.com](mailto:copilot@github.com)\" was now being appended to every commit message in the background — silently, without showing up in the commit message editor, and critically, without verifying that Copilot had generated any of the code.\n\nDevelopers noticed within days. The backlash was significant. VS Code 1.119 shipped May 3 with the default reverted and a consent requirement added. Microsoft apologized.\n\nThe technical fix was straightforward. The governance question it exposed is not.\n\nThe developer anger wasn't really about attribution credit. It was about consent and accuracy. The co-author trailer was added to commits where AI features were disabled. It was added when developers had manually written every line. It attributed work that wasn't done.\n\nBut underneath that anger is a more important problem: even when Copilot does write code, a \"Co-authored-by\" git trailer tells you almost nothing useful from a governance or security standpoint.\n\nIt tells you that a tool called Copilot existed somewhere in the developer's editor during some portion of the work that eventually became this commit. That's it.\n\nIt doesn't tell you which model generated which lines. It doesn't tell you what the developer prompted for. It doesn't contain the raw model response. It doesn't tell you whether any of the AI-generated lines touched authentication paths, hardcoded credentials, or SQL construction. It says nothing about when generation happened relative to the commit. It carries no risk score.\n\nIf you had to defend a specific commit in a security audit six months from now — \"which parts of this function were AI-generated, under what prompt, using what model?\" — a git trailer gets you nowhere.\n\nLineageLens captures provenance at insertion time, not commit time. Each AI code insertion generates a `ProviderAgnosticProvenanceEvent`\n\nstructured around schema version `lineagelens.provenance-event.v1`\n\n. Here is what that record contains:\n\n```\ntype ProviderAgnosticProvenanceEvent = {\n  schemaVersion: 'lineagelens.provenance-event.v1';\n  eventId: string;\n\n  timestamps: {\n    observedAtIso: string;         // when the extension saw the insertion\n    insertedAtIso: string;         // when the text hit the buffer\n    requestAtIso: string | null;   // when the proxy saw the outbound request\n    responseAtIso: string | null;  // when the model responded\n  };\n\n  source: {\n    ide: string | null;           // 'vscode'\n    shim: string;                 // which capture path fired\n    toolName: string | null;      // 'Edit', 'Write', 'apply_patch', etc.\n    provider: string | null;      // 'anthropic', 'openai', 'google'\n    adapterName: string | null;   // 'claude-code', 'copilot', 'cursor', etc.\n  };\n\n  capture: {\n    level: CaptureStatus;         // 'full' | 'metadata_only' | 'tunnel_only' | 'file_diff'\n    promptStatus: 'captured' | 'not-captured';\n    capabilities: ProvenanceEventCapability[];  // 10 named slots\n  };\n\n  model: {\n    name: unknown;\n    parameters: Record<string, unknown> | null;  // temperature, max_tokens, etc.\n  };\n\n  prompt: {\n    body: unknown;    // the full prompt messages array\n    system: unknown;  // the system prompt\n  };\n\n  diff: {\n    insertedText: string;\n    chunks: ProvenanceInsertedChunk[];\n    netAddedLines: number;\n  };\n\n  correlation: {\n    confidence: number;                     // 0.0–1.0\n    timingDifferenceMs: number | null;\n    contentSimilarityScore: number | null;\n    fileContextMatched: boolean;\n  };\n};\n```\n\nCompare that to what a git trailer gives you: a tool name and an email address.\n\nThe most important part of the schema is the `capture.capabilities`\n\narray. Every provenance event gets 10 named capability assessments:\n\n```\nprompt-body       — was the full prompt captured?\nresponse-body     — was the raw model response captured?\nheaders           — were the request headers available?\nrequest-id        — was a UUID present to link request to insertion?\nsession-id        — was there session context?\nmodel             — was the model name captured?\nuser-agent        — was the tool's user-agent available?\nfile-diff         — was the inserted diff captured? (always 'provided')\nfile-context      — did the file context match to the capture?\nworkspace         — was workspace context available?\n```\n\nEach entry carries a status: `provided`\n\n, `missing`\n\n, or `unknown`\n\n.\n\nThis matters because it tells you precisely what you know about a given insertion and what you don't. A record with `prompt-body: missing`\n\nand `promptStatus: 'not-captured'`\n\nis not the same as no record — it is an explicit declaration that the prompt gap exists. That gap is auditable. An audit trail with explicit gaps is categorically more useful than a label with no gaps declared.\n\nThe VS Code co-author trailer has no gap declarations. It has no granularity at all — it just has nothing.\n\nThe harder architectural point: by the time you are in a git commit, you have already lost the evidence.\n\nThe prompt body does not live anywhere post-generation. The model name was in the HTTP response header. The raw response body was discarded after the tool processed it. The timing data only exists in the milliseconds between request and file write.\n\nNone of that is in the commit. None of it can be recovered retroactively.\n\nLineageLens captures the `ProviderAgnosticProvenanceEvent`\n\nat the insertion event — before the diff even exists as a file change. The `observedAtIso`\n\ntimestamp records when the VS Code extension detected the text entering the buffer. The `requestAtIso`\n\nand `responseAtIso`\n\ntimestamps come from the proxy intercept that happened seconds or minutes before. By the time you type a commit message, the provenance record has already been stored.\n\nA git trailer is a retroactive label. Provenance is an evidence chain that exists before the label does.\n\nMicrosoft reverted the default. They added a consent gate. They clarified that `disableAIFeatures: true`\n\nnow also disables the co-authoring trailer.\n\nNone of that gives you a provenance record. You still do not know which lines in a given commit were AI-generated. You still cannot answer \"what did Copilot generate in auth.py last month\" from git history alone.\n\nThe incident forced consent around labeling. That is progress. It did not touch the underlying gap: labeling that something was AI-assisted is not the same as recording what the AI actually did.\n\nIf you are on a team shipping AI-generated code — and 84% of development teams are, per the 2026 Stack Overflow Developer Survey — you are almost certainly making three implicit assumptions:\n\nAll three assumptions are likely wrong for the same reason: commit-time labeling cannot carry insertion-time evidence.\n\nThe EU AI Act Articles 11 and 12 enforcement window opens in August 2026. The question \"which AI model generated this code, under what prompt, at what risk level?\" is going to become a routine compliance requirement.\n\nWhen it does, a git trailer is not going to be a defensible answer.\n\nLineageLens Base is a free VS Code extension that starts capturing provenance events at insertion time today, even without proxy infrastructure. Lite, Plus, and Max tiers add proxy capture for full prompt, model, and response-body fields. The full architecture details are at lineage-website.vercel.app. The Hashnode post goes deeper on schema design tradeoffs.\n\nOne question for the comments: **what data would your team actually need to survive a security audit of your AI-generated code?** Not in theory — what specific fields would an auditor ask for?", "url": "https://wpnews.pro/news/co-authored-by-copilot-is-not-an-audit-trail-here-s-what-one-actually-looks-like", "canonical_source": "https://dev.to/pn_28428886923dfc665/co-authored-by-copilot-is-not-an-audit-trail-heres-what-one-actually-looks-like-65a", "published_at": "2026-06-13 05:45:34+00:00", "updated_at": "2026-06-13 06:17:21.409836+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools", "ai-ethics", "ai-policy", "ai-products"], "entities": ["Microsoft", "VS Code", "Copilot", "GitHub", "LineageLens"], "alternates": {"html": "https://wpnews.pro/news/co-authored-by-copilot-is-not-an-audit-trail-here-s-what-one-actually-looks-like", "markdown": "https://wpnews.pro/news/co-authored-by-copilot-is-not-an-audit-trail-here-s-what-one-actually-looks-like.md", "text": "https://wpnews.pro/news/co-authored-by-copilot-is-not-an-audit-trail-here-s-what-one-actually-looks-like.txt", "jsonld": "https://wpnews.pro/news/co-authored-by-copilot-is-not-an-audit-trail-here-s-what-one-actually-looks-like.jsonld"}}