adk-doc-audit 0.2.1

Documentation audit system for ADK-Rust that validates documentation against actual crate implementations
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
# adk-doc-audit

Documentation audit system for ADK-Rust that validates documentation against actual crate implementations.

## Overview

The `adk-doc-audit` crate provides a comprehensive system for ensuring that ADK-Rust's documentation stays accurate and up-to-date with the actual crate implementations. It performs static analysis of documentation files, validates code examples, and cross-references API signatures with actual implementations.

## Features

- **API Reference Validation**: Ensures all API references in documentation match actual implementations
- **Code Example Compilation**: Validates that code examples compile with current crate versions  
- **Version Consistency Checking**: Verifies version references are current and consistent
- **Cross-Reference Validation**: Validates internal links and references
- **Missing Feature Detection**: Identifies features that exist in code but are missing from documentation
- **Automated Suggestions**: Provides fix suggestions for identified issues
- **Comprehensive Reporting**: Generates detailed audit reports in multiple formats (Console, JSON, Markdown)
- **CI/CD Integration**: Supports integration with build pipelines with appropriate exit codes
- **Incremental Auditing**: Process only changed files for efficient CI/CD workflows

## Installation

Add to your `Cargo.toml`:

```toml
[dependencies]
adk-doc-audit = { git = "https://github.com/zavora-ai/adk-rust" }
```

Or use the main ADK-Rust crate with the `doc-audit` feature:

```toml
[dependencies]
adk-rust = { git = "https://github.com/zavora-ai/adk-rust", features = ["doc-audit"] }
```

## Quick Start

### Basic Usage

```rust
use adk_doc_audit::{AuditConfig, AuditOrchestrator, OutputFormat};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = AuditConfig::builder()
        .workspace_path(".")
        .docs_path("docs/official_docs")
        .output_format(OutputFormat::Console)
        .build();
    
    let orchestrator = AuditOrchestrator::new(config)?;
    let report = orchestrator.run_full_audit().await?;
    
    println!("Audit Results:");
    println!("  Total files: {}", report.summary.total_files);
    println!("  Files with issues: {}", report.summary.files_with_issues);
    println!("  Total issues: {}", report.summary.total_issues);
    println!("  Critical issues: {}", report.summary.critical_issues);
    println!("  Coverage: {:.1}%", report.summary.coverage_percentage);
    
    // Exit with error code if critical issues found
    if report.summary.critical_issues > 0 {
        std::process::exit(1);
    }
    
    Ok(())
}
```

### Single File Validation

```rust
use adk_doc_audit::{AuditConfig, AuditOrchestrator};
use std::path::Path;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = AuditConfig::builder()
        .workspace_path(".")
        .docs_path("docs")
        .build();
    
    let orchestrator = AuditOrchestrator::new(config)?;
    let result = orchestrator.validate_file(Path::new("docs/getting-started.md")).await?;
    
    for issue in &result.issues {
        println!("{:?}: {}", issue.severity, issue.message);
        if let Some(suggestion) = &issue.suggestion {
            println!("  Suggestion: {}", suggestion);
        }
    }
    
    Ok(())
}
```

### Incremental Audit

```rust
use adk_doc_audit::{AuditConfig, AuditOrchestrator};
use std::path::PathBuf;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = AuditConfig::builder()
        .workspace_path(".")
        .docs_path("docs")
        .build();
    
    let orchestrator = AuditOrchestrator::new(config)?;
    
    // Only audit changed files (useful for CI/CD)
    let changed_files = vec![
        PathBuf::from("docs/api-reference.md"),
        PathBuf::from("docs/examples.md"),
    ];
    
    let report = orchestrator.run_incremental_audit(&changed_files).await?;
    
    println!("Incremental audit complete: {} issues in {} files", 
             report.summary.total_issues, changed_files.len());
    
    Ok(())
}
```

## CLI Usage

The crate provides a command-line interface for easy integration with development workflows:

### Full Audit

Run a complete audit of all documentation:

```bash
# Basic audit with console output
adk-doc-audit audit --workspace . --docs docs/official_docs

# Generate JSON report for programmatic consumption
adk-doc-audit audit --workspace . --docs docs/official_docs --format json > audit-report.json

# Generate Markdown report for documentation
adk-doc-audit audit --workspace . --docs docs/official_docs --format markdown > audit-report.md
```

### Incremental Audit

Audit only specific files (useful for CI/CD when you know which files changed):

```bash
adk-doc-audit incremental --workspace . --docs docs/official_docs --changed file1.md file2.md
```

### Single File Validation

Validate a specific documentation file:

```bash
adk-doc-audit validate docs/official_docs/getting-started.md
```

### Configuration File

Create a `.adk-doc-audit.toml` configuration file:

