#!/usr/bin/env python3 """ Fleet Resource Tracker — Tracks Capacity, Uptime, and Innovation. Paperclips-inspired tension model: - Capacity: spent on fleet improvements, generates through utilization - Uptime: earned when services stay up, Fibonacci milestones unlock capabilities - Innovation: only generates when capacity < 70%. Fuels Phase 3+. This is the heart of the fleet progression system. """ import os import json import time import socket from datetime import datetime, timezone from pathlib import Path # === CONFIG === DATA_DIR = Path(os.path.expanduser("~/.local/timmy/fleet-resources")) RESOURCES_FILE = DATA_DIR / "resources.json" # Tension thresholds INNOVATION_THRESHOLD = 0.70 # Innovation only generates when capacity < 70% INNOVATION_RATE = 5.0 # Innovation generated per hour when under threshold CAPACITY_REGEN_RATE = 2.0 # Capacity regenerates per hour of healthy operation FIBONACCI = [95.0, 95.5, 96.0, 97.0, 97.5, 98.0, 98.3, 98.6, 98.9, 99.0, 99.5] def init(): DATA_DIR.mkdir(parents=True, exist_ok=True) if not RESOURCES_FILE.exists(): data = { "capacity": { "current": 100.0, "max": 100.0, "spent_on": [], "history": [] }, "uptime": { "current_pct": 100.0, "milestones_reached": [], "total_checks": 0, "successful_checks": 0, "history": [] }, "innovation": { "current": 0.0, "total_generated": 0.0, "spent_on": [], "last_calculated": time.time() } } RESOURCES_FILE.write_text(json.dumps(data, indent=2)) print("Initialized resource tracker") return RESOURCES_FILE.exists() def load(): if RESOURCES_FILE.exists(): return json.loads(RESOURCES_FILE.read_text()) return None def save(data): RESOURCES_FILE.write_text(json.dumps(data, indent=2)) def update_uptime(checks: dict): """Update uptime stats from health check results. checks = {'ezra': True, 'allegro': True, 'bezalel': True, 'gitea': True, ...} """ data = load() if not data: return data["uptime"]["total_checks"] += 1 successes = sum(1 for v in checks.values() if v) total = len(checks) # Overall uptime percentage overall = successes / max(total, 1) * 100.0 data["uptime"]["successful_checks"] += successes # Calculate rolling uptime if "history" not in data["uptime"]: data["uptime"]["history"] = [] data["uptime"]["history"].append({ "ts": datetime.now(timezone.utc).isoformat(), "checks": checks, "overall": round(overall, 2) }) # Keep last 1000 checks if len(data["uptime"]["history"]) > 1000: data["uptime"]["history"] = data["uptime"]["history"][-1000:] # Calculate current uptime %, last 100 checks recent = data["uptime"]["history"][-100:] recent_ok = sum(c["overall"] for c in recent) / max(len(recent), 1) data["uptime"]["current_pct"] = round(recent_ok, 2) # Check Fibonacci milestones new_milestones = [] for fib in FIBONACCI: if fib not in data["uptime"]["milestones_reached"] and recent_ok >= fib: data["uptime"]["milestones_reached"].append(fib) new_milestones.append(fib) save(data) if new_milestones: print(f" UPTIME MILESTONE: {','.join(str(m) + '%') for m in new_milestones}") print(f" Current uptime: {recent_ok:.1f}%") return data["uptime"] def spend_capacity(amount: float, purpose: str): """Spend capacity on a fleet improvement.""" data = load() if not data: return False if data["capacity"]["current"] < amount: print(f" INSUFFICIENT CAPACITY: Need {amount}, have {data['capacity']['current']:.1f}") return False data["capacity"]["current"] -= amount data["capacity"]["spent_on"].append({ "purpose": purpose, "amount": amount, "ts": datetime.now(timezone.utc).isoformat() }) save(data) print(f" Spent {amount} capacity on: {purpose}") return True def regenerate_resources(): """Regenerate capacity and calculate innovation.""" data = load() if not data: return now = time.time() last = data["innovation"]["last_calculated"] hours = (now - last) / 3600.0 if hours < 0.1: # Only update every ~6 minutes return # Regenerate capacity capacity_gain = CAPACITY_REGEN_RATE * hours data["capacity"]["current"] = min( data["capacity"]["max"], data["capacity"]["current"] + capacity_gain ) # Calculate capacity utilization utilization = 1.0 - (data["capacity"]["current"] / data["capacity"]["max"]) # Generate innovation only when under threshold innovation_gain = 0.0 if utilization < INNOVATION_THRESHOLD: innovation_gain = INNOVATION_RATE * hours * (1.0 - utilization / INNOVATION_THRESHOLD) data["innovation"]["current"] += innovation_gain data["innovation"]["total_generated"] += innovation_gain # Record history if "history" not in data["capacity"]: data["capacity"]["history"] = [] data["capacity"]["history"].append({ "ts": datetime.now(timezone.utc).isoformat(), "capacity": round(data["capacity"]["current"], 1), "utilization": round(utilization * 100, 1), "innovation": round(data["innovation"]["current"], 1), "innovation_gain": round(innovation_gain, 1) }) # Keep last 500 capacity records if len(data["capacity"]["history"]) > 500: data["capacity"]["history"] = data["capacity"]["history"][-500:] data["innovation"]["last_calculated"] = now save(data) print(f" Capacity: {data['capacity']['current']:.1f}/{data['capacity']['max']:.1f}") print(f" Utilization: {utilization*100:.1f}%") print(f" Innovation: {data['innovation']['current']:.1f} (+{innovation_gain:.1f} this period)") return data def status(): """Print current resource status.""" data = load() if not data: print("Resource tracker not initialized. Run --init first.") return print("\n=== Fleet Resources ===") print(f" Capacity: {data['capacity']['current']:.1f}/{data['capacity']['max']:.1f}") utilization = 1.0 - (data["capacity"]["current"] / data["capacity"]["max"]) print(f" Utilization: {utilization*100:.1f}%") innovation_status = "GENERATING" if utilization < INNOVATION_THRESHOLD else "BLOCKED" print(f" Innovation: {data['innovation']['current']:.1f} [{innovation_status}]") print(f" Uptime: {data['uptime']['current_pct']:.1f}%") print(f" Milestones: {', '.join(str(m)+'%' for m in data['uptime']['milestones_reached']) or 'None yet'}") # Phase gate checks phase_2_ok = data['uptime']['current_pct'] >= 95.0 phase_3_ok = phase_2_ok and data['innovation']['current'] > 100 phase_5_ok = phase_2_ok and data['innovation']['current'] > 500 print(f"\n Phase Gates:") print(f" Phase 2 (Automation): {'UNLOCKED' if phase_2_ok else 'LOCKED (need 95% uptime)'}") print(f" Phase 3 (Orchestration): {'UNLOCKED' if phase_3_ok else 'LOCKED (need 95% uptime + 100 innovation)'}") print(f" Phase 5 (Scale): {'UNLOCKED' if phase_5_ok else 'LOCKED (need 95% uptime + 500 innovation)'}") if __name__ == "__main__": import sys init() if len(sys.argv) > 1 and sys.argv[1] == "status": status() elif len(sys.argv) > 1 and sys.argv[1] == "regen": regenerate_resources() else: regenerate_resources() status()