AgentReady Assessment — OpenStack Nova (vanilla)
🤖 AgentReady Assessment Report
Repository: repo
Path: /repo
Branch: master | Commit: 7e0f18ff
Assessed: March 23, 2026 at 5:39 PM
AgentReady Version: 2.29.6
Run by: sbauza@9ce339bc1218
📊 Summary
| Metric | Value |
|---|---|
| Overall Score | 20.8/100 ⚠️ Needs Improvement (Tier Definitions) |
| Attributes Assessed | 20/25 |
| Attributes Not Assessed | 5 |
| Assessment Duration | 23.0s |
Languages Detected
- Python: 1499 files
- YAML: 1157 files
- JSON: 913 files
- Shell: 24 files
Repository Stats
- Total Files: 4,733
- Total Lines: 702,795
🎯 Priority Improvements
Focus on these high-impact fixes first:
- CLAUDE.md Configuration Files (Tier 1) - +10.0 points potential
- Create CLAUDE.md or AGENTS.md with project-specific configuration for AI coding assistants
- README Structure (Tier 1) - +10.0 points potential
- Create or enhance README.md with essential sections
- Dependency Pinning for Reproducibility (Tier 1) - +10.0 points potential
- Improve dependency version pinning
- Dependency Security & Vulnerability Scanning (Tier 1) - +4.0 points potential
- Configure security scanning for dependencies and code
- Type Annotations (Tier 1) - +10.0 points potential
- Add type annotations to function signatures
📋 Detailed Findings
Findings sorted by priority (Tier 1 failures first, then Tier 2, etc.)
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 ``` README Structure ❌ 0/100
📝 Remediation Steps
**Measured**: missing (Threshold: present with sections) **Evidence**: - README.md not found Create or enhance README.md with essential sections 1. Add project overview and description 2. Include installation/setup instructions 3. Document basic usage with examples 4. Add development/contributing guidelines 5. Include build and test commands **Examples**: ``` # Project Name ## Overview What this project does and why it exists. ## Installation ```bash pip install -e . ``` ## Usage ```bash myproject --help ``` ## Development ```bash # Run tests pytest # Format code black . ``` ``` Dependency Pinning for Reproducibility ❌ 0/100
📝 Remediation Steps
**Measured**: requirements.txt (Threshold: lock file with pinned versions, < 6 months old) **Evidence**: - Found requirements.txt: 0 pinned, 60 unpinned - ⚠️ 60 dependencies not pinned (use '==' not '>=') Improve dependency version pinning 1. Use exact version pinning (== not >=) in requirements.txt 2. Or switch to poetry.lock or Pipfile.lock for automatic pinning 3. Update dependencies regularly (at least every 6 months) **Commands**: ```bash pip freeze > requirements.txt # Exact versions poetry lock # Auto-managed lock file ``` Dependency Security & Vulnerability Scanning ❌ 0/100
📝 Remediation Steps
**Measured**: No security scanning tools configured (Threshold: ≥60 points (Dependabot/Renovate + SAST or multiple scanners)) **Evidence**: - No security scanning tools detected Configure security scanning for dependencies and code 1. Enable Dependabot in GitHub repository settings 2. Add .github/dependabot.yml configuration file 3. Or configure Renovate: add renovate.json to repository root 4. Set up CodeQL scanning for SAST 5. Add secret detection to pre-commit hooks 6. Configure language-specific security scanners **Commands**: ```bash gh repo edit --enable-security pip install pre-commit detect-secrets pre-commit install ``` **Examples**: ``` # .github/dependabot.yml version: 2 updates: - package-ecosystem: pip directory: / schedule: interval: weekly ``` ``` # renovate.json { "extends": ["config:base"], "schedule": "after 10pm every weekday" } ``` ``` # .pre-commit-config.yaml repos: - repo: https://github.com/Yelp/detect-secrets rev: v1.4.0 hooks: - id: detect-secrets ``` Type Annotations ❌ 2/100
📝 Remediation Steps
**Measured**: 1.6% (Threshold: ≥80%) **Evidence**: - Typed functions: 465/28905 - Coverage: 1.6% 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 } } ``` Standard Project Layouts ❌ 50/100
📝 Remediation Steps
**Measured**: 1/2 directories (Threshold: 2/2 directories) **Evidence**: - Found 1/2 standard directories - source (project-named): ✓ (nova/) - tests/: ✗ Organize code into standard directories 1. Create tests/ directory for test files 2. Add at least one test file **Commands**: ```bash # Create tests directory mkdir -p tests touch tests/__init__.py touch tests/test_example.py ``` **Examples**: ``` # src layout (recommended for distributable packages) project/ ├── src/ │ └── mypackage/ │ ├── __init__.py │ └── module.py ├── tests/ │ └── test_module.py └── pyproject.toml # flat layout (common in major projects like pandas, numpy) project/ ├── mypackage/ │ ├── __init__.py │ └── module.py ├── tests/ │ └── test_module.py └── pyproject.toml ``` Conventional Commit Messages ❌ 0/100
📝 Remediation Steps
**Measured**: not configured (Threshold: configured) **Evidence**: - No commitlint configuration found (.commitlintrc.json, package.json, husky, or pre-commit) Configure conventional commits with commitlint 1. Option A (Python/pre-commit): Add conventional-pre-commit to .pre-commit-config.yaml 2. Option B (JS/commitlint): Install commitlint and configure husky for commit-msg hook **Commands**: ```bash # Python (pre-commit): pip install pre-commit && pre-commit install --hook-type commit-msg # JS (commitlint + husky): npm install --save-dev @commitlint/cli @commitlint/config-conventional husky ``` File Size Limits ❌ 0/100
📝 Remediation Steps
**Measured**: 113 huge, 113 large out of 1499 (Threshold: <5% files >500 lines, 0 files >1000 lines) **Evidence**: - Found 113 files >1000 lines (7.5% of 1499 files) - Largest: nova/api/openstack/compute/schemas/servers.py (2119 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 ``` Inline Documentation ❌ 24/100
📝 Remediation Steps
**Measured**: 18.8% (Threshold: ≥80%) **Evidence**: - Documented items: 5444/28915 - Coverage: 18.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); } ``` .gitignore Completeness ❌ 50/100
📝 Remediation Steps
**Measured**: 6/12 patterns (Threshold: ≥70% of language-specific patterns) **Evidence**: - .gitignore found (772 bytes) - Pattern coverage: 6/12 (50%) - Missing 6 recommended patterns Add missing language-specific ignore patterns 1. Review GitHub's gitignore templates for your language 2. Add the 6 missing patterns 3. Ensure editor/IDE patterns are included **Examples**: ``` # Missing patterns: .vscode/ __pycache__/ .pytest_cache/ *.py[cod] .env ``` Separation of Concerns ❌ 66/100
📝 Remediation Steps
**Measured**: organization:100, cohesion:85, naming:0 (Threshold: ≥75 overall) **Evidence**: - Good directory organization (feature-based or flat) - File cohesion: 17882/119891 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 ``` Pre-commit Hooks & CI/CD Linting ✅ 100/100
Test Coverage Requirements ⊘
One-Command Build/Setup ⊘
Concise Documentation ⊘
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 ``` ``` Issue & Pull Request Templates ❌ 0/100
📝 Remediation Steps
**Measured**: PR:False, Issues:0 (Threshold: PR template + ≥2 issue templates) **Evidence**: - No PR template found - No issue template directory found Create GitHub issue and PR templates in .github/ directory 1. Create .github/ directory if it doesn't exist 2. Add PULL_REQUEST_TEMPLATE.md for PRs 3. Create .github/ISSUE_TEMPLATE/ directory 4. Add bug_report.md for bug reports 5. Add feature_request.md for feature requests 6. Optionally add config.yml to configure template chooser **Commands**: ```bash # Create directories mkdir -p .github/ISSUE_TEMPLATE # Create PR template cat > .github/PULL_REQUEST_TEMPLATE.md << 'EOF' ## Summary ## Related Issues Fixes # ## Testing - [ ] Tests added/updated - [ ] All tests pass ## Checklist - [ ] Documentation updated - [ ] CHANGELOG.md updated EOF ``` **Examples**: ``` # Bug Report Template (.github/ISSUE_TEMPLATE/bug_report.md) ```markdown --- name: Bug Report about: Create a report to help us improve title: '[BUG] ' labels: bug assignees: '' --- **Describe the bug** A clear description of what the bug is. **To Reproduce** Steps to reproduce: 1. Go to '...' 2. Click on '....' 3. See error **Expected behavior** What you expected to happen. **Environment** - OS: [e.g. macOS 13.0] - Version: [e.g. 1.0.0] ``` ``` CI/CD Pipeline Visibility ❌ 0/100
📝 Remediation Steps
**Measured**: no CI config (Threshold: CI config present) **Evidence**: - No CI/CD configuration found - Checked: GitHub Actions, GitLab CI, CircleCI, Travis CI Add or improve CI/CD pipeline configuration 1. Create CI config for your platform (GitHub Actions, GitLab CI, etc.) 2. Define jobs: lint, test, build 3. Use descriptive job and step names 4. Configure dependency caching 5. Enable parallel job execution 6. Upload artifacts: test results, coverage reports 7. Add status badge to README **Commands**: ```bash # Create GitHub Actions workflow mkdir -p .github/workflows touch .github/workflows/ci.yml # Validate workflow gh workflow view ci.yml ``` **Examples**: ``` # .github/workflows/ci.yml - Good example name: CI Pipeline on: push: branches: [main] pull_request: branches: [main] jobs: lint: name: Lint Code runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.11' cache: 'pip' # Caching - name: Install dependencies run: pip install -r requirements.txt - name: Run linters run: | black --check . isort --check . ruff check . test: name: Run Tests runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.11' cache: 'pip' - name: Install dependencies run: pip install -r requirements.txt - name: Run tests with coverage run: pytest --cov --cov-report=xml - name: Upload coverage reports uses: codecov/codecov-action@v3 with: files: ./coverage.xml build: name: Build Package runs-on: ubuntu-latest needs: [lint, test] # Runs after lint/test pass steps: - uses: actions/checkout@v4 - name: Build package run: python -m build - name: Upload build artifacts uses: actions/upload-artifact@v3 with: name: dist path: dist/ ``` 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, setup.py - 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}") ``` 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" ``` Semantic Naming ✅ 94/100
Cyclomatic Complexity Thresholds ✅ 100/100
Code Smell Elimination ✅ 80/100
Branch Protection Rules ⊘
Container/Virtualization Setup ⊘
📝 Assessment Metadata
- AgentReady Version: v2.29.6
- Research Version: v1.0.1
- Repository Snapshot: 7e0f18ff2baaf6aec89eb300b6942c488541da7e
- Assessment Duration: 23.0s
- Assessed By: sbauza@9ce339bc1218
- Assessment Date: March 23, 2026 at 5:39 PM
🤖 Generated with Claude Code