cortex-runtime 0.2.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 (76) hide show
  1. cortex/__init__.py +51 -0
  2. cortex/__main__.py +13 -0
  3. cortex/client.py +263 -0
  4. cortex/compat.py +20 -0
  5. cortex/exceptions.py +57 -0
  6. cortex/plugin.py +50 -0
  7. cortex/py.typed +1 -0
  8. cortex/schema/__init__.py +29 -0
  9. cortex/schema/events.py +127 -0
  10. cortex/tools/__init__.py +3 -0
  11. cortex/tools/cli/__init__.py +3 -0
  12. cortex/tools/cli/main.py +139 -0
  13. cortex/tools/cli/runner.py +94 -0
  14. cortex/tools/cli/scaffolder.py +109 -0
  15. cortex/tools/gen_test_bin.py +35 -0
  16. cortex/tools/kernel/__init__.py +3 -0
  17. cortex/tools/kernel/actors/__init__.py +3 -0
  18. cortex/tools/kernel/actors/executor.py +44 -0
  19. cortex/tools/kernel/actors/planner.py +38 -0
  20. cortex/tools/kernel/context.py +22 -0
  21. cortex/tools/kernel/drivers/__init__.py +3 -0
  22. cortex/tools/kernel/drivers/mock_robot.py +84 -0
  23. cortex/tools/kernel/drivers/rtl_verilator.py +49 -0
  24. cortex/tools/kernel/graph/__init__.py +3 -0
  25. cortex/tools/kernel/graph/analyzer.py +52 -0
  26. cortex/tools/kernel/graph/execution_graph.py +44 -0
  27. cortex/tools/kernel/mailbox.py +35 -0
  28. cortex/tools/kernel/plugin/__init__.py +3 -0
  29. cortex/tools/kernel/plugin/loader.py +87 -0
  30. cortex/tools/kernel/plugin/manifest.py +53 -0
  31. cortex/tools/kernel/registry.py +36 -0
  32. cortex/tools/kernel/schema/__init__.py +3 -0
  33. cortex/tools/kernel/schema/contract.py +16 -0
  34. cortex/tools/kernel/schema/event.py +54 -0
  35. cortex/tools/kernel/schema/message.py +105 -0
  36. cortex/tools/kernel/schema/workflow.py +38 -0
  37. cortex/tools/kernel/services/__init__.py +3 -0
  38. cortex/tools/kernel/services/event_store.py +25 -0
  39. cortex/tools/kernel/services/execution_intelligence.py +49 -0
  40. cortex/tools/kernel/services/graph_builder.py +81 -0
  41. cortex/tools/kernel/services/replay.py +50 -0
  42. cortex/tools/kernel/services/verification.py +85 -0
  43. cortex/tools/kernel/transport.py +50 -0
  44. cortex/tools/run_phase2_verification.sh +20 -0
  45. cortex/tools/verification/__init__.py +5 -0
  46. cortex/tools/verification/adapters/__init__.py +3 -0
  47. cortex/tools/verification/adapters/base.py +14 -0
  48. cortex/tools/verification/adapters/coq.py +73 -0
  49. cortex/tools/verification/adapters/rtl.py +77 -0
  50. cortex/tools/verification/adapters/rust.py +72 -0
  51. cortex/tools/verification/archive.py +58 -0
  52. cortex/tools/verification/bus.py +28 -0
  53. cortex/tools/verification/contract.py +70 -0
  54. cortex/tools/verification/engine.py +121 -0
  55. cortex/tools/verification/generator/__init__.py +3 -0
  56. cortex/tools/verification/generator/composer.py +36 -0
  57. cortex/tools/verification/generator/program.py +46 -0
  58. cortex/tools/verification/generator/state.py +54 -0
  59. cortex/tools/verification/invariants/__init__.py +3 -0
  60. cortex/tools/verification/invariants/capability.py +62 -0
  61. cortex/tools/verification/metrics/__init__.py +3 -0
  62. cortex/tools/verification/metrics/base.py +18 -0
  63. cortex/tools/verification/metrics/opcode.py +25 -0
  64. cortex/tools/verification/metrics/state_space.py +26 -0
  65. cortex/tools/verification/metrics/trap.py +26 -0
  66. cortex/tools/verification/mutation.py +48 -0
  67. cortex/tools/verification/oracle.py +164 -0
  68. cortex/tools/verification/schema/__init__.py +44 -0
  69. cortex/tools/verification/schema/event.py +44 -0
  70. cortex/tools/verification/shrink.py +26 -0
  71. cortex/tools/verify.py +64 -0
  72. cortex_runtime-0.2.0.dist-info/METADATA +220 -0
  73. cortex_runtime-0.2.0.dist-info/RECORD +76 -0
  74. cortex_runtime-0.2.0.dist-info/WHEEL +4 -0
  75. cortex_runtime-0.2.0.dist-info/entry_points.txt +2 -0
  76. cortex_runtime-0.2.0.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,139 @@