```toml
workspace_path = "."
docs_path = "docs/official_docs"
output_format = "console"

# Files to exclude from auditing
excluded_files = [
    "docs/internal/*",
    "docs/drafts/*"
]

# Crates to exclude from analysis
excluded_crates = [
    "example-crate",
    "test-utils"
]

# Severity threshold for failing builds
severity_threshold = "warning"
fail_on_critical = true

# Timeout for code example compilation
example_timeout = "30s"
```

Then run without arguments:

```bash
adk-doc-audit audit
```

## Configuration

### AuditConfig Builder

```rust
use adk_doc_audit::{AuditConfig, OutputFormat, IssueSeverity};
use std::time::Duration;

let config = AuditConfig::builder()
    .workspace_path(".")
    .docs_path("docs/official_docs")
    .output_format(OutputFormat::Json)
    .excluded_files(vec!["docs/internal/*".to_string()])
    .excluded_crates(vec!["test-utils".to_string()])
    .severity_threshold(IssueSeverity::Warning)
    .fail_on_critical(true)
    .example_timeout(Duration::from_secs(30))
    .build();
```

### Configuration Options

| Option | Description | Default |
|--------|-------------|---------|
| `workspace_path` | Path to the Rust workspace root | `"."` |
| `docs_path` | Path to documentation directory | `"docs"` |
| `output_format` | Report format (Console, Json, Markdown) | `Console` |
| `excluded_files` | Glob patterns for files to exclude | `[]` |
| `excluded_crates` | Crate names to exclude from analysis | `[]` |
| `severity_threshold` | Minimum severity to report | `Info` |
| `fail_on_critical` | Exit with error on critical issues | `true` |
| `example_timeout` | Timeout for compiling examples | `30s` |

## Issue Types and Severity

### Issue Categories

- **ApiMismatch**: API references that don't match actual implementations
- **VersionInconsistency**: Version numbers that don't match workspace versions
- **CompilationError**: Code examples that fail to compile
- **BrokenLink**: Internal links that point to non-existent files
- **MissingDocumentation**: Public APIs not documented
- **DeprecatedApi**: References to deprecated APIs

### Severity Levels

- **Critical**: Issues that make documentation incorrect or unusable
- **Warning**: Issues that may confuse users but don't break functionality
- **Info**: Minor issues or suggestions for improvement

## CI/CD Integration

### GitHub Actions

```yaml
name: Documentation Audit
on: [push, pull_request]

jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions-rs/toolchain@v1
        with:
          toolchain: stable
      - name: Run documentation audit
        run: |
          cargo install --git https://github.com/zavora-ai/adk-rust adk-doc-audit
          adk-doc-audit audit --workspace . --docs docs --format json
```

### Exit Codes

- `0`: Audit passed (no critical issues)
- `1`: Audit failed (critical issues found or configuration error)

### Incremental CI/CD

For faster CI/CD, audit only changed files:

```bash
# Get changed files from git
CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD -- '*.md' | tr '\n' ' ')

if [ -n "$CHANGED_FILES" ]; then
    adk-doc-audit incremental --workspace . --docs docs --changed $CHANGED_FILES
else
    echo "No documentation files changed"
fi
```

## Integration with ADK-Rust Workflows

### Spec-Driven Development

The audit system integrates with ADK-Rust's spec-driven development workflow:

1. **Requirements Phase**: Validate that all requirements are documented
2. **Design Phase**: Ensure design documents reference valid APIs
3. **Implementation Phase**: Verify code examples compile with new implementations
4. **Testing Phase**: Validate that property tests are documented

### Hook Integration

Set up automatic audits when crates are updated:

```rust
use adk_doc_audit::{AuditOrchestrator, AuditConfig};

// Register hook for crate updates
let config = AuditConfig::builder()
    .workspace_path(".")
    .docs_path("docs")
    .build();

let orchestrator = AuditOrchestrator::new(config)?;

// This would be called by the hook system when a crate is updated
orchestrator.register_hook("crate_updated", |crate_name| async move {
    println!("Running audit after {} was updated", crate_name);
    // Run incremental audit on affected documentation
});
```

## Report Formats

### Console Output

Human-readable output with colored indicators:

```
=== Documentation Audit Report ===
📊 Summary:
  Total files: 15
  Files with issues: 3
  Total issues: 7
  Critical: 2, Warning: 3, Info: 2
  Coverage: 87.5%

❌ docs/api-reference.md:42
   [Critical] API reference 'GeminiModel::new_with_config' not found in crate
   💡 Suggestion: Use 'GeminiModel::with_config' instead

⚠️  docs/examples.md:15
   [Warning] Version reference '0.1.8' doesn't match workspace version '0.2.0'
   💡 Suggestion: Update to version '0.2.0'
```

### JSON Output

