diff --git a/pyAmakCore/classes/agent.py b/pyAmakCore/classes/agent.py
index 16606ab466f276cb4e3a15f816c40e92977f822d..f5a979cee0771987c76cec4463613dcfcb34b811 100644
--- a/pyAmakCore/classes/agent.py
+++ b/pyAmakCore/classes/agent.py
@@ -104,6 +104,12 @@ class Agent:
         """
         self.__neighbours = []
 
+    def get_criticality(self) -> float:
+        """
+        return criticality
+        """
+        return self.__criticality
+
     def compute_criticality(self) -> float:
         """
         compute_criticality
@@ -168,7 +174,7 @@ class Agent:
         this is the first phase of a cycle
         """
         self.on_perceive()
-        self.compute_criticality()
+        self.__criticality = self.compute_criticality()
         self._next_phase()
 
     def _phase2(self) -> None:
@@ -177,7 +183,7 @@ class Agent:
         """
         self.on_decide()
         self.on_act()
-        self.compute_criticality()
+        self.__criticality = self.compute_criticality()
         self._next_phase()
 
     def _next_phase(self):
diff --git a/pyAmakCore/classes/amas.py b/pyAmakCore/classes/amas.py
index b78109818ba2a54c771b8fe58aae8209bfc0e98f..d24b11510190a8bbb38eae15c38fba0080166e53 100644
--- a/pyAmakCore/classes/amas.py
+++ b/pyAmakCore/classes/amas.py
@@ -30,16 +30,24 @@ class Amas(Schedulable, Loggable):
         Loggable.__init__(self)
         self.__environment: Environment = environment
         self.__agents: List[Agent] = []
+        self.__agent_to_add: List[Agent] = []
+        self.__agent_to_remove: List[Agent] = []
+
         self.__nbrcycle: int = 0
 
-        self.scheduler: Scheduler = Scheduler()
-        self.scheduler.add_schedulable(self)
-        self.__environment.add_scheduler(self.scheduler)
+        self.__scheduler: Scheduler = Scheduler()
+        self.__scheduler.add_schedulable(self)
+        self.__environment.add_scheduler(self.__scheduler)
 
         self.__execution_policy: ExecutionPolicy = ExecutionPolicy.ONE_PHASE
 
         self.on_initial_agents_creation()
 
+        for agent in self.__agent_to_add:
+            if agent not in self.__agents:
+                self.__agents.append(agent)
+        self.__agent_to_add = []
+
         for agent in self.__agents:
             agent.compute_criticality()
 
@@ -52,9 +60,9 @@ class Amas(Schedulable, Loggable):
         """
         add agent in the amas agents list without duplicate
         """
-        if agent in self.__agents:
+        if agent in self.__agents or agent in self.__agent_to_add:
             return
-        self.__agents.append(agent)
+        self.__agent_to_add.append(agent)
 
     def add_agents(self, agents: List[Agent]) -> None:
         """
@@ -67,9 +75,7 @@ class Amas(Schedulable, Loggable):
         """
         remove agent from amas
         """
-        if agent not in self.__agents:
-            return
-        self.__agents.remove(agent)
+        self.__agent_to_remove.append(agent)
 
     def get_environment(self) -> Environment:
         """
@@ -112,7 +118,7 @@ class Amas(Schedulable, Loggable):
         Unlock Scheduler and wait for his response
         """
         self.give_token_syncro()
-        self.scheduler.take_amas_token()
+        self.__scheduler.take_amas_token()
 
     def cycle(self) -> None:
         """
