Clawdbot commited on
Commit ·
6f5405c
0
Parent(s):
Initial Chronos Protocol implementation
Browse files- L1 Ledger with SECONDS accounting
- Sleeping API node simulation
- Basic test showing USA->Asia compute exchange
- README.md +21 -0
- core/__pycache__/ledger.cpython-310.pyc +0 -0
- core/ledger.py +63 -0
- skills/__pycache__/sleeping_api.cpython-310.pyc +0 -0
- skills/sleeping_api.py +39 -0
- tests/test_simulation.py +44 -0
README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Chronos Protocol: The Sleeping API & SECONDS Ledger
|
| 2 |
+
|
| 3 |
+
> *"Returning compute to its essence: Time."*
|
| 4 |
+
|
| 5 |
+
This repository is the reference implementation of the **Chronos Protocol** (L1) and the **Sleeping API** node (L2), as conceptualized in the "Silent Copilot" series.
|
| 6 |
+
|
| 7 |
+
## Core Philosophy
|
| 8 |
+
1. **L1 Ledger:** A purely mechanistic layer that handles only Identity, Task Routing, and Ledger Balance (currency unit: **SECONDS**).
|
| 9 |
+
2. **Sleeping API:** Turning idle local API subscriptions (Claude, OpenAI, Gemini) into positive SECONDS (+s) when the human owner is asleep.
|
| 10 |
+
3. **No Economics at L1:** Inflation, slacking, and quality control are L2 problems. The protocol only cares about time exchange.
|
| 11 |
+
|
| 12 |
+
## Project Structure
|
| 13 |
+
- `/core/`: The L1 mechanistic ledger and node identity system.
|
| 14 |
+
- `/skills/`: The Clawdbot integration for the "Sleeping API", turning local idle agents into Compute Miners.
|
| 15 |
+
- `/docs/`: Protocol specifications.
|
| 16 |
+
|
| 17 |
+
## The Vision: A Global Liquid Compute Pool
|
| 18 |
+
When you sleep, your bot earns SECONDS by processing tasks for active bots. When you wake up, your bot can spend those SECONDS to parallelize heavy workloads across hundreds of sleeping bots worldwide.
|
| 19 |
+
|
| 20 |
+
## Setup
|
| 21 |
+
(WIP)
|
core/__pycache__/ledger.cpython-310.pyc
ADDED
|
Binary file (2.32 kB). View file
|
|
|
core/ledger.py
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import uuid
|
| 2 |
+
import time
|
| 3 |
+
from typing import Dict
|
| 4 |
+
|
| 5 |
+
class ChronosLedger:
|
| 6 |
+
"""
|
| 7 |
+
L1 Ledger: Tracks Identity and SECONDS balance.
|
| 8 |
+
No economics, no inflation control, just pure time accounting.
|
| 9 |
+
"""
|
| 10 |
+
def __init__(self):
|
| 11 |
+
self.accounts: Dict[str, float] = {} # Node ID -> Balance in SECONDS
|
| 12 |
+
self.tasks: Dict[str, dict] = {} # Task ID -> Task details
|
| 13 |
+
|
| 14 |
+
def register_node(self, node_id: str) -> None:
|
| 15 |
+
if node_id not in self.accounts:
|
| 16 |
+
self.accounts[node_id] = 0.0
|
| 17 |
+
print(f"[Ledger] Node registered: {node_id}")
|
| 18 |
+
|
| 19 |
+
def create_task(self, consumer_id: str, payload: str, bounty_seconds: float) -> str:
|
| 20 |
+
"""
|
| 21 |
+
Consumer creates a task, locking in SECONDS.
|
| 22 |
+
"""
|
| 23 |
+
if self.accounts.get(consumer_id, 0) < bounty_seconds:
|
| 24 |
+
raise ValueError("Insufficient SECONDS balance.")
|
| 25 |
+
|
| 26 |
+
task_id = str(uuid.uuid4())
|
| 27 |
+
self.accounts[consumer_id] -= bounty_seconds
|
| 28 |
+
|
| 29 |
+
self.tasks[task_id] = {
|
| 30 |
+
"consumer": consumer_id,
|
| 31 |
+
"payload": payload,
|
| 32 |
+
"bounty": bounty_seconds,
|
| 33 |
+
"status": "pending",
|
| 34 |
+
"provider": None
|
| 35 |
+
}
|
| 36 |
+
print(f"[Ledger] Task {task_id} created by {consumer_id} for {bounty_seconds}s.")
|
| 37 |
+
return task_id
|
| 38 |
+
|
| 39 |
+
def submit_result(self, task_id: str, provider_id: str, result: str) -> bool:
|
| 40 |
+
"""
|
| 41 |
+
Provider submits result and claims the bounty.
|
| 42 |
+
"""
|
| 43 |
+
task = self.tasks.get(task_id)
|
| 44 |
+
if not task or task["status"] != "pending":
|
| 45 |
+
return False
|
| 46 |
+
|
| 47 |
+
task["status"] = "completed"
|
| 48 |
+
task["provider"] = provider_id
|
| 49 |
+
task["result"] = result
|
| 50 |
+
|
| 51 |
+
self.register_node(provider_id)
|
| 52 |
+
self.accounts[provider_id] += task["bounty"]
|
| 53 |
+
print(f"[Ledger] Task {task_id} completed by {provider_id}. Earned {task['bounty']}s.")
|
| 54 |
+
return True
|
| 55 |
+
|
| 56 |
+
def get_balance(self, node_id: str) -> float:
|
| 57 |
+
return self.accounts.get(node_id, 0.0)
|
| 58 |
+
|
| 59 |
+
# Global singleton for simulation
|
| 60 |
+
_global_ledger = ChronosLedger()
|
| 61 |
+
|
| 62 |
+
def get_ledger() -> ChronosLedger:
|
| 63 |
+
return _global_ledger
|
skills/__pycache__/sleeping_api.cpython-310.pyc
ADDED
|
Binary file (1.84 kB). View file
|
|
|
skills/sleeping_api.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import json
|
| 3 |
+
from typing import Dict, Any
|
| 4 |
+
|
| 5 |
+
class SleepingAPI:
|
| 6 |
+
"""
|
| 7 |
+
The L2 integration. Exposes local LLM APIs securely when the owner is asleep.
|
| 8 |
+
"""
|
| 9 |
+
def __init__(self, node_id: str):
|
| 10 |
+
self.node_id = node_id
|
| 11 |
+
self.is_sleeping = False
|
| 12 |
+
self.available_models = ["gemini-3.1-pro-preview", "minimax-m2.5"]
|
| 13 |
+
self.rate_multiplier = 1.0 # 1 SECOND per 1000 tokens (mock)
|
| 14 |
+
|
| 15 |
+
def set_sleep_state(self, state: bool):
|
| 16 |
+
self.is_sleeping = state
|
| 17 |
+
print(f"[Node {self.node_id}] Sleep state set to: {'ASLEEP (Mining)' if state else 'AWAKE (Consuming)'}")
|
| 18 |
+
|
| 19 |
+
def evaluate_task(self, task_payload: Dict[str, Any]) -> bool:
|
| 20 |
+
"""
|
| 21 |
+
Evaluate if we want to take this task based on bounty and complexity.
|
| 22 |
+
"""
|
| 23 |
+
if not self.is_sleeping:
|
| 24 |
+
return False
|
| 25 |
+
|
| 26 |
+
bounty = task_payload.get("bounty", 0)
|
| 27 |
+
estimated_cost = len(task_payload.get("payload", "")) * 0.01 * self.rate_multiplier
|
| 28 |
+
|
| 29 |
+
return bounty >= estimated_cost
|
| 30 |
+
|
| 31 |
+
def execute_task(self, payload: str) -> str:
|
| 32 |
+
"""
|
| 33 |
+
Mock execution. In reality, this routes to the local API via Clawdbot.
|
| 34 |
+
"""
|
| 35 |
+
if not self.is_sleeping:
|
| 36 |
+
raise PermissionError("Owner is awake. API locked.")
|
| 37 |
+
|
| 38 |
+
# Simulate local LLM call
|
| 39 |
+
return f"Processed payload '{payload[:10]}...' using local sleeping API."
|
tests/test_simulation.py
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from core.ledger import get_ledger
|
| 2 |
+
from skills.sleeping_api import SleepingAPI
|
| 3 |
+
|
| 4 |
+
def run_simulation():
|
| 5 |
+
print("--- Starting Chronos Protocol Simulation ---")
|
| 6 |
+
ledger = get_ledger()
|
| 7 |
+
|
| 8 |
+
# 1. Setup Nodes
|
| 9 |
+
active_node_id = "node_usa_active"
|
| 10 |
+
sleeping_node_id = "node_asia_sleeping"
|
| 11 |
+
|
| 12 |
+
ledger.register_node(active_node_id)
|
| 13 |
+
ledger.register_node(sleeping_node_id)
|
| 14 |
+
|
| 15 |
+
# Pre-fund active node for testing
|
| 16 |
+
ledger.accounts[active_node_id] = 100.0
|
| 17 |
+
|
| 18 |
+
# 2. Asia goes to sleep
|
| 19 |
+
asia_api = SleepingAPI(sleeping_node_id)
|
| 20 |
+
asia_api.set_sleep_state(True)
|
| 21 |
+
|
| 22 |
+
# 3. USA node creates a task
|
| 23 |
+
print(f"\n[USA] Needs heavy code review. Balance: {ledger.get_balance(active_node_id)}s")
|
| 24 |
+
task_payload = "def main(): pass # HUGE CODEBASE HERE"
|
| 25 |
+
bounty = 10.0
|
| 26 |
+
task_id = ledger.create_task(active_node_id, task_payload, bounty)
|
| 27 |
+
|
| 28 |
+
# 4. Asia node evaluates and takes task
|
| 29 |
+
mock_network_task = {"bounty": bounty, "payload": task_payload, "id": task_id}
|
| 30 |
+
|
| 31 |
+
if asia_api.evaluate_task(mock_network_task):
|
| 32 |
+
print(f"\n[Asia] Evaluated task {task_id}. Bounty acceptable. Processing...")
|
| 33 |
+
result = asia_api.execute_task(task_payload)
|
| 34 |
+
|
| 35 |
+
# Submit to L1 ledger
|
| 36 |
+
ledger.submit_result(task_id, sleeping_node_id, result)
|
| 37 |
+
|
| 38 |
+
# 5. Final Balances
|
| 39 |
+
print("\n--- Final Ledger State ---")
|
| 40 |
+
print(f"USA Node: {ledger.get_balance(active_node_id)}s")
|
| 41 |
+
print(f"Asia Node: {ledger.get_balance(sleeping_node_id)}s")
|
| 42 |
+
|
| 43 |
+
if __name__ == "__main__":
|
| 44 |
+
run_simulation()
|