+
    jHàj%,  ã                  óF  € R t ^ RIHt ^ RIHtHtHt ^ RIt^ RIt^ RI	t	^ RI
HtHtHt ^ RIHt Rt]! RR7       ! R	 R
4      4       t]! RR7       ! R R4      4       tR R ltR R ltR R ltRRRRRRRRRRRRRRR^ RR/	R R  lltR! R" ltR# R$ ltR% R& ltR' R( ltR# ))uQ  Kanban Swarm v1: thin swarm topology helpers on top of Kanban.

Deliberately no second scheduler â€” a small task graph written 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 structured JSON comments on the root task, so all
state lives in existing task_comments/task_events rows and the dashboard,
notifier, slash command and dispatcher keep working without a new service.
)Úannotations)ÚasdictÚ	dataclassÚfieldN)ÚAnyÚIterableÚOptional)Ú	kanban_dbz[swarm:blackboard] T)Úfrozenc                  ór   € ] tR t^t$ RtR]R&   R]R&   R]R&   ]! ]R7      tR]R&   ^ t	R	]R
&   Rt
R]R&   RtR# )ÚSwarmWorkerSpecz)A single parallel worker card in a swarm.ÚstrÚprofileÚtitleÚbody)Údefault_factoryú	list[str]ÚskillsÚintÚpriorityNzOptional[int]Úmax_runtime_seconds© )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__annotations__r   Úlistr   r   r   Ú__static_attributes__r   ó    Ú</home/ubuntu/.hermes/hermes-agent/hermes_cli/kanban_swarm.pyr   r      s8   ‡ á3àƒLØƒJØ
ƒIÙ¨dÔ3€FˆIÓ3Ø€HˆcÓØ)-Ð˜×-r    r   c                  óP   € ] tR t^)t$ RtR]R&   R]R&   R]R&   R]R&   R R	 ltR
tR# )ÚSwarmCreatedz%IDs produced by :func:`create_swarm`.r   Úroot_idr   Ú
worker_idsÚverifier_idÚsynthesizer_idc               ó   € V ^8„  d   QhRR/# )é   Úreturnúdict[str, Any]r   )Úformats   "r!   Ú__annotate__ÚSwarmCreated.__annotate__2   s   € ÷ ñ ˜ñ r    c                	ó   € \        V 4      # )N)r   )Úselfs   &r!   Úas_dictÚSwarmCreated.as_dict2   s   € Ü�d‹|Ðr    r   N)r   r   r   r   r   r   r1   r   r   r    r!   r#   r#   )   s&   ‡ á/àƒLØÓØÓØÓ÷ñ r    r#   c               ó$   € V ^8„  d   QhRRRRRR/# )r)   Úvaluer   Ú
field_namer*   r   )r,   s   "r!   r-   r-   6   s!   € ÷ ñ ˜ð ¨#ð °#ñ r    c                óf   € T ;'       g    R P                  4       pV'       g   \        V R24      hV# )Ú z is required)ÚstripÚ
ValueError)r4   r5   Útexts   && r!   Ú_require_textr;   6   s0   € Ø�KˆK�R×ÑÓ €DßÜ˜J˜< |Ð4Ó5Ð5Ø€Kr    c               ó$   € V ^8„  d   QhRRRRRR/# )r)   r$   r   Úgoalr*   r   )r,   s   "r!   r-   r-   =   s!   € ÷ ñ ˜Cð  sð ¨sñ r    c                ó0   € R V  RVP                  4        R2# )z7

## 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: Ú
)r8   )r$   r=   s   &&r!   Ú_swarm_contextr@   =   s(   € à
DÀWÀIð N)ð *.¯©«¨°bð	:ðr    c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r)   Úconnúsqlite3.Connectionr$   r   ÚsummaryÚmetadatar+   r*   Úboolr   )r,   s   "r!   r-   r-   F   s:   € ÷ !ñ !Ø
ð!àð!ð ð	!ð
 ð!ð 
ñ!r    c          
     ó  € V P                  R\        \        P                  ! 4       4      V34      pVP                  ^8w  d   R# \        P
                  ! WRW#R7      p\        P                  ! YRR^ RVR,          ;'       g    R/VR	7       R
# )u3  Inline blockedâ†’done CAS flip + event insert for the swarm root.

Runs INSIDE create_swarm's write_txn, so it must not call
``kb.complete_task`` (own transaction + post-commit side effects that
would run while the outer txn can still roll back). The caller runs
``recompute_ready`` after the outer commit.
a  
        UPDATE tasks
           SET status       = 'done',
               completed_at = ?,
               claim_lock   = NULL,
               claim_expires= NULL,
               worker_pid   = NULL
         WHERE id = ?
           AND status = 'blocked'
        FÚ	completed)ÚoutcomerD   rE   Ú
