diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..3da2005 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,9 @@ +# Agent Instructions + +Use `docs-cms/` as durable project memory. Read relevant ADRs, RFCs, PRDs, and memos before changing architecture, validation, schemas, templates, release process, or agent workflow guidance. + +Docuchango maintains its own `docs-cms/`. Product decisions and durable maintenance knowledge belong there. `examples/docs-cms/` is sample user content, not authoritative project memory. + +After docs-cms edits, run `docuchango validate` and summarize remaining manual issues. + +Do not mark agent-authored architectural decisions `Accepted` without explicit user approval. Use `Proposed` or a memo for inferred content. diff --git a/COVERAGE_ROADMAP.md b/COVERAGE_ROADMAP.md deleted file mode 100644 index 427eeac..0000000 --- a/COVERAGE_ROADMAP.md +++ /dev/null @@ -1,258 +0,0 @@ -# Test Coverage Improvement Roadmap - -**Current Coverage:** 49.53% (224 tests) -**Target Coverage:** 70%+ (350+ tests) -**Last Updated:** 2025-11-05 - -## Priority Ranking (Maximize ROI) - -### Tier 1: Quick Wins - Zero Coverage Modules (391 statements, ~20% coverage gain) -*Estimated effort: 2-3 hours | Impact: Very High | Difficulty: Low* - -These modules follow similar patterns to already-tested modules. Each should take ~15-20 minutes. - -| Priority | Module | Statements | Complexity | Estimated Tests | Notes | -|----------|--------|-----------|------------|-----------------|-------| -| **1** | `internal_links.py` | 83 (0%) | LOW | ~18 tests | Similar to broken_links.py pattern | -| **2** | `mdx_syntax.py` | 76 (0%) | MEDIUM | ~16 tests | Regex replacements, test edge cases | -| **3** | `doc_links.py` | 70 (0%) | LOW | ~15 tests | Link fixing, straightforward | -| **4** | `proto_imports.py` | 61 (0%) | MEDIUM | ~13 tests | Import statement fixes | -| **5** | `migration_syntax.py` | 51 (0%) | MEDIUM | ~12 tests | Syntax transformations | -| **6** | `mdx_code_blocks.py` | 50 (0%) | LOW | ~12 tests | Similar to code_blocks.py | - -**Subtotal Impact:** +391 statements covered → **~70% total coverage** - ---- - -### Tier 2: High-Value Improvements (409 statements, ~21% coverage gain) -*Estimated effort: 6-8 hours | Impact: Very High | Difficulty: Medium-High* - -| Priority | Module | Miss | Current | Target | Estimated Tests | Notes | -|----------|--------|------|---------|--------|-----------------|-------| -| **7** | `validator.py` | 409 | 48.10% | 75%+ | ~40 tests | **Biggest prize**: Core validation logic, complex workflows | - -**Key Areas to Test in validator.py:** -- Document scanning and parsing (lines 484-561) -- Link validation logic (lines 565-607) -- Error reporting and aggregation (lines 611-631) -- Formatting checks (lines 635-674) -- Build validation (lines 678-746) -- Integration scenarios (lines 1084-1196) - ---- - -### Tier 3: Incremental Improvements (139 statements, ~7% coverage gain) -*Estimated effort: 3-4 hours | Impact: Medium | Difficulty: Low-Medium* - -Polish existing coverage to 90%+ where practical. - -| Priority | Module | Miss | Current | Target | Estimated Tests | Focus Areas | -|----------|--------|------|---------|--------|-----------------|-------------| -| **8** | `docs.py` | 34 | 75.26% | 90%+ | ~10 tests | Main function, edge cases (lines 179-224) | -| **9** | `cli.py` | 42 | 76.82% | 85%+ | ~12 tests | Exception handling, import errors (lines 55-57, 86-88, 100-102) | -| **10** | `code_blocks.py` | 27 | 73.43% | 85%+ | ~8 tests | Main function logic (lines 134-170) | -| **11** | `broken_links.py` | 19 | 55.00% | 80%+ | ~8 tests | Main function (lines 77-102) | -| **12** | `code_blocks_proper.py` | 18 | 67.44% | 85%+ | ~6 tests | Main function (lines 78-99) | -| **13** | `cross_plugin_links.py` | 15 | 41.86% | 75%+ | ~8 tests | Main function (lines 38-57) | -| **14** | `schemas.py` | 9 | 92.53% | 95%+ | ~5 tests | Edge cases in validators | - ---- - -### Tier 4: Low Priority (11 statements, <1% coverage gain) -*Estimated effort: 1 hour | Impact: Low | Difficulty: Low* - -| Priority | Module | Miss | Current | Target | Notes | -|----------|--------|------|---------|--------|-------| -| **15** | `__init__.py` | 2 | 77.78% | 100% | ~2 tests | Import edge cases | - ---- - -## Implementation Strategy - -### Phase 1: Quick Wins (Week 1) -**Goal:** Reach 70% coverage - -1. Add tests for all Tier 1 modules (6 test files) -2. Use existing test patterns from similar modules -3. Focus on: - - Happy path coverage - - Common edge cases (empty files, Unicode, multiple matches) - - Dry-run modes - - Error handling - -**Expected Outcome:** 49.53% → ~70% coverage (+115 tests) - ---- - -### Phase 2: Validator Deep Dive (Week 2-3) -**Goal:** Reach 75% coverage - -1. Break validator.py into test suites: - - `test_validator_scanning.py` - Document discovery - - `test_validator_links.py` - Link validation - - `test_validator_formatting.py` - Format checks - - `test_validator_errors.py` - Error handling - - `test_validator_integration.py` - End-to-end scenarios - -2. Use property-based testing for complex scenarios -3. Create comprehensive validator fixtures - -**Expected Outcome:** 70% → ~75% coverage (+40 tests) - ---- - -### Phase 3: Polish (Week 4) -**Goal:** Reach 80% coverage - -1. Fill gaps in existing modules (Tier 3) -2. Add integration tests -3. Test main() functions that were skipped -4. Add edge case coverage - -**Expected Outcome:** 75% → 80%+ coverage (+30 tests) - ---- - -## Testing Techniques to Apply - -### 1. **Fixture Reuse** -- Leverage existing `conftest.py` generators -- Create module-specific fixtures for fix patterns - -### 2. **Parameterized Tests** -```python -@pytest.mark.parametrize("input,expected", [ - ("case1", "result1"), - ("case2", "result2"), -]) -def test_multiple_cases(input, expected): - assert fix(input) == expected -``` - -### 3. **Property-Based Testing** (for validator.py) -```python -from hypothesis import given, strategies as st - -@given(st.text()) -def test_validator_handles_any_markdown(content): - # Should not crash on any input - result = validate(content) - assert isinstance(result, ValidationResult) -``` - -### 4. **Golden Files** -- Store expected outputs for complex transformations -- Compare against known-good results - -### 5. **Mocking External Dependencies** -- Mock file system operations where appropriate -- Mock subprocess calls for build validation - ---- - -## Success Metrics - -| Milestone | Coverage | Tests | Timeline | -|-----------|----------|-------|----------| -| ✅ Baseline | 39.81% | 115 | Completed | -| ✅ Phase 0 | 49.53% | 224 | Completed | -| 🎯 Phase 1 | 70% | 330+ | Week 1 | -| 🎯 Phase 2 | 75% | 370+ | Week 2-3 | -| 🎯 Phase 3 | 80% | 400+ | Week 4 | -| 🌟 Stretch | 85%+ | 450+ | Week 5-6 | - ---- - -## Test Quality Checklist - -For each new test module, ensure: - -- ✅ Uses pytest fixtures from conftest.py -- ✅ Tests happy path -- ✅ Tests edge cases (empty, Unicode, special chars) -- ✅ Tests error handling -- ✅ Tests dry-run modes (where applicable) -- ✅ Descriptive test names and docstrings -- ✅ Grouped by functionality (test classes) -- ✅ No flaky tests (deterministic) -- ✅ Fast execution (< 0.1s per test) - ---- - -## Quick Reference: Test File Templates - -### Fix Module Pattern -```python -"""Tests for {module_name}.py fix module.""" - -from docuchango.fixes.{module_name} import fix_function - -class Test{ModuleName}Fixes: - """Test {module} fixing functionality.""" - - def test_basic_fix(self, tmp_path): - """Test basic fix scenario.""" - test_file = tmp_path / "test.md" - test_file.write_text("content", encoding="utf-8") - - result = fix_function(test_file) - assert result > 0 - - def test_no_changes_needed(self, tmp_path): - """Test file with no issues.""" - # ... - - def test_dry_run(self, tmp_path): - """Test dry-run mode.""" - # ... - - def test_unicode_content(self, tmp_path): - """Test Unicode handling.""" - # ... -``` - ---- - -## Command Reference - -```bash -# Run all tests with coverage -uv run pytest --cov=docuchango --cov-report=term-missing tests/ - -# Run specific module tests -uv run pytest tests/test_internal_links.py -v - -# Watch mode for TDD -uv run pytest-watch tests/ -- --cov=docuchango - -# Coverage HTML report -uv run pytest --cov=docuchango --cov-report=html tests/ -open htmlcov/index.html - -# Run only new tests -uv run pytest tests/test_*.py -v --co # List tests -uv run pytest tests/test_internal_links.py -v # Run one -``` - ---- - -## Notes - -- **Don't over-optimize**: 80% coverage is excellent for most projects -- **Focus on value**: Test important paths, not just coverage numbers -- **Keep tests fast**: Total suite should run in < 3 seconds -- **Maintain quality**: Every test should be valuable and maintainable -- **Document complex tests**: Add docstrings explaining "why" not just "what" - ---- - -## Estimated Total Effort - -| Phase | Effort | Coverage Gain | Test Gain | -|-------|--------|---------------|-----------| -| Phase 1 | 2-3 hours | +20% | +115 tests | -| Phase 2 | 6-8 hours | +5% | +40 tests | -| Phase 3 | 3-4 hours | +5% | +30 tests | -| **Total** | **11-15 hours** | **+30%** | **+185 tests** | - -**ROI:** Achievable in 2-3 focused work sessions to reach 80% coverage milestone. diff --git a/FRONTMATTER_ISSUES_ANALYSIS.md b/FRONTMATTER_ISSUES_ANALYSIS.md deleted file mode 100644 index bad5dda..0000000 --- a/FRONTMATTER_ISSUES_ANALYSIS.md +++ /dev/null @@ -1,187 +0,0 @@ -# Frontmatter CMS Issues - Probability Analysis - -## High Probability (>70%) - Implement Auto-Fixes - -### 1. Inconsistent Tag Formatting (90%) -**Issue:** Tags in different formats (string vs array, mixed case, spaces) -- `tags: backend` (should be array) -- `tags: ["Backend", "frontend"]` (inconsistent case) -- `tags: ["API Design", "api-design"]` (spaces vs dashes) - -**Auto-fix:** -- Convert string tags to arrays -- Normalize to lowercase with dashes -- Remove duplicates -- Sort alphabetically - -### 2. Missing Required Fields (85%) -**Issue:** Documents missing critical fields -- Missing `doc_uuid` (required for cross-references) -- Missing `project_id` (required for multi-project setups) -- Missing `tags` field (should be empty array, not absent) - -**Auto-fix:** -- Generate UUID if missing -- Set default project_id from config -- Add empty tags array if missing - -### 3. Trailing/Leading Whitespace in Values (80%) -**Issue:** Values with extra whitespace -- `title: " My Document "` -- `status: "Accepted "` -- `deciders: "Team Lead "` - -**Auto-fix:** -- Trim all string values -- Preserve intentional spacing in content - -### 4. Inconsistent Field Ordering (75%) -**Issue:** Fields in random order across documents -- Makes diffs harder to review -- Inconsistent with templates - -**Auto-fix:** -- Reorder fields to match template -- Standard order: id, title, status, created, updated, date, deciders, tags, project_id, doc_uuid - -### 5. Boolean Values as Strings (70%) -**Issue:** Boolean fields stored as strings -- `deprecated: "true"` (should be `true`) -- `draft: "false"` (should be `false`) - -**Auto-fix:** -- Convert string "true"/"false" to boolean -- Handle case variations (True, TRUE, etc.) - -## Medium Probability (40-70%) - Implement Auto-Fixes - -### 6. Empty String vs Null vs Missing (60%) -**Issue:** Inconsistent handling of empty values -- `description: ""` vs `description: null` vs field missing -- Affects validation and queries - -**Auto-fix:** -- Remove fields with empty strings (prefer missing) -- Convert null to missing for optional fields -- Keep empty arrays for list fields - -### 7. Numeric Values as Strings (55%) -**Issue:** Numbers stored as strings -- `priority: "1"` (should be `1`) -- `version: "2"` (should be `2`) - -**Auto-fix:** -- Convert numeric strings to numbers -- Preserve semantic versions as strings ("1.2.3") - -### 8. Inconsistent Author/Deciders Format (50%) -**Issue:** Author fields in different formats -- `deciders: "John Doe"` (single string) -- `deciders: "John, Jane"` (comma-separated) -- `deciders: ["John", "Jane"]` (array - correct) - -**Auto-fix:** -- Convert single string to array -- Split comma-separated strings -- Trim whitespace from names - -### 9. Duplicate Field Definitions (45%) -**Issue:** Same field defined multiple times (YAML allows this) -- Last value wins, creates confusion -- Usually copy-paste errors - -**Auto-fix:** -- Detect and remove duplicate keys -- Keep the last occurrence (YAML behavior) -- Warn user in verbose mode - -### 10. Related Document References (40%) -**Issue:** Cross-references in wrong format -- `supersedes: adr-001` (string, should be array) -- `related: ["adr-001", "ADR-002"]` (inconsistent case) -- Missing doc_uuid references - -**Auto-fix:** -- Normalize to arrays -- Standardize case to lowercase -- Validate referenced docs exist -- Add doc_uuid lookups - -## Low Probability (20-40%) - Manual Fix Recommended - -### 11. Title/ID Mismatch Content (35%) -**Issue:** Title describes different content than document -- Likely needs human review -- Could check for similarity - -### 12. Outdated Status (30%) -**Issue:** Status doesn't reflect current state -- "In Review" but merged 6 months ago -- Needs context to determine correct status - -### 13. Missing Descriptions/Summaries (25%) -**Issue:** Optional description fields empty -- Could generate from first paragraph -- Quality concerns with auto-generation - -### 14. Inconsistent Terminology (20%) -**Issue:** Same concepts described differently -- "API" vs "api" vs "Application Programming Interface" -- Needs taxonomy/glossary - -## Very Low Probability (<20%) - Detection Only - -### 15. Invalid YAML Syntax (15%) -**Issue:** Broken YAML that doesn't parse -- Usually caught immediately -- Validation catches this - -### 16. Encoding Issues (10%) -**Issue:** Non-UTF-8 characters -- Rare in modern editors -- Usually editor/system issue - -### 17. Merge Conflict Markers (5%) -**Issue:** Git merge markers in frontmatter -- `<<<<<<< HEAD` -- Very rare, usually caught by CI - -## Implementation Priority - -### Phase 1 (This PR) - High Impact, High Confidence -1. ✅ Invalid status values (already implemented) -2. ✅ Invalid date formats (already implemented) -3. ✅ Missing frontmatter blocks (already implemented) -4. **Tags normalization** - NEW -5. **Missing required fields** - ENHANCE EXISTING -6. **Whitespace trimming** - NEW -7. **Field ordering** - NEW - -### Phase 2 (Next PR) - Medium Impact -8. Boolean string conversion -9. Empty value normalization -10. Numeric string conversion -11. Author/deciders format - -### Phase 3 (Future) - Lower Impact -12. Duplicate field detection -13. Related document references -14. Status consistency checks - -## Auto-Fix Confidence Levels - -**High Confidence (Safe to auto-fix):** -- Tags normalization (reversible, clear rules) -- Whitespace trimming (no semantic change) -- Boolean/numeric conversions (type-safe) -- Missing required fields with defaults (additive) - -**Medium Confidence (Auto-fix with warnings):** -- Field reordering (changes diff, but semantically same) -- Empty value normalization (could affect queries) -- Duplicate field removal (might not be obvious which to keep) - -**Low Confidence (Suggest fixes only):** -- Status consistency (needs context) -- Title/content mismatch (subjective) -- Missing descriptions (quality concerns) diff --git a/QUICK_WINS.md b/QUICK_WINS.md deleted file mode 100644 index 3b3505f..0000000 --- a/QUICK_WINS.md +++ /dev/null @@ -1,373 +0,0 @@ -# Quick Wins: Zero-Coverage Modules - -**Time to 70% Coverage: ~2-3 hours** - -This guide provides step-by-step instructions for the fastest path to 70% coverage. - ---- - -## Test Creation Order (By ROI) - -### 1. test_internal_links.py (~15-20 min) -**Impact:** 83 statements | **Pattern:** Similar to test_broken_links.py - -
-Key Functions to Test - -```python -# docuchango/fixes/internal_links.py -def fix_links_in_content(content: str) -> tuple[str, int] -def fix_file(file_path: Path, dry_run: bool = False) -> int -def main() # Lines 77-145 -``` - -**Test Scenarios:** -- ✅ Remove date prefix from RFC links: `2025-10-13-rfc-001-name.md` → `rfc-001-name.md` -- ✅ Remove date prefix from ADR links: `2025-10-15-adr-003-name.md` → `adr-003-name.md` -- ✅ Remove date prefix from MEMO links: `2025-11-01-memo-005-name.md` → `memo-005-name.md` -- ✅ Handle relative paths: `../rfcs/2025-10-13-rfc-001.md` -- ✅ Handle same-dir paths: `./2025-10-15-adr-003.md` -- ✅ Preserve anchors: `...rfc-001.md#section` -- ✅ Dry-run mode -- ✅ No changes needed (already fixed) -- ✅ Multiple links in one file -- ✅ Unicode content preservation - -**Copy From:** `test_broken_links.py` (very similar structure) - -
- -**Command:** -```bash -# Create the test file -touch tests/test_internal_links.py - -# Run while developing -uv run pytest tests/test_internal_links.py -v --cov=docuchango.fixes.internal_links -``` - ---- - -### 2. test_mdx_syntax.py (~20 min) -**Impact:** 76 statements | **Pattern:** Regex replacements - -
-Key Functions to Test - -```python -# docuchango/fixes/mdx_syntax.py -def fix_mdx_syntax(file_path: Path) -> tuple[int, list[str]] -def main() # Lines 77-153 -``` - -**Test Scenarios:** -- ✅ Fix bare numbers to backticks: `<10ms` → `` `<10ms` `` -- ✅ Fix percentage: `<100%` → `` `<100%` `` -- ✅ Fix with units: `<5MB`, `<2.5GB`, `<1KB` -- ✅ Fix with words: `<1 minute`, `<10 seconds` -- ✅ Skip already backticked: `` `<10ms` `` -- ✅ ReDoS protection (test with adversarial input) -- ✅ Multiple replacements in one file -- ✅ Preserve indentation -- ✅ Unicode content -- ✅ Empty file - -**Key Edge Cases:** -- Input with 30+ repeated patterns (test regex performance) -- Long words (test bounded backtracking) - -
- ---- - -### 3. test_doc_links.py (~15 min) -**Impact:** 70 statements | **Pattern:** Link transformations - -
-Key Functions to Test - -```python -# docuchango/fixes/doc_links.py -def fix_doc_links(file_path: Path, dry_run: bool = False) -> int -def main() # Lines 77-138 -``` - -**Test Scenarios:** -- ✅ Convert .md links to docusaurus format -- ✅ Remove file extensions from internal links -- ✅ Fix relative path references -- ✅ Handle anchor links -- ✅ Dry-run mode -- ✅ No changes needed -- ✅ Multiple links -- ✅ Preserve link text -- ✅ Unicode - -
- ---- - -### 4. test_proto_imports.py (~20 min) -**Impact:** 61 statements | **Pattern:** Import statement fixes - -
-Key Functions to Test - -```python -# docuchango/fixes/proto_imports.py -def fix_proto_imports(file_path: Path) -> tuple[int, list[str]] -def main() # Lines 77-138 -``` - -**Test Scenarios:** -- ✅ Fix old import style to new style -- ✅ Update import paths -- ✅ Handle multiple imports in file -- ✅ Preserve non-proto imports -- ✅ Handle already-correct imports -- ✅ Preserve import ordering -- ✅ Unicode in comments -- ✅ Empty file - -**Note:** This may be project-specific. Read the file first to understand the transformation rules. - -
- ---- - -### 5. test_migration_syntax.py (~15 min) -**Impact:** 51 statements | **Pattern:** Syntax transformations - -
-Key Functions to Test - -```python -# docuchango/fixes/migration_syntax.py -def fix_migration_syntax(file_path: Path) -> tuple[int, list[str]] -def main() # Lines 55-94 -``` - -**Test Scenarios:** -- ✅ Transform old syntax to new syntax -- ✅ Handle multiple transformations -- ✅ Skip already-migrated code -- ✅ Preserve formatting -- ✅ Handle edge cases -- ✅ Unicode content -- ✅ Empty file - -
- ---- - -### 6. test_mdx_code_blocks.py (~15 min) -**Impact:** 50 statements | **Pattern:** Very similar to test_code_blocks.py - -
-Key Functions to Test - -```python -# docuchango/fixes/mdx_code_blocks.py -def fix_code_blocks(file_path: Path) -> tuple[int, str] -def main() # Lines 67-90 -``` - -**Test Scenarios:** -- ✅ Add 'text' to unlabeled code blocks -- ✅ Preserve labeled code blocks -- ✅ Track line numbers correctly -- ✅ Handle nested code blocks -- ✅ Handle indented code blocks -- ✅ Empty file -- ✅ No code blocks - -**Copy From:** `test_code_blocks.py` (almost identical) - -
- ---- - -## Template Code - -### Basic Test Structure -```python -"""Tests for {module}.py fix module.""" - -from pathlib import Path -from docuchango.fixes.{module} import {function_name} - - -class Test{Module}Fixes: - """Test {module} fixing functionality.""" - - def test_basic_transformation(self, tmp_path): - """Test basic transformation.""" - test_file = tmp_path / "test.md" - content = """Input content here""" - test_file.write_text(content, encoding="utf-8") - - result = {function_name}(test_file) - assert result > 0 # or tuple unpacking - - output = test_file.read_text(encoding="utf-8") - assert "expected" in output - - def test_no_changes_needed(self, tmp_path): - """Test file with no issues.""" - test_file = tmp_path / "test.md" - content = """Already correct content""" - test_file.write_text(content, encoding="utf-8") - - result = {function_name}(test_file) - assert result == 0 # No changes - - def test_unicode_preserved(self, tmp_path): - """Test Unicode handling.""" - test_file = tmp_path / "test.md" - content = """Content with → ✓ 中文""" - test_file.write_text(content, encoding="utf-8") - - {function_name}(test_file) - output = test_file.read_text(encoding="utf-8") - - assert "→" in output - assert "✓" in output - assert "中文" in output - - def test_empty_file(self, tmp_path): - """Test empty file handling.""" - test_file = tmp_path / "test.md" - test_file.write_text("", encoding="utf-8") - - result = {function_name}(test_file) - assert result == 0 -``` - ---- - -## Testing Workflow - -### Step-by-Step Process - -1. **Read the source file** to understand transformations: -```bash -cat docuchango/fixes/internal_links.py | head -50 -``` - -2. **Copy similar test file** as template: -```bash -cp tests/test_broken_links.py tests/test_internal_links.py -``` - -3. **Adapt tests** to new module: -- Update imports -- Update test scenarios -- Adjust assertions - -4. **Run tests** with coverage: -```bash -uv run pytest tests/test_internal_links.py -v \ - --cov=docuchango.fixes.internal_links \ - --cov-report=term-missing -``` - -5. **Iterate** until coverage is high: -- Check missing lines in coverage report -- Add tests for uncovered branches -- Focus on main() function last (often low value) - -6. **Verify** no regressions: -```bash -uv run pytest tests/ -v -``` - ---- - -## Coverage Targets - -| Module | Current | Target | Priority | -|--------|---------|--------|----------| -| internal_links.py | 0% | 65%+ | 🔥 High | -| mdx_syntax.py | 0% | 65%+ | 🔥 High | -| doc_links.py | 0% | 65%+ | 🔥 High | -| proto_imports.py | 0% | 60%+ | 🔥 High | -| migration_syntax.py | 0% | 60%+ | 🔥 High | -| mdx_code_blocks.py | 0% | 65%+ | 🔥 High | - -**Note:** Target 60-65% for each module. The main() functions are often low-value (just CLI wrappers), so don't stress about 100%. - ---- - -## Expected Outcome - -**Before:** 49.53% coverage (224 tests) - -**After Phase 1:** ~70% coverage (330+ tests) - -**Time Investment:** 2-3 hours - -**Commands to Verify:** -```bash -# Run all tests -uv run pytest --cov=docuchango --cov-report=term tests/ - -# Should see: -# - TOTAL: 70%+ -# - ~330+ tests passing -# - All new modules with 60%+ coverage -``` - ---- - -## Tips for Speed - -1. **Reuse patterns**: Copy from similar test files -2. **Skip main()**: Focus on core logic functions first -3. **Use tmp_path**: Built-in pytest fixture for temp files -4. **Parallel work**: Write tests for multiple modules simultaneously -5. **Auto-format**: `uv run ruff format tests/` after each file -6. **TDD**: Write test → run → fail → implement → pass → refactor - ---- - -## Common Pitfalls - -❌ **Don't:** -- Test main() functions extensively (low ROI) -- Aim for 100% coverage (diminishing returns) -- Write brittle tests (depend on exact output formatting) -- Test implementation details - -✅ **Do:** -- Test core transformation logic -- Test edge cases (empty, Unicode, multiple) -- Test error handling -- Keep tests simple and readable -- Use descriptive names - ---- - -## Measurement - -Track progress with: -```bash -# Quick coverage check -uv run pytest --cov=docuchango --cov-report=term tests/ | grep TOTAL - -# Detailed report -uv run pytest --cov=docuchango --cov-report=html tests/ -open htmlcov/index.html -``` - ---- - -## Next Steps After Quick Wins - -Once you hit 70% coverage: - -1. **Celebrate!** 🎉 You've doubled coverage -2. **Review the HTML report** to identify remaining gaps -3. **Move to Phase 2:** validator.py deep dive (see COVERAGE_ROADMAP.md) -4. **Consider diminishing returns:** 70% is already excellent coverage - -**Remember:** Perfect is the enemy of good. 70% coverage with quality tests beats 90% coverage with brittle tests. diff --git a/READABILITY_FEATURE.md b/READABILITY_FEATURE.md deleted file mode 100644 index 74bc045..0000000 --- a/READABILITY_FEATURE.md +++ /dev/null @@ -1,152 +0,0 @@ -# Document Readability Analysis - -DocuChango now includes optional document readability analysis using the textstat library. This feature analyzes each paragraph of readable text and reports when they fall below configured readability thresholds. - -## Installation - -Install with readability support: - -```bash -pip install docuchango[readability] -# or with uv -uv sync --extra readability -``` - -The readability feature is **optional**. If textstat is not installed, validation will skip readability checks without failing. - -## Quick Start - -Add readability configuration to your `docs-project.yaml`: - -```yaml -readability: - enabled: true - flesch_reading_ease_min: 60.0 # 0-100, higher = easier - flesch_kincaid_grade_max: 10.0 # Maximum US grade level - gunning_fog_max: 12.0 - smog_index_max: 12.0 - automated_readability_index_max: 10.0 - coleman_liau_index_max: 10.0 - dale_chall_max: 9.0 - min_paragraph_length: 100 # Minimum characters to analyze -``` - -Run validation: - -```bash -docuchango validate --verbose -``` - -## Supported Metrics - -- **Flesch Reading Ease** (0-100): Higher scores = easier to read - - 90-100: Very Easy (5th grade) - - 80-90: Easy (6th grade) - - 70-80: Fairly Easy (7th grade) - - 60-70: Standard (8th-9th grade) ← Default threshold - - 50-60: Fairly Difficult (10th-12th grade) - - 30-50: Difficult (College) - - 0-30: Very Difficult (College graduate) - -- **Flesch-Kincaid Grade Level**: US grade level required (e.g., 10.0 = 10th grade) -- **Gunning FOG Index**: Years of formal education needed -- **SMOG Index**: Grade level (requires 3+ sentences) -- **Automated Readability Index (ARI)**: Grade level approximation -- **Coleman-Liau Index**: Character-based grade level -- **Dale-Chall Score**: Grade level using common words - -## Configuration Examples - -### Technical Documentation (Default) -Good for developer documentation, RFCs, ADRs: - -```yaml -readability: - enabled: true - flesch_reading_ease_min: 60.0 - flesch_kincaid_grade_max: 10.0 -``` - -### Consumer Documentation (Easier) -For user guides, help documentation: - -```yaml -readability: - enabled: true - flesch_reading_ease_min: 70.0 # Fairly easy - flesch_kincaid_grade_max: 8.0 # 8th grade -``` - -### Disable Specific Metrics -```yaml -readability: - enabled: true - flesch_reading_ease_min: 60.0 - flesch_kincaid_grade_max: null # Disabled - gunning_fog_max: null # Disabled -``` - -### Disable Entirely -```yaml -readability: - enabled: false -``` - -## What Gets Analyzed - -The scorer **includes**: -- Regular paragraph text -- Multi-line paragraphs - -The scorer **excludes**: -- Code blocks (fenced with ``` or indented) -- YAML frontmatter (--- delimited) -- Headings (# markers) -- Lists (-, *, + markers) -- Blockquotes (> marker) -- HTML/MDX tags -- Paragraphs shorter than `min_paragraph_length` - -## Error Reporting - -Errors show the exact line number and which threshold was violated: - -``` -📖 Checking readability... - ✗ adr-001.md:45: Flesch Reading Ease score 45.2 below minimum 60.0 (harder to read) - ✗ adr-001.md:45: Flesch-Kincaid grade level 12.3 exceeds maximum 10.0 - ✓ rfc-002.md: 5 paragraphs analyzed, all readable -``` - -## Tips for Writing Readable Documentation - -1. **Use shorter sentences**: Break complex ideas into multiple sentences -2. **Prefer simple words**: "use" instead of "utilize", "help" instead of "facilitate" -3. **Active voice**: "We implemented X" instead of "X was implemented" -4. **Concrete examples**: Show, don't just tell -5. **One idea per paragraph**: Keep paragraphs focused - -## Technical Details - -- Analyses only paragraphs meeting minimum length (default 100 chars) -- Gracefully skips when textstat not installed -- Line numbers track paragraph start location -- All metrics can be individually enabled/disabled -- Full Unicode support - -## Development - -Run tests (includes 30 readability-specific tests): - -```bash -uv sync --extra dev -uv run pytest tests/test_readability.py -v -``` - -Note: Tests are automatically skipped if textstat is not installed. - -## References - -- [textstat library](https://pypi.org/project/textstat/) -- [Flesch Reading Ease](https://en.wikipedia.org/wiki/Flesch%E2%80%93Kincaid_readability_tests) -- [Gunning FOG](https://en.wikipedia.org/wiki/Gunning_fog_index) diff --git a/TEST_COVERAGE_GUIDE.md b/TEST_COVERAGE_GUIDE.md deleted file mode 100644 index 6e6f17e..0000000 --- a/TEST_COVERAGE_GUIDE.md +++ /dev/null @@ -1,326 +0,0 @@ -# Test Coverage Improvement Guide - -**Current Status:** 49.53% coverage (224 tests) -**Quick Win Target:** 70% coverage (310+ tests) -**Ultimate Target:** 80% coverage (380+ tests) - ---- - -## 📚 Documentation Overview - -This directory contains a complete roadmap for improving test coverage. Choose your starting point: - -### 🚀 Quick Start (Want results now?) -**→ Read: [QUICK_WINS.md](QUICK_WINS.md)** -- Step-by-step guide for 6 modules -- 2-3 hours to 70% coverage -- Includes code templates and examples - -### 📊 Strategic Planning (Want the big picture?) -**→ Read: [COVERAGE_ROADMAP.md](COVERAGE_ROADMAP.md)** -- Complete 3-phase roadmap -- Success metrics and timelines -- Testing techniques and best practices - -### 🎯 At-a-Glance (Want priorities only?) -**→ Read: [COVERAGE_PRIORITIES.txt](COVERAGE_PRIORITIES.txt)** -- Ranked list by ROI -- Effort estimates -- Quick command reference - -### 📈 Visual Roadmap (Want to see the journey?) -**→ Read: [COVERAGE_VISUAL.txt](COVERAGE_VISUAL.txt)** -- Coverage progression charts -- ROI analysis graphs -- Impact heat maps - ---- - -## 🎯 The Bottom Line - -### Fastest Path to 70% Coverage - -1. **Test 6 zero-coverage modules** (391 statements, 0% → 65%) - - `internal_links.py` (~20 min) - - `mdx_syntax.py` (~20 min) - - `doc_links.py` (~15 min) - - `proto_imports.py` (~20 min) - - `migration_syntax.py` (~15 min) - - `mdx_code_blocks.py` (~15 min) - -2. **Time Investment:** 2-3 hours -3. **Result:** 49.53% → 70% coverage (+20.47%) -4. **New Tests:** +86 tests - -### Why These 6 Modules? - -✅ **Zero coverage** = Maximum impact -✅ **Simple patterns** = Copy existing tests -✅ **Independent** = Can do in any order -✅ **High value** = Core fixing functionality - ---- - -## 💡 Key Insights - -### ROI by Phase - -| Phase | Time | Coverage Gain | Tests Added | ROI (Coverage/Hour) | -|-------|------|---------------|-------------|---------------------| -| **Phase 1** | 2h | +20% | +86 | **10.24%/hr** ⭐ | -| Phase 2 | 8h | +5% | +40 | 0.63%/hr | -| Phase 3 | 4h | +5% | +30 | 1.25%/hr | - -**Phase 1 has 4x better ROI than other phases!** - -### Coverage Sweet Spots - -- **40-50%**: Basic coverage, many gaps -- **50-70%**: Good coverage, core paths tested ← **We are here** -- **70-80%**: Excellent coverage, edge cases handled ← **Phase 1 target** -- **80-90%**: Very good coverage, diminishing returns -- **90%+**: Exceptional, may not be worth the effort - -**Target 70% first, then reassess.** - ---- - -## 🛠️ Getting Started - -### Prerequisites - -```bash -# Ensure dependencies installed -uv sync - -# Verify current coverage -uv run pytest --cov=docuchango --cov-report=term tests/ | grep TOTAL -# Should show: TOTAL ... 49.53% -``` - -### Step 1: Pick a Module - -Start with `internal_links.py` (easiest, similar to existing tests): - -```bash -# Read the source -cat docuchango/fixes/internal_links.py | head -50 - -# Copy similar test as template -cp tests/test_broken_links.py tests/test_internal_links.py -``` - -### Step 2: Adapt the Tests - -Edit `tests/test_internal_links.py`: -1. Update imports -2. Change function names -3. Adapt test scenarios to match the module's logic -4. Update assertions - -### Step 3: Run and Iterate - -```bash -# Run with coverage -uv run pytest tests/test_internal_links.py -v \ - --cov=docuchango.fixes.internal_links \ - --cov-report=term-missing - -# See uncovered lines, add more tests -# Repeat until 60-65% coverage -``` - -### Step 4: Verify - -```bash -# Run all tests -uv run pytest tests/ -v - -# Check overall coverage -uv run pytest --cov=docuchango --cov-report=term tests/ - -# Generate HTML report -uv run pytest --cov=docuchango --cov-report=html tests/ -open htmlcov/index.html -``` - -### Step 5: Repeat for Other 5 Modules - -Continue with: -- `mdx_syntax.py` -- `doc_links.py` -- `proto_imports.py` -- `migration_syntax.py` -- `mdx_code_blocks.py` - ---- - -## 📋 Test Checklist - -For each module, ensure tests cover: - -- ✅ **Happy path**: Basic transformation works -- ✅ **No changes**: File already correct -- ✅ **Multiple**: Multiple transformations in one file -- ✅ **Edge cases**: Empty files, Unicode, special characters -- ✅ **Error handling**: Handles invalid input gracefully -- ✅ **Dry-run**: Doesn't modify files in dry-run mode - -**Don't test:** -- ❌ `main()` functions extensively (low value) -- ❌ CLI argument parsing (covered elsewhere) -- ❌ Exact output formatting (brittle) - ---- - -## 🎓 Learning from Existing Tests - -### Best Examples to Copy - -**For link fixing modules:** -```bash -# Use as template for: internal_links, doc_links -cat tests/test_broken_links.py -``` - -**For code block modules:** -```bash -# Use as template for: mdx_code_blocks -cat tests/test_code_blocks.py -``` - -**For regex/syntax modules:** -```bash -# Use as template for: mdx_syntax, migration_syntax, proto_imports -cat tests/test_bug_fixes.py # See regex ReDoS tests -``` - ---- - -## 📊 Tracking Progress - -### During Development - -```bash -# Quick check -uv run pytest --cov=docuchango tests/ -q | tail -5 - -# Detailed report -uv run pytest --cov=docuchango --cov-report=term-missing tests/ -``` - -### Coverage Milestones - -Track your progress: - -``` -Start: 49.53% ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░░░░░░░░░░░ -After 1: ~53% ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░░░░░░░░░ -After 2: ~57% ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░░░░░░ -After 3: ~61% ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░░░░ -After 4: ~64% ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░░░ -After 5: ~67% ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░ -After 6: ~70% ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░ ✨ -``` - ---- - -## 🚦 Decision Points - -### After Reaching 70% - -**Option A: Stop Here** ✅ -- 70% is excellent coverage -- Core functionality well-tested -- Good ROI achieved - -**Option B: Continue to Validator** 💪 -- Big prize: validator.py (409 uncovered statements) -- High effort: 6-8 hours -- Lower ROI: 0.63%/hour -- Worth it if validator is critical - -**Option C: Polish Existing** 🎨 -- Improve modules to 80-90% each -- Lower effort: 3-4 hours -- Moderate ROI: 1.25%/hour -- Good for completeness - ---- - -## 🎯 Success Criteria - -You've succeeded when: - -✅ Overall coverage ≥ 70% -✅ All 6 zero-coverage modules ≥ 60% -✅ All tests pass -✅ No coverage regressions -✅ Tests run in < 3 seconds -✅ HTML report shows green for critical paths - ---- - -## 💬 Common Questions - -**Q: Why not aim for 100%?** -A: Diminishing returns. 70-80% is the sweet spot for most projects. - -**Q: Should I test main() functions?** -A: Usually no. They're thin CLI wrappers with low business value. - -**Q: What about edge cases?** -A: Test the important ones (empty files, Unicode), skip obscure ones. - -**Q: How do I know when to stop?** -A: When adding tests feels like busywork rather than adding value. - -**Q: What if I find bugs?** -A: Great! Write a failing test, fix the bug, watch test pass. - ---- - -## 📚 Additional Resources - -- **Existing Tests:** `tests/` directory - learn from examples -- **Fixtures:** `tests/conftest.py` - reusable test utilities -- **Coverage Report:** `htmlcov/index.html` - visual coverage explorer -- **pytest Docs:** https://docs.pytest.org/ - ---- - -## 🎉 Celebrate Progress! - -Remember: -- **39.81% → 49.53%** already achieved (+9.72%) ✅ -- **49.53% → 70%** is the next quick win (+20.47%) -- Every test adds value and confidence -- Perfect is the enemy of good - -**Start with just ONE module today. You've got this!** 💪 - ---- - -## Quick Command Reference - -```bash -# Start a new test module -cp tests/test_broken_links.py tests/test_internal_links.py - -# Run one test file -uv run pytest tests/test_internal_links.py -v - -# Check coverage -uv run pytest --cov=docuchango tests/ -q | tail -5 - -# View HTML report -uv run pytest --cov=docuchango --cov-report=html tests/ && open htmlcov/index.html - -# Run all checks (format, lint, type, test) -uv run ruff format . && uv run ruff check . && uv run mypy docuchango && uv run pytest tests/ -``` - ---- - -**Last Updated:** 2025-11-05 -**Status:** Phase 0 Complete ✅ | Phase 1 Ready 🚀 diff --git a/docs-cms/docs-project.yaml b/docs-cms/docs-project.yaml new file mode 100644 index 0000000..cdbfaaf --- /dev/null +++ b/docs-cms/docs-project.yaml @@ -0,0 +1,32 @@ +# yaml-language-server: $schema=../docuchango/templates/docs-project.schema.json +version: "1" +docuchango_version: "1.18.1" + +project: + id: docuchango + name: Docuchango + description: Product documentation hub for docuchango itself + +structure: + adr_dir: adr + rfc_dir: rfcs + memo_dir: memos + prd_dir: prd + template_dir: templates + document_folders: + - adr + - rfcs + - memos + - prd + +security: + allow_external_paths: false + +metadata: + created: "2026-05-30" + maintainers: + - Engineering Team + purpose: Durable documentation for docuchango architecture, proposals, product requirements, and maintenance knowledge + +readability: + enabled: false diff --git a/docs-cms/memos/memo-001-frontmatter-auto-fix-priorities.md b/docs-cms/memos/memo-001-frontmatter-auto-fix-priorities.md new file mode 100644 index 0000000..7a182f1 --- /dev/null +++ b/docs-cms/memos/memo-001-frontmatter-auto-fix-priorities.md @@ -0,0 +1,59 @@ +--- +author: Engineering Team +created: '2026-05-30' +doc_uuid: 07a83898-94f0-4c55-a190-f900c6d7250f +id: memo-001 +project_id: docuchango +tags: +- frontmatter +- normalization +- validation +title: Frontmatter Auto-Fix Priorities +--- + +# Memo-001: Frontmatter Auto-Fix Priorities + +## Summary + +Docuchango should prioritize frontmatter fixes that are deterministic, reversible, and low risk. The highest-value work is normalizing tags, adding safe missing fields, trimming whitespace, and ordering fields consistently. + +## High-Confidence Fixes + +Implement these first because they have clear rules and low semantic risk: + +- Normalize tags from strings or mixed arrays into lowercase, dash-separated arrays. +- Remove duplicate tags and sort them alphabetically. +- Generate `doc_uuid` when missing. +- Set missing `project_id` from project configuration. +- Add an empty `tags` array when tags are absent. +- Trim leading and trailing whitespace from frontmatter string values. +- Reorder frontmatter fields to match template order for cleaner diffs. + +## Medium-Confidence Fixes + +These are useful but should emit explicit warnings because they can affect downstream queries or review diffs: + +- Convert boolean strings such as `"true"` and `"false"` to booleans. +- Remove optional fields with empty strings or null values. +- Convert numeric strings to numbers while preserving semantic versions. +- Normalize `author` and `deciders` formats where schemas permit arrays. +- Detect duplicate YAML keys and retain the value that YAML parsing would keep. +- Normalize related-document references into lowercase arrays after checking that referenced documents exist. + +## Detection-Only Cases + +These require human review and should not be automatically rewritten: + +- Title and ID mismatches where the content appears to describe a different document. +- Status values that may be outdated based on project history. +- Missing descriptions or summaries that require judgment about quality. +- Inconsistent terminology that should be resolved through a glossary or taxonomy. +- Invalid YAML, encoding issues, and merge-conflict markers. + +## Implementation Order + +Phase 1 should focus on safe fixes: invalid status values, invalid date formats, missing frontmatter blocks, tag normalization, missing required fields, whitespace trimming, and field ordering. + +Phase 2 should add medium-confidence conversions: boolean strings, empty value normalization, numeric strings, and author or decider normalization. + +Phase 3 should add duplicate-field detection, related-reference checks, and status-consistency suggestions. diff --git a/docs-cms/memos/memo-002-test-coverage-roadmap.md b/docs-cms/memos/memo-002-test-coverage-roadmap.md new file mode 100644 index 0000000..c3a91dd --- /dev/null +++ b/docs-cms/memos/memo-002-test-coverage-roadmap.md @@ -0,0 +1,63 @@ +--- +author: Engineering Team +created: 2026-05-30 +doc_uuid: 7428b7a9-2e68-4fb2-90f0-33609d466601 +id: memo-002 +project_id: docuchango +tags: [coverage, roadmap, testing] +title: Test Coverage Roadmap +--- + +# Memo-002: Test Coverage Roadmap + +## Summary + +The fastest path to stronger coverage is to test zero-coverage fix modules before investing in deeper validator coverage. The prior working target was to move from roughly 49.5% coverage and 224 tests toward at least 70% coverage. + +## Priority Order + +Tier 1 covers zero-coverage modules with high return on investment: + +| Priority | Module | Rationale | +|----------|--------|-----------| +| 1 | `internal_links.py` | Similar to existing broken-link tests | +| 2 | `mdx_syntax.py` | Regex transformations with important edge cases | +| 3 | `doc_links.py` | Straightforward link rewriting | +| 4 | `proto_imports.py` | Import statement rewrites | +| 5 | `migration_syntax.py` | Syntax transformations | +| 6 | `mdx_code_blocks.py` | Similar to existing code-block tests | + +Tier 2 should target `validator.py`, especially document scanning, link validation, error aggregation, formatting checks, build validation, and integration workflows. + +Tier 3 should polish existing modules such as `docs.py`, `cli.py`, `code_blocks.py`, `broken_links.py`, `code_blocks_proper.py`, `cross_plugin_links.py`, and `schemas.py`. + +## Test Strategy + +For each fix module, cover these cases: + +- Basic transformation works. +- Files with no issues remain unchanged. +- Multiple transformations in one file work. +- Empty files and Unicode content are handled. +- Dry-run mode does not modify files where supported. +- Error handling is deterministic and does not hide failures. + +Prefer `pytest` fixtures and `tmp_path` for file-based tests. Use parametrized tests for transformation tables and golden files only when expected output is complex enough to justify them. + +## Commands + +Run focused coverage while developing a module: + +```bash +uv run pytest tests/test_internal_links.py -v --cov=docuchango.fixes.internal_links --cov-report=term-missing +``` + +Run the full suite and coverage report: + +```bash +uv run pytest --cov=docuchango --cov-report=term-missing tests/ +``` + +## Success Metrics + +The first milestone is 70% coverage with the Tier 1 modules tested. Later milestones should reassess whether 75%, 80%, or higher coverage is worth the maintenance cost. diff --git a/docs-cms/rfcs/rfc-002-readability-validation.md b/docs-cms/rfcs/rfc-002-readability-validation.md new file mode 100644 index 0000000..f8965f8 --- /dev/null +++ b/docs-cms/rfcs/rfc-002-readability-validation.md @@ -0,0 +1,77 @@ +--- +author: Engineering Team +created: 2026-05-30 +doc_uuid: 427be5ee-a803-48f7-8cf8-e4326edf4f63 +id: rfc-002 +project_id: docuchango +status: Implemented +tags: [documentation, readability, validation] +title: Readability Validation +--- + +# RFC-002: Readability Validation + +## Summary + +Docuchango supports optional readability validation for documentation prose. When enabled and the optional `textstat` dependency is installed, validation reports paragraphs that fall below configured readability thresholds. + +## Motivation + +Documentation quality is not only structural. Long, dense prose can pass schema and link checks while still being difficult for readers to use. Readability checks provide automated feedback without blocking projects that do not want this feature. + +## Configuration + +Enable readability in `docs-project.yaml`: + +```yaml +readability: + enabled: true + flesch_reading_ease_min: 60.0 + flesch_kincaid_grade_max: 10.0 + gunning_fog_max: 12.0 + smog_index_max: 12.0 + automated_readability_index_max: 10.0 + coleman_liau_index_max: 10.0 + dale_chall_max: 9.0 + min_paragraph_length: 100 +``` + +Install optional support with: + +```bash +pip install docuchango[readability] +``` + +or during development: + +```bash +uv sync --extra readability +``` + +If `textstat` is not installed, readability checks are skipped without failing validation. + +## Metrics + +Supported metrics include Flesch Reading Ease, Flesch-Kincaid Grade Level, Gunning Fog Index, SMOG Index, Automated Readability Index, Coleman-Liau Index, and Dale-Chall Score. Each metric can be enabled or disabled independently by setting the threshold to a number or `null`. + +## Scope + +Readability analysis includes regular paragraph text and multi-line paragraphs. + +Readability analysis excludes frontmatter, headings, lists, blockquotes, code blocks, HTML or MDX tags, and paragraphs shorter than `min_paragraph_length`. + +## Reporting + +Validation should report the document path, line number, metric, observed score, and configured threshold so authors can revise the exact paragraph that needs attention. + +## Authoring Guidance + +Readable docs should use shorter sentences, simpler words, active voice, concrete examples, and focused paragraphs. Technical docs can tolerate more complexity than consumer help docs, so projects should tune thresholds by audience. + +## Verification + +Run readability-specific tests with: + +```bash +uv run pytest tests/test_readability.py -v +``` \ No newline at end of file diff --git a/docs/BOOTSTRAP_GUIDE.md b/docs/BOOTSTRAP_GUIDE.md index cb874b8..b8745ba 100644 --- a/docs/BOOTSTRAP_GUIDE.md +++ b/docs/BOOTSTRAP_GUIDE.md @@ -28,19 +28,23 @@ This guide shows you how to bootstrap a working `docs-cms` system for agent-driv ## Quick Start -### 1. Bootstrap the Structure +### 1. Initialize docs-cms -Create the core `docs-cms` directory structure: +Use the CLI to create the project structure, configuration, schema, and templates: ```bash -mkdir -p docs-cms/{adr,rfcs,memos,templates} +docuchango init --project-id my-project --project-name "My Project" ``` -### 2. Create Configuration +For an existing repository, inspect `docs-cms/` first and avoid overwriting human-authored documents. If the project already has a `docs-cms` directory, add only missing configuration or guidance files. -Create `docs-cms/docs-project.yaml`: +### 2. Review Configuration + +Review `docs-cms/docs-project.yaml` and keep project-specific values accurate: ```yaml +# yaml-language-server: $schema=./docs-project.schema.json +version: "1" project: id: my-project name: My Project @@ -50,106 +54,31 @@ structure: adr_dir: adr rfc_dir: rfcs memo_dir: memos + prd_dir: prd template_dir: templates + document_folders: + - adr + - rfcs + - memos + - prd ``` -### 3. Copy Templates - -Copy templates from docuchango: - -```bash -# ADR Template -cat > docs-cms/templates/adr-template.md << 'EOF' ---- -id: adr-NNN -title: Brief decision title -status: Proposed -date: YYYY-MM-DD -tags: [architecture, decision] -project_id: my-project -doc_uuid: generate-uuid-v4-here ---- - -# ADR-NNN: Brief Decision Title - -## Status -Proposed | Accepted | Deprecated | Superseded - -## Context -What is the issue we're facing? What constraints exist? +Use the local `docs-cms/docs-project.schema.json` file as the config reference. If it is unavailable, use the stable schema URL: `https://jrepp.github.io/docuchango/schemas/docs-project.schema.json`. -## Decision -What did we decide to do? +### 3. Add Agent Instructions -## Consequences -What are the positive and negative outcomes? +Create or update a repository-level `AGENTS.md` file so coding agents know that `docs-cms` is the durable project memory: -## Alternatives Considered -- Alternative 1: Why not chosen -- Alternative 2: Why not chosen -EOF +```markdown +# Agent Instructions -# RFC Template -cat > docs-cms/templates/rfc-template.md << 'EOF' ---- -id: rfc-NNN -title: Proposal title -status: Draft -date: YYYY-MM-DD -author: Your Name -tags: [rfc, proposal] -project_id: my-project -doc_uuid: generate-uuid-v4-here ---- - -# RFC-NNN: Proposal Title - -## Summary -Brief 2-3 sentence overview - -## Motivation -Why are we doing this? What problem does it solve? +Use `docs-cms/` as durable project memory. Before changing architecture, workflows, documentation policy, validation behavior, templates, or release process, search and read relevant ADRs, RFCs, PRDs, and memos. -## Proposed Solution -Detailed explanation of the proposal +When new durable knowledge is created, add or update a `docs-cms` document instead of leaving root-level working notes. Use ADRs for accepted decisions, RFCs for proposals, PRDs for product requirements, and memos for durable findings or plans. -## Implementation -How will this be implemented? +For this repository itself, remember that docuchango maintains docuchango's own docs-cms. Avoid circular wording such as "the tool validates itself" unless the exact scope is clear: changes to docuchango's product behavior belong in `docs-cms/`, while generated examples under `examples/docs-cms/` remain sample content. -## Alternatives -What other approaches were considered? - -## Open Questions -- Question 1? -- Question 2? -EOF - -# Memo Template -cat > docs-cms/templates/memo-template.md << 'EOF' ---- -id: memo-NNN -title: Memo title -date: YYYY-MM-DD -author: Your Name -tags: [memo] -project_id: my-project -doc_uuid: generate-uuid-v4-here ---- - -# Memo: Title - -## Purpose -Why this memo exists - -## Key Points -- Point 1 -- Point 2 -- Point 3 - -## Next Actions -- [ ] Action 1 -- [ ] Action 2 -EOF +Run `docuchango validate --dry-run` before applying automatic documentation fixes, then run `docuchango validate` and summarize any remaining manual issues. ``` ### 4. Install docuchango @@ -161,52 +90,12 @@ pip install docuchango ### 5. Create Your First Document ```bash -# Generate a UUID +cp docs-cms/templates/adr-000-template.md docs-cms/adr/adr-001-adopt-docs-cms.md uuidgen | tr '[:upper:]' '[:lower:]' -# Output: 550e8400-e29b-41d4-a716-446655440000 - -# Create first ADR -cat > docs-cms/adr/adr-001-adopt-docs-cms.md << 'EOF' ---- -id: adr-001 -title: Adopt docs-cms for Documentation -status: Accepted -date: 2025-10-27 -tags: [architecture, documentation] -project_id: my-project -doc_uuid: 550e8400-e29b-41d4-a716-446655440000 ---- - -# ADR-001: Adopt docs-cms for Documentation - -## Status -Accepted - -## Context -We need a structured way to document architectural decisions and collaborate with AI agents on documentation. - -## Decision -Adopt docs-cms as our documentation framework with docuchango validation. - -## Consequences - -**Positive:** -- Consistent documentation structure -- Automated validation -- Version controlled in git -- Agent-friendly format - -**Negative:** -- Requires learning frontmatter schema -- Need to install docuchango tooling - -## Alternatives Considered -- Wiki: Too unstructured, hard to validate -- Confluence: Not in version control, not agent-friendly -- Plain markdown: No validation, no consistency -EOF ``` +Then fill all placeholder frontmatter fields, update the heading and body, and validate before committing. + ### 6. Validate Your Documentation ```bash @@ -299,14 +188,15 @@ All documents require these fields: --- id: doc-NNN # Unique identifier (e.g., adr-001) title: Brief title # Human-readable title -status: Draft # Status (varies by type) -date: 2025-10-27 # Creation/update date +created: 2026-05-30 # Creation date or timestamp tags: [tag1, tag2] # Categorization tags project_id: my-project # Project identifier doc_uuid: uuid-v4-here # Unique UUID v4 --- ``` +Some document types require additional fields. For example, ADRs require `status` and `deciders`, RFCs require `status` and `author`, PRDs require `status`, `author`, and `target_release`, and memos require `author`. + ### Generating UUIDs ```bash @@ -390,19 +280,19 @@ docuchango validate **ADR Status Flow:** ``` Proposed → Accepted → Implemented - → Rejected + → Deprecated → Superseded (by adr-XXX) ``` **RFC Status Flow:** ``` -Draft → In Review → Approved → Implemented - → Rejected - → Withdrawn +Draft → Proposed → Accepted → Implemented + → Deprecated + → Superseded ``` **Memo Status:** -Memos typically don't have status (informational only) +Memos do not require a status. Use them for durable findings, plans, or informational context. ## Integration with CI/CD @@ -431,10 +321,11 @@ jobs: ## Next Steps -1. **Read the Agent Guide**: See `docs/AGENT_GUIDE.md` for instructions on how agents should interact with docs-cms -2. **Review Examples**: Check `examples/docs-cms/` for sample documents -3. **Set up CI**: Add validation to your CI/CD pipeline -4. **Write Your First ADR**: Document why you adopted docs-cms! +1. **Add agent instructions**: Create or update `AGENTS.md` with the repository-specific docs-cms guidance above +2. **Read the Agent Guide**: See `docs/AGENT_GUIDE.md` for instructions on how agents should interact with docs-cms +3. **Review Examples**: Check `examples/docs-cms/` for sample documents +4. **Set up CI**: Add validation to your CI/CD pipeline +5. **Write Your First ADR**: Document why you adopted docs-cms! ## Troubleshooting @@ -460,7 +351,7 @@ Fix: Update link to point to existing file or create the target **Invalid Status Value** ``` -Error: status must be one of: Proposed, Accepted, Rejected, Superseded +Error: status must be one of the valid values for that document type Fix: Use a valid status value from the schema ```