From e1c4658421e7a8b2066c714aa3ab4896f25b2b89 Mon Sep 17 00:00:00 2001 From: dahlem Date: Thu, 12 Feb 2026 16:21:14 +0000 Subject: [PATCH] build: Bootstrap agent-ready infrastructure Co-Authored-By: Claude Opus 4.6 --- .agentready/assessment-20260212-110150.json | 1078 +++++++ .agentready/assessment-latest.json | 1 + .agentready/report-20260212-110150.html | 2922 +++++++++++++++++++ .agentready/report-20260212-110150.md | 791 +++++ .agentready/report-latest.html | 1 + .agentready/report-latest.md | 1 + .github/CODEOWNERS | 13 + .github/ISSUE_TEMPLATE/bug_report.md | 42 + .github/ISSUE_TEMPLATE/feature_request.md | 46 + .github/PULL_REQUEST_TEMPLATE.md | 56 + .github/dependabot.yml | 18 + .github/workflows/agentready-assessment.yml | 63 + .github/workflows/security.yml | 144 +- .github/workflows/tests.yml | 50 + .pre-commit-config.yaml | 51 +- CODE_OF_CONDUCT.md | 35 + 16 files changed, 5173 insertions(+), 139 deletions(-) create mode 100644 .agentready/assessment-20260212-110150.json create mode 120000 .agentready/assessment-latest.json create mode 100644 .agentready/report-20260212-110150.html create mode 100644 .agentready/report-20260212-110150.md create mode 120000 .agentready/report-latest.html create mode 120000 .agentready/report-latest.md create mode 100644 .github/CODEOWNERS create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/agentready-assessment.yml create mode 100644 .github/workflows/tests.yml create mode 100644 CODE_OF_CONDUCT.md 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 @@ + + + + + + + AgentReady Assessment - NeMo-Guardrails + + + + +
+ + +
+ +
+
+

🤖 AgentReady Assessment Report

+
+
+

NeMo-Guardrails

+
📁 ~/Documents/repos/trusty/red-hat-data-services/NeMo-Guardrails
+
🌿 main @ 938fdf81
+
+ +
+
Assessed: February 12, 2026 at 11:01 AM
+
AgentReady: v2.27.0
+
Run by: ddahlem@ddahlem-mac
+
+ +
+
+ + +
+
+

Overall Score

+
56.5
+
+
+

Certification

+
Bronze
+
+
+

Assessed

+
23/25
+
+
+

Duration

+
2.1s
+
+
+ + +
+
+

💎 Platinum

+

90-100

+
+
+

🥇 Gold

+

75-89

+
+
+

🥈 Silver

+

60-74

+
+
+

🥉 Bronze

+

40-59

+
+
+

⚠️ Needs Work

+

0-39

+
+
+ + +
+
+ + + + + +
+ +
+ + +
+ +
+ +
+
+ + +
+ +
+ +
+
+ + ❌ + + +
+

CLAUDE.md Configuration Files

+
+ Context Window Optimization • + Tier 1 + • missing +
+
+
+ +
+ 0 +
+ +
+ +
+ +
+

Evidence

+
    + +
  • CLAUDE.md not found in repository root
  • + +
  • AGENTS.md not found (alternative)
  • + +
+
+ + + +
+

Remediation

+

Create CLAUDE.md or AGENTS.md with project-specific configuration for AI coding assistants

+ + +
    + +
  1. Choose one of three approaches:
  2. + +
  3. Option 1: Create standalone CLAUDE.md (>50 bytes) with project context
  4. + +
  5. Option 2: Create AGENTS.md and symlink CLAUDE.md to it (cross-tool compatibility)
  6. + +
  7. Option 3: Create AGENTS.md and reference it with @AGENTS.md in minimal CLAUDE.md
  8. + +
  9. Add project overview and purpose
  10. + +
  11. Document key architectural patterns
  12. + +
  13. Specify coding standards and conventions
  14. + +
  15. Include build/test/deployment commands
  16. + +
  17. Add any project-specific context that helps AI assistants
  18. + +
+ + + +

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)
+
+## 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
+
+ + +
+ + + +
+
+ +
+ +
+
+ + ✅ + + +
+

README Structure

+
+ Documentation Standards • + Tier 1 + • 3/3 sections +
+
+
+ +
+ 100 +
+ +
+ +
+ +
+

Evidence

+
    + +
  • Found 3/3 essential sections
  • + +
  • Installation: ✓
  • + +
  • Usage: ✓
  • + +
  • Development: ✓
  • + +
+
+ + + + + +
+
+ +
+ +
+
+ + ❌ + + +
+

Type Annotations

+
+ Code Quality • + Tier 1 + • 29.9% +
+
+
+ +
+ 37 +
+ +
+ +
+ +
+

Evidence

+
    + +
  • Typed functions: 979/3279
  • + +
  • Coverage: 29.9%
  • + +
+
+ + + +
+

Remediation

+

Add type annotations to function signatures

+ + +
    + +
  1. For Python: Add type hints to function parameters and return types
  2. + +
  3. For TypeScript: Enable strict mode in tsconfig.json
  4. + +
  5. Use mypy or pyright for Python type checking
  6. + +
  7. Use tsc --strict for TypeScript
  8. + +
  9. Add type annotations gradually to existing code
  10. + +
+ + + +

Commands

+
# Python
+pip install mypy
+mypy --strict src/
+
+# TypeScript
+npm install --save-dev typescript
+echo '{"compilerOptions": {"strict": true}}' > tsconfig.json
+ + + +

Examples

+ +
# 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
+  }
+}
+
+ + +
+ + + +
+
+ +
+ +
+
+ + ❌ + + +
+

Standard Project Layouts

+
+ Repository Structure • + Tier 1 + • 1/2 directories +
+
+
+ +
+ 50 +
+ +
+ +
+ +
+

Evidence

+
    + +
  • Found 1/2 standard directories
  • + +
  • src/: ✗
  • + +
  • tests/: ✓
  • + +