result_lenrD   :Ni�  NN)Úrun_idT)Úexecuter   ÚtimeÚrowcountÚkbÚ_synthesize_ended_runÚ_append_event)rB   r$   rD   rE   ÚcurrK   s   &&$$  r!   Ú_activate_root_inlinerS   F   s…   € ð �,‰,ð		ô 
ŒT�YŠY‹[Ó	˜7Ð#ó€Cð ‡|�|�qÔÙÜ×%Ò% d¸[ÐRYÔm€FÜ×ÒØ�{ \°1°iÀÈÅ×AVÐAVÐRVÐ$WÐ`fõñ r    Ú
root_titleÚverifier_titlezVerify swarm outputsÚsynthesizer_titlezSynthesize swarm outputsÚtenantÚ
created_byzswarm-orchestratorÚworkspace_kindÚworkspace_pathr   Úidempotency_keyc               óT   € V ^8„  d   QhRRRRRRRRRRR	R
RRRRRR
RRRR
RR
RRRR
RR/# ©r)   rB   rC   r=   r   ÚworkerszIterable[SwarmWorkerSpec]Úverifier_assigneeÚsynthesizer_assigneerT   zOptional[str]rU   rV   rW   rX   rY   rZ   r   r   r[   r*   r#   r   )r,   s   "r!   r-   r-   j   s    € ÷ 8ñ 8Ø
ð8ð ð8ð 'ð	8ð
 ð8ð ð8ð ð8ð ð8ð ð8ð ð8ð ð8ð "ð8ð "ð8ð ð8ð #ð8ð  ñ!8r    c               ó<  € RpRp\         P                  ! V 4      ;_uu_ 4        \        WW#WEWgVWšVWÍR7      p\         P                  ! V VP                  4      pVee   VP
                  R8X  dT   \        V VP                  VRRRVP                  4       R	\        VP                  4      /R
7      '       g   \        R4      hRpRRR4       V'       dº   \         P                  ! V 4       \         P                  ! V XP                  4      p\         P                  ! V VP                  4      p\         P                  ! RVP                  \         P                  ! 4       V'       d   VP                  MRV'       d   VP                   MRVR7       X#   + '       g   i     LÓ; i)zCAtomically create a durable, immediately dispatchable Kanban swarm.z;Swarm topology planned; root remains the shared blackboard.F)r=   r^   r_   r`   rT   rU   rV   rW   rX   rY   rZ   r   r[   NÚblockedÚkindÚkanban_swarm_v1r=   Úworker_count)rD   rE   z/could not activate the completed swarm topologyTÚkanban_task_completed)ÚboardÚassigneerK   rD   )rO   Ú	write_txnÚ_create_swarm_uncommittedÚget_taskr$   ÚstatusrS   r8   Úlenr%   ÚRuntimeErrorÚrecompute_readyÚ
latest_runÚ_fire_kanban_lifecycle_hookÚget_current_boardrh   Úid)rB   r=   r^   r_   r`   rT   rU   rV   rW   rX   rY   rZ   r   r[   Úactivation_summaryÚ	activatedÚcreatedÚrootÚruns   &$$$$$$$$$$$$$     r!   Úcreate_swarmry   j   sJ  € ð$ WÐØ€IÜ	�Š�d×	Õ	Ü+Ø WØ!5Ø)ÐW]Ø!ÐQ_Øô
ˆô �{Š{˜4 §¡Ó1ˆØÒ §¡¨yÔ 8Ü(ØØ—‘Ø*àÐ-Ø˜DŸJ™J›LØ"¤C¨×(:Ñ(:Ó$;ð÷		ó 	ô #Ð#TÓUÐUØˆI÷+ 
÷, ô 	×Ò˜4Ô Ü�{Š{˜4 §¡Ó1ˆÜ�mŠm˜D '§/¡/Ó2ˆÜ
×&Ò&Ø#Ø�O‰OÜ×&Ò&Ó(ß&*�T—]’]°ß �3—6’6 dØ&õ	
ð €N÷I 
×	ús   £BFÆF	c               óT   € V ^8„  d   QhRRRRRRRRRRR	R
RRRRRR
RRRR
RR
RRRR
RR/# r]   r   )r,   s   "r!   r-   r-   ¥   s¯   € ÷ ]ñ ]Ø
ð]Ø'*ð]Ø5Nð]àð]à25ð]àCPð]ð ð]ð -0ð]ð :Gð]ð UXð]ð "ð	]ð 4Að	]ð MPð	]ð cpð	]ð
 ñ]r    c               óÆ  € \        VR4      p\        VR4      p\        VR4      p\        V4      pV'       g   \        R4      h\        V^R7       F:  w  pp\        VP                  RV R24       \        VP
                  RV R24       K<  	  \        W˜W«R	7      p\        P                  ! V 3R
T;'       g"    RVP                  4       ^ ,          R,           2RRV 2RV	RVRVRR/VB p\        V V4      P                  R4      p\        V\        4      '       d�   VP                  R. 4       Uu. uF  pV'       g   K  \        V4      NK  	  ppVP                  R4      pVP                  R4      pV'       d1   V'       d)   V'       d!   \        VV\        V4      \        V4      4      # \        VV4      pV Uu. uFŠ  p\        P                  ! V 3R
VP
                  RVP                   ;'       g    RV,           RVP                  RV.RVP"                  ;'       g    TRVP$                  ;'       g    RRVP&                  /VB NKŒ  	  pp\        P                  ! V 3R
VRRV,           RVRVRVRR./VB p\        P                  ! V 3R
VRRV,           RVRV.RVRR ./VB p\        VVVV4      p\)        V VV	RVP+                  4       RV/,          R!7       V# u upi u upi )"zÓCreate the swarm graph inside the caller's transaction: planning root
(``blocked`` until the caller activates it), parallel workers, a verifier
waiting on every worker, and a synthesizer waiting on the verifier.r=   r_   r`   zat least one worker is required)Ústartzworkers[z	].profilez].title)rX   rW   rY   rZ   r   zSwarm: :NéP   Nr   z¥Kanban 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:
rh   r   r[   Úinitial_statusrb   Útopologyr%   r&   r'   r7   Úparentsr   Nr   zµReview 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-reviewzwSynthesize the verified worker outputs into the final deliverable. Do not start until the verifier has passed the gate.Ú	humanizer)ÚauthorÚkeyr4   )r;   r   r9   Ú	enumerater   r   ÚdictrO   Úcreate_taskÚ
splitlinesÚlatest_blackboardÚgetÚ
isinstancer   r#   r@   r   r   r   r   Úpost_blackboard_updater1   )rB   r=   r^   r_   r`   rT   rU   rV   rW   rX   rY   rZ   r   r[   Úworker_specsÚiÚspecÚcommonrw   ÚexistingÚxr%   r&   r'   Úcontext_suffixÚverifierÚsynthesizerrv   s   &$$$$$$$$$$$$$              r!   rj   rj   ¥   s�  € ô ˜˜vÓ&€DÜ%Ð&7Ð9LÓMÐÜ(Ð)=Ð?UÓVÐÜ˜“=€LßÜÐ:Ó;Ð;Ü˜\°×3‰ˆˆ4Ü�d—l‘l h¨q¨c°Ð$;Ô<Ü�d—j‘j H¨Q¨C¨wÐ"7Ö8ñ 4ô ØØ%ô€Fô �>Š>Øñà×AÐA˜g d§o¡oÓ&7¸Õ&:¸3Õ&?Ð%@ÐAðð>à>B¸VðEðð ðð ðð (ðð !ðð ñ€Dô !  tÓ,×0Ñ0°Ó<€HÜ�(œD×!Ò!Ø&.§l¡l°<ÀÔ&DÓJÑ&D Ì”f”c˜!–fÑ&Dˆ
ÐJØ—l‘l =Ó1ˆØ!Ÿ™Ð&6Ó7ˆßŸ+¯.Ü  j´#°kÓ2BÄCÈÓDWÓXÐXä# D¨$Ó/€Nñ !óñ !ˆDô 	�ŠØñ
	
à—*‘*ð
	
ð —)‘)—/�/˜r ^Õ3ð
	
