Skip to content

Commit cbefcb6

Browse files
Add system kernel, networking, security, web design system, configs
- system/events: append-only event store with replay - system/kernel: process manager with restart policies - system/networking: WireGuard mesh config, PowerDNS management - system/permissions: RBAC with agent tiers - system/security: secret scanner, port scanner, full audit - system/storage: backup manager with rotation and verification - web/brand: complete CSS design system (150+ vars), React components - web/dashboard: real-time fleet dashboard with WebSocket - config/routing: full domain→service routing map - config/policies: security policies (rate limits, CORS, CSP) - config/secrets: secrets template Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> RoadChain-SHA2048: 50c4646d738cf64e RoadChain-Identity: alexa@sovereign RoadChain-Full: 50c4646d738cf64ea5c7767e510866e87ab4ffdc7cd74e533e985c3c1adec728e65d3ce154340a0d17650e8949993fef8ce4716c28ffbcd72a958aeac21b86cb312831a5ba29656546cc81a4c82b395ee7b71d9cf7dd6e263a3576fe07d3724230e64da7a800348a6a8f07c8abbaab252e1e90e672dc5f4f43ffd36cd3072da887321e69620390e6b28e5c1d6def60be6d7b1bb5465601561651700f65604090d931902a3150270f80ba8dfad8aa6a30763d2265d4e1677003e995a6cfb0ee13796975e9523092399985d6d914888e60830fe77ee406b6c22fde3a0b6ba6eff4dd9ab9abde26b06743f40c2224c46bb0828eb1089d282cb9a1ad80b11a39177b
1 parent 46540cc commit cbefcb6

13 files changed

Lines changed: 1067 additions & 0 deletions

File tree

config/policies/security.yaml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Security policies
2+
rate_limiting:
3+
default: 100/minute
4+
api: 60/minute
5+
auth: 10/minute
6+
search: 30/minute
7+
8+
cors:
9+
allowed_origins:
10+
- "https://blackroad.io"
11+
- "https://*.blackroad.io"
12+
- "https://blackroadai.com"
13+
- "https://lucidia.earth"
14+
allowed_methods: [GET, POST, PUT, DELETE, OPTIONS]
15+
allowed_headers: [Content-Type, Authorization, X-Agent-ID]
16+
max_age: 86400
17+
18+
csp:
19+
default-src: "'self'"
20+
script-src: "'self' 'unsafe-inline'"
21+
style-src: "'self' 'unsafe-inline' https://fonts.googleapis.com"
22+
font-src: "'self' https://fonts.gstatic.com"
23+
img-src: "'self' https://images.blackroad.io data:"
24+
connect-src: "'self' https://*.blackroad.io wss://*.blackroad.io"
25+
26+
headers:
27+
X-Frame-Options: DENY
28+
X-Content-Type-Options: nosniff
29+
Referrer-Policy: strict-origin-when-cross-origin
30+
Permissions-Policy: camera=(), microphone=(self), geolocation=()
31+
32+
tls:
33+
min_version: "1.2"
34+
hsts: true
35+
hsts_max_age: 31536000

