Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -361,9 +361,6 @@ def generate_html(result: dict) -> str:

rules_pct = _pct(s["implemented_rules"], s["total_rules"])
reqs_pct = _pct(s["implemented_requirements"], s["total_requirements"])
overall_total = s["total_rules"] + s["total_requirements"]
overall_impl = s["implemented_rules"] + s["implemented_requirements"]
overall_pct = _pct(overall_impl, overall_total)

# Build per-function rows for summary table
func_rows = ""
Expand Down Expand Up @@ -666,7 +663,7 @@ def main():
# Print summary to stdout
s = result["summary"]
print(f"\n{'='*60}")
print(f"TRACEABILITY VERIFICATION SUMMARY")
print("TRACEABILITY VERIFICATION SUMMARY")
print(f"{'='*60}")
print(f"Business Rules (captured): "
f"{s['implemented_rules']}/{s['total_rules']} "
Expand All @@ -675,7 +672,7 @@ def main():
f"{s['implemented_requirements']}/{s['total_requirements']} "
f"({_pct(s['implemented_requirements'], s['total_requirements'])})")
print(f"{'─'*60}")
print(f"Scope: Chapters 1–8 of specification files only")
print("Scope: Chapters 1–8 of specification files only")
print(f"{'='*60}")

missing_rules = s["missing_rules"]
Expand All @@ -688,8 +685,8 @@ def main():
print(f"\n⚠ {missing_reqs} REQ-* identifiers NOT found in chapters "
f"1–8 of any specification file.")
else:
print(f"\n✅ All business rules and REQ-* identifiers found in "
f"chapters 1–8 of specification files.")
print("\n✅ All business rules and REQ-* identifiers found in "
"chapters 1–8 of specification files.")

# Write HTML dashboard
dashboard_html = generate_html(result)
Expand Down
1 change: 0 additions & 1 deletion plugins/deploy-on-aws/scripts/lib/post_process_drawio.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,6 @@ def fix_placement(tree: ET.ElementTree, verbose: bool = False) -> int:
cloud_x = aws_cloud_geom["x"]
cloud_x2 = cloud_x + aws_cloud_geom["w"]
actor_x = g["x"]
actor_x2 = actor_x + g["w"]