+
+ + + +
+

Remediation

+

Organize code into standard directories (src/, tests/, docs/)

+ + +
    + +
  1. Create src/ directory for source code
  2. + +
  3. Create tests/ directory for test files
  4. + +
  5. Create docs/ directory for documentation
  6. + +
  7. Move source code into src/
  8. + +
  9. Move tests into tests/
  10. + +
+ + + +

Commands

+
mkdir -p src tests docs
+# Move source files to src/
+# Move test files to tests/
+ + + +
+ + + +
+
+ +
+ +
+
+ + ✅ + + +
+

Dependency Pinning for Reproducibility

+
+ Dependency Management • + Tier 1 + • poetry.lock, requirements.txt +
+
+
+ +
+ 100 +
+ +
+ +
+ +
+

Evidence

+
    + +
  • Found lock file(s): poetry.lock
  • + +
+
+ + + + + +
+
+ +
+ +
+
+ + ✅ + + +
+

Dependency Security & Vulnerability Scanning

+
+ Security • + Tier 1 + • Security tools configured: Dependabot +
+
+
+ +
+ 40 +
+ +
+ +
+ +
+

Evidence

+
    + +
  • ✓ Dependabot configured for dependency alerts
  • + +
  • 2 package ecosystem(s) monitored
  • + +
  • ✓ SECURITY.md present (vulnerability disclosure policy)
  • + +
+
+ + + +
+

Remediation

+

Add more security scanning tools for comprehensive coverage

+ + +
    + +
  1. Enable Dependabot alerts in GitHub repository settings
  2. + +
  3. Add CodeQL scanning workflow for SAST
  4. + +
  5. Configure secret detection (detect-secrets, gitleaks)
  6. + +
  7. Set up language-specific scanners (pip-audit, npm audit, Snyk)
  8. + +
+ + + +

Commands

+
gh repo edit --enable-security
+pip install detect-secrets  # Python secret detection
+npm audit  # JavaScript dependency audit
+ + + +

Examples

+ +
# .github/dependabot.yml
+version: 2
+updates:
+  - package-ecosystem: pip
+    directory: /
+    schedule:
+      interval: weekly
+ + +
+ + + +
+
+ +
+ +
+
+ + ✅ + + +
+

Test Coverage Requirements

+
+ Testing & CI/CD • + Tier 2 + • configured +
+
+
+ +
+ 100 +
+ +
+ +
+ +
+

Evidence

+
    + +
  • Coverage configuration found
  • + +
  • pytest-cov dependency present
  • + +
+
+ + + + + +
+
+ +
+ +
+
+ + ✅ + + +
+

Pre-commit Hooks & CI/CD Linting

+
+ Testing & CI/CD • + Tier 2 + • configured +
+
+
+ +
+ 100 +
+ +
+ +
+ +
+

Evidence

+
    + +
  • .pre-commit-config.yaml found
  • + +
+
+ + + + + +
+
+ +
+ +
+
+ + ❌ + + +
+

Conventional Commit Messages

+
+ Git & Version Control • + Tier 2 + • not configured +
+
+
+ +
+ 0 +
+ +
+ +
+ +
+

Evidence

+
    + +
  • No commitlint or husky configuration
  • + +
+
+ + + +
+

Remediation

+

Configure conventional commits with commitlint

+ + +
    + +
  1. Install commitlint
  2. + +
  3. Configure husky for commit-msg hook
  4. + +
+ + + +

Commands

+
npm install --save-dev @commitlint/cli @commitlint/config-conventional husky
+ + + +
+ + + +
+
+ +
+ +
+
+ + ✅ + + +
+

.gitignore Completeness

+
+ Git & Version Control • + Tier 2 + • 12/17 patterns +
+
+
+ +
+ 71 +
+ +
+ +
+ +
+

Evidence

+
    + +
  • .gitignore found (908 bytes)
  • + +
  • Pattern coverage: 12/17 (71%)
  • + +
  • Missing 5 recommended patterns
  • + +
+
+ + + + + +
+
+ +
+ +
+
+ + ✅ + + +
+

One-Command Build/Setup

+
+ Build & Development • + Tier 2 + • To install +
+
+
+ +
+ 100 +
+ +
+ +
+ +
+

Evidence

+
    + +
  • Setup command found in README: 'To install'
  • + +
  • Setup automation found: Makefile, pyproject.toml
  • + +
  • Setup instructions in prominent location
  • + +
+
+ + + + + +
+
+ +
+ +
+
+ + ❌ + + +
+

File Size Limits

+
+ Context Window Optimization • + Tier 2 + • 16 huge, 29 large out of 580 +
+
+
+ +
+ 42 +
+ +
+ +
+ +
+

Evidence

+
    + +
  • Found 16 files >1000 lines (2.8% of 580 files)
  • + +
  • Largest: docs/colang-2/examples/csl.py (1096 lines)
  • + +
+
+ + + +
+

Remediation

+

Refactor large files into smaller, focused modules

+ + +
    + +
  1. Identify files >1000 lines
  2. + +
  3. Split into logical submodules
  4. + +
  5. Extract classes/functions into separate files
  6. + +
  7. Maintain single responsibility principle
  8. + +
+ + + + + +

Examples

+ +
# Split large file:
+# models.py (1500 lines) → models/user.py, models/product.py, models/order.py
+ + +
+ + + +
+
+ +
+ +
+
+ + ❌ + + +
+

Separation of Concerns

+
+ Code Organization • + Tier 2 + • organization:100, cohesion:92, naming:0 +
+
+
+ +
+ 68 +
+ +
+ +
+ +
+

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

+

Refactor code to improve separation of concerns

+ + +
    + +
  1. Avoid layer-based directories (models/, views/, controllers/)
  2. + +
  3. Organize by feature/domain instead (auth/, users/, billing/)
  4. + +
  5. Break large files (>500 lines) into focused modules
  6. + +
  7. Eliminate catch-all modules (utils.py, helpers.py)
  8. + +
  9. Each module should have single, well-defined responsibility
  10. + +
  11. Group related functions/classes by domain, not technical layer
  12. + +