ð —\‘\ð	
	
ð
 �Fð
	
ð —]‘]×.Ð. hð
	
ð —;‘;×&Ð& $ð
	
ð !%× 8Ñ 8ð
	
ð ô
	
ñ !ð ð ô �~Š~ØñàððCð õð	ð #ðð ðð ðð )Ð)ðð ñ€Hô —.’.ØñàððCàõð	ð &ðð �
ðð ðð ˆ}ðð ñ€Kô ˜4 ¨X°{ÓC€GÜ˜4 ¨j¸jÐPW×P_ÑP_ÓPaÐekÐmqÐdrÕPrÕsØ€Nùòk Kùòs$   Ä/
KÄ>KÆ96KÇ0+KÈKÈ2Kc               ó0   € V ^8„  d   QhRRRRRRRRRRR	R
/# )r)   rB   rC   r$   r   r‚   rƒ   r4   r   r*   r   r   )r,   s   "r!   r-   r-     sB   € ÷ Zñ ZÐ!3ð Z¸cð ZÈcð ZÐX[ð ZÐdgð ZÐloñ Zr    c               óÌ   € \        VR4       \        VR4      p\        VR4      p\        P                  ! RVRV/RRR7      p\        P                  ! WV\
        V,           R7      # )	z:Append one structured update to the swarm root blackboard.r$   r‚   rƒ   r4   FT)Úensure_asciiÚ	sort_keys)r‚   r   )r;   ÚjsonÚdumpsrO   Úadd_commentÚBLACKBOARD_PREFIX)rB   r$   r‚   rƒ   r4   Úpayloads   &&$$$ r!   r‹   r‹     sZ   € ä�'˜9Ô%Ü˜6 8Ó,€FÜ
˜˜UÓ
#€CÜ�jŠj˜%  g¨uÐ5ÀEÐUYÔZ€GÜ�>Š>˜$°Ô=NÐQXÕ=XÔYÐYr    c               ó$   € V ^8„  d   QhRRRRRR/# )r)   rB   rC   r$   r   r*   r+   r   )r,   s   "r!   r-   r-     s"   € ÷ ñ Ð.ð ¸ð Àñ r    c                óð  € / p/ p\         P                  ! W4       F¯  pVP                  ;'       g    RpVP                  \        4      '       g   K6   \
        P                  ! V\        \        4      R 4      pTP                  R4      p\        T\        4      '       d	   T'       g   KŽ  TP                  R4      Y'&   TP                  Y7&   K±  	  V'       d   W2R&   V#   \
        P                   d     KÙ  i ; i)z³Merge 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.r7   Nrƒ   r4   Ú_authors)rO   Úlist_commentsr   Ú
