diff --git a/.ai-todo/.ai-todo.log b/.ai-todo/.ai-todo.log index aec434f..499d8f0 100644 --- a/.ai-todo/.ai-todo.log +++ b/.ai-todo/.ai-todo.log @@ -4080,3 +4080,34 @@ main-3 | - [D] **#fxstein-25** Test 2026-01-31 02:48:30 | oratzes | CLI | UPDATE | | 44012105 | 2026-01-31 02:50:03 | oratzes | CLI | UPDATE | | a469e776 | 2026-01-31 02:50:35 | oratzes | CLI | UPDATE | | ed917836 | +2026-01-31 03:27:13 | oratzes | CLI | UPDATE | | c991d3a4 | +2026-01-31 03:27:13 | oratzes | CLI | UPDATE | | 677f01d6 | +2026-01-31 03:27:17 | oratzes | CLI | UPDATE | | c6e12795 | +2026-01-31 03:27:17 | oratzes | CLI | UPDATE | | 4b9f447f | +2026-01-31 03:27:19 | oratzes | CLI | UPDATE | | 726c4b52 | +2026-01-31 03:27:19 | oratzes | CLI | UPDATE | | 1847083a | +2026-01-31 03:27:20 | oratzes | CLI | UPDATE | | b1a75f21 | +2026-01-31 03:27:20 | oratzes | CLI | UPDATE | | 2f540b25 | +2026-01-31 03:27:21 | oratzes | CLI | UPDATE | | 9e19420d | +2026-01-31 03:27:21 | oratzes | CLI | UPDATE | | 1234f1b9 | +2026-01-31 03:27:22 | oratzes | CLI | UPDATE | | 202ac510 | +2026-01-31 03:27:22 | oratzes | CLI | UPDATE | | 1fd61014 | +2026-01-31 03:27:24 | oratzes | CLI | UPDATE | | 84c11afb | +2026-01-31 03:27:24 | oratzes | CLI | UPDATE | | 9f3f78cd | +2026-01-31 03:27:25 | oratzes | CLI | UPDATE | | b1efd551 | +2026-01-31 03:27:25 | oratzes | CLI | UPDATE | | 73a23605 | +2026-01-31 03:27:55 | oratzes | CLI | UPDATE | | 59bc811d | +2026-01-31 03:29:49 | oratzes | CLI | UPDATE | | 45a6416b | +2026-01-31 03:29:52 | oratzes | CLI | UPDATE | | ffa48408 | +2026-01-31 03:30:35 | oratzes | CLI | UPDATE | | 08ed1c73 | +2026-01-31 03:38:54 | oratzes | CLI | UPDATE | | c77a5577 | +2026-01-31 03:38:54 | oratzes | CLI | UPDATE | | 1f8d0ae7 | +2026-01-31 03:39:29 | oratzes | CLI | UPDATE | | 474721eb | +2026-01-31 03:39:30 | oratzes | CLI | UPDATE | | 32d37811 | +2026-01-31 03:39:55 | oratzes | CLI | UPDATE | | d49d46e9 | +2026-01-31 03:39:55 | oratzes | CLI | UPDATE | | f87fe106 | +2026-01-31 03:41:38 | oratzes | CLI | UPDATE | | 663ba9be | +2026-01-31 03:41:38 | oratzes | CLI | UPDATE | | 43e2b403 | +2026-01-31 03:42:12 | oratzes | CLI | UPDATE | | ce9e5358 | +2026-01-31 03:42:13 | oratzes | CLI | UPDATE | | 0845cef5 | +2026-01-31 03:42:50 | oratzes | CLI | UPDATE | | 1a7a0d24 | diff --git a/.ai-todo/.ai-todo.serial b/.ai-todo/.ai-todo.serial index 2a095c4..8006072 100644 --- a/.ai-todo/.ai-todo.serial +++ b/.ai-todo/.ai-todo.serial @@ -1 +1 @@ -271 \ No newline at end of file +272 \ No newline at end of file diff --git a/.ai-todo/state/TODO.md b/.ai-todo/state/TODO.md index e746e6f..b369300 100644 --- a/.ai-todo/state/TODO.md +++ b/.ai-todo/state/TODO.md @@ -4,6 +4,40 @@ ## Tasks +- [x] **#272** [AIT-9] ascii-guard linting `#documentation` `#tooling` `#urgent` (2026-01-31) + > Add fxstein/ascii-guard linting to pre-commit and CICD workflows. Need to make sure all documents are cleaned - especially documentation, and various documents created during analysis and design reviews. + > Linear Issue: https://linear.app/fxstein/issue/AIT-9/ascii-guard-linting + - [x] **#272.7** Verify and document ascii-guard integration `#documentation` `#validation` (2026-01-31) + > Final verification: + > - Test pre-commit hook locally + > - Verify CI/CD workflow runs successfully + > - Update relevant documentation + > - Ensure all documents are clean + - [x] **#272.6** Clean existing documentation files `#cleanup` `#documentation` (2026-01-31) + > Run ascii-guard on all existing documents and clean up any non-ASCII characters: + > - Documentation in docs/ + > - Analysis and design documents + > - README and other markdown files + > - Any other documentation artifacts + - [x] **#272.5** Create tests for ascii-guard integration `#testing` `#validation` (2026-01-31) + > Create unit and integration tests to verify ascii-guard correctly identifies non-ASCII characters in documents and that the integration works in both pre-commit and CI/CD contexts. + - [x] **#272.4** Add ascii-guard to CI/CD workflows `#ci-cd` `#implementation` (2026-01-31) + > Integrate ascii-guard linting into GitHub Actions CI/CD pipeline (.github/workflows/ci-cd.yml). + - [x] **#272.3** Implement ascii-guard in pre-commit configuration `#implementation` `#pre-commit` (2026-01-31) + > Add ascii-guard hook to .pre-commit-config.yaml with appropriate configuration for the repository. + - [x] **#272.2** Human review of design document `#checkpoint` `#review` (2026-01-31) + > Pause for human review and approval of the design document before proceeding with implementation. + > This is a checkpoint to ensure the approach is correct. + - [x] **#272.1** Create design document for ascii-guard integration `#design` `#documentation` (2026-01-31) + > Research fxstein/ascii-guard tool and create a comprehensive design document covering: + > - How ascii-guard works and its purpose + > - Integration points (pre-commit, CI/CD workflows) + > - Configuration requirements + > - Document cleanup strategy + > - Testing approach + > Document location: docs/design/ascii-guard-integration.md + > ✅ Design document created: docs/design/ascii-guard-integration.md + - [ ] **#271** [AIT-15] Incorrect branch names for linear issue > When starting to work on a new linear issue, the branch that gets created has the wrong user id as the prefix. The cursor rule needs to explicitly use the GitHub userid and not any name Linear provides in its suggested branch name. > Linear: https://linear.app/fxstein/issue/AIT-15/incorrect-branch-names-for-linear-issue @@ -1350,6 +1384,11 @@ --- +## Task Metadata + +Task relationships and dependencies (managed by ai-todo). +View with: `ai-todo show ` + --- -**ai-todo** | Last Updated: 2026-01-31 02:50:35 +**ai-todo** | Last Updated: 2026-01-31 03:42:50 diff --git a/.ai-todo/state/checksum b/.ai-todo/state/checksum index 66fbad2..6dfc6e2 100644 --- a/.ai-todo/state/checksum +++ b/.ai-todo/state/checksum @@ -1 +1 @@ -ed9178366908bf798d7ab54c2c7b01633bc80a6e4389ab778eef37e58593493a +1a7a0d24d203b498b6d52230691a1ac58220cce93217e167092517ba5b0412cf diff --git a/.ascii-guard.toml b/.ascii-guard.toml new file mode 100644 index 0000000..6695b80 --- /dev/null +++ b/.ascii-guard.toml @@ -0,0 +1,44 @@ +# .ascii-guard.toml +# Configuration for ascii-guard linter + +[files] +# Scan all text files (empty = all) +extensions = [] + +# Exclude patterns (gitignore-style) +exclude = [ + ".git/", + "node_modules/", + "__pycache__/", + ".venv/", + "venv/", + ".tox/", + "build/", + "dist/", + ".mypy_cache/", + ".pytest_cache/", + ".ruff_cache/", + "*.egg-info/", + # Project-specific excludes: + ".ai-todo/", # ai-todo state directory + "htmlcov/", + ".coverage", + "uv.lock", +] + +# Follow symbolic links when scanning +follow_symlinks = false + +# Maximum file size to scan in MB +max_file_size = 10 + +[rules] +# Phase 2: Enable/disable specific validation rules (future) +# check_alignment = true +# check_corners = true +# check_width = true + +[output] +# Phase 2: Output customization (future) +# color = "auto" +# verbose = false diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 848bb29..d006a8f 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -156,6 +156,9 @@ jobs: - name: Install dependencies run: uv sync --all-extras + - name: Lint ASCII art boxes + run: uv run ascii-guard lint . + - name: Lint TODO.md run: uv run ai-todo lint diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 57ce021..c5f0f99 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -61,14 +61,14 @@ repos: pass_filenames: true files: ^(release/|\.github/|scripts/) - # Temporarily disabled due to pipx environment issues - # - id: ascii-guard - # name: ascii-guard - # entry: ascii-guard lint - # language: system - # types: [markdown] - # pass_filenames: true - # files: \.(md|mdc)$ + - id: ascii-guard + name: ascii-guard + entry: uv run ascii-guard lint + language: system + types: [markdown] + pass_filenames: true + files: \.(md|mdc)$ + exclude: ^\.ai-todo/ - id: todo-ai-lint name: ai-todo lint diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2591a64..65ef80f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -56,6 +56,32 @@ If you are not using Cursor: - Example: `git checkout -b jdoe/AIT-12-fix-login`. 3. Open a PR from that branch to `main`. The branch name will be checked by the Linear PR Check workflow. +## Pre-commit Hooks + +This project uses pre-commit hooks to ensure code quality: + +```bash +# Install pre-commit hooks (one-time setup) +pre-commit install + +# Run manually on all files +pre-commit run --all-files +``` + +**ASCII Art Guidelines:** + +We use [ascii-guard](https://github.com/fxstein/ascii-guard) to ensure consistent ASCII diagram formatting: + +```bash +# Check ASCII art in documentation +uv run ascii-guard lint docs/ + +# Auto-fix alignment issues +uv run ascii-guard fix docs/ +``` + +When creating diagrams, use Unicode box-drawing characters: `─ │ ┌ ┐ └ ┘`. The pre-commit hook will catch alignment issues automatically. + --- For other contribution guidelines (code style, tests, release process), see the main [README](README.md) and [docs/](docs/). diff --git a/TODO.md b/TODO.md index e746e6f..b369300 100644 --- a/TODO.md +++ b/TODO.md @@ -4,6 +4,40 @@ ## Tasks +- [x] **#272** [AIT-9] ascii-guard linting `#documentation` `#tooling` `#urgent` (2026-01-31) + > Add fxstein/ascii-guard linting to pre-commit and CICD workflows. Need to make sure all documents are cleaned - especially documentation, and various documents created during analysis and design reviews. + > Linear Issue: https://linear.app/fxstein/issue/AIT-9/ascii-guard-linting + - [x] **#272.7** Verify and document ascii-guard integration `#documentation` `#validation` (2026-01-31) + > Final verification: + > - Test pre-commit hook locally + > - Verify CI/CD workflow runs successfully + > - Update relevant documentation + > - Ensure all documents are clean + - [x] **#272.6** Clean existing documentation files `#cleanup` `#documentation` (2026-01-31) + > Run ascii-guard on all existing documents and clean up any non-ASCII characters: + > - Documentation in docs/ + > - Analysis and design documents + > - README and other markdown files + > - Any other documentation artifacts + - [x] **#272.5** Create tests for ascii-guard integration `#testing` `#validation` (2026-01-31) + > Create unit and integration tests to verify ascii-guard correctly identifies non-ASCII characters in documents and that the integration works in both pre-commit and CI/CD contexts. + - [x] **#272.4** Add ascii-guard to CI/CD workflows `#ci-cd` `#implementation` (2026-01-31) + > Integrate ascii-guard linting into GitHub Actions CI/CD pipeline (.github/workflows/ci-cd.yml). + - [x] **#272.3** Implement ascii-guard in pre-commit configuration `#implementation` `#pre-commit` (2026-01-31) + > Add ascii-guard hook to .pre-commit-config.yaml with appropriate configuration for the repository. + - [x] **#272.2** Human review of design document `#checkpoint` `#review` (2026-01-31) + > Pause for human review and approval of the design document before proceeding with implementation. + > This is a checkpoint to ensure the approach is correct. + - [x] **#272.1** Create design document for ascii-guard integration `#design` `#documentation` (2026-01-31) + > Research fxstein/ascii-guard tool and create a comprehensive design document covering: + > - How ascii-guard works and its purpose + > - Integration points (pre-commit, CI/CD workflows) + > - Configuration requirements + > - Document cleanup strategy + > - Testing approach + > Document location: docs/design/ascii-guard-integration.md + > ✅ Design document created: docs/design/ascii-guard-integration.md + - [ ] **#271** [AIT-15] Incorrect branch names for linear issue > When starting to work on a new linear issue, the branch that gets created has the wrong user id as the prefix. The cursor rule needs to explicitly use the GitHub userid and not any name Linear provides in its suggested branch name. > Linear: https://linear.app/fxstein/issue/AIT-15/incorrect-branch-names-for-linear-issue @@ -1350,6 +1384,11 @@ --- +## Task Metadata + +Task relationships and dependencies (managed by ai-todo). +View with: `ai-todo show ` + --- -**ai-todo** | Last Updated: 2026-01-31 02:50:35 +**ai-todo** | Last Updated: 2026-01-31 03:42:50 diff --git a/docs/archive/RELEASE_NUMBERING_MAPPING.md b/docs/archive/RELEASE_NUMBERING_MAPPING.md index aac248f..6ae45dc 100644 --- a/docs/archive/RELEASE_NUMBERING_MAPPING.md +++ b/docs/archive/RELEASE_NUMBERING_MAPPING.md @@ -44,25 +44,25 @@ The release numbering logic uses a **highest-level-first approach** to determine ``` ┌─────────────────────────────────────────────────────────────────┐ -│ Step 1: Scan ALL commits and classify each by release level │ -│ ───────────────────────────────────────────────────────────── │ -│ Process each commit individually: │ +│ Step 1: Scan ALL commits and classify each by release level │ │ +│ ───────────────────────────────────────────────────────────── │ +│ Process each commit individually: │ │ → Classify each commit: MAJOR > MINOR > PATCH │ │ → Step down from highest to lowest level per commit │ │ → Track the HIGHEST level found across all commits │ └─────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────┐ -│ Step 2: Find Highest Level Across All Commits │ -│ ───────────────────────────────────────────────────────────── │ -│ Logic: │ +│ Step 2: Find Highest Level Across All Commits │ +│ ───────────────────────────────────────────────────────────── │ +│ Logic: │ │ → A single MAJOR commit makes the entire release MAJOR │ │ → A single MINOR commit (with no MAJOR) makes release MINOR │ │ → Otherwise, it's PATCH │ -│ │ +│ │ │ Priority order (highest to lowest): │ │ 1. MAJOR: breaking, break, major, !:, feat!:, fix!: │ -│ 2. MINOR: feat:, feature: (if user-facing) │ +│ 2. MINOR: feat:, feature: (if user-facing) │ │ 3. PATCH: backend:, infra:, release:, internal:, fix:, bugfix: │ │ 4. MINOR: add, new, implement, create, support (if not backend) │ │ 5. PATCH: (default for all other commits) │ diff --git a/docs/design/BUG_REPORTING_DESIGN.md b/docs/design/BUG_REPORTING_DESIGN.md index 720880d..d12c8ae 100644 --- a/docs/design/BUG_REPORTING_DESIGN.md +++ b/docs/design/BUG_REPORTING_DESIGN.md @@ -206,7 +206,7 @@ Labels are passed to `gh issue create --label` command with fallback to basic "b ▼ ▼ ┌──────────────────┐ ┌─────────────────┐ │ Reply to Issue │ │ Create New Issue│ -│ - "Me too" msg │ │ - Full report │ +│ - "Me too" msg │ ││- Full report │ │ - Attach logs │ │ - All context │ └──────────────────┘ └─────────────────┘ ``` diff --git a/docs/design/GIT_HOOKS_DESIGN.md b/docs/design/GIT_HOOKS_DESIGN.md index b769d74..42125e7 100644 --- a/docs/design/GIT_HOOKS_DESIGN.md +++ b/docs/design/GIT_HOOKS_DESIGN.md @@ -39,31 +39,31 @@ Currently, there are no automated checks before commits. This can lead to: │ ▼ ┌─────────────────────┐ -│ Pre-commit Hook │ -│ Triggered │ -└────────┬────────────┘ +│ Pre-commit Hook │ +│ Triggered │ +└─────────────────────┘ │ ▼ ┌─────────────────────┐ │ Get Staged Files │ │ - Detect file types │ -│ - Filter relevant │ -└────────┬────────────┘ +│ - Filter relevant │ +└─────────────────────┘ │ ▼ ┌─────────────────────┐ -│ Run Validators │ -│ ├─ Markdown linter │ -│ ├─ YAML linter │ -│ ├─ JSON linter │ -│ └─ TODO.md lint │ -└────────┬────────────┘ +│ Run Validators │ +│ ├─ Markdown linter │ +│ ├─ YAML linter │ +│ ├─ JSON linter │ +│ └─ TODO.md lint │ +└─────────────────────┘ │ ▼ ┌─────────────────────┐ -│ Check Results │ -│ - Any errors? │ -└────────┬────────────┘ +│ Check Results │ +│ - Any errors? │ +└─────────────────────┘ │ ┌────┴────┐ │ │ diff --git a/docs/design/ascii-guard-integration.md b/docs/design/ascii-guard-integration.md new file mode 100644 index 0000000..bf9373b --- /dev/null +++ b/docs/design/ascii-guard-integration.md @@ -0,0 +1,80 @@ +# ASCII-Guard Integration Design + +**Status:** Design +**Created:** 2026-01-31 +**Task:** #272.1 ([AIT-9](https://linear.app/fxstein/issue/AIT-9)) + +## Why + +AI-generated ASCII diagrams in our documentation (17+ files) often have subtle alignment errors that break visual integrity. We need automated validation to ensure consistency without manual review overhead. + +## What + +Integrate `ascii-guard` (our own linting tool for ASCII box-drawing characters) into: + +- Pre-commit hooks - catch issues before commit +- CI/CD workflows - block merges with malformed diagrams +- Documentation - 17+ files need initial cleanup + +## How + +### 1. Add Dependency + +```toml +# pyproject.toml +[project.optional-dependencies] +dev = [ + "ascii-guard>=1.5.0", # Add to existing dev dependencies +] +``` + +### 2. Enable Pre-commit Hook + +```yaml +# .pre-commit-config.yaml (uncomment and fix existing hook) +- id: ascii-guard + name: ascii-guard + entry: uv run ascii-guard lint # Changed from plain 'ascii-guard lint' + language: system + types: [markdown] + pass_filenames: true + files: \.(md|mdc)$ + exclude: ^\.ai-todo/ +``` + +### 3. Add to CI/CD + +```yaml +# .github/workflows/ci-cd.yml (add to docs-quality job after markdownlint) +- name: Lint ASCII art boxes + run: uv run ascii-guard lint '**/*.md' '**/*.mdc' +``` + +### 4. Clean Existing Docs + +```bash +# Run once to fix existing 17+ files +uv run ascii-guard fix docs/ +``` + +### 5. Add Validation Test + +```python +# tests/validation/test_ascii_art_validation.py (new file) +def test_ascii_guard_passes_on_all_docs(): + """Verify all documentation passes ascii-guard linting.""" + result = subprocess.run(["uv", "run", "ascii-guard", "lint", "docs/"], ...) + assert result.returncode == 0 +``` + +## Rollout Order + +1. Add dependency to `pyproject.toml` +2. Clean existing docs (`ascii-guard fix docs/`) +3. Enable pre-commit hook (uncomment + fix entry point) +4. Add CI/CD step to `docs-quality` job +5. Add validation test + +## Rollback + +Comment out pre-commit hook and CI/CD step. Remove from `pyproject.toml`. diff --git a/pyproject.toml b/pyproject.toml index 01ee3da..2bc3272 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,7 +64,7 @@ dev = [ "pre-commit>=3.7.0", "build>=1.0.0", "twine>=5.0.0", - "ascii-guard>=0.1.0", + "ascii-guard>=1.5.0", "types-requests>=2.31.0", "types-pyyaml>=6.0.12.12", ] diff --git a/tests/validation/test_ascii_art_validation.py b/tests/validation/test_ascii_art_validation.py new file mode 100644 index 0000000..68112f0 --- /dev/null +++ b/tests/validation/test_ascii_art_validation.py @@ -0,0 +1,28 @@ +"""Validation tests for ASCII art formatting.""" + +import subprocess + + +def test_ascii_guard_installed(): + """Verify ascii-guard is installed and executable.""" + result = subprocess.run( + ["uv", "run", "ascii-guard", "--version"], + capture_output=True, + text=True, + ) + + assert result.returncode == 0, "ascii-guard not installed or not executable" + assert "ascii-guard" in result.stdout.lower(), "Unexpected version output" + + +def test_ascii_guard_passes_on_all_docs(): + """Verify all documentation passes ascii-guard linting.""" + result = subprocess.run( + ["uv", "run", "ascii-guard", "lint", "docs/"], + capture_output=True, + text=True, + ) + + assert result.returncode == 0, ( + f"ascii-guard found errors in documentation:\n{result.stdout}\n{result.stderr}" + ) diff --git a/uv.lock b/uv.lock index d146a0e..df192ec 100644 --- a/uv.lock +++ b/uv.lock @@ -37,7 +37,7 @@ dev = [ [package.metadata] requires-dist = [ - { name = "ascii-guard", marker = "extra == 'dev'", specifier = ">=0.1.0" }, + { name = "ascii-guard", marker = "extra == 'dev'", specifier = ">=1.5.0" }, { name = "build", marker = "extra == 'dev'", specifier = ">=1.0.0" }, { name = "click", specifier = ">=8.1.0" }, { name = "fastmcp", specifier = ">=2.14.4,<3.0.0" },