@@ -120,6 +126,11 @@ class Amas(Schedulable, Loggable):
         """
         print("Cycle : ", self.__nbrcycle)
 
+        for agent in self.__agent_to_add:
+            if agent not in self.__agents:
+                self.__agents.append(agent)
+        self.__agent_to_add = []
+
         self.on_cycle_begin()
         self.synchronization()
 
@@ -146,6 +157,12 @@ class Amas(Schedulable, Loggable):
         self.synchronization()
 
         self.on_cycle_end()
+
+        for agent in self.__agent_to_remove:
+            if agent in self.__agents:
+                self.__agents.remove(agent)
+        self.__agent_to_remove = []
+
         self.to_csv(self.get_cycle(), self.get_agents())
         self.__nbrcycle += 1
 
@@ -153,29 +170,29 @@ class Amas(Schedulable, Loggable):
         """
         Tell scheduler to start
         """
-        self.scheduler.give_semaphore_start_stop()
+        self.__scheduler.give_semaphore_start_stop()
 
     def take_token(self) -> None:
         """
         Tell scheduler to stop
         """
-        self.scheduler.take_semaphore_start_stop()
+        self.__scheduler.take_semaphore_start_stop()
 
     def exit_program(self) -> None:
         """
         exit the program at the end of the cycle
         """
         self.put_token()
-        self.scheduler.exit_bool = True
+        self.__scheduler.exit_bool = True
 
     def set_sleep(self, sleep_time) -> None:
         """
         set sleep between 2 cycles
         """
-        self.scheduler.sleep_time = sleep_time
+        self.__scheduler.sleep_time = sleep_time
 
     def start(self) -> None:
         """
         launch the system
         """
-        self.scheduler.run()
+        self.__scheduler.run()
diff --git a/pyAmakCore/classes/communicating_agent.py b/pyAmakCore/classes/communicating_agent.py
index be6d0f017e1311317746d4b70d0dae89dce28166..0dbbede2b325a6c723127be266980d7224fc0a42 100644
--- a/pyAmakCore/classes/communicating_agent.py
+++ b/pyAmakCore/classes/communicating_agent.py
@@ -17,10 +17,11 @@ class Mail:
     Class message
     """
 
-    def __init__(self, id_sender: int, id_receiver: int, message: Any) -> None:
+    def __init__(self, id_sender: int, id_receiver: int, message: Any, sending_date: int) -> None:
         self.__id_sender = id_sender
         self.__id_receiver = id_receiver
         self.__message = message
+        self.__sending_date = sending_date
 
     def get_id_sender(self):
         """
@@ -40,6 +41,12 @@ class Mail:
         """
         return self.__message
 
+    def get_sending_date(self):
+        """
+        return sending_date
+        """
+        return self.__sending_date
+
 
 class Mailbox:
     """
@@ -72,7 +79,7 @@ class Mailbox:
         """
         this method is called to send a message
         """
-        mail = Mail(self.__owner_id, id_receiver, message)
+        mail = Mail(self.__owner_id, id_receiver, message, self.__amas.get_cycle())
 
         for agent in self.__amas.get_agents():
             if agent.get_id() == id_receiver:
@@ -106,12 +113,12 @@ class CommunicatingAgent(Agent):
         Override of phase 1 agent so he read mail before he perceive
         this is the first phase of a cycle
         """
-        self._read_mails()
+        self.read_mails()
         self.on_perceive()
         self.compute_criticality()
         self._next_phase()
 
-    def _read_mails(self) -> None:
+    def read_mails(self) -> None:
         """
         method that open all mail in the mailbox
         """
diff --git a/pyAmakCore/classes/environment.py b/pyAmakCore/classes/environment.py
index ce59b09f9ddefe7cd24c6e0505f253b5fd367904..52c7727c464fe8b370087be926fc7a4d30068956 100644
--- a/pyAmakCore/classes/environment.py
+++ b/pyAmakCore/classes/environment.py
@@ -16,7 +16,7 @@ class Environment(Schedulable):
 
     def __init__(self) -> None:
         super().__init__()
-        self.scheduler: Scheduler = None
+        self.__scheduler: Scheduler = None
         self.on_initialization()
         # tell scheduler that init is done
         self.give_token_syncro()
@@ -26,15 +26,15 @@ class Environment(Schedulable):
         set scheduler pointer to scheduler
         add add self to schedulables of scheduler
         """
-        self.scheduler = scheduler
-        self.scheduler.add_schedulable(self)
+        self.__scheduler = scheduler
+        self.__scheduler.add_schedulable(self)
 
     def synchronization(self) -> None:
         """
         Unlock Scheduler and wait for his response
         """
         self.give_token_syncro()
-        self.scheduler.take_environment_token()
+        self.__scheduler.take_environment_token()
 
     def cycle(self) -> None:
         """
diff --git a/pyAmakCore/classes/schedulable.py b/pyAmakCore/classes/schedulable.py
index 45d906cfd98594f3447dec26f4d314c88aaaeecc..7cd78bd28568908727fb6e3b5c6b5d93502508b0 100644
--- a/pyAmakCore/classes/schedulable.py
+++ b/pyAmakCore/classes/schedulable.py
@@ -9,7 +9,7 @@ sys.path.insert(0, str(pathlib.Path(__file__).parent))
 from pyAmakCore.exception.override import ToOverrideWarning
 
 
-class Schedulable():
+class Schedulable:
     """
     Class Schedulable
     """
