
    sj2              
      B   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Zdddddd dddd!	d=d1Zdddddd dddd!	d=d2Zd>d6Zd?d7Zd@d9ZdS )Au  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                  p    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<   dS )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        ;/home/agent/.hermes/hermes-agent/hermes_cli/kanban_swarm.pyr   r      st         33LLLJJJIIId333F3333H)-------r   r   c                  D    e Zd ZU dZded<   ded<   ded<   ded<   dd
ZdS )SwarmCreatedz%IDs produced by :func:`create_swarm`.r   root_idr   
worker_idsverifier_idsynthesizer_idreturndict[str, Any]c                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   s/    |t//+"1	
 
 	
r   N)r&   r'   )r   r   r   r   r   r+   r   r   r   r!   r!   )   s]         //LLL
 
 
 
 
 
r   r!   valuer   
field_namer&   c                Z    | pd                                 }|st          | d          |S )N z is required)strip
ValueError)r,   r-   texts      r   _require_textr3   ;   s;    KR  D 6J444555Kr   r"   goalc                8    d|  d|                                  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: 
r0   )r"   r4   s     r   _swarm_contextr8   B   s5    	$.5	$ 	$
 ::<<	$ 	$ 	$r   connsqlite3.Connectionsummarymetadatar'   boolc          	        ddl }t          |                                           }|                     d||f          }|j        dk    rdS t	          j        | |d||          }t	          j        | |dd|dd         pdd	|
           dS )u  Inline blocked→done CAS flip + event insert for the swarm root.

    Runs INSIDE create_swarm's outer write_txn, so it must not call
    ``kb.complete_task`` — that helper opens its own transaction and fires
    post-commit side effects (workspace cleanup, failure-counter clear,
    ``recompute_ready``) that would execute while the outer transaction can
    still roll back. Instead we do the minimal durable writes here and let
    the caller run ``recompute_ready`` after the outer commit.
    r   Na  
        UPDATE tasks
           SET status       = 'done',
               completed_at = ?,
               claim_lock   = NULL,
               claim_expires= NULL,
               worker_pid   = NULL
         WHERE id = ?
           AND status = 'blocked'
           F	completed)outcomer;   r<   i  )
result_lenr;   )run_idT)timer   executerowcountkb_synthesize_ended_run_append_event)r9   r"   r;   r<   _timenowcurrC   s           r   _activate_root_inlinerM   M   s      
ejjll

C
,,		 
g C |qu%  F WTcT]%:d;;    4r   zVerify swarm outputszSynthesize swarm outputszswarm-orchestratorscratch)	
root_titleverifier_titlesynthesizer_titletenant
created_byworkspace_kindworkspace_pathr   idempotency_keyworkersIterable[SwarmWorkerSpec]verifier_assigneesynthesizer_assigneerO   Optional[str]rP   rQ   rR   rS   rT   rU   r   r   rV   c                  d}d}t          j        |           5  t          | |||||||||	|
|||          }t          j        | |j                  }|\|j        dk    rQt          | |j        |d|                                t          |j	                  d          st          d	          d
}ddd           n# 1 swxY w Y   |rt          j        |            t          j        | |j                  }t          j        | |j                  }t          j        d|j        t          j                    |r|j        nd|r|j        nd|           |S )zCAtomically create a durable, immediately dispatchable Kanban swarm.z;Swarm topology planned; root remains the shared blackboard.F)r4   rW   rY   rZ   rO   rP   rQ   rR   rS   rT   rU   r   rV   Nblockedkanban_swarm_v1)kindr4   worker_count)r;   r<   z/could not activate the completed swarm topologyTkanban_task_completed)boardassigneerC   r;   )rG   	write_txn_create_swarm_uncommittedget_taskr"   statusrM   r0   lenr#   RuntimeErrorrecompute_ready
latest_run_fire_kanban_lifecycle_hookget_current_boardrc   id)r9   r4   rW   rY   rZ   rO   rP   rQ   rR   rS   rT   rU   r   rV   activation_summary	activatedcreatedrootruns                      r   create_swarmrt      s   & 	F  I	d		  +/!5!)/!))+
 
 
  {411y 8 8(*- JJLL$'(:$;$; 		 	 	 
V ##TUUUI=              >  
 	4   {411mD'/22
&#O&((&*4T]] *366d&	
 	
 	
 	
 Ns   BB;;B?B?c               (   t          |d          }t          |d          }t          |d          }t          |          }|st          d          t          |d          D ]7\  }}t          |j        d| d           t          |j        d| d	           8t          j        | |p$d
|                                d         dd          d| |	|	|||d|
|          }t          | |          
                    d          }t          |t                    r}d |
                    dg           D             }|
                    d          }|
                    d          }|r1|r/|r-t          ||t          |          t          |                    S t          ||          }g }|D ]_}t          j        | |j        |j        pd|z   |j        |	|g||j        p||
