Reaper
The `reaper` is a tactical agent designed to terminate other agents. It can operate in two modes: **mission mode**, where it is launched with a specific list of targets to kill, or **patrol mode**, where it runs persistently and watches for "hit cookie" files to appear in other agents' directories.
⚙️ How it Works
The `reaper` uses the `ReaperUniversalHandler` to manage the termination process. This handler first attempts a "graceful" shutdown by dropping a `die` file into the target's `/incoming` directory. If the agent doesn't shut down within a timeout period, the handler escalates to forcefully terminate the underlying process ID. In mission mode, the `reaper` executes its kill list and then terminates itself. In patrol mode, it continuously scans all `/comm` directories for a `hit.cookie` file and executes a hit on any target specified within.
🧩 Configuration
* **`is_mission`** (Default: `false`): If `true`, the agent runs once, kills the `kill_list`, and exits. If `false`, it enters patrol mode.
* **`kill_list`** (Default: `[]`): A list of `universal_id`s to terminate when in mission mode.
* **`delay`** (Default: `0`): Seconds to wait before executing a mission, allowing other processes to initialize.
* **`tombstone_comm`** (Default: `true`): If `true`, leaves a `tombstone` file in the target's `/comm` directory.
* **`tombstone_pod`** (Default: `true`): If `true`, leaves a `tombstone` file in the target's `/pod` directory.
🧭 Directive
matrix_directive = {
"universal_id": "matrix",
"name": "matrix",
"children": [
{
"universal_id": "reaper-assassin-1",
"name": "reaper",
"config": {
"is_mission": True,
"kill_list": ["agent-x", "agent-y"]
}
}
]
}
📦 Source
#Authored by Daniel F MacDonald and ChatGPT 4
# ?????????????????????????????????????????????????
# ? ? REAPER AGENT ? ?
# ? Tactical Cleanup Wipe Authority V2.5 ?
# ? Forged in the halls of Matrix ?
# ? Accepts: .cmd / .json | Modes: soft/full ?
# ?????????????????????????????????????????????????
import sys
import os
sys.path.insert(0, os.getenv("SITE_ROOT"))
sys.path.insert(0, os.getenv("AGENT_PATH"))
# DisposableReaperAgent.py
import json
import time
import threading
from pathlib import Path
from matrixswarm.core.boot_agent import BootAgent
from matrixswarm.core.class_lib.processes.reaper_universal_id_handler import ReaperUniversalHandler # PID Handler
from matrixswarm.core.utils.swarm_sleep import interruptible_sleep
class Agent(BootAgent):
def __init__(self):
super().__init__()
# Load targets, kill ID, and initialize paths
config = self.tree_node.get("config", {})
self.is_mission = bool(config.get("is_mission", False))
self.targets = self.command_line_args.get("targets") or config.get("kill_list", [])
self.universal_ids = self.command_line_args.get("universal_ids") or config.get("universal_ids", {})
self.kill_id = self.command_line_args.get("kill_id") or config.get("kill_id") or f"reap-{int(time.time())}"
self.strike_delay = config.get("delay", 0)
self.tombstone_comm = config.get("tombstone_comm", True)
self.tombstone_pod = config.get("tombstone_pod", True)
self.cleanup_die = config.get("cleanup_die", False)
self.universal_id_handler = ReaperUniversalHandler(self.path_resolution['pod_path'], self.path_resolution['comm_path'], logger=self.logger)
def post_boot(self):
"""
Logs the mission details and starts the mission in a separate thread.
"""
if self.is_mission:
self.mission()
else:
threading.Thread(target=self.patrol_comm_for_hit_cookies, daemon=True).start()
def worker_pre(self):
self.log("[REAPER] Agent entering execution mode. Targets loaded. Blades sharp.")
def worker_post(self):
self.log("[REAPER] Mission completed. Reaper dissolving into silence.")
def mission(self):
"""
Execute the mission using the Permanent ID handler to process shutdown requests for all targets.
"""
self.log("[INFO] Inserting hit team...")
if self.strike_delay > 0:
self.log(f"[REAPER] ? Waiting {self.strike_delay} seconds before executing strike...")
time.sleep(self.strike_delay)
# Filter `self.targets` based on valid universal_ids
filtered_universal_ids = {universal_id: self.universal_ids[universal_id] for universal_id in self.targets if universal_id in self.universal_ids}
if not filtered_universal_ids:
self.log("[WARNING] No valid targets found in the provided target list.")
self.running = False # Mark the agent as stopped
return
# Use central handler to process all valid targets at once
try:
self.universal_id_handler.process_all_universal_ids(
filtered_universal_ids,
tombstone_mode=True,
wait_seconds=20,
tombstone_comm=self.tombstone_comm,
tombstone_pod=self.tombstone_pod
)
if self.cleanup_die:
for uid in filtered_universal_ids:
try:
die_path = os.path.join(self.path_resolution["comm_path"], uid, "incoming", "die")
if os.path.exists(die_path):
os.remove(die_path)
self.log(f"[REAPER] Removed die signal from comm: {uid}")
except Exception as e:
self.log(f"[REAPER][ERROR] Failed to remove die for {uid}: {e}")
self.log("[INFO] Mission completed successfully.")
except Exception as e:
self.log(f"[ERROR] Failed to complete mission: {str(e)}")
self.running = False # Mark the agent as stopped
self.log("[INFO] Mission completed and the agent is now stopping.")
self.leave_tombstone_and_die()
#TODO verify Matrix sig
def verify_hit_cookie(self, payload, signature):
try:
pass
except Exception as e:
#self.log(f"[ERROR] Failed to complete mission: {str(e)}")
pass
return True
def patrol_comm_for_hit_cookies(self):
self.log("[REAPER] ? Patrol mode active. Scanning for hit cookies...")
comm_root = Path(self.path_resolution["comm_path"])
while True:
try:
for agent_dir in comm_root.iterdir():
hello_path = agent_dir / "hello.moto"
cookie_path = hello_path / "hit.cookie"
if not cookie_path.exists():
continue
payload = {}
uid=None
with open(cookie_path, "r", encoding="utf-8") as f:
try:
payload = json.load(f)
uid = payload.get("target")
except Exception as e:
self.log(f"[REAPER][WARN] Malformed cookie in {cookie_path}: {e}")
continue
# Optional: verify signature
signature = "sig" # payload.get("signature")
if not self.verify_hit_cookie(payload, signature):
if not uid:
uid = "[not set]"
self.log(f"[REAPER][WARN] Invalid or unsigned kill cookie for {uid}, skipping.")
continue
if not uid:
continue
# TODO: Verify signature if encryption is enabled (hook here)
self.log(f"[REAPER] ? Target marked: {uid} executing...")
# Execute: reuse universal_id handler
self.process_universal_id(uid)
#cookie_path.unlink() # Remove cookie after execution - scavenger will do it
except Exception as e:
self.log(f"[REAPER][ERROR] Patrol loop failed: {e}")
interruptible_sleep(self, 15)
def process_universal_id(self, uid):
handler = ReaperUniversalHandler(self.path_resolution["pod_path"], self.path_resolution["comm_path"], logger=self.logger)
handler.process_all_universal_ids(
[uid],
tombstone_mode=True,
wait_seconds=15,
tombstone_comm=True,
tombstone_pod=True
)
def leave_tombstone_and_die(self):
"""
Reaper drops his own tombstone and shuts down cleanly.
"""
try:
incoming_dir = os.path.join(self.path_resolution["comm_path"], self.command_line_args["universal_id"], "incoming")
os.makedirs(incoming_dir, exist_ok=True)
pod_dir = os.path.join(self.path_resolution["pod_path"], self.command_line_args["install_name"])
# Write tombstone to comm
die_path = os.path.join(incoming_dir, "die")
with open(die_path, "w", encoding="utf-8") as f:
f.write("true")
# Write tombstone to comm
tombstone_path = os.path.join(incoming_dir, "tombstone")
with open(tombstone_path, "w", encoding="utf-8") as f:
f.write("true")
# Write tombstone to pod
tombstone_path = os.path.join(pod_dir, "tombstone")
with open(tombstone_path, "w", encoding="utf-8") as f:
f.write("true")
death_warrant=self.tree_node.get('config',{}).get('death_warrant', False)
if death_warrant:
self.deliver_death_warrant(death_warrant)
self.log(f"[DISPOSABLE-REAPER] Die cookie dropped & Tombstone dropped. Mission complete. Signing off.")
except Exception as e:
self.log(f"[DISPOSABLE-REAPER][ERROR] Failed to leave tombstone: {str(e)}")
finally:
self.running = False # Always stop running, even if tombstone writing fails
def attempt_kill(self, universal_id):
"""
Deliver 'die' and 'tombstone' signals to a directory and wait for graceful shutdown.
Escalates with Permanent ID Handler if the process resists termination.
"""
# Paths for the target
pod_path = os.path.join(self.path_resolution['pod_path'], universal_id)
comm_path = os.path.join(self.path_resolution['comm_path'], universal_id)
# Send 'die' and 'tombstone' signals via `comm_path`
incoming = os.path.join(comm_path, "incoming")
os.makedirs(incoming, exist_ok=True)
with open(os.path.join(incoming, "die"), "w", encoding="utf-8") as f:
json.dump({"cmd": "die", "force": False}, f)
with open(os.path.join(incoming, "tombstone"), "w", encoding="utf-8") as f:
f.write("true")
self.log(f"[DISPOSABLE-REAPER] Die and tombstone delivered to {universal_id}")
# Monitor shutdown success via hello.moto file
hello_path = os.path.join(pod_path, "hello.moto")
max_wait = 18
elapsed = 0
while elapsed < max_wait:
if not os.path.exists(hello_path):
self.log(f"[DISPOSABLE-REAPER] {universal_id} down gracefully.")
return True
time.sleep(3)
elapsed += 3
# Escalate with PID handler if process resists
self.log(f"[DISPOSABLE-REAPER] {universal_id} resisted invoking Full PID Handler escalation.")
self.escalate_with_pid_handler(universal_id)
return False
def escalate_with_pid_handler(self, universal_id):
"""
Escalate the shutdown process using the Permanent ID handler for the specified target.
"""
try:
self.universal_id_handler.shutdown_processes(universal_id, universal_id)
self.log(f"[DISPOSABLE-REAPER] PID Handler escalation complete for {universal_id}")
except Exception as e:
self.log(f"[DISPOSABLE-REAPER] PID Handler escalation FAILED for {universal_id}: {e}")
def deliver_death_warrant(self, signed_warrant):
try:
# request the agent_tree_master from Matrix
packet = self.get_delivery_packet("standard.command.packet", new=True)
packet.set_data({
"handler": "cmd_validate_warrant",
"agent_id": self.command_line_args["universal_id"],
"content": { # ? wrap inside content
"agent_id": self.command_line_args["universal_id"],
"warrant": signed_warrant
},
"timestamp": time.time(),
"origin": self.command_line_args["universal_id"]
})
self.pass_packet(packet, "matrix")
self.log("[REAPER] ? Death warrant dispatched to Matrix for post-mission validation.")
except Exception as e:
self.log(f"Sync request failed: {e}")
def send_mission_report(self, results):
"""
Generate and save a mission report including results for each target.
"""
payload = {
"kill_id": self.kill_id,
"targets": self.targets,
"results": results,
"timestamp": time.time(),
"message": f"Kill operation {self.kill_id} complete."
}
report_path = os.path.join(self.outbox_path, f"reaper_mission_{self.kill_id}.json")
with open(report_path, "w", encoding="utf-8") as f:
json.dump(payload, f, indent=2)
self.log(f"[DISPOSABLE-REAPER] Mission report written: {report_path}")
if __name__ == "__main__":
agent = Agent()
agent.boot()
Comments 0
Category: security
Tags: #security, #process-management, #system-utility, #terminator, #agent-management, #patrol, #tactical, #cleanup
Version: v2.5.0
Author: matrixswarm
Views: 100
Added: July 22, 2025Updated: July 26, 2025