@startuml Core Class Diagram !theme plain skinparam classAttributeIconSize 0 title Orchestrated Discussions - Core Classes package "discussion.py" { class Discussion { +path: Path +title: str +phase: str +status: str +template: str +participant_aliases: list[str] +comments: list[Comment] +created: datetime -_raw_content: str -- +{static} load(path): Discussion +{static} create(path, title, ...): Discussion +save() +add_comment(author, text, vote): Comment +get_context(): str +get_votes(): dict[str, str] +get_questions(): list[Question] +get_action_items(): list[ActionItem] +get_decisions(): list[Decision] +get_concerns(): list[Concern] +get_mentions(target): list[Mention] +check_consensus(config): ConsensusResult +has_consensus(): bool +update_phase(new_phase) +update_status(new_status) +get_content(): str } class Comment { +author: str +body: str +vote: str +questions: list[Question] +action_items: list[ActionItem] +decisions: list[Decision] +concerns: list[Concern] +mentions: list[Mention] } Discussion "1" *-- "*" Comment } package "markers.py" { class Question { +text: str +author: str +status: str = "open" } class ActionItem { +text: str +author: str +assignee: str +status: str = "todo" } class Decision { +text: str +author: str +supporters: list[str] } class Concern { +text: str +author: str +addressed: bool = False } class Diagram { +path: str +author: str } class Mention { +target: str +author: str +context: str } class "<>" as MarkerFunctions { +extract_vote(text): str +extract_questions(text, author): list[Question] +extract_action_items(text, author): list[ActionItem] +extract_decisions(text, author): list[Decision] +extract_concerns(text, author): list[Concern] +extract_diagrams(text, author): list[Diagram] +extract_mentions(text, author): list[Mention] +extract_all_markers(text, author): dict } Comment ..> Question : contains Comment ..> ActionItem : contains Comment ..> Decision : contains Comment ..> Concern : contains Comment ..> Mention : contains } package "voting.py" { class VotingConfig { +threshold_ready: float = 0.67 +threshold_reject: float = 0.01 +human_required: bool = True +minimum_votes: int = 1 } class ConsensusResult { +reached: bool +outcome: str +ready_count: int +changes_count: int +reject_count: int +total_votes: int +blocked_by: list[str] +reason: str } class "<>" as VotingFunctions { +is_human_participant(name): bool +calculate_consensus(votes, config): ConsensusResult +format_vote_summary(votes): str +format_vote_details(votes): str } Discussion ..> VotingConfig : uses Discussion ..> ConsensusResult : returns } package "participant.py" { class Participant { +alias: str +name: str +description: str +participant_type: str +tool_path: Path -- +is_voting(): bool +tool_name(): str } class ParticipantRegistry { -_smarttools_dir: Path -_participants: dict[str, Participant] -_loaded: bool -- +get(alias): Participant +get_all(): list[Participant] +get_voting(): list[Participant] +get_background(): list[Participant] +aliases(): list[str] +refresh() } class "<>" as ParticipantFunctions { +discover_participants(dir): list[Participant] +check_tool_exists(alias): bool +get_registry(): ParticipantRegistry +get_participant(alias): Participant +list_participants(): list[Participant] } ParticipantRegistry "1" *-- "*" Participant } package "runner.py" { class TurnResult { +responses: list[ParticipantResponse] +vote_summary: dict +consensus_reached: bool +consensus_reason: str +status_promoted: bool +new_status: str -- +successful_count: int +failed_count: int +skipped_count: int } class ParticipantResponse { +alias: str +name: str +comment: str +vote: str +success: bool +error: str +raw_output: str } class VariableStore { -_store: dict -- +set(name, value) +get(ref): any +resolve(value): str +resolve_args(args): list[str] +dump(): dict } class "<>" as RunnerFunctions { +run_turn(path, participants, ...): TurnResult +run_pipeline_turn(path, ...): TurnResult +run_discussion_turn(path, ...): TurnResult } TurnResult "1" *-- "*" ParticipantResponse } ' Cross-package relationships Discussion ..> Participant : references by alias @enduml