||j        pd|j                  }|                    |           `d|z   }t          j        | ||||	||||
|dg          }d|z   }t          j        | ||||	|g|||
|dg          }t          ||||          }t+          | ||	d|                                d|iz             |S )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.
    r4   rY   rZ   zat least one worker is requiredr?   )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   r   rc   rS   rR   r   rV   initial_statusrT   rU   topologyc                0    g | ]}|t          |          S r   )r   ).0xs     r   
<listcomp>z-_create_swarm_uncommitted.<locals>.<listcomp>  s#    JJJJc!ffJJJr   r#   r$   r%   r)   r/   )r   r   rc   rS   parentsrR   r   rT   rU   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   rc   rS   r~   rR   r   rT   rU   r   zwSynthesize the verified worker outputs into the final deliverable. Do not start until the verifier has passed the gate.	humanizer)authorkeyr,   )r3   r   r1   	enumerater   r   rG   create_task
splitlineslatest_blackboardget
isinstancedictr!   r   r8   r   r   r   r   appendpost_blackboard_updater+   )r9   r4   rW   rY   rZ   rO   rP   rQ   rR   rS   rT   rU   r   rV   worker_specsispecrr   existingr#   r$   r%   context_suffix	worker_idverifier_bodyverifiersynthesizer_bodysynthesizerrq   s                                r   re   re      st   0 v&&D%&79LMM()=?UVV==L <:;;;\333 9 94dl$;q$;$;$;<<<dj"7Q"7"7"78888>AAdoo&7&7&:3B3&?AA  
 ' %%!  D, !t,,00<<H(D!! 
JJhll<&D&DJJJ
ll=11!&677 	+ 	. 	%,,">22	    $D$//NJ % %N*)/r^3\!F].h));&$ $ 8
 
 
	 	)$$$$	? 	  ~"%%()  H	?
	 
 .%
%%}  K 4X{CCGoo64.0    Nr   r   r   r   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"   r   r   )r   r,   FT)ensure_ascii	sort_keys)r   r   )r3   jsondumpsrG   add_commentBLACKBOARD_PREFIX)r9   r"   r   r   r,   payloads         r   r   r   Q  sq     '9%%%68,,F
U
#
#Cju55EUYZZZG>$=NQX=XYYYYr   c                   i }i }t          j        | |          D ]}|j        pd}|                    t                    s&	 t          j        |t          t                    d                   }n# t
          j        $ r Y gw xY w|	                    d          }t          |t                    r|s|	                    d          ||<   |j        ||<   |r||d<   |S )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/   Nr   r,   _authors)rG   list_commentsr   
startswithr   r   loadsrh   JSONDecodeErrorr   r   r   r   )r9   r"   mergedauthorscommentr   r   r   s           r   r   r   b  s     F G#D'22 & &|!r011 		jc*;&<&<&=&=!>??GG# 	 	 	H	kk%  #s## 	3 	kk'**s~ %$zMs   .A00BBrawc                T   d |                      dd          D             }t          |          dk     rt          d          g }t          |          dk    r-|d         r%d |d                              d          D             }t          |d         |d	         |d	         |
          S )z:Parse CLI ``--worker profile:title[:skill,skill]`` values.c                6    g | ]}|                                 S r   r7   )r{   ps     r   r}   z$parse_worker_arg.<locals>.<listcomp>  s     2221QWWYY222r   :   z9worker must be profile:title or profile:title:skill,skill   c                ^    g | ]*}|                                 |                                 +S r   r7   )r{   ss     r   r}   z$parse_worker_arg.<locals>.<listcomp>  s-    FFFAGGIIF!''))FFFr   ,r   r?   )r   r   r   r   )splitrh   r1   r   )r   partsr   s      r   parse_worker_argr   }  s     32		#q 1 1222E
5zzA~~TUUUF
5zzQ58FFU1X^^C%8%8FFF5858%(SYZZZZr   )r,   r   r-   r   r&   r   )r"   r   r4   r   r&   r   )
r9   r:   r"   r   r;   r   r<   r'   r&   r=   )r9   r:   r4   r   rW   rX   rY   r   rZ   r   rO   r[   rP   r   rQ   r   rR   r[   rS   r   rT   r   rU   r[   r   r   rV   r[   r&   r!   )r9   r:   r"   r   r   r   r   r   r,   r   r&   r   )r9   r:   r"   r   r&   r'   )r   r   r&   r   )r   
__future__r   dataclassesr   r   r   sqlite3typingr   r   r   
hermes_clir	   rG   r   r   r!   r3   r8   rM   rt   re   r   r   r   r   r   r   <module>r      s     # " " " " " ( ( ( ( ( ( ( (   * * * * * * * * * * & & & & & &)  $. . . . . . . . $
 
 
 
 
 
 
 
"      0 0 0 0t !%07 *#$(%)D D D D D D\ !%07 *#$(%)G G G G G GTZ Z Z Z"   6	[ 	[ 	[ 	[ 	[ 	[r   