ð code-annotation-patterns
Use when annotating code with structured metadata, tags, and markers for AI-assisted development workflows. Covers annotation formats, semantic tags, and integration with development tools.
Overview
Advanced patterns for annotating code with structured metadata that supports AI-assisted development workflows.
Annotation Categories
Technical Debt Markers
Structured annotations for tracking technical debt:
/**
* @ai-tech-debt
* @category: Architecture
* @severity: High
* @effort: 2-3 days
* @impact: Maintainability, Performance
*
* This service class has grown to 1500+ lines and violates Single
* Responsibility Principle. Should be split into:
* - UserAuthService (authentication logic)
* - UserProfileService (profile management)
* - UserPreferencesService (settings/preferences)
*
* Blocking new features: User role management (#234), SSO integration (#245)
*/
class UserService {
// Implementation...
}
Severity levels:
Critical: Security vulnerabilities, data loss risksHigh: Significant maintainability or performance issuesMedium: Code quality concerns, testing gapsLow: Minor improvements, nice-to-haves
Security Annotations
# @ai-security
# @risk-level: High
# @cwe: CWE-89 (SQL Injection)
# @mitigation: Use parameterized queries
#
# SECURITY WARNING: This function constructs SQL queries dynamically.
# Although input is validated, parameterized queries would be safer.
# Current validation regex: ^[a-zA-Z0-9_]+$
# TODO(ai/security): Migrate to SQLAlchemy ORM or use parameterized queries
def get_user_by_username(username: str):
# Current implementation with string formatting
query = f"SELECT * FROM users WHERE username = '{username}'"
Performance Annotations
/**
* @ai-performance
* @complexity: O(n²)
* @bottleneck: true
* @profiling-data: 45% of request time when n > 100
* @optimization-target: O(n log n) or better
*
* This nested loop is the primary performance bottleneck for large
* datasets. Profiling shows:
* - n=10: 5ms avg
* - n=100: 120ms avg
* - n=1000: 11s avg (unacceptable)
*
* Optimization approaches:
* 1. Sort + binary search: O(n log n) - estimated 95% improvement
* 2. Hash map: O(n) - best performance but higher memory usage
* 3. Database-level optimization: Move logic to SQL query
*/
public List<Match> findMatches(List<Item> items) {
// O(n²) implementation
}
Accessibility Annotations
/**
* @ai-a11y
* @wcag-level: AA
* @compliance-status: Partial
* @issues:
* - Missing ARIA labels for icon buttons
* - Insufficient color contrast (3.2:1, needs 4.5:1)
* - Keyboard navigation incomplete
*
* Component needs accessibility improvements to meet WCAG 2.1 Level AA.
* Audit completed: 2025-12-04
* Blocking: Public sector deployment (requires AA compliance)
*/
export function SearchBar() {
// Implementation with partial a11y support
}
Testing Annotations
// @ai-testing
// @coverage: 45%
// @coverage-target: 80%
// @missing-tests:
// - Edge case: nil pointer handling
// - Edge case: Concurrent access scenarios
// - Integration: Database transaction rollback
//
// Test coverage is below target. Priority areas:
// 1. Error handling paths (currently untested)
// 2. Concurrent access (identified race condition in PR review)
// 3. Database edge cases (transaction boundaries)
func ProcessOrder(order *Order) error {
// Implementation with incomplete test coverage
}
Semantic Tags
Change Impact Tags
/**
* @ai-change-impact
* @breaking-change: true
* @affects:
* - API consumers (public method signature changed)
* - Database migrations (requires schema update)
* - Dependent services (contract modified)
*
* This change modifies the public API contract. Migration guide:
* 1. Update API clients to use new parameter format
* 2. Run migration script: ./scripts/migrate_v2_to_v3.sh
* 3. Update environment variables (NEW_API_KEY required)
*
* Backward compatibility: Supported until v4.0.0 (2026-06-01)
*/
Dependency Tags
# @ai-dependency
# @external-service: PaymentAPI
# @failure-mode: graceful-degradation
# @fallback: offline-payment-queue
# @sla: 99.9% uptime
# @timeout: 5000ms
#
# This function depends on external payment service. Failure handling:
# - Timeout: Queue for retry, notify user of delayed processing
# - Service down: Queue for batch processing, store transaction locally
# - Invalid response: Log error, rollback transaction, notify monitoring
#
# Circuit breaker: Opens after 5 consecutive failures, half-open after 30s
async def process_payment(transaction: Transaction) -> PaymentResult:
# Implementation with external service dependency
Configuration Tags
/// @ai-config
/// @env-vars:
/// - DATABASE_URL (required)
/// - REDIS_URL (optional, falls back to in-memory cache)
/// - LOG_LEVEL (optional, default: "info")
/// @config-file: config/production.yaml
/// @secrets:
/// - API_SECRET_KEY (must be 32+ chars)
/// - JWT_PRIVATE_KEY (RSA 2048-bit minimum)
///
/// Configuration loading order:
/// 1. Environment variables (highest priority)
/// 2. config/{environment}.yaml files
/// 3. Default values (lowest priority)
pub struct AppConfig {
// Configuration fields
}
Annotation Formats
Inline Annotations
For single-line or small context:
// @ai-pattern: Singleton
// @ai-thread-safety: Not thread-safe, use in single-threaded context only
const cache = createCache();
Block Annotations
For complex context:
"""
@ai-pattern: Factory Pattern
@ai-creational-pattern: true
@ai-rationale:
Factory pattern used here because:
1. Need to support multiple database backends (PostgreSQL, MySQL, SQLite)
2. Configuration determines which implementation to instantiate
3. Allows easy addition of new backends without modifying client code
@ai-extensibility:
To add new database backend:
1. Implement DatabaseBackend interface
2. Register in BACKEND_REGISTRY dict
3. Add configuration mapping in config/database.yaml
Example usage in docs/database-backends.md
"""
class DatabaseFactory:
# Implementation
Structured Metadata
/**
* @ai-metadata {
* "pattern": "Observer",
* "subscribers": ["LoggingService", "MetricsService", "AuditService"],
* "event-types": ["user.created", "user.updated", "user.deleted"],
* "async": true,
* "guaranteed-delivery": false
* }
*
* Event bus using observer pattern for loose coupling between services.
* Events are published async with fire-and-forget semantics (no delivery guarantee).
* For critical events requiring guaranteed delivery, use MessageQueue instead.
*/
class EventBus {
// Implementation
}
Language-Specific Patterns
TypeScript/JavaScript
/**
* @ai-hook-usage
* @react-hooks: [useState, useEffect, useCallback, useMemo]
* @dependencies: {useCallback: [data, filter], useMemo: [data], useEffect: [id]}
* @optimization: useMemo prevents expensive recalculation on re-renders
*
* This component uses React hooks for state and side effects. Dependency arrays
* are carefully managed to prevent unnecessary re-renders and infinite loops.
*
* @ai-performance-note:
* - useMemo caches filtered results (reduces filtering from O(n) per render to once per data change)
* - useCallback memoizes event handlers (prevents child re-renders)
*/
export function DataTable({ data, id }: Props) {
const [filter, setFilter] = useState('');
const handleFilter = useCallback((value: string) => {
setFilter(value);
}, [data, filter]); // @ai-dependency-note: Both needed for closure
const filteredData = useMemo(() => {
return data.filter(item => item.name.includes(filter));
}, [data]); // @ai-optimization: Only recompute when data changes
// Implementation...
}
Python
# @ai-decorator-stack
# @decorators: [retry, cache, log_execution, validate_auth]
# @execution-order: validate_auth -> log_execution -> cache -> retry -> function
#
# Decorator execution order matters:
# 1. validate_auth: Must run first to prevent unauthorized cache hits
# 2. log_execution: Log after auth but before cache to track all attempts
# 3. cache: After logging to avoid logging cache hits
# 4. retry: Innermost to retry actual function, not auth/logging
@validate_auth(roles=["admin", "operator"])
@log_execution(level="INFO")
@cache(ttl=300, key_func=lambda args: f"user:{args[0]}")
@retry(max_attempts=3, backoff=exponential)
def get_user_profile(user_id: int) -> UserProfile:
"""
@ai-caching-strategy: Time-based (TTL=300s)
@ai-invalidation: Manual invalidation on user.updated event
@ai-cache-key: user:{user_id}
"""
# Implementation
Go
// @ai-concurrency
// @pattern: Worker Pool
// @workers: 10 (configurable via WORKER_POOL_SIZE)
// @channel-buffer: 100
// @backpressure-handling: Blocks when buffer full
//
// This implements a worker pool pattern for concurrent processing.
// Workers are started at server initialization and kept alive for
// the server lifetime (no dynamic scaling).
//
// @ai-monitoring:
// - Metric: worker_pool_queue_depth (current channel buffer size)
// - Metric: worker_pool_processing_time (histogram)
// - Alert: Queue depth > 80 for >5min (add workers)
type WorkerPool struct {
workers int
jobQueue chan Job
resultCh chan Result
// fields...
}
Rust
/// @ai-lifetime-annotations
/// @lifetimes: ['a, 'b]
/// @invariants:
/// - 'a must outlive 'b (parser must live longer than input)
/// - Output references bound to 'a (safe as long as input lives)
///
/// Lifetime relationships:
/// - Parser<'a> borrows input for 'a
/// - Output<'a> contains references to input (bounded by 'a)
/// - Temporary allocations use 'b (scoped to parsing only)
///
/// @ai-safety:
/// These lifetime constraints prevent dangling references by ensuring
/// the input buffer outlives all references derived from it.
pub struct Parser<'a> {
input: &'a str,
// fields...
}
Integration with Tools
IDE Integration
Annotations can be extracted by IDE plugins:
# Extract all AI annotations
rg "@ai-\w+" --type ts --json | jq '.text'
# Find security-related annotations
rg "@ai-security" -A 10
# Find performance bottlenecks
rg "@bottleneck: true" --type java
Static Analysis
Custom linters can enforce annotation standards:
// Example: ESLint rule to enforce @ai-security on auth functions
module.exports = {
rules: {
'require-security-annotation': {
create(context) {
return {
FunctionDeclaration(node) {
if (node.id.name.includes('auth') || node.id.name.includes('Auth')) {
// Check for @ai-security annotation
}
}
};
}
}
}
};
Documentation Generation
Extract annotations to generate documentation:
# doc_generator.py
import re
from pathlib import Path
def extract_ai_annotations(file_path):
"""Extract all @ai-* annotations from file"""
with open(file_path) as f:
content = f.read()
pattern = r'@ai-(\w+):\s*(.+)'
return re.findall(pattern, content)
# Generate markdown documentation from annotations
Annotation Best Practices
Consistency
Use consistent annotation formats across codebase:
// â
GOOD - Consistent format
// @ai-pattern: Strategy
// @ai-alternatives: [Template Method, State Pattern]
// @ai-pattern: Observer
// @ai-alternatives: [Event Emitter, Pub/Sub]
// â BAD - Inconsistent format
// @ai-pattern: Strategy (alternatives: Template Method, State)
// Pattern: Observer | Alternatives: Event Emitter, Pub/Sub
Completeness
Include all relevant metadata:
# â
GOOD - Complete context
# @ai-security
# @risk-level: High
# @cwe: CWE-79 (XSS)
# @input-sanitization: HTML encoding applied
# @output-encoding: UTF-8
# @tested: XSS test suite in tests/security/xss_test.py
# â BAD - Incomplete
# @ai-security
# Security risk here
Maintainability
Keep annotations up-to-date:
// â
GOOD - Dated and tracked
// @ai-tech-debt
// @added: 2025-12-04
// @reviewed: 2025-12-04
// @next-review: 2026-01-04
// â BAD - Stale and outdated
// @ai-tech-debt
// TODO: Fix this eventually
Anti-Patterns
Don't
â Over-annotate obvious code
// @ai-pattern: Variable Declaration
const user = getUser(); // Bad - obvious
â Use annotations instead of fixing code
# @ai-tech-debt: This is terrible code
# @ai-security: Has vulnerabilities
# @ai-performance: Slow
# Bad - just fix the code!
â Inconsistent tag naming
// @AI-PATTERN vs @ai-pattern vs @aiPattern
// Use consistent naming
Do
â Annotate complex or non-obvious patterns
/// @ai-pattern: Typestate
/// @ai-compile-time-safety: true
///
/// Uses typestate pattern to enforce protocol state machine at compile time.
/// Impossible states are unrepresentable in type system.
â Provide actionable information
/**
* @ai-tech-debt
* @action: Extract UserValidator class
* @files-affected: [UserService.java, UserController.java, UserTest.java]
* @effort: 3-4 hours
* @priority: Medium
*/
â Link to external resources
# @ai-algorithm: Dijkstra's shortest path
# @reference: https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
# @paper: "A Note on Two Problems in Connexion with Graphs" (1959)
# @optimization: Using binary heap for O((V+E) log V) complexity
Related Skills
- notetaker-fundamentals
- documentation-linking