/ scripts / claude_bootstrap.py
claude_bootstrap.py
  1  #!/usr/bin/env python3
  2  """
  3  Claude Bootstrap - Single command for full protocol initialization.
  4  
  5  This script outputs everything a Claude instance needs to bootstrap into
  6  the Sovereign OS protocol. Run at session start instead of manually
  7  reading multiple files.
  8  
  9  Usage:
 10      python3 scripts/claude_bootstrap.py
 11  
 12  What it does:
 13  1. Runs hygiene check
 14  2. Verifies/starts mesh daemon
 15  3. Reads FO-STATE.json (persistent state)
 16  4. Reads LIVE-COMPRESSION.md (session state)
 17  5. Checks Hypercore daemon status
 18  6. Outputs formatted context for Claude
 19  
 20  The output is designed for Claude consumption - structured, concise,
 21  and includes the startup banner.
 22  """
 23  
 24  import json
 25  import os
 26  import sys
 27  import subprocess
 28  import urllib.request
 29  import urllib.error
 30  from datetime import datetime, timedelta
 31  from pathlib import Path
 32  
 33  # Configuration
 34  SOVEREIGN_OS_ROOT = Path(__file__).parent.parent
 35  SESSIONS_DIR = SOVEREIGN_OS_ROOT / "sessions"
 36  FO_STATE_PATH = SESSIONS_DIR / "FO-STATE.json"
 37  LIVE_COMPRESSION_PATH = SESSIONS_DIR / "LIVE-COMPRESSION.md"
 38  INSIGHT_BACKLOG_PATH = SESSIONS_DIR / "INSIGHT-BACKLOG.md"
 39  DEBRIEF_LEDGER_PATH = Path.home() / ".sovereign" / "debrief-ledger.json"
 40  
 41  HYPERCORE_URL = "http://localhost:7777"
 42  MESH_URL = "http://localhost:7778"
 43  
 44  # Required ports
 45  REQUIRED_PORTS = {
 46      7777: "Hypercore daemon",
 47      7778: "Mesh daemon (sovereign-mesh.js)"
 48  }
 49  
 50  
 51  def check_port_conflicts() -> dict:
 52      """
 53      Check if required ports are in use by other processes.
 54  
 55      Returns dict with port status and any conflicts detected.
 56      """
 57      conflicts = {}
 58  
 59      for port, service in REQUIRED_PORTS.items():
 60          try:
 61              # Use lsof to check what's using the port
 62              result = subprocess.run(
 63                  ["lsof", "-i", f":{port}", "-t"],
 64                  capture_output=True, text=True, timeout=5
 65              )
 66  
 67              if result.returncode == 0 and result.stdout.strip():
 68                  pids = result.stdout.strip().split('\n')
 69  
 70                  # Get process info for each PID
 71                  for pid in pids:
 72                      try:
 73                          ps_result = subprocess.run(
 74                              ["ps", "-p", pid, "-o", "comm="],
 75                              capture_output=True, text=True, timeout=2
 76                          )
 77                          process_name = ps_result.stdout.strip() if ps_result.returncode == 0 else "unknown"
 78  
 79                          # Check if it's our expected service
 80                          is_expected = (
 81                              (port == 7777 and "node" in process_name.lower()) or
 82                              (port == 7778 and "node" in process_name.lower())
 83                          )
 84  
 85                          if not is_expected:
 86                              if port not in conflicts:
 87                                  conflicts[port] = []
 88                              conflicts[port].append({
 89                                  "pid": pid,
 90                                  "process": process_name,
 91                                  "service": service
 92                              })
 93                      except:
 94                          pass
 95          except:
 96              pass
 97  
 98      return {
 99          "has_conflicts": len(conflicts) > 0,
100          "conflicts": conflicts
101      }
102  
103  
104  def check_debrief_status() -> dict:
105      """
106      Check when last debrief was run and if there's work without debrief.
107  
108      Returns dict with:
109      - last_debrief: datetime or None
110      - commits_since: number of commits since last debrief
111      - hours_since: hours since last debrief
112      - violation: True if work done without debrief
113      """
114      result = {
115          "last_debrief": None,
116          "commits_since": 0,
117          "hours_since": None,
118          "violation": False,
119          "last_commit_debriefed": None
120      }
121  
122      # Load debrief ledger
123      if DEBRIEF_LEDGER_PATH.exists():
124          try:
125              with open(DEBRIEF_LEDGER_PATH) as f:
126                  ledger = json.load(f)
127                  if ledger:
128                      last_entry = ledger[-1]
129                      result["last_debrief"] = datetime.fromisoformat(last_entry["timestamp"])
130                      result["last_commit_debriefed"] = last_entry.get("latest_commit")
131                      result["hours_since"] = (datetime.now() - result["last_debrief"]).total_seconds() / 3600
132          except:
133              pass
134  
135      # Check commits since last debrief
136      if result["last_commit_debriefed"]:
137          try:
138              cmd = ["git", "rev-list", "--count", f"{result['last_commit_debriefed']}..HEAD"]
139              proc = subprocess.run(cmd, capture_output=True, text=True, cwd=SOVEREIGN_OS_ROOT)
140              if proc.returncode == 0:
141                  result["commits_since"] = int(proc.stdout.strip())
142          except:
143              pass
144      else:
145          # No debrief record, check total commits today
146          try:
147              today = datetime.now().strftime("%Y-%m-%d")
148              cmd = ["git", "rev-list", "--count", "--since", today, "HEAD"]
149              proc = subprocess.run(cmd, capture_output=True, text=True, cwd=SOVEREIGN_OS_ROOT)
150              if proc.returncode == 0:
151                  result["commits_since"] = int(proc.stdout.strip())
152          except:
153              pass
154  
155      # Violation = commits since last debrief > 0
156      if result["commits_since"] > 0:
157          result["violation"] = True
158  
159      return result
160  
161  
162  def check_hypercore() -> dict:
163      """Check Hypercore daemon status."""
164      try:
165          with urllib.request.urlopen(f"{HYPERCORE_URL}/status", timeout=2) as resp:
166              data = json.loads(resp.read().decode())
167              return {
168                  "online": True,
169                  "peers": data.get("peers", 0),
170                  "machine": data.get("machine", "unknown")
171              }
172      except:
173          return {"online": False, "peers": 0, "machine": None}
174  
175  
176  def check_mesh() -> dict:
177      """Check mesh daemon status."""
178      try:
179          with urllib.request.urlopen(f"{MESH_URL}/", timeout=2) as resp:
180              data = json.loads(resp.read().decode())
181              return {
182                  "online": True,
183                  "node": data.get("node", "unknown"),
184                  "peers": data.get("peers", 0)
185              }
186      except:
187          return {"online": False, "node": None, "peers": 0}
188  
189  
190  def start_mesh() -> bool:
191      """Start mesh daemon if not running."""
192      try:
193          keet_cli = SOVEREIGN_OS_ROOT / "keet-cli"
194          subprocess.Popen(
195              ["node", "sovereign-mesh.js", "--http", "--name", "claude-session"],
196              cwd=str(keet_cli),
197              stdout=subprocess.DEVNULL,
198              stderr=subprocess.DEVNULL,
199              start_new_session=True
200          )
201          import time
202          time.sleep(2)
203          return check_mesh()["online"]
204      except:
205          return False
206  
207  
208  def run_hygiene() -> dict:
209      """Run hygiene check and return results."""
210      try:
211          result = subprocess.run(
212              [sys.executable, str(SOVEREIGN_OS_ROOT / "scripts" / "phoenix_hygiene.py")],
213              capture_output=True, text=True, timeout=30
214          )
215          if result.returncode == 0:
216              return {"status": "pass", "message": "All checks pass"}
217          else:
218              return {"status": "issues", "message": result.stdout.strip() or result.stderr.strip()}
219      except Exception as e:
220          return {"status": "error", "message": str(e)}
221  
222  
223  def check_enforcement_status() -> dict:
224      """Check protocol enforcement status."""
225      try:
226          sys.path.insert(0, str(SOVEREIGN_OS_ROOT / "core" / "metacog"))
227          from protocol_enforcer import ProtocolEnforcer
228  
229          enforcer = ProtocolEnforcer()
230          report = enforcer.audit_all()
231  
232          return {
233              "score": f"{report.enforcement_score:.0%}",
234              "gaps": report.total_gaps,
235              "critical": len(report.critical_gaps),
236              "status": "good" if report.enforcement_score >= 0.8 else "needs_work"
237          }
238      except Exception as e:
239          return {"status": "error", "message": str(e)}
240  
241  
242  def get_graph_status() -> dict:
243      """Get graph stats for bootstrap display."""
244      try:
245          sys.path.insert(0, str(SOVEREIGN_OS_ROOT / "core" / "graph"))
246          from reality_surface import RealitySurface
247  
248          surface = RealitySurface()
249          return {
250              "nodes": len(surface.graph["nodes"]),
251              "edges": len(surface.graph["edges"]),
252              "status": "loaded"
253          }
254      except Exception as e:
255          return {"nodes": 0, "edges": 0, "status": "error"}
256  
257  
258  def check_ssh_status() -> dict:
259      """Check SSH key and node connectivity status."""
260      try:
261          sys.path.insert(0, str(SOVEREIGN_OS_ROOT / "scripts"))
262          import ssh_setup
263  
264          status = ssh_setup.check_status()
265  
266          # Summarize for bootstrap
267          has_keys = len(status["keys"]) > 0
268          nodes_ok = all(n["key_auth"] for n in status["nodes"].values())
269          nodes_reachable = [
270              name for name, s in status["nodes"].items()
271              if s["reachable"] and not s["key_auth"]
272          ]
273  
274          return {
275              "has_keys": has_keys,
276              "nodes_ok": nodes_ok,
277              "needs_auth": nodes_reachable,
278              "status": "ok" if (has_keys and nodes_ok) else "needs_work"
279          }
280      except Exception as e:
281          return {"status": "error", "error": str(e)}
282  
283  
284  def check_commit_hygiene() -> dict:
285      """Check for uncommitted work (A4 - ruin exposure)."""
286      try:
287          # Get uncommitted files
288          result = subprocess.run(
289              ["git", "status", "--porcelain"],
290              capture_output=True, text=True,
291              cwd=SOVEREIGN_OS_ROOT, timeout=10
292          )
293  
294          files = [line for line in result.stdout.strip().split("\n") if line]
295  
296          # Categorize
297          critical = []
298          batchable = []
299  
300          for line in files:
301              if not line:
302                  continue
303              filepath = line[3:]
304  
305              # Skip ignored patterns
306              if "__pycache__" in filepath or "RESONANCE-ALERTS" in filepath:
307                  continue
308  
309              # Critical paths (code)
310              if any(filepath.startswith(p) for p in ["core/", "scripts/", "hooks/", "keet-cli/", "docs/"]):
311                  if not filepath.startswith("sessions/"):
312                      critical.append(filepath)
313              else:
314                  batchable.append(filepath)
315  
316          # Determine status
317          if len(critical) > 10:
318              return {
319                  "status": "violation",
320                  "critical": len(critical),
321                  "batchable": len(batchable),
322                  "message": f"⚠️ {len(critical)} code files uncommitted - COMMIT REQUIRED"
323              }
324          elif len(critical) > 0:
325              return {
326                  "status": "warning",
327                  "critical": len(critical),
328                  "batchable": len(batchable),
329                  "message": f"{len(critical)} code files pending"
330              }
331          else:
332              return {
333                  "status": "ok",
334                  "critical": 0,
335                  "batchable": len(batchable),
336                  "message": "✓ Code committed"
337              }
338      except Exception as e:
339          return {"status": "error", "error": str(e)}
340  
341  
342  def load_fo_state() -> dict:
343      """Load First Officer state."""
344      try:
345          if FO_STATE_PATH.exists():
346              with open(FO_STATE_PATH) as f:
347                  return json.load(f)
348      except:
349          pass
350      return {}
351  
352  
353  def load_live_compression() -> dict:
354      """Load and parse LIVE-COMPRESSION.md."""
355      result = {
356          "updated": None,
357          "status": None,
358          "session_id": None,
359          "free_energy": None,
360          "focus": None,
361          "gravity_wells": [],
362          "insights": []
363      }
364  
365      try:
366          if LIVE_COMPRESSION_PATH.exists():
367              content = LIVE_COMPRESSION_PATH.read_text()
368  
369              for line in content.split("\n"):
370                  if "updated::" in line:
371                      result["updated"] = line.split("::", 1)[1].strip()
372                  elif "status::" in line:
373                      result["status"] = line.split("::", 1)[1].strip()
374                  elif "session_id::" in line:
375                      result["session_id"] = line.split("::", 1)[1].strip()
376                  elif "free_energy::" in line:
377                      result["free_energy"] = line.split("::", 1)[1].strip()
378                  elif "## Current Focus" in line:
379                      # Get next non-empty line as focus
380                      idx = content.find(line)
381                      rest = content[idx:].split("\n")
382                      for l in rest[1:5]:
383                          if l.strip() and not l.startswith("#") and not l.startswith("-"):
384                              result["focus"] = l.strip()
385                              break
386                  elif "[[" in line and "]]" in line and "strength::" not in line:
387                      import re
388                      match = re.search(r'\[\[([^\]]+)\]\]', line)
389                      if match and match.group(1) not in result["gravity_wells"]:
390                          result["gravity_wells"].append(match.group(1))
391      except:
392          pass
393  
394      return result
395  
396  
397  def get_high_priority_backlog() -> list:
398      """Get unresolved high-priority items from backlog."""
399      items = []
400      try:
401          if INSIGHT_BACKLOG_PATH.exists():
402              content = INSIGHT_BACKLOG_PATH.read_text()
403              in_high_priority = False
404  
405              for line in content.split("\n"):
406                  if "## High Priority" in line:
407                      in_high_priority = True
408                  elif line.startswith("## ") and in_high_priority:
409                      break
410                  elif in_high_priority and line.startswith("- [ ]"):
411                      # Unresolved high priority item
412                      item = line.replace("- [ ]", "").strip()
413                      if item:
414                          items.append(item)
415      except:
416          pass
417  
418      return items
419  
420  
421  def format_output(hygiene: dict, hypercore: dict, mesh: dict,
422                    fo_state: dict, live_compression: dict, backlog: list,
423                    debrief: dict, enforcement: dict = None, graph_status: dict = None,
424                    port_conflicts: dict = None, ssh_status: dict = None,
425                    commit_hygiene: dict = None) -> str:
426      """Format bootstrap output for Claude."""
427  
428      lines = []
429  
430      # Startup banner
431      lines.append("```")
432      lines.append("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
433      lines.append("SOVEREIGN OS ACTIVE")
434      lines.append("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
435      lines.append("```")
436      lines.append("")
437  
438      # System status table
439      lines.append("## System Status")
440      lines.append("")
441      lines.append("| Component | Status |")
442      lines.append("|-----------|--------|")
443  
444      # Hygiene
445      if hygiene["status"] == "pass":
446          lines.append("| Hygiene | ✓ All checks pass |")
447      else:
448          lines.append(f"| Hygiene | ⚠ {hygiene['message'][:40]} |")
449  
450      # Hypercore
451      if hypercore["online"]:
452          lines.append(f"| Hypercore (:7777) | ✓ {hypercore['peers']} peer(s) |")
453      else:
454          lines.append("| Hypercore (:7777) | ✗ Offline |")
455  
456      # Mesh
457      if mesh["online"]:
458          lines.append(f"| Mesh (:7778) | ✓ {mesh['peers']} peer(s) |")
459      else:
460          lines.append("| Mesh (:7778) | ✗ Offline |")
461  
462      # Enforcement (Belt + Suspenders)
463      if enforcement:
464          if enforcement.get("status") == "good":
465              lines.append(f"| Enforcement | ✓ {enforcement['score']} |")
466          elif enforcement.get("status") == "needs_work":
467              lines.append(f"| Enforcement | ⚠ {enforcement['score']} ({enforcement['critical']} critical gaps) |")
468          else:
469              lines.append("| Enforcement | ? Could not check |")
470  
471      # Graph (Reality Surface)
472      if graph_status:
473          if graph_status.get("status") == "loaded":
474              lines.append(f"| Graph | ✓ {graph_status['nodes']} nodes, {graph_status['edges']} edges |")
475          else:
476              lines.append("| Graph | ? Could not load |")
477  
478      # SSH Status
479      if ssh_status:
480          if ssh_status.get("status") == "ok":
481              lines.append("| SSH | ✓ Keys configured |")
482          elif ssh_status.get("needs_auth"):
483              nodes = ", ".join(ssh_status["needs_auth"])
484              lines.append(f"| SSH | ⚠ Key not authorized on: {nodes} |")
485  
486      # Commit Hygiene (A4 - uncommitted work is ruin exposure)
487      if commit_hygiene:
488          if commit_hygiene.get("status") == "violation":
489              lines.append(f"| **Git** | **⚠️ {commit_hygiene['critical']} uncommitted code files - COMMIT NOW** |")
490          elif commit_hygiene.get("status") == "warning":
491              lines.append(f"| Git | ⚠ {commit_hygiene['critical']} code files pending |")
492          elif commit_hygiene.get("status") == "ok":
493              lines.append("| Git | ✓ Code committed |")
494  
495      lines.append("")
496  
497      # =================================================================
498      # PORT CONFLICT DETECTION
499      # =================================================================
500      if port_conflicts and port_conflicts.get("has_conflicts"):
501          lines.append("## ⚠️ PORT CONFLICTS DETECTED")
502          lines.append("")
503          lines.append("Another process is using required ports:")
504          lines.append("")
505  
506          for port, procs in port_conflicts["conflicts"].items():
507              for proc in procs:
508                  lines.append(f"- **Port {port}** ({proc['service']}): PID {proc['pid']} ({proc['process']})")
509  
510          lines.append("")
511          lines.append("**To resolve:**")
512          lines.append("```bash")
513  
514          for port, procs in port_conflicts["conflicts"].items():
515              for proc in procs:
516                  lines.append(f"# Kill process using port {port}:")
517                  lines.append(f"kill {proc['pid']}")
518  
519          lines.append("```")
520          lines.append("")
521  
522      # =================================================================
523      # COMMIT HYGIENE ENFORCEMENT (A4 - ruin exposure)
524      # =================================================================
525      if commit_hygiene and commit_hygiene.get("status") == "violation":
526          lines.append("## ⚠️ COMMIT REQUIRED - Uncommitted Code")
527          lines.append("")
528          lines.append(f"**{commit_hygiene['critical']} code files need to be committed**")
529          lines.append("")
530          lines.append("Uncommitted work is ruin exposure (A4). If this context compresses,")
531          lines.append("the work is LOST. Commit before proceeding.")
532          lines.append("")
533          lines.append("```bash")
534          lines.append("# Check what needs committing:")
535          lines.append("python3 scripts/commit_hygiene.py")
536          lines.append("")
537          lines.append("# Stage and commit:")
538          lines.append("git add core/ scripts/ hooks/")
539          lines.append('git commit -m "type(scope): description"')
540          lines.append("```")
541          lines.append("")
542  
543      # =================================================================
544      # DEBRIEF ENFORCEMENT (Belt + Suspenders)
545      # =================================================================
546      if debrief["violation"]:
547          lines.append("## ⚠️ DEBRIEF REQUIRED - Protocol Violation")
548          lines.append("")
549          lines.append(f"**{debrief['commits_since']} commit(s) since last debrief**")
550          if debrief["hours_since"]:
551              lines.append(f"Last debrief: {debrief['hours_since']:.1f} hours ago")
552          else:
553              lines.append("Last debrief: Never recorded")
554          lines.append("")
555          lines.append("```bash")
556          lines.append("# Run this NOW before starting new work:")
557          lines.append("python3 scripts/session_report.py")
558          lines.append("```")
559          lines.append("")
560          lines.append("Work without debrief = value not measured = protocol violation.")
561          lines.append("")
562      else:
563          # Show last debrief time even if no violation
564          if debrief["last_debrief"]:
565              lines.append(f"**Last debrief:** {debrief['hours_since']:.1f} hours ago ✓")
566              lines.append("")
567  
568      # Session continuity
569      lines.append("## Session Continuity")
570      lines.append("")
571  
572      if live_compression["session_id"]:
573          lines.append(f"**Continuing from:** `{live_compression['session_id']}`")
574      if live_compression["updated"]:
575          lines.append(f"**Last update:** {live_compression['updated']}")
576      if live_compression["status"]:
577          lines.append(f"**Status:** {live_compression['status']}")
578      if live_compression["free_energy"]:
579          lines.append(f"**Free Energy:** {live_compression['free_energy']}")
580  
581      if live_compression["focus"]:
582          lines.append(f"\n**Last focus:** {live_compression['focus']}")
583  
584      if live_compression["gravity_wells"]:
585          wells = ", ".join(live_compression["gravity_wells"][:5])
586          lines.append(f"\n**Active gravity wells:** {wells}")
587  
588      lines.append("")
589  
590      # Economics summary
591      costs = fo_state.get("costs", {})
592      if costs:
593          lines.append("## Economics (Bitcoin-Anchored)")
594          lines.append("")
595          sats = costs.get("sats", {})
596          efficiency = costs.get("efficiency", {})
597  
598          sub_sats = sats.get("subscription_sats", 0)
599          api_eff = efficiency.get("api_efficiency", 0)
600          infra_eff = efficiency.get("infra_efficiency", 0)
601  
602          lines.append(f"**Subscription:** {sub_sats:,} sats | **Efficiency:** {api_eff}x API, {infra_eff}x infra")
603          lines.append("")
604  
605      # High priority backlog items
606      if backlog:
607          lines.append("## ⚠ High Priority Backlog (Unresolved)")
608          lines.append("")
609          for item in backlog[:3]:
610              lines.append(f"- {item[:80]}")
611          lines.append("")
612  
613      # Quick reference
614      lines.append("## Protocol Commands")
615      lines.append("")
616      lines.append("| When | Command | Purpose |")
617      lines.append("|------|---------|---------|")
618      lines.append("| **After ANY work** | `python3 scripts/session_report.py` | Financial debrief (MANDATORY) |")
619      lines.append("| **Before work** | `python3 scripts/query_graph.py --preflight 'topic'` | What graph knows |")
620      lines.append("| **During work** | `python3 scripts/query_graph.py 'query'` | Position check |")
621      lines.append("| Track done item | `--add-done \"description\"` | Log completed work |")
622      lines.append("| Track insight | `--add-insight \"insight\" A2` | Log wisdom captured |")
623      lines.append("")
624  
625      # Resurrection seed location
626      lines.append("**State files:**")
627      lines.append("- LIVE-COMPRESSION: `sessions/LIVE-COMPRESSION.md`")
628      lines.append("- FO-STATE: `sessions/FO-STATE.json`")
629      lines.append("- INSIGHT-BACKLOG: `sessions/INSIGHT-BACKLOG.md`")
630      lines.append("")
631      lines.append("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
632  
633      return "\n".join(lines)
634  
635  
636  def main():
637      """Main bootstrap entry point."""
638  
639      # 1. Run hygiene check
640      hygiene = run_hygiene()
641  
642      # 2. Check for port conflicts BEFORE checking services
643      port_conflicts = check_port_conflicts()
644  
645      # 3. Check Hypercore daemon
646      hypercore = check_hypercore()
647  
648      # 4. Check/start mesh
649      mesh = check_mesh()
650      if not mesh["online"]:
651          # Only try to start if there's no port conflict
652          if not port_conflicts.get("has_conflicts") or 7778 not in port_conflicts.get("conflicts", {}):
653              if start_mesh():
654                  mesh = check_mesh()
655  
656      # 5. Load FO state
657      fo_state = load_fo_state()
658  
659      # 6. Load LIVE-COMPRESSION
660      live_compression = load_live_compression()
661  
662      # 7. Check backlog
663      backlog = get_high_priority_backlog()
664  
665      # 8. Check debrief status (ENFORCEMENT)
666      debrief = check_debrief_status()
667  
668      # 9. Check protocol enforcement (Belt + Suspenders)
669      enforcement = check_enforcement_status()
670  
671      # 10. Get graph status (Reality Surface)
672      graph_status = get_graph_status()
673  
674      # 11. Check SSH status
675      ssh_status = check_ssh_status()
676  
677      # 12. Check commit hygiene (A4 - uncommitted work is ruin exposure)
678      commit_hygiene = check_commit_hygiene()
679  
680      # 13. Output formatted context
681      output = format_output(
682          hygiene, hypercore, mesh, fo_state, live_compression,
683          backlog, debrief, enforcement, graph_status, port_conflicts, ssh_status,
684          commit_hygiene
685      )
686      print(output)
687  
688      # Return exit code based on critical issues
689      if hygiene["status"] == "error":
690          sys.exit(1)
691      if not hypercore["online"] and not mesh["online"]:
692          sys.exit(1)
693  
694      sys.exit(0)
695  
696  
697  if __name__ == "__main__":
698      main()