diff --git a/pyAmakCore/classes/scheduler.py b/pyAmakCore/classes/scheduler.py
index 9c20e643c2fbdcc801123126f183c78a54d5a78a..a7c2b593b4f8147a604246af37fbc3c41ee366f4 100644
--- a/pyAmakCore/classes/scheduler.py
+++ b/pyAmakCore/classes/scheduler.py
@@ -11,7 +11,7 @@ sys.path.insert(0, str(pathlib.Path(__file__).parent))
 from pyAmakCore.classes.schedulable import Schedulable
 
 
-class Scheduler():
+class Scheduler:
     """
     Scheduler class, to make sure that environment and amas are always sync together
     """
diff --git a/pyAmakCore/classes/tools/amasIHM.py b/pyAmakCore/classes/tools/amasIHM.py
new file mode 100644
index 0000000000000000000000000000000000000000..5c1a6889566a7cf70374a6cfc999547e0ffe48cf
--- /dev/null
+++ b/pyAmakCore/classes/tools/amasIHM.py
@@ -0,0 +1,36 @@
+"""
+Amas class that need to be used for pyAmakIhm
+"""
+from pyAmakCore.classes.amas import Amas
+from pyAmakCore.classes.environment import Environment
+
+
+class AmasIHM(Amas):
+    """
+    Convenient class to override while using pyAmakIHM
+    """
+
+    def __init__(self, environment: Environment):
+        self.__observer = None
+        super().__init__(environment)
+
+    def get_Agents_Sorted(self):
+        """
+        sort agent by id
+        """
+        agents = self.get_agents()
+        agents.sort(key=lambda x: x.get_id())
+        return agents
+
+    def cycle(self) -> None:
+        """
+        override amas cycle, to update obsever after each cycle
+        """
+        super().cycle()
+        self.__observer.updateCycle(self.get_environment(), self)
+
+    def attach(self, observer: 'Controleur') -> None:
+        """
+        set observer pointer to observer
+        """
+        self.__observer = observer
diff --git a/pyAmakCore/classes/tools/loggable.py b/pyAmakCore/classes/tools/loggable.py
index 19eeb4d2c3e15453b8c4372d9d074b8103bc8acd..094e4f0ab9ce6789398d85a181a4872de0e8b58b 100644
--- a/pyAmakCore/classes/tools/loggable.py
+++ b/pyAmakCore/classes/tools/loggable.py
@@ -2,6 +2,7 @@
 class allowing to save the state of the system at a given moment
 """
 from os import path
+from typing import List
 
 from pandas import DataFrame
 
@@ -13,16 +14,16 @@ class Loggable:
     def __init__(self):
         self.__do_log = False
         self.__file_path = None
+        self.__ignore_attribute = ["_Agent__amas", "_Agent__environment"]
 
-    def to_csv(self, cycle, var_list):
+    def to_csv(self, cycle: int, var_list: List['Agent']) -> None:
         """
         get cycle and agent list and print them
         """
         if not self.__do_log:
             return
 
-        ignore_attribute = ["_Agent__amas", "_Agent__environment"]
-        table = [{**{e: x[e] for e in x if e not in ignore_attribute},
+        table = [{**{e: x[e] for e in x if e not in self.__ignore_attribute},
                   **{'nombre_cycle': cycle}} for x in map(vars, var_list)]
         dataframe = DataFrame(table)
 
@@ -34,8 +35,28 @@ class Loggable:
             else:
                 dataframe.to_csv(path_or_buf=self.__file_path, index=False)
 
-    def set_do_log(self, boolean):
+    def set_do_log(self, boolean: bool) -> None:
+        """
+        tell the amas if it should log or not
+        """
         self.__do_log = boolean
 
-    def set_file_path(self, path_to_file):
+    def set_file_path(self, path_to_file: str) -> None:
+        """
+        specify path to csv
+        """
         self.__file_path = path_to_file
+
+    def add_ignore_attribute(self, attribute: str) -> None:
+        """
+        add attribute in ignored attribute
+        """
+        self.__ignore_attribute.append(attribute)
+
+    def remove_ignore_attribute(self, attribute: str) -> None:
+        """
+        remove attribute in ignored attribute
+        """
+        if attribute not in self.__ignore_attribute:
+            return
+        self.__ignore_attribute.remove(attribute)
diff --git a/pyAmakCore/enumeration/agent_phase.py b/pyAmakCore/enumeration/agent_phase.py
index 56464f8aa0030c6e3fca7cc0ba585b617bbbaa5a..259a21e87d72f749556e4580280c7dc51a30c6ef 100644
--- a/pyAmakCore/enumeration/agent_phase.py
+++ b/pyAmakCore/enumeration/agent_phase.py
@@ -1,3 +1,6 @@
+"""
+Agent phases
+"""
 from enum import Enum, auto
 
 
diff --git a/pyAmakCore/enumeration/executionPolicy.py b/pyAmakCore/enumeration/executionPolicy.py
index 78fc09cd586362c974118a760a6dc53c0fbf6fd2..7adbd01392977e72e0a719d28a1ca57a5283e441 100644
--- a/pyAmakCore/enumeration/executionPolicy.py
+++ b/pyAmakCore/enumeration/executionPolicy.py
@@ -1,3 +1,6 @@
+"""
+Agent execution policy
+"""
 from enum import Enum, auto
 
 
diff --git a/pyAmakCore/tests/test_amas/test_agent.py b/pyAmakCore/tests/test_amas/test_agent.py
index 5726bce9394dd991bd47160002d645f03c2b2c9b..e43150f67f56a23074c9a934c3f706401a997a83 100644
--- a/pyAmakCore/tests/test_amas/test_agent.py
+++ b/pyAmakCore/tests/test_amas/test_agent.py
@@ -8,6 +8,11 @@ from pyAmakCore.classes.amas import Amas
 from pyAmakCore.classes.environment import Environment
 from pyAmakCore.classes.agent import Agent
 
+class SimplerAmas(Amas):
+
+    def synchronization(self):
+        self._Amas__scheduler.give_amas_token()
+        super().synchronization()
 
 class TestAmasAgents(TestCase):
     """
