diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 00000000..366384db
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,16 @@
+## Goal
+
+
+## Changes
+
+
+## Testing
+
+
+## Notes (Optional)
+
+
+## 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/.github/workflows/github-actions-demo.yml b/.github/workflows/github-actions-demo.yml
new file mode 100644
index 00000000..503ab041
--- /dev/null
+++ b/.github/workflows/github-actions-demo.yml
@@ -0,0 +1,25 @@
+name: GitHub Actions Demo
+run-name: ${{ github.actor }} is testing out GitHub Actions 🚀
+on: [push, workflow_dispatch]
+jobs:
+ Explore-GitHub-Actions:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Gather system information
+ run: |
+ uname -a
+ nproc
+ free -h
+ df -h
+ cat /proc/cpuinfo | head -20
+ - run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
+ - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
+ - run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
+ - name: Check out repository code
+ uses: actions/checkout@v5
+ - run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
+ - run: echo "🖥️ The workflow is now ready to test your code on the runner."
+ - name: List files in the repository
+ run: |
+ ls ${{ github.workspace }}
+ - run: echo "🍏 This job's status is ${{ job.status }}."
diff --git a/images/screenshots/screenshot1.png b/images/screenshots/screenshot1.png
new file mode 100644
index 00000000..fdef7ba4
Binary files /dev/null and b/images/screenshots/screenshot1.png differ
diff --git a/images/screenshots/screenshot2.png b/images/screenshots/screenshot2.png
new file mode 100644
index 00000000..fd461d13
Binary files /dev/null and b/images/screenshots/screenshot2.png differ
diff --git a/images/screenshots/screenshot3.png b/images/screenshots/screenshot3.png
new file mode 100644
index 00000000..e04ff150
Binary files /dev/null and b/images/screenshots/screenshot3.png differ
diff --git a/images/screenshots/screenshot4.png b/images/screenshots/screenshot4.png
new file mode 100644
index 00000000..d3a1dce2
Binary files /dev/null and b/images/screenshots/screenshot4.png differ
diff --git a/labs/submission1.md b/labs/submission1.md
new file mode 100644
index 00000000..c87a020d
--- /dev/null
+++ b/labs/submission1.md
@@ -0,0 +1,36 @@
+# Signing commits (Task1)
+
+## Short summary
+
+Signing commits ensures that the commit was made by the true author and that its contents have not been changed.
+
+## Proofs
+
+
+
+```
+platon@arch ~> ls .ssh/id_*
+.ssh/id_ed25519 .ssh/id_ed25519.pub
+```
+
+
+
+## Why is commit signing important in DevOps workflows?
+1. Confirms the author's identity
+2. Commit immutability
+3. Can configure the pipeline to only allow verified commits
+
+---
+# PR (Task2)
+
+## Analysis of how PR templates improve collaboration.
+
+Templates help maintain a consistent PR structure so that everyone working on the project can easily analyze any PR, and PR is probably a kind of documentation.
+Also, checklists help, typical human errors are corrected even before merging.
+
+## Proofs
+
+
+
+
+
\ No newline at end of file
diff --git a/labs/submission2.md b/labs/submission2.md
new file mode 100644
index 00000000..08cd7928
--- /dev/null
+++ b/labs/submission2.md
@@ -0,0 +1,317 @@
+# Lab2
+
+## Task 1
+
+
+### Outputs from terminal
+
+
+Output
+
+```sh
+platon@arch ~/D/DevOps-Intro (main)> git log --oneline -3
+f98c674 (HEAD -> main) chore: add test file
+ac316a7 (origin/main, origin/feature/lab1, origin/HEAD, feature/lab1) docs(submission1.md): add task2 proofs
+0763882 docs(submission1.md): add task2
+platon@arch ~/D/DevOps-Intro (main)> git cat-file -p f98c674
+tree 209296c6dd01bc86ecacc4e62d3dfdb5750ab716
+parent ac316a7816b62cdddbd7d32729b5112eff61deb8
+author Platon U. 1770797024 +0300
+committer Platon U. 1770797024 +0300
+gpgsig -----BEGIN SSH SIGNATURE-----
+ U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgnLrvPmJtc1KnCYWG1RuJdtDzLJ
+ ABmeZefbw5NoH1Nj0AAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5
+ AAAAQMHaHsbT8qblMtZYoKuQtvgOfOtsSuYB8k8ysYPInSOsH5N2g8E2XS4nGfyfCGH67w
+ 9pvBrD43AhxQQ0fd5FUAw=
+ -----END SSH SIGNATURE-----
+
+chore: add test file
+platon@arch ~/D/DevOps-Intro (main)> git cat-file -p 209296c6dd01bc86ecacc4e62d3dfdb5750ab716
+040000 tree e17290e5ed9e98452e0563ed37f3f36cbe8138bd .github
+100644 blob 6e60bebec0724892a7c82c52183d0a7b467cb6bb README.md
+040000 tree a1061247fd38ef2a568735939f86af7b1000f83c app
+040000 tree cb32363119d52d7a1d2b8974bdc8890c5ff7ad05 images
+040000 tree 182b748e8fc19a10326e6c8aba98bdf84791adbd labs
+040000 tree d3fb3722b7a867a83efde73c57c49b5ab3e62c63 lectures
+100644 blob 2eec599a1130d2ff231309bb776d1989b97c6ab2 test.txt
+platon@arch ~/D/DevOps-Intro (main)> git cat-file -p 2eec599a1130d2ff231309bb776d1989b97c6ab2
+Test content
+```
+
+
+
+### Explanation of what each object type represents
+`Blob`: show raw content of file
+
+`Tree`: it's "directory" -- list of blobs and other trees with permissions and names of files
+
+`Commit`: it's pointer which show -- tree+author+message+link to parent
+
+### Analysis of how Git stores repository data
+
+Git stores a full snapshot of the repo for each commit, not diffs. But identicaly content stored only once -- if the file hasn't changed, the commit's tree simply references the existing blob
+
+
+## Task 2
+
+### Outputs from terminal
+
+
+Output
+
+```sh
+platon@arch ~/D/DevOps-Intro (main)> git switch -c git-reset-practice
+ echo "First commit" > file.txt && git add file.txt && git commit -m "First commit"
+ echo "Second commit" >> file.txt && git add file.txt && git commit -m "Second commit"
+ echo "Third commit" >> file.txt && git add file.txt && git commit -m "Third commit"
+Switched to a new branch 'git-reset-practice'
+[git-reset-practice 9931ac0] First commit
+ 1 file changed, 1 insertion(+)
+ create mode 100644 file.txt
+[git-reset-practice 182ed31] Second commit
+ 1 file changed, 1 insertion(+)
+[git-reset-practice e15aeb8] Third commit
+ 1 file changed, 1 insertion(+)
+platon@arch ~/D/DevOps-Intro (git-reset-practice)> git reset --soft HEAD^
+platon@arch ~/D/DevOps-Intro (git-reset-practice)> git log --oneline -3
+98e89c0 (HEAD -> git-reset-practice) Second commit
+e134d25 First commit
+f98c674 (main) chore: add test file
+platon@arch ~/D/DevOps-Intro (git-reset-practice)> git reset --hard HEAD^
+HEAD is now at e134d25 First commit
+platon@arch ~/D/DevOps-Intro (git-reset-practice)> git log --oneline -3
+e134d25 (HEAD -> git-reset-practice) First commit
+f98c674 (main) chore: add test file
+ac316a7 (origin/main, origin/feature/lab1, origin/HEAD, feature/lab1) docs(submission1.md): add task2 proofs
+platon@arch ~/D/DevOps-Intro (git-reset-practice)> git reflog
+e134d25 (HEAD -> git-reset-practice) HEAD@{0}: reset: moving to HEAD^
+98e89c0 HEAD@{1}: reset: moving to HEAD^
+90a5679 HEAD@{2}: commit: Third commit
+98e89c0 HEAD@{3}: commit: Second commit
+e134d25 (HEAD -> git-reset-practice) HEAD@{4}: commit: First commit
+f98c674 (main) HEAD@{5}: checkout: moving from main to git-reset-practice
+f98c674 (main) HEAD@{6}: commit: chore: add test file
+ac316a7 (origin/main, origin/feature/lab1, origin/HEAD, feature/lab1) HEAD@{7}: pull origin feature/lab1: Fast-forward
+3b71c57 HEAD@{8}: checkout: moving from feature/lab1 to main
+ac316a7 (origin/main, origin/feature/lab1, origin/HEAD, feature/lab1) HEAD@{9}: commit: docs(submission1.md): add task2 proofs
+0763882 HEAD@{10}: commit: docs(submission1.md): add task2
+3b71c57 HEAD@{11}: checkout: moving from main to feature/lab1
+3b71c57 HEAD@{12}: commit: chore: add PR template
+839a326 HEAD@{13}: checkout: moving from feature/lab1 to main
+839a326 HEAD@{14}: checkout: moving from main to feature/lab1
+839a326 HEAD@{15}: commit: docs: add second proof(screenshot with **Verified**)
+002455b HEAD@{16}: commit: docs: add commit signing summary
+d6b6a03 HEAD@{17}: clone: from github.com:revlze/DevOps-Intro.git
+platon@arch ~/D/DevOps-Intro (git-reset-practice)> git reset --hard 90a5679
+HEAD is now at 90a5679 Third commit
+platon@arch ~/D/DevOps-Intro (git-reset-practice)> git log --oneline -3
+90a5679 (HEAD -> git-reset-practice) Third commit
+98e89c0 Second commit
+e134d25 First commit
+platon@arch ~/D/DevOps-Intro (git-reset-practice)>
+```
+
+
+### What changed in the working tree, index, and history for each reset
+
+`git reset --soft HEAD^`: HEAD moved from Third to Second commit. Working tree and index untouched -- Third commit changes stayed staged (ready to commit again). History lost Third commit from `git log`.
+
+`git reset --hard HEAD^`: HEAD moved from Second to First commit. Working tree and index both wiped -- Second commit changes gone from disk. History lost Second commit from `git log`. File `file.txt` now only contains "First commit".
+
+### Analysis of recovery process using reflog
+
+After both resets, `git log` shows only First commit -- Second and Third are "gone". But `git reflog` still tracks every HEAD movement:
+```
+90a5679 HEAD@{2}: commit: Third commit
+98e89c0 HEAD@{3}: commit: Second commit
+```
+
+Ran `git reset --hard 90a5679` to recover all three commits. `git log` now shows First → Second → Third again.
+
+## Task 3
+
+### Output from terminal
+
+
+Output
+
+```sh
+platon@arch ~/D/DevOps-Intro (main)> git switch -c side-branch
+Switched to a new branch 'side-branch'
+platon@arch ~/D/DevOps-Intro (side-branch)> echo "Branch commit" >> history.txt
+platon@arch ~/D/DevOps-Intro (side-branch)> git add history.txt && git commit -m "Side branch commit"
+[side-branch cb8397c] Side branch commit
+ 1 file changed, 1 insertion(+)
+ create mode 100644 history.txt
+platon@arch ~/D/DevOps-Intro (side-branch)> git switch -
+Switched to branch 'main'
+Your branch is ahead of 'origin/main' by 1 commit.
+ (use "git push" to publish your local commits)
+platon@arch ~/D/DevOps-Intro (main)> echo "Main commit" >> main.txt
+platon@arch ~/D/DevOps-Intro (main)> git add main.txt && git commit -m "Main branch commit"
+[main 87da990] Main branch commit
+ 1 file changed, 1 insertion(+)
+ create mode 100644 main.txt
+platon@arch ~/D/DevOps-Intro (main)> git log --oneline --graph --all
+* 87da990 (HEAD -> main) Main branch commit
+| * cb8397c (side-branch) Side branch commit
+|/
+* f98c674 chore: add test file
+* ac316a7 (origin/main, origin/feature/lab1, origin/HEAD, feature/lab1) docs(submission1.md): add task2 proofs
+* 0763882 docs(submission1.md): add task2
+* 3b71c57 chore: add PR template
+* 839a326 docs: add second proof(screenshot with **Verified**)
+* 002455b docs: add commit signing summary
+* d6b6a03 Update lab2
+* 87810a0 feat: remove old Exam Exemption Policy
+* 1e1c32b feat: update structure
+* 6c27ee7 feat: publish lecs 9 & 10
+* 1826c36 feat: update lab7
+* 3049f08 feat: publish lec8
+* da8f635 feat: introduce all labs and revised structure
+* 04b174e feat: publish lab and lec #5
+* 67f12f1 feat: publish labs 4&5, revise others
+* 82d1989 feat: publish lab3 and lec3
+* 3f80c83 feat: publish lec2
+* 499f2ba feat: publish lab2
+* af0da89 feat: update lab1
+* 74a8c27 Publish lab1
+* f0485c0 Publish lec1
+* 31dd11b Publish README.md
+```
+
+
+
+Output `git log --all --oneline`
+
+```sh
+platon@arch ~/D/DevOps-Intro (main)> git log --all --oneline
+87da990 (HEAD -> main) Main branch commit
+cb8397c (side-branch) Side branch commit
+f98c674 chore: add test file
+ac316a7 (origin/main, origin/feature/lab1, origin/HEAD, feature/lab1) docs(submission1.md): add task2 proofs
+0763882 docs(submission1.md): add task2
+3b71c57 chore: add PR template
+839a326 docs: add second proof(screenshot with **Verified**)
+002455b docs: add commit signing summary
+d6b6a03 Update lab2
+87810a0 feat: remove old Exam Exemption Policy
+1e1c32b feat: update structure
+6c27ee7 feat: publish lecs 9 & 10
+1826c36 feat: update lab7
+3049f08 feat: publish lec8
+da8f635 feat: introduce all labs and revised structure
+04b174e feat: publish lab and lec #5
+67f12f1 feat: publish labs 4&5, revise others
+82d1989 feat: publish lab3 and lec3
+3f80c83 feat: publish lec2
+499f2ba feat: publish lab2
+af0da89 feat: update lab1
+74a8c27 Publish lab1
+f0485c0 Publish lec1
+31dd11b Publish README.md
+```
+
+
+
+### Reflection on how the graph aids understanding
+The graph shows where each branch points and how commits relate to each other -- makes it easy to spot diverged branches, merges, and parallel work instead of reading simple log output.
+
+
+
+## Task 4
+
+### Output terminal
+
+```sh
+platon@arch ~/D/DevOps-Intro (main)> git tag v1.0.0
+platon@arch ~/D/DevOps-Intro (main)> git push origin v1.0.0
+Total 0 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
+To github.com:revlze/DevOps-Intro.git
+ * [new tag] v1.0.0 -> v1.0.0
+```
+
+### Tag and associated commit
+
+| Tag | Commit hash | Message |
+| -------- | ----------- | ------------------------------------ |
+| `v1.0.0` | `ac316a7` | docs(submission1.md): add task2 proofs |
+
+### Why tags matter
+
+Tags pin a human-readable version label to an exact commit, which is essential for release management. CI/CD pipelines often trigger builds and deployments on tag pushes (e.g. `v*`), and tags serve as anchors for generating changelogs and release notes.
+
+## Task 5
+
+### git switch (modern — branch switching)
+
+```sh
+platon@arch ~/D/DevOps-Intro (main)> git switch -c cmd-compare
+Switched to a new branch 'cmd-compare'
+platon@arch ~/D/DevOps-Intro (cmd-compare)> git switch -
+Switched to branch 'main'
+```
+
+### git checkout (legacy — overloaded)
+
+```sh
+platon@arch ~/D/DevOps-Intro (main)> git checkout -b cmd-compare-2
+Switched to a new branch 'cmd-compare-2'
+platon@arch ~/D/DevOps-Intro (cmd-compare-2)> git status
+On branch cmd-compare-2
+Untracked files:
+ (use "git add ..." to include in what will be committed)
+ labs/submission2.md
+
+nothing added to commit but untracked files present (use "git add" to track)
+platon@arch ~/D/DevOps-Intro (cmd-compare-2)> git branch
+ cmd-compare
+* cmd-compare-2
+ feature/lab1
+ main
+ side-branch
+```
+
+### git restore (modern — file operations)
+
+```sh
+platon@arch ~/D/DevOps-Intro (main)> echo "scratch" >> demo.txt
+platon@arch ~/D/DevOps-Intro (main)> git status
+Changes not staged for commit:
+ modified: demo.txt
+platon@arch ~/D/DevOps-Intro (main)> git restore demo.txt
+platon@arch ~/D/DevOps-Intro (main)> git status
+nothing added to commit but untracked files present
+
+platon@arch ~/D/DevOps-Intro (main)> echo "scratch" >> demo.txt
+platon@arch ~/D/DevOps-Intro (main)> git add demo.txt
+platon@arch ~/D/DevOps-Intro (main)> git status
+Changes to be committed:
+ modified: demo.txt
+platon@arch ~/D/DevOps-Intro (main)> git restore --staged demo.txt
+platon@arch ~/D/DevOps-Intro (main)> git status
+Changes not staged for commit:
+ modified: demo.txt
+
+platon@arch ~/D/DevOps-Intro (main)> git restore --source=HEAD^ demo.txt
+platon@arch ~/D/DevOps-Intro (main)> git status
+Changes not staged for commit:
+ deleted: demo.txt
+```
+
+### When to use each command
+
+`git switch` — use for branch operations only: creating, switching, toggling between branches. It's focused and won't accidentally touch files.
+
+`git checkout` — legacy command that handles both branches (`-b`) and files (`-- `). Still works, but its dual purpose makes it confusing and error-prone. Avoid in new workflows.
+
+`git restore` — use for file operations only: discarding working tree changes, unstaging files (`--staged`), or restoring a file from another commit (`--source`). It replaced the ambiguous `git checkout -- ` syntax.
+
+## Task 6
+
+### GitHub Community
+
+Starring a repo bookmarks it and signals appreciation to maintainers -- high star count boosts project visibility, attracts contributors, and serves as a trust indicator in the open-source ecosystem.
+
+Following developers keeps their activity (commits, new repos, stars) in your feed, which helps stay in sync with teammates during projects and exposes you to new tools and patterns from experienced engineers.
+
diff --git a/labs/submission3.md b/labs/submission3.md
new file mode 100644
index 00000000..3309a7a9
--- /dev/null
+++ b/labs/submission3.md
@@ -0,0 +1,133 @@
+# Lab 3
+
+## Task 1
+
+### Task 1.1
+
+I followed the [GitHub Actions quickstart guide](https://docs.github.com/en/actions/quickstart) and created a workflow file at `.github/workflows/github-actions-demo.yml`.
+
+**Workflow file contents:**
+
+```yaml
+name: GitHub Actions Demo
+run-name: ${{ github.actor }} is testing out GitHub Actions
+on: [push]
+jobs:
+ Explore-GitHub-Actions:
+ runs-on: ubuntu-latest
+ steps:
+ - run: echo "The job was automatically triggered by a ${{ github.event_name }} event."
+ - run: echo "This job is now running on a ${{ runner.os }} server hosted by GitHub!"
+ - run: echo "The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
+ - name: Check out repository code
+ uses: actions/checkout@v5
+ - run: echo "The ${{ github.repository }} repository has been cloned to the runner."
+ - run: echo "The workflow is now ready to test your code on the runner."
+ - name: List files in the repository
+ run: |
+ ls ${{ github.workspace }}
+ - run: echo "This job's status is ${{ job.status }}."
+```
+
+**Key concepts learned:**
+
+- **Workflow** — an automated process defined in a YAML file inside `.github/workflows/`. Triggered by events, schedules, or manually.
+- **Job** — a set of steps that execute on the same runner. In this workflow there is one job: `Explore-GitHub-Actions`.
+- **Step** — an individual task within a job. Can be a shell command (`run:`) or a reusable action (`uses:`).
+- **Runner** — a virtual machine (hosted by GitHub) that executes the job. Here we use `ubuntu-latest`.
+- **Trigger** — the event that starts the workflow. Here it is `push` — any push to any branch triggers the workflow.
+- **Action** — a reusable unit of code (e.g. `actions/checkout@v5` clones the repository onto the runner).
+
+### Task 1.2
+
+**Successful run link:** [GitHub Actions Demo — Run #22031908377](https://github.com/revlze/DevOps-Intro/actions/runs/22031908377)
+
+**What caused the run to trigger:**
+The workflow was triggered by a `push` event — I committed and pushed the workflow file to the `feature/lab3` branch. Since the trigger is `on: [push]`, any push to any branch starts the workflow.
+
+**Workflow execution analysis:**
+
+1. GitHub detected the push event and found the workflow file in `.github/workflows/`.
+2. A fresh `ubuntu-latest` runner was provisioned.
+3. The job `Explore-GitHub-Actions` started executing steps sequentially:
+ - Printed event metadata (event type, OS, branch, repo).
+ - Checked out the repository code using `actions/checkout@v5`.
+ - Listed the repository files in the workspace.
+ - Reported the final job status as `success`.
+4. The entire workflow completed in ~6 seconds.
+
+---
+
+## Task 2
+
+### Task 2.1
+
+Added `workflow_dispatch` trigger to the workflow file to enable manual runs:
+
+```yaml
+on: [push, workflow_dispatch]
+```
+
+### Task 2.2
+
+**Manual dispatch run link:** [GitHub Actions Demo — Run #22032552231](https://github.com/revlze/DevOps-Intro/actions/runs/22032552231)
+
+The workflow was triggered manually via the Actions tab using the "Run workflow" button.
+
+**Manual vs automatic triggers comparison:**
+
+| Aspect | `push` trigger | `workflow_dispatch` trigger |
+|--------|---------------|----------------------------|
+| How it starts | Automatically on every push | Manually via Actions tab |
+| Use case | CI on every code change | On-demand runs, debugging, deployments |
+| `github.event_name` | `push` | `workflow_dispatch` |
+| Branch selection | Determined by the push | Selected manually in the UI |
+
+### Task 2.3
+
+Added a "Gather system information" step to the workflow:
+
+```yaml
+- name: Gather system information
+ run: |
+ uname -a
+ nproc
+ free -h
+ df -h
+ cat /proc/cpuinfo | head -20
+```
+
+**System information output from runner:**
+
+```
+Linux runnervmjduv7 6.14.0-1017-azure #17~24.04.1-Ubuntu SMP Mon Dec 1 20:10:50 UTC 2025 x86_64 GNU/Linux
+4
+ total used free shared buff/cache available
+Mem: 15Gi 799Mi 13Gi 38Mi 1.8Gi 14Gi
+Swap: 3.0Gi 0B 3.0Gi
+Filesystem Size Used Avail Use% Mounted on
+/dev/root 145G 53G 92G 37% /
+tmpfs 7.9G 84K 7.9G 1% /dev/shm
+```
+
+**CPU info:**
+
+```
+vendor_id : AuthenticAMD
+model name : AMD EPYC 7763 64-Core Processor
+cpu MHz : 3246.381
+cache size : 512 KB
+cpu cores : 2
+siblings : 4
+```
+
+**Runner environment analysis:**
+
+- **OS:** Ubuntu 24.04.3 LTS running on Azure (kernel 6.14.0-1017-azure)
+- **CPU:** AMD EPYC 7763, 4 vCPUs (2 physical cores with SMT), ~3.2 GHz
+- **RAM:** 16 GB total, ~14 GB available
+- **Disk:** 145 GB root partition, 92 GB free
+- **Runner version:** 2.331.0
+- **Region:** Azure East US
+
+The GitHub-hosted runner provides a fairly powerful VM — enough for most CI tasks like building, testing, and deploying typical projects.