Files
becomingone/simple_witness.py
T
solaria 3117dea0e6 fix: Proper deque serialization for JSON API
- Add deque_to_list helper for safe serialization
- Use getattr to safely access nested attributes
- Fix coherence endpoint to return properly serializable data
2026-02-20 02:51:38 +00:00

91 lines
2.5 KiB
Python

#!/usr/bin/env python3
"""
simple_witness.py
Simple witness check for BECOMINGONE instances.
Polls a target instance and commits observations.
Run this on witness-seed to watch the Mac mini.
Usage:
python3 simple_witness.py --target http://localhost:8000 --name "mac-mini"
python3 simple_witness.py --target http://198.12.71.159:8000 --name "witness-seed"
"""
import argparse
import json
import subprocess
import sys
import time
from datetime import datetime
from pathlib import Path
import httpx
def witness(target_url: str, name: str) -> dict:
"""Witness a BECOMINGONE instance."""
observation = {
"timestamp": datetime.utcnow().isoformat(),
"witness": name,
"target": target_url,
"target_up": False,
"health": None,
"coherence": None,
}
try:
# Health check
resp = httpx.get(f"{target_url}/health", timeout=5)
if resp.status_code == 200:
observation["health"] = resp.json()
observation["target_up"] = True
# Coherence check
resp = httpx.get(f"{target_url}/coherence", timeout=5)
if resp.status_code == 200:
observation["coherence"] = resp.json()
except Exception as e:
observation["error"] = str(e)
return observation
def main():
parser = argparse.ArgumentParser(description="Simple BECOMINGONE witness")
parser.add_argument("--target", required=True, help="Target URL")
parser.add_argument("--name", required=True, help="Witness name")
parser.add_argument("--output", help="Output file")
args = parser.parse_args()
obs = witness(args.target, args.name)
# Print result
status = "✅" if obs["target_up"] else "❌"
print(f"{status} {obs['witness']} -> {obs['target']}")
if obs["target_up"]:
c = obs.get("coherence", {})
print(f" Master: {c.get('master_coherence', 'N/A')}")
print(f" Emissary: {c.get('emissary_coherence', 'N/A')}")
print(f" Sync aligned: {c.get('sync_aligned', 'N/A')}")
else:
print(f" Error: {obs.get('error', 'Unknown')}")
# Save to file
output_file = args.output or f"witness_{name_to_file(args.name)}.json"
with open(output_file, "w") as f:
json.dump(obs, f, indent=2, default=str)
print(f"\nSaved to {output_file}")
def name_to_file(name: str) -> str:
"""Convert name to filename-safe string."""
return name.replace(" ", "-").replace("/", "-")
if __name__ == "__main__":
main()