diff --git a/pallets/authority-members/src/lib.rs b/pallets/authority-members/src/lib.rs
index c60df43b7dde52cc9da701caf577ff90aef1403e..9284bb25c88a8d02111a972a59f910fc7ab7f14a 100644
--- a/pallets/authority-members/src/lib.rs
+++ b/pallets/authority-members/src/lib.rs
@@ -69,6 +69,8 @@ pub mod pallet {
         type IsMember: IsMember<Self::MemberId>;
         type OnNewSession: OnNewSession;
         type OnRemovedMember: OnRemovedMember<Self::MemberId>;
+        type OnOutgoingMember: OnOutgoingMember<Self::MemberId>;
+        type OnIncomingMember: OnIncomingMember<Self::MemberId>;
         /// Max number of authorities allowed
         #[pallet::constant]
         type MaxAuthorities: Get<u32>;
@@ -542,6 +544,13 @@ impl<T: Config> pallet_session::SessionManager<T::ValidatorId> for Pallet<T> {
             });
         }
 
+        for member_id in members_ids_to_add.iter() {
+            T::OnIncomingMember::on_incoming_member(member_id.clone());
+        }
+        for member_id in members_ids_to_del.iter() {
+            T::OnOutgoingMember::on_outgoing_member(member_id.clone());
+        }
+
         // updates the list of OnlineAuthorities and returns the list of their key
         Some(
             OnlineAuthorities::<T>::mutate(|members_ids| {
diff --git a/pallets/authority-members/src/traits.rs b/pallets/authority-members/src/traits.rs
index eb3452b58af951f88da5ad940aaef19e5263e577..639ef95df0b0bfc94434137df489064b4dd5a7d7 100644
--- a/pallets/authority-members/src/traits.rs
+++ b/pallets/authority-members/src/traits.rs
@@ -41,6 +41,16 @@ impl<MemberId> OnBlacklistedMember<MemberId> for () {
     fn on_blacklisted_member(_: MemberId) {}
 }
 
+/// Handle the consequences of going in the authority set for other pallets.
+/// Typically, a smith won't expire as long as he is in the authority set.
+pub trait OnIncomingMember<MemberId> {
+    fn on_incoming_member(member_id: MemberId);
+}
+/// By default: no consequences
+impl<MemberId> OnIncomingMember<MemberId> for () {
+    fn on_incoming_member(_: MemberId) {}
+}
+
 /// Handle the consequences of going out of authority set for other pallets.
 /// Typically, the smiths are not allowed to stay offline for a too long time.
 pub trait OnOutgoingMember<MemberId> {
diff --git a/pallets/smith-members/src/impls.rs b/pallets/smith-members/src/impls.rs
index d1a576043d9c2e30e1786a1576dbdf5b5aba99b4..be6180f05c9523ce5c916dc52c4dcb0bd07ebc26 100644
--- a/pallets/smith-members/src/impls.rs
+++ b/pallets/smith-members/src/impls.rs
@@ -1,4 +1,7 @@
-use crate::{Config, Pallet};
+use crate::{Config, CurrentSession, Pallet};
+use frame_support::StorageValue;
+use pallet_authority_members::SessionIndex;
+use sp_runtime::traits::Convert;
 
 /// We want to remove a Smith when he is removed from the higher level set of "authorities".
 impl<T: Config> pallet_authority_members::OnRemovedMember<T> for Pallet<T> {
@@ -19,8 +22,27 @@ impl<T: Config> pallet_authority_members::OnBlacklistedMember<T> for Pallet<T> {
 }
 
 ///
-impl<T: Config> pallet_authority_members::OnOutgoingMember<T> for Pallet<T> {
-    fn on_outgoing_member(member_id: T) {
-        todo!("Has gone out of authority set, start offline counter")
+impl<T: Config> pallet_authority_members::OnOutgoingMember<T::MemberId> for Pallet<T> {
+    fn on_outgoing_member(member_id: T::MemberId) {
+        Pallet::<T>::smith_goes_offline(
+            T::IdtyIdOfAuthorityId::convert(member_id).expect("convertion should be ok"),
+        );
+    }
+}
+
+/// As long as a Smith is in the authority set, he will not expire.
+impl<T: Config> pallet_authority_members::OnIncomingMember<T::MemberId> for Pallet<T> {
+    fn on_incoming_member(member_id: T::MemberId) {
+        Pallet::<T>::smith_goes_online(
+            T::IdtyIdOfAuthorityId::convert(member_id).expect("convertion should be ok"),
+        );
+    }
+}
+
+///
+impl<T: Config> pallet_authority_members::OnNewSession for Pallet<T> {
+    fn on_new_session(index: SessionIndex) {
+        CurrentSession::<T>::put(index);
+        Pallet::<T>::remove_expired_smiths(index);
     }
 }
diff --git a/pallets/smith-members/src/lib.rs b/pallets/smith-members/src/lib.rs
index c34deaccbe6a1e77ebea21230d97407adf1f6094..040e4fb039eefa4af66fcd6790a98fa1aae69e58 100644
--- a/pallets/smith-members/src/lib.rs
+++ b/pallets/smith-members/src/lib.rs
@@ -19,9 +19,10 @@
 #[cfg(test)]
 mod mock;
 
-mod impls;
 #[cfg(test)]
 mod tests;
+
+mod impls;
 mod traits;
 mod types;
 
@@ -33,7 +34,9 @@ use sp_runtime::traits::AtLeast32BitUnsigned;
 use sp_std::fmt::Debug;
 use sp_std::prelude::*;
 
+use crate::traits::OnSmithDelete;
 pub use pallet::*;
+use pallet_authority_members::SessionIndex;
 pub use types::*;
 
 #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]
@@ -43,7 +46,7 @@ pub enum SmithRemovalReason {
     Blacklisted,
 }
 
-#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]
+#[derive(Encode, Decode, Copy, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]
 pub enum SmithStatus {
     /// The identity has been invited by a smith but has not accepted yet
     Invited,
@@ -63,6 +66,7 @@ pub mod pallet {
     use frame_support::{pallet_prelude::*, traits::ReservableCurrency};
     use frame_system::pallet_prelude::*;
     use frame_system::pallet_prelude::*;
+    use pallet_authority_members::SessionIndex;
     use sp_runtime::traits::{Convert, IsMember};
     use std::collections::BTreeMap;
 
@@ -76,7 +80,10 @@ pub mod pallet {
     /// The pallet's config trait.
     #[pallet::config]
     pub trait Config: frame_system::Config {
+        /// To only allow WoT members to be invited
         type IsWoTMember: IsMember<Self::IdtyIndex>;
+        /// Notify when a smith is removed (for authority-members to react)
+        type OnSmithDelete: traits::OnSmithDelete<Self::IdtyIndex>;
         /// The overarching event type.
         type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
         /// A short identity index.
@@ -89,9 +96,10 @@ pub mod pallet {
             + MaybeSerializeDeserialize
             + Debug
             + MaxEncodedLen;
-        /// Duration of validity of a certification
-        type ValidityPeriod: Get<Self::BlockNumber>;
+        /// Identifier for an authority-member
+        type MemberId: Copy + Ord + MaybeSerializeDeserialize + Parameter;
         /// Maximum number of active certifications by issuer
+        #[pallet::constant]
         type MaxByIssuer: Get<u32>;
         /// Minimum number of certifications to be able to create a smith
         #[pallet::constant]
@@ -99,8 +107,13 @@ pub mod pallet {
         /// Minimum number of certifications to become a Smith
         #[pallet::constant]
         type MinCertForMembership: Get<u32>;
+        /// Maximum duration of inactivity before a smith is removed
+        #[pallet::constant]
+        type InactivityMaxDuration: Get<u32>;
         /// Something that gives the IdtyId of an AccountId
         type IdtyIdOf: Convert<Self::AccountId, Option<Self::IdtyIndex>>;
+        /// Something that gives the IdtyId of an AccountId
+        type IdtyIdOfAuthorityId: Convert<Self::MemberId, Option<Self::IdtyIndex>>;
     }
 
     /// Events type.
@@ -132,6 +145,7 @@ pub mod pallet {
     #[pallet::genesis_build]
     impl<T: Config> GenesisBuild<T> for GenesisConfig<T> {
         fn build(&self) {
+            CurrentSession::<T>::put(0);
             let mut cert_meta_by_issuer =
                 BTreeMap::<T::IdtyIndex, SmithCertMeta<T::BlockNumber>>::new();
             for (receiver, issuers) in &self.certs_by_receiver {
@@ -165,7 +179,19 @@ pub mod pallet {
                 } else {
                     SmithStatus::Pending
                 };
-                Smiths::<T>::insert(receiver, smith_status);
+                Smiths::<T>::insert(
+                    receiver,
+                    SmithMeta {
+                        status: smith_status,
+                        expires_on: Some(
+                            CurrentSession::<T>::get() + T::InactivityMaxDuration::get(),
+                        ),
+                    },
+                );
+                ExpiresOn::<T>::append(
+                    CurrentSession::<T>::get() + T::InactivityMaxDuration::get(),
+                    receiver,
+                );
             }
         }
     }
@@ -177,8 +203,16 @@ pub mod pallet {
 
     /// maps identity index to smith status
     #[pallet::storage]
-    pub type Smiths<T: Config> =
-        StorageMap<_, Twox64Concat, T::IdtyIndex, SmithStatus, OptionQuery>;
+    pub type Smiths<T: Config> = StorageMap<_, Twox64Concat, T::IdtyIndex, SmithMeta, OptionQuery>;
+
+    /// maps session index to possible smith removals
+    #[pallet::storage]
+    pub type ExpiresOn<T: Config> =
+        StorageMap<_, Twox64Concat, SessionIndex, Vec<T::IdtyIndex>, OptionQuery>;
+
+    /// maps session index to possible smith removals
+    #[pallet::storage]
+    pub type CurrentSession<T: Config> = StorageValue<_, SessionIndex, ValueQuery>;
 
     // ERRORS //
 
@@ -218,8 +252,9 @@ pub mod pallet {
         ) -> DispatchResultWithPostInfo {
             let who = ensure_signed(origin.clone())?;
             let issuer = T::IdtyIdOf::convert(who.clone()).ok_or(Error::<T>::UnknownIssuer)?;
-            let issuer_status =
-                Smiths::<T>::get(issuer).ok_or(Error::<T>::IssuerHasNoSmithStatus)?;
+            let issuer_status = Smiths::<T>::get(issuer)
+                .ok_or(Error::<T>::IssuerHasNoSmithStatus)?
+                .status;
             ensure!(
                 issuer_status == SmithStatus::Smith,
                 Error::<T>::CannotInvite
@@ -229,7 +264,15 @@ pub mod pallet {
                 Error::<T>::ReceveirAlreadyHasSmithStatus
             );
 
-            Smiths::<T>::insert(receiver, SmithStatus::Invited);
+            let new_expires_on = CurrentSession::<T>::get() + T::InactivityMaxDuration::get();
+            Smiths::<T>::insert(
+                receiver,
+                SmithMeta {
+                    status: SmithStatus::Invited,
+                    expires_on: Some(new_expires_on),
+                },
+            );
+            ExpiresOn::<T>::append(new_expires_on, receiver);
 
             Ok(().into())
         }
@@ -239,13 +282,18 @@ pub mod pallet {
         pub fn accept_invitation(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
             let who = ensure_signed(origin.clone())?;
             let pretender = T::IdtyIdOf::convert(who.clone()).ok_or(Error::<T>::UnknownIssuer)?;
-            let pretender_status = Smiths::<T>::get(pretender).ok_or(Error::<T>::NotInvited)?;
+            let pretender_status = Smiths::<T>::get(pretender)
+                .ok_or(Error::<T>::NotInvited)?
+                .status;
             ensure!(
                 pretender_status == SmithStatus::Invited,
                 Error::<T>::AlreadyAcceptedInvitation
             );
 
-            Smiths::<T>::insert(pretender, SmithStatus::Pending);
+            Smiths::<T>::mutate(pretender, |maybe_smith_meta| {
+                let maybe_smith_meta = maybe_smith_meta.as_mut().expect("status checked earlier");
+                maybe_smith_meta.status = SmithStatus::Pending;
+            });
 
             Ok(().into())
         }
@@ -259,14 +307,16 @@ pub mod pallet {
             let who = ensure_signed(origin)?;
             let issuer = T::IdtyIdOf::convert(who.clone()).ok_or(Error::<T>::UnknownIssuer)?;
             ensure!(issuer != receiver, Error::<T>::CannotCertifySelf);
-            let issuer_status =
-                Smiths::<T>::get(issuer).ok_or(Error::<T>::IssuerHasNoSmithStatus)?;
+            let issuer_status = Smiths::<T>::get(issuer)
+                .ok_or(Error::<T>::IssuerHasNoSmithStatus)?
+                .status;
             ensure!(
                 issuer_status == SmithStatus::Smith,
                 Error::<T>::IssuerIsNotASmith
             );
-            let receiver_status =
-                Smiths::<T>::get(receiver).ok_or(Error::<T>::ReceiverHasNotBeenInvited)?;
+            let receiver_status = Smiths::<T>::get(receiver)
+                .ok_or(Error::<T>::ReceiverHasNotBeenInvited)?
+                .status;
             ensure!(
                 receiver_status != SmithStatus::Invited,
                 Error::<T>::ReceveirMustAcceptInvitation
@@ -275,23 +325,73 @@ pub mod pallet {
             CertsByReceiver::<T>::mutate(receiver, |certs| {
                 let certs = certs.get_or_insert(vec![]);
                 certs.push(issuer);
-                // TODO: "as u32" allowed?
-                if certs.len() as u32 >= T::MinCertForMembership::get() {
-                    Smiths::<T>::insert(receiver, SmithStatus::Smith);
-                } else {
-                    Smiths::<T>::insert(receiver, SmithStatus::Pending);
-                }
+                Smiths::<T>::mutate(receiver, |maybe_smith_meta| {
+                    let maybe_smith_meta =
+                        maybe_smith_meta.as_mut().expect("status checked earlier");
+                    // TODO: "as u32" allowed?
+                    maybe_smith_meta.status =
+                        if certs.len() as u32 >= T::MinCertForMembership::get() {
+                            SmithStatus::Smith
+                        } else {
+                            SmithStatus::Pending
+                        };
+                });
             });
 
             Ok(().into())
         }
     }
+}
+
+impl<T: Config> Pallet<T> {
+    // TODO: return what?
+    fn remove_expired_smiths(at: SessionIndex) {
+        if let Some(smiths_to_remove) = ExpiresOn::<T>::get(at) {
+            for smith in smiths_to_remove {
+                if let Some(smith_meta) = Smiths::<T>::get(smith) {
+                    if let Some(expires_on) = smith_meta.expires_on {
+                        if expires_on == at {
+                            Smiths::<T>::remove(smith);
+                            T::OnSmithDelete::on_smith_delete(
+                                smith,
+                                SmithRemovalReason::OfflineTooLong,
+                            );
+                        }
+                    }
+                }
+            }
+        }
+    }
 
-    // TODO: on confirm
-    // ensure!(
-    //             T::IsWoTMember::is_member(&receiver),
-    //             Error::<T>::NotAMember
-    //         );
+    // TODO: return what?
+    fn smith_goes_online(idty_index: T::IdtyIndex) {
+        if let Some(smith_meta) = Smiths::<T>::get(idty_index) {
+            if smith_meta.expires_on.is_some() {
+                Smiths::<T>::mutate(idty_index, |maybe_smith_meta| {
+                    let maybe_smith_meta = maybe_smith_meta.as_mut().expect("checked earlier");
+                    // As long as the smith is online, it cannot expire
+                    maybe_smith_meta.expires_on = None;
+                    // FIXME: also update ExpiresOn storage
+                });
+            }
+        }
+    }
+
+    // TODO: return what?
+    fn smith_goes_offline(idty_index: T::IdtyIndex) {
+        if let Some(smith_meta) = Smiths::<T>::get(idty_index) {
+            if smith_meta.expires_on.is_none() {
+                Smiths::<T>::mutate(idty_index, |maybe_smith_meta| {
+                    let maybe_smith_meta = maybe_smith_meta.as_mut().expect("checked earlier");
+                    // As long as the smith is online, it cannot expire
+                    let new_expires_on =
+                        CurrentSession::<T>::get() + T::InactivityMaxDuration::get();
+                    maybe_smith_meta.expires_on = Some(new_expires_on);
+                    ExpiresOn::<T>::append(new_expires_on, idty_index);
+                });
+            }
+        }
+    }
 }
 
 impl<T: Config> Pallet<T> {
diff --git a/pallets/smith-members/src/mock.rs b/pallets/smith-members/src/mock.rs
index 36fca3cd989c0db444b88171c7a7b905e88db5b8..b32cf9b0ffc4999c9d63d9cad0eb8ff3120afc41 100644
--- a/pallets/smith-members/src/mock.rs
+++ b/pallets/smith-members/src/mock.rs
@@ -16,8 +16,9 @@
 
 #![cfg(test)]
 
+use crate::traits::OnSmithDelete;
 use crate::{self as pallet_smith_members};
-use frame_support::pallet_prelude::GenesisBuild;
+use frame_support::pallet_prelude::{GenesisBuild, Hooks};
 use frame_support::{
     parameter_types,
     traits::{ConstU32, ConstU64},
@@ -92,10 +93,13 @@ impl pallet_smith_members::Config for Runtime {
     type IdtyIndex = u64;
     type IsWoTMember = EveryoneExceptIdZero;
     type IdtyIdOf = ConvertInto;
-    type ValidityPeriod = ConstU64<1>;
     type MinCertForMembership = ConstU32<2>;
     type MinCertForCreateIdtyRight = ConstU32<3>;
     type MaxByIssuer = ConstU32<5>;
+    type InactivityMaxDuration = ConstU32<5>;
+    type OnSmithDelete = ();
+    type IdtyIdOfAuthorityId = ConvertInto;
+    type MemberId = u64;
 }
 
 pub fn new_test_ext(
diff --git a/pallets/smith-members/src/tests.rs b/pallets/smith-members/src/tests.rs
index c2868d5148edfbfb270f682c4c3ef0d7acfd1a93..a88d5e7062f3777c36a91bd47df4cb66c0bede52 100644
--- a/pallets/smith-members/src/tests.rs
+++ b/pallets/smith-members/src/tests.rs
@@ -22,9 +22,10 @@ use frame_support::{assert_err, assert_ok};
 
 #[cfg(test)]
 use maplit::btreemap;
+use pallet_authority_members::OnNewSession;
 
 #[test]
-fn process_to_become_a_smith() {
+fn process_to_become_a_smith_and_lose_it() {
     new_test_ext(GenesisConfig {
         certs_by_receiver: btreemap![
             1 => btreemap![
@@ -51,21 +52,41 @@ fn process_to_become_a_smith() {
         )));
         // State after
         assert_eq!(CertsByReceiver::<Runtime>::get(5), None);
-        assert_eq!(Smiths::<Runtime>::get(5).unwrap(), SmithStatus::Pending);
+        assert_eq!(
+            Smiths::<Runtime>::get(5).unwrap().status,
+            SmithStatus::Pending
+        );
         // Then certification 1/2
         assert_ok!(Pallet::<Runtime>::certify_smith(
             RuntimeOrigin::signed(1),
             5
         ));
         assert_eq!(CertsByReceiver::<Runtime>::get(5).unwrap().len(), 1);
-        assert_eq!(Smiths::<Runtime>::get(5).unwrap(), SmithStatus::Pending);
+        assert_eq!(
+            Smiths::<Runtime>::get(5).unwrap().status,
+            SmithStatus::Pending
+        );
         // Then certification 2/2
         assert_ok!(Pallet::<Runtime>::certify_smith(
             RuntimeOrigin::signed(2),
             5
         ));
         assert_eq!(CertsByReceiver::<Runtime>::get(5).unwrap().len(), 2);
-        assert_eq!(Smiths::<Runtime>::get(5).unwrap(), SmithStatus::Smith);
+        assert_eq!(
+            Smiths::<Runtime>::get(5).unwrap().status,
+            SmithStatus::Smith
+        );
+
+        // On session 4 everything if fine
+        Pallet::<Runtime>::on_new_session(4);
+        assert_eq!(Smiths::<Runtime>::get(1).is_some(), true);
+        assert_eq!(Smiths::<Runtime>::get(2).is_some(), true);
+        assert_eq!(Smiths::<Runtime>::get(5).is_some(), true);
+        // On session 5 no more smiths because of lack of activity
+        Pallet::<Runtime>::on_new_session(5);
+        assert_eq!(Smiths::<Runtime>::get(1), None);
+        assert_eq!(Smiths::<Runtime>::get(2), None);
+        assert_eq!(Smiths::<Runtime>::get(5), None);
     });
 }
 
@@ -94,10 +115,22 @@ fn should_have_checks_on_certify() {
     .execute_with(|| {
         // Initially
         assert_eq!(CertsByReceiver::<Runtime>::iter().count(), 4);
-        assert_eq!(Smiths::<Runtime>::get(1).unwrap(), SmithStatus::Smith);
-        assert_eq!(Smiths::<Runtime>::get(2).unwrap(), SmithStatus::Smith);
-        assert_eq!(Smiths::<Runtime>::get(3).unwrap(), SmithStatus::Pending);
-        assert_eq!(Smiths::<Runtime>::get(4).unwrap(), SmithStatus::Smith);
+        assert_eq!(
+            Smiths::<Runtime>::get(1).unwrap().status,
+            SmithStatus::Smith
+        );
+        assert_eq!(
+            Smiths::<Runtime>::get(2).unwrap().status,
+            SmithStatus::Smith
+        );
+        assert_eq!(
+            Smiths::<Runtime>::get(3).unwrap().status,
+            SmithStatus::Pending
+        );
+        assert_eq!(
+            Smiths::<Runtime>::get(4).unwrap().status,
+            SmithStatus::Smith
+        );
         assert_eq!(CertsByReceiver::<Runtime>::get(1).unwrap().len(), 3);
         assert_eq!(CertsByReceiver::<Runtime>::get(2).unwrap().len(), 2);
         assert_eq!(CertsByReceiver::<Runtime>::get(3).unwrap().len(), 1);
@@ -123,7 +156,10 @@ fn should_have_checks_on_certify() {
 
         // #3: state before
         assert_eq!(CertsByReceiver::<Runtime>::get(3).unwrap().len(), 1);
-        assert_eq!(Smiths::<Runtime>::get(3).unwrap(), SmithStatus::Pending);
+        assert_eq!(
+            Smiths::<Runtime>::get(3).unwrap().status,
+            SmithStatus::Pending
+        );
         // Try to certify #3
         assert_ok!(Pallet::<Runtime>::certify_smith(
             RuntimeOrigin::signed(1),
@@ -131,6 +167,73 @@ fn should_have_checks_on_certify() {
         ));
         // #3: state after
         assert_eq!(CertsByReceiver::<Runtime>::get(3).unwrap().len(), 2);
-        assert_eq!(Smiths::<Runtime>::get(3).unwrap(), SmithStatus::Smith);
+        assert_eq!(
+            Smiths::<Runtime>::get(3).unwrap().status,
+            SmithStatus::Smith
+        );
+    });
+}
+
+#[test]
+fn smith_activity_postpones_expiration() {
+    new_test_ext(GenesisConfig {
+        certs_by_receiver: btreemap![
+            1 => btreemap![
+                2 => None,
+                3 => None,
+                4 => None,
+            ],
+            2 => btreemap![
+                4 => None,
+                4 => None,
+                5 => None,
+            ]
+        ],
+    })
+    .execute_with(|| {
+        // On session 4 everything is fine
+        Pallet::<Runtime>::on_new_session(4);
+        assert_eq!(Smiths::<Runtime>::get(1).is_some(), true);
+        assert_eq!(Smiths::<Runtime>::get(2).is_some(), true);
+
+        // Smith #2 is online but not #1
+        Pallet::<Runtime>::smith_goes_online(2);
+
+        // On session 5 no more smiths because of lack of activity
+        Pallet::<Runtime>::on_new_session(5);
+        assert_eq!(Smiths::<Runtime>::get(1), None);
+        assert_eq!(
+            Smiths::<Runtime>::get(2),
+            Some(SmithMeta {
+                status: SmithStatus::Smith,
+                expires_on: None
+            })
+        );
+
+        // Smith #2 goes offline
+        Pallet::<Runtime>::on_new_session(6);
+        Pallet::<Runtime>::smith_goes_offline(2);
+        assert_eq!(Smiths::<Runtime>::get(1), None);
+        assert_eq!(
+            Smiths::<Runtime>::get(2),
+            Some(SmithMeta {
+                status: SmithStatus::Smith,
+                expires_on: Some(11)
+            })
+        );
+        // Still not expired on session 10
+        Pallet::<Runtime>::on_new_session(10);
+        assert_eq!(Smiths::<Runtime>::get(1), None);
+        assert_eq!(
+            Smiths::<Runtime>::get(2),
+            Some(SmithMeta {
+                status: SmithStatus::Smith,
+                expires_on: Some(11)
+            })
+        );
+        // Finally expired on session 11
+        Pallet::<Runtime>::on_new_session(11);
+        assert_eq!(Smiths::<Runtime>::get(1), None);
+        assert_eq!(Smiths::<Runtime>::get(2), None);
     });
 }
diff --git a/pallets/smith-members/src/traits.rs b/pallets/smith-members/src/traits.rs
index 7b15e78b98dc77eaca5d38f1cf88aea2a6393420..f59b6fc1c775e15ba69e32704da9238516a18db4 100644
--- a/pallets/smith-members/src/traits.rs
+++ b/pallets/smith-members/src/traits.rs
@@ -1,8 +1,8 @@
 use crate::SmithRemovalReason;
 
-pub trait OnSmithDelete {
-    fn on_smith_delete(reason: SmithRemovalReason);
+pub trait OnSmithDelete<IdtyIndex> {
+    fn on_smith_delete(idty_index: IdtyIndex, reason: SmithRemovalReason);
 }
-impl OnSmithDelete for () {
-    fn on_smith_delete(_: SmithRemovalReason) {}
+impl<IdtyIndex> OnSmithDelete<IdtyIndex> for () {
+    fn on_smith_delete(_: IdtyIndex, _: SmithRemovalReason) {}
 }
diff --git a/pallets/smith-members/src/types.rs b/pallets/smith-members/src/types.rs
index d47d5704ed2128ebdbbf5375697adcdc023ae936..f1298055190fa798a3e670ff83a476fc249d30ee 100644
--- a/pallets/smith-members/src/types.rs
+++ b/pallets/smith-members/src/types.rs
@@ -16,11 +16,21 @@
 
 //! Various basic types for use in the identity pallet.
 
+use crate::SmithStatus;
 use codec::{Decode, Encode};
 use frame_support::pallet_prelude::*;
-use scale_info::TypeInfo;
 #[cfg(feature = "std")]
-use serde::{Deserialize, Serialize};
+use pallet_authority_members::SessionIndex;
+use scale_info::TypeInfo;
+
+/// certification metadata attached to an identity
+#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug, TypeInfo)]
+pub struct SmithMeta {
+    /// current status of the smith
+    pub status: SmithStatus,
+    /// the session at which the smith will expire (for lack of validation activity)
+    pub expires_on: Option<SessionIndex>,
+}
 
 /// certification metadata attached to an identity
 #[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug, TypeInfo)]