
    `gj$              
      H   d Z ddlmZ ddlmZmZ ddlZddlZddlm	Z	m
Z
mZ ddlmZ dZ ed	       G d
 d             Z ed	       G d d             ZddZddZdddddddddd		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ	 	 	 	 	 	 	 	 	 	 	 	 ddZddZddZy)u  Kanban Swarm v1: thin swarm topology helpers on top of Kanban.

This module intentionally does not introduce a second scheduler. It writes a
small task graph into the existing Kanban kernel:

    planning root (completed immediately)
        ├─ parallel specialist workers (ready)
        └─ verifier (todo until all workers done)
             └─ synthesizer (todo until verifier done)

The shared blackboard is also deliberately low-tech: structured JSON comments on
the root task. That keeps all state in existing task_comments/task_events rows,
so the dashboard, notifier, slash command, and dispatcher keep working without a
new service.
    )annotations)	dataclassfieldN)AnyIterableOptional)	kanban_dbz[swarm:blackboard] T)frozenc                  h    e Zd ZU dZded<   ded<   ded<    ee      Zded<   d	Zd
ed<   dZ	ded<   y)SwarmWorkerSpecz)A single parallel worker card in a swarm.strprofiletitlebody)default_factory	list[str]skillsr   intpriorityNzOptional[int]max_runtime_seconds)
__name__
__module____qualname____doc____annotations__r   listr   r   r        J/root/.hermes/venv/lib/python3.12/site-packages/hermes_cli/kanban_swarm.pyr   r      s8    3LJ
Id3FI3Hc)--r   r   c                  B    e Zd ZU dZded<   ded<   ded<   ded<   d
dZy	)SwarmCreatedz%IDs produced by :func:`create_swarm`.r   root_idr   
worker_idsverifier_idsynthesizer_idc                r    | j                   t        | j                        | j                  | j                  dS )Nr"   r#   r$   r%   )r"   r   r#   r$   r%   )selfs    r   as_dictzSwarmCreated.as_dict2   s1    ||t/++"11	
 	
r   N)returndict[str, Any])r   r   r   r   r   r)   r   r   r   r!   r!   )   s!    /L
r   r!   c                N    | xs dj                         }|st        | d      |S )N z is required)strip
ValueError)value
field_nametexts      r   _require_textr3   ;   s.    KR DJ<|455Kr   c                0    d|  d|j                          dS )Nz7

## Swarm protocol
- Swarm root / shared blackboard: `z`.
- Read sibling/parent handoffs from Kanban context before working.
- Put machine-readable facts in completion metadata.
- Put cross-worker notes on the root task using structured comments.
- Goal: 
)r.   )r"   goals     r   _swarm_contextr7   B   s*    	..5Y 7 ::<.	$r   zVerify swarm outputszSynthesize swarm outputszswarm-orchestratorscratch)	
root_titleverifier_titlesynthesizer_titletenant
created_byworkspace_kindworkspace_pathr   idempotency_keyc               @   t        |d      }t        |d      }t        |d      }t        |      }|st        d      t        |d      D ]9  \  }}t        |j                  d| d       t        |j
                  d| d	       ; t        j                  | |xs d
|j                         d   dd  d| |	|	||||
|
      }t        | |      j                  d      }t        |t              rt|j                  dg       D cg c]  }|st        |       }}|j                  d      }|j                  d      }|r%|r#|r!t        ||t        |      t        |            S t        j                  | |dd|t!        |      d       t#        ||      }g }|D ]  }t        j                  | |j
                  |j$                  xs d|z   |j                  |	|g||j&                  xs ||
||j(                  xs d|j*                        }|j-                  |        d|z   }t        j                  | ||||	||||
|dg      }d|z   }t        j                  | ||||	|g|||
|dg      }t        ||||      }t/        | ||	d|j1                         d|iz          |S c c}w )!a  Create a durable Kanban swarm graph.

    The returned graph is immediately dispatchable: the planning root is marked
    ``done`` with topology metadata, parallel workers are ``ready``, the verifier
    waits for every worker, and the synthesizer waits for the verifier.
    r6   verifier_assigneesynthesizer_assigneezat least one worker is required   )startzworkers[z	].profilez].titlezSwarm: r   NP   zKanban Swarm v1 planning/root card. This card is completed immediately so parallel workers can start while it remains the shared blackboard and audit anchor.

Goal:
)	r   r   assigneer=   r<   r   r@   r>   r?   topologyr#   r$   r%   r'   z;Swarm topology planned; root remains the shared blackboard.kanban_swarm_v1)kindr6   worker_count)summarymetadatar-   )r   r   rG   r=   parentsr<   r   r>   r?   r   r   zReview every worker handoff and blackboard update. Gate the swarm: complete only with metadata {"gate": "pass"} when evidence is sufficient; otherwise block with exact missing work.zrequesting-code-review)
r   r   rG   r=   rN   r<   r   r>   r?   r   zwSynthesize the verified worker outputs into the final deliverable. Do not start until the verifier has passed the gate.	humanizer)authorkeyr0   )r3   r   r/   	enumerater   r   kbcreate_task
splitlineslatest_blackboardget
isinstancedictr   r!   complete_tasklenr7   r   r   r   r   appendpost_blackboard_updater)   )connr6   workersrB   rC   r9   r:   r;   r<   r=   r>   r?   r   r@   worker_specsispecrootexistingxr#   r$   r%   context_suffix	worker_idverifier_bodyverifiersynthesizer_bodysynthesizercreateds                                 r   create_swarmrm   M   s   0 v&D%&79LM()=?UV=L:;;\3 94dllhqc$;<djjHQCw"789 >>Agdoo&7&:3B&?%@A V
 '%%D* !t,00<H(D!&.ll<&DJc!fJ
Jll=1!&67+.%,">2	  M%-
		 $D$/NJ %NN**))/r^3\\!F]].h));;&$ $ 8 8
	 	)$%$	? 	  ~~"%%()H	?
	 
 ..%
%%}K 4X{CGoo64.0 Nq Ks   J
Jc                   t        |d       t        |d      }t        |d      }t        j                  ||ddd      }t        j                  | ||t
        |z         S )	z:Append one structured update to the swarm root blackboard.r"   rP   rQ   )rQ   r0   FT)ensure_ascii	sort_keys)rP   r   )r3   jsondumpsrS   add_commentBLACKBOARD_PREFIX)r^   r"   rP   rQ   r0   payloads         r   r]   r]      sZ     '9%68,F
U
#Cjju5EUYZG>>$=NQX=XYYr   c                   i }i }t        j                  | |      D ]  }|j                  xs d}|j                  t              s)	 t        j                  |t        t              d       }|j                  d      }t        |t              r|ss|j                  d      ||<   |j                  ||<    |r||d<   |S # t
        j                  $ r Y w xY w)zMerge structured blackboard comments on a root card.

    Later comments replace earlier values for the same key. ``_authors`` records
    the author of the winning value for traceability.
    r-   NrQ   r0   _authors)rS   list_commentsr   
startswithrt   rq   loadsr[   JSONDecodeErrorrW   rX   r   rP   )r^   r"   mergedauthorscommentr   ru   rQ   s           r   rV   rV      s      F G##D'2 &||!r01	jjc*;&<&=!>?G kk% #s#3kk'*s~~& $zM ## 		s   %B<<CCc                |   | j                  dd      D cg c]  }|j                          }}t        |      dk  rt        d      g }t        |      dk(  rE|d   r@|d   j                  d      D cg c]#  }|j                         s|j                         % }}t	        |d   |d   |d   |      S c c}w c c}w )	z:Parse CLI ``--worker profile:title[:skill,skill]`` values.:   z9worker must be profile:title or profile:title:skill,skill   ,r   rD   )r   r   r   r   )splitr.   r[   r/   r   )rawppartsr   ss        r   parse_worker_argr     s     !$		#q 121QWWY2E2
5zA~TUUF
5zQ58%*1X^^C%8FAGGI!'')FF5858%(SYZZ 3
 Gs   B42B9B9)r0   r   r1   r   r*   r   )r"   r   r6   r   r*   r   )r^   sqlite3.Connectionr6   r   r_   zIterable[SwarmWorkerSpec]rB   r   rC   r   r9   Optional[str]r:   r   r;   r   r<   r   r=   r   r>   r   r?   r   r   r   r@   r   r*   r!   )r^   r   r"   r   rP   r   rQ   r   r0   r   r*   r   )r^   r   r"   r   r*   r+   )r   r   r*   r   )r   
__future__r   dataclassesr   r   rq   sqlite3typingr   r   r   
hermes_clir	   rS   rt   r   r!   r3   r7   rm   r]   rV   r   r   r   r   <module>r      s    # (   * * &)  $. . . $
 
 
"$ !%07 *#$(%)Q
Q Q '	Q
 Q Q Q Q Q Q Q Q "Q Q #Q  !QhZ
ZZ 	Z
 
Z Z 	Z"6	[r   