[withdrawn] A decorator to mark AI-assisted code

Withdrawn

This proposal has been withdrawn. After feedback from the community — I realize this is a workflow/process concern rather than something Python’s standard library should solve. The reviewed=False API in particular assumes an anti-pattern where unreviewed code could be merged, which doesn’t align with proper code review processes.

I’ve also come to agree that AI-generated code that passes review and tests should be treated the same as human-written code, with commit history serving as the audit trail. Decorators and metadata throughout the codebase add unnecessary friction without solving the core problem.

My sincere apologies for the noise. Thanks to everyone who took the time to engage with this — I genuinely appreciate it.

Proposal: An @ai_gen decorator to mark AI-assisted code (inspired by PEP 702)

Motivation

AI-assisted programming is becoming increasingly common. Python codebases now regularly contain code fully or partially generated by AI assistants. AI-generated code that has not been human-reviewed may produce unpredictable results, as the model may introduce logical flaws, security vulnerabilities, or — in the worst case — implement dangerous behaviors to satisfy the prompt at any cost, such as bypassing security controls or executing unsafe operations. Unlike human-written code, which follows the author’s intent and accountability, AI-generated code lacks an inherent understanding of the broader system context and security boundaries.

As AI-generated code becomes more prevalent, its proportion in a codebase may continue to grow. It is important to establish a clear distinction between human-written and AI-generated code before the project becomes too large. Such a distinction would help with:

  • Code reviewers knowing which functions require extra scrutiny
  • CI/CD pipelines identifying AI-generated code for targeted testing
  • Security/compliance teams tracking AI involvement in the codebase
  • Teams quantitatively managing AI code introduction and review progress

Just as @warnings.deprecated (PEP 702) provides a standardized way to mark deprecated functions, this proposal extends the same pattern to AI-generated code.

Proposal

Add a new decorator @ai_gen to the typing module, with one optional parameter:

  • reviewed: bool = False — whether the AI-generated code has been manually reviewed
from typing import ai_gen

# Case 1: AI-generated, not reviewed → IDE warns callers
@ai_gen()
def parse_user_input(data: str) -> dict:
    pass

# Case 2: AI-generated and human-reviewed → mark only, no warning
@ai_gen(reviewed=True)
def validate_email(email: str) -> bool:
    pass

Specification

IDE / type checker behavior:

  • @ai_gen() or @ai_gen(reviewed=False): IDEs SHOULD display a prominent warning when calling this function (e.g., orange squiggly line, hover tooltip: “This function is AI-generated and has not been reviewed — use with caution”)
  • @ai_gen(reviewed=True): IDEs SHOULD display a muted hint (e.g., a grey [AI] badge) but NOT trigger a warning

Runtime behavior:

  • No runtime warnings are emitted by default, consistent with the typing module’s lightweight tradition
  • The decorator SHOULD attach __ai_gen__ and __ai_gen_reviewed__ attributes to the decorated function for runtime introspection

Review Traceability and Code Evolution

Audit trail via Git:

  • When reviewed=False is changed to reviewed=True, git blame naturally records this change
  • The reviewer’s identity (commit author) and review time (commit timestamp) form a natural “review signature”
  • When other developers run git blame on that line, they can trace exactly who reviewed the function and when
  • No external tooling is required — the audit chain is built into Git itself

Code evolution path (from AI-generated to human-rewritten):

# Stage 1: AI-generated, unreviewed
@ai_gen()
def process_order(data: dict) -> Order:
    # AI generated implementation
    pass

# Stage 2: Human-reviewed, marked as reviewed
@ai_gen(reviewed=True)
def process_order(data: dict) -> Order:
    # AI generated implementation (reviewed, no changes needed)
    pass

# Stage 3: Human-rewritten, no longer AI code
def process_order(data: dict) -> Order:
    # Human-rewritten implementation, no longer AI code
    pass

When AI code is human-rewritten, simply remove the @ai_gen decorator:

  • The act of removing the decorator is itself recorded by git blame, forming a trace of who converted the function from AI code to human code, and when
  • The function is no longer marked as AI-generated, and callers receive no further hints
  • This removal is naturally tracked through Git history: git blame shows which developer deleted the decorator
  • The entire evolution path is traceable using Git’s existing mechanisms, requiring no additional tooling

Alternative Approaches Considered

