fix(assessors): support project-named directories and test-only repos in standard_layout check#322
Conversation
… in standard_layout Enhances StandardLayoutAssessor to recognize multiple valid Python project structures instead of rigidly requiring src/: - Project-named directories (e.g., pandas/pandas/) now pass the check - Test-only repositories now receive NOT_APPLICABLE instead of failing - Parses pyproject.toml for project name (PEP 621 and Poetry formats) - Falls back to detecting any root directory with __init__.py - Adds blocklist to exclude non-source directories (tests, docs, utils, etc.) - Updates remediation to present both src/ and flat layout as valid options Fixes ambient-code#246 Fixes ambient-code#305 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
📈 Test Coverage Report
Coverage calculated from unit tests only |
AgentReady Code Review — PR #322Scope: StandardLayoutAssessor — support project-named directories and test-only repos SummaryThis PR correctly identifies two real shortcomings in the original StandardLayoutAssessor and the general approach is sound. The three-strategy source detection and context-aware remediation are meaningful improvements. However, there are several correctness and reliability issues that need addressing before merge. IssuesCritical1. setup.cfg is not a test-only indicator (structure.py:262) setup.cfg is used across nearly all Python projects for mypy, flake8, coverage.py, setuptools, and many other tools. Including it in test_indicators will incorrectly classify regular Python projects that lack a src/ layout as test-only repos — returning not_applicable when they should fail and receive remediation guidance. tox.ini is similarly risky — it is used by many non-test-only projects for linting, building, and docs. At minimum remove setup.cfg; consider also removing tox.ini. 2. Non-deterministic directory ordering in Strategy 3 (structure.py:214) Path.iterdir() returns entries in filesystem-dependent order (hash-randomized on some filesystems, inode order on others). The first qualifying directory found becomes the reported source directory, producing inconsistent behaviour across runs and platforms. Fix: Significant3. Strategy 3 fallback is too permissive (structure.py:204-220) Any root-level directory with __init__.py not in _NON_SOURCE_DIRS qualifies as a source directory. This will match migrations/, alembic/, config/, middleware/, settings/, celery/ etc. — none of which are package source directories. A project with migrations/__init__.py and tests/ but no src/ and no pyproject.toml would pass when it should fail. Consider whether Strategy 3 should exist at all without a pyproject.toml. 4. Name-based test-only detection is over-broad (structure.py:272) Using Use word-boundary matching instead: import re
name_suggests_tests = bool(
re.search(r"(^\|[-_.])(test\|tests\|testing\|spec\|specs)($\|[-_.])", repository.name.lower())
)5. _NON_SOURCE_DIRS is missing common entries (structure.py:14) The blocklist omits migrations, alembic, config, settings, middleware, static, assets, data, ci, resources, locale, i18n. These are common root-level directories with __init__.py that Strategy 3 would pick up as false-positive source directories. Minor6. Redundant has_tests re-check in _is_test_only_repository (structure.py:249) The caller only invokes this method when 7. Empty strings in commands list create blank entries (structure.py:320) Empty strings in the commands list render as blank command lines in the HTML report. Use a comment line or handle spacing in the template instead. Positives
AgentReady Attribute Compliance
Score Impact AssessmentTest-only repo case (not_applicable): Repos penalised for a non-applicable attribute will have it excluded from their denominator. This is the correct behaviour and improves score accuracy. Project-named directory case: Repos using flat layout (numpy/pandas style) that were scoring 50/100 on this attribute will now score 100/100. This directly fixes the reported false negatives. standard_layout carries 10% weight (Tier 1 Essential). A 50 to 100 correction on this attribute translates to a +5 point boost to the overall score for affected repos. RecommendationRequest changes. The core approach is correct and the bugs being fixed are real. The critical issues (setup.cfg false positive, non-deterministic iteration, over-broad name matching, Strategy 3 false positives) need to be addressed before this is safe to merge. The risk is that the fix introduces a new class of false positives that silently suppress remediation guidance for repos that need it. |
AgentReady Code Review — PR #322Scope: SummaryThis PR correctly identifies two real shortcomings in the original IssuesCritical1.
2. Non-deterministic directory ordering in Strategy 3 (
Fix: Significant3. Strategy 3 fallback is too permissive ( Any root-level directory with Consider whether Strategy 3 should exist at all without a 4. Name-based test-only detection is over-broad ( Using Use word-boundary matching: name_suggests_tests = bool(
re.search(r"(^|[-_.])(test|tests|testing|spec|specs)($|[-_.])", repository.name.lower())
)5. The blocklist omits Minor6. Redundant The caller only invokes this method when 7. Empty strings in Empty strings in the commands list render as blank lines in the HTML report. Use a comment line instead. Positives
AgentReady Attribute Compliance
Score Impact AssessmentTest-only repo case ( Project-named directory case: Repos using flat layout (numpy/pandas style) that were scoring 50/100 will now score 100/100. Directly fixes reported false negatives.
RecommendationRequest changes. The core approach is correct and the bugs being fixed are real. The critical issues ( |
Changes based on code review: Critical: - Remove setup.cfg from test_indicators (false positive risk) - Sort directory iteration for deterministic cross-platform behavior Significant: - Limit Strategy 3 (fallback detection) to repos with pyproject.toml - Use word-boundary regex for test-only repo name detection - Expand _NON_SOURCE_DIRS blocklist with migrations, config, etc. Minor: - Remove redundant has_tests check (caller already verifies) - Replace empty strings in commands with comment separators Updated test to expect failure for project-named directory without pyproject.toml, matching the new stricter detection behavior. All 16 tests pass. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
AgentReady Code Review — PR #322Attribute: SummaryThis PR addresses two real issues (#246, #305) with solid overall design: the three-strategy source detection and the Issues[Bug]
|
| Scenario | Before | After |
|---|---|---|
| Flat-layout project (pandas-style) | FAIL (50) — false negative | PASS (100) ✓ |
| Test-only repo (opendatahub-tests) | FAIL (50) — false positive | NOT_APPLICABLE ✓ |
Project with pytest.ini, no detectable src |
FAIL (50) | NOT_APPLICABLE — possible false skip |
| Celery project assessment | PASS (100) | FAIL (50) — regression |
Verdict
Request changes on the pytest.ini/conftest.py test-only indicators and the celery blocklist entry before merging. The core design is sound and most changes are clear improvements.
Review generated by AgentReady code review skill
Fixes based on code review comment #3948171727: Bug fixes: - pytest.ini/conftest.py only indicate test-only repos when pyproject.toml is absent; mixed projects typically have pyproject.toml so these files alone are not reliable test-only indicators - Remove celery, middleware, alembic from blocklist since these are legitimate package names for their respective projects (Celery, etc.) Design improvement: - Strategy 3 (heuristic fallback) now returns type "heuristic" and evidence shows "— verify" suffix to flag that this is a best-guess match, not an exact name match from pyproject.toml Style cleanup: - Remove self-referential "PR ambient-code#322 feedback:" comments; replaced with direct rationale where still needed Added 3 new tests: - test_pytest_ini_with_pyproject_is_not_test_only - test_celery_directory_not_blocked - test_heuristic_match_shows_verify_in_evidence All 19 tests pass. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
AgentReady Code Review - PR #322SummaryThis PR addresses two real-world correctness bugs (#246, #305) in AgentReady Attribute Analysis
Security ReviewNo security issues found. The PR reads only local filesystem paths derived from the already-trusted Code QualityStrategy 3 gating comment is inaccurate. Strategy 3 executes inside the Untyped return value from The method returns a plain from typing import TypedDict
class SourceDirectoryResult(TypedDict):
found: bool
type: str
directory: strLatent fragility in
Test assertion is missing an explanatory comment. In
Common directories like Python version compatibility -- confirmed safe.
RecommendationsP0 -- Address before merge:
P1 -- Strong recommendations:
P2 -- Nice to have:
Score Impact EstimateThe Estimated impact: affected repositories could see a +5 to +10 point improvement in overall AgentReady score, depending on which other Tier 1 attributes were previously passing. This directly improves assessor correctness and reduces false negatives for real-world Python project layouts. Review generated by the AgentReady Development Agent. |
High Priority Fixes: - Add TypedDict (SourceDirectoryInfo) for _find_source_directory return type to provide type safety and prevent runtime key typos - Fix Strategy 3 scoping bug: heuristic fallback now runs whenever pyproject.toml exists, not just when a package name is found. This allows repos with pyproject.toml containing only [build-system] to still benefit from heuristic source directory detection. Medium Priority (Tests): - Add test for pyproject.toml without name field (only [build-system]) - Add test for project-named directory without __init__.py (namespace packages) verifying Strategy 2 falls through to Strategy 3 correctly Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add missing blank line after TypedDict class definition. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Summary
Enhances
StandardLayoutAssessorto recognize multiple valid Python project structures:pandas/pandas/) now passNOT_APPLICABLEinstead of failingRelated Issues
Root Cause
The original implementation hardcoded
src/as a required directory, following the research report's guidance for "src layout." However, this didn't account for:Changes
src/agentready/assessors/structure.py_NON_SOURCE_DIRSblocklist to exclude non-source directories from detection_find_source_directory()with three-strategy detection:src/(existing behavior)pyproject.tomlfor project name, look for matching directory__init__.pynot in blocklist_get_package_name_from_pyproject()supporting PEP 621 and Poetry formats_is_test_only_repository()to detect test repos by config files and naming_create_remediation()to provide context-aware guidancetests/unit/test_assessors_structure.pyAdded 11 new tests covering:
Testing
opendatahub-tests(test-only repo)mypackage/dirsrc/dir# All 16 tests pass uv run pytest tests/unit/test_assessors_structure.py -vBreaking Changes
None. Backward compatible:
src/layout continue to pass unchangedNOT_APPLICABLEChecklist
Co-Authored-By: Claude Opus 4.5 noreply@anthropic.com