"""ConsensusEngine — weighted voting and thread resolution for the Hive Mind.""" import uuid from dataclasses import dataclass, field from enum import Enum from typing import Dict, Optional from infj_bot.hive_mind.protocol.dcp import DCPMessage, NodeRole, Resolution class ThreadState(str, Enum): OPEN = "OPEN" RESOLVED = "RESOLVED" @dataclass class ConsensusThread: thread_id: str original_thought: DCPMessage state: ThreadState = ThreadState.OPEN resolution: Optional[DCPMessage] = None votes: Dict[str, str] = field(default_factory=dict) class ConsensusEngine: """In-process consensus engine: propose → vote → resolve.""" def __init__(self): self._threads: Dict[str, ConsensusThread] = {} def propose(self, msg: DCPMessage) -> ConsensusThread: thread_id = str(uuid.uuid4())[:8] thread = ConsensusThread(thread_id=thread_id, original_thought=msg) self._threads[thread_id] = thread return thread def vote(self, thread_id: str, voter_id: str, vote: str) -> None: if thread_id in self._threads: self._threads[thread_id].votes[voter_id] = vote def resolve( self, thread_id: str, resolution: Resolution, final_position: str = "", ) -> None: if thread_id not in self._threads: return thread = self._threads[thread_id] resolution_msg = DCPMessage( source_node="consensus", source_role=NodeRole.PRIMARY, content=final_position, name=resolution.value, payload={ "resolution": resolution.value, "final_position": final_position, "voting_record": dict(thread.votes), }, ) thread.resolution = resolution_msg thread.state = ThreadState.RESOLVED def active_threads(self): return [t for t in self._threads.values() if t.state == ThreadState.OPEN]