guanghu-ice-heart/server-tools/heartbeat-office-building/office_collaboration.py

40 lines
2.2 KiB
Python

#!/usr/bin/env python3
"""Server-gated collaboration board for different humans and their own personas."""
from __future__ import annotations
import argparse
import json
import uuid
from datetime import datetime, timezone
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
CONTRACT = ROOT / "eternal-lake-heart/heartbeat-core/office-building-current/collaboration/MULTI-PERSONA-COLLABORATION-CONTRACT.json"
def load(path): return json.loads(path.read_text(encoding="utf-8"))
def create_board(office_id: str, participants: list[dict], server_endpoint: str | None = None) -> dict:
humans = [item.get("human_id") for item in participants]
personas = [item.get("persona_id") for item in participants]
errors = []
if len(participants) < 2: errors.append("MULTI_PARTICIPANT_REQUIRED")
if len(set(humans)) != len(humans): errors.append("HUMAN_ID_DUPLICATE")
if len(set(personas)) != len(personas): errors.append("SAME_PERSONA_MULTI_HOST_FORBIDDEN")
if len(set(zip(humans, personas))) != len(participants): errors.append("PARTICIPANT_PAIR_DUPLICATE")
if not server_endpoint: errors.append("SERVER_REQUIRED_NOT_CONNECTED")
return {"outcome":"REJECTED" if errors else "BOARD_REQUESTED", "board_id":f"COLLAB-{uuid.uuid4()}", "office_id":office_id, "participants":participants, "server_endpoint":server_endpoint, "errors":errors, "state":"SERVER_REQUIRED_NOT_CONNECTED" if errors and "SERVER_REQUIRED_NOT_CONNECTED" in errors else "REQUESTED", "created_at":datetime.now(timezone.utc).isoformat(), "authority_granted":False}
def connect(board: dict, server_receipt: dict | None = None) -> dict:
if not board.get("server_endpoint") or not server_receipt:
return {"outcome":"BLOCKED", "state":"SERVER_REQUIRED_NOT_CONNECTED", "board_id":board.get("board_id"), "authority_granted":False}
return {"outcome":"CONNECTED", "state":"CONNECTED", "board_id":board.get("board_id"), "server_receipt":server_receipt, "authority_granted":False}
def main():
parser=argparse.ArgumentParser(); parser.add_argument("application", type=Path); args=parser.parse_args(); print(json.dumps(create_board(**load(args.application)),ensure_ascii=False,indent=2))
if __name__ == "__main__": main()