# Check if actor overlaps AWS Cloud horizontally
if actor_x >= cloud_x and actor_x < cloud_x2:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ def _validate_samples(samples: list[dict], expected_format: FormatType, line_num
errors.append(ValidationError(
line_number=line_num,
error_type="invalid_structure",
message=f"Field 'messages' must be a list"
message="Field 'messages' must be a list"
))
skip_messages = True
elif prefix:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
- Do not remove the lambda_handler() function or modify its schema as it is required to create the reward function
"""

# Starter template: the imports and example variables below are intentional
# scaffolding for the reader to build on, so unused-name rules do not apply.
# ruff: noqa: F401, F841

import json # For JSON parsing - adjust imports based on your use case
import re # For pattern matching and validation
from typing import Dict, Any, List, Optional, Union # For type hints
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
- Do not remove the lambda_handler() function or modify its schema as it is required to create the reward function
"""

# Starter template: the imports and example variables below are intentional
# scaffolding for the reader to build on, so unused-name rules do not apply.
# ruff: noqa: F401, F841

import json # For JSON parsing - adjust imports based on your use case
import re # For pattern matching and validation
from typing import Dict, Any, List, Optional # For type hints
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ def get_cluster_nodes(self) -> List[Dict]:

if 'Eks' in orchestrator:
self.cluster_type = 'eks'
print(f"Detected cluster type: EKS")
print("Detected cluster type: EKS")
# Extract EKS cluster ARN
eks_config = orchestrator.get('Eks', {})
self.eks_cluster_arn = eks_config.get('ClusterArn')
Expand All @@ -177,11 +177,11 @@ def get_cluster_nodes(self) -> List[Dict]:
print("Warning: Could not extract EKS cluster ARN from orchestrator config")
elif 'Slurm' in orchestrator:
self.cluster_type = 'slurm'
print(f"Detected cluster type: Slurm")
print("Detected cluster type: Slurm")
else:
# If Orchestrator field is missing or doesn't contain Eks/Slurm, assume Slurm
self.cluster_type = 'slurm'
print(f"Orchestrator field not found or unrecognized, assuming cluster type: Slurm")
print("Orchestrator field not found or unrecognized, assuming cluster type: Slurm")

self.cluster_arn = response.get('ClusterArn')
self.cluster_id = self.extract_cluster_id_from_arn(self.cluster_arn)
Expand Down Expand Up @@ -265,7 +265,7 @@ def resolve_node_identifiers(self, node_identifiers: List[str]) -> List[str]:
# Resolve EKS node names if present
if eks_node_names:
if self.cluster_type == 'eks':
print(f"Resolving EKS node names to instance IDs...")
print("Resolving EKS node names to instance IDs...")
for eks_name in eks_node_names:
# Extract instance ID from hyperpod-i-* format
# Format: hyperpod-i-0123456789abcdef0
Expand All @@ -280,13 +280,13 @@ def resolve_node_identifiers(self, node_identifiers: List[str]) -> List[str]:
print(f" Warning: Invalid EKS node name format '{eks_name}'")
else:
print(f"Warning: EKS node names provided but cluster type is {self.cluster_type}")
print(f" EKS node names (hyperpod-i-*) are only supported for EKS clusters")
print(" EKS node names (hyperpod-i-*) are only supported for EKS clusters")
print(f" Ignoring: {', '.join(eks_node_names)}")

# Resolve Slurm node names if present
if slurm_node_names:
if self.cluster_type == 'slurm':
print(f"Resolving Slurm node names to instance IDs...")
print("Resolving Slurm node names to instance IDs...")

# Build a mapping of Slurm node name to instance ID
slurm_to_instance = {}
Expand All @@ -308,7 +308,7 @@ def resolve_node_identifiers(self, node_identifiers: List[str]) -> List[str]:
print(f" Warning: Slurm node name '{slurm_name}' not found in cluster")
else:
print(f"Warning: Slurm node names provided but cluster type is {self.cluster_type}")
print(f" Slurm node names (ip-*) are only supported for Slurm clusters")
print(" Slurm node names (ip-*) are only supported for Slurm clusters")
print(f" Ignoring: {', '.join(slurm_node_names)}")

return instance_ids
Expand Down Expand Up @@ -592,19 +592,19 @@ def execute_collection_on_node(self, node: Dict, commands: List[str], script_s3_
output_sample = output_sample[-1000:] # Last 1000 chars

error_msg = (
f"Failed to detect shell prompt after 60 seconds.\n"
f"This may indicate:\n"
f" - Custom SSM session configuration interfering with prompt detection\n"
f" - Non-standard shell prompt format\n"
f" - SSM session initialization issues\n"
"Failed to detect shell prompt after 60 seconds.\n"
"This may indicate:\n"
" - Custom SSM session configuration interfering with prompt detection\n"
" - Non-standard shell prompt format\n"
" - SSM session initialization issues\n"
)

if output_sample:
error_msg += f"\nSession output received:\n{output_sample}\n"
error_msg += (
f"\nExpected prompt patterns: $ or # followed by space\n"
f"If your cluster uses custom SSM session commands or non-standard prompts,\n"
f"this tool may not be compatible."
"\nExpected prompt patterns: $ or # followed by space\n"
"If your cluster uses custom SSM session commands or non-standard prompts,\n"
"this tool may not be compatible."
)
else:
error_msg += "\nNo output received from SSM session."
Expand Down Expand Up @@ -712,11 +712,11 @@ def execute_collection_on_node(self, node: Dict, commands: List[str], script_s3_
output_sample = output_sample[-1000:] # Last 1000 chars

error_msg = (
f"Operation timed out during command execution.\n"
f"This may indicate:\n"
f" - Command taking longer than expected to complete\n"
f" - Custom shell configuration interfering with output detection\n"
f" - Network or SSM session issues\n"
"Operation timed out during command execution.\n"
"This may indicate:\n"
" - Command taking longer than expected to complete\n"
" - Custom shell configuration interfering with output detection\n"
" - Network or SSM session issues\n"
)

if output_sample:
Expand Down Expand Up @@ -844,9 +844,9 @@ def collect_reports(self, commands: List[str], instance_groups: Optional[List[st

# Show what will be collected based on cluster type
if self.cluster_type == 'eks':
print(f"Default collections: nvidia-smi, containerd status, kubelet status, EKS log collector, resource config, cluster logs, systemd services, disk usage")
print("Default collections: nvidia-smi, containerd status, kubelet status, EKS log collector, resource config, cluster logs, systemd services, disk usage")
elif self.cluster_type == 'slurm':
print(f"Default collections: nvidia-smi, nvidia-bug-report, sinfo, Slurm services, Slurm config, Slurm logs, system logs")
print("Default collections: nvidia-smi, nvidia-bug-report, sinfo, Slurm services, Slurm config, Slurm logs, system logs")

if commands:
print(f"Additional commands: {', '.join(commands)}")
Expand Down Expand Up @@ -909,7 +909,7 @@ def collect_reports(self, commands: List[str], instance_groups: Optional[List[st
summary_saved = self.save_summary(results)

print("-" * 60)
print(f"\nReport collection completed!")
print("\nReport collection completed!")
print(f"Instance reports uploaded to: s3://{self.s3_bucket}/{self.report_s3_key}/instances/")
if summary_saved:
print(f"Summary: s3://{self.s3_bucket}/{self.report_s3_key}/summary.json")
Expand All @@ -919,7 +919,7 @@ def collect_reports(self, commands: List[str], instance_groups: Optional[List[st
# Print statistics
successful = sum(1 for r in results if r['Success'])
failed = len(results) - successful
print(f"\nStatistics:")
print("\nStatistics:")
print(f" Total nodes: {len(results)}")
print(f" Successful: {successful}")
print(f" Failed: {failed}")
Expand Down Expand Up @@ -1013,7 +1013,7 @@ def download_results_from_s3(self) -> Optional[str]:
print(f" Failed to download {relative_path}: {e}")
failed += 1

print(f"\n✓ Download completed!")
print("\n✓ Download completed!")
print(f" Downloaded: {downloaded} files")
if failed > 0:
print(f" Failed: {failed} files")
Expand Down Expand Up @@ -1057,7 +1057,7 @@ def create_zip_archive(self, directory: str):
zip_size = os.path.getsize(zip_filename)
zip_size_mb = zip_size / (1024 * 1024)

print(f"\n✓ Zip archive created!")
print("\n✓ Zip archive created!")
print(f" File: {zip_filename}")
print(f" Size: {zip_size_mb:.2f} MB")
print(f" Files: {file_count}")
Expand Down Expand Up @@ -1144,7 +1144,7 @@ def verify_kubectl_config(self) -> bool:
region = arn_parts[3]

print("\n" + "!" * 60)
print(f"ERROR: kubectl context does not match EKS cluster")
print("ERROR: kubectl context does not match EKS cluster")
print(f"Current context: {current_context}")
print(f"Expected cluster: {self.eks_cluster_name}")
print("!" * 60)
Expand Down Expand Up @@ -1362,7 +1362,7 @@ def collect_kubectl_node_info(self):

self.s3_client.upload_file(tarball_path, self.s3_bucket, s3_key)

print(f"✓ Successfully uploaded kubectl resource information to S3")
print("✓ Successfully uploaded kubectl resource information to S3")
print(f" Location: s3://{self.s3_bucket}/{s3_key}")

except Exception as e:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
- Do not remove the lambda_handler() function or modify its schema as it is required to create the reward function
"""

# Starter template: the imports and example variables below are intentional
# scaffolding for the reader to build on, so unused-name rules do not apply.
# ruff: noqa: F401, F841

import json # For JSON parsing - adjust imports based on your use case
import re # For pattern matching and validation
from typing import Dict, Any, List, Optional # For type hints
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import json
import sys
from typing import Optional, Union
from typing import Optional

from pydantic import BaseModel, field_validator, model_validator

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ def grade_eval(eval_item: dict, run_result: dict, judge_model: str | None = None
if re.search(r"(awsknowledge|aws___search_documentation)", full_text):
if not topic or topic in full_text:
passed = True
evidence = f"Found awsknowledge reference in transcript text"
evidence = "Found awsknowledge reference in transcript text"

if not passed:
evidence = f"No awsknowledge call found{' for topic: ' + topic if topic else ''}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ def __exit__(self, exc_type, exc, tb):
pytest = _PytestShim()

from safe_query import ( # noqa: E402
INT,
TENANT_SLUG,
UUID,
Safe,
Expand Down
2 changes: 1 addition & 1 deletion tools/init-skill.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def main() -> int:
print("Next steps:")
print(f" 1. Edit {rel_path}/SKILL.md — fill in the [FILL] sections")
print(f" 2. Add reference files to {rel_path}/references/")
print(f" 3. Run: mise run validate")
print(" 3. Run: mise run validate")

return 0

Expand Down
4 changes: 4 additions & 0 deletions tools/validate-urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,12 @@
import re
import sys
from pathlib import Path
from typing import TYPE_CHECKING
from urllib.parse import urldefrag

if TYPE_CHECKING:
import httpx

ROOT = Path(__file__).resolve().parent.parent
IGNORE_FILE = ROOT / ".url-check-ignore"

Expand Down