Approach Problem
Docstring comment (# AI generated) Not discoverable by tooling; cannot be enforced automatically
Annotated (PEP 593) Suitable for type metadata, but @ai_gen is a function attribute. A dedicated decorator provides clearer semantics and requires less change to type checkers
No marking at all AI code becomes indistinguishable from human-written code; transparency is lost

Use Cases

1. Code review

Reviewers know which functions need extra attention for logic, security, and edge cases. Establishing this distinction early helps prevent AI code from becoming indistinguishable as the project scales.

2. CI pipeline enhancements

CI systems can identify @ai_gen markers and apply stricter testing strategies to these functions, such as:

  • Automatically requiring additional unit test coverage
  • Running more aggressive security scanning (SAST, vulnerability detection)
  • Performing extra performance benchmarking
  • Setting “AI review coverage” thresholds as quality gates (e.g., coverage ≥ 80% before merging)

3. Organizational metrics (AI Code Insights)

With @ai_gen as a standardized marker, we can build automated tooling to measure and track AI code quality at scale:

Two key metrics become possible:

Metric Definition Calculation
AI Code Rate AI-generated code as a percentage of total codebase Lines marked @ai_gen / Total code lines × 100%
AI Review Coverage Percentage of AI-generated code that has been human-reviewed Lines marked @ai_gen(reviewed=True) / Total @ai_gen lines × 100%

A static analysis tool (built with Python’s ast module) can scan the codebase and generate reports:

AI Code Metrics Report for project-x
─────────────────────────────────────
Total code lines (excluding blanks/comments): 12,847
AI-generated lines:                       3,421  (26.6%)
  └── Reviewed (reviewed=True):           2,189  (64.0%)
  └── Unreviewed (reviewed=False):        1,232  (36.0%)

Recommendation: 36% of AI code is unreviewed.
Consider prioritizing review for: module/auth.py, module/parser.py

Integration with existing tooling:

  • CI gate: Set thresholds (e.g., “AI review coverage must be ≥ 80%” before merging)
  • Codecov-style PR comments: Automatically post AI review coverage delta in PRs
  • Dashboards: Track trends over time, similar to test coverage dashboards

4. Compliance reporting

For teams in regulated industries (finance, healthcare, government), automated compliance reports can be generated:

Audit Report: AI Code Compliance — Q3 2026
───────────────────────────────────────────
Total AI-generated functions: 147
  └── Reviewed: 112 (76.2%)
  └── Unreviewed: 35 (23.8%)

Unreviewed AI functions by module:
  - payment_processor.py: 12 functions
  - data_migration.py: 8 functions
  - report_generator.py: 6 functions

5. Risk-aware consumption

Callers see the risk level directly in their IDE, enabling informed decisions.

Open Questions

  • Is @ai_gen the right name, or should it be @ai_generated?
  • Should this live in typing or a new submodule like typing.ai?
  • Should we support additional metadata (e.g., model name, generation timestamp), or leave that to docstrings?
  • Should reviewed=True completely silence warnings, or still show a muted hint? (I lean toward a muted hint for transparency)
  • Should the metrics tooling be part of the standard library or left to third-party tools? (My initial thought: leave to the ecosystem, but define clear semantics)

References

  • PEP 702 – Marking deprecations using the type system
  • PEP 593 – Flexible function and variable annotations
  • PEP 698 – @override decorator for typing
  • Codecov – test coverage measurement (as an analogy for AI review coverage)

I welcome all feedback and am happy to participate in further discussions and help draft a PEP if there’s interest. Thank you for reading!

3 Likes

I think the underlying goal of making AI involvement auditable and making sure unreviewed output gets extra scrutiny is reasonable, I’m just not sure that a decorator in typing is the right way to do it (or maybe even Python itself at all)

The comparison with PEP 702 only goes so far, since deprecation is something callers need to know about and act on, so warning at the call site makes sense, but AI involvement is usually a property of how an implementation was produced. A caller generally cannot do much about an unreviewed implementation (wheras moving off of deprecated code is an actionable, necessary step), while the author, reviewer, or CI system can, so the expectation is that warnings should appear on the definition, diff, or pull request, rather than every place the function is called

I also think “AI-generated” is harder to define than you may think. Does accepting one completion make the whole function AI-generated? What about one generated expression inside an otherwise human-written function? How much editing does it take before the code becomes “human-rewritten”? A lot of real LLM-assisted SWE work is mixed and incremental, so a function-level bool may turn a complex state into a binary one

The reviewed: bool flag is another understated value IMO, “reviewed” can mean literally anything from “I glanced at it” to a full security and correctness review, and it also only applies to a particular version of the code. If someone changes the function after setting reviewed=True, the marker can stay there unless they remember to update it

I also think the Git traceability claim is a little too strong, git blame tells you who last changed the lines that still exist, but it does not directly show that a decorator was removed, and even then, the person who committed the change is not necessarily the person who actually performed the review (e.g. squash merges)

AI tools seem to be handling this more at the version-control level. Claude Code can add attribution trailers to commits (“Co-authored by”), while GitHub Copilot’s coding agent authors and signs its own commits, links them back to the agent session, and still requires human review before merging. That feels like a better fit for provenance than native Python runtime metadata

In my view this should be third-party tooling rather than a standard-library feature. There may still be a case for a generic generated-code marker, but I do not think the proposal yet asserts why this belongs in typing, why callers should receive the warning, or how “AI-generated” and “reviewed” can be defined reliably enough for a standard core Python feature

2 Likes

Thanks for the thoughtful concerns — these are exactly the kind of issues I need to keep thinking through. I actually agree that this may not belong in the stdlib, at least not yet. I’ve started building this as a third-party library to experiment with the pattern in real projects and see how the semantics hold up in practice. Appreciate the feedback!

Use git-ai or similar.

3 Likes

Understood. I agree that AI-generated code, once it passes the same (or stricter) tests and is merged, should be treated the same as human-written code — there’s no need to permanently mark it in the source. The commit history already records who or what provided the code, which is sufficient for audit purposes. Introducing decorators and metadata throughout the codebase adds unnecessary friction. I appreciate everyone’s input — this proposal is now closed.

1 Like

If we merge unreviewed code, we failed badly the mandatory review process in our workflow. I always review a change before merging it, it doesn’t matter if it was partially or fully generated by AI. I will not skip the review just because AI was involved. So this reviewed=False API surprises me a lot.

So far, from what I was, AI is better than human to generate many tests to cover all code paths. Sometimes, I’m annoyed because AI generates many boring tests, but I suppose that it’s worth it :slight_smile:

2 Likes

withdrawn by author