Add generated project health and release status report#28
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a project health and release status reporting mechanism. It adds a new script, scripts/generate_project_health_report.py, which generates a deterministic Markdown report summarizing workflow readiness, contract validation surfaces, and cross-repo promotion status. The agent workflow and release checklists have been updated to include this report as a mandatory step. Feedback on the implementation suggests optimizing the file system traversal to prune ignored directories, ensuring the report consistently includes itself for better determinism, and refining the logic for detecting contract schemas to avoid false positives.
| def iter_repo_files(root: Path) -> list[Path]: | ||
| """Return repository files in stable order while skipping bulky trees.""" | ||
| files: list[Path] = [] | ||
| for path in root.rglob("*"): | ||
| rel = path.relative_to(root) | ||
| if any(part in SKIP_DIRS for part in rel.parts): | ||
| continue | ||
| if path.is_file(): | ||
| files.append(rel) | ||
| return sorted(files, key=lambda item: item.as_posix()) |
There was a problem hiding this comment.
The current implementation using rglob("*") followed by a filter is inefficient for repositories with large ignored directories (like .git or node_modules), as it traverses the entire tree before filtering. Pruning the traversal at the directory level would significantly improve performance, especially in an industrial context where repository size can grow.
| def iter_repo_files(root: Path) -> list[Path]: | |
| """Return repository files in stable order while skipping bulky trees.""" | |
| files: list[Path] = [] | |
| for path in root.rglob("*"): | |
| rel = path.relative_to(root) | |
| if any(part in SKIP_DIRS for part in rel.parts): | |
| continue | |
| if path.is_file(): | |
| files.append(rel) | |
| return sorted(files, key=lambda item: item.as_posix()) | |
| def iter_repo_files(root: Path) -> list[Path]: | |
| """Return repository files in stable order while skipping bulky trees.""" | |
| files: list[Path] = [] | |
| def _walk(current: Path): | |
| for path in sorted(current.iterdir(), key=lambda p: p.name): | |
| if path.is_dir(): | |
| if path.name in SKIP_DIRS: | |
| continue | |
| _walk(path) | |
| elif path.is_file(): | |
| files.append(path.relative_to(root)) | |
| _walk(root) | |
| return files |
| scripts = [path for path in files if path.parts[:1] == ("scripts",) and path.suffix == ".py"] | ||
| contract_files = [path for path in files if path.parts[:1] == ("contracts",) and path.suffix == ".json" and "examples" not in path.parts] | ||
| contract_examples = [path for path in files if path.parts[:2] == ("contracts", "examples") and path.suffix == ".json"] | ||
| report_files = [path for path in files if path.parts[:2] == ("docs", "reports")] |
There was a problem hiding this comment.
The report includes itself in the "Existing report files" section only if it already exists on disk when the script starts. This makes the output non-deterministic depending on whether the file was present before the script ran. To ensure a truly deterministic snapshot as intended, the report should always include itself in this list.
| report_files = [path for path in files if path.parts[:2] == ("docs", "reports")] | |
| report_path_rel = REPORT_PATH.relative_to(ROOT) | |
| report_files = sorted({path for path in files if path.parts[:2] == ("docs", "reports")} | {report_path_rel}, key=lambda item: item.as_posix()) |
| contract_examples = [path for path in files if path.parts[:2] == ("contracts", "examples") and path.suffix == ".json"] | ||
| report_files = [path for path in files if path.parts[:2] == ("docs", "reports")] | ||
|
|
||
| contract_schema_present = any(path.parts[:1] == ("contracts",) and path.name.endswith(".schema.json") for path in files) |
There was a problem hiding this comment.
The logic for contract_schema_present is inconsistent with contract_files because it does not explicitly exclude the examples directory. This could lead to a false positive if a schema file is incorrectly placed in contracts/examples/. It is better to derive this status from the already filtered contract_files list.
| contract_schema_present = any(path.parts[:1] == ("contracts",) and path.name.endswith(".schema.json") for path in files) | |
| contract_schema_present = any(path.name.endswith(".schema.json") for path in contract_files) |
Motivation
Description
scripts/generate_project_health_report.py, a Python 3.11+ standard-library-only generator that inspects repository paths and file-existence metadata, uses a staticgenerated_at(2026-01-01T00:00:00Z), and writesdocs/reports/project-health-report.md.docs/reports/project-health-report.mdand include the report sections required by the issue (repository overview, workflows, scripts, contracts/examples, existing reports, validation commands, release readiness, cross-repo checklist, next PRs, and safety notes)..github/workflows/agent-checks.ymlto compile and run the new generator as part of agent checks by addingpython -m py_compile scripts/generate_project_health_report.pyandpython scripts/generate_project_health_report.py.docs/AGENT_WORKFLOW.mdanddocs/CROSS_REPO_RELEASE_CHECKLIST.mdto reference the generator and the generated report and to instruct agents when to generate/review the health report.Testing
python -m py_compile scripts/generate_project_health_report.pywhich completed without errors.python scripts/generate_project_health_report.pywhich wrotedocs/reports/project-health-report.mdsuccessfully.Closes #27.
Codex Task