startswithrœ   r™   Úloadsrm   ÚJSONDecodeErrorr‰   rŠ   r   r‚   )rB   r$   ÚmergedÚauthorsÚcommentr   r�   rƒ   s   &&      r!   rˆ   rˆ     sÑ   € ð  €FØ €GÜ×#Ò# DÖ2ˆØ�|‰|×!Ð!˜rˆØ�‰Ô0×1Ò1Ùð	Ü—j’j ¤cÔ*;Ó&<Ð&=Ð!>Ó?ˆGð �k‰k˜%Ó ˆÜ˜#œs×#Ò#¯3ÙØ—k‘k 'Ó*ˆ‰Ø—~‘~ˆ‹ñ 3÷ Ø$ˆzÑØ€Møô ×#Ñ#ô 	Úð	ús   Á&CÃC5Ã4C5c               ó    € V ^8„  d   QhRRRR/# )r)   Úrawr   r*   r   r   )r,   s   "r!   r-   r-   &  s   € ÷ [ñ [˜#ð [ /ñ [r    c                óÌ  € V P                  R^4       Uu. uF  qP                  4       NK  	  pp\        V4      ^8  d   \        R4      h\        V4      ^8X  d]   V^,          '       dN   V^,          P                  R4       Uu. uF*  q3P                  4       '       g   K  VP                  4       NK,  	  upM. p\	        V^ ,          V^,          V^,          VR7      # u upi u upi )z:Parse CLI ``--worker profile:title[:skill,skill]`` values.Ú:z9worker must be profile:title or profile:title:skill,skillÚ,)r   r   r   r   )Úsplitr8   rm   r9   r   )r©   ÚpÚpartsÚsr   s   &    r!   Úparse_worker_argr±   &  s²   € à #§	¡	¨#¨qÔ 1Ó2Ñ 1˜1�W‰WŽYÑ 1€EÐ2Ü
ˆ5ƒz�A„~ÜÐTÓUÐUÜFIÈ%ÃjÐTUÄoÐZ_Ð`a×ZbÔZb  q¥§¡°Ô!4ÓBÑ!4˜A¿¹¿	Œiˆa�g‰gŽiÑ!4ÒBÐhj€FÜ 5¨¥8°5¸µ8À%ÈÅ(ÐSYÔZÐZùò	 3ùò Cs   •CÂC!ÂC!)r   Ú
__future__r   Údataclassesr   r   r   r™   Úsqlite3rM   Útypingr   r   r   Ú
hermes_clir	   rO   rœ   r   r#   r;   r@   rS   ry   rj   r‹   rˆ   r±   r   r    r!   Ú<module>r·      sñ   ðñõ #ç 0Ñ 0Û Û Û ß *Ñ *å &à)Ð ñ �$Ô÷.ð .ó ð.ñ �$Ô÷	ð 	ó ð	õõõ!ðH8ð !%ð8ð 1ð8ð 8ð8ð !ð8ð +ð8ð %)ð8ð %)ð8ð ð8ð &*÷8õv]õ@Zõ÷0[r    