diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
deleted file mode 100644
index 09fb0c371ec331db74fb0194bd182594d91b9a30..0000000000000000000000000000000000000000
--- a/.gitlab-ci.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-stages:
-  - build
-  - test
-  - deploy
-
-build:
-  stage: build
-  script:
-    - docker build -t myproject .
-
-test:
-  stage: test
-  script:
-    - docker run myproject pytest
-
- script:
-    - echo "Deploying the application..."
-    # Add deployment scripts here
-    - scp docker-compose.yml $DEPLOY_USER@$DEPLOY_SERVER:/path/to/deployment
-    - ssh $DEPLOY_USER@$DEPLOY_SERVER 'docker-compose down && docker-compose up -d'
diff --git a/README.md b/README.md
index 534cb06053e7fc7b8725455d42045a02a2d5f5ad..2c713280234490c3e1d3d5b5bc79a122b771aeaf 100644
--- a/README.md
+++ b/README.md
@@ -15,18 +15,17 @@ All folders are isolated projects. `cd` into the folder to run/build them.
 1. Install [python](https://www.python.org/downloads/) (version 3.11.5)
 2. Install [poetry](https://python-poetry.org/docs/#installation) (version 1.7.1)
 3. Install [docker](https://docs.docker.com/engine/install/). If you want to run docker as non-root user then you need to add it to the docker group (see [documentation](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user)).
-4. We are storing Docker images at GitLab's integrated container registry by running:
-
-        docker login git.imp.fu-berlin.de:5000 -u <GITLAB_USERNAME> -p <TOKEN> 
-*Some Project Access Tokens are available and will be provided to members.*
-
-5. From the root directory of this repo, run
+4. From the root directory of this repo, run
  
         make init
 
 #### Do this happily ever after
-
+1. Start a (new) shell and activate the virtual environment
     poetry shell
+2. We are storing Docker images at GitLab's integrated container registry by running:
+
+        docker login git.imp.fu-berlin.de:5000 -u <GITLAB_USERNAME> -p <TOKEN> 
+*Some Project Access Tokens are available and will be provided to members.*
 
 ## Local development
 ### jobs
@@ -46,8 +45,13 @@ For live experience (meaning you enter the container), run:
 
 If you change code in `src`, you need to rebuild the image with `bash build/build_image.sh`. The `src` folder can also be mounted in the image, but the assumption is that life is already difficult as it is...
 
-### tasks
+### tasks (! Under construction !)
 
 Tasks are python scripts that can spawn jobs which run in docker containers. Before calling a task, make sure you have built the related job-image. 
 
-    python -B src/a-task.py local --config=docker.yaml --IN0 demo-inputs/system.json --OUT /tmp/test-a-task
\ No newline at end of file
+    python -B src/a_task.py local --config=docker.yaml --IN0 demo-inputs/system.json --OUT /tmp/test-a-task
+
+##### TODO for jung
+- [] Figure out `docker-compose` and `MinIO` to transfer docker images from `jobs` to `tasks`
+- [] Setup CI/CD pipeline with `.gitlab-ci.yml` (File removed for the time being)
+- [] Deploy where? (pypi or docker hub or GitLab package registry)
\ No newline at end of file
diff --git a/docker-compose.yaml b/docker-compose.yaml
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..5d6a5422810efdeeaa55244f6b1f1c1800c0d9ab 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -0,0 +1,18 @@
+version: '3.4'
+services:
+  minio:
+    image: minio/minio
+    container_name: minio-s3
+    environment:
+      MINIO_ROOT_USER: minioadmin
+      MINIO_ROOT_PASSWORD: minioadmin
+    ports:
+      - '9000:9000'
+      - '9001:9001'
+    command: server /data --console-address ":9001"
+    volumes:
+      - minio_data:/data
+
+# let docker handle persistence of the data directory
+volumes:
+  minio_data: {}
\ No newline at end of file
diff --git a/jobs/src/a_job.py b/jobs/src/a_job.py
index 6445a2c91007c1d48e90c71dcf46f370631aad27..e07abb83f00f815e0323f342eee2edad63c0be52 100644
--- a/jobs/src/a_job.py
+++ b/jobs/src/a_job.py
@@ -4,5 +4,25 @@ Just some toy code for demonstration
 import numpy as np
 
 
-def id_func(x: np.ndarray) -> np.ndarray:
-    return x * np.ones(x.shape)
+def sigma_x() -> np.ndarray:
+    """
+    Pauli gate X (or NOT gate) 
+    """
+
+    return np.array([[0, 1], [1, 0]])
+
+
+def sigma_y() -> np.ndarray:
+    """
+    Pauli gate Y
+    """
+
+    return np.array([[0, -1j], [1j, 0]])
+
+
+def sigma_z() -> np.ndarray:
+    """
+    Pauli gate Z
+    """
+
+    return np.array([[1, 0], [0, -1]])
diff --git a/jobs/unittests/test_a_job.py b/jobs/unittests/test_a_job.py
index 519f3c2fe80d0960dff38769c731b08aa5ff2768..83b0b3b721a5dab962750c50b44fe82a86275cf6 100644
--- a/jobs/unittests/test_a_job.py
+++ b/jobs/unittests/test_a_job.py
@@ -3,14 +3,39 @@ import unittest
 
 import numpy as np
 
-from src.a_job import id_func
+from src.a_job import sigma_x, sigma_y, sigma_z
 
 logger = logging.getLogger(__name__)
+logging.basicConfig(level=logging.INFO)
 
 
 class AJobTest(unittest.TestCase):
 
     def test_a_job(self):
-        a_vector = np.ndarray([1, 2, 3])
-        self.assertEqual(id_func(a_vector), a_vector)
-        logger.info("Test passes")
+        """
+        Test functionalities of Pauli gates on single qubits
+        """
+        qubit_0 = np.array([1, 0])
+        qubit_1 = np.array([0, 1])
+
+        # ensure input is a single qubit
+        self.assertTrue(qubit_0.shape[0] == 2)
+        self.assertTrue(qubit_1.shape[0] == 2)
+
+        # test Pauli gate X
+        self.assertTrue(np.array_equal(np.dot(sigma_x(), qubit_0), qubit_1))
+        self.assertTrue(np.array_equal(np.dot(sigma_x(), qubit_1), qubit_0))
+
+        # test Pauli gate Y
+        self.assertTrue(np.array_equal(np.dot(sigma_y(), qubit_0), 1j * qubit_1))
+        self.assertTrue(np.array_equal(np.dot(sigma_y(), qubit_1), -1j * qubit_0))
+
+        # test Pauli gate Z
+        self.assertTrue(np.array_equal(np.dot(sigma_z(), qubit_0), qubit_0))
+        self.assertTrue(np.array_equal(np.dot(sigma_z(), qubit_1), -qubit_1))
+
+        logger.info("Logging for fun!")
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tasks/docker.yaml b/tasks/docker.yaml
index b8d7412984e8f23c93d9d8c9891c56d1f4a0a7db..63076dceffda35fd549e8dae323130184db0e57e 100644
--- a/tasks/docker.yaml
+++ b/tasks/docker.yaml
@@ -1,5 +1,5 @@
 backend:
-  name: docker
+  name: docker-dev
   kind: docker
   release: local
   transport:
@@ -7,10 +7,25 @@ backend:
     kind: s3
     url: s3+http://minioadmin:minioadmin@127.0.0.1:9000/test
     remoteUrl: s3+http://minioadmin:minioadmin@127.0.0.1:9000/test
+  imageSpecs:
+    "git.imp.fu-berlin.de:5000/comp-sci-project:local":
+      network_mode: host
+      volumes:
+        ../jobs/src:
+          bind: /usr/src/app/src
+          mode: ro
   defaultSpecs:
     network_mode: host
     maxCpu: 4
-    environment:
-      NUMPROCS: 3  # no cpu+1
+
+plugins:
+  - kind: logging
+  - kind: resources
+  - kind: metrics
+    name: honeycomb
+    host: https://api.honeycomb.io
+    apiKey: 1X7YfLO8iH3zevALRjxL5F
+    dataset: honeycomb-python-example
+  - kind: storage
 
 numJobs: 3
diff --git a/tasks/integration-tests/test_a_task.py b/tasks/integration-tests/test_a_task.py
index bb56fc0f19fe12154b54a43152dd30a7ec102f8e..93c36b9915a1fb8a3d677b4c80101c326753adcf 100644
--- a/tasks/integration-tests/test_a_task.py
+++ b/tasks/integration-tests/test_a_task.py
@@ -1,2 +1,43 @@
-class TestATask:
-    pass
+import logging
+import unittest
+
+import numpy as np
+
+from src.a_task import swap_gate
+
+logger = logging.getLogger(__name__)
+logging.basicConfig(level=logging.INFO)
+
+
+class ATaskTest(unittest.TestCase):
+
+    def test_a_task(self):
+        """
+        Test functionalities of swap gate on 2-qubits
+        """
+
+        qubit_0 = np.array([1, 0])
+        qubit_1 = np.array([0, 1])
+
+        qubit_00 = np.kron(qubit_0, qubit_0)
+        qubit_11 = np.kron(qubit_1, qubit_1)
+        qubit_01 = np.kron(qubit_0, qubit_1)
+        qubit_10 = np.kron(qubit_1, qubit_0)
+
+        # ensure input is a 2-qubit
+        self.assertTrue(qubit_00.shape[0] == 4)
+        self.assertTrue(qubit_01.shape[0] == 4)
+        self.assertTrue(qubit_10.shape[0] == 4)
+        self.assertTrue(qubit_11.shape[0] == 4)
+
+        self.assertTrue(np.array_equal(np.dot(swap_gate(), qubit_00), qubit_00))
+        self.assertTrue(np.array_equal(np.dot(swap_gate(), qubit_11), qubit_11))
+
+        self.assertTrue(np.array_equal(np.dot(swap_gate(), qubit_01), qubit_10))
+        self.assertTrue(np.array_equal(np.dot(swap_gate(), qubit_10), qubit_01))
+
+        logger.info("Logging for fun!")
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tasks/src/a-task.py b/tasks/src/a-task.py
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/tasks/src/a_task.py b/tasks/src/a_task.py
new file mode 100644
index 0000000000000000000000000000000000000000..7a53867f8638f139220c922834d9baa02a370b0f
--- /dev/null
+++ b/tasks/src/a_task.py
@@ -0,0 +1,16 @@
+"""
+This module implements the SWAP gate using the Pauli gates
+Example:
+    python -B src/a_task.py local --config=docker-dev.yaml --IN0 demo-inputs/a_2_qubit.txt --OUT /tmp/test-a-task
+"""
+
+import numpy as np
+
+from jobs.src.a_job import sigma_x, sigma_y, sigma_z
+
+
+def swap_gate() -> np.ndarray:
+
+    swap_matrix = (np.kron(np.identity(2), np.identity(2)) + np.kron(sigma_x(), sigma_x()) +
+                   np.kron(sigma_y(), sigma_y()) + np.kron(sigma_z(), sigma_z()))
+    return swap_matrix