v0.9.6: InfoNet hashchain, Wormhole gate encryption, mesh reputation, 16 community contributors

Gate messages now propagate via the Infonet hashchain as encrypted blobs — every node syncs them
through normal chain sync while only Gate members with MLS keys can decrypt. Added mesh reputation
system, peer push workers, voluntary Wormhole opt-in for node participation, fork recovery,
killwormhole scripts, obfuscated terminology, and hardened the self-updater to protect encryption
keys and chain state during updates.

New features: Shodan search, train tracking, Sentinel Hub imagery, 8 new intelligence layers,
CCTV expansion to 11,000+ cameras across 6 countries, Mesh Terminal CLI, prediction markets,
desktop-shell scaffold, and comprehensive mesh test suite (215 frontend + backend tests passing).

Community contributors: @wa1id, @AlborzNazari, @adust09, @Xpirix, @imqdcr, @csysp, @suranyami,
@chr0n1x, @johan-martensson, @singularfailure, @smithbh, @OrfeoTerkuci, @deuza, @tm-const,
@Elhard1, @ttulttul
This commit is contained in:
anoracleofra-code
2026-03-26 05:58:04 -06:00
parent d363013742
commit 668ce16dc7
363 changed files with 170456 additions and 23229 deletions
@@ -0,0 +1,115 @@
import argparse
import json
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
BACKEND_DIR = ROOT / "backend"
if str(BACKEND_DIR) not in sys.path:
sys.path.insert(0, str(BACKEND_DIR))
from services.mesh.mesh_bootstrap_manifest import ( # noqa: E402
bootstrap_signer_public_key_b64,
generate_bootstrap_signer,
write_signed_bootstrap_manifest,
)
def _load_peers(args: argparse.Namespace) -> list[dict]:
peers: list[dict] = []
if args.peers_file:
raw = json.loads(Path(args.peers_file).read_text(encoding="utf-8"))
if not isinstance(raw, list):
raise ValueError("peers file must be a JSON array")
for entry in raw:
if not isinstance(entry, dict):
raise ValueError("peers file entries must be objects")
peers.append(dict(entry))
for peer_arg in args.peer or []:
parts = [part.strip() for part in str(peer_arg).split(",", 3)]
if len(parts) < 3:
raise ValueError("peer entries must look like url,transport,role[,label]")
peer_url, transport, role = parts[:3]
label = parts[3] if len(parts) > 3 else ""
peers.append(
{
"peer_url": peer_url,
"transport": transport,
"role": role,
"label": label,
}
)
if not peers:
raise ValueError("at least one peer is required")
return peers
def cmd_generate_keypair(_args: argparse.Namespace) -> int:
signer = generate_bootstrap_signer()
print(json.dumps(signer, indent=2))
return 0
def cmd_sign(args: argparse.Namespace) -> int:
peers = _load_peers(args)
manifest = write_signed_bootstrap_manifest(
args.output,
signer_id=args.signer_id,
signer_private_key_b64=args.private_key_b64,
peers=peers,
valid_for_hours=int(args.valid_hours),
)
print(f"Wrote signed bootstrap manifest to {Path(args.output).resolve()}")
print(f"signer_id={manifest.signer_id}")
print(f"valid_until={manifest.valid_until}")
print(f"peer_count={len(manifest.peers)}")
print(f"MESH_BOOTSTRAP_SIGNER_PUBLIC_KEY={bootstrap_signer_public_key_b64(args.private_key_b64)}")
return 0
def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
description="Generate and sign Infonet bootstrap manifests for participant nodes."
)
subparsers = parser.add_subparsers(dest="command", required=True)
keygen = subparsers.add_parser("generate-keypair", help="Generate an Ed25519 bootstrap signer keypair")
keygen.set_defaults(func=cmd_generate_keypair)
sign = subparsers.add_parser("sign", help="Sign a bootstrap manifest from peer entries")
sign.add_argument("--output", required=True, help="Output path for bootstrap_peers.json")
sign.add_argument("--signer-id", required=True, help="Manifest signer identifier")
sign.add_argument(
"--private-key-b64",
required=True,
help="Raw Ed25519 private key in base64 returned by generate-keypair",
)
sign.add_argument(
"--peers-file",
help="JSON file containing an array of peer objects with peer_url, transport, role, and optional label",
)
sign.add_argument(
"--peer",
action="append",
help="Inline peer in the form url,transport,role[,label]. May be repeated.",
)
sign.add_argument(
"--valid-hours",
type=int,
default=168,
help="Manifest validity window in hours (default: 168)",
)
sign.set_defaults(func=cmd_sign)
return parser
def main() -> int:
parser = build_parser()
args = parser.parse_args()
return args.func(args)
if __name__ == "__main__":
raise SystemExit(main())
+5
View File
@@ -0,0 +1,5 @@
param(
[string]$Python = "python"
)
& $Python -c "from services.env_check import validate_env; validate_env(strict=False)"
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
PYTHON="${PYTHON:-python3}"
"$PYTHON" -c "from services.env_check import validate_env; validate_env(strict=False)"
+45
View File
@@ -0,0 +1,45 @@
from datetime import datetime
from services.data_fetcher import get_latest_data
from services.fetchers._store import source_timestamps, active_layers, source_freshness
from services.fetch_health import get_health_snapshot
def _fmt_ts(ts: str | None) -> str:
if not ts:
return "-"
try:
return datetime.fromisoformat(ts).strftime("%Y-%m-%d %H:%M:%S")
except Exception:
return ts
def main():
data = get_latest_data()
print("=== Diagnostics ===")
print(f"Last updated: {_fmt_ts(data.get('last_updated'))}")
print(
f"Active layers: {sum(1 for v in active_layers.values() if v)} enabled / {len(active_layers)} total"
)
print("\n--- Source Timestamps ---")
for k, v in sorted(source_timestamps.items()):
print(f"{k:20} {_fmt_ts(v)}")
print("\n--- Source Freshness ---")
for k, v in sorted(source_freshness.items()):
last_ok = _fmt_ts(v.get("last_ok"))
last_err = _fmt_ts(v.get("last_error"))
print(f"{k:20} ok={last_ok} err={last_err}")
print("\n--- Fetch Health ---")
health = get_health_snapshot()
for k, v in sorted(health.items()):
print(
f"{k:20} ok={v.get('ok_count', 0)} err={v.get('error_count', 0)} "
f"last_ok={_fmt_ts(v.get('last_ok'))} last_err={_fmt_ts(v.get('last_error'))} "
f"avg_ms={v.get('avg_duration_ms')}"
)
if __name__ == "__main__":
main()
+138
View File
@@ -0,0 +1,138 @@
import argparse
import hashlib
import json
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
PACKAGE_JSON = ROOT / "frontend" / "package.json"
def _normalize_version(raw: str) -> str:
version = str(raw or "").strip()
if version.startswith("v"):
version = version[1:]
parts = version.split(".")
if len(parts) != 3 or not all(part.isdigit() for part in parts):
raise ValueError("Version must look like X.Y.Z")
return version
def _read_package_json() -> dict:
return json.loads(PACKAGE_JSON.read_text(encoding="utf-8"))
def _write_package_json(data: dict) -> None:
PACKAGE_JSON.write_text(json.dumps(data, indent=2) + "\n", encoding="utf-8")
def current_version() -> str:
return str(_read_package_json().get("version") or "").strip()
def set_version(version: str) -> str:
normalized = _normalize_version(version)
data = _read_package_json()
data["version"] = normalized
_write_package_json(data)
return normalized
def expected_tag(version: str) -> str:
return f"v{_normalize_version(version)}"
def expected_asset(version: str) -> str:
normalized = _normalize_version(version)
return f"ShadowBroker_v{normalized}.zip"
def sha256_file(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as handle:
for chunk in iter(lambda: handle.read(1024 * 128), b""):
digest.update(chunk)
return digest.hexdigest().lower()
def cmd_show(_args: argparse.Namespace) -> int:
version = current_version()
if not version:
print("package.json has no version", file=sys.stderr)
return 1
print(f"package.json version : {version}")
print(f"expected git tag : {expected_tag(version)}")
print(f"expected zip asset : {expected_asset(version)}")
return 0
def cmd_set_version(args: argparse.Namespace) -> int:
version = set_version(args.version)
print(f"Set frontend/package.json version to {version}")
print(f"Next release tag : {expected_tag(version)}")
print(f"Next zip asset : {expected_asset(version)}")
return 0
def cmd_hash(args: argparse.Namespace) -> int:
version = _normalize_version(args.version) if args.version else current_version()
if not version:
print("No version available; pass --version or set frontend/package.json", file=sys.stderr)
return 1
zip_path = Path(args.zip_path).resolve()
if not zip_path.is_file():
print(f"ZIP not found: {zip_path}", file=sys.stderr)
return 1
digest = sha256_file(zip_path)
expected_name = expected_asset(version)
asset_matches = zip_path.name == expected_name
print(f"release version : {version}")
print(f"expected git tag : {expected_tag(version)}")
print(f"zip path : {zip_path}")
print(f"zip name matches : {'yes' if asset_matches else 'no'}")
print(f"expected zip asset : {expected_name}")
print(f"SHA-256 : {digest}")
print("")
print("Updater pin:")
print(f"MESH_UPDATE_SHA256={digest}")
return 0 if asset_matches else 2
def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
description="Helper for ShadowBroker release version/tag/asset consistency."
)
subparsers = parser.add_subparsers(dest="command", required=True)
show_parser = subparsers.add_parser("show", help="Show current version, expected tag, and asset")
show_parser.set_defaults(func=cmd_show)
set_version_parser = subparsers.add_parser("set-version", help="Update frontend/package.json version")
set_version_parser.add_argument("version", help="Version like 0.9.6")
set_version_parser.set_defaults(func=cmd_set_version)
hash_parser = subparsers.add_parser(
"hash", help="Compute SHA-256 for a release ZIP and print the updater pin"
)
hash_parser.add_argument("zip_path", help="Path to the release ZIP")
hash_parser.add_argument(
"--version",
help="Release version like 0.9.6. Defaults to frontend/package.json version.",
)
hash_parser.set_defaults(func=cmd_hash)
return parser
def main() -> int:
parser = build_parser()
args = parser.parse_args()
return args.func(args)
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,48 @@
from __future__ import annotations
import json
from pathlib import Path
from services.mesh import mesh_secure_storage
from services.mesh.mesh_wormhole_contacts import CONTACTS_FILE
from services.mesh.mesh_wormhole_identity import IDENTITY_FILE, _default_identity
from services.mesh.mesh_wormhole_persona import PERSONA_FILE, _default_state as _default_persona_state
from services.mesh.mesh_wormhole_ratchet import STATE_FILE as RATCHET_FILE
def _load_payloads() -> dict[Path, object]:
return {
IDENTITY_FILE: mesh_secure_storage.read_secure_json(IDENTITY_FILE, _default_identity),
PERSONA_FILE: mesh_secure_storage.read_secure_json(PERSONA_FILE, _default_persona_state),
RATCHET_FILE: mesh_secure_storage.read_secure_json(RATCHET_FILE, lambda: {}),
CONTACTS_FILE: mesh_secure_storage.read_secure_json(CONTACTS_FILE, lambda: {}),
}
def main() -> None:
payloads = _load_payloads()
master_key_file = mesh_secure_storage.MASTER_KEY_FILE
backup_key_file = master_key_file.with_suffix(master_key_file.suffix + ".bak")
if master_key_file.exists():
if backup_key_file.exists():
backup_key_file.unlink()
master_key_file.replace(backup_key_file)
for path, payload in payloads.items():
mesh_secure_storage.write_secure_json(path, payload)
print(
json.dumps(
{
"ok": True,
"rewrapped": [str(path.name) for path in payloads.keys()],
"master_key": str(master_key_file),
"backup_master_key": str(backup_key_file) if backup_key_file.exists() else "",
}
)
)
if __name__ == "__main__":
main()
+121
View File
@@ -0,0 +1,121 @@
#!/usr/bin/env bash
# scan-secrets.sh — Catch keys, secrets, and credentials before they hit git.
#
# Usage:
# ./backend/scripts/scan-secrets.sh # Scan staged files (pre-commit)
# ./backend/scripts/scan-secrets.sh --all # Scan entire working tree
# ./backend/scripts/scan-secrets.sh --staged # Scan staged files only (default)
#
# Exit code: 0 = clean, 1 = secrets found
set -euo pipefail
RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
NC='\033[0m'
MODE="${1:---staged}"
FOUND=0
# ── Get file list based on mode ─────────────────────────────────────────
if [[ "$MODE" == "--all" ]]; then
FILELIST=$(mktemp)
{ git ls-files 2>/dev/null; git ls-files --others --exclude-standard 2>/dev/null; } > "$FILELIST"
echo -e "${YELLOW}Scanning entire working tree...${NC}"
else
FILELIST=$(mktemp)
git diff --cached --name-only --diff-filter=ACMR 2>/dev/null > "$FILELIST" || true
if [[ ! -s "$FILELIST" ]]; then
echo -e "${GREEN}No staged files to scan.${NC}"
rm -f "$FILELIST"
exit 0
fi
echo -e "${YELLOW}Scanning $(wc -l < "$FILELIST" | tr -d ' ') staged files...${NC}"
fi
# ── Check 1: Dangerous file extensions ──────────────────────────────────
KEY_EXT='\.key$|\.pem$|\.p12$|\.pfx$|\.jks$|\.keystore$|\.p8$|\.der$'
SECRET_EXT='\.secret$|\.secrets$|\.credential$|\.credentials$'
HITS=$(grep -iE "$KEY_EXT|$SECRET_EXT" "$FILELIST" 2>/dev/null || true)
if [[ -n "$HITS" ]]; then
echo -e "\n${RED}BLOCKED: Key/secret files detected:${NC}"
echo "$HITS" | while read -r f; do echo -e " ${RED}$f${NC}"; done
FOUND=1
fi
# ── Check 2: Dangerous filenames ────────────────────────────────────────
RISKY='id_rsa|id_ed25519|id_ecdsa|private_key|private\.key|secret_key|master\.key'
RISKY+='|serviceaccount|gcloud.*\.json|firebase.*\.json|\.htpasswd'
HITS=$(grep -iE "$RISKY" "$FILELIST" 2>/dev/null || true)
if [[ -n "$HITS" ]]; then
echo -e "\n${RED}BLOCKED: Risky filenames detected:${NC}"
echo "$HITS" | while read -r f; do echo -e " ${RED}$f${NC}"; done
FOUND=1
fi
# ── Check 3: .env files (not .env.example) ──────────────────────────────
HITS=$(grep -E '(^|/)\.env(\.[^e].*)?$' "$FILELIST" 2>/dev/null | grep -v '\.example' || true)
if [[ -n "$HITS" ]]; then
echo -e "\n${RED}BLOCKED: Environment files detected:${NC}"
echo "$HITS" | while read -r f; do echo -e " ${RED}$f${NC}"; done
FOUND=1
fi
# ── Check 4: _domain_keys directory (project-specific) ──────────────────
HITS=$(grep '_domain_keys/' "$FILELIST" 2>/dev/null || true)
if [[ -n "$HITS" ]]; then
echo -e "\n${RED}BLOCKED: Domain keys directory detected:${NC}"
echo "$HITS" | while read -r f; do echo -e " ${RED}$f${NC}"; done
FOUND=1
fi
# ── Check 5: Content scan for embedded secrets (single grep pass) ───────
# Build one mega-pattern and run grep once across all files (fast!)
SECRET_REGEX='PRIVATE KEY-----|'
SECRET_REGEX+='ssh-rsa AAAA[0-9A-Za-z+/]|'
SECRET_REGEX+='ssh-ed25519 AAAA[0-9A-Za-z+/]|'
SECRET_REGEX+='ghp_[0-9a-zA-Z]{36}|' # GitHub PAT
SECRET_REGEX+='github_pat_[0-9a-zA-Z]{22}_[0-9a-zA-Z]{59}|' # GitHub fine-grained
SECRET_REGEX+='gho_[0-9a-zA-Z]{36}|' # GitHub OAuth
SECRET_REGEX+='sk-[0-9a-zA-Z]{48}|' # OpenAI key
SECRET_REGEX+='sk-ant-[0-9a-zA-Z-]{90,}|' # Anthropic key
SECRET_REGEX+='AKIA[0-9A-Z]{16}|' # AWS access key
SECRET_REGEX+='AIzaSy[0-9A-Za-z_-]{33}|' # Google API key
SECRET_REGEX+='xox[bpoas]-[0-9a-zA-Z-]+|' # Slack token
SECRET_REGEX+='npm_[0-9a-zA-Z]{36}|' # npm token
SECRET_REGEX+='pypi-[0-9a-zA-Z-]{50,}' # PyPI token
# Filter to text-like files only (skip binaries by extension + skip this script)
TEXT_FILES=$(grep -ivE '\.(png|jpg|jpeg|gif|ico|svg|woff2?|ttf|eot|pbf|zip|tar|gz|db|sqlite|xlsx|pdf|mp[34]|wav|ogg|webm|webp|avif)$' "$FILELIST" | grep -v 'scan-secrets\.sh$' || true)
if [[ -n "$TEXT_FILES" ]]; then
# Use grep with file list, skip missing/binary, limit output
CONTENT_HITS=$(echo "$TEXT_FILES" | xargs grep -lE "$SECRET_REGEX" 2>/dev/null || true)
if [[ -n "$CONTENT_HITS" ]]; then
echo -e "\n${RED}BLOCKED: Embedded secrets/tokens found in:${NC}"
echo "$CONTENT_HITS" | while read -r f; do
echo -e " ${RED}$f${NC}"
# Show first matching line for context
grep -nE "$SECRET_REGEX" "$f" 2>/dev/null | head -2 | while read -r line; do
echo -e " ${YELLOW}$line${NC}"
done
done
FOUND=1
fi
fi
rm -f "$FILELIST"
# ── Result ──────────────────────────────────────────────────────────────
echo ""
if [[ $FOUND -eq 1 ]]; then
echo -e "${RED}Secret scan FAILED. Add these to .gitignore or remove them before committing.${NC}"
echo -e "${YELLOW}If intentional (e.g. test fixtures): git commit --no-verify${NC}"
exit 1
else
echo -e "${GREEN}Secret scan passed. No keys or secrets detected.${NC}"
exit 0
fi
+10
View File
@@ -0,0 +1,10 @@
param(
[string]$Python = "python"
)
$repoRoot = Resolve-Path (Join-Path $PSScriptRoot "..")
$venvPath = Join-Path $repoRoot "venv"
& $Python -m venv $venvPath
$pip = Join-Path $venvPath "Scripts\pip.exe"
& $pip install -r (Join-Path $repoRoot "requirements-dev.txt")
+9
View File
@@ -0,0 +1,9 @@
#!/usr/bin/env bash
set -euo pipefail
PYTHON="${PYTHON:-python3}"
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
VENV_DIR="$REPO_ROOT/venv"
"$PYTHON" -m venv "$VENV_DIR"
"$VENV_DIR/bin/pip" install -r "$REPO_ROOT/requirements-dev.txt"