Machine-readable format for integration:

```json
{
  "summary": {
    "total_files": 15,
    "files_with_issues": 3,
    "total_issues": 7,
    "critical_issues": 2,
    "warning_issues": 3,
    "info_issues": 2,
    "coverage_percentage": 87.5
  },
  "issues": [
    {
      "file_path": "docs/api-reference.md",
      "line_number": 42,
      "severity": "Critical",
      "category": "ApiMismatch",
      "message": "API reference 'GeminiModel::new_with_config' not found in crate",
      "suggestion": "Use 'GeminiModel::with_config' instead"
    }
  ],
  "timestamp": "2024-01-15T10:30:00Z"
}
```

### Markdown Output

Documentation-friendly format:

```markdown
# Documentation Audit Report

Generated: 2024-01-15 10:30:00 UTC

## Summary

- **Total files**: 15
- **Files with issues**: 3  
- **Total issues**: 7
- **Critical issues**: 2
- **Coverage**: 87.5%

## Issues by File

### docs/api-reference.md

#### ❌ Line 42 - Critical
**API reference 'GeminiModel::new_with_config' not found in crate**
- Category: ApiMismatch
- Suggestion: Use 'GeminiModel::with_config' instead
```

## Advanced Usage

### Custom Validators

Extend the audit system with custom validation logic:

```rust
use adk_doc_audit::{Validator, ValidationResult, CodeExample};
use async_trait::async_trait;

struct CustomValidator;

#[async_trait]
impl Validator for CustomValidator {
    async fn validate_example(&self, example: &CodeExample) -> ValidationResult {
        // Custom validation logic
        ValidationResult {
            success: true,
            errors: vec![],
            warnings: vec![],
            suggestions: vec!["Consider adding error handling".to_string()],
        }
    }
}

// Register custom validator
let mut orchestrator = AuditOrchestrator::new(config)?;
orchestrator.add_validator(Box::new(CustomValidator));
```

### Programmatic Report Processing

Process audit reports programmatically:

```rust
use adk_doc_audit::{AuditReport, IssueSeverity, IssueCategory};

fn process_report(report: &AuditReport) {
    // Filter critical API mismatches
    let critical_api_issues: Vec<_> = report.issues
        .iter()
        .filter(|issue| {
            matches!(issue.severity, IssueSeverity::Critical) &&
            matches!(issue.category, IssueCategory::ApiMismatch)
        })
        .collect();
    
    if !critical_api_issues.is_empty() {
        println!("Found {} critical API issues that need immediate attention:", 
                 critical_api_issues.len());
        
        for issue in critical_api_issues {
            println!("  - {}: {}", issue.file_path.display(), issue.message);
        }
    }
    
    // Generate metrics for tracking
    let metrics = serde_json::json!({
        "total_issues": report.summary.total_issues,
        "critical_issues": report.summary.critical_issues,
        "coverage": report.summary.coverage_percentage,
        "timestamp": report.timestamp
    });
    
    // Send to monitoring system, save to database, etc.
}
```

## Troubleshooting

### Common Issues

1. **"Workspace not found"**: Ensure the workspace path points to a directory with `Cargo.toml`
2. **"Documentation directory not found"**: Check that the docs path exists and contains markdown files
3. **"Compilation timeout"**: Increase `example_timeout` for complex examples
4. **"Permission denied"**: Ensure the process has read access to workspace and docs directories

### Debug Mode

Enable debug logging for troubleshooting:

```rust
use tracing_subscriber;

// Initialize debug logging
tracing_subscriber::fmt()
    .with_max_level(tracing::Level::DEBUG)
    .init();

// Run audit with debug output
let report = orchestrator.run_full_audit().await?;
```

### Performance Tuning

For large documentation sets:

```rust
let config = AuditConfig::builder()
    .workspace_path(".")
    .docs_path("docs")
    .example_timeout(Duration::from_secs(60))  // Increase timeout
    .excluded_files(vec![
        "docs/generated/*",  // Exclude auto-generated docs
        "docs/archive/*",    // Exclude archived content
    ])
    .build();
```

## Contributing

Contributions are welcome! Please see the [ADK-Rust contributing guide](https://github.com/zavora-ai/adk-rust/blob/main/CONTRIBUTING.md) for details.

### Adding New Validators

To add new validation capabilities:

1. Implement the `Validator` trait
2. Add configuration options if needed
3. Write property tests for the validator
4. Update documentation and examples

### Extending Report Formats

To add new report formats:

1. Implement the `ReportFormatter` trait
2. Add the format to the `OutputFormat` enum
3. Update CLI argument parsing
4. Add tests and documentation

## License

Licensed under the Apache License, Version 2.0. See [LICENSE](https://github.com/zavora-ai/adk-rust/blob/main/LICENSE) for details.