config/routing/routes.yaml

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# BlackRoad domain routing configuration
2+
routes:
3+
# Root domains
4+
- domain: blackroad.io
5+
backend: gateway
6+
target: 192.168.4.49:80
7+
features: [ssl, cache, compress]
8+
9+
- domain: blackroad.company
10+
backend: pages
11+
target: blackroad-company.pages.dev
12+
13+
- domain: blackroadai.com
14+
backend: pages
15+
target: blackroadai.pages.dev
16+
17+
- domain: blackroadinc.us
18+
backend: pages
19+
target: blackroadinc-us.pages.dev
20+
21+
# Product subdomains (blackroad.io)
22+
- domain: chat.blackroad.io
23+
backend: worker
24+
target: chat-blackroad.workers.dev
25+
service: roundtrip-chat
26+
27+
- domain: search.blackroad.io
28+
backend: worker
29+
target: road-search.workers.dev
30+
service: road-search
31+
32+
- domain: pay.blackroad.io
33+
backend: worker
34+
target: pay-blackroad.workers.dev
35+
service: stripe-payments
36+
37+
- domain: auth.blackroad.io
38+
backend: worker
39+
target: auth-blackroad.workers.dev
40+
service: authentication
41+
42+
- domain: social.blackroad.io
43+
backend: worker
44+
target: backroad-social.workers.dev
45+
service: backroad
46+
47+
- domain: api.blackroad.io
48+
backend: gateway
49+
target: 192.168.4.49:8000
50+
features: [ssl, rate-limit, cors]
51+
52+
- domain: roundtrip.blackroad.io
53+
backend: worker
54+
target: roundtrip-blackroad.workers.dev
55+
56+
- domain: images.blackroad.io
57+
backend: r2
58+
bucket: blackroad-assets
59+
60+
- domain: hq.blackroad.io
61+
backend: worker
62+
target: hq-blackroad.workers.dev
63+
64+
# Lucidia domains
65+
- domain: lucidia.earth
66+
backend: pages
67+
target: lucidia-earth.pages.dev
68+
69+
- domain: lucidia.studio
70+
redirect: lucidia.earth
71+
72+
# Blockchain
73+
- domain: roadchain.io
74+
backend: pages
75+
target: roadchain-io.pages.dev
76+
77+
- domain: roadcoin.io
78+
backend: pages
79+
target: roadcoin-io.pages.dev
80+
81+
load_balancer:
82+
strategy: least-connections
83+
health_check_interval: 30
84+
backends:
85+
- name: alice
86+
url: http://192.168.4.49
87+
weight: 2
88+
- name: gematria
89+
url: http://67.205.0.0
90+
weight: 3
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# BlackRoad Secrets Template — NEVER commit actual values
2+
# Copy to .env and fill in real values
3+
4+
# Cloudflare
5+
CF_API_TOKEN=
6+
CF_ACCOUNT_ID=
7+
CF_ZONE_ID_BLACKROAD_IO=
8+
9+
# Stripe
10+
STRIPE_SECRET_KEY=
11+
STRIPE_PUBLISHABLE_KEY=
12+
STRIPE_WEBHOOK_SECRET=
13+
14+
# Database
15+
DATABASE_URL=sqlite:///data/roadcode.db
16+
POSTGRESQL_URL=postgresql://blackroad:@192.168.4.49:5432/roadcode
17+
18+
# Redis
19+
REDIS_URL=redis://192.168.4.49:6379
20+
21+
# MinIO / S3
22+
MINIO_ENDPOINT=http://192.168.4.96:9000
23+
MINIO_ACCESS_KEY=
24+
MINIO_SECRET_KEY=
25+
26+
# Ollama
27+
OLLAMA_PRIMARY=http://192.168.4.96:11434
28+
OLLAMA_FALLBACK=http://192.168.4.38:11434
29+
30+
# Qdrant
31+
QDRANT_URL=http://192.168.4.49:6333
32+
33+
# GitHub
34+
GITHUB_TOKEN=
35+
GITHUB_ORG=BlackRoad-OS-Inc
36+
37+
# Auth
38+
JWT_SECRET=
39+
SESSION_SECRET=
40+
41+
# NATS
42+
NATS_URL=nats://192.168.4.101:4222
43+
44+
# WireGuard
45+
WG_PRIVATE_KEY=
46+
WG_ENDPOINT=
47+
48+
# Gitea
49+
GITEA_URL=http://192.168.4.101:3100
50+
GITEA_TOKEN=

system/events/event_store.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
"""Append-only event store with replay capability."""
2+
from __future__ import annotations
3+
import json
4+
import sqlite3
5+
import time
6+
from dataclasses import dataclass
7+
from pathlib import Path
8+
from typing import Any
9+
10+
@dataclass
11+
class StoredEvent:
12+
id: int
13+
stream: str
14+
event_type: str
15+
data: dict[str, Any]
16+
timestamp: float
17+
version: int
18+
19+
class EventStore:
20+
def __init__(self, db_path: str = "data/events.db"):
21+
Path(db_path).parent.mkdir(parents=True, exist_ok=True)
22+
self.conn = sqlite3.connect(db_path)
23+
self.conn.executescript("""
24+
CREATE TABLE IF NOT EXISTS events (
25+
id INTEGER PRIMARY KEY AUTOINCREMENT,
26+
stream TEXT NOT NULL,
27+
event_type TEXT NOT NULL,
28+
data TEXT NOT NULL,
29+
timestamp REAL NOT NULL,
30+
version INTEGER NOT NULL DEFAULT 1
31+
);
32+
CREATE INDEX IF NOT EXISTS idx_stream ON events(stream);
33+
CREATE INDEX IF NOT EXISTS idx_type ON events(event_type);
34+
CREATE INDEX IF NOT EXISTS idx_ts ON events(timestamp);
35+
""")
36+
37+
def append(self, stream: str, event_type: str, data: dict) -> StoredEvent:
38+
version = self._next_version(stream)
39+
now = time.time()
40+
cur = self.conn.execute(
41+
"INSERT INTO events (stream, event_type, data, timestamp, version) VALUES (?,?,?,?,?)",
42+
(stream, event_type, json.dumps(data), now, version),
43+
)
44+
self.conn.commit()
45+
return StoredEvent(cur.lastrowid, stream, event_type, data, now, version)
46+
47+
def _next_version(self, stream: str) -> int:
48+
row = self.conn.execute("SELECT MAX(version) FROM events WHERE stream = ?", (stream,)).fetchone()
49+
return (row[0] or 0) + 1
50+
51+
def replay(self, stream: str, from_version: int = 0) -> list[StoredEvent]:
52+
rows = self.conn.execute(
53+
"SELECT id, stream, event_type, data, timestamp, version FROM events WHERE stream = ? AND version > ? ORDER BY version",
54+
(stream, from_version),
55+
).fetchall()
56+
return [StoredEvent(r[0], r[1], r[2], json.loads(r[3]), r[4], r[5]) for r in rows]
57+
58+
def query(self, event_type: str | None = None, since: float = 0, limit: int = 100) -> list[StoredEvent]:
59+
if event_type:
60+
rows = self.conn.execute(
61+
"SELECT id, stream, event_type, data, timestamp, version FROM events WHERE event_type = ? AND timestamp > ? ORDER BY timestamp DESC LIMIT ?",
62+
(event_type, since, limit),
63+
).fetchall()
64+
else:
65+
rows = self.conn.execute(
66+
"SELECT id, stream, event_type, data, timestamp, version FROM events WHERE timestamp > ? ORDER BY timestamp DESC LIMIT ?",
67+
(since, limit),
68+
).fetchall()
69+
return [StoredEvent(r[0], r[1], r[2], json.loads(r[3]), r[4], r[5]) for r in rows]
70+
71+
def streams(self) -> list[str]:
72+
return [r[0] for r in self.conn.execute("SELECT DISTINCT stream FROM events").fetchall()]
73+
74+
def count(self, stream: str | None = None) -> int:
75+
if stream:
76+
return self.conn.execute("SELECT COUNT(*) FROM events WHERE stream = ?", (stream,)).fetchone()[0]
77+
return self.conn.execute("SELECT COUNT(*) FROM events").fetchone()[0]