1
+ """
2
+ Cortex Developer CLI Command Entrypoint
3
+
4
+ Usage:
5
+ cortex init <project_name> [--type {app|plugin}]
6
+ cortex workflow run <workflow_file> [--output <file>]
7
+ cortex workflow inspect <workflow_id_or_file>
8
+ cortex workflow replay <workflow_id_or_file>
9
+ """
10
+
11
+ import argparse
12
+ import os
13
+ import sys
14
+ from collections.abc import Sequence
15
+ from typing import cast
16
+
17
+ from cortex.exceptions import CortexError
18
+ from cortex.tools.cli.runner import inspect_workflow, replay_workflow, run_workflow_file
19
+ from cortex.tools.cli.scaffolder import scaffold_project
20
+
21
+
22
+ def cli_entrypoint() -> None:
23
+ """Console script entrypoint for PyPI cortex-runtime executable."""
24
+ sys.exit(main())
25
+
26
+
27
+ def main(argv: Sequence[str] | None = None) -> int:
28
+ """Main CLI entrypoint for Cortex framework."""
29
+ if argv is None:
30
+ argv = sys.argv[1:]
31
+
32
+ parser = argparse.ArgumentParser(
33
+ prog="cortex",
34
+ description="Cortex Platform Developer CLI & Workflow Engine",
35
+ )
36
+ subparsers = parser.add_subparsers(dest="command", help="Command to execute")
37
+
38
+ # cortex init
39
+ init_parser = subparsers.add_parser("init", help="Scaffold a new Cortex plugin or application")
40
+ _ = init_parser.add_argument("project_name", help="Name of the project directory to create")
41
+ _ = init_parser.add_argument(
42
+ "--type",
43
+ choices=["app", "plugin"],
44
+ default="app",
45
+ help="Type of project to scaffold (default: app)",
46
+ )
47
+
48
+ # cortex workflow
49
+ wf_parser = subparsers.add_parser("workflow", help="Workflow execution and inspection management")
50
+ wf_sub = wf_parser.add_subparsers(dest="wf_command", help="Workflow subcommand")
51
+
52
+ # cortex workflow run
53
+ wf_run = wf_sub.add_parser("run", help="Trigger workflow execution from spec file")
54
+ _ = wf_run.add_argument("workflow_file", help="Path to workflow definition JSON file")
55
+ _ = wf_run.add_argument("--output", "-o", help="Optional path to save event journal JSON trace")
56
+
57
+ # cortex workflow inspect
58
+ wf_inspect = wf_sub.add_parser("inspect", help="Inspect execution graph and lineage for workflow ID or file")
59
+ _ = wf_inspect.add_argument("workflow_id", help="Workflow ID or path to event trace JSON file")
60
+
61
+ # cortex workflow replay
62
+ wf_replay = wf_sub.add_parser("replay", help="Deterministically replay workflow execution trace")
63
+ _ = wf_replay.add_argument("workflow_id", help="Workflow ID or path to event trace JSON file")
64
+
65
+ args = parser.parse_args(argv)
66
+ cmd = str(getattr(args, "command", ""))
67
+ wf_cmd = str(getattr(args, "wf_command", ""))
68
+
69
+ try:
70
+ if cmd == "init":
71
+ p_name = str(getattr(args, "project_name", "my_cortex_app"))
72
+ p_type = str(getattr(args, "type", "app"))
73
+ path = scaffold_project(p_name, project_type=p_type)
74
+ print(f"[+] Successfully scaffolded Cortex {p_type} project at: {path}")
75
+ return 0
76
+
77
+ elif cmd == "workflow":
78
+ if wf_cmd == "run":
79
+ wf_file = str(getattr(args, "workflow_file", ""))
80
+ out_file = cast(str | None, getattr(args, "output", None))
81
+ res = run_workflow_file(wf_file, output_file=out_file)
82
+ print("[+] Workflow execution finished.")
83
+ print(f" ID: {res['workflow_id']}")
84
+ print(f" State: {res['state']}")
85
+ print(f" Events Log: {res['event_count']}")
86
+ print(f" Trace Saved: {res['output_file']}")
87
+ return 0
88
+
89
+ elif wf_cmd == "inspect":
90
+ wf_id = str(getattr(args, "workflow_id", ""))
91
+ res = inspect_workflow(wf_id)
92
+ causality_tree = cast(list[str], res.get("causality_tree", []))
93
+ failed_nodes = cast(list[dict[str, object]], res.get("failed_nodes", []))
94
+
95
+ print("=== Cortex Execution Graph Inspection ===")
96
+ print(f"Workflow ID: {res['workflow_id']}")
97
+ print(f"Name: {res['name']}")
98
+ print(f"Goal: {res['goal']}")
99
+ print(f"State: {res['state']}")
100
+ print(f"Total Nodes: {res['node_count']}")
101
+ print("\n--- Causality Tree ---")
102
+ for line in causality_tree:
103
+ print(f" {line}")
104
+ if failed_nodes:
105
+ print(f"\n[!] Verification Failures ({len(failed_nodes)}):")
106
+ for node in failed_nodes:
107
+ print(f" - Node {node['id']}: {node['payload']}")
108
+ else:
109
+ print("\n[+] Verification Status: ALL PASSED")
110
+ return 0
111
+
112
+ elif wf_cmd == "replay":
113
+ wf_id = str(getattr(args, "workflow_id", ""))
114
+ res = replay_workflow(wf_id)
115
+ print("=== Cortex Deterministic Replay Engine ===")
116
+ print(f"Workflow ID: {res['workflow_id']}")
117
+ print(f"Events Replayed: {res['events_replayed']}")
118
+ print(f"Status: {'SUCCESS' if res['deterministic'] else 'FAILED'}")
119
+ print(f"Result: {res['verification_result']}")
120
+ return 0 if res["deterministic"] else 1
121
+
122
+ else:
123
+ wf_parser.print_help(sys.stderr)
124
+ return 1
125
+
126
+ else:
127
+ parser.print_help(sys.stderr)
128
+ return 1
129
+
130
+ except CortexError as err:
131
+ print(f"[!] Cortex Error: {err.message}", file=sys.stderr)
132
+ return err.exit_code
133
+ except Exception as err:
134
+ print(f"[!] Unexpected Error: {err}", file=sys.stderr)
135
+ return getattr(os, "EX_SOFTWARE", 1)
136
+
137
+
138
+ if __name__ == "__main__":
139
+ sys.exit(main())
@@ -0,0 +1,94 @@
1
+ """
2
+ Thin CLI Adapter Engine for Cortex Platform
3
+
4
+ Delegates workflow lifecycle execution, trace inspection, and deterministic
5
+ replay directly to the public CortexClient API. Contains zero state machine logic.
6
+ """
7
+
8
+ import json
9
+ import os
10
+ from typing import cast
11
+
12
+ from cortex.client import CortexClient
13
+ from cortex.exceptions import WorkflowExecutionError
14
+ from cortex.schema import IntentEvent, WorkflowPolicy
15
+
16
+
17
+ def run_workflow_file(workflow_file: str, output_file: str | None = None) -> dict[str, str | int]:
18
+ """Runs a workflow file by instantiating CortexClient thin wrapper."""
19
+ if not os.path.exists(workflow_file):
20
+ raise WorkflowExecutionError(f"Workflow file not found: {workflow_file}")
21
+
22
+ with open(workflow_file, "r", encoding="utf-8") as f:
23
+ if workflow_file.endswith(".yaml") or workflow_file.endswith(".yml"):
24
+ import yaml
25
+ data = cast(dict[str, object], yaml.safe_load(f)) or {}
26
+ else:
27
+ data = cast(dict[str, object], json.load(f))
28
+
29
+ client = CortexClient()
30
+
31
+ wf_name = str(data.get("name", "cli_workflow"))
32
+ wf_goal = str(data.get("goal", "Execute CLI workflow"))
33
+ policy_data = cast(dict[str, object], data.get("policy", {}))
34
+
35
+ policy = WorkflowPolicy(
36
+ timeout_seconds=float(str(policy_data.get("timeout_seconds", 300.0))),
37
+ max_retries=int(str(policy_data.get("max_retries", 3))),
38
+ abort_on_verification_failure=bool(policy_data.get("abort_on_verification_failure", True)),
39
+ )
40
+
41
+ workflow = client.create_workflow(name=wf_name, goal=wf_goal, policy=policy)
42
+
43
+ intent_data = cast(dict[str, object], data.get("initial_intent", {}))
44
+ initial_intent = IntentEvent(
45
+ workflow_id=workflow.workflow_id,
46
+ goal=str(intent_data.get("goal", wf_goal)),
47
+ parameters=cast(dict[str, object], intent_data.get("parameters", {})),
48
+ )
49
+
50
+ executed_wf = client.run_workflow(workflow, initial_intent=initial_intent)
51
+
52
+ if output_file is None:
53
+ cortex_dir = os.path.join(os.getcwd(), ".cortex", "events")
54
+ output_file = os.path.join(cortex_dir, f"{executed_wf.workflow_id}.json")
55
+
56
+ saved_path = client.save_trace(executed_wf.workflow_id, output_file, name=wf_name, goal=wf_goal)
57
+
58
+ return {
59
+ "workflow_id": executed_wf.workflow_id,
60
+ "state": executed_wf.state.value,
61
+ "event_count": len(client.event_store.get_log()),
62
+ "output_file": saved_path,
63
+ }
64
+
65
+
66
+ def inspect_workflow(trace_path_or_id: str) -> dict[str, str | int | list[str] | list[dict[str, object]]]:
67
+ """Delegates trace inspection to CortexClient."""
68
+ client = CortexClient()
69
+ res = client.inspect_workflow(trace_path_or_id)
70
+ causality_tree = cast(list[str], res.get("causality_tree", []))
71
+ failed_nodes = cast(list[dict[str, object]], res.get("failed_nodes", []))
72
+
73
+ return {
74
+ "workflow_id": trace_path_or_id,
75
+ "name": cast(str, res.get("name", "Inspected Workflow")),
76
+ "goal": cast(str, res.get("goal", "Trace Inspection")),
77
+ "state": "FAILED" if failed_nodes else "COMPLETED",
78
+ "node_count": cast(int, res.get("node_count", 0)),
79
+ "total_events": cast(int, res.get("total_events", 0)),
80
+ "causality_tree": causality_tree,
81
+ "failed_nodes": failed_nodes,
82
+ }
83
+
84
+
85
+ def replay_workflow(trace_path_or_id: str) -> dict[str, str | int | bool]:
86
+ """Delegates trace replay to CortexClient."""
87
+ client = CortexClient()
88
+ res = client.replay_workflow(trace_path_or_id)
89
+ return {
90
+ "workflow_id": trace_path_or_id,
91
+ "events_replayed": cast(int, res.get("replayed_count", 0)),
92
+ "deterministic": cast(bool, res.get("deterministic", False)),
93
+ "verification_result": cast(str, res.get("reason", "")),
94
+ }
@@ -0,0 +1,109 @@
1
+ """
2
+ Cortex Project Scaffolding Engine
3
+
4
+ Scaffolds a new Cortex application or plugin project template with declarative
5
+ manifests, workflow definitions, and sample handlers adhering to public Cortex standards.
6
+ """
7
+
8
+ import json
9
+ import os
10
+
11
+
12
+ def scaffold_project(project_name: str, project_type: str = "app", target_dir: str | None = None) -> str:
13
+ """Scaffolds a standard Cortex application or plugin project directory structure."""
14
+ if target_dir is None:
15
+ target_dir = os.path.join(os.getcwd(), project_name)
16
+
17
+ os.makedirs(target_dir, exist_ok=True)
18
+
19
+ cortex_config: dict[str, str] = {
20
+ "name": project_name,
21
+ "type": project_type,
22
+ "version": "0.1.0",
23
+ "cortex_version": "0.2.0",
24
+ "entrypoint": "main.py" if project_type == "app" else "plugin.py",
25
+ }
26
+ with open(os.path.join(target_dir, "cortex.json"), "w", encoding="utf-8") as f:
27
+ json.dump(cortex_config, f, indent=2)
28
+
29
+ plugin_manifest: dict[str, str | list[str]] = {
30
+ "name": f"{project_name}-plugin",
31
+ "version": "0.1.0",
32
+ "description": f"Custom {project_type} plugin for {project_name}",
33
+ "consumes_events": ["IntentEvent"],
34
+ "produces_events": ["PlanGeneratedEvent", "CommandIssuedEvent"],
35
+ "required_capabilities": ["workflow.plan.create", "workflow.command.issue"],
36
+ }
37
+ with open(os.path.join(target_dir, "manifest.json"), "w", encoding="utf-8") as f:
38
+ json.dump(plugin_manifest, f, indent=2)
39
+
40
+ workflow_def: dict[str, object] = {
41
+ "name": f"{project_name}_workflow",
42
+ "goal": f"Execute default workflow for {project_name}",
43
+ "policy": {
44
+ "timeout_seconds": 300.0,
45
+ "max_retries": 3,
46
+ "abort_on_verification_failure": True,
47
+ },
48
+ "initial_intent": {
49
+ "goal": f"Initialize {project_name} execution",
50
+ "parameters": {"environment": "development"},
51
+ },
52
+ }
53
+ with open(os.path.join(target_dir, "workflow.json"), "w", encoding="utf-8") as f:
54
+ json.dump(workflow_def, f, indent=2)
55
+
56
+ code_content = _generate_sample_code(project_name, project_type)
57
+ code_filename = "main.py" if project_type == "app" else "plugin.py"
58
+ with open(os.path.join(target_dir, code_filename), "w", encoding="utf-8") as f:
59
+ _ = f.write(code_content)
60
+
61
+ return target_dir
62
+
63
+
64
+ def _generate_sample_code(project_name: str, project_type: str) -> str:
65
+ if project_type == "plugin":
66
+ return f'''"""
67
+ Plugin Handler for {project_name}
68
+ """
69
+
70
+ from cortex import BasePlugin, PluginManifest, IntentEvent, PlanGeneratedEvent
71
+
72
+ MANIFEST = PluginManifest(
73
+ name="{project_name}-plugin",
74
+ version="0.1.0",
75
+ description="Custom plugin for {project_name}",
76
+ consumes_events=["IntentEvent"],
77
+ produces_events=["PlanGeneratedEvent"],
78
+ required_capabilities=["workflow.plan.create"],
79
+ )
80
+
81
+ class CustomPlugin(BasePlugin):
82
+ def __init__(self):
83
+ super().__init__(MANIFEST)
84
+
85
+ def on_event(self, event):
86
+ if isinstance(event, IntentEvent) and self.context:
87
+ plan = PlanGeneratedEvent(
88
+ intent_id=event.intent_id,
89
+ workflow_id=event.workflow_id,
90
+ steps=[{{"step": 1, "action": "initialize"}}]
91
+ )
92
+ self.context.publish(plan)
93
+ '''
94
+ return f'''"""
95
+ Application Handler for {project_name}
96
+ """
97
+
98
+ from cortex import CortexClient, IntentEvent
99
+
100
+ def run_app():
101
+ client = CortexClient()
102
+ workflow = client.create_workflow(name="{project_name}_workflow", goal="Run autonomous task")
103
+ intent = IntentEvent(workflow_id=workflow.workflow_id, goal=workflow.goal)
104
+ executed = client.run_workflow(workflow, initial_intent=intent)
105
+ print(f"Workflow {{executed.workflow_id}} status: {{executed.state.value}}")
106
+
107
+ if __name__ == "__main__":
108
+ run_app()
109
+ '''
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env python3
2
+ import os
3
+ import struct
4
+
5
+
6
+ def encode_inst(opcode: int, stcr_id: int, arg_reg: int, imm: int) -> int:
7
+ return ((opcode & 0x3F) << 26) | ((stcr_id & 0x1F) << 21) | ((arg_reg & 0x1F) << 16) | (imm & 0xFFFF)
8
+
9
+ def generate_canonical_test_bin(output_path: str):
10
+ MAGIC = b"CORTEX"
11
+ VERSION = 1
12
+
13
+ # Sequence of instructions exercising all SDS v1.0 refinement properties:
14
+ instructions = [
15
+ encode_inst(0x01, 0, 1, 0), # PC 0: invoke_cap STCR0, R1 -> Expected: COMMIT (Valid)
16
+ encode_inst(0x03, 0, 0, 0x4000), # PC 1: restrict_cap STCR0, READ (Bit 62) -> Expected: COMMIT
17
+ encode_inst(0x01, 0, 2, 0), # PC 2: invoke_cap STCR0, R2 -> Expected: COMMIT
18
+ encode_inst(0x05, 0, 0, 0), # PC 3: hec.inc -> Expected: COMMIT (Epoch = 1)
19
+ encode_inst(0x01, 0, 3, 0), # PC 4: invoke_cap STCR0, R3 -> Expected: EFF_TRAP (Epoch Expired if Max_Epoch == 0)
20
+ encode_inst(0x00, 0, 0, 0), # PC 5: Opcode 0x00 -> Expected: EFF_TRAP (Illegal/Reserved Opcode)
21
+ ]
22
+
23
+ header = MAGIC + struct.pack(">H", VERSION) + struct.pack(">I", len(instructions))
24
+ payload = b"".join(struct.pack(">I", inst) for inst in instructions)
25
+
26
+ os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True)
27
+ with open(output_path, "wb") as f:
28
+ f.write(header + payload)
29
+
30
+ print(f"[+] Canonical test binary successfully generated at {output_path} ({len(header + payload)} bytes)")
31
+
32
+ if __name__ == "__main__":
33
+ import sys
34
+ out_path = sys.argv[1] if len(sys.argv) > 1 else "tests/canonical_test_program.bin"
35
+ generate_canonical_test_bin(out_path)
@@ -0,0 +1,3 @@
1
+ """
2
+ Cortex Kernel Runtime Core
3
+ """
@@ -0,0 +1,3 @@
1
+ """
2
+ Kernel Actors Infrastructure
3
+ """
@@ -0,0 +1,44 @@
1
+ """
2
+ TaskExecutor Actor
3
+
4
+ Consumes: PlanGeneratedEvent
5
+ Produces: CommandIssuedEvent
6
+
7
+ Iterates over the steps within a PlanGeneratedEvent and issues
8
+ individual CommandIssuedEvent instances to the driver layer.
9
+ The executor has zero knowledge of which driver will consume
10
+ the command — it only knows the message contract.
11
+ """
12
+
13
+ from collections.abc import Callable
14
+ from typing import cast
15
+
16
+ from cortex.tools.kernel.context import RuntimeContext
17
+ from cortex.tools.kernel.schema.message import CommandIssuedEvent, PlanGeneratedEvent
18
+ from cortex.tools.kernel.transport import AnyEvent
19
+
20
+
21
+ class TaskExecutorActor:
22
+ context: RuntimeContext
23
+ publish_cb: Callable[[AnyEvent], object]
24
+
25
+ def __init__(self, context: RuntimeContext, publish_cb: Callable[[AnyEvent], object]):
26
+ self.context = context
27
+ self.publish_cb = publish_cb
28
+
29
+ def handle_plan(self, plan: PlanGeneratedEvent) -> list[CommandIssuedEvent]:
30
+ commands: list[CommandIssuedEvent] = []
31
+ for step in plan.steps:
32
+ action_val = str(step.get("action", "unknown"))
33
+ params_val = step.get("parameters", {})
34
+ params_dict = cast(dict[str, object], params_val) if isinstance(params_val, dict) else {}
35
+
36
+ cmd = CommandIssuedEvent(
37
+ plan_id=plan.plan_id,
38
+ correlation_id=plan.correlation_id,
39
+ action=action_val,
40
+ parameters=params_dict,
41
+ )
42
+ commands.append(cmd)
43
+ self.publish_cb(cmd)
44
+ return commands
@@ -0,0 +1,38 @@
1
+ """
2
+ IntentPlanner Actor
3
+
4
+ Consumes: IntentEvent
5
+ Produces: PlanGeneratedEvent
6
+
7
+ Decomposes a high-level goal intent into an ordered sequence of
8
+ actionable steps. The planner has zero knowledge of downstream
9
+ executors or drivers — it only knows the message contract.
10
+ """
11
+
12
+ from collections.abc import Callable
13
+ from typing import Any
14
+
15
+ from cortex.tools.kernel.context import RuntimeContext
16
+ from cortex.tools.kernel.schema.message import IntentEvent, PlanGeneratedEvent
17
+
18
+
19
+ class IntentPlannerActor:
20
+ context: RuntimeContext
21
+ publish_cb: Callable[[Any], object]
22
+
23
+ def __init__(self, context: RuntimeContext, publish_cb: Callable[[Any], object]):
24
+ self.context = context
25
+ self.publish_cb = publish_cb
26
+
27
+ def handle_intent(self, intent: IntentEvent) -> PlanGeneratedEvent:
28
+ steps = [
29
+ {"action": "move_actuator", "parameters": {"actuator": "arm_joint_1", "delta": 10.0}},
30
+ {"action": "move_actuator", "parameters": {"actuator": "arm_joint_2", "delta": -5.0}},
31
+ ]
32
+ plan = PlanGeneratedEvent(
33
+ intent_id=intent.intent_id,
34
+ correlation_id=intent.session_id,
35
+ steps=steps,
36
+ )
37
+ self.publish_cb(plan)
38
+ return plan
@@ -0,0 +1,22 @@
1
+ """
2
+ Runtime Context Provided to Kernel Actors
3
+ """
4
+
5
+ from cortex.tools.kernel.mailbox import Mailbox
6
+ from cortex.tools.kernel.transport import AnyEvent, InMemoryTransport
7
+
8
+
9
+ class RuntimeContext:
10
+ actor_id: str
11
+ session_id: str
12
+ mailbox: Mailbox
13
+ _transport: InMemoryTransport
14
+
15
+ def __init__(self, actor_id: str, session_id: str, transport: InMemoryTransport):
16
+ self.actor_id = actor_id
17
+ self.session_id = session_id
18
+ self.mailbox = Mailbox()
19
+ self._transport = transport
20
+
21
+ def publish(self, event: AnyEvent) -> None:
22
+ self._transport.publish(event)
@@ -0,0 +1,3 @@
1
+ """
2
+ Kernel Drivers & Adapters
3
+ """
@@ -0,0 +1,84 @@
1
+ """
2
+ Mock Robot Driver
3
+
4
+ Consumes: CommandIssuedEvent
5
+ Produces: DriverTelemetryEvent
6
+
7
+ Translates abstract commands into simulated actuator state changes
8
+ and emits raw telemetry facts. The driver has zero knowledge of
9
+ upstream planners or downstream verification services.
10
+
11
+ Also provides a legacy step_actuator() method for Stage 2
12
+ verification domain tests that operate through the event.py
13
+ MotorFeedbackEvent hierarchy.
14
+ """
15
+
16
+ from collections.abc import Callable
17
+ from typing import cast
18
+
19
+ from cortex.tools.kernel.context import RuntimeContext
20
+ from cortex.tools.kernel.schema.event import MotorFeedbackEvent
21
+ from cortex.tools.kernel.schema.message import CommandIssuedEvent, DriverTelemetryEvent
22
+ from cortex.tools.kernel.transport import AnyEvent
23
+
24
+
25
+ class MockRobotDriver:
26
+ context: RuntimeContext
27
+ actuator_id: str
28
+ publish_cb: Callable[[AnyEvent], object]
29
+ positions: dict[str, float]
30
+ position: float
31
+ velocity: float
32
+
33
+ def __init__(
34
+ self,
35
+ context: RuntimeContext,
36
+ actuator_id_or_cb: str | Callable[[AnyEvent], object] = "arm_joint_1",
37
+ publish_cb: Callable[[AnyEvent], object] | None = None,
38
+ ):
39
+ self.context = context
40
+ if callable(actuator_id_or_cb):
41
+ self.actuator_id = "arm_joint_1"
42
+ self.publish_cb = actuator_id_or_cb
43
+ else:
44
+ self.actuator_id = str(actuator_id_or_cb)
45
+ self.publish_cb = publish_cb or context.publish
46
+
47
+ self.positions = {"arm_joint_1": 0.0, "arm_joint_2": 0.0}
48
+ self.position = 0.0
49
+ self.velocity = 0.0
50
+
51
+ # -- Verification Domain (event.py hierarchy) --------------------------
52
+
53
+ def step_actuator(self, delta_pos: float, velocity: float) -> None:
54
+ """Stage 2 verification interface emitting MotorFeedbackEvent."""
55
+ self.position += delta_pos
56
+ self.velocity = velocity
57
+ event = MotorFeedbackEvent(
58
+ session_id=self.context.session_id,
59
+ actuator_id=self.actuator_id,
60
+ position=self.position,
61
+ velocity=self.velocity,
62
+ )
63
+ _ = self.publish_cb(event)
64
+
65
+ # -- Kernel Runtime Domain (message.py hierarchy) ----------------------
66
+
67
+ def handle_command(self, cmd: CommandIssuedEvent) -> DriverTelemetryEvent:
68
+ """Stage 4 kernel interface consuming CommandIssuedEvent."""
69
+ actuator = cast(str, cmd.parameters.get("actuator", "arm_joint_1"))
70
+ delta = float(cast(int | float, cmd.parameters.get("delta", 0.0)))
71
+
72
+ current = self.positions.get(actuator, 0.0) + delta
73
+ self.positions[actuator] = current
74
+
75
+ telemetry = DriverTelemetryEvent(
76
+ causation_id=cmd.command_id,
77
+ correlation_id=cmd.correlation_id,
78
+ root_id=cmd.plan_id,
79
+ driver_id=actuator,
80
+ status="ok",
81
+ payload={"actuator": actuator, "position": current, "delta": delta},
82
+ )
83
+ _ = self.publish_cb(telemetry)
84
+ return telemetry
@@ -0,0 +1,49 @@
1
+ """
2
+ RTL Verilator Driver for Hardware Telemetry & Trace Ingestion
3
+ """
4
+
5
+ import json
6
+ import os
7
+ from typing import cast
8
+
9
+ from cortex.tools.kernel.context import RuntimeContext
10
+ from cortex.tools.kernel.schema.event import RawRTLTraceEvent
11
+
12
+
13
+ class RTLVerilatorDriver:
14
+ context: RuntimeContext
15
+
16
+ def __init__(self, context: RuntimeContext):
17
+ self.context = context
18
+
19
+ def ingest_trace_file(self, trace_json_path: str = "rtl_trace.json") -> int:
20
+ if not os.path.exists(trace_json_path):
21
+ fallback = "Research/artifacts/phase2/rtl_trace.json"
22
+ if os.path.exists(fallback):
23
+ trace_json_path = fallback
24
+
25
+ with open(trace_json_path, "r") as f:
26
+ data = cast(dict[str, object], json.load(f))
27
+
28
+ frames = cast(list[dict[str, object]], data.get("trace", []))
29
+ for frame in frames:
30
+ seq_num = int(cast(int | float, frame.get("step", 0)))
31
+ pc_val = int(cast(int | float, frame.get("pc", 0)))
32
+ raw_inst = str(frame.get("raw_instruction", "0x00000000"))
33
+ eff_trap = bool(frame.get("eff_trap", False))
34
+ trap_cause = int(cast(int | float, frame.get("trap_cause", 0)))
35
+ stcr_list = cast(list[object], frame.get("stcr_registers", []))
36
+ stcr_regs = {idx: str(val) for idx, val in enumerate(stcr_list)}
37
+
38
+ event = RawRTLTraceEvent(
39
+ session_id=self.context.session_id,
40
+ sequence_number=seq_num,
41
+ pc=pc_val,
42
+ raw_instruction=raw_inst,
43
+ eff_trap=eff_trap,
44
+ trap_cause=trap_cause,
45
+ stcr_registers=stcr_regs
46
+ )
47
+ self.context.publish(event)
48
+
49
+ return len(frames)
@@ -0,0 +1,3 @@
1
+ """
2
+ Kernel Causal Execution Graph Engine
3
+ """