anchor.diff:            rc_stats          = none                              :: rr_recon_stats:stats() | none,
             rs_stats          = none                              :: rr_resolve:stats() | none,
             rs_called         = 0                                 :: non_neg_integer(),
  -          rs_finish         = 0                                 :: non_neg_integer()
  +          rs_finish         = 0                                 :: non_neg_integer(),
  +          ttl               = ?required(session, ttl)           :: pos_integer()    %time to live in milliseconds
           }).
   -type session() :: #session{}.
  -%TODO Session TTL
   
   -record(rrepair_state,
           {
            trigger_state  = ?required(rrepair_state, trigger_state)   :: trigger:state(),
  +         gc_trigger     = ?required(rrepair_state, gc_trigger)      :: trigger:state(),     %garbage collector trigger to remove dead sessions
            round          = {0, 0}                                    :: round(),
            open_recon     = 0                                         :: non_neg_integer(),
            open_resolve   = 0                                         :: non_neg_integer(),
  
positive.code: 
  -spec new_session(round(), comm:mypid(), rr_recon:method()) -> session().
  new_session(Round, Pid, RCMethod) ->
      #session{ id = {Round, Pid}, rc_method = RCMethod }.
  
  -spec session_id_equal(session_id(), session_id()) -> boolean().
  session_id_equal({{R, _}, Pid}, {{R, _}, Pid}) -> true;
  
negative.code:     {get_state, Sender::comm:mypid(), Key::state_field()} |
      % internal
      {?TRIGGER_NAME} |
      {?GC_TRIGGER} |
  	{continue_recon, SenderRRPid::comm:mypid(), session_id() | null, ReqMsg::rr_recon:request()} |
      {request_resolve, session_id() | null, rr_resolve:operation(), rr_resolve:options()} |
      {recon_forked} |
  