aiox-core 5.0.7 → 5.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.aiox-core/cli/commands/pro/buyer.js +379 -0
- package/.aiox-core/cli/commands/pro/index.js +191 -52
- package/.aiox-core/cli/commands/validate/index.js +2 -0
- package/.aiox-core/core/code-intel/helpers/dev-helper.js +1 -1
- package/.aiox-core/core/code-intel/helpers/devops-helper.js +0 -1
- package/.aiox-core/core/code-intel/helpers/planning-helper.js +1 -1
- package/.aiox-core/core/code-intel/helpers/qa-helper.js +2 -2
- package/.aiox-core/core/config/schemas/framework-config.schema.json +1 -0
- package/.aiox-core/core/config/template-overrides.js +1 -1
- package/.aiox-core/core/doctor/checks/ide-sync.js +81 -25
- package/.aiox-core/core/doctor/checks/rules-files.js +0 -1
- package/.aiox-core/core/doctor/checks/skills-count.js +83 -15
- package/.aiox-core/core/graph-dashboard/cli.js +1 -2
- package/.aiox-core/core/graph-dashboard/data-sources/code-intel-source.js +1 -1
- package/.aiox-core/core/ids/layer-classifier.js +1 -1
- package/.aiox-core/core/pro/pro-updater.js +578 -0
- package/.aiox-core/core/synapse/context/context-tracker.js +107 -9
- package/.aiox-core/core/synapse/layers/layer-processor.js +1 -1
- package/.aiox-core/core-config.yaml +15 -1
- package/.aiox-core/data/capability-detection.js +15 -15
- package/.aiox-core/data/entity-registry.yaml +18 -2
- package/.aiox-core/data/registry-update-log.jsonl +5 -0
- package/.aiox-core/data/tok3-token-comparison.js +0 -4
- package/.aiox-core/data/tool-search-validation.js +1 -1
- package/.aiox-core/development/agents/aiox-master.md +44 -6
- package/.aiox-core/development/agents/data-engineer.md +4 -4
- package/.aiox-core/development/agents/devops.md +52 -2
- package/.aiox-core/development/agents/po.md +1 -1
- package/.aiox-core/development/agents/qa.md +5 -11
- package/.aiox-core/development/agents/sm.md +3 -3
- package/.aiox-core/development/agents/ux-design-expert.md +1 -1
- package/.aiox-core/development/scripts/unified-activation-pipeline.js +29 -3
- package/.aiox-core/development/tasks/dev-develop-story.md +46 -7
- package/.aiox-core/development/tasks/devops-pro-access-grant.md +93 -0
- package/.aiox-core/development/tasks/devops-pro-activate.md +42 -0
- package/.aiox-core/development/tasks/devops-pro-check-access.md +34 -0
- package/.aiox-core/development/tasks/devops-pro-request-reset.md +34 -0
- package/.aiox-core/development/tasks/devops-pro-resend-verification.md +32 -0
- package/.aiox-core/development/tasks/devops-pro-reset-password.md +36 -0
- package/.aiox-core/development/tasks/devops-pro-validate-login.md +36 -0
- package/.aiox-core/development/tasks/devops-pro-verify-status.md +33 -0
- package/.aiox-core/development/tasks/qa-gate.md +54 -4
- package/.aiox-core/development/tasks/validate-next-story.md +39 -2
- package/.aiox-core/framework-config.yaml +1 -0
- package/.aiox-core/infrastructure/scripts/codex-skills-sync/README.md +69 -0
- package/.aiox-core/infrastructure/scripts/codex-skills-sync/bootstrap.js +727 -0
- package/.aiox-core/infrastructure/scripts/codex-skills-sync/index.js +10 -0
- package/.aiox-core/infrastructure/scripts/codex-skills-sync/validate.js +65 -4
- package/.aiox-core/infrastructure/scripts/generate-settings-json.js +29 -4
- package/.aiox-core/infrastructure/scripts/ide-sync/agent-parser.js +4 -0
- package/.aiox-core/infrastructure/scripts/ide-sync/index.js +67 -7
- package/.aiox-core/infrastructure/scripts/ide-sync/transformers/claude-code.js +145 -3
- package/.aiox-core/infrastructure/scripts/repair-agent-references.js +263 -0
- package/.aiox-core/infrastructure/scripts/validate-claude-integration.js +60 -8
- package/.aiox-core/infrastructure/scripts/validate-paths.js +13 -0
- package/.aiox-core/install-manifest.yaml +134 -82
- package/.aiox-core/utils/filters/index.js +2 -1
- package/.claude/commands/AIOX/agents/aiox-master.md +21 -0
- package/.claude/commands/AIOX/agents/analyst.md +21 -0
- package/.claude/commands/AIOX/agents/architect.md +21 -0
- package/.claude/commands/AIOX/agents/data-engineer.md +21 -0
- package/.claude/commands/AIOX/agents/dev.md +21 -0
- package/.claude/commands/AIOX/agents/devops.md +21 -0
- package/.claude/commands/AIOX/agents/pm.md +21 -0
- package/.claude/commands/AIOX/agents/po.md +21 -0
- package/.claude/commands/AIOX/agents/qa.md +21 -0
- package/.claude/commands/AIOX/agents/sm.md +21 -0
- package/.claude/commands/AIOX/agents/squad-creator.md +21 -0
- package/.claude/commands/AIOX/agents/ux-design-expert.md +21 -0
- package/.claude/commands/AIOX/scripts/agent-config-loader.js +624 -0
- package/.claude/commands/AIOX/scripts/generate-greeting.js +160 -0
- package/.claude/commands/AIOX/scripts/greeting-builder.js +866 -0
- package/.claude/commands/AIOX/scripts/session-context-loader.js +286 -0
- package/.claude/commands/AIOX/stories/story-6.1.4.md +1404 -0
- package/.claude/commands/cohort-squad/agents/cohort-manager.md +156 -0
- package/.claude/commands/design-system/agents/brad-frost.md +1097 -0
- package/.claude/commands/design-system/agents/dan-mall.md +857 -0
- package/.claude/commands/design-system/agents/dave-malouf.md +2272 -0
- package/.claude/commands/design-system/agents/design-chief.md +102 -0
- package/.claude/commands/design-system/agents/nano-banana-generator.md +162 -0
- package/.claude/commands/greet.md +101 -0
- package/.claude/commands/synapse/manager.md +75 -0
- package/.claude/commands/synapse/tasks/add-rule.md +94 -0
- package/.claude/commands/synapse/tasks/create-command.md +109 -0
- package/.claude/commands/synapse/tasks/create-domain.md +127 -0
- package/.claude/commands/synapse/tasks/diagnose-synapse.md +245 -0
- package/.claude/commands/synapse/tasks/edit-rule.md +109 -0
- package/.claude/commands/synapse/tasks/suggest-domain.md +116 -0
- package/.claude/commands/synapse/tasks/toggle-domain.md +83 -0
- package/.claude/commands/synapse/templates/domain-template +8 -0
- package/.claude/commands/synapse/templates/manifest-entry-template +4 -0
- package/.claude/commands/synapse/utils/manifest-parser-reference.md +134 -0
- package/.claude/hooks/precompact-session-digest.cjs +2 -2
- package/.claude/skills/AIOX/agents/aiox-master/SKILL.md +511 -0
- package/.claude/skills/AIOX/agents/analyst/SKILL.md +281 -0
- package/.claude/skills/AIOX/agents/architect/SKILL.md +482 -0
- package/.claude/skills/AIOX/agents/data-engineer/SKILL.md +503 -0
- package/.claude/skills/AIOX/agents/dev/SKILL.md +568 -0
- package/.claude/skills/AIOX/agents/devops/SKILL.md +597 -0
- package/.claude/skills/AIOX/agents/pm/SKILL.md +385 -0
- package/.claude/skills/AIOX/agents/po/SKILL.md +343 -0
- package/.claude/skills/AIOX/agents/qa/SKILL.md +451 -0
- package/.claude/skills/AIOX/agents/sm/SKILL.md +295 -0
- package/.claude/skills/AIOX/agents/squad-creator/SKILL.md +352 -0
- package/.claude/skills/AIOX/agents/ux-design-expert/SKILL.md +503 -0
- package/.claude/skills/architect-first/SKILL.md +275 -0
- package/.claude/skills/architect-first/assets/architecture-template.md +505 -0
- package/.claude/skills/architect-first/assets/config-template.yaml +351 -0
- package/.claude/skills/architect-first/references/architecture-checklist.md +216 -0
- package/.claude/skills/architect-first/references/pre-implementation-checklist.md +119 -0
- package/.claude/skills/architect-first/references/stop-rules-guide.md +291 -0
- package/.claude/skills/architect-first/references/testing-strategy-guide.md +477 -0
- package/.claude/skills/architect-first/scripts/architecture_validator.py +490 -0
- package/.claude/skills/architect-first/scripts/check_coupling.py +306 -0
- package/.claude/skills/architect-first/scripts/validate_risk_mitigation.py +382 -0
- package/.claude/skills/checklist-runner/SKILL.md +113 -0
- package/.claude/skills/clone-mind.md +329 -0
- package/.claude/skills/coderabbit-review/SKILL.md +106 -0
- package/.claude/skills/course-generation-workflow.md +76 -0
- package/.claude/skills/enhance-workflow.md +466 -0
- package/.claude/skills/mcp-builder/LICENSE.txt +202 -0
- package/.claude/skills/mcp-builder/SKILL.md +328 -0
- package/.claude/skills/mcp-builder/reference/evaluation.md +602 -0
- package/.claude/skills/mcp-builder/reference/mcp_best_practices.md +915 -0
- package/.claude/skills/mcp-builder/reference/node_mcp_server.md +916 -0
- package/.claude/skills/mcp-builder/reference/python_mcp_server.md +752 -0
- package/.claude/skills/mcp-builder/scripts/connections.py +151 -0
- package/.claude/skills/mcp-builder/scripts/evaluation.py +373 -0
- package/.claude/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/.claude/skills/mcp-builder/scripts/requirements.txt +2 -0
- package/.claude/skills/ralph.md +181 -0
- package/.claude/skills/skill-creator/LICENSE.txt +202 -0
- package/.claude/skills/skill-creator/SKILL.md +209 -0
- package/.claude/skills/skill-creator/scripts/init_skill.py +303 -0
- package/.claude/skills/skill-creator/scripts/package_skill.py +110 -0
- package/.claude/skills/skill-creator/scripts/quick_validate.py +65 -0
- package/.claude/skills/squad.md +301 -0
- package/.claude/skills/synapse/SKILL.md +132 -0
- package/.claude/skills/synapse/assets/README.md +50 -0
- package/.claude/skills/synapse/references/brackets.md +100 -0
- package/.claude/skills/synapse/references/commands.md +118 -0
- package/.claude/skills/synapse/references/domains.md +126 -0
- package/.claude/skills/synapse/references/layers.md +186 -0
- package/.claude/skills/synapse/references/manifest.md +142 -0
- package/.claude/skills/tech-search/SKILL.md +431 -0
- package/.claude/skills/tech-search/prompts/page-extract.md +133 -0
- package/README.en.md +2 -2
- package/README.md +8 -2
- package/bin/aiox.js +55 -4
- package/bin/utils/framework-guard.js +4 -2
- package/bin/utils/pro-detector.js +119 -28
- package/bin/utils/validate-publish.js +6 -6
- package/docs/aiox-agent-flows/devops-system.md +18 -0
- package/docs/aiox-workflows/README.md +1 -0
- package/docs/aiox-workflows/pro-access-grant-workflow.md +218 -0
- package/docs/guides/pro/access-grant-ops-playbook.md +370 -0
- package/docs/guides/pro/install-gate-setup.md +12 -6
- package/docs/guides/pro/squad-creator-handoff-pro-access-ops.md +134 -0
- package/docs/guides/supabase-ops-handoff.md +768 -0
- package/package.json +12 -1
- package/packages/aiox-pro-cli/bin/aiox-pro.js +33 -12
- package/packages/installer/src/config/configure-environment.js +118 -50
- package/packages/installer/src/installer/aiox-core-installer.js +124 -27
- package/packages/installer/src/installer/brownfield-upgrader.js +66 -9
- package/packages/installer/src/installer/dependency-installer.js +4 -0
- package/packages/installer/src/pro/pro-scaffolder.js +5 -5
- package/packages/installer/src/updater/index.js +151 -10
- package/packages/installer/src/wizard/ide-config-generator.js +73 -7
- package/packages/installer/src/wizard/index.js +119 -31
- package/packages/installer/src/wizard/pro-setup.js +118 -47
- package/packages/installer/src/wizard/validation/validators/dependency-validator.js +32 -25
- package/packages/installer/src/wizard/validation/validators/file-structure-validator.js +26 -0
- package/packages/installer/tests/unit/artifact-copy-pipeline/artifact-copy-pipeline.test.js +84 -1
- package/packages/installer/tests/unit/claude-md-template-v5/claude-md-template-v5.test.js +1 -1
- package/packages/installer/tests/unit/doctor/doctor-checks.test.js +85 -19
- package/packages/installer/tests/unit/entity-registry-bootstrap.test.js +4 -4
- package/packages/installer/tests/unit/generate-settings-json/generate-settings-json.test.js +5 -5
- package/packages/installer/tests/unit/ide-sync-integration/ide-sync-integration.test.js +4 -4
- package/packages/installer/tests/unit/merger/yaml-merger.test.js +11 -11
- package/pro/README.md +12 -1
- package/pro/license/index.js +3 -11
- package/pro/license/license-api.js +25 -0
- package/pro/license/license-cache.js +135 -31
- package/pro/license/license-crypto.js +59 -3
- package/pro/package.json +5 -4
- package/pro/squads/README.md +16 -16
- package/pro/squads/index.js +1 -1
- package/scripts/e2e/installed-skills-smoke.js +264 -0
- package/scripts/package-synapse.js +3 -3
- package/scripts/validate-package-completeness.js +8 -11
- package/.aiox-core/lib/build.json +0 -1
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Architecture Documentation Validator
|
|
4
|
+
|
|
5
|
+
Validates that architectural documentation is complete before implementation.
|
|
6
|
+
Checks for required sections, diagrams, and documentation completeness.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
python architecture_validator.py [--path ARCH_DOC_PATH]
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import os
|
|
13
|
+
import sys
|
|
14
|
+
import argparse
|
|
15
|
+
import re
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
from typing import List, Dict, Set, Tuple
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ValidationIssue:
|
|
21
|
+
"""Represents a validation issue"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, severity: str, category: str, message: str, location: str = ""):
|
|
24
|
+
self.severity = severity # error, warning, info
|
|
25
|
+
self.category = category
|
|
26
|
+
self.message = message
|
|
27
|
+
self.location = location
|
|
28
|
+
|
|
29
|
+
def __str__(self):
|
|
30
|
+
icon = {"error": "❌", "warning": "⚠️", "info": "ℹ️"}[self.severity]
|
|
31
|
+
loc = f" ({self.location})" if self.location else ""
|
|
32
|
+
return f"{icon} [{self.category}] {self.message}{loc}"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ArchitectureValidator:
|
|
36
|
+
"""Validates architecture documentation completeness"""
|
|
37
|
+
|
|
38
|
+
def __init__(self, doc_path: Path):
|
|
39
|
+
self.doc_path = doc_path
|
|
40
|
+
self.content = ""
|
|
41
|
+
self.issues: List[ValidationIssue] = []
|
|
42
|
+
|
|
43
|
+
# Required sections in architecture doc
|
|
44
|
+
self.required_sections = [
|
|
45
|
+
"Overview",
|
|
46
|
+
"Architecture",
|
|
47
|
+
"Components",
|
|
48
|
+
"Data Flow",
|
|
49
|
+
"Integration",
|
|
50
|
+
"Configuration",
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
# Recommended sections
|
|
54
|
+
self.recommended_sections = [
|
|
55
|
+
"Deployment",
|
|
56
|
+
"Security",
|
|
57
|
+
"Performance",
|
|
58
|
+
"Monitoring",
|
|
59
|
+
"Testing",
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
def _load_document(self) -> bool:
|
|
63
|
+
"""Load architecture document"""
|
|
64
|
+
try:
|
|
65
|
+
with open(self.doc_path, "r", encoding="utf-8") as f:
|
|
66
|
+
self.content = f.read()
|
|
67
|
+
return True
|
|
68
|
+
except Exception as e:
|
|
69
|
+
self.issues.append(
|
|
70
|
+
ValidationIssue(
|
|
71
|
+
"error",
|
|
72
|
+
"DOCUMENT",
|
|
73
|
+
f"Could not load document: {e}",
|
|
74
|
+
)
|
|
75
|
+
)
|
|
76
|
+
return False
|
|
77
|
+
|
|
78
|
+
def _check_required_sections(self):
|
|
79
|
+
"""Check for required sections"""
|
|
80
|
+
found_sections = set()
|
|
81
|
+
|
|
82
|
+
# Find all markdown headers
|
|
83
|
+
headers = re.findall(r"^#{1,3}\s+(.+)$", self.content, re.MULTILINE)
|
|
84
|
+
|
|
85
|
+
for header in headers:
|
|
86
|
+
header_clean = header.strip().lower()
|
|
87
|
+
for required in self.required_sections:
|
|
88
|
+
if required.lower() in header_clean:
|
|
89
|
+
found_sections.add(required)
|
|
90
|
+
|
|
91
|
+
# Report missing sections
|
|
92
|
+
missing = set(self.required_sections) - found_sections
|
|
93
|
+
for section in missing:
|
|
94
|
+
self.issues.append(
|
|
95
|
+
ValidationIssue(
|
|
96
|
+
"error",
|
|
97
|
+
"REQUIRED_SECTION",
|
|
98
|
+
f"Missing required section: '{section}'",
|
|
99
|
+
)
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
# Check recommended sections
|
|
103
|
+
for recommended in self.recommended_sections:
|
|
104
|
+
if not any(recommended.lower() in h.lower() for h in headers):
|
|
105
|
+
self.issues.append(
|
|
106
|
+
ValidationIssue(
|
|
107
|
+
"warning",
|
|
108
|
+
"RECOMMENDED_SECTION",
|
|
109
|
+
f"Missing recommended section: '{recommended}'",
|
|
110
|
+
)
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
def _check_diagrams(self):
|
|
114
|
+
"""Check for architectural diagrams"""
|
|
115
|
+
# Look for diagram indicators
|
|
116
|
+
diagram_indicators = [
|
|
117
|
+
r"!\[.*\]\(.*\.(?:png|jpg|svg|drawio)\)", # Image links
|
|
118
|
+
r"```(?:mermaid|plantuml|dot)", # Diagram code blocks
|
|
119
|
+
r"#{2,3}\s+.*[Dd]iagram", # Diagram sections
|
|
120
|
+
]
|
|
121
|
+
|
|
122
|
+
has_diagrams = any(
|
|
123
|
+
re.search(pattern, self.content) for pattern in diagram_indicators
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
if not has_diagrams:
|
|
127
|
+
self.issues.append(
|
|
128
|
+
ValidationIssue(
|
|
129
|
+
"error",
|
|
130
|
+
"DIAGRAMS",
|
|
131
|
+
"No architectural diagrams found. Include at least: "
|
|
132
|
+
"system architecture, component interaction, and data flow diagrams.",
|
|
133
|
+
)
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
def _check_component_documentation(self):
|
|
137
|
+
"""Check that components are documented"""
|
|
138
|
+
# Look for components section
|
|
139
|
+
components_match = re.search(
|
|
140
|
+
r"#{1,3}\s+Components.*?\n(.*?)(?=\n#{1,3}|\Z)",
|
|
141
|
+
self.content,
|
|
142
|
+
re.DOTALL | re.IGNORECASE,
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
if not components_match:
|
|
146
|
+
self.issues.append(
|
|
147
|
+
ValidationIssue(
|
|
148
|
+
"error",
|
|
149
|
+
"COMPONENTS",
|
|
150
|
+
"Components section not found or empty",
|
|
151
|
+
)
|
|
152
|
+
)
|
|
153
|
+
return
|
|
154
|
+
|
|
155
|
+
components_section = components_match.group(1)
|
|
156
|
+
|
|
157
|
+
# Check for component descriptions (bullets or numbered lists)
|
|
158
|
+
component_items = re.findall(
|
|
159
|
+
r"^[-*\d.]+\s+\*\*([^*:]+)\*\*:?\s*(.+)$",
|
|
160
|
+
components_section,
|
|
161
|
+
re.MULTILINE,
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
if len(component_items) < 2:
|
|
165
|
+
self.issues.append(
|
|
166
|
+
ValidationIssue(
|
|
167
|
+
"warning",
|
|
168
|
+
"COMPONENTS",
|
|
169
|
+
"Components section has few documented components. "
|
|
170
|
+
"Ensure all major components are listed and described.",
|
|
171
|
+
)
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
# Check that each component has a description
|
|
175
|
+
for name, description in component_items:
|
|
176
|
+
if len(description.strip()) < 20:
|
|
177
|
+
self.issues.append(
|
|
178
|
+
ValidationIssue(
|
|
179
|
+
"warning",
|
|
180
|
+
"COMPONENTS",
|
|
181
|
+
f"Component '{name}' has minimal description",
|
|
182
|
+
"Components",
|
|
183
|
+
)
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
def _check_data_flow(self):
|
|
187
|
+
"""Check data flow documentation"""
|
|
188
|
+
data_flow_keywords = [
|
|
189
|
+
"data flow",
|
|
190
|
+
"flow diagram",
|
|
191
|
+
"data pipeline",
|
|
192
|
+
"workflow",
|
|
193
|
+
]
|
|
194
|
+
|
|
195
|
+
has_data_flow = any(
|
|
196
|
+
kw in self.content.lower() for kw in data_flow_keywords
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
if not has_data_flow:
|
|
200
|
+
self.issues.append(
|
|
201
|
+
ValidationIssue(
|
|
202
|
+
"error",
|
|
203
|
+
"DATA_FLOW",
|
|
204
|
+
"Data flow not documented. Include data flow diagram "
|
|
205
|
+
"or detailed description of how data moves through the system.",
|
|
206
|
+
)
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
def _check_integration_points(self):
|
|
210
|
+
"""Check integration points documentation"""
|
|
211
|
+
integration_keywords = [
|
|
212
|
+
"integration",
|
|
213
|
+
"api",
|
|
214
|
+
"interface",
|
|
215
|
+
"endpoint",
|
|
216
|
+
"external",
|
|
217
|
+
]
|
|
218
|
+
|
|
219
|
+
integration_match = re.search(
|
|
220
|
+
r"#{1,3}\s+Integration.*?\n(.*?)(?=\n#{1,3}|\Z)",
|
|
221
|
+
self.content,
|
|
222
|
+
re.DOTALL | re.IGNORECASE,
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
if not integration_match:
|
|
226
|
+
self.issues.append(
|
|
227
|
+
ValidationIssue(
|
|
228
|
+
"warning",
|
|
229
|
+
"INTEGRATION",
|
|
230
|
+
"Integration section not found. Document external integrations.",
|
|
231
|
+
)
|
|
232
|
+
)
|
|
233
|
+
return
|
|
234
|
+
|
|
235
|
+
integration_section = integration_match.group(1)
|
|
236
|
+
|
|
237
|
+
# Check for API/interface documentation
|
|
238
|
+
if len(integration_section.strip()) < 100:
|
|
239
|
+
self.issues.append(
|
|
240
|
+
ValidationIssue(
|
|
241
|
+
"warning",
|
|
242
|
+
"INTEGRATION",
|
|
243
|
+
"Integration section is brief. Document all external integrations, "
|
|
244
|
+
"APIs, and interfaces in detail.",
|
|
245
|
+
)
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
def _check_configuration(self):
|
|
249
|
+
"""Check configuration documentation"""
|
|
250
|
+
config_match = re.search(
|
|
251
|
+
r"#{1,3}\s+Configuration.*?\n(.*?)(?=\n#{1,3}|\Z)",
|
|
252
|
+
self.content,
|
|
253
|
+
re.DOTALL | re.IGNORECASE,
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
if not config_match:
|
|
257
|
+
self.issues.append(
|
|
258
|
+
ValidationIssue(
|
|
259
|
+
"error",
|
|
260
|
+
"CONFIGURATION",
|
|
261
|
+
"Configuration section not found. Must document configuration schema.",
|
|
262
|
+
)
|
|
263
|
+
)
|
|
264
|
+
return
|
|
265
|
+
|
|
266
|
+
config_section = config_match.group(1)
|
|
267
|
+
|
|
268
|
+
# Check for YAML/config examples
|
|
269
|
+
has_yaml_example = re.search(r"```ya?ml", config_section, re.IGNORECASE)
|
|
270
|
+
|
|
271
|
+
if not has_yaml_example:
|
|
272
|
+
self.issues.append(
|
|
273
|
+
ValidationIssue(
|
|
274
|
+
"warning",
|
|
275
|
+
"CONFIGURATION",
|
|
276
|
+
"No YAML configuration example found. Include sample configuration.",
|
|
277
|
+
)
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
# Check for configuration parameters documentation
|
|
281
|
+
if "parameter" not in config_section.lower() and "option" not in config_section.lower():
|
|
282
|
+
self.issues.append(
|
|
283
|
+
ValidationIssue(
|
|
284
|
+
"warning",
|
|
285
|
+
"CONFIGURATION",
|
|
286
|
+
"Configuration parameters not documented. List all config options.",
|
|
287
|
+
)
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
def _check_decision_documentation(self):
|
|
291
|
+
"""Check for documented architectural decisions"""
|
|
292
|
+
decision_keywords = [
|
|
293
|
+
"decision",
|
|
294
|
+
"rationale",
|
|
295
|
+
"trade-off",
|
|
296
|
+
"alternative",
|
|
297
|
+
"chose",
|
|
298
|
+
"option",
|
|
299
|
+
]
|
|
300
|
+
|
|
301
|
+
has_decisions = any(kw in self.content.lower() for kw in decision_keywords)
|
|
302
|
+
|
|
303
|
+
if not has_decisions:
|
|
304
|
+
self.issues.append(
|
|
305
|
+
ValidationIssue(
|
|
306
|
+
"warning",
|
|
307
|
+
"DECISIONS",
|
|
308
|
+
"Architectural decisions not documented. Include decision rationale "
|
|
309
|
+
"and alternatives considered.",
|
|
310
|
+
)
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
def _check_document_length(self):
|
|
314
|
+
"""Check if document has sufficient detail"""
|
|
315
|
+
word_count = len(self.content.split())
|
|
316
|
+
line_count = len(self.content.split("\n"))
|
|
317
|
+
|
|
318
|
+
if word_count < 500:
|
|
319
|
+
self.issues.append(
|
|
320
|
+
ValidationIssue(
|
|
321
|
+
"warning",
|
|
322
|
+
"COMPLETENESS",
|
|
323
|
+
f"Document is brief ({word_count} words). "
|
|
324
|
+
"Ensure sufficient detail for implementation.",
|
|
325
|
+
)
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
if line_count < 100:
|
|
329
|
+
self.issues.append(
|
|
330
|
+
ValidationIssue(
|
|
331
|
+
"info",
|
|
332
|
+
"COMPLETENESS",
|
|
333
|
+
f"Document is short ({line_count} lines). Consider adding more detail.",
|
|
334
|
+
)
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
def _check_code_examples(self):
|
|
338
|
+
"""Check for code examples or technical details"""
|
|
339
|
+
code_blocks = re.findall(r"```[\w]*\n", self.content)
|
|
340
|
+
|
|
341
|
+
if len(code_blocks) < 2:
|
|
342
|
+
self.issues.append(
|
|
343
|
+
ValidationIssue(
|
|
344
|
+
"info",
|
|
345
|
+
"EXAMPLES",
|
|
346
|
+
"Few code examples found. Consider adding code snippets "
|
|
347
|
+
"to illustrate implementation.",
|
|
348
|
+
)
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
def run(self) -> int:
|
|
352
|
+
"""Run validation"""
|
|
353
|
+
print("🔍 Validating architecture documentation...")
|
|
354
|
+
print(f" Document: {self.doc_path}")
|
|
355
|
+
print()
|
|
356
|
+
|
|
357
|
+
# Load document
|
|
358
|
+
if not self._load_document():
|
|
359
|
+
self._report_results()
|
|
360
|
+
return 1
|
|
361
|
+
|
|
362
|
+
# Run all validations
|
|
363
|
+
print("📋 Checking required sections...")
|
|
364
|
+
self._check_required_sections()
|
|
365
|
+
|
|
366
|
+
print("🎨 Checking diagrams...")
|
|
367
|
+
self._check_diagrams()
|
|
368
|
+
|
|
369
|
+
print("🧩 Checking component documentation...")
|
|
370
|
+
self._check_component_documentation()
|
|
371
|
+
|
|
372
|
+
print("🔄 Checking data flow documentation...")
|
|
373
|
+
self._check_data_flow()
|
|
374
|
+
|
|
375
|
+
print("🔌 Checking integration points...")
|
|
376
|
+
self._check_integration_points()
|
|
377
|
+
|
|
378
|
+
print("⚙️ Checking configuration documentation...")
|
|
379
|
+
self._check_configuration()
|
|
380
|
+
|
|
381
|
+
print("💡 Checking decision documentation...")
|
|
382
|
+
self._check_decision_documentation()
|
|
383
|
+
|
|
384
|
+
print("📏 Checking document completeness...")
|
|
385
|
+
self._check_document_length()
|
|
386
|
+
|
|
387
|
+
print("💻 Checking code examples...")
|
|
388
|
+
self._check_code_examples()
|
|
389
|
+
|
|
390
|
+
print()
|
|
391
|
+
|
|
392
|
+
return self._report_results()
|
|
393
|
+
|
|
394
|
+
def _report_results(self) -> int:
|
|
395
|
+
"""Report validation results"""
|
|
396
|
+
if not self.issues:
|
|
397
|
+
print("=" * 80)
|
|
398
|
+
print("✅ ARCHITECTURE DOCUMENTATION VALID")
|
|
399
|
+
print("=" * 80)
|
|
400
|
+
print()
|
|
401
|
+
print("All required sections present and documented.")
|
|
402
|
+
print("Ready to proceed to implementation.")
|
|
403
|
+
return 0
|
|
404
|
+
|
|
405
|
+
# Categorize issues
|
|
406
|
+
errors = [i for i in self.issues if i.severity == "error"]
|
|
407
|
+
warnings = [i for i in self.issues if i.severity == "warning"]
|
|
408
|
+
info = [i for i in self.issues if i.severity == "info"]
|
|
409
|
+
|
|
410
|
+
print("=" * 80)
|
|
411
|
+
print("VALIDATION RESULTS")
|
|
412
|
+
print("=" * 80)
|
|
413
|
+
print()
|
|
414
|
+
print(f"Errors: {len(errors)}")
|
|
415
|
+
print(f"Warnings: {len(warnings)}")
|
|
416
|
+
print(f"Info: {len(info)}")
|
|
417
|
+
print()
|
|
418
|
+
|
|
419
|
+
# Report errors first
|
|
420
|
+
if errors:
|
|
421
|
+
print("ERRORS (must fix before implementation):")
|
|
422
|
+
print("-" * 80)
|
|
423
|
+
for issue in errors:
|
|
424
|
+
print(f" {issue}")
|
|
425
|
+
print()
|
|
426
|
+
|
|
427
|
+
# Then warnings
|
|
428
|
+
if warnings:
|
|
429
|
+
print("WARNINGS (should address):")
|
|
430
|
+
print("-" * 80)
|
|
431
|
+
for issue in warnings:
|
|
432
|
+
print(f" {issue}")
|
|
433
|
+
print()
|
|
434
|
+
|
|
435
|
+
# Then info
|
|
436
|
+
if info:
|
|
437
|
+
print("SUGGESTIONS:")
|
|
438
|
+
print("-" * 80)
|
|
439
|
+
for issue in info:
|
|
440
|
+
print(f" {issue}")
|
|
441
|
+
print()
|
|
442
|
+
|
|
443
|
+
print("=" * 80)
|
|
444
|
+
|
|
445
|
+
if errors:
|
|
446
|
+
print("❌ VALIDATION FAILED")
|
|
447
|
+
print()
|
|
448
|
+
print("Architecture documentation incomplete.")
|
|
449
|
+
print("Fix all errors before proceeding to implementation.")
|
|
450
|
+
print()
|
|
451
|
+
print("See: references/stop-rules-guide.md (Stop Rule 4)")
|
|
452
|
+
return 1
|
|
453
|
+
elif warnings:
|
|
454
|
+
print("⚠️ VALIDATION PASSED WITH WARNINGS")
|
|
455
|
+
print()
|
|
456
|
+
print("Consider addressing warnings for more complete documentation.")
|
|
457
|
+
return 0
|
|
458
|
+
else:
|
|
459
|
+
print("✅ VALIDATION PASSED")
|
|
460
|
+
return 0
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
def main():
|
|
464
|
+
parser = argparse.ArgumentParser(
|
|
465
|
+
description="Validate architecture documentation completeness"
|
|
466
|
+
)
|
|
467
|
+
parser.add_argument(
|
|
468
|
+
"--path",
|
|
469
|
+
type=Path,
|
|
470
|
+
help="Path to architecture document (markdown file)",
|
|
471
|
+
required=True,
|
|
472
|
+
)
|
|
473
|
+
|
|
474
|
+
args = parser.parse_args()
|
|
475
|
+
|
|
476
|
+
if not args.path.exists():
|
|
477
|
+
print(f"❌ Error: Document not found: {args.path}", file=sys.stderr)
|
|
478
|
+
sys.exit(1)
|
|
479
|
+
|
|
480
|
+
if not args.path.is_file():
|
|
481
|
+
print(f"❌ Error: Not a file: {args.path}", file=sys.stderr)
|
|
482
|
+
sys.exit(1)
|
|
483
|
+
|
|
484
|
+
validator = ArchitectureValidator(args.path)
|
|
485
|
+
exit_code = validator.run()
|
|
486
|
+
sys.exit(exit_code)
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
if __name__ == "__main__":
|
|
490
|
+
main()
|