+ + + + + +

Examples

+ +
# 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
+
+ + +
+ + + +
+
+ +
+ +
+
+ + ❌ + + +
+

Concise Documentation

+
+ Documentation • + Tier 2 + • 337 lines, 25 headings, 8 bullets +
+
+
+ +
+ 72 +
+ +
+ +
+ +
+

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

+

Make documentation more concise and structured

+ + +
    + +
  1. Break long README into multiple documents (docs/ directory)
  2. + +
  3. Add clear Markdown headings (##, ###) for structure
  4. + +
  5. Convert prose paragraphs to bullet points where possible
  6. + +
  7. Add table of contents for documents >100 lines
  8. + +
  9. Use code blocks instead of describing commands in prose
  10. + +
  11. Move detailed content to wiki or docs/, keep README focused
  12. + +
+ + + +

Commands

+
# Check README length
+wc -l README.md
+
+# Count headings
+grep -c '^#' README.md
+ + + +

Examples

+ +
# 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...]
+
+ + +
+ + + +
+
+ +
+ +
+
+ + ❌ + + +
+

Inline Documentation

+
+ Documentation • + Tier 2 + • 53.8% +
+
+
+ +
+ 67 +
+ +
+ +
+ +
+

Evidence

+
    + +
  • Documented items: 2074/3853
  • + +
  • Coverage: 53.8%
  • + +
  • Many public functions/classes lack docstrings
  • + +
+
+ + + +
+

Remediation

+

Add docstrings to public functions and classes

+ + +
    + +
  1. Identify functions/classes without docstrings
  2. + +
  3. Add PEP 257 compliant docstrings for Python
  4. + +
  5. Add JSDoc comments for JavaScript/TypeScript
  6. + +
  7. Include: description, parameters, return values, exceptions
  8. + +
  9. Add examples for complex functions
  10. + +
  11. Run pydocstyle to validate docstring format
  12. + +
+ + + +

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
+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);
+}
+
+ + +
+ + + +
+
+ +
+ +
+
+ + ⊘ + + +
+

Cyclomatic Complexity Thresholds

+
+ Code Quality • + Tier 3 + +
+
+
+ +
+ +
+ +
+ +
+

Evidence

+
    + +
  • Missing tool: radon
  • + +
+
+ + + +
+

Remediation

+

Install with: pip install radon

+ + +
    + +
  1. Install with: pip install radon
  2. + +
+ + + + + +
+ + + +
+
+ +
+ +
+
+ + ❌ + + +
+

Architecture Decision Records (ADRs)

+
+ Documentation Standards • + Tier 3 + • no ADR directory +
+
+
+ +
+ 0 +
+ +
+ +
+ +
+

Evidence

+
    + +
  • No ADR directory found (checked docs/adr/, .adr/, adr/, docs/decisions/)
  • + +
+
+ + + +
+

Remediation

+

Create Architecture Decision Records (ADRs) directory and document key decisions

+ + +
    + +
  1. Create docs/adr/ directory in repository root
  2. + +
  3. Use Michael Nygard ADR template or MADR format
  4. + +
  5. Document each significant architectural decision
  6. + +
  7. Number ADRs sequentially (0001-*.md, 0002-*.md)
  8. + +
  9. Include Status, Context, Decision, and Consequences sections
  10. + +
  11. Update ADR status when decisions are revised (Superseded, Deprecated)
  12. + +
+ + + +

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
+
+```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
+```
+
+ + +
+ + + +
+
+ +
+ +
+
+ + ✅ + + +
+

Issue & Pull Request Templates

+
+ Repository Structure • + Tier 3 + • PR:True, Issues:6 +
+
+
+ +
+ 100 +
+ +
+ +
+ +
+

Evidence

+
    + +
  • PR template found
  • + +
  • Issue templates found: 6 templates
  • + +
+
+ + + + + +
+
+ +
+ +
+
+ + ✅ + + +
+

CI/CD Pipeline Visibility

+
+ Testing & CI/CD • + Tier 3 + • configured with best practices +
+
+
+ +
+ 80 +
+ +
+ +
+ +
+

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
  • + +
+
+ + + + + +
+
+ +
+ +
+
+ + ✅ + + +
+

Semantic Naming

+
+ Code Quality • + Tier 3 + • functions:99%, classes:100% +
+
+
+ +
+ 99 +
+ +
+ +
+ +
+

Evidence

+
    + +
  • Functions: 158/160 follow snake_case (98.8%)
  • + +
  • Classes: 45/45 follow PascalCase (100.0%)
  • + +
  • No generic names (temp, data, obj) detected
  • + +
+
+ + + + + +
+
+ +
+ +
+
+ + ❌ + + +
+

Structured Logging

+
+ Code Quality • + Tier 3 + • not configured +
+
+
+ +
+ 0 +
+ +
+ +
+ +
+

Evidence

+
    + +
  • No structured logging library found
  • + +
  • Checked files: pyproject.toml, requirements.txt
  • + +
  • Using built-in logging module (unstructured)
  • + +
+
+ + + +
+

Remediation

+

Add structured logging library for machine-parseable logs

+ + +
    + +
  1. Choose structured logging library (structlog for Python, winston for Node.js)
  2. + +
  3. Install library and configure JSON formatter
  4. + +
  5. Add standard fields: timestamp, level, message, context
  6. + +
  7. Include request context: request_id, user_id, session_id
  8. + +
  9. Use consistent field naming (snake_case for Python)
  10. + +
  11. Never log sensitive data (passwords, tokens, PII)
  12. + +
  13. Configure different formats for dev (pretty) and prod (JSON)
  14. + +
+ + + +

Commands

+
# Install structlog
+pip install structlog
+
+# Configure structlog
+# See examples for configuration
+ + + +