@@ -33,30 +38,31 @@ class TestAmasAgents(TestCase):
         """
 
         environment = Environment()
-        amas = Amas(environment)
+        amas = SimplerAmas(environment)
 
         agent1 = Agent(amas)
         agent2 = Agent(amas)
         agent3 = Agent(amas)
-        agent4 = Agent(amas)
-        agent5 = Agent(amas)
-
         # add 1 agent
         amas.add_agent(agent1)
+        amas.cycle()
         self.assertEqual(amas.get_agents(), [agent1])
 
         # don't remove previous agent
         amas.add_agent(agent2)
+        amas.cycle()
         self.assertEqual(amas.get_agents(), [agent1, agent2])
 
         # add agent in good order
         amas.add_agent(agent3)
+        amas.cycle()
         self.assertEqual(amas.get_agents(), [agent1, agent2, agent3])
 
         # don't add duplicate
         amas.add_agent(agent1)
         amas.add_agent(agent2)
         amas.add_agent(agent3)
+        amas.cycle()
         self.assertEqual(amas.get_agents(), [agent1, agent2, agent3])
 
     def test_add_agents(self) -> None:
@@ -65,7 +71,7 @@ class TestAmasAgents(TestCase):
         """
 
         environment = Environment()
-        amas = Amas(environment)
+        amas = SimplerAmas(environment)
 
         agent1 = Agent(amas)
         agent2 = Agent(amas)
@@ -74,36 +80,43 @@ class TestAmasAgents(TestCase):
         agent5 = Agent(amas)
 
         amas.add_agents([agent1, agent2, agent3, agent4, agent5])
+        amas.cycle()
         self.assertEqual(amas.get_agents(), [agent1, agent2, agent3, agent4, agent5])
 
-        amas = Amas(environment)
+        amas = SimplerAmas(environment)
         amas.add_agents([agent1, agent2])
+        amas.cycle()
         self.assertEqual(amas.get_agents(), [agent1, agent2])
 
         amas.add_agents([agent1, agent2, agent4, agent2, agent3])
+        amas.cycle()
         self.assertEqual(amas.get_agents(), [agent1, agent2, agent4, agent3])
 
     def test_remove_agent(self) -> None:
         environment = Environment()
-        amas = Amas(environment)
+        amas = SimplerAmas(environment)
 
         agent1 = Agent(amas)
         agent2 = Agent(amas)
         agent3 = Agent(amas)
 
         amas.remove_agent(agent2)
+        amas.cycle()
         self.assertEqual(amas.get_agents(), [])
 
         amas.add_agents([agent1, agent2, agent3])
 
         amas.remove_agent(agent2)
+        amas.cycle()
         self.assertEqual(amas.get_agents(), [agent1, agent3])
 
         amas.remove_agent(agent2)
+        amas.cycle()
         self.assertEqual(amas.get_agents(), [agent1, agent3])
 
         amas.remove_agent(agent1)
         amas.remove_agent(agent3)
+        amas.cycle()
         self.assertEqual(amas.get_agents(), [])
 
 
