Skip to content

Commit 4bd34e2

Browse files
committed
feat: prioritize execution graph insights in generated readmes
Standard README order is now: Overview Architecture Overview Execution Graph Summary Execution Routes Recommendations Variable Reference Task File Reference Handlers
1 parent f09bf6a commit 4bd34e2

4 files changed

Lines changed: 48 additions & 8 deletions

File tree

docsible/analyzers/recommendations/__init__.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
from pathlib import Path
22

33
from docsible.models.recommendation import Recommendation
4+
from docsible.models.severity import Severity
45

56
from .enhancement import EnhancementRecommendationGenerator
67
from .quality import QualityRecommendationGenerator
78
from .security import SecurityRecommendationGenerator
89

910

10-
def generate_all_recommendations(role_path: Path) -> list[Recommendation]:
11+
def generate_all_recommendations(role_path: Path, analysis_report=None) -> list[Recommendation]:
1112
"""Generate all recommendations for a role.
1213
1314
Args:
@@ -30,6 +31,31 @@ def generate_all_recommendations(role_path: Path) -> list[Recommendation]:
3031
enhancement_gen = EnhancementRecommendationGenerator()
3132
all_recommendations.extend(enhancement_gen.analyze_role(role_path))
3233

34+
if analysis_report is not None:
35+
metrics = analysis_report.metrics
36+
if metrics.dynamic_boundaries:
37+
all_recommendations.append(
38+
Recommendation(
39+
severity=Severity.INFO,
40+
category="execution_graph",
41+
message=f"{metrics.dynamic_boundaries} dynamic execution boundaries need runtime review",
42+
rationale="Templated includes cannot be resolved to one static execution path.",
43+
remediation="Review the Execution Graph Summary and validate each dynamic path.",
44+
confidence=1.0,
45+
)
46+
)
47+
if metrics.collection_dependencies:
48+
all_recommendations.append(
49+
Recommendation(
50+
severity=Severity.INFO,
51+
category="execution_graph",
52+
message=f"Role depends on {metrics.collection_dependencies} Ansible collections",
53+
rationale="Collection availability affects portability and runtime module resolution.",
54+
remediation="Pin and document collection requirements.",
55+
confidence=1.0,
56+
)
57+
)
58+
3359
# Sort by severity (critical first)
3460
all_recommendations.sort(key=lambda r: r.severity.priority, reverse=True)
3561

docsible/commands/document_role/orchestrators/role_orchestrator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def execute(self) -> None:
8585
self._validate_documentation(role_info, analysis_report, diagrams, dependency_data)
8686

8787
# Step 7.5: Generate recommendations (use validated role_path from step 1)
88-
recommendations = generate_all_recommendations(role_path)
88+
recommendations = generate_all_recommendations(role_path, analysis_report)
8989

9090
if self.context.analysis.apply_suppressions:
9191
from docsible.suppression.engine import apply_suppressions

docsible/templates/role/sections/adaptive_diagrams.jinja2

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,16 @@ This role contains **{{ complexity_report.metrics.total_tasks }} tasks** across
6161
- Task Includes: {{ complexity_report.metrics.task_includes }}
6262
- Role Dependencies: {{ complexity_report.metrics.role_dependencies }}
6363

64+
### Execution Graph Summary
65+
- Collection dependencies: {{ complexity_report.metrics.collection_dependencies }}
66+
- Conditional decision points: {{ complexity_report.metrics.conditional_decision_points }}
67+
- Statically reachable task files: {{ complexity_report.metrics.static_reachable_task_files }}
68+
- Dynamic boundaries: {{ complexity_report.metrics.dynamic_boundaries }}
69+
- Unknown boundaries: {{ complexity_report.metrics.unknown_boundaries }}
70+
- Handler notification edges: {{ complexity_report.metrics.notification_edges }}
71+
- Loop-bearing tasks: {{ complexity_report.metrics.loop_tasks }}
72+
- Orphan task files: {{ complexity_report.metrics.orphan_task_files }}
73+
6474
{% if architecture_diagram %}
6575
### Component Architecture
6676
This diagram shows the internal structure and data flow of the role:

docsible/templates/role/standard_modular.jinja2

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,28 @@
1313
{% include 'sections/argument_specs.jinja2' %}
1414
{% endif %}
1515
{% endif %}
16+
{% if not no_diagrams %}
17+
{% include 'sections/complexity_analysis.jinja2' %}
18+
{% include 'sections/simplification_suggestions.jinja2' %}
19+
{% include 'sections/adaptive_diagrams.jinja2' %}
20+
{% include 'sections/integration_boundary.jinja2' %}
21+
{% endif %}
22+
{% if role.defaults or role.vars %}
23+
## Variable Reference
24+
{% endif %}
1625
{% if role.defaults %}
1726
{% include 'sections/defaults.jinja2' %}
1827
{% endif %}
1928
{% if role.vars %}
2029
{% include 'sections/vars.jinja2' %}
2130
{% endif %}
2231
{% if not no_tasks %}
32+
## Task File Reference
2333
{% include 'sections/tasks.jinja2' %}
2434
{% endif %}
2535
{% if not no_handlers %}
2636
{% include 'sections/handlers.jinja2' %}
2737
{% endif %}
28-
{% if not no_diagrams %}
29-
{% include 'sections/complexity_analysis.jinja2' %}
30-
{% include 'sections/simplification_suggestions.jinja2' %}
31-
{% include 'sections/adaptive_diagrams.jinja2' %}
32-
{% include 'sections/integration_boundary.jinja2' %}
33-
{% endif %}
3438
{% include 'sections/playbook.jinja2' %}
3539
{% include 'sections/dependencies.jinja2' %}
3640
<!-- DOCSIBLE END -->

0 commit comments

Comments
 (0)