diff --git a/.agentready/assessment-20260212-110150.json b/.agentready/assessment-20260212-110150.json new file mode 100644 index 0000000000..831f668165 --- /dev/null +++ b/.agentready/assessment-20260212-110150.json @@ -0,0 +1,1078 @@ +{ + "schema_version": "1.0.0", + "metadata": { + "agentready_version": "2.27.0", + "research_version": "1.0.1", + "assessment_timestamp": "2026-02-12T11:01:50.506311", + "assessment_timestamp_human": "February 12, 2026 at 11:01 AM", + "executed_by": "ddahlem@ddahlem-mac", + "command": "/Users/ddahlem/.local/bin/agentready assess .", + "working_directory": "/Users/ddahlem/Documents/repos/trusty/red-hat-data-services/NeMo-Guardrails" + }, + "repository": { + "path": "/Users/ddahlem/Documents/repos/trusty/red-hat-data-services/NeMo-Guardrails", + "name": "NeMo-Guardrails", + "url": "https://github.com/red-hat-data-services/NeMo-Guardrails.git", + "branch": "main", + "commit_hash": "938fdf81a9035dd14bb04515a4f8be14091ed55e", + "languages": { + "JSON": 18, + "YAML": 258, + "Markdown": 208, + "Python": 569, + "JavaScript": 11, + "TOML": 3 + }, + "total_files": 1495, + "total_lines": 255626 + }, + "timestamp": "2026-02-12T11:01:50.506311", + "overall_score": 56.5, + "certification_level": "Bronze", + "attributes_assessed": 23, + "attributes_skipped": 2, + "attributes_total": 25, + "findings": [ + { + "attribute": { + "id": "claude_md_file", + "name": "CLAUDE.md Configuration Files", + "category": "Context Window Optimization", + "tier": 1, + "description": "Project-specific configuration for Claude Code", + "criteria": "CLAUDE.md file exists in repository root", + "default_weight": 0.1 + }, + "status": "fail", + "score": 0.0, + "measured_value": "missing", + "threshold": "present", + "evidence": [ + "CLAUDE.md not found in repository root", + "AGENTS.md not found (alternative)" + ], + "remediation": { + "summary": "Create CLAUDE.md or AGENTS.md with project-specific configuration for AI coding assistants", + "steps": [ + "Choose one of three approaches:", + " Option 1: Create standalone CLAUDE.md (>50 bytes) with project context", + " Option 2: Create AGENTS.md and symlink CLAUDE.md to it (cross-tool compatibility)", + " Option 3: Create AGENTS.md and reference it with @AGENTS.md in minimal CLAUDE.md", + "Add project overview and purpose", + "Document key architectural patterns", + "Specify coding standards and conventions", + "Include build/test/deployment commands", + "Add any project-specific context that helps AI assistants" + ], + "tools": [], + "commands": [ + "# Option 1: Standalone CLAUDE.md", + "touch CLAUDE.md", + "# Add content describing your project", + "", + "# Option 2: Symlink CLAUDE.md to AGENTS.md", + "touch AGENTS.md", + "# Add content to AGENTS.md", + "ln -s AGENTS.md CLAUDE.md", + "", + "# Option 3: @ reference in CLAUDE.md", + "echo '@AGENTS.md' > CLAUDE.md", + "touch AGENTS.md", + "# Add content to AGENTS.md" + ], + "examples": [ + "# Standalone CLAUDE.md (Option 1)\n\n## Overview\nBrief description of what this project does.\n\n## Architecture\nKey patterns and structure.\n\n## Development\n```bash\n# Install dependencies\nnpm install\n\n# Run tests\nnpm test\n\n# Build\nnpm run build\n```\n\n## Coding Standards\n- Use TypeScript strict mode\n- Follow ESLint configuration\n- Write tests for new features\n", + "# CLAUDE.md with @ reference (Option 3)\n@AGENTS.md\n", + "# AGENTS.md (shared by multiple tools)\n\n## Project Overview\nThis project implements a REST API for user management.\n\n## Architecture\n- Layered architecture: controllers, services, repositories\n- PostgreSQL database with SQLAlchemy ORM\n- FastAPI web framework\n\n## Development Workflow\n```bash\n# Setup\npython -m venv .venv\nsource .venv/bin/activate\npip install -e .\n\n# Run tests\npytest\n\n# Start server\nuvicorn app.main:app --reload\n```\n\n## Code Conventions\n- Use type hints for all functions\n- Follow PEP 8 style guide\n- Write docstrings for public APIs\n- Maintain >80% test coverage\n" + ], + "citations": [ + { + "source": "Anthropic", + "title": "Claude Code Documentation", + "url": "https://docs.anthropic.com/claude-code", + "relevance": "Official guidance on CLAUDE.md configuration" + }, + { + "source": "agents.md", + "title": "AGENTS.md Specification", + "url": "https://agents.md/", + "relevance": "Emerging standard for cross-tool AI assistant configuration" + } + ] + }, + "error_message": null + }, + { + "attribute": { + "id": "readme_structure", + "name": "README Structure", + "category": "Documentation Standards", + "tier": 1, + "description": "Well-structured README with key sections", + "criteria": "README.md with installation, usage, and development sections", + "default_weight": 0.1 + }, + "status": "pass", + "score": 100.0, + "measured_value": "3/3 sections", + "threshold": "3/3 sections", + "evidence": [ + "Found 3/3 essential sections", + "Installation: \u2713", + "Usage: \u2713", + "Development: \u2713" + ], + "remediation": null, + "error_message": null + }, + { + "attribute": { + "id": "type_annotations", + "name": "Type Annotations", + "category": "Code Quality", + "tier": 1, + "description": "Type hints in function signatures", + "criteria": ">80% of functions have type annotations", + "default_weight": 0.1 + }, + "status": "fail", + "score": 37.32082952119549, + "measured_value": "29.9%", + "threshold": "\u226580%", + "evidence": [ + "Typed functions: 979/3279", + "Coverage: 29.9%" + ], + "remediation": { + "summary": "Add type annotations to function signatures", + "steps": [ + "For Python: Add type hints to function parameters and return types", + "For TypeScript: Enable strict mode in tsconfig.json", + "Use mypy or pyright for Python type checking", + "Use tsc --strict for TypeScript", + "Add type annotations gradually to existing code" + ], + "tools": [ + "mypy", + "pyright", + "typescript" + ], + "commands": [ + "# Python", + "pip install mypy", + "mypy --strict src/", + "", + "# TypeScript", + "npm install --save-dev typescript", + "echo '{\"compilerOptions\": {\"strict\": true}}' > tsconfig.json" + ], + "examples": [ + "# Python - Before\ndef calculate(x, y):\n return x + y\n\n# Python - After\ndef calculate(x: float, y: float) -> float:\n return x + y\n", + "// TypeScript - tsconfig.json\n{\n \"compilerOptions\": {\n \"strict\": true,\n \"noImplicitAny\": true,\n \"strictNullChecks\": true\n }\n}\n" + ], + "citations": [ + { + "source": "Python.org", + "title": "Type Hints", + "url": "https://docs.python.org/3/library/typing.html", + "relevance": "Official Python type hints documentation" + }, + { + "source": "TypeScript", + "title": "TypeScript Handbook", + "url": "https://www.typescriptlang.org/docs/handbook/2/everyday-types.html", + "relevance": "TypeScript type system guide" + } + ] + }, + "error_message": null + }, + { + "attribute": { + "id": "standard_layout", + "name": "Standard Project Layouts", + "category": "Repository Structure", + "tier": 1, + "description": "Follows standard project structure for language", + "criteria": "Standard directories (src/, tests/, docs/) present", + "default_weight": 0.1 + }, + "status": "fail", + "score": 50.0, + "measured_value": "1/2 directories", + "threshold": "2/2 directories", + "evidence": [ + "Found 1/2 standard directories", + "src/: \u2717", + "tests/: \u2713" + ], + "remediation": { + "summary": "Organize code into standard directories (src/, tests/, docs/)", + "steps": [ + "Create src/ directory for source code", + "Create tests/ directory for test files", + "Create docs/ directory for documentation", + "Move source code into src/", + "Move tests into tests/" + ], + "tools": [], + "commands": [ + "mkdir -p src tests docs", + "# Move source files to src/", + "# Move test files to tests/" + ], + "examples": [], + "citations": [ + { + "source": "Python Packaging Authority", + "title": "Python Project Structure", + "url": "https://packaging.python.org/en/latest/tutorials/packaging-projects/", + "relevance": "Standard Python project layout" + } + ] + }, + "error_message": null + }, + { + "attribute": { + "id": "lock_files", + "name": "Dependency Pinning for Reproducibility", + "category": "Dependency Management", + "tier": 1, + "description": "Dependencies pinned to exact versions in lock files", + "criteria": "Lock file with pinned versions, updated within 6 months", + "default_weight": 0.1 + }, + "status": "pass", + "score": 100.0, + "measured_value": "poetry.lock, requirements.txt", + "threshold": "lock file with pinned versions, < 6 months old", + "evidence": [ + "Found lock file(s): poetry.lock" + ], + "remediation": null, + "error_message": null + }, + { + "attribute": { + "id": "dependency_security", + "name": "Dependency Security & Vulnerability Scanning", + "category": "Security", + "tier": 1, + "description": "Security scanning tools configured for dependencies and code", + "criteria": "Dependabot, CodeQL, or SAST tools configured; secret detection enabled", + "default_weight": 0.04 + }, + "status": "pass", + "score": 40, + "measured_value": "Security tools configured: Dependabot", + "threshold": "\u226560 points (Dependabot + SAST or multiple scanners)", + "evidence": [ + "\u2713 Dependabot configured for dependency alerts", + " 2 package ecosystem(s) monitored", + "\u2713 SECURITY.md present (vulnerability disclosure policy)" + ], + "remediation": { + "summary": "Add more security scanning tools for comprehensive coverage", + "steps": [ + "Enable Dependabot alerts in GitHub repository settings", + "Add CodeQL scanning workflow for SAST", + "Configure secret detection (detect-secrets, gitleaks)", + "Set up language-specific scanners (pip-audit, npm audit, Snyk)" + ], + "tools": [ + "Dependabot", + "CodeQL", + "detect-secrets", + "pip-audit", + "npm audit" + ], + "commands": [ + "gh repo edit --enable-security", + "pip install detect-secrets # Python secret detection", + "npm audit # JavaScript dependency audit" + ], + "examples": [ + "# .github/dependabot.yml\nversion: 2\nupdates:\n - package-ecosystem: pip\n directory: /\n schedule:\n interval: weekly" + ], + "citations": [ + { + "source": "OWASP", + "title": "Dependency-Check Project", + "url": "https://owasp.org/www-project-dependency-check/", + "relevance": "Open-source tool for detecting known vulnerabilities in dependencies" + }, + { + "source": "GitHub", + "title": "Dependabot Documentation", + "url": "https://docs.github.com/en/code-security/dependabot", + "relevance": "Official guide for configuring automated dependency updates and security alerts" + } + ] + }, + "error_message": null + }, + { + "attribute": { + "id": "test_coverage", + "name": "Test Coverage Requirements", + "category": "Testing & CI/CD", + "tier": 2, + "description": "Test coverage thresholds configured and enforced", + "criteria": ">80% code coverage", + "default_weight": 0.03 + }, + "status": "pass", + "score": 100.0, + "measured_value": "configured", + "threshold": "configured with >80% threshold", + "evidence": [ + "Coverage configuration found", + "pytest-cov dependency present" + ], + "remediation": null, + "error_message": null + }, + { + "attribute": { + "id": "precommit_hooks", + "name": "Pre-commit Hooks & CI/CD Linting", + "category": "Testing & CI/CD", + "tier": 2, + "description": "Pre-commit hooks configured for linting and formatting", + "criteria": ".pre-commit-config.yaml exists", + "default_weight": 0.03 + }, + "status": "pass", + "score": 100.0, + "measured_value": "configured", + "threshold": "configured", + "evidence": [ + ".pre-commit-config.yaml found" + ], + "remediation": null, + "error_message": null + }, + { + "attribute": { + "id": "conventional_commits", + "name": "Conventional Commit Messages", + "category": "Git & Version Control", + "tier": 2, + "description": "Follows conventional commit format", + "criteria": "\u226580% of recent commits follow convention", + "default_weight": 0.03 + }, + "status": "fail", + "score": 0.0, + "measured_value": "not configured", + "threshold": "configured", + "evidence": [ + "No commitlint or husky configuration" + ], + "remediation": { + "summary": "Configure conventional commits with commitlint", + "steps": [ + "Install commitlint", + "Configure husky for commit-msg hook" + ], + "tools": [ + "commitlint", + "husky" + ], + "commands": [ + "npm install --save-dev @commitlint/cli @commitlint/config-conventional husky" + ], + "examples": [], + "citations": [] + }, + "error_message": null + }, + { + "attribute": { + "id": "gitignore_completeness", + "name": ".gitignore Completeness", + "category": "Git & Version Control", + "tier": 2, + "description": "Comprehensive .gitignore file with language-specific patterns", + "criteria": ".gitignore exists and includes language-specific patterns from GitHub templates", + "default_weight": 0.03 + }, + "status": "pass", + "score": 70.58823529411765, + "measured_value": "12/17 patterns", + "threshold": "\u226570% of language-specific patterns", + "evidence": [ + ".gitignore found (908 bytes)", + "Pattern coverage: 12/17 (71%)", + "Missing 5 recommended patterns" + ], + "remediation": null, + "error_message": null + }, + { + "attribute": { + "id": "one_command_setup", + "name": "One-Command Build/Setup", + "category": "Build & Development", + "tier": 2, + "description": "Single command to set up development environment from fresh clone", + "criteria": "Single command (make setup, npm install, etc.) documented prominently", + "default_weight": 0.03 + }, + "status": "pass", + "score": 100, + "measured_value": "To install", + "threshold": "single command", + "evidence": [ + "Setup command found in README: 'To install'", + "Setup automation found: Makefile, pyproject.toml", + "Setup instructions in prominent location" + ], + "remediation": null, + "error_message": null + }, + { + "attribute": { + "id": "file_size_limits", + "name": "File Size Limits", + "category": "Context Window Optimization", + "tier": 2, + "description": "Files are reasonably sized for AI context windows", + "criteria": "<5% of files >500 lines, no files >1000 lines", + "default_weight": 0.03 + }, + "status": "fail", + "score": 42.41379310344827, + "measured_value": "16 huge, 29 large out of 580", + "threshold": "<5% files >500 lines, 0 files >1000 lines", + "evidence": [ + "Found 16 files >1000 lines (2.8% of 580 files)", + "Largest: docs/colang-2/examples/csl.py (1096 lines)" + ], + "remediation": { + "summary": "Refactor large files into smaller, focused modules", + "steps": [ + "Identify files >1000 lines", + "Split into logical submodules", + "Extract classes/functions into separate files", + "Maintain single responsibility principle" + ], + "tools": [ + "refactoring tools", + "linters" + ], + "commands": [], + "examples": [ + "# Split large file:\n# models.py (1500 lines) \u2192 models/user.py, models/product.py, models/order.py" + ], + "citations": [] + }, + "error_message": null + }, + { + "attribute": { + "id": "separation_of_concerns", + "name": "Separation of Concerns", + "category": "Code Organization", + "tier": 2, + "description": "Code organized with single responsibility per module", + "criteria": "Feature-based organization, cohesive modules, low coupling", + "default_weight": 0.03 + }, + "status": "fail", + "score": 67.62741652021089, + "measured_value": "organization:100, cohesion:92, naming:0", + "threshold": "\u226575 overall", + "evidence": [ + "Good directory organization (feature-based or flat)", + "File cohesion: 45/569 files >500 lines", + "Anti-pattern files found: utils.py, utils.py, utils.py" + ], + "remediation": { + "summary": "Refactor code to improve separation of concerns", + "steps": [ + "Avoid layer-based directories (models/, views/, controllers/)", + "Organize by feature/domain instead (auth/, users/, billing/)", + "Break large files (>500 lines) into focused modules", + "Eliminate catch-all modules (utils.py, helpers.py)", + "Each module should have single, well-defined responsibility", + "Group related functions/classes by domain, not technical layer" + ], + "tools": [], + "commands": [], + "examples": [ + "# Good: Feature-based organization\nproject/\n\u251c\u2500\u2500 auth/\n\u2502 \u251c\u2500\u2500 login.py\n\u2502 \u251c\u2500\u2500 signup.py\n\u2502 \u2514\u2500\u2500 tokens.py\n\u251c\u2500\u2500 users/\n\u2502 \u251c\u2500\u2500 profile.py\n\u2502 \u2514\u2500\u2500 preferences.py\n\u2514\u2500\u2500 billing/\n \u251c\u2500\u2500 invoices.py\n \u2514\u2500\u2500 payments.py\n\n# Bad: Layer-based organization\nproject/\n\u251c\u2500\u2500 models/\n\u2502 \u251c\u2500\u2500 user.py\n\u2502 \u251c\u2500\u2500 invoice.py\n\u251c\u2500\u2500 views/\n\u2502 \u251c\u2500\u2500 user_view.py\n\u2502 \u251c\u2500\u2500 invoice_view.py\n\u2514\u2500\u2500 controllers/\n \u251c\u2500\u2500 user_controller.py\n \u251c\u2500\u2500 invoice_controller.py\n" + ], + "citations": [ + { + "source": "Martin Fowler", + "title": "PresentationDomainDataLayering", + "url": "https://martinfowler.com/bliki/PresentationDomainDataLayering.html", + "relevance": "Explains layering vs feature organization" + }, + { + "source": "Uncle Bob Martin", + "title": "The Single Responsibility Principle", + "url": "https://blog.cleancoder.com/uncle-bob/2014/05/08/SingleReponsibilityPrinciple.html", + "relevance": "Core SRP principle for module design" + } + ] + }, + "error_message": null + }, + { + "attribute": { + "id": "concise_documentation", + "name": "Concise Documentation", + "category": "Documentation", + "tier": 2, + "description": "Documentation maximizes information density while minimizing token consumption", + "criteria": "README <500 lines with clear structure, bullet points over prose", + "default_weight": 0.03 + }, + "status": "fail", + "score": 72.0, + "measured_value": "337 lines, 25 headings, 8 bullets", + "threshold": "<500 lines, structured format", + "evidence": [ + "README length: 337 lines (good)", + "Heading density: 7.4 per 100 lines (target: 3-5)", + "Only 8 bullet points (prefer bullets over prose)" + ], + "remediation": { + "summary": "Make documentation more concise and structured", + "steps": [ + "Break long README into multiple documents (docs/ directory)", + "Add clear Markdown headings (##, ###) for structure", + "Convert prose paragraphs to bullet points where possible", + "Add table of contents for documents >100 lines", + "Use code blocks instead of describing commands in prose", + "Move detailed content to wiki or docs/, keep README focused" + ], + "tools": [], + "commands": [ + "# Check README length", + "wc -l README.md", + "", + "# Count headings", + "grep -c '^#' README.md" + ], + "examples": [ + "# Good: Concise with structure\n\n## Quick Start\n```bash\npip install -e .\nagentready assess .\n```\n\n## Features\n- Fast repository scanning\n- HTML and Markdown reports\n- 25 agent-ready attributes\n\n## Documentation\nSee [docs/](docs/) for detailed guides.\n", + "# Bad: Verbose prose\n\nThis project is a tool that helps you assess your repository\nagainst best practices for AI-assisted development. It works by\nscanning your codebase and checking for various attributes that\nmake repositories more effective when working with AI coding\nassistants like Claude Code...\n\n[Many more paragraphs of prose...]\n" + ], + "citations": [ + { + "source": "ArXiv", + "title": "LongCodeBench: Evaluating Coding LLMs at 1M Context Windows", + "url": "https://arxiv.org/abs/2501.00343", + "relevance": "Research showing performance degradation with long contexts" + }, + { + "source": "Markdown Guide", + "title": "Basic Syntax", + "url": "https://www.markdownguide.org/basic-syntax/", + "relevance": "Best practices for Markdown formatting" + } + ] + }, + "error_message": null + }, + { + "attribute": { + "id": "inline_documentation", + "name": "Inline Documentation", + "category": "Documentation", + "tier": 2, + "description": "Function, class, and module-level documentation using language-specific conventions", + "criteria": "\u226580% of public functions/classes have docstrings", + "default_weight": 0.03 + }, + "status": "fail", + "score": 67.28523228652999, + "measured_value": "53.8%", + "threshold": "\u226580%", + "evidence": [ + "Documented items: 2074/3853", + "Coverage: 53.8%", + "Many public functions/classes lack docstrings" + ], + "remediation": { + "summary": "Add docstrings to public functions and classes", + "steps": [ + "Identify functions/classes without docstrings", + "Add PEP 257 compliant docstrings for Python", + "Add JSDoc comments for JavaScript/TypeScript", + "Include: description, parameters, return values, exceptions", + "Add examples for complex functions", + "Run pydocstyle to validate docstring format" + ], + "tools": [ + "pydocstyle", + "jsdoc" + ], + "commands": [ + "# Install pydocstyle", + "pip install pydocstyle", + "", + "# Check docstring coverage", + "pydocstyle src/", + "", + "# Generate documentation", + "pip install sphinx", + "sphinx-apidoc -o docs/ src/" + ], + "examples": [ + "# Python - Good docstring\ndef calculate_discount(price: float, discount_percent: float) -> float:\n \"\"\"Calculate discounted price.\n\n Args:\n price: Original price in USD\n discount_percent: Discount percentage (0-100)\n\n Returns:\n Discounted price\n\n Raises:\n ValueError: If discount_percent not in 0-100 range\n\n Example:\n >>> calculate_discount(100.0, 20.0)\n 80.0\n \"\"\"\n if not 0 <= discount_percent <= 100:\n raise ValueError(\"Discount must be 0-100\")\n return price * (1 - discount_percent / 100)\n", + "// JavaScript - Good JSDoc\n/**\n * Calculate discounted price\n *\n * @param {number} price - Original price in USD\n * @param {number} discountPercent - Discount percentage (0-100)\n * @returns {number} Discounted price\n * @throws {Error} If discountPercent not in 0-100 range\n * @example\n * calculateDiscount(100.0, 20.0)\n * // Returns: 80.0\n */\nfunction calculateDiscount(price, discountPercent) {\n if (discountPercent < 0 || discountPercent > 100) {\n throw new Error(\"Discount must be 0-100\");\n }\n return price * (1 - discountPercent / 100);\n}\n" + ], + "citations": [ + { + "source": "Python.org", + "title": "PEP 257 - Docstring Conventions", + "url": "https://peps.python.org/pep-0257/", + "relevance": "Python docstring standards" + }, + { + "source": "TypeScript", + "title": "TSDoc Reference", + "url": "https://tsdoc.org/", + "relevance": "TypeScript documentation standard" + } + ] + }, + "error_message": null + }, + { + "attribute": { + "id": "cyclomatic_complexity", + "name": "Cyclomatic Complexity Thresholds", + "category": "Code Quality", + "tier": 3, + "description": "Cyclomatic complexity thresholds enforced", + "criteria": "Average complexity <10, no functions >15", + "default_weight": 0.03 + }, + "status": "skipped", + "score": null, + "measured_value": null, + "threshold": null, + "evidence": [ + "Missing tool: radon" + ], + "remediation": { + "summary": "Install with: pip install radon", + "steps": [ + "Install with: pip install radon" + ], + "tools": [], + "commands": [], + "examples": [], + "citations": [] + }, + "error_message": null + }, + { + "attribute": { + "id": "architecture_decisions", + "name": "Architecture Decision Records (ADRs)", + "category": "Documentation Standards", + "tier": 3, + "description": "Lightweight documents capturing architectural decisions", + "criteria": "ADR directory with documented decisions", + "default_weight": 0.015 + }, + "status": "fail", + "score": 0.0, + "measured_value": "no ADR directory", + "threshold": "ADR directory with decisions", + "evidence": [ + "No ADR directory found (checked docs/adr/, .adr/, adr/, docs/decisions/)" + ], + "remediation": { + "summary": "Create Architecture Decision Records (ADRs) directory and document key decisions", + "steps": [ + "Create docs/adr/ directory in repository root", + "Use Michael Nygard ADR template or MADR format", + "Document each significant architectural decision", + "Number ADRs sequentially (0001-*.md, 0002-*.md)", + "Include Status, Context, Decision, and Consequences sections", + "Update ADR status when decisions are revised (Superseded, Deprecated)" + ], + "tools": [ + "adr-tools", + "log4brains" + ], + "commands": [ + "# Create ADR directory", + "mkdir -p docs/adr", + "", + "# Create first ADR using template", + "cat > docs/adr/0001-use-architecture-decision-records.md << 'EOF'", + "# 1. Use Architecture Decision Records", + "", + "Date: 2025-11-22", + "", + "## Status", + "Accepted", + "", + "## Context", + "We need to record architectural decisions made in this project.", + "", + "## Decision", + "We will use Architecture Decision Records (ADRs) as described by Michael Nygard.", + "", + "## Consequences", + "- Decisions are documented with context", + "- Future contributors understand rationale", + "- ADRs are lightweight and version-controlled", + "EOF" + ], + "examples": [ + "# Example ADR Structure\n\n```markdown\n# 2. Use PostgreSQL for Database\n\nDate: 2025-11-22\n\n## Status\nAccepted\n\n## Context\nWe need a relational database for complex queries and ACID transactions.\nTeam has PostgreSQL experience. Need full-text search capabilities.\n\n## Decision\nUse PostgreSQL 15+ as primary database.\n\n## Consequences\n- Positive: Robust ACID, full-text search, team familiarity\n- Negative: Higher resource usage than SQLite\n- Neutral: Need to manage migrations, backups\n```\n" + ], + "citations": [ + { + "source": "Michael Nygard", + "title": "Documenting Architecture Decisions", + "url": "https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions", + "relevance": "Original ADR format and rationale" + }, + { + "source": "GitHub adr/madr", + "title": "Markdown ADR (MADR) Template", + "url": "https://github.com/adr/madr", + "relevance": "Modern ADR template with examples" + } + ] + }, + "error_message": null + }, + { + "attribute": { + "id": "issue_pr_templates", + "name": "Issue & Pull Request Templates", + "category": "Repository Structure", + "tier": 3, + "description": "Standardized templates for issues and PRs", + "criteria": "PR template and issue templates in .github/", + "default_weight": 0.015 + }, + "status": "pass", + "score": 100, + "measured_value": "PR:True, Issues:6", + "threshold": "PR template + \u22652 issue templates", + "evidence": [ + "PR template found", + "Issue templates found: 6 templates" + ], + "remediation": null, + "error_message": null + }, + { + "attribute": { + "id": "cicd_pipeline_visibility", + "name": "CI/CD Pipeline Visibility", + "category": "Testing & CI/CD", + "tier": 3, + "description": "Clear, well-documented CI/CD configuration files", + "criteria": "CI config with descriptive names, caching, parallelization", + "default_weight": 0.015 + }, + "status": "pass", + "score": 80, + "measured_value": "configured with best practices", + "threshold": "CI with best practices", + "evidence": [ + "CI config found: .github/workflows/release.yml, .github/workflows/test-published-dist.yml, .github/workflows/security.yml, .github/workflows/_test.yml, .github/workflows/latest-deps-tests.yml, .github/workflows/lint.yml, .github/workflows/push-server-image.yml, .github/workflows/pr-tests-skip.yml, .github/workflows/pr-tests.yml, .github/workflows/full-tests.yml, .github/workflows/test-and-build-wheel.yml, .github/workflows/tests.yml, .github/workflows/agentready-assessment.yml, .github/workflows/test-docker.yml, .github/workflows/create-tag.yml, .github/workflows/publish-wheel.yml, .github/workflows/publish-pypi-approval.yml, .github/workflows/docs-build.yaml, .github/workflows/docs-preview-pr.yaml, .github/workflows/docs-remove-stale-reviews.yaml, .gitlab-ci.yml", + "Descriptive job/step names found", + "No caching detected", + "Parallel job execution detected", + "Config includes comments" + ], + "remediation": null, + "error_message": null + }, + { + "attribute": { + "id": "semantic_naming", + "name": "Semantic Naming", + "category": "Code Quality", + "tier": 3, + "description": "Systematic naming patterns following language conventions", + "criteria": "Language conventions followed, avoid generic names", + "default_weight": 0.015 + }, + "status": "pass", + "score": 99.25, + "measured_value": "functions:99%, classes:100%", + "threshold": "\u226575% compliance", + "evidence": [ + "Functions: 158/160 follow snake_case (98.8%)", + "Classes: 45/45 follow PascalCase (100.0%)", + "No generic names (temp, data, obj) detected" + ], + "remediation": null, + "error_message": null + }, + { + "attribute": { + "id": "structured_logging", + "name": "Structured Logging", + "category": "Code Quality", + "tier": 3, + "description": "Logging in structured format (JSON) with consistent fields", + "criteria": "Structured logging library configured (structlog, winston, zap)", + "default_weight": 0.015 + }, + "status": "fail", + "score": 0.0, + "measured_value": "not configured", + "threshold": "structured logging library", + "evidence": [ + "No structured logging library found", + "Checked files: pyproject.toml, requirements.txt", + "Using built-in logging module (unstructured)" + ], + "remediation": { + "summary": "Add structured logging library for machine-parseable logs", + "steps": [ + "Choose structured logging library (structlog for Python, winston for Node.js)", + "Install library and configure JSON formatter", + "Add standard fields: timestamp, level, message, context", + "Include request context: request_id, user_id, session_id", + "Use consistent field naming (snake_case for Python)", + "Never log sensitive data (passwords, tokens, PII)", + "Configure different formats for dev (pretty) and prod (JSON)" + ], + "tools": [ + "structlog", + "winston", + "zap" + ], + "commands": [ + "# Install structlog", + "pip install structlog", + "", + "# Configure structlog", + "# See examples for configuration" + ], + "examples": [ + "# Python with structlog\nimport structlog\n\n# Configure structlog\nstructlog.configure(\n processors=[\n structlog.stdlib.add_log_level,\n structlog.processors.TimeStamper(fmt=\"iso\"),\n structlog.processors.JSONRenderer()\n ]\n)\n\nlogger = structlog.get_logger()\n\n# Good: Structured logging\nlogger.info(\n \"user_login\",\n user_id=\"123\",\n email=\"user@example.com\",\n ip_address=\"192.168.1.1\"\n)\n\n# Bad: Unstructured logging\nlogger.info(f\"User {user_id} logged in from {ip}\")\n" + ], + "citations": [ + { + "source": "structlog", + "title": "structlog Documentation", + "url": "https://www.structlog.org/en/stable/", + "relevance": "Python structured logging library" + } + ] + }, + "error_message": null + }, + { + "attribute": { + "id": "openapi_specs", + "name": "OpenAPI/Swagger Specifications", + "category": "API Documentation", + "tier": 3, + "description": "Machine-readable API documentation in OpenAPI format", + "criteria": "OpenAPI 3.x spec with complete endpoint documentation", + "default_weight": 0.015 + }, + "status": "fail", + "score": 0.0, + "measured_value": "no OpenAPI spec", + "threshold": "OpenAPI 3.x spec present", + "evidence": [ + "No OpenAPI specification found", + "Searched recursively for: openapi.yaml, openapi.yml, openapi.json, swagger.yaml, swagger.yml, swagger.json" + ], + "remediation": { + "summary": "Create OpenAPI specification for API endpoints", + "steps": [ + "Create openapi.yaml in repository root", + "Define OpenAPI version 3.x", + "Document all API endpoints with full schemas", + "Add request/response examples", + "Define security schemes (API keys, OAuth, etc.)", + "Validate spec with Swagger Editor or Spectral", + "Generate API documentation with Swagger UI or ReDoc" + ], + "tools": [ + "swagger-editor", + "spectral", + "openapi-generator" + ], + "commands": [ + "# Install OpenAPI validator", + "npm install -g @stoplight/spectral-cli", + "", + "# Validate spec", + "spectral lint openapi.yaml", + "", + "# Generate client SDK", + "npx @openapitools/openapi-generator-cli generate \\", + " -i openapi.yaml \\", + " -g python \\", + " -o client/" + ], + "examples": [ + "# openapi.yaml - Minimal example\nopenapi: 3.1.0\ninfo:\n title: My API\n version: 1.0.0\n description: API for managing users\n\nservers:\n - url: https://api.example.com/v1\n\npaths:\n /users/{userId}:\n get:\n summary: Get user by ID\n parameters:\n - name: userId\n in: path\n required: true\n schema:\n type: string\n responses:\n '200':\n description: User found\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/User'\n '404':\n description: User not found\n\ncomponents:\n schemas:\n User:\n type: object\n required:\n - id\n - email\n properties:\n id:\n type: string\n example: \"user_123\"\n email:\n type: string\n format: email\n example: \"user@example.com\"\n name:\n type: string\n example: \"John Doe\"\n" + ], + "citations": [ + { + "source": "OpenAPI Initiative", + "title": "OpenAPI Specification", + "url": "https://spec.openapis.org/oas/v3.1.0", + "relevance": "Official OpenAPI 3.1 specification" + }, + { + "source": "Swagger", + "title": "API Documentation Best Practices", + "url": "https://swagger.io/resources/articles/best-practices-in-api-documentation/", + "relevance": "Guide to writing effective API docs" + } + ] + }, + "error_message": null + }, + { + "attribute": { + "id": "branch_protection", + "name": "Branch Protection Rules", + "category": "Git & Version Control", + "tier": 4, + "description": "Required status checks and review approvals before merging", + "criteria": "Branch protection enabled with status checks and required reviews", + "default_weight": 0.005 + }, + "status": "not_applicable", + "score": null, + "measured_value": null, + "threshold": null, + "evidence": [ + "Requires GitHub API integration for branch protection checks. Future implementation will verify: required status checks, required reviews, force push prevention, and branch update requirements." + ], + "remediation": null, + "error_message": null + }, + { + "attribute": { + "id": "code_smells", + "name": "Code Smell Elimination", + "category": "Code Quality", + "tier": 4, + "description": "Linter configuration for detecting code smells and anti-patterns", + "criteria": "Language-specific linters configured (pylint, ESLint, RuboCop, etc.)", + "default_weight": 0.01 + }, + "status": "fail", + "score": 50.0, + "measured_value": "pylint, ruff", + "threshold": "\u226560% of applicable linters configured", + "evidence": [ + "Linters configured: pylint, ruff", + "Coverage: 40/80 points (50%)" + ], + "remediation": { + "summary": "Configure 3 missing linter(s)", + "steps": [ + "Configure ESLint for JavaScript/TypeScript", + "Add actionlint for GitHub Actions workflow validation", + "Configure markdownlint for documentation quality" + ], + "tools": [ + "ESLint", + "actionlint", + "markdownlint" + ], + "commands": [ + "npm install --save-dev eslint && npx eslint --init", + "npm install --save-dev markdownlint-cli && touch .markdownlint.json" + ], + "examples": [ + "# .pylintrc example\n[MASTER]\nmax-line-length=100\n\n[MESSAGES CONTROL]\ndisable=C0111", + "# .eslintrc.json example\n{\n \"extends\": \"eslint:recommended\",\n \"rules\": {\n \"no-console\": \"warn\"\n }\n}" + ], + "citations": [ + { + "source": "Pylint", + "title": "Pylint Documentation", + "url": "https://pylint.readthedocs.io/", + "relevance": "Official documentation for Pylint code analysis tool" + }, + { + "source": "ESLint", + "title": "ESLint Documentation", + "url": "https://eslint.org/docs/latest/", + "relevance": "Official documentation for ESLint JavaScript/TypeScript linter" + } + ] + }, + "error_message": null + }, + { + "attribute": { + "id": "container_setup", + "name": "Container/Virtualization Setup", + "category": "Build & Development", + "tier": 4, + "description": "Container configuration for consistent development environments", + "criteria": "Dockerfile/Containerfile, docker-compose.yml, .dockerignore, multi-stage builds", + "default_weight": 0.01 + }, + "status": "pass", + "score": 60, + "measured_value": "60 points", + "threshold": "\u226570 points (Dockerfile + compose + .dockerignore)", + "evidence": [ + "\u2713 Dockerfile present", + "\u2139\ufe0f Single-stage build (consider multi-stage for smaller images)", + "\u2713 .dockerignore present (excludes unnecessary files)" + ], + "remediation": { + "summary": "Improve container configuration", + "steps": [ + "Add docker-compose.yml for multi-service development", + "Create .dockerignore to exclude build artifacts and secrets", + "Consider multi-stage builds to reduce image size" + ], + "tools": [ + "docker", + "podman", + "docker-compose" + ], + "commands": [ + "docker build -t myapp .", + "docker-compose up -d" + ], + "examples": [ + "# .dockerignore example\n.git\n.venv\n__pycache__\n*.pyc\n.env\nnode_modules", + "# Multi-stage Dockerfile example\nFROM node:18 AS builder\nWORKDIR /app\nCOPY . .\nRUN npm ci && npm run build\n\nFROM node:18-alpine\nWORKDIR /app\nCOPY --from=builder /app/dist ./dist\nCMD [\"node\", \"dist/index.js\"]" + ], + "citations": [ + { + "source": "Docker", + "title": "Dockerfile Best Practices", + "url": "https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", + "relevance": "Official Docker guide for writing efficient and secure Dockerfiles" + } + ] + }, + "error_message": null + } + ], + "config": { + "weights": {}, + "excluded_attributes": [], + "language_overrides": {}, + "output_dir": null, + "report_theme": "default", + "custom_theme": null + }, + "duration_seconds": 2.1, + "discovered_skills": [] +} \ No newline at end of file diff --git a/.agentready/assessment-latest.json b/.agentready/assessment-latest.json new file mode 120000 index 0000000000..565b7c612a --- /dev/null +++ b/.agentready/assessment-latest.json @@ -0,0 +1 @@ +assessment-20260212-110150.json \ No newline at end of file diff --git a/.agentready/report-20260212-110150.html b/.agentready/report-20260212-110150.html new file mode 100644 index 0000000000..a919687261 --- /dev/null +++ b/.agentready/report-20260212-110150.html @@ -0,0 +1,2922 @@ + + +
+ + + +main @ 938fdf8190-100
+75-89
+60-74
+40-59
+0-39
+Create CLAUDE.md or AGENTS.md with project-specific configuration for AI coding assistants
+ + +# Option 1: Standalone CLAUDE.md
+touch CLAUDE.md
+# Add content describing your project
+
+# Option 2: Symlink CLAUDE.md to AGENTS.md
+touch AGENTS.md
+# Add content to AGENTS.md
+ln -s AGENTS.md CLAUDE.md
+
+# Option 3: @ reference in CLAUDE.md
+echo '@AGENTS.md' > CLAUDE.md
+touch AGENTS.md
+# Add content to AGENTS.md
+
+
+
+ # Standalone CLAUDE.md (Option 1)
+
+## Overview
+Brief description of what this project does.
+
+## Architecture
+Key patterns and structure.
+
+## Development
+```bash
+# Install dependencies
+npm install
+
+# Run tests
+npm test
+
+# Build
+npm run build
+```
+
+## Coding Standards
+- Use TypeScript strict mode
+- Follow ESLint configuration
+- Write tests for new features
+
+
+ # CLAUDE.md with @ reference (Option 3)
+@AGENTS.md
+
+
+ # AGENTS.md (shared by multiple tools)
+
+## Project Overview
+This project implements a REST API for user management.
+
+## Architecture
+- Layered architecture: controllers, services, repositories
+- PostgreSQL database with SQLAlchemy ORM
+- FastAPI web framework
+
+## Development Workflow
+```bash
+# Setup
+python -m venv .venv
+source .venv/bin/activate
+pip install -e .
+
+# Run tests
+pytest
+
+# Start server
+uvicorn app.main:app --reload
+```
+
+## Code Conventions
+- Use type hints for all functions
+- Follow PEP 8 style guide
+- Write docstrings for public APIs
+- Maintain >80% test coverage
+
+
+
+ Add type annotations to function signatures
+ + +# Python
+pip install mypy
+mypy --strict src/
+
+# TypeScript
+npm install --save-dev typescript
+echo '{"compilerOptions": {"strict": true}}' > tsconfig.json
+
+
+
+ # Python - Before
+def calculate(x, y):
+ return x + y
+
+# Python - After
+def calculate(x: float, y: float) -> float:
+ return x + y
+
+
+ // TypeScript - tsconfig.json
+{
+ "compilerOptions": {
+ "strict": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true
+ }
+}
+
+
+
+ Organize code into standard directories (src/, tests/, docs/)
+ + +mkdir -p src tests docs
+# Move source files to src/
+# Move test files to tests/
+
+
+
+ Add more security scanning tools for comprehensive coverage
+ + +gh repo edit --enable-security
+pip install detect-secrets # Python secret detection
+npm audit # JavaScript dependency audit
+
+
+
+ # .github/dependabot.yml
+version: 2
+updates:
+ - package-ecosystem: pip
+ directory: /
+ schedule:
+ interval: weekly
+
+
+ Configure conventional commits with commitlint
+ + +npm install --save-dev @commitlint/cli @commitlint/config-conventional husky
+
+
+
+ Refactor large files into smaller, focused modules
+ + +# Split large file:
+# models.py (1500 lines) → models/user.py, models/product.py, models/order.py
+
+
+ Refactor code to improve separation of concerns
+ + +# Good: Feature-based organization
+project/
+├── auth/
+│ ├── login.py
+│ ├── signup.py
+│ └── tokens.py
+├── users/
+│ ├── profile.py
+│ └── preferences.py
+└── billing/
+ ├── invoices.py
+ └── payments.py
+
+# Bad: Layer-based organization
+project/
+├── models/
+│ ├── user.py
+│ ├── invoice.py
+├── views/
+│ ├── user_view.py
+│ ├── invoice_view.py
+└── controllers/
+ ├── user_controller.py
+ ├── invoice_controller.py
+
+
+
+ Make documentation more concise and structured
+ + +# Check README length
+wc -l README.md
+
+# Count headings
+grep -c '^#' README.md
+
+
+
+ # Good: Concise with structure
+
+## Quick Start
+```bash
+pip install -e .
+agentready assess .
+```
+
+## Features
+- Fast repository scanning
+- HTML and Markdown reports
+- 25 agent-ready attributes
+
+## Documentation
+See [docs/](docs/) for detailed guides.
+
+
+ # Bad: Verbose prose
+
+This project is a tool that helps you assess your repository
+against best practices for AI-assisted development. It works by
+scanning your codebase and checking for various attributes that
+make repositories more effective when working with AI coding
+assistants like Claude Code...
+
+[Many more paragraphs of prose...]
+
+
+
+ Add docstrings to public functions and classes
+ + +# Install pydocstyle
+pip install pydocstyle
+
+# Check docstring coverage
+pydocstyle src/
+
+# Generate documentation
+pip install sphinx
+sphinx-apidoc -o docs/ src/
+
+
+
+ # Python - Good docstring
+def calculate_discount(price: float, discount_percent: float) -> float:
+ """Calculate discounted price.
+
+ Args:
+ price: Original price in USD
+ discount_percent: Discount percentage (0-100)
+
+ Returns:
+ Discounted price
+
+ Raises:
+ ValueError: If discount_percent not in 0-100 range
+
+ Example:
+ >>> calculate_discount(100.0, 20.0)
+ 80.0
+ """
+ if not 0 <= discount_percent <= 100:
+ raise ValueError("Discount must be 0-100")
+ return price * (1 - discount_percent / 100)
+
+
+ // JavaScript - Good JSDoc
+/**
+ * Calculate discounted price
+ *
+ * @param {number} price - Original price in USD
+ * @param {number} discountPercent - Discount percentage (0-100)
+ * @returns {number} Discounted price
+ * @throws {Error} If discountPercent not in 0-100 range
+ * @example
+ * calculateDiscount(100.0, 20.0)
+ * // Returns: 80.0
+ */
+function calculateDiscount(price, discountPercent) {
+ if (discountPercent < 0 || discountPercent > 100) {
+ throw new Error("Discount must be 0-100");
+ }
+ return price * (1 - discountPercent / 100);
+}
+
+
+
+ Install with: pip install radon
+ + +Create Architecture Decision Records (ADRs) directory and document key decisions
+ + +# Create ADR directory
+mkdir -p docs/adr
+
+# Create first ADR using template
+cat > docs/adr/0001-use-architecture-decision-records.md << 'EOF'
+# 1. Use Architecture Decision Records
+
+Date: 2025-11-22
+
+## Status
+Accepted
+
+## Context
+We need to record architectural decisions made in this project.
+
+## Decision
+We will use Architecture Decision Records (ADRs) as described by Michael Nygard.
+
+## Consequences
+- Decisions are documented with context
+- Future contributors understand rationale
+- ADRs are lightweight and version-controlled
+EOF
+
+
+
+ # Example ADR Structure
+
+```markdown
+# 2. Use PostgreSQL for Database
+
+Date: 2025-11-22
+
+## Status
+Accepted
+
+## Context
+We need a relational database for complex queries and ACID transactions.
+Team has PostgreSQL experience. Need full-text search capabilities.
+
+## Decision
+Use PostgreSQL 15+ as primary database.
+
+## Consequences
+- Positive: Robust ACID, full-text search, team familiarity
+- Negative: Higher resource usage than SQLite
+- Neutral: Need to manage migrations, backups
+```
+
+
+
+ Add structured logging library for machine-parseable logs
+ + +# Install structlog
+pip install structlog
+
+# Configure structlog
+# See examples for configuration
+
+
+
+ # Python with structlog
+import structlog
+
+# Configure structlog
+structlog.configure(
+ processors=[
+ structlog.stdlib.add_log_level,
+ structlog.processors.TimeStamper(fmt="iso"),
+ structlog.processors.JSONRenderer()
+ ]
+)
+
+logger = structlog.get_logger()
+
+# Good: Structured logging
+logger.info(
+ "user_login",
+ user_id="123",
+ email="user@example.com",
+ ip_address="192.168.1.1"
+)
+
+# Bad: Unstructured logging
+logger.info(f"User {user_id} logged in from {ip}")
+
+
+
+ Create OpenAPI specification for API endpoints
+ + +# Install OpenAPI validator
+npm install -g @stoplight/spectral-cli
+
+# Validate spec
+spectral lint openapi.yaml
+
+# Generate client SDK
+npx @openapitools/openapi-generator-cli generate \
+ -i openapi.yaml \
+ -g python \
+ -o client/
+
+
+
+ # openapi.yaml - Minimal example
+openapi: 3.1.0
+info:
+ title: My API
+ version: 1.0.0
+ description: API for managing users
+
+servers:
+ - url: https://api.example.com/v1
+
+paths:
+ /users/{userId}:
+ get:
+ summary: Get user by ID
+ parameters:
+ - name: userId
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ description: User found
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/User'
+ '404':
+ description: User not found
+
+components:
+ schemas:
+ User:
+ type: object
+ required:
+ - id
+ - email
+ properties:
+ id:
+ type: string
+ example: "user_123"
+ email:
+ type: string
+ format: email
+ example: "user@example.com"
+ name:
+ type: string
+ example: "John Doe"
+
+
+
+ Configure 3 missing linter(s)
+ + +npm install --save-dev eslint && npx eslint --init
+npm install --save-dev markdownlint-cli && touch .markdownlint.json
+
+
+
+ # .pylintrc example
+[MASTER]
+max-line-length=100
+
+[MESSAGES CONTROL]
+disable=C0111
+
+ # .eslintrc.json example
+{
+ "extends": "eslint:recommended",
+ "rules": {
+ "no-console": "warn"
+ }
+}
+
+
+ Improve container configuration
+ + +docker build -t myapp .
+docker-compose up -d
+
+
+
+ # .dockerignore example
+.git
+.venv
+__pycache__
+*.pyc
+.env
+node_modules
+
+ # Multi-stage Dockerfile example
+FROM node:18 AS builder
+WORKDIR /app
+COPY . .
+RUN npm ci && npm run build
+
+FROM node:18-alpine
+WORKDIR /app
+COPY --from=builder /app/dist ./dist
+CMD ["node", "dist/index.js"]
+
+
+