""" 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)