diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 00000000..d11bb306
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,13 @@
+## Goal
+What is the purpose of this PR?
+
+## Changes
+What was changed?
+
+## Testing
+How was it tested?
+
+### Checklist
+- [ ] Clear, descriptive PR title
+- [ ] Documentation/README updated (if needed)
+- [ ] No secrets or large temporary files committed
\ No newline at end of file
diff --git a/current-state.txt b/current-state.txt
new file mode 100644
index 00000000..345c3ef0
--- /dev/null
+++ b/current-state.txt
@@ -0,0 +1,3 @@
+version: 1.0
+app: myapp
+replicas: 3
diff --git a/desired-state.txt b/desired-state.txt
new file mode 100644
index 00000000..345c3ef0
--- /dev/null
+++ b/desired-state.txt
@@ -0,0 +1,3 @@
+version: 1.0
+app: myapp
+replicas: 3
diff --git a/healthcheck.sh b/healthcheck.sh
new file mode 100644
index 00000000..f429380d
--- /dev/null
+++ b/healthcheck.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+DESIRED_MD5=$(md5sum desired-state.txt | awk '{print $1}')
+CURRENT_MD5=$(md5sum current-state.txt | awk '{print $1}')
+TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
+
+if [ "$DESIRED_MD5" = "$CURRENT_MD5" ]; then
+ echo "OK: state is synchronized"
+ echo "$TIMESTAMP OK desired=$DESIRED_MD5 current=$CURRENT_MD5" >> health.log
+else
+ echo "CRITICAL: drift detected"
+ echo "$TIMESTAMP CRITICAL desired=$DESIRED_MD5 current=$CURRENT_MD5" >> health.log
+fi
diff --git a/labs/submission4.md b/labs/submission4.md
new file mode 100644
index 00000000..c7c3c31c
--- /dev/null
+++ b/labs/submission4.md
@@ -0,0 +1,180 @@
+# Lab 4 — Submission
+
+## Task 1 — Operating System Analysis
+
+---
+
+### 1.1 Boot Performance Analysis
+
+```text
+systemd-analyze
+Startup finished in 3.212s (userspace)
+graphical.target reached after 3.159s in userspace.
+```
+
+```text
+systemd-analyze blame | head -n 10
+6.849s apt-daily-upgrade.service
+1.487s landscape-client.service
+751ms dev-sdd.device
+659ms snapd.seeded.service
+513ms snapd.service
+383ms wsl-pro.service
+```
+
+```text
+uptime
+16:43:28 up 9 min, 1 user, load average: 0.02, 0.06, 0.02
+```
+
+```text
+w
+USER TTY LOGIN@ IDLE WHAT
+krasand pts/1 16:34 9:23 -bash
+```
+
+**Observations:**
+
+- The system booted in approximately 3 seconds (userspace), which is expected for WSL.
+- The longest starting service was `apt-daily-upgrade.service`.
+- Load average values are very low, indicating the system is mostly idle.
+- Only one active user session is present.
+
+---
+
+### 1.2 Process Forensics
+
+```text
+ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head -n 6
+613 1 /usr/bin/python3 ... 0.9 0.0
+217 1 /usr/bin/python3 ... 0.6 0.0
+897 1 /usr/libexec/packagekitd 0.5 0.0
+```
+
+```text
+ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%cpu | head -n 6
+1 0 /sbin/init 0.3 0.3
+613 1 /usr/bin/python3 ... 0.9 0.0
+```
+
+**Top memory-consuming process:**
+`/usr/bin/python3` (system service process).
+
+**Observations:**
+
+- Memory and CPU usage are minimal.
+- The system is not under load.
+- Processes consuming memory are mostly background services.
+
+---
+
+### 1.3 Memory Analysis
+
+```text
+free -h
+Mem: 3.3Gi total, 440Mi used, 2.8Gi free
+Swap: 1.0Gi total, 0B used
+```
+
+```text
+MemTotal: 3459304 kB
+MemAvailable: 3008040 kB
+SwapTotal: 1048576 kB
+```
+
+**Observations:**
+
+- Most memory is available (~2.9Gi).
+- Swap is configured but not used.
+- The system has sufficient free memory.
+
+---
+
+### 1.4 User Sessions
+
+```text
+who -a
+system boot 2026-02-27 16:34
+krasand pts/1 2026-02-27 16:34
+```
+
+```text
+last -n 5
+reboot system boot 6.6.87.2-microsoft ...
+```
+
+**Observations:**
+
+- Only one user session is active.
+- Recent system activity shows WSL reboots.
+- No unusual login activity detected.
+
+---
+
+## Task 2 — Networking Analysis
+
+---
+
+### 2.1 Network Path Tracing
+
+```text
+traceroute github.com
+1 172.26.160.XXX
+2 10.240.16.XXX
+3 10.250.0.XXX
+...
+18 r1-fra3-de.as5405.net (94.103.180.24)
+19 cust-sid436.fra3-de.as5405.net (45.153.82.37)
+```
+
+```text
+dig github.com
+
+ANSWER SECTION:
+github.com. IN A 140.82.121.4
+```
+
+**Observations:**
+
+- The route includes private internal network hops (10.x.x.x and 172.x.x.x) before reaching public internet routers.
+- DNS resolution confirms `github.com` resolves to IP address `140.82.121.4`.
+
+---
+
+### 2.2 Packet Capture (DNS Traffic)
+
+```text
+sudo tcpdump -c 5 -i any 'port 53' -nn
+
+Out IP 172.26.162.XXX.58057 > 172.26.160.XXX.53: A? google.com.
+In IP 172.26.160.XXX.53 > 172.26.162.XXX.58057: A 172.217.19.238
+```
+
+**Observations:**
+
+- The packet capture shows a DNS query for `google.com`.
+- The response contains the resolved IP address.
+- Local IP addresses were partially masked for privacy.
+
+---
+
+### 2.3 Reverse DNS Lookup
+
+```text
+dig -x 8.8.4.4
+
+ANSWER SECTION:
+4.4.8.8.in-addr.arpa. PTR dns.google.
+```
+
+```text
+dig -x 1.1.2.2
+
+status: NXDOMAIN
+```
+
+**Observations:**
+
+- The IP address `8.8.4.4` resolves to `dns.google`, confirming it belongs to Google DNS.
+- The IP address `1.1.2.2` does not have a PTR record (NXDOMAIN).
+- Reverse DNS depends on whether a PTR record is configured for the IP address.
\ No newline at end of file
diff --git a/labs/submission5.md b/labs/submission5.md
new file mode 100644
index 00000000..b331a7a9
--- /dev/null
+++ b/labs/submission5.md
@@ -0,0 +1,172 @@
+# Lab 5 --- Virtualization and System Analysis
+
+## Platform
+
+Virtual Machine running **Ubuntu 24.04 LTS** inside **Oracle
+VirtualBox**.
+
+------------------------------------------------------------------------
+
+# Task 2 --- System Analysis
+
+## Operating System Information
+
+### Command
+
+ uname -a
+
+### Output
+
+ Linux andrey-VirtualBox 6.17.0-14-generic #14~24.04.1-Ubuntu SMP PREEMPT_DYNAMIC Thu Jan 15 15:52:10 UTC x86_64 x86_64 x86_64 GNU/Linux
+
+### Detailed OS information
+
+Command
+
+ cat /etc/os-release
+
+Output
+
+ PRETTY_NAME="Ubuntu 24.04.4 LTS"
+ NAME="Ubuntu"
+ VERSION_ID="24.04"
+ VERSION="24.04.4 LTS (Noble Numbat)"
+ VERSION_CODENAME=noble
+ ID=ubuntu
+ ID_LIKE=debian
+
+### Conclusion
+
+The system is running **Ubuntu 24.04.4 LTS (Noble Numbat)**.
+
+------------------------------------------------------------------------
+
+# CPU Information
+
+### Command
+
+ lscpu
+
+### Key Information
+
+- Architecture: **x86_64**
+- CPU Model: **AMD Ryzen 5 3500U with Radeon Vega Mobile Gfx**
+- CPU cores allocated to VM: **2**
+- Virtualization type: **full**
+- Hypervisor vendor: **KVM**
+
+### Conclusion
+
+The virtual machine is using **2 virtual CPU cores provided by the host
+machine**.
+
+------------------------------------------------------------------------
+
+# Memory Information
+
+### Command
+
+ free -h
+
+### Output
+
+ Mem: 3.8Gi total
+ Used: 1.0Gi
+ Free: 1.3Gi
+ Swap: 3.8Gi
+
+### Conclusion
+
+The virtual machine has:
+
+- **3.8 GB RAM**
+- **3.8 GB swap memory**
+
+Memory usage is relatively low.
+
+------------------------------------------------------------------------
+
+# Storage Information
+
+### Command
+
+ lsblk
+
+### Output
+
+ sda 25G disk
+ └─sda2 25G mounted on /
+
+### Disk Usage
+
+Command
+
+ df -h
+
+Output
+
+ Filesystem Size Used Avail Use%
+ /dev/sda2 25G 9.5G 14G 41%
+
+### Conclusion
+
+The system uses a **25 GB virtual disk**, with **14 GB available free
+space**.
+
+------------------------------------------------------------------------
+
+# Network Configuration
+
+### Command
+
+ ip a
+
+### Key Information
+
+Network interface:
+
+ enp0s3
+
+IP address:
+
+ 10.0.2.15
+
+### Conclusion
+
+The VM is connected to the network using **VirtualBox NAT networking**.
+
+------------------------------------------------------------------------
+
+# Virtualization Detection
+
+### Command
+
+ systemd-detect-virt
+
+### Output
+
+ oracle
+
+### Conclusion
+
+The operating system correctly detects that it is running inside
+**Oracle VirtualBox virtualization environment**.
+
+------------------------------------------------------------------------
+
+# Final Summary
+
+This lab demonstrated system inspection inside a virtual machine
+environment.
+
+The analyzed system has:
+
+- Ubuntu **24.04 LTS**
+- **2 virtual CPU cores**
+- **\~4 GB RAM**
+- **25 GB virtual disk**
+- NAT network configuration
+- Virtualization platform: **Oracle VirtualBox**
+
+The system tools successfully detected the virtualization environment
+and provided detailed information about system resources.
diff --git a/labs/submission6.md b/labs/submission6.md
new file mode 100644
index 00000000..30af210e
--- /dev/null
+++ b/labs/submission6.md
@@ -0,0 +1,371 @@
+# Lab 6 — Docker Fundamentals
+
+## Task 1 — Container Lifecycle & Image Management
+
+### Existing containers
+
+```text
+docker ps -a
+
+CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
+```
+
+### Pull Ubuntu image
+
+```text
+docker pull ubuntu:latest
+docker images ubuntu
+
+REPOSITORY TAG IMAGE ID CREATED SIZE
+ubuntu latest c35e29c94501 2 weeks ago 78.1MB
+```
+
+### Run Ubuntu container and inspect it
+
+```text
+docker run -it --name ubuntu_container ubuntu:latest
+```
+
+Inside the container:
+
+```text
+cat /etc/os-release
+
+PRETTY_NAME="Ubuntu 24.04.4 LTS"
+NAME="Ubuntu"
+VERSION_ID="24.04"
+VERSION="24.04.4 LTS (Noble Numbat)"
+VERSION_CODENAME=noble
+ID=ubuntu
+ID_LIKE=debian
+UBUNTU_CODENAME=noble
+```
+
+```text
+ps aux
+
+USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
+root 1 0.0 0.0 4112 3328 pts/0 Ss 23:47 0:00 /bin/bash
+root 15 0.0 0.0 8540 4352 pts/0 R+ 23:47 0:00 ps aux
+```
+
+### Save image to tar archive
+
+```text
+docker save -o ubuntu_image.tar ubuntu:latest
+ls -lh ubuntu_image.tar
+
+-rw------- 1 andrey andrey 77M Mar 27 02:48 ubuntu_image.tar
+```
+
+### Attempt to remove image while container still exists
+
+```text
+docker rmi ubuntu:latest
+
+Error response from daemon: conflict: unable to remove repository reference "ubuntu:latest" (must force) - container 0bdbca25355e is using its referenced image c35e29c94501bc21680f16e27d3d4769a04f34057d0b8d2ad278b5e4efea5f8d
+```
+
+### Remove container and then remove image
+
+```text
+docker rm ubuntu_container
+docker rmi ubuntu:latest
+
+ubuntu_container
+Untagged: ubuntu:latest
+Deleted: sha256:c35e29c94501bc21680f16e27d3d4769a04f34057d0b8d2ad278b5e4efea5f8d
+```
+
+### Analysis
+
+The Ubuntu image size is **78.1 MB**, while the exported archive size is **77 MB**.
+Docker does not allow removing an image if an existing container still references it. This protects the consistency of container metadata and prevents breaking containers created from that image.
+The file `ubuntu_image.tar` stores the Docker image data in portable form, including image layers and metadata, so it can be transferred or loaded on another machine.
+
+---
+
+## Task 2 — Custom Image Creation & Analysis
+
+### Run nginx and inspect the default page
+
+```text
+docker run -d -p 80:80 --name nginx_container nginx
+curl http://localhost
+```
+
+Default page output:
+
+```html
+
+
+
+Welcome to nginx!
+...
+Welcome to nginx!
+...
+
+```
+
+### Custom HTML file
+
+```html
+
+
+The best
+
+
+website
+
+
+```
+
+### Copy the new page into the container
+
+```text
+docker cp index.html nginx_container:/usr/share/nginx/html/
+curl http://localhost
+```
+
+Updated page output:
+
+```html
+
+
+The best
+
+
+website
+
+
+```
+
+### Commit the modified container into a new image
+
+```text
+docker commit nginx_container my_website:latest
+docker images my_website
+
+REPOSITORY TAG IMAGE ID CREATED SIZE
+my_website latest 546b46f55510 Less than a second ago 161MB
+```
+
+### Remove old container and run new image
+
+```text
+docker rm -f nginx_container
+docker run -d -p 80:80 --name my_website_container my_website:latest
+curl http://localhost
+```
+
+Output:
+
+```html
+
+
+The best
+
+
+website
+
+
+```
+
+### Inspect filesystem changes
+
+```text
+docker diff my_website_container
+
+C /etc
+C /etc/nginx
+C /etc/nginx/conf.d
+C /etc/nginx/conf.d/default.conf
+C /run
+C /run/nginx.pid
+```
+
+### Analysis
+
+The custom page was successfully embedded into a new image called `my_website:latest`.
+In `docker diff`, the letter `C` means **changed**. In general:
+- `A` = added
+- `C` = changed
+- `D` = deleted
+
+`docker commit` creates an image from the current state of a container, but it is not reproducible or easy to track in version control.
+A **Dockerfile** is usually better in real projects because it is declarative, repeatable, and easier to review, automate, and maintain.
+
+---
+
+## Task 3 — Container Networking & Service Discovery
+
+### Create a user-defined bridge network
+
+```text
+docker network create lab_network
+docker network ls
+
+NETWORK ID NAME DRIVER SCOPE
+acde0a6bea4a bridge bridge local
+5efe57884f34 host host local
+a977719bf87a lab_network bridge local
+8c5654fe4655 none null local
+```
+
+### Run two Alpine containers on that network
+
+```text
+docker run -dit --network lab_network --name container1 alpine ash
+docker run -dit --network lab_network --name container2 alpine ash
+```
+
+### Verify connectivity between containers
+
+```text
+docker exec container1 ping -c 3 container2
+
+PING container2 (172.18.0.3): 56 data bytes
+64 bytes from 172.18.0.3: seq=0 ttl=64 time=1.021 ms
+64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.108 ms
+64 bytes from 172.18.0.3: seq=2 ttl=64 time=0.088 ms
+
+--- container2 ping statistics ---
+3 packets transmitted, 3 packets received, 0% packet loss
+round-trip min/avg/max = 0.088/0.405/1.021 ms
+```
+
+### Inspect network details
+
+```text
+docker network inspect lab_network
+```
+
+Relevant part of the output:
+
+```text
+"Subnet": "172.18.0.0/16",
+"Gateway": "172.18.0.1"
+
+"Containers": {
+ ...
+ "Name": "container1",
+ "IPv4Address": "172.18.0.2/16",
+ ...
+ "Name": "container2",
+ "IPv4Address": "172.18.0.3/16"
+}
+```
+
+### Verify Docker DNS name resolution
+
+```text
+docker exec container1 nslookup container2
+
+Server: 127.0.0.11
+Address: 127.0.0.11:53
+
+Non-authoritative answer:
+Name: container2
+Address: 172.18.0.3
+```
+
+### Analysis
+
+The two containers can communicate over the custom bridge network by container name.
+Docker provides an internal DNS service for user-defined networks, so `container1` can resolve `container2` automatically.
+A user-defined bridge network is better than the default bridge because it provides built-in DNS-based service discovery and better isolation.
+
+---
+
+## Task 4 — Data Persistence with Volumes
+
+### Create a named volume
+
+```text
+docker volume create app_data
+docker volume ls
+
+DRIVER VOLUME NAME
+local app_data
+```
+
+### Start nginx with the volume mounted
+
+```text
+docker run -d -p 8080:80 -v app_data:/usr/share/nginx/html --name web nginx
+curl http://localhost:8080
+```
+
+Initial output:
+
+```html
+
+
+
+Welcome to nginx!
+...
+Welcome to nginx!
+...
+
+```
+
+### Create a persistent HTML page
+
+```html
+Persistent Data
+```
+
+### Copy the file into the container and verify it
+
+```text
+docker cp index.html web:/usr/share/nginx/html/
+curl http://localhost:8080
+```
+
+Output:
+
+```html
+Persistent Data
+```
+
+### Remove the container and start a new one with the same volume
+
+```text
+docker stop web
+docker rm web
+docker run -d -p 8080:80 -v app_data:/usr/share/nginx/html --name web_new nginx
+sleep 3
+curl http://localhost:8080
+```
+
+Output after recreation:
+
+```html
+Persistent Data
+```
+
+### Inspect the volume
+
+```text
+docker volume inspect app_data
+
+[
+ {
+ "CreatedAt": "2026-03-27T02:57:31+03:00",
+ "Driver": "local",
+ "Mountpoint": "/var/lib/docker/volumes/app_data/_data",
+ "Name": "app_data",
+ "Scope": "local"
+ }
+]
+```
+
+### Analysis
+
+The HTML page remained available after deleting the first container and starting a new one with the same volume. This demonstrates persistent storage outside the container lifecycle.
+
+Docker volumes are useful for application data that must survive container recreation.
+Compared to other storage options:
+- **Volumes** are managed by Docker and are recommended for persistent application data.
+- **Bind mounts** map a host directory directly into a container.
+- **Container storage** is ephemeral and is lost when the container is removed.
diff --git a/labs/submission7.md b/labs/submission7.md
new file mode 100644
index 00000000..384887e8
--- /dev/null
+++ b/labs/submission7.md
@@ -0,0 +1,293 @@
+# Lab 7 — GitOps Simulation
+
+## Task 1 — Git State Reconciliation
+
+### Initial desired state
+
+`desired-state.txt`
+
+```text
+version: 1.0
+app: myapp
+replicas: 3
+```
+
+### Initial current state
+
+`current-state.txt`
+
+```text
+version: 1.0
+app: myapp
+replicas: 3
+```
+
+### Reconciliation script
+
+`reconcile.sh`
+
+```bash
+#!/bin/bash
+
+if cmp -s desired-state.txt current-state.txt; then
+ echo "States are synchronized."
+else
+ echo "Drift detected."
+ cp desired-state.txt current-state.txt
+ echo "Reconciliation completed."
+fi
+```
+
+### Manual drift simulation
+
+Modified `current-state.txt`:
+
+```text
+version: 2.0
+app: myapp
+replicas: 10
+```
+
+Difference before reconciliation:
+
+```text
+1c1
+< version: 1.0
+---
+> version: 2.0
+3c3
+< replicas: 3
+---
+> replicas: 10
+```
+
+Reconciliation output:
+
+```text
+Drift detected.
+Reconciliation completed.
+```
+
+State after reconciliation:
+
+```text
+version: 1.0
+app: myapp
+replicas: 3
+```
+
+### Continuous reconciliation loop
+
+A watch-based loop was started with:
+
+```bash
+watch -n 5 ./reconcile.sh
+```
+
+Then `current-state.txt` was modified again:
+
+```text
+version: 1.0
+app: myapp
+replicas: 3
+replicas: 10
+```
+
+The reconciliation loop automatically restored the correct state. Final synchronized state:
+
+```text
+version: 1.0
+app: myapp
+replicas: 3
+```
+
+### Analysis
+
+The reconciliation loop continuously compares the current state with the desired state and restores the system when drift is detected. This simulates the core GitOps idea: Git (or the desired-state file in this lab) acts as the single source of truth.
+
+By automatically correcting changes, reconciliation reduces configuration drift and keeps the system consistent over time.
+
+### Reflection
+
+Declarative configuration is preferable to imperative commands in production because it defines **what the final state should be**, rather than **how to reach it**. This makes systems easier to audit, version, reproduce, and automatically recover when unexpected changes occur.
+
+---
+
+## Task 2 — GitOps Health Monitoring
+
+### Health check script
+
+`healthcheck.sh`
+
+```bash
+#!/bin/bash
+
+DESIRED_MD5=$(md5sum desired-state.txt | awk '{print $1}')
+CURRENT_MD5=$(md5sum current-state.txt | awk '{print $1}')
+TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
+
+if [ "$DESIRED_MD5" = "$CURRENT_MD5" ]; then
+ echo "OK: state is synchronized"
+ echo "$TIMESTAMP OK desired=$DESIRED_MD5 current=$CURRENT_MD5" >> health.log
+else
+ echo "CRITICAL: drift detected"
+ echo "$TIMESTAMP CRITICAL desired=$DESIRED_MD5 current=$CURRENT_MD5" >> health.log
+fi
+```
+
+### Healthy state check
+
+Output of `./healthcheck.sh` when both files matched:
+
+```text
+OK: state is synchronized
+```
+
+Initial log entry:
+
+```text
+2026-03-27 05:58:54 OK desired=a15a1a4f965ecd8f9e23a33a6b543155 current=a15a1a4f965ecd8f9e23a33a6b543155
+```
+
+### Drifted state check
+
+Drift was introduced with:
+
+```bash
+echo "unapproved-change: true" >> current-state.txt
+```
+
+Modified state:
+
+```text
+version: 1.0
+app: myapp
+replicas: 3
+unapproved-change: true
+```
+
+Health check output:
+
+```text
+CRITICAL: drift detected
+```
+
+Log after drift:
+
+```text
+2026-03-27 05:58:54 OK desired=a15a1a4f965ecd8f9e23a33a6b543155 current=a15a1a4f965ecd8f9e23a33a6b543155
+2026-03-27 06:01:41 CRITICAL desired=a15a1a4f965ecd8f9e23a33a6b543155 current=48168ff3ab5ffc0214e81c7e2ee356f5
+```
+
+### Recovery after drift
+
+Reconciliation and health check:
+
+```text
+Drift detected.
+Reconciliation completed.
+OK: state is synchronized
+```
+
+Log after recovery:
+
+```text
+2026-03-27 05:58:54 OK desired=a15a1a4f965ecd8f9e23a33a6b543155 current=a15a1a4f965ecd8f9e23a33a6b543155
+2026-03-27 06:01:41 CRITICAL desired=a15a1a4f965ecd8f9e23a33a6b543155 current=48168ff3ab5ffc0214e81c7e2ee356f5
+2026-03-27 06:03:17 OK desired=a15a1a4f965ecd8f9e23a33a6b543155 current=a15a1a4f965ecd8f9e23a33a6b543155
+```
+
+### Monitor loop script
+
+`monitor.sh`
+
+```bash
+#!/bin/bash
+
+for i in {1..10}; do
+ echo "Iteration $i"
+ ./healthcheck.sh
+ ./reconcile.sh
+ sleep 3
+done
+```
+
+### Monitor loop execution
+
+Before running the monitor, drift was introduced again:
+
+```text
+version: 1.0
+app: myapp
+replicas: 3
+replicas: 99
+```
+
+Output of `./monitor.sh`:
+
+```text
+Iteration 1
+CRITICAL: drift detected
+Drift detected.
+Reconciliation completed.
+Iteration 2
+OK: state is synchronized
+States are synchronized.
+Iteration 3
+OK: state is synchronized
+States are synchronized.
+Iteration 4
+OK: state is synchronized
+States are synchronized.
+Iteration 5
+OK: state is synchronized
+States are synchronized.
+Iteration 6
+OK: state is synchronized
+States are synchronized.
+Iteration 7
+OK: state is synchronized
+States are synchronized.
+Iteration 8
+OK: state is synchronized
+States are synchronized.
+Iteration 9
+OK: state is synchronized
+States are synchronized.
+Iteration 10
+OK: state is synchronized
+States are synchronized.
+```
+
+Final `health.log`:
+
+```text
+2026-03-27 05:58:54 OK desired=a15a1a4f965ecd8f9e23a33a6b543155 current=a15a1a4f965ecd8f9e23a33a6b543155
+2026-03-27 06:01:41 CRITICAL desired=a15a1a4f965ecd8f9e23a33a6b543155 current=48168ff3ab5ffc0214e81c7e2ee356f5
+2026-03-27 06:03:17 OK desired=a15a1a4f965ecd8f9e23a33a6b543155 current=a15a1a4f965ecd8f9e23a33a6b543155
+2026-03-27 06:05:08 OK desired=a15a1a4f965ecd8f9e23a33a6b543155 current=a15a1a4f965ecd8f9e23a33a6b543155
+2026-03-27 06:05:58 CRITICAL desired=a15a1a4f965ecd8f9e23a33a6b543155 current=93d541ce03f5304eec60b2363acf80c9
+2026-03-27 06:06:01 OK desired=a15a1a4f965ecd8f9e23a33a6b543155 current=a15a1a4f965ecd8f9e23a33a6b543155
+2026-03-27 06:06:04 OK desired=a15a1a4f965ecd8f9e23a33a6b543155 current=a15a1a4f965ecd8f9e23a33a6b543155
+2026-03-27 06:06:08 OK desired=a15a1a4f965ecd8f9e23a33a6b543155 current=a15a1a4f965ecd8f9e23a33a6b543155
+2026-03-27 06:06:11 OK desired=a15a1a4f965ecd8f9e23a33a6b543155 current=a15a1a4f965ecd8f9e23a33a6b543155
+2026-03-27 06:06:14 OK desired=a15a1a4f965ecd8f9e23a33a6b543155 current=a15a1a4f965ecd8f9e23a33a6b543155
+2026-03-27 06:06:17 OK desired=a15a1a4f965ecd8f9e23a33a6b543155 current=a15a1a4f965ecd8f9e23a33a6b543155
+2026-03-27 06:06:20 OK desired=a15a1a4f965ecd8f9e23a33a6b543155 current=a15a1a4f965ecd8f9e23a33a6b543155
+2026-03-27 06:06:23 OK desired=a15a1a4f965ecd8f9e23a33a6b543155 current=a15a1a4f965ecd8f9e23a33a6b543155
+2026-03-27 06:06:27 OK desired=a15a1a4f965ecd8f9e23a33a6b543155 current=a15a1a4f965ecd8f9e23a33a6b543155
+```
+
+Final synchronized state:
+
+```text
+version: 1.0
+app: myapp
+replicas: 3
+```
+
+### Analysis
+
+Checksums provide a simple and reliable way to detect whether two configuration files are identical. If the MD5 hashes differ, the system can immediately identify that drift has occurred.
+
+This is conceptually similar to the Sync Status in tools such as ArgoCD and Flux: the desired state is compared with the observed state, and a mismatch is reported as unhealthy or out of sync.
diff --git a/labs/test b/labs/test
new file mode 100644
index 00000000..2a99ea22
--- /dev/null
+++ b/labs/test
@@ -0,0 +1 @@
+test commit
diff --git a/monitor.sh b/monitor.sh
new file mode 100644
index 00000000..946bc35d
--- /dev/null
+++ b/monitor.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+for i in {1..10}; do
+ echo "Iteration $i"
+ ./healthcheck.sh
+ ./reconcile.sh
+ sleep 3
+done
diff --git a/reconcile.sh b/reconcile.sh
new file mode 100644
index 00000000..951858b2
--- /dev/null
+++ b/reconcile.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+if cmp -s desired-state.txt current-state.txt; then
+ echo "States are synchronized."
+else
+ echo "Drift detected."
+ cp desired-state.txt current-state.txt
+ echo "Reconciliation completed."
+fi