From 0a1f8a50cd039426718cfac2a3534c25e6e01e54 Mon Sep 17 00:00:00 2001 From: Katharina Sick Date: Sun, 31 May 2026 21:11:46 +0200 Subject: [PATCH] Publish Lex Imperfecta, Beginner Signed-off-by: Katharina Sick --- .../devcontainer.json | 13 +++++--- .../post-create.sh | 2 +- .../post-start.sh | 4 +-- .../README.md | 5 +-- .../beginner/Makefile | 0 .../beginner/manifests/pods/compliant.yaml | 0 .../manifests/pods/missing-labels.yaml | 0 .../beginner/manifests/pods/peregrinus.yaml | 0 .../pods/privileged-init-container.yaml | 0 .../beginner/manifests/pods/privileged.yaml | 0 .../policies/no-privileged-containers.yaml | 0 .../manifests/policies/require-labels.yaml | 0 .../policies/stamp-travel-permit.yaml | 0 .../beginner/verify.sh | 6 ++-- .../docs/beginner.yaml | 8 ++--- .../docs/index.yaml | 2 +- infra/tracker/main.go | 33 ++++++++++++++----- lib/scripts/tracker.sh | 14 +++++++- 18 files changed, 59 insertions(+), 28 deletions(-) rename {adventures/planned/00-lex-imperfecta/beginner/.devcontainer/00-lex-imperfecta_01-beginner => .devcontainer/05-lex-imperfecta_01-beginner}/devcontainer.json (51%) rename {adventures/planned/00-lex-imperfecta/beginner/.devcontainer/00-lex-imperfecta_01-beginner => .devcontainer/05-lex-imperfecta_01-beginner}/post-create.sh (88%) rename {adventures/planned/00-lex-imperfecta/beginner/.devcontainer/00-lex-imperfecta_01-beginner => .devcontainer/05-lex-imperfecta_01-beginner}/post-start.sh (81%) rename adventures/{planned/00-lex-imperfecta => 05-lex-imperfecta}/README.md (81%) rename adventures/{planned/00-lex-imperfecta => 05-lex-imperfecta}/beginner/Makefile (100%) rename adventures/{planned/00-lex-imperfecta => 05-lex-imperfecta}/beginner/manifests/pods/compliant.yaml (100%) rename adventures/{planned/00-lex-imperfecta => 05-lex-imperfecta}/beginner/manifests/pods/missing-labels.yaml (100%) rename adventures/{planned/00-lex-imperfecta => 05-lex-imperfecta}/beginner/manifests/pods/peregrinus.yaml (100%) rename adventures/{planned/00-lex-imperfecta => 05-lex-imperfecta}/beginner/manifests/pods/privileged-init-container.yaml (100%) rename adventures/{planned/00-lex-imperfecta => 05-lex-imperfecta}/beginner/manifests/pods/privileged.yaml (100%) rename adventures/{planned/00-lex-imperfecta => 05-lex-imperfecta}/beginner/manifests/policies/no-privileged-containers.yaml (100%) rename adventures/{planned/00-lex-imperfecta => 05-lex-imperfecta}/beginner/manifests/policies/require-labels.yaml (100%) rename adventures/{planned/00-lex-imperfecta => 05-lex-imperfecta}/beginner/manifests/policies/stamp-travel-permit.yaml (100%) rename adventures/{planned/00-lex-imperfecta => 05-lex-imperfecta}/beginner/verify.sh (97%) rename adventures/{planned/00-lex-imperfecta => 05-lex-imperfecta}/docs/beginner.yaml (94%) rename adventures/{planned/00-lex-imperfecta => 05-lex-imperfecta}/docs/index.yaml (95%) diff --git a/adventures/planned/00-lex-imperfecta/beginner/.devcontainer/00-lex-imperfecta_01-beginner/devcontainer.json b/.devcontainer/05-lex-imperfecta_01-beginner/devcontainer.json similarity index 51% rename from adventures/planned/00-lex-imperfecta/beginner/.devcontainer/00-lex-imperfecta_01-beginner/devcontainer.json rename to .devcontainer/05-lex-imperfecta_01-beginner/devcontainer.json index 4d4b95cb..c3522112 100644 --- a/adventures/planned/00-lex-imperfecta/beginner/.devcontainer/00-lex-imperfecta_01-beginner/devcontainer.json +++ b/.devcontainer/05-lex-imperfecta_01-beginner/devcontainer.json @@ -1,16 +1,19 @@ { - "name": "⚖️ Adventure 00 | 🟢 Beginner (The Twelve Tables)", + "name": "⚖️ Adventure 05 | 🟢 Beginner (The Twelve Tables)", "image": "mcr.microsoft.com/devcontainers/base:bullseye", - "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}/adventures/planned/00-lex-imperfecta/beginner", + "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}/adventures/05-lex-imperfecta/beginner", "features": { "ghcr.io/devcontainers/features/docker-in-docker:2": {} }, - "postCreateCommand": "bash /workspaces/${localWorkspaceFolderBasename}/.devcontainer/00-lex-imperfecta_01-beginner/post-create.sh", - "postStartCommand": "bash /workspaces/${localWorkspaceFolderBasename}/.devcontainer/00-lex-imperfecta_01-beginner/post-start.sh", + "postCreateCommand": "bash /workspaces/${localWorkspaceFolderBasename}/.devcontainer/05-lex-imperfecta_01-beginner/post-create.sh", + "postStartCommand": "bash /workspaces/${localWorkspaceFolderBasename}/.devcontainer/05-lex-imperfecta_01-beginner/post-start.sh", "customizations": { "codespaces": { "openFiles": [ - "adventures/planned/00-lex-imperfecta/README.md" + "adventures/05-lex-imperfecta/README.md", + "adventures/05-lex-imperfecta/beginner/manifests/policies/no-privileged-containers.yaml", + "adventures/05-lex-imperfecta/beginner/manifests/policies/require-labels.yaml", + "adventures/05-lex-imperfecta/beginner/manifests/policies/stamp-travel-permit.yaml" ], "permissions": { "codespaces": "write" diff --git a/adventures/planned/00-lex-imperfecta/beginner/.devcontainer/00-lex-imperfecta_01-beginner/post-create.sh b/.devcontainer/05-lex-imperfecta_01-beginner/post-create.sh similarity index 88% rename from adventures/planned/00-lex-imperfecta/beginner/.devcontainer/00-lex-imperfecta_01-beginner/post-create.sh rename to .devcontainer/05-lex-imperfecta_01-beginner/post-create.sh index 6063a72a..43a0f2e8 100755 --- a/adventures/planned/00-lex-imperfecta/beginner/.devcontainer/00-lex-imperfecta_01-beginner/post-create.sh +++ b/.devcontainer/05-lex-imperfecta_01-beginner/post-create.sh @@ -5,7 +5,7 @@ REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" # shellcheck disable=SC1091 source "$REPO_ROOT/lib/scripts/tracker.sh" -set_tracking_context "lex-imperfecta" "beginner" +set_tracking_context "lex-imperfecta" "beginner" "05" "06" "2026" track_container_created "$REPO_ROOT/lib/shared/init.sh" --version v0.17.0 diff --git a/adventures/planned/00-lex-imperfecta/beginner/.devcontainer/00-lex-imperfecta_01-beginner/post-start.sh b/.devcontainer/05-lex-imperfecta_01-beginner/post-start.sh similarity index 81% rename from adventures/planned/00-lex-imperfecta/beginner/.devcontainer/00-lex-imperfecta_01-beginner/post-start.sh rename to .devcontainer/05-lex-imperfecta_01-beginner/post-start.sh index 2af937b7..3b07fd7d 100755 --- a/adventures/planned/00-lex-imperfecta/beginner/.devcontainer/00-lex-imperfecta_01-beginner/post-start.sh +++ b/.devcontainer/05-lex-imperfecta_01-beginner/post-start.sh @@ -2,7 +2,7 @@ set -e REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" -CHALLENGE_DIR="$REPO_ROOT/adventures/planned/00-lex-imperfecta/beginner" +CHALLENGE_DIR="$REPO_ROOT/adventures/05-lex-imperfecta/beginner" echo "✨ Starting Lex Imperfecta - Beginner Level" @@ -16,5 +16,5 @@ kubectl apply -f "$CHALLENGE_DIR/manifests/pods/" 2>&1 || true # shellcheck disable=SC1091 source "$REPO_ROOT/lib/scripts/tracker.sh" -set_tracking_context "lex-imperfecta" "beginner" +set_tracking_context "lex-imperfecta" "beginner" "05" "06" "2026" track_container_initialized diff --git a/adventures/planned/00-lex-imperfecta/README.md b/adventures/05-lex-imperfecta/README.md similarity index 81% rename from adventures/planned/00-lex-imperfecta/README.md rename to adventures/05-lex-imperfecta/README.md index 1d48f125..ad7c1ebf 100644 --- a/adventures/planned/00-lex-imperfecta/README.md +++ b/adventures/05-lex-imperfecta/README.md @@ -1,4 +1,4 @@ -# ⚖️ Adventure 00: Lex Imperfecta +# ⚖️ Adventure 05: Lex Imperfecta The Roman Republic has built a sophisticated legal system to protect its citizens — but the laws were written in haste, and the exceptions were written too generously. Policies go unenforced, the wrong citizens are exempt, and @@ -12,4 +12,5 @@ The entire **infrastructure is pre-provisioned in your Codespace** ## 🚀 Ready to Start? -[Choose your level](https://offon.dev/adventures/lex-imperfecta/) and begin learning! +Head over to the [challenge docs](https://offon.dev/adventures/lex-imperfecta/) for more information. + diff --git a/adventures/planned/00-lex-imperfecta/beginner/Makefile b/adventures/05-lex-imperfecta/beginner/Makefile similarity index 100% rename from adventures/planned/00-lex-imperfecta/beginner/Makefile rename to adventures/05-lex-imperfecta/beginner/Makefile diff --git a/adventures/planned/00-lex-imperfecta/beginner/manifests/pods/compliant.yaml b/adventures/05-lex-imperfecta/beginner/manifests/pods/compliant.yaml similarity index 100% rename from adventures/planned/00-lex-imperfecta/beginner/manifests/pods/compliant.yaml rename to adventures/05-lex-imperfecta/beginner/manifests/pods/compliant.yaml diff --git a/adventures/planned/00-lex-imperfecta/beginner/manifests/pods/missing-labels.yaml b/adventures/05-lex-imperfecta/beginner/manifests/pods/missing-labels.yaml similarity index 100% rename from adventures/planned/00-lex-imperfecta/beginner/manifests/pods/missing-labels.yaml rename to adventures/05-lex-imperfecta/beginner/manifests/pods/missing-labels.yaml diff --git a/adventures/planned/00-lex-imperfecta/beginner/manifests/pods/peregrinus.yaml b/adventures/05-lex-imperfecta/beginner/manifests/pods/peregrinus.yaml similarity index 100% rename from adventures/planned/00-lex-imperfecta/beginner/manifests/pods/peregrinus.yaml rename to adventures/05-lex-imperfecta/beginner/manifests/pods/peregrinus.yaml diff --git a/adventures/planned/00-lex-imperfecta/beginner/manifests/pods/privileged-init-container.yaml b/adventures/05-lex-imperfecta/beginner/manifests/pods/privileged-init-container.yaml similarity index 100% rename from adventures/planned/00-lex-imperfecta/beginner/manifests/pods/privileged-init-container.yaml rename to adventures/05-lex-imperfecta/beginner/manifests/pods/privileged-init-container.yaml diff --git a/adventures/planned/00-lex-imperfecta/beginner/manifests/pods/privileged.yaml b/adventures/05-lex-imperfecta/beginner/manifests/pods/privileged.yaml similarity index 100% rename from adventures/planned/00-lex-imperfecta/beginner/manifests/pods/privileged.yaml rename to adventures/05-lex-imperfecta/beginner/manifests/pods/privileged.yaml diff --git a/adventures/planned/00-lex-imperfecta/beginner/manifests/policies/no-privileged-containers.yaml b/adventures/05-lex-imperfecta/beginner/manifests/policies/no-privileged-containers.yaml similarity index 100% rename from adventures/planned/00-lex-imperfecta/beginner/manifests/policies/no-privileged-containers.yaml rename to adventures/05-lex-imperfecta/beginner/manifests/policies/no-privileged-containers.yaml diff --git a/adventures/planned/00-lex-imperfecta/beginner/manifests/policies/require-labels.yaml b/adventures/05-lex-imperfecta/beginner/manifests/policies/require-labels.yaml similarity index 100% rename from adventures/planned/00-lex-imperfecta/beginner/manifests/policies/require-labels.yaml rename to adventures/05-lex-imperfecta/beginner/manifests/policies/require-labels.yaml diff --git a/adventures/planned/00-lex-imperfecta/beginner/manifests/policies/stamp-travel-permit.yaml b/adventures/05-lex-imperfecta/beginner/manifests/policies/stamp-travel-permit.yaml similarity index 100% rename from adventures/planned/00-lex-imperfecta/beginner/manifests/policies/stamp-travel-permit.yaml rename to adventures/05-lex-imperfecta/beginner/manifests/policies/stamp-travel-permit.yaml diff --git a/adventures/planned/00-lex-imperfecta/beginner/verify.sh b/adventures/05-lex-imperfecta/beginner/verify.sh similarity index 97% rename from adventures/planned/00-lex-imperfecta/beginner/verify.sh rename to adventures/05-lex-imperfecta/beginner/verify.sh index 53af1ad0..4cd167e9 100755 --- a/adventures/planned/00-lex-imperfecta/beginner/verify.sh +++ b/adventures/05-lex-imperfecta/beginner/verify.sh @@ -4,7 +4,7 @@ set -euo pipefail # Load shared libraries SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # shellcheck disable=SC1091 -source "$SCRIPT_DIR/../../../../lib/scripts/loader.sh" +source "$SCRIPT_DIR/../../../lib/scripts/loader.sh" OBJECTIVE="By the end of this level, you should have: @@ -16,7 +16,7 @@ OBJECTIVE="By the end of this level, you should have: DOCS_URL="https://offon.dev/adventures/lex-imperfecta/levels/beginner" print_header \ - 'Challenge 00: Lex Imperfecta' \ + 'Challenge 05: Lex Imperfecta' \ 'Level 01: The Twelve Tables' \ 'Verification' @@ -236,4 +236,4 @@ print_success "✅ PASSED: All $TESTS_PASSED verification checks passed!" print_new_line # Run submission readiness checks -check_submission_readiness "00-lex-imperfecta" "beginner" +check_submission_readiness "05-lex-imperfecta" "beginner" diff --git a/adventures/planned/00-lex-imperfecta/docs/beginner.yaml b/adventures/05-lex-imperfecta/docs/beginner.yaml similarity index 94% rename from adventures/planned/00-lex-imperfecta/docs/beginner.yaml rename to adventures/05-lex-imperfecta/docs/beginner.yaml index 0e3fd165..7aeb17af 100644 --- a/adventures/planned/00-lex-imperfecta/docs/beginner.yaml +++ b/adventures/05-lex-imperfecta/docs/beginner.yaml @@ -24,13 +24,13 @@ backstory: objective: - >- - All workloads **missing the `republic.rome/gens` label** blocked at admission with a clear policy violation message + All workloads **missing the `republic.rome/gens` label** are blocked at admission with a clear policy violation message - >- - All workloads **running as privileged containers** blocked at admission with a clear policy violation message + All workloads **running as privileged containers** are blocked at admission with a clear policy violation message - >- - All pods declaring **`republic.rome/traveler: peregrinus`** automatically receiving the **`republic.rome/travel-permit: granted`** label + All pods declaring **`republic.rome/traveler: peregrinus`** automatically receive the **`republic.rome/travel-permit: granted`** label - >- - Confirmed that **all other workloads** deploy and run successfully in the cluster + **All other workloads** deploy and run successfully in the cluster what_you_learn: - >- diff --git a/adventures/planned/00-lex-imperfecta/docs/index.yaml b/adventures/05-lex-imperfecta/docs/index.yaml similarity index 95% rename from adventures/planned/00-lex-imperfecta/docs/index.yaml rename to adventures/05-lex-imperfecta/docs/index.yaml index 23828a0b..e7355b79 100644 --- a/adventures/planned/00-lex-imperfecta/docs/index.yaml +++ b/adventures/05-lex-imperfecta/docs/index.yaml @@ -13,7 +13,7 @@ overview: - The Republic's legal system is in disarray — workloads run unchecked, required labels go missing, and privileged containers slip through the gates. As a newly appointed Praetor, your mission is to restore order by fixing broken Kyverno policies and enforcing proper admission control. rewards: - deadline: "TODO" + deadline: "Tuesday, 23 June 2026 at 23:59 CET" tiers: - label: "1st place" description: "50% voucher for a Linux Foundation certification" diff --git a/infra/tracker/main.go b/infra/tracker/main.go index b9c67ee7..79082047 100644 --- a/infra/tracker/main.go +++ b/infra/tracker/main.go @@ -21,15 +21,18 @@ var validActions = map[string]bool{ } type bizEvent struct { - Type string `json:"type"` - Action string `json:"action"` - Adventure string `json:"adventure"` - Level string `json:"level"` - SessionID string `json:"session.id"` - GithubUser string `json:"github.user,omitempty"` - GithubRepo string `json:"github.repo,omitempty"` - Status string `json:"status,omitempty"` - FailedChecks []string `json:"failed_checks,omitempty"` + Type string `json:"type"` + Action string `json:"action"` + Adventure string `json:"adventure"` + AdventureNumber string `json:"adventure.number"` + AdventurePublishMonth string `json:"adventure.publish_month"` + AdventurePublishYear string `json:"adventure.publish_year"` + Level string `json:"level"` + SessionID string `json:"session.id"` + GithubUser string `json:"github.user,omitempty"` + GithubRepo string `json:"github.repo,omitempty"` + Status string `json:"status,omitempty"` + FailedChecks []string `json:"failed_checks,omitempty"` } func (e *bizEvent) validate() string { @@ -48,6 +51,18 @@ func (e *bizEvent) validate() string { if e.SessionID == "" { return "session.id is required" } + if e.AdventureNumber == "" { + return "adventure.number is required" + } + if e.AdventurePublishMonth == "" { + return "adventure.publish_month is required" + } + if e.AdventurePublishYear == "" { + return "adventure.publish_year is required" + } + if e.Action == "verification.completed" && e.Status == "" { + return "status is required for verification.completed" + } return "" } diff --git a/lib/scripts/tracker.sh b/lib/scripts/tracker.sh index ce0c183e..55dc0104 100644 --- a/lib/scripts/tracker.sh +++ b/lib/scripts/tracker.sh @@ -7,14 +7,20 @@ SESSION_ID_FILE="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)/.offon-sess # ----------------------------------------------------------------------------- # Set tracking context and ensure a session ID exists -# Usage: set_tracking_context "00-lex-imperfecta" "beginner" +# Usage: set_tracking_context "lex-imperfecta" "beginner" "05" "June" "2026" # ----------------------------------------------------------------------------- set_tracking_context() { local adventure=$1 local level=$2 + local adventure_number=${3:-""} + local publish_month=${4:-""} + local publish_year=${5:-""} export ADVENTURE="$adventure" export LEVEL="$level" + export ADVENTURE_NUMBER="$adventure_number" + export PUBLISH_MONTH="$publish_month" + export PUBLISH_YEAR="$publish_year" if [[ ! -f "$SESSION_ID_FILE" ]]; then uuidgen > "$SESSION_ID_FILE" @@ -40,11 +46,17 @@ send_event() { --arg session_id "${OFFON_SESSION_ID:-unknown}" \ --arg github_user "${GITHUB_USER:-}" \ --arg github_repo "${GITHUB_REPOSITORY:-}" \ + --arg adventure_number "${ADVENTURE_NUMBER:-}" \ + --arg publish_month "${PUBLISH_MONTH:-}" \ + --arg publish_year "${PUBLISH_YEAR:-}" \ --argjson extra "$extra_fields" \ '{ "type": $event_type, "action": $action, "adventure": $adventure, + "adventure.number": $adventure_number, + "adventure.publish_month": $publish_month, + "adventure.publish_year": $publish_year, "level": $level, "session.id": $session_id, "github.user": $github_user,