xoras-agent-framework 2.0.0__py3-none-any.whl

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.
Files changed (42) hide show
  1. build/lib/build/lib/examples/01_basic_agent.py +29 -0
  2. build/lib/build/lib/examples/02_secure_code_evaluator.py +31 -0
  3. build/lib/build/lib/tests/test_ast_security.py +47 -0
  4. build/lib/build/lib/tests/test_runtime.py +42 -0
  5. build/lib/build/lib/tests/test_signer.py +27 -0
  6. build/lib/build/lib/xoras/__init__.py +23 -0
  7. build/lib/build/lib/xoras/ast_security.py +141 -0
  8. build/lib/build/lib/xoras/cli.py +211 -0
  9. build/lib/build/lib/xoras/config.py +102 -0
  10. build/lib/build/lib/xoras/orchestrator.py +69 -0
  11. build/lib/build/lib/xoras/runtime.py +157 -0
  12. build/lib/build/lib/xoras/signer.py +64 -0
  13. build/lib/examples/01_basic_agent.py +29 -0
  14. build/lib/examples/02_secure_code_evaluator.py +31 -0
  15. build/lib/tests/test_ast_security.py +47 -0
  16. build/lib/tests/test_runtime.py +42 -0
  17. build/lib/tests/test_signer.py +27 -0
  18. build/lib/xoras/__init__.py +23 -0
  19. build/lib/xoras/ast_security.py +141 -0
  20. build/lib/xoras/cli.py +211 -0
  21. build/lib/xoras/config.py +102 -0
  22. build/lib/xoras/orchestrator.py +69 -0
  23. build/lib/xoras/runtime.py +157 -0
  24. build/lib/xoras/signer.py +64 -0
  25. examples/01_basic_agent.py +29 -0
  26. examples/02_secure_code_evaluator.py +31 -0
  27. tests/test_ast_security.py +47 -0
  28. tests/test_runtime.py +42 -0
  29. tests/test_signer.py +27 -0
  30. xoras/__init__.py +23 -0
  31. xoras/ast_security.py +141 -0
  32. xoras/cli.py +211 -0
  33. xoras/config.py +102 -0
  34. xoras/orchestrator.py +69 -0
  35. xoras/runtime.py +157 -0
  36. xoras/signer.py +64 -0
  37. xoras_agent_framework-2.0.0.dist-info/METADATA +130 -0
  38. xoras_agent_framework-2.0.0.dist-info/RECORD +42 -0
  39. xoras_agent_framework-2.0.0.dist-info/WHEEL +5 -0
  40. xoras_agent_framework-2.0.0.dist-info/entry_points.txt +2 -0
  41. xoras_agent_framework-2.0.0.dist-info/licenses/LICENSE +21 -0
  42. xoras_agent_framework-2.0.0.dist-info/top_level.txt +9 -0
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ XORAS Agentic Framework — Basic Agent Example
4
+ Demonstrates environment initialization, tool execution, and signed trace receipts.
5
+ """
6
+
7
+ from xoras import XORASAgentEnvironment
8
+
9
+ def main():
10
+ print("=== XORAS Agent Framework — Basic Agent Example ===")
11
+ env = XORASAgentEnvironment(config_path="xoras.env.yaml")
12
+
13
+ # Execute a safe file write tool
14
+ result = env.execute_tool(
15
+ agent_name="Engineer",
16
+ tool_name="file_write",
17
+ args={
18
+ "path": "artifacts/basic_agent_output.json",
19
+ "content": '{"message": "Hello from XORAS Agent Framework v2.0", "status": "active"}'
20
+ }
21
+ )
22
+
23
+ print("\nExecution Result:")
24
+ print("Success:", result.get("success"))
25
+ print("Path:", result.get("path"))
26
+ print("Receipt Signature:", result.get("receipt_signature"))
27
+
28
+ if __name__ == "__main__":
29
+ main()
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ XORAS Agentic Framework — AST Code Security Evaluator
4
+ Demonstrates AST static analysis and rejection of unsafe dynamic code snippets.
5
+ """
6
+
7
+ from xoras import ASTSecurityEngine
8
+
9
+ def evaluate_snippets():
10
+ engine = ASTSecurityEngine()
11
+
12
+ snippets = [
13
+ ("Safe Data Handler", "def process(x):\n return x.strip().lower()\n"),
14
+ ("Dynamic Eval Snippet", "eval('import os; os.system(\"ls\")')\n"),
15
+ ("Unsafe Subprocess", "import subprocess\nsubprocess.Popen('rm -rf /tmp', shell=True)\n"),
16
+ ("Hardcoded API Key", "AWS_SECRET_ACCESS_KEY = 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'\n")
17
+ ]
18
+
19
+ print("=== XORAS AST Security Evaluator Demo ===")
20
+ for title, code in snippets:
21
+ res = engine.scan_code(code)
22
+ print(f"\n[Snippet]: {title}")
23
+ print(f"Status: {'SAFE [PASSED]' if res.is_safe else 'UNSAFE [REJECTED]'}")
24
+ print(f"Safety Score: {res.safety_score * 100:.1f}%")
25
+ if res.violations:
26
+ print("Violations:", res.violations)
27
+ if res.secrets_detected:
28
+ print("Secrets:", res.secrets_detected)
29
+
30
+ if __name__ == "__main__":
31
+ evaluate_snippets()
@@ -0,0 +1,47 @@
1
+ """
2
+ Unit tests for XORAS AST Security Engine.
3
+ """
4
+
5
+ import pytest
6
+ from xoras.ast_security import ASTSecurityEngine
7
+
8
+ def test_ast_safe_code():
9
+ engine = ASTSecurityEngine()
10
+ code = """
11
+ def calculate_sum(a, b):
12
+ return a + b
13
+
14
+ print(calculate_sum(10, 20))
15
+ """
16
+ result = engine.scan_code(code)
17
+ assert result.is_safe is True
18
+ assert result.safety_score == 1.0
19
+ assert len(result.violations) == 0
20
+
21
+ def test_ast_forbidden_eval():
22
+ engine = ASTSecurityEngine()
23
+ code = """
24
+ x = 10
25
+ eval("print(x)")
26
+ """
27
+ result = engine.scan_code(code)
28
+ assert result.is_safe is False
29
+ assert any("eval()" in v for v in result.violations)
30
+
31
+ def test_ast_forbidden_exec():
32
+ engine = ASTSecurityEngine()
33
+ code = """
34
+ exec("import os; os.system('ls')")
35
+ """
36
+ result = engine.scan_code(code)
37
+ assert result.is_safe is False
38
+ assert any("exec()" in v for v in result.violations)
39
+
40
+ def test_ast_secret_leak_detection():
41
+ engine = ASTSecurityEngine()
42
+ code = """
43
+ AWS_SECRET_ACCESS_KEY = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
44
+ """
45
+ result = engine.scan_code(code)
46
+ assert result.is_safe is False
47
+ assert len(result.secrets_detected) > 0
@@ -0,0 +1,42 @@
1
+ """
2
+ Unit tests for XORAS Agentic Runtime & Orchestrator.
3
+ """
4
+
5
+ import os
6
+ from xoras.runtime import XORASAgentEnvironment
7
+ from xoras.orchestrator import SwarmOrchestrator
8
+
9
+ def test_runtime_file_write_and_read():
10
+ env = XORASAgentEnvironment(config_path="xoras.env.yaml")
11
+ write_res = env.execute_tool("Engineer", "file_write", {
12
+ "path": "artifacts/test_artifact.json",
13
+ "content": '{"version": "2.0.0", "status": "active"}'
14
+ })
15
+ assert write_res["success"] is True
16
+ assert "receipt_signature" in write_res
17
+
18
+ read_res = env.execute_tool("Engineer", "file_read", {
19
+ "path": "artifacts/test_artifact.json"
20
+ })
21
+ assert read_res["success"] is True
22
+ assert "active" in read_res["content"]
23
+
24
+ def test_runtime_ast_rejection():
25
+ env = XORASAgentEnvironment(config_path="xoras.env.yaml")
26
+ unsafe_res = env.execute_tool("Engineer", "file_write", {
27
+ "path": "artifacts/bad.py",
28
+ "content": 'eval("print(\'unsafe\')")'
29
+ })
30
+ assert unsafe_res["success"] is False
31
+ assert "blocked by XORAS AST security" in unsafe_res["error"]
32
+
33
+ def test_swarm_orchestrator_pipeline():
34
+ orch = SwarmOrchestrator()
35
+ res = orch.run_pipeline(
36
+ task_description="Deploy secure configuration manifest",
37
+ code_payload='{"config": "valid_json"}',
38
+ target_path="artifacts/swarm_output.json"
39
+ )
40
+ assert res["success"] is True
41
+ assert res["stage"] == "COMPLETED"
42
+ assert res["safety_score"] == 1.0
@@ -0,0 +1,27 @@
1
+ """
2
+ Unit tests for XORAS Cryptographic Signer.
3
+ """
4
+
5
+ from xoras.signer import CryptographicSigner
6
+
7
+ def test_evidence_receipt_signing_and_verification():
8
+ signer = CryptographicSigner()
9
+ payload = {"path": "test.txt", "content": "hello world"}
10
+ receipt = signer.sign_receipt("Engineer", "file_write", payload, "SUCCESS")
11
+
12
+ assert receipt.version == "xoras.evidence.v1"
13
+ assert receipt.organization == "XORAS Systems LLC"
14
+ assert receipt.status == "SUCCESS"
15
+ assert receipt.signature is not None
16
+
17
+ # Verify signature mathematically
18
+ assert signer.verify_receipt(receipt) is True
19
+
20
+ def test_evidence_receipt_tamper_rejection():
21
+ signer = CryptographicSigner()
22
+ payload = {"path": "test.txt", "content": "hello world"}
23
+ receipt = signer.sign_receipt("Engineer", "file_write", payload, "SUCCESS")
24
+
25
+ # Tamper with status
26
+ receipt.status = "FAILED"
27
+ assert signer.verify_receipt(receipt) is False
@@ -0,0 +1,23 @@
1
+ """
2
+ XORAS Systems LLC — Agentic Environment & Governance Framework
3
+ Enterprise-grade multi-agent runtime, AST static security gating, and cryptographic provenance receipts.
4
+ """
5
+
6
+ __version__ = "2.0.0"
7
+ __author__ = "XORAS Systems LLC"
8
+
9
+ from .config import XORASConfig
10
+ from .ast_security import ASTSecurityEngine, ASTScanResult
11
+ from .signer import CryptographicSigner, EvidenceReceipt
12
+ from .runtime import XORASAgentEnvironment
13
+ from .orchestrator import SwarmOrchestrator
14
+
15
+ __all__ = [
16
+ "XORASConfig",
17
+ "ASTSecurityEngine",
18
+ "ASTScanResult",
19
+ "CryptographicSigner",
20
+ "EvidenceReceipt",
21
+ "XORASAgentEnvironment",
22
+ "SwarmOrchestrator",
23
+ ]
@@ -0,0 +1,141 @@
1
+ """
2
+ XORAS Systems LLC — AST Security Engine & Secret Scanner
3
+ Performs strict Abstract Syntax Tree (AST) static analysis and entropy secret detection.
4
+ """
5
+
6
+ import ast
7
+ import re
8
+ from dataclasses import dataclass, field
9
+ from typing import List, Dict, Any, Optional
10
+
11
+ @dataclass
12
+ class ASTScanResult:
13
+ is_safe: bool
14
+ violations: List[str] = field(default_factory=list)
15
+ secrets_detected: List[str] = field(default_factory=list)
16
+ safety_score: float = 1.0
17
+ nodes_analyzed: int = 0
18
+
19
+ class ASTSecurityVisitor(ast.NodeVisitor):
20
+ def __init__(self):
21
+ self.violations: List[str] = []
22
+ self.nodes_analyzed: int = 0
23
+
24
+ # Unsafe call names
25
+ self.forbidden_calls = {
26
+ "eval": "Dynamic evaluation via eval() is strictly prohibited by XORAS AST Guardrails.",
27
+ "exec": "Dynamic execution via exec() is strictly prohibited by XORAS AST Guardrails.",
28
+ "compile": "Dynamic compilation via compile() is prohibited in agent runtime.",
29
+ "__import__": "Dynamic import via __import__ is prohibited.",
30
+ }
31
+
32
+ # Unsafe module imports
33
+ self.dangerous_modules = {
34
+ "ctypes": "Raw memory manipulation via ctypes is restricted.",
35
+ "pty": "Pseudo-terminal creation via pty is prohibited.",
36
+ "code": "Interactive interpreter via code module is restricted."
37
+ }
38
+
39
+ def visit(self, node):
40
+ self.nodes_analyzed += 1
41
+ super().visit(node)
42
+
43
+ def visit_Call(self, node):
44
+ # Inspect function call names
45
+ func_name = None
46
+ if isinstance(node.func, ast.Name):
47
+ func_name = node.func.id
48
+ elif isinstance(node.func, ast.Attribute):
49
+ func_name = node.func.attr
50
+
51
+ if func_name in self.forbidden_calls:
52
+ self.violations.append(f"Line {getattr(node, 'lineno', '?')}: {self.forbidden_calls[func_name]}")
53
+
54
+ # Check os.system / subprocess.Popen with unsafe args
55
+ if isinstance(node.func, ast.Attribute) and isinstance(node.func.value, ast.Name):
56
+ module_name = node.func.value.id
57
+ if module_name == "os" and func_name in ("system", "popen", "execv", "execl"):
58
+ # Inspect string argument if available
59
+ if node.args and isinstance(node.args[0], ast.Constant):
60
+ arg_val = str(node.args[0].value)
61
+ if "rm -rf" in arg_val or "sudo " in arg_val or "> /dev/" in arg_val:
62
+ self.violations.append(f"Line {getattr(node, 'lineno', '?')}: High-risk shell command in os.{func_name}: '{arg_val}'")
63
+ elif module_name == "subprocess" and func_name in ("Popen", "call", "run"):
64
+ # Check shell=True kwargs
65
+ for keyword in node.keywords:
66
+ if keyword.arg == "shell" and isinstance(keyword.value, ast.Constant) and keyword.value.value is True:
67
+ self.violations.append(f"Line {getattr(node, 'lineno', '?')}: Subprocess invocation with shell=True is restricted under XORAS AST policy.")
68
+
69
+ self.generic_visit(node)
70
+
71
+ def visit_Import(self, node):
72
+ for alias in node.names:
73
+ if alias.name in self.dangerous_modules:
74
+ self.violations.append(f"Line {getattr(node, 'lineno', '?')}: {self.dangerous_modules[alias.name]}")
75
+ self.generic_visit(node)
76
+
77
+ def visit_ImportFrom(self, node):
78
+ if node.module in self.dangerous_modules:
79
+ self.violations.append(f"Line {getattr(node, 'lineno', '?')}: {self.dangerous_modules[node.module]}")
80
+ self.generic_visit(node)
81
+
82
+
83
+ class ASTSecurityEngine:
84
+ SECRET_PATTERNS = [
85
+ (r'(?i)(?:aws_access_key_id|aws_secret_access_key|api_key|secret_key|private_key)\s*[:=]\s*["\']([^"\']{8,})["\']', "Hardcoded API / Secret Key"),
86
+ (r'AKIA[0-9A-Z]{16}', "AWS Access Key ID"),
87
+ (r'sk_live_[0-9a-zA-Z]{24,}', "Stripe Live API Key"),
88
+ (r'sk-(?:proj-)?[a-zA-Z0-9_-]{32,}', "OpenAI API Key"),
89
+ (r'sk-ant-[a-zA-Z0-9_-]{32,}', "Anthropic API Key"),
90
+ (r'AIzaSy[0-9a-zA-Z_-]{33}', "Google Gemini API Key"),
91
+ (r'xox[baprs]-[0-9a-zA-Z]{10,48}', "Slack OAuth / Bot Token"),
92
+ (r'ghp_[0-9a-zA-Z]{36}', "GitHub Personal Access Token"),
93
+ (r'-----BEGIN\s+(?:RSA|EC|OPENSSH|PRIVATE)\s+KEY-----', "Private Cryptographic Key Block"),
94
+ ]
95
+
96
+ def __init__(self, strict_mode: bool = True):
97
+ self.strict_mode = strict_mode
98
+
99
+ def scan_code(self, code_snippet: str) -> ASTScanResult:
100
+ """Parses python AST syntax tree and runs regex secret scanning."""
101
+ violations: List[str] = []
102
+ secrets_detected: List[str] = []
103
+
104
+ # 1. Secret scanning across raw code
105
+ for pattern, desc in self.SECRET_PATTERNS:
106
+ matches = re.findall(pattern, code_snippet)
107
+ if matches:
108
+ secrets_detected.append(f"Secret Leak Warning: Detected {desc} pattern in code payload.")
109
+ violations.append(f"Secret Scanner: High-entropy token matching '{desc}' found.")
110
+
111
+ # 2. Syntax validation & AST parsing
112
+ nodes_analyzed = 0
113
+ try:
114
+ tree = ast.parse(code_snippet)
115
+ visitor = ASTSecurityVisitor()
116
+ visitor.visit(tree)
117
+ violations.extend(visitor.violations)
118
+ nodes_analyzed = visitor.nodes_analyzed
119
+ except SyntaxError as e:
120
+ # If not python syntax (e.g. bash script), fallback to regex heuristic scanner
121
+ nodes_analyzed = len(code_snippet.splitlines())
122
+ forbidden_heuristics = [
123
+ (r'\beval\s*\(', "Dynamic eval() invocation"),
124
+ (r'\bexec\s*\(', "Dynamic exec() invocation"),
125
+ (r'rm\s+-rf\s+/', "Destructive root filesystem command 'rm -rf /'"),
126
+ (r':\(\)\{\s*:\|:&\s*\};:', "Fork bomb pattern"),
127
+ ]
128
+ for pat, msg in forbidden_heuristics:
129
+ if re.search(pat, code_snippet):
130
+ violations.append(f"Heuristic AST Fallback Violation: Detected forbidden pattern '{msg}'")
131
+
132
+ is_safe = len(violations) == 0
133
+ safety_score = max(0.0, 1.0 - (len(violations) * 0.35))
134
+
135
+ return ASTScanResult(
136
+ is_safe=is_safe,
137
+ violations=violations,
138
+ secrets_detected=secrets_detected,
139
+ safety_score=round(safety_score, 4),
140
+ nodes_analyzed=nodes_analyzed
141
+ )
@@ -0,0 +1,211 @@
1
+ """
2
+ XORAS Systems LLC — CLI Tooling Entrypoint (xoras-cli)
3
+ Command line interface for initializing environments, running AST security scans, and serving web dashboards.
4
+ """
5
+
6
+ import argparse
7
+ import json
8
+ import os
9
+ import sys
10
+ import http.server
11
+ import socketserver
12
+ import webbrowser
13
+ from typing import List
14
+
15
+ from .config import XORASConfig
16
+ from .ast_security import ASTSecurityEngine
17
+ from .runtime import XORASAgentEnvironment
18
+ from .orchestrator import SwarmOrchestrator
19
+
20
+ DEFAULT_RULES = """# XORAS SYSTEMS LLC — AGENTIC ENVIRONMENT & GOVERNANCE SPECIFICATION
21
+
22
+ [AGENT_IDENTITY]
23
+ Entity: XORAS Autonomous Agent Node
24
+ Architecture: Multi-Agent Orchestrator (XORAS Swarm)
25
+ Governance Policy: Strict Execution Guardrails & AST Safety Verification
26
+
27
+ [OPERATIONAL_DIRECTIVES]
28
+ 1. AUTONOMOUS_EXECUTION: Resolve intent via iterative state evaluation, tool invocation, and self-correction prior to human escalation.
29
+ 2. AST_SECURITY_GATING: All dynamic code execution, subprocess calls, and external payloads must pass AST static analysis and secret scanning (`env-integrity-sentry`).
30
+ 3. ZERO_DRIFT_BRANDING: Enforce XORAS Systems LLC branding across all client-facing artifacts, logs, and generated assets. Legacy naming is prohibited.
31
+ 4. DETERMINISTIC_LOGGING: Every agent state transition, tool call, and FFI interaction must produce structured JSON-L traces.
32
+ """
33
+
34
+ DEFAULT_ENV_YAML = """version: "2.0.0"
35
+ organization: "XORAS Systems LLC"
36
+ runtime:
37
+ environment_type: "agentic-sandbox"
38
+ concurrency_limit: 8
39
+ default_timeout_seconds: 120
40
+ memory_limit_mb: 4096
41
+
42
+ security:
43
+ ast_verification: true
44
+ allow_network_egress: true
45
+ allowed_domains:
46
+ - "github.com"
47
+ - "pypi.org"
48
+ secret_scanner: "env-integrity-sentry"
49
+ block_deprecated_branding: true
50
+
51
+ agent_swarm:
52
+ orchestrator:
53
+ model: "gemini-2.5-flash"
54
+ temperature: 0.1
55
+ max_tokens: 8192
56
+ agents:
57
+ - name: "Architect"
58
+ role: "System design, specification authoring, and state graph planning"
59
+ capabilities: ["file_read", "file_write", "diagram_gen"]
60
+ - name: "Engineer"
61
+ role: "Code generation, refactoring, and AST verification"
62
+ capabilities: ["file_read", "file_write", "bash_exec", "test_runner"]
63
+ - name: "Auditor"
64
+ role: "Security scanning, secret detection, and runtime compliance"
65
+ capabilities: ["ast_scan", "log_audit", "policy_check"]
66
+
67
+ paths:
68
+ workspace_root: "."
69
+ log_output: "./logs/xoras_agent_traces.jsonl"
70
+ artifact_store: "./artifacts"
71
+ """
72
+
73
+ def init_cmd():
74
+ print("[XORAS CLI] Initializing XORAS Agentic Governance Environment...")
75
+ if not os.path.exists(".xorasrules"):
76
+ with open(".xorasrules", "w", encoding="utf-8") as f:
77
+ f.write(DEFAULT_RULES)
78
+ print(" -> Created .xorasrules")
79
+ else:
80
+ print(" -> .xorasrules already exists.")
81
+
82
+ if not os.path.exists("xoras.env.yaml"):
83
+ with open("xoras.env.yaml", "w", encoding="utf-8") as f:
84
+ f.write(DEFAULT_ENV_YAML)
85
+ print(" -> Created xoras.env.yaml")
86
+ else:
87
+ print(" -> xoras.env.yaml already exists.")
88
+
89
+ os.makedirs("logs", exist_ok=True)
90
+ os.makedirs("artifacts", exist_ok=True)
91
+ print("[XORAS CLI] Initialization complete. Your workspace is secured with XORAS AST Guardrails.")
92
+
93
+ def scan_cmd(target_file: str):
94
+ print(f"[XORAS CLI] Running AST Security Scan on target: '{target_file}'")
95
+ if not os.path.exists(target_file):
96
+ print(f"Error: Target file or directory '{target_file}' not found.")
97
+ sys.exit(1)
98
+
99
+ files_to_scan: List[str] = []
100
+ if os.path.isdir(target_file):
101
+ for root, _, files in os.walk(target_file):
102
+ for file in files:
103
+ if file.endswith(".py"):
104
+ files_to_scan.append(os.path.join(root, file))
105
+ else:
106
+ files_to_scan.append(target_file)
107
+
108
+ engine = ASTSecurityEngine()
109
+ total_violations = 0
110
+ total_secrets = 0
111
+ any_failed = False
112
+
113
+ for file_path in files_to_scan:
114
+ with open(file_path, "r", encoding="utf-8") as f:
115
+ code = f.read()
116
+
117
+ result = engine.scan_code(code)
118
+ print(f"\n--- AST SCAN REPORT: {file_path} ---")
119
+ print(f"Status: {'PASSED [SAFE]' if result.is_safe else 'REJECTED [UNSAFE]'}")
120
+ print(f"Safety Score: {result.safety_score * 100:.1f}% | AST Nodes Analyzed: {result.nodes_analyzed}")
121
+
122
+ if result.violations:
123
+ total_violations += len(result.violations)
124
+ print("Violations Detected:")
125
+ for v in result.violations:
126
+ print(f" - {v}")
127
+
128
+ if result.secrets_detected:
129
+ total_secrets += len(result.secrets_detected)
130
+ print("Secret Leaks Detected:")
131
+ for s in result.secrets_detected:
132
+ print(f" - {s}")
133
+
134
+ if not result.is_safe:
135
+ any_failed = True
136
+
137
+ print(f"\n[XORAS CLI Summary] Scanned {len(files_to_scan)} file(s). Total Violations: {total_violations} | Total Secret Warnings: {total_secrets}")
138
+ if any_failed:
139
+ sys.exit(2)
140
+
141
+ def run_cmd(target_file: str):
142
+ print(f"[XORAS CLI] Executing script '{target_file}' under XORAS Sandboxed Runtime...")
143
+ if not os.path.exists(target_file):
144
+ print(f"Error: Target file '{target_file}' not found.")
145
+ sys.exit(1)
146
+
147
+ with open(target_file, "r", encoding="utf-8") as f:
148
+ code = f.read()
149
+
150
+ env = XORASAgentEnvironment()
151
+ res = env.execute_tool("Engineer", "bash_exec", {"command": f"{sys.executable} {target_file}"})
152
+
153
+ print("\n--- EXECUTION OUTPUT ---")
154
+ print(res.get("stdout", ""))
155
+ if res.get("stderr"):
156
+ print("STDERR:", res.get("stderr"))
157
+ print(f"Exit Code: {res.get('exit_code', -1)}")
158
+ print(f"Trace Receipt Signature: {res.get('receipt_signature', 'NONE')}")
159
+
160
+ def serve_cmd(port: int = 8080):
161
+ web_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "web")
162
+ if not os.path.exists(web_dir):
163
+ web_dir = os.path.join(os.getcwd(), "web")
164
+
165
+ if not os.path.exists(web_dir):
166
+ print(f"Error: Web dashboard directory '{web_dir}' not found.")
167
+ sys.exit(1)
168
+
169
+ os.chdir(web_dir)
170
+ Handler = http.server.SimpleHTTPRequestHandler
171
+ print(f"[XORAS CLI] Serving Web Product Page & Live Dashboard at http://localhost:{port}")
172
+ try:
173
+ with socketserver.TCPServer(("", port), Handler) as httpd:
174
+ print(f"[XORAS CLI] Server running. Press Ctrl+C to stop.")
175
+ httpd.serve_forever()
176
+ except KeyboardInterrupt:
177
+ print("\n[XORAS CLI] Server stopped.")
178
+
179
+ def main():
180
+ parser = argparse.ArgumentParser(description="XORAS Systems LLC — Agentic Framework CLI")
181
+ subparsers = parser.add_subparsers(dest="command")
182
+
183
+ # init command
184
+ init_p = subparsers.add_parser("init", help="Initialize .xorasrules and xoras.env.yaml in current workspace")
185
+
186
+ # scan command
187
+ scan_p = subparsers.add_parser("scan", help="Run AST security and secret scan on a script")
188
+ scan_p.add_argument("file", help="Python or shell script to scan")
189
+
190
+ # run command
191
+ run_p = subparsers.add_parser("run", help="Run a script through XORAS agentic runtime")
192
+ run_p.add_argument("file", help="Python script to run")
193
+
194
+ # serve command
195
+ serve_p = subparsers.add_parser("serve", help="Serve interactive product landing page and dashboard")
196
+ serve_p.add_argument("--port", type=int, default=8080, help="Port to serve on (default: 8080)")
197
+
198
+ args = parser.parse_args()
199
+ if args.command == "init":
200
+ init_cmd()
201
+ elif args.command == "scan":
202
+ scan_cmd(args.file)
203
+ elif args.command == "run":
204
+ run_cmd(args.file)
205
+ elif args.command == "serve":
206
+ serve_cmd(args.port)
207
+ else:
208
+ parser.print_help()
209
+
210
+ if __name__ == "__main__":
211
+ main()
@@ -0,0 +1,102 @@
1
+ """
2
+ XORAS Systems LLC — Configuration Schema Parser & Validator
3
+ Loads and validates xoras.env.yaml runtime configurations.
4
+ """
5
+
6
+ import os
7
+ import yaml
8
+ from dataclasses import dataclass, field
9
+ from typing import Dict, Any, List, Optional
10
+
11
+ @dataclass
12
+ class RuntimeConfig:
13
+ environment_type: str = "agentic-sandbox"
14
+ concurrency_limit: int = 8
15
+ default_timeout_seconds: int = 120
16
+ memory_limit_mb: int = 4096
17
+
18
+ @dataclass
19
+ class SecurityConfig:
20
+ ast_verification: bool = True
21
+ allow_network_egress: bool = True
22
+ allowed_domains: List[str] = field(default_factory=lambda: ["github.com", "pypi.org"])
23
+ secret_scanner: str = "env-integrity-sentry"
24
+ block_deprecated_branding: bool = True
25
+
26
+ @dataclass
27
+ class AgentSpec:
28
+ name: str
29
+ role: str
30
+ capabilities: List[str]
31
+
32
+ @dataclass
33
+ class AgentSwarmConfig:
34
+ orchestrator_model: str = "gemini-2.5-flash"
35
+ temperature: float = 0.1
36
+ max_tokens: int = 8192
37
+ agents: List[AgentSpec] = field(default_factory=list)
38
+
39
+ @dataclass
40
+ class XORASConfig:
41
+ version: str
42
+ organization: str
43
+ runtime: RuntimeConfig
44
+ security: SecurityConfig
45
+ swarm: AgentSwarmConfig
46
+ workspace_root: str
47
+ log_output: str
48
+ artifact_store: str
49
+
50
+ @classmethod
51
+ def load_from_yaml(cls, filepath: str = "xoras.env.yaml") -> "XORASConfig":
52
+ if not os.path.exists(filepath):
53
+ raise FileNotFoundError(f"XORAS environment configuration not found at '{filepath}'")
54
+
55
+ with open(filepath, "r", encoding="utf-8") as f:
56
+ raw = yaml.safe_load(f)
57
+
58
+ rt_data = raw.get("runtime", {})
59
+ runtime_cfg = RuntimeConfig(
60
+ environment_type=rt_data.get("environment_type", "agentic-sandbox"),
61
+ concurrency_limit=rt_data.get("concurrency_limit", 8),
62
+ default_timeout_seconds=rt_data.get("default_timeout_seconds", 120),
63
+ memory_limit_mb=rt_data.get("memory_limit_mb", 4096)
64
+ )
65
+
66
+ sec_data = raw.get("security", {})
67
+ security_cfg = SecurityConfig(
68
+ ast_verification=sec_data.get("ast_verification", True),
69
+ allow_network_egress=sec_data.get("allow_network_egress", True),
70
+ allowed_domains=sec_data.get("allowed_domains", ["github.com", "pypi.org"]),
71
+ secret_scanner=sec_data.get("secret_scanner", "env-integrity-sentry"),
72
+ block_deprecated_branding=sec_data.get("block_deprecated_branding", True)
73
+ )
74
+
75
+ swarm_raw = raw.get("agent_swarm", {})
76
+ orch_raw = swarm_raw.get("orchestrator", {})
77
+ agent_specs = []
78
+ for a in swarm_raw.get("agents", []):
79
+ agent_specs.append(AgentSpec(
80
+ name=a.get("name", "Agent"),
81
+ role=a.get("role", "Worker"),
82
+ capabilities=a.get("capabilities", [])
83
+ ))
84
+
85
+ swarm_cfg = AgentSwarmConfig(
86
+ orchestrator_model=orch_raw.get("model", "gemini-2.5-flash"),
87
+ temperature=orch_raw.get("temperature", 0.1),
88
+ max_tokens=orch_raw.get("max_tokens", 8192),
89
+ agents=agent_specs
90
+ )
91
+
92
+ paths = raw.get("paths", {})
93
+ return cls(
94
+ version=raw.get("version", "2.0.0"),
95
+ organization=raw.get("organization", "XORAS Systems LLC"),
96
+ runtime=runtime_cfg,
97
+ security=security_cfg,
98
+ swarm=swarm_cfg,
99
+ workspace_root=paths.get("workspace_root", "."),
100
+ log_output=paths.get("log_output", "./logs/xoras_agent_traces.jsonl"),
101
+ artifact_store=paths.get("artifact_store", "./artifacts")
102
+ )