replica-omnisciente/scripts/data_sharing/sync.py
Raphael Cautus (Maestro) 2f26f2d836 feat(scripts): onboarding, GWS, lifestream, muscriptor, music, data-sharing
- onboard-client.py: client replica scaffolding CLI
- gws/: Google Workspace sync (Gmail, Calendar, Drive)
- lifestream/: life event stream collector
- muscriptor-mcp/: audio → MIDI MCP server
- music-mcp/: music library MCP server
- data_sharing/: consent-gated data sharing (Python + TS)
- sync-mirrors.py: GitHub → Forgejo mirror engine
- brain-to-gbrain.py, vault-sync.py, test-all.sh
- shared/: TS data-sharing library + index
- dirac: provider registry update
- .gitignore: exclude Rust build artifacts

Co-authored-by: Álvaro de Campos <campos@portugalfuturista.org>
2026-07-31 14:58:02 +01:00

138 lines
4.2 KiB
Python

"""
Sync orchestrator — collect → filter → transmit.
This is the main entry point for the data sharing cycle. It:
1. Loads consent from the workspace config.toml
2. Collects consented data from the local brain
3. Transmits via the configured transport
4. Reports the result
"""
from __future__ import annotations
import json
import sys
from datetime import datetime, timezone
from pathlib import Path
from typing import Any
from .consent import ConsentRecord, load_consent
from .collector import collect
from .transports import get_transport, TransmissionResult
def run_sync(
replica_root: Path | None = None,
config_path: str | Path | None = None,
dry_run: bool = False,
) -> dict[str, Any]:
"""
Execute the full data-sharing cycle.
Args:
replica_root: Path to the replica-omnisciente root. Auto-detected if None.
config_path: Path to config.toml. Auto-detected if None.
dry_run: If True, collect but don't transmit.
Returns:
Summary dict with consent state, collection stats, and transmission result.
"""
if replica_root is None:
# Auto-detect: parent of scripts/ directory
replica_root = Path(__file__).resolve().parents[2]
# 1. Load consent
consent = load_consent(config_path)
if not consent.enabled:
return {
"status": "disabled",
"message": "Data sharing is disabled. Set [data_sharing].enabled = true in config.toml",
"consent": _consent_summary(consent),
}
granted = consent.granted_categories()
if not granted:
return {
"status": "no_consent",
"message": "Data sharing is enabled but no categories are opted in. "
"Enable at least one category in [data_sharing.categories].",
"consent": _consent_summary(consent),
}
# 2. Collect
payload = collect(replica_root, consent)
# 3. Transmit (or preview)
if dry_run:
return {
"status": "dry_run",
"message": f"Would transmit {sum(payload.get('_summary', {}).values())} items "
f"via {consent.transport}",
"consent": _consent_summary(consent),
"payload_preview": {
"schema_version": payload.get("schema_version"),
"categories": payload.get("_summary"),
"payload_size_bytes": len(json.dumps(payload).encode("utf-8")),
},
}
transport = get_transport(consent.transport)
result = transport.transmit(payload, consent)
return {
"status": "success" if result.success else "failed",
"message": result.message,
"consent": _consent_summary(consent),
"transmission": {
"transport": result.transport,
"bytes_sent": result.bytes_sent,
"timestamp": result.timestamp,
},
"items_collected": payload.get("_summary", {}),
}
def _consent_summary(consent: ConsentRecord) -> dict[str, Any]:
"""Summarize consent state for reporting."""
return {
"enabled": consent.enabled,
"transport": consent.transport,
"endpoint": consent.endpoint or "(not set)",
"categories_granted": consent.granted_categories(),
"retention_days": consent.retention_days,
"redact_secrets": consent.redact_secrets,
}
def show_status(
replica_root: Path | None = None,
config_path: str | Path | None = None,
) -> str:
"""
Return a human-readable status string for CLI display.
Shows current consent state and what would be shared.
"""
consent = load_consent(config_path)
lines = [
"=" * 50,
" DATA SHARING STATUS",
"=" * 50,
"",
consent.to_display(),
"",
]
if not consent.enabled:
lines.append("Data sharing is OFF — nothing is sent to Portugal Futurista.")
elif not consent.granted_categories():
lines.append("Data sharing enabled but NO categories opted in.")
lines.append("Nothing will be sent.")
else:
lines.append(f"Ready to share: {', '.join(consent.granted_categories())}")
lines.append(f"via {consent.transport} transport")
lines.append("")
return "\n".join(lines)