system/kernel/process_manager.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
"""Process manager — manages system processes with restart policies."""
2+
from __future__ import annotations
3+
import asyncio
4+
import time
5+
from dataclasses import dataclass, field
6+
from enum import Enum
7+
from typing import Optional
8+
9+
class RestartPolicy(Enum):
10+
NEVER = "never"
11+
ON_FAILURE = "on-failure"
12+
ALWAYS = "always"
13+
14+
class ProcessState(Enum):
15+
STOPPED = "stopped"
16+
STARTING = "starting"
17+
RUNNING = "running"
18+
FAILED = "failed"
19+
20+
@dataclass
21+
class ManagedProcess:
22+
name: str
23+
command: str
24+
restart_policy: RestartPolicy = RestartPolicy.ON_FAILURE
25+
state: ProcessState = ProcessState.STOPPED
26+
pid: Optional[int] = None
27+
started_at: float = 0
28+
restart_count: int = 0
29+
max_restarts: int = 5
30+
last_exit_code: int = 0
31+
32+
@property
33+
def uptime(self) -> float:
34+
return time.time() - self.started_at if self.state == ProcessState.RUNNING else 0
35+
36+
class ProcessManager:
37+
def __init__(self):
38+
self.processes: dict[str, ManagedProcess] = {}
39+
self._tasks: dict[str, asyncio.Task] = {}
40+
41+
def register(self, name: str, command: str, restart: RestartPolicy = RestartPolicy.ON_FAILURE) -> ManagedProcess:
42+
proc = ManagedProcess(name=name, command=command, restart_policy=restart)
43+
self.processes[name] = proc
44+
return proc
45+
46+
async def start(self, name: str) -> bool:
47+
proc = self.processes.get(name)
48+
if not proc or proc.state == ProcessState.RUNNING:
49+
return False
50+
proc.state = ProcessState.STARTING
51+
self._tasks[name] = asyncio.create_task(self._supervise(proc))
52+
return True
53+
54+
async def stop(self, name: str) -> bool:
55+
proc = self.processes.get(name)
56+
if not proc:
57+
return False
58+
proc.state = ProcessState.STOPPED
59+
task = self._tasks.pop(name, None)
60+
if task:
61+
task.cancel()
62+
return True
63+
64+
async def _supervise(self, proc: ManagedProcess) -> None:
65+
while proc.state != ProcessState.STOPPED:
66+
proc.state = ProcessState.RUNNING
67+
proc.started_at = time.time()
68+
try:
69+
p = await asyncio.create_subprocess_shell(proc.command)
70+
proc.pid = p.pid
71+
proc.last_exit_code = await p.wait()
72+
except Exception:
73+
proc.last_exit_code = 1
74+
if proc.state == ProcessState.STOPPED:
75+
break
76+
proc.state = ProcessState.FAILED
77+
should_restart = (
78+
proc.restart_policy == RestartPolicy.ALWAYS or
79+
(proc.restart_policy == RestartPolicy.ON_FAILURE and proc.last_exit_code != 0)
80+
)
81+
if should_restart and proc.restart_count < proc.max_restarts:
82+
proc.restart_count += 1
83+
await asyncio.sleep(min(30, 2 ** proc.restart_count))
84+
else:
85+
break
86+
87+
def status(self) -> list[dict]:
88+
return [{"name": p.name, "state": p.state.value, "pid": p.pid,
89+
"uptime": round(p.uptime), "restarts": p.restart_count} for p in self.processes.values()]

0 commit comments

Comments
 (0)