Examples

+ +
# 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}")
+
+ + +
+ + + +
+
+ +
+ +
+
+ + ❌ + + +
+

OpenAPI/Swagger Specifications

+
+ API Documentation • + Tier 3 + • no OpenAPI spec +
+
+
+ +
+ 0 +
+ +
+ +
+ +
+

Evidence

+
    + +
  • No OpenAPI specification found
  • + +
  • Searched recursively for: openapi.yaml, openapi.yml, openapi.json, swagger.yaml, swagger.yml, swagger.json
  • + +
+
+ + + +
+

Remediation

+

Create OpenAPI specification for API endpoints

+ + +
    + +
  1. Create openapi.yaml in repository root
  2. + +
  3. Define OpenAPI version 3.x
  4. + +
  5. Document all API endpoints with full schemas
  6. + +
  7. Add request/response examples
  8. + +
  9. Define security schemes (API keys, OAuth, etc.)
  10. + +
  11. Validate spec with Swagger Editor or Spectral
  12. + +
  13. Generate API documentation with Swagger UI or ReDoc
  14. + +
+ + + +

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
+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"
+
+ + +
+ + + +
+
+ +
+ +
+
+ + ⊘ + + +
+

Branch Protection Rules

+
+ Git & Version Control • + Tier 4 + +
+
+
+ +
+ +
+ +
+ +
+

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.
  • + +
+
+ + + + + +
+
+ +
+ +
+
+ + ❌ + + +
+

Code Smell Elimination

+
+ Code Quality • + Tier 4 + • pylint, ruff +
+
+
+ +
+ 50 +
+ +
+ +
+ +
+

Evidence

+
    + +
  • Linters configured: pylint, ruff
  • + +
  • Coverage: 40/80 points (50%)
  • + +
+
+ + + +
+

Remediation

+

Configure 3 missing linter(s)

+ + +
    + +
  1. Configure ESLint for JavaScript/TypeScript
  2. + +
  3. Add actionlint for GitHub Actions workflow validation
  4. + +
  5. Configure markdownlint for documentation quality
  6. + +
+ + + +

Commands

+
npm install --save-dev eslint && npx eslint --init
+npm install --save-dev markdownlint-cli && touch .markdownlint.json
+ + + +

Examples

+ +
# .pylintrc example
+[MASTER]
+max-line-length=100
+
+[MESSAGES CONTROL]
+disable=C0111
+ +
# .eslintrc.json example
+{
+  "extends": "eslint:recommended",
+  "rules": {
+    "no-console": "warn"
+  }
+}
+ + +
+ + + +
+
+ +
+ +
+
+ + ✅ + + +
+

Container/Virtualization Setup

+
+ Build & Development • + Tier 4 + • 60 points +
+
+
+ +
+ 60 +
+ +
+ +
+ +
+

Evidence

+
    + +
  • ✓ Dockerfile present
  • + +
  • ℹ️ Single-stage build (consider multi-stage for smaller images)
  • + +
  • ✓ .dockerignore present (excludes unnecessary files)
  • + +
+
+ + + +
+

Remediation

+

Improve container configuration

+ + +
    + +
  1. Add docker-compose.yml for multi-service development
  2. + +
  3. Create .dockerignore to exclude build artifacts and secrets
  4. + +
  5. Consider multi-stage builds to reduce image size
  6. + +
+ + + +

Commands

+
docker build -t myapp .
+docker-compose up -d
+ + + +

Examples

+ +
# .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"]
+ + +
+ + + +
+
+ +
+ +
+ +

Generated by AgentReady v2.27.0 (Research v1.0.1)

+

Repository: ~/Documents/repos/trusty/red-hat-data-services/NeMo-Guardrails • Branch: main • Commit: 938fdf81

+

Assessed by ddahlem@ddahlem-mac on February 12, 2026 at 11:01 AM

+ +

+ 🤖 Generated with Claude Code +