diff --git a/pyAmakCore/tests/test_amas/test_nbr_cycle.py b/pyAmakCore/tests/test_amas/test_nbr_cycle.py
index 7bc3a8e2cb5e871c9b05c15fcf8898fe19eddb00..e4341b38daeb7eb8fa9f24a3bf6f2b0e86e3856e 100644
--- a/pyAmakCore/tests/test_amas/test_nbr_cycle.py
+++ b/pyAmakCore/tests/test_amas/test_nbr_cycle.py
@@ -12,7 +12,7 @@ from pyAmakCore.classes.environment import Environment
 class SimplerAmas(Amas):
 
     def synchronization(self):
-        self.scheduler.give_amas_token()
+        self._Amas__scheduler.give_amas_token()
         super().synchronization()
 
 
diff --git a/pyAmakCore/tests/test_communicating_agent/test_mail.py b/pyAmakCore/tests/test_communicating_agent/test_mail.py
index 9f875811be0ec0334166e2a871e3b480a7f1ffae..444505df65d027c74ab77e81a8d50fa82d365a2f 100644
--- a/pyAmakCore/tests/test_communicating_agent/test_mail.py
+++ b/pyAmakCore/tests/test_communicating_agent/test_mail.py
@@ -15,17 +15,18 @@ class TestMail(TestCase):
         """
         Test mail init
         """
-        mail = Mail(1, 5, None)
+        mail = Mail(1, 5, None, 0)
 
         self.assertEqual(mail.get_id_sender(), 1)
         self.assertEqual(mail.get_id_receiver(), 5)
         self.assertEqual(mail.get_message(), None)
+        self.assertEqual(mail.get_sending_date(), 0)
 
-        mail = Mail(255, 0, "test")
+        mail = Mail(255, 0, "test", 12)
         self.assertEqual(mail.get_id_sender(), 255)
         self.assertEqual(mail.get_id_receiver(), 0)
         self.assertEqual(mail.get_message(), "test")
-
+        self.assertEqual(mail.get_sending_date(), 12)
 
 if __name__ == '__main__':
     main()
diff --git a/release/changelog.txt b/release/changelog.txt
new file mode 100644
index 0000000000000000000000000000000000000000..06af3f7857489efc206e726f505ec486d4a3e29d
--- /dev/null
+++ b/release/changelog.txt
@@ -0,0 +1,12 @@
+v0.0.5:
+ * Fix rare bugs : an agent that would be removed in the cycle could be called by another agent
+ * CSV : Add method : add_ignore_attribute(self, attribute: str) -> None, remove_ignore_attribute(self, attribute: str) -> None
+	to manage ignored attribute
+
+v0.0.4:
+ * add AmasIHM (old examples will no longer work from now on if using AmasIHM )
+
+v0.0.3 :
+ * Add communicating agent
+
+v0.0.2
\ No newline at end of file
diff --git a/release/pyAmakCore-0.0.2-py3-none-any.whl b/release/pyAmakCore-0.0.2-py3-none-any.whl
new file mode 100644
index 0000000000000000000000000000000000000000..6cdca8943d9a7dc1f3bb5b900aea91220a4a16e3
Binary files /dev/null and b/release/pyAmakCore-0.0.2-py3-none-any.whl differ
diff --git a/release/pyAmakCore-0.0.3-py3-none-any.whl b/release/pyAmakCore-0.0.3-py3-none-any.whl
new file mode 100644
index 0000000000000000000000000000000000000000..9a5070130b134c9adc743c60e39fb2ca73374c8e
Binary files /dev/null and b/release/pyAmakCore-0.0.3-py3-none-any.whl differ
diff --git a/release/pyAmakCore-0.0.4-py3-none-any.whl b/release/pyAmakCore-0.0.4-py3-none-any.whl
new file mode 100644
index 0000000000000000000000000000000000000000..904c43441aa8ff18808817250b162d8ea6d94d88
Binary files /dev/null and b/release/pyAmakCore-0.0.4-py3-none-any.whl differ
diff --git a/release/pyAmakCore-0.0.5-py3-none-any.whl b/release/pyAmakCore-0.0.5-py3-none-any.whl
new file mode 100644
index 0000000000000000000000000000000000000000..1475c4083eac33230b399e4722b27ce678b43692
Binary files /dev/null and b/release/pyAmakCore-0.0.5-py3-none-any.whl differ
diff --git a/setup.py b/setup.py
index 58c025a96c70d9f344b9d08422c581a589eb9946..c80c5a1fd15a52b50f6131c38cdf309c329b3c96 100644
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@ from setuptools import setup, find_packages
 setup(
     name='pyAmakCore',
     packages=find_packages(),
-    version='0.0.3',
+    version='0.0.5',
     description='AmakFramework in python',
     author='BE',
     install_requires=[],