+
+
+ + + + \ No newline at end of file diff --git a/.agentready/report-20260212-110150.md b/.agentready/report-20260212-110150.md new file mode 100644 index 0000000000..5760dec712 --- /dev/null +++ b/.agentready/report-20260212-110150.md @@ -0,0 +1,791 @@ +# 🤖 AgentReady Assessment Report + +**Repository**: NeMo-Guardrails +**Path**: `/Users/ddahlem/Documents/repos/trusty/red-hat-data-services/NeMo-Guardrails` +**Branch**: `main` | **Commit**: `938fdf81` +**Assessed**: February 12, 2026 at 11:01 AM +**AgentReady Version**: 2.27.0 +**Run by**: ddahlem@ddahlem-mac + +--- + +## 📊 Summary + +| Metric | Value | +|--------|-------| +| **Overall Score** | **56.5/100** 🥉 **Bronze** ([Tier Definitions](https://agentready.dev/attributes.html#tier-system)) | +| **Attributes Assessed** | 23/25 | +| **Attributes Not Assessed** | 2 | +| **Assessment Duration** | 2.1s | + +### Languages Detected + +- **Python**: 569 files +- **YAML**: 258 files +- **Markdown**: 208 files +- **JSON**: 18 files +- **JavaScript**: 11 files +- **TOML**: 3 files + +### Repository Stats + +- **Total Files**: 1,495 +- **Total Lines**: 255,626 + +## 🎯 Priority Improvements + +Focus on these high-impact fixes first: + +1. **CLAUDE.md Configuration Files** (Tier 1) - +10.0 points potential + - Create CLAUDE.md or AGENTS.md with project-specific configuration for AI coding assistants +2. **Type Annotations** (Tier 1) - +10.0 points potential + - Add type annotations to function signatures +3. **Standard Project Layouts** (Tier 1) - +10.0 points potential + - Organize code into standard directories (src/, tests/, docs/) +4. **Conventional Commit Messages** (Tier 2) - +3.0 points potential + - Configure conventional commits with commitlint +5. **File Size Limits** (Tier 2) - +3.0 points potential + - Refactor large files into smaller, focused modules + +## 📋 Detailed Findings + +Findings sorted by priority (Tier 1 failures first, then Tier 2, etc.) + +![T1](https://img.shields.io/badge/T1-CLAUDE.md_Configuration_Files_0--100-red) **CLAUDE.md Configuration Files** ❌ 0/100 +
+📝 Remediation Steps + +**Measured**: missing (Threshold: present) + +**Evidence**: +- CLAUDE.md not found in repository root +- AGENTS.md not found (alternative) + +Create CLAUDE.md or AGENTS.md with project-specific configuration for AI coding assistants + +1. Choose one of three approaches: +2. Option 1: Create standalone CLAUDE.md (>50 bytes) with project context +3. Option 2: Create AGENTS.md and symlink CLAUDE.md to it (cross-tool compatibility) +4. Option 3: Create AGENTS.md and reference it with @AGENTS.md in minimal CLAUDE.md +5. Add project overview and purpose +6. Document key architectural patterns +7. Specify coding standards and conventions +8. Include build/test/deployment commands +9. Add any project-specific context that helps AI assistants + +**Commands**: +```bash +# 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) + +## 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 + +``` + +
+ +![T1](https://img.shields.io/badge/T1-Type_Annotations_37--100-red) **Type Annotations** ❌ 37/100 +
+📝 Remediation Steps + +**Measured**: 29.9% (Threshold: ≥80%) + +**Evidence**: +- Typed functions: 979/3279 +- Coverage: 29.9% + +Add type annotations to function signatures + +1. For Python: Add type hints to function parameters and return types +2. For TypeScript: Enable strict mode in tsconfig.json +3. Use mypy or pyright for Python type checking +4. Use tsc --strict for TypeScript +5. Add type annotations gradually to existing code + +**Commands**: +```bash +# Python +pip install mypy +mypy --strict src/ + +# TypeScript +npm install --save-dev typescript +echo '{"compilerOptions": {"strict": true}}' > tsconfig.json +``` + +**Examples**: +``` +# 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 + } +} + +``` + +
+ +![T1](https://img.shields.io/badge/T1-Standard_Project_Layouts_50--100-red) **Standard Project Layouts** ❌ 50/100 +
+📝 Remediation Steps + +**Measured**: 1/2 directories (Threshold: 2/2 directories) + +**Evidence**: +- Found 1/2 standard directories +- src/: ✗ +- tests/: ✓ + +Organize code into standard directories (src/, tests/, docs/) + +1. Create src/ directory for source code +2. Create tests/ directory for test files +3. Create docs/ directory for documentation +4. Move source code into src/ +5. Move tests into tests/ + +**Commands**: +```bash +mkdir -p src tests docs +# Move source files to src/ +# Move test files to tests/ +``` + +
+ +![T1](https://img.shields.io/badge/T1-Dependency_Security_%26_Vulnerability_Scanning_40--100-green) **Dependency Security & Vulnerability Scanning** ✅ 40/100 + +![T1](https://img.shields.io/badge/T1-README_Structure_100--100-green) **README Structure** ✅ 100/100 + +![T1](https://img.shields.io/badge/T1-Dependency_Pinning_for_Reproducibility_100--100-green) **Dependency Pinning for Reproducibility** ✅ 100/100 + +![T2](https://img.shields.io/badge/T2-Conventional_Commit_Messages_0--100-red) **Conventional Commit Messages** ❌ 0/100 +
+📝 Remediation Steps + +**Measured**: not configured (Threshold: configured) + +**Evidence**: +- No commitlint or husky configuration + +Configure conventional commits with commitlint + +1. Install commitlint +2. Configure husky for commit-msg hook + +**Commands**: +```bash +npm install --save-dev @commitlint/cli @commitlint/config-conventional husky +``` + +
+ +![T2](https://img.shields.io/badge/T2-File_Size_Limits_42--100-red) **File Size Limits** ❌ 42/100 +
+📝 Remediation Steps + +**Measured**: 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) + +Refactor large files into smaller, focused modules + +1. Identify files >1000 lines +2. Split into logical submodules +3. Extract classes/functions into separate files +4. Maintain single responsibility principle + +**Examples**: +``` +# Split large file: +# models.py (1500 lines) → models/user.py, models/product.py, models/order.py +``` + +
+ +![T2](https://img.shields.io/badge/T2-Inline_Documentation_67--100-red) **Inline Documentation** ❌ 67/100 +
+📝 Remediation Steps + +**Measured**: 53.8% (Threshold: ≥80%) + +**Evidence**: +- Documented items: 2074/3853 +- Coverage: 53.8% +- Many public functions/classes lack docstrings + +Add docstrings to public functions and classes + +1. Identify functions/classes without docstrings +2. Add PEP 257 compliant docstrings for Python +3. Add JSDoc comments for JavaScript/TypeScript +4. Include: description, parameters, return values, exceptions +5. Add examples for complex functions +6. Run pydocstyle to validate docstring format + +**Commands**: +```bash +# Install pydocstyle +pip install pydocstyle + +# Check docstring coverage +pydocstyle src/ + +# Generate documentation +pip install sphinx +sphinx-apidoc -o docs/ src/ +``` + +**Examples**: +``` +# 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); +} + +``` + +
+ +![T2](https://img.shields.io/badge/T2-Separation_of_Concerns_68--100-red) **Separation of Concerns** ❌ 68/100 +
+📝 Remediation Steps + +**Measured**: organization:100, cohesion:92, naming:0 (Threshold: ≥75 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 + +Refactor code to improve separation of concerns + +1. Avoid layer-based directories (models/, views/, controllers/) +2. Organize by feature/domain instead (auth/, users/, billing/) +3. Break large files (>500 lines) into focused modules +4. Eliminate catch-all modules (utils.py, helpers.py) +5. Each module should have single, well-defined responsibility +6. Group related functions/classes by domain, not technical layer + +**Examples**: +``` +# 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 + +``` + +
+ +![T2](https://img.shields.io/badge/T2-Concise_Documentation_72--100-red) **Concise Documentation** ❌ 72/100 +
+📝 Remediation Steps + +**Measured**: 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) + +Make documentation more concise and structured + +1. Break long README into multiple documents (docs/ directory) +2. Add clear Markdown headings (##, ###) for structure +3. Convert prose paragraphs to bullet points where possible +4. Add table of contents for documents >100 lines +5. Use code blocks instead of describing commands in prose +6. Move detailed content to wiki or docs/, keep README focused + +**Commands**: +```bash +# Check README length +wc -l README.md + +# Count headings +grep -c '^#' README.md +``` + +**Examples**: +``` +# 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...] + +``` + +
+ +![T2](https://img.shields.io/badge/T2-.gitignore_Completeness_71--100-green) **.gitignore Completeness** ✅ 71/100 + +![T2](https://img.shields.io/badge/T2-Test_Coverage_Requirements_100--100-green) **Test Coverage Requirements** ✅ 100/100 + +![T2](https://img.shields.io/badge/T2-Pre-commit_Hooks_%26_CI%2FCD_Linting_100--100-green) **Pre-commit Hooks & CI/CD Linting** ✅ 100/100 + +![T2](https://img.shields.io/badge/T2-One-Command_Build%2FSetup_100--100-green) **One-Command Build/Setup** ✅ 100/100 + +![T3](https://img.shields.io/badge/T3-Architecture_Decision_Records_%28ADRs%29_0--100-red) **Architecture Decision Records (ADRs)** ❌ 0/100 +
+📝 Remediation Steps + +**Measured**: no ADR directory (Threshold: ADR directory with decisions) + +**Evidence**: +- No ADR directory found (checked docs/adr/, .adr/, adr/, docs/decisions/) + +Create Architecture Decision Records (ADRs) directory and document key decisions + +1. Create docs/adr/ directory in repository root +2. Use Michael Nygard ADR template or MADR format +3. Document each significant architectural decision +4. Number ADRs sequentially (0001-*.md, 0002-*.md) +5. Include Status, Context, Decision, and Consequences sections +6. Update ADR status when decisions are revised (Superseded, Deprecated) + +**Commands**: +```bash +# 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 + +```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 +``` + +``` + +
+ +![T3](https://img.shields.io/badge/T3-Structured_Logging_0--100-red) **Structured Logging** ❌ 0/100 +
+📝 Remediation Steps + +**Measured**: not configured (Threshold: structured logging library) + +**Evidence**: +- No structured logging library found +- Checked files: pyproject.toml, requirements.txt +- Using built-in logging module (unstructured) + +Add structured logging library for machine-parseable logs + +1. Choose structured logging library (structlog for Python, winston for Node.js) +2. Install library and configure JSON formatter +3. Add standard fields: timestamp, level, message, context +4. Include request context: request_id, user_id, session_id +5. Use consistent field naming (snake_case for Python) +6. Never log sensitive data (passwords, tokens, PII) +7. Configure different formats for dev (pretty) and prod (JSON) + +**Commands**: +```bash +# Install structlog +pip install structlog + +# Configure structlog +# See examples for configuration +``` + +**Examples**: +``` +# 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}") + +``` + +
+ +![T3](https://img.shields.io/badge/T3-OpenAPI%2FSwagger_Specifications_0--100-red) **OpenAPI/Swagger Specifications** ❌ 0/100 +
+📝 Remediation Steps + +**Measured**: 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 + +Create OpenAPI specification for API endpoints + +1. Create openapi.yaml in repository root +2. Define OpenAPI version 3.x +3. Document all API endpoints with full schemas +4. Add request/response examples +5. Define security schemes (API keys, OAuth, etc.) +6. Validate spec with Swagger Editor or Spectral +7. Generate API documentation with Swagger UI or ReDoc + +**Commands**: +```bash +# 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 +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" + +``` + +
+ +![T3](https://img.shields.io/badge/T3-CI%2FCD_Pipeline_Visibility_80--100-green) **CI/CD Pipeline Visibility** ✅ 80/100 + +![T3](https://img.shields.io/badge/T3-Semantic_Naming_99--100-green) **Semantic Naming** ✅ 99/100 + +![T3](https://img.shields.io/badge/T3-Issue_%26_Pull_Request_Templates_100--100-green) **Issue & Pull Request Templates** ✅ 100/100 + +![T3](https://img.shields.io/badge/T3-Cyclomatic_Complexity_Thresholds_N--A-lightgray) **Cyclomatic Complexity Thresholds** ⊘ + +![T4](https://img.shields.io/badge/T4-Code_Smell_Elimination_50--100-red) **Code Smell Elimination** ❌ 50/100 +
+📝 Remediation Steps + +**Measured**: pylint, ruff (Threshold: ≥60% of applicable linters configured) + +**Evidence**: +- Linters configured: pylint, ruff +- Coverage: 40/80 points (50%) + +Configure 3 missing linter(s) + +1. Configure ESLint for JavaScript/TypeScript +2. Add actionlint for GitHub Actions workflow validation +3. Configure markdownlint for documentation quality + +**Commands**: +```bash +npm install --save-dev eslint && npx eslint --init +npm install --save-dev markdownlint-cli && touch .markdownlint.json +``` + +**Examples**: +``` +# .pylintrc example +[MASTER] +max-line-length=100 + +[MESSAGES CONTROL] +disable=C0111 +``` +``` +# .eslintrc.json example +{ + "extends": "eslint:recommended", + "rules": { + "no-console": "warn" + } +} +``` + +
+ +![T4](https://img.shields.io/badge/T4-Container%2FVirtualization_Setup_60--100-green) **Container/Virtualization Setup** ✅ 60/100 + +![T4](https://img.shields.io/badge/T4-Branch_Protection_Rules_N--A-lightgray) **Branch Protection Rules** ⊘ + + +--- + +## 📝 Assessment Metadata + +- **AgentReady Version**: v2.27.0 +- **Research Version**: v1.0.1 +- **Repository Snapshot**: 938fdf81a9035dd14bb04515a4f8be14091ed55e +- **Assessment Duration**: 2.1s +- **Assessed By**: ddahlem@ddahlem-mac +- **Assessment Date**: February 12, 2026 at 11:01 AM + +🤖 Generated with [Claude Code](https://claude.com/claude-code) \ No newline at end of file diff --git a/.agentready/report-latest.html b/.agentready/report-latest.html new file mode 120000 index 0000000000..5ecdb25ee2 --- /dev/null +++ b/.agentready/report-latest.html @@ -0,0 +1 @@ +report-20260212-110150.html \ No newline at end of file diff --git a/.agentready/report-latest.md b/.agentready/report-latest.md new file mode 120000 index 0000000000..5e20af444a --- /dev/null +++ b/.agentready/report-latest.md @@ -0,0 +1 @@ +report-20260212-110150.md \ No newline at end of file diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..ac0a66414f --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,13 @@ +# CODEOWNERS file +# Define code ownership for automatic review requests + +# Global owners - these users are requested for review on all PRs +# * @owner + +# Specific paths can have different owners +# /docs/ @documentation-team +# /src/ @development-team +# /.github/ @devops-team + +# Default: assign to repository owner +* @owner \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000000..76fff4a71c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,42 @@ +--- +name: Bug Report +about: Create a report to help us improve +title: '[BUG] ' +labels: bug +assignees: '' +--- + +## Bug Description + +A clear and concise description of what the bug is. + +## To Reproduce + +Steps to reproduce the behavior: + +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +## Expected Behavior + +A clear and concise description of what you expected to happen. + +## Actual Behavior + +A clear and concise description of what actually happened. + +## Environment + +- OS: [e.g. macOS 14.0, Ubuntu 22.04] +- Version: [e.g. 1.0.0] +- Python Version: [e.g. 3.11] + +## Additional Context + +Add any other context about the problem here. Include screenshots if applicable. + +## Possible Solution + +If you have suggestions on how to fix the bug, please describe them here. \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000000..b93cb72e2e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,46 @@ +--- +name: Feature Request +about: Suggest an idea for this project +title: '[FEATURE] ' +labels: enhancement +assignees: '' +--- + +## Problem Statement + +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +## Proposed Solution + +A clear and concise description of what you want to happen. + +## Alternatives Considered + +A clear and concise description of any alternative solutions or features you've considered. + +## Use Cases + +Describe specific use cases where this feature would be valuable. + +1. Use case 1 +2. Use case 2 +3. Use case 3 + +## Additional Context + +Add any other context, screenshots, or mockups about the feature request here. + +## Acceptance Criteria + +- [ ] Criterion 1 +- [ ] Criterion 2 +- [ ] Criterion 3 + +## Priority + +How important is this feature to you? + +- [ ] Critical (blocking my work) +- [ ] High (significantly improves workflow) +- [ ] Medium (nice to have) +- [ ] Low (minor enhancement) \ No newline at end of file diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..d368a50aeb --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,56 @@ +## Description + + + +## Type of Change + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] Documentation update +- [ ] Refactoring (no functional changes) +- [ ] Performance improvement +- [ ] Test coverage improvement + +## Related Issues + + + +Fixes # +Relates to # + +## Changes Made + + + +- +- +- + +## Testing + + + +- [ ] Unit tests pass (`pytest`) +- [ ] Integration tests pass +- [ ] Manual testing performed +- [ ] No new warnings or errors + +## Checklist + +- [ ] My code follows the project's code style +- [ ] I have performed a self-review of my own code +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [ ] My changes generate no new warnings +- [ ] I have added tests that prove my fix is effective or that my feature works +- [ ] New and existing unit tests pass locally with my changes +- [ ] Any dependent changes have been merged and published + +## Screenshots (if applicable) + + + +## Additional Notes + + \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..540878d85b --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,18 @@ +version: 2 +updates: + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 10 + labels: + - "dependencies" + - "python" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + labels: + - "dependencies" + - "github-actions" \ No newline at end of file diff --git a/.github/workflows/agentready-assessment.yml b/.github/workflows/agentready-assessment.yml new file mode 100644 index 0000000000..259ccc44f6 --- /dev/null +++ b/.github/workflows/agentready-assessment.yml @@ -0,0 +1,63 @@ +name: AgentReady Assessment + +on: + pull_request: + types: [opened, synchronize, reopened] + push: + branches: [main, master] + workflow_dispatch: + +jobs: + assess: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install AgentReady + run: | + pip install agentready + + - name: Run AgentReady Assessment + run: | + agentready assess . --verbose + + - name: Upload Assessment Reports + uses: actions/upload-artifact@v4 + if: always() + with: + name: agentready-reports + path: .agentready/ + retention-days: 30 + + - name: Comment on PR + if: github.event_name == 'pull_request' + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const reportPath = '.agentready/report-latest.md'; + + if (!fs.existsSync(reportPath)) { + console.log('No report found'); + return; + } + + const report = fs.readFileSync(reportPath, 'utf8'); + + // Post comment with assessment results + await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: report + }); \ No newline at end of file diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index a957fcbe5e..9ba779d7a4 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -1,137 +1,53 @@ -name: Security Scan +name: Security on: - pull_request: - branches: - - develop push: - branches: - - develop + branches: [main, master] + pull_request: + schedule: + - cron: '0 0 * * 0' # Weekly on Sunday + workflow_dispatch: -env: - POETRY_VERSION: 1.8.2 +permissions: + contents: read + security-events: write jobs: - trivy-scan: - name: Trivy + codeql: + name: CodeQL Analysis runs-on: ubuntu-latest - permissions: - contents: read - security-events: write - actions: read steps: - name: Checkout code - uses: actions/checkout@v5 + uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v6 + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 with: - python-version: "3.12" - - - name: Bootstrap poetry - run: | - curl -sSL https://install.python-poetry.org | POETRY_VERSION=${{ env.POETRY_VERSION }} python - - echo "$HOME/.local/bin" >> $GITHUB_PATH - - - name: Configure poetry - run: poetry config virtualenvs.in-project true - - - name: Install dependencies - run: poetry install --with dev + languages: python + - name: Autobuild + uses: github/codeql-action/autobuild@v3 - - name: Run Trivy filesystem scan - uses: aquasecurity/trivy-action@master - with: - scan-type: "fs" - scan-ref: "." - format: "sarif" - output: "trivy-fs-results.sarif" - severity: "CRITICAL,HIGH,MEDIUM,LOW" - exit-code: "0" - - - name: Run Trivy dependency scan - uses: aquasecurity/trivy-action@master - with: - scan-type: "fs" - scan-ref: "." - format: "sarif" - output: "trivy-deps-results.sarif" - severity: "CRITICAL,HIGH,MEDIUM,LOW" - scanners: "vuln" - exit-code: "0" - - - name: Check for critical and high vulnerabilities - uses: aquasecurity/trivy-action@master - with: - scan-type: "fs" - scan-ref: "." - format: "table" - severity: "CRITICAL,HIGH" - exit-code: "1" - - - name: Upload Trivy filesystem scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v3 - if: always() && github.event_name == 'pull_request' && github.base_ref == 'develop' - with: - sarif_file: "trivy-fs-results.sarif" - category: "trivy-filesystem" + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 - - name: Upload Trivy dependency scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v3 - if: always() && github.event_name == 'pull_request' && github.base_ref == 'develop' - with: - sarif_file: "trivy-deps-results.sarif" - category: "trivy-dependencies" - - bandit-scan: - name: Bandit + safety: + name: Dependency Security Scan runs-on: ubuntu-latest - permissions: - security-events: write - actions: read - contents: read - checks: write steps: - - uses: actions/checkout@v5 + - name: Checkout code + uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v6 + uses: actions/setup-python@v5 with: - python-version: "3.12" - - - name: Bootstrap poetry - run: | - curl -sSL https://install.python-poetry.org | POETRY_VERSION=${{ env.POETRY_VERSION }} python - - echo "$HOME/.local/bin" >> $GITHUB_PATH - - - name: Configure poetry - run: poetry config virtualenvs.in-project true + python-version: '3.12' - name: Install dependencies - run: poetry install --with dev - - - name: Install Bandit - run: poetry run pip install bandit[sarif] - - - name: Run Bandit Security Scan - uses: PyCQA/bandit-action@v1 - with: - targets: "." - exclude: "tests" - - - name: Upload SARIF results to Security tab - if: github.ref == 'refs/heads/develop' - uses: github/codeql-action/upload-sarif@v3 - with: - sarif_file: results.sarif - category: bandit-security-scan + run: | + pip install safety - - name: Upload SARIF as artifact - uses: actions/upload-artifact@v4 - with: - name: bandit-sarif-results - path: results.sarif - retention-days: 30 - continue-on-error: true + - name: Run safety check + run: | + safety check --json || true diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000000..7c07f349d9 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,50 @@ +name: Tests + +on: + pull_request: + push: + branches: [main, master] + workflow_dispatch: + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ['3.12', '3.13'] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -e ".[dev]" + + - name: Run black + run: | + black --check . + + - name: Run isort + run: | + isort --check . + + - name: Run ruff + run: | + ruff check . + + - name: Run pytest + run: | + pytest --cov=src --cov-report=xml --cov-report=term + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v4 +if: matrix.python-version == '3.11' with: + files: ./coverage.xml + fail_ci_if_error: false diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fbcccf1311..454b73c83e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,35 +1,36 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + rev: v4.5.0 hooks: - - id: check-yaml - - id: end-of-file-fixer - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files + - id: check-merge-conflict + - id: check-toml + - id: check-json + - id: detect-private-key + + - repo: https://github.com/psf/black + rev: 24.1.1 + hooks: + - id: black + language_version: python3.12 + + - repo: https://github.com/pycqa/isort + rev: 5.13.2 + hooks: + - id: isort + args: ["--profile", "black"] - repo: https://github.com/astral-sh/ruff-pre-commit - # Ruff version. - rev: v0.14.6 + rev: v0.1.14 hooks: - # Run the linter. - id: ruff - args: [--fix] - # Run the formatter. - - id: ruff-format + args: ["--fix"] - - repo: https://github.com/Lucas-C/pre-commit-hooks - rev: v1.4.2 - hooks: - - id: insert-license - files: \.py$ - args: - - --license-filepath - - LICENSE.md - - --use-current-year - - repo: local + - repo: https://github.com/compilerla/conventional-pre-commit + rev: v3.0.0 hooks: - - id: pyright - name: pyright - entry: poetry run pyright - language: system - types: [python] - pass_filenames: false + - id: conventional-pre-commit + stages: [commit-msg] \ No newline at end of file diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..b9c34c2532 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,35 @@ +# Code of Conduct + +## Our Commitment + +We are committed to providing a welcoming and inclusive environment for all contributors. + +## Standards + +Examples of behavior that contributes to a positive environment: +- Using welcoming and inclusive language +- Being respectful of differing viewpoints +- Accepting constructive criticism gracefully +- Focusing on what is best for the community + +Examples of unacceptable behavior: +- Trolling or insulting comments +- Public or private harassment +- Publishing others' private information +- Other conduct which could reasonably be considered inappropriate + +## Responsibilities + +Project maintainers are responsible for clarifying standards of acceptable behavior and will take appropriate action in response to unacceptable behavior. + +## Scope + +This Code of Conduct applies within all project spaces and when representing the project in public spaces. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the project team. All complaints will be reviewed and investigated promptly and fairly. + +## Attribution + +This Code of Conduct is adapted from common open source community standards. \ No newline at end of file