name: vet-challenge
description: Vets a community-author-submitted challenge for malicious content and sanity, then prepares and validates a scripted .solution.sh. Use when asked to review/vet a third-party challenge submission.
argument-hint:
Vet the community-submitted challenge $0 and prepare a reliable scripted solution.
Resolve the bare challenge name from $0 (strip any https://labs.iximiuz.com/challenges/ prefix). Refer to it below as <name>.
Steps
Pull the source. Invoke the
pull-content-sourceskill withchallenge <name>. Third-party challenges live in3rd-party/challenges/<name>— pull there if no local folder is detected:labctl content pull challenge <name> --dir 3rd-party/challenges/<name> --forceSecurity review. Read
index.mdand every solution file. Look for malicious content: keyloggers, cryptominers, XSS, reverse shells, credential/data exfiltration, fetching+executing remote code, suspicious base64/obfuscation. Report findings explicitly.Sanity review. Confirm the challenge is clearly written, reasonable, and pedagogically helpful. Flag authoring issues (e.g., malformed YAML indentation in
tasks:, brokenneeds:chains, cross-machine initneeds:) even when the platform tolerates them. Also flag narrative/diagnostic mismatches — where the symptom the text tells the student to look for differs from what actually happens (cross-check this against the live broken state in step 4). E.g. a "the pod is OOMKilled, runkubectl describe pod" story when the pod is in fact rejected at admission and never exists to describe. The fix the challenge teaches may still be correct while the explanation misleads the learner.Launch it as a free-tier user, non-interactively:
labctl challenge start --as-free-tier-user --safety-disclaimer-consent --no-open --no-ssh <name>Find the playground ID in the output of the above command. Verify the intended broken/initial state matches the scenario with
labctl ssh <id> -- <diagnostic>.Write
3rd-party/challenges/<name>/.solution.sh. Rules:- No shebang and no
set -euo pipefail—set -exuo pipefailis injected automatically when the solution is applied (see thesolve-challengeskill). - Guard benign non-zero exits — because
set -exuo pipefailis injected, any command whose non-zero exit is expected will abort the whole script (and waste a fresh-start cycle). Neutralize such commands with|| trueor move them into anif. The classic offender is a value-probe in a$(...)assignment that legitimately fails before the resource exists, e.g. inside a polling loopphase=$(kubectl get pod ... -o jsonpath='{.items[0].status.phase}')errors with "array index out of bounds" while the pod list is empty — write... 2>/dev/null || true. - After the command(s) that satisfy each task, call
examinerctl task wait <task-name>(task name is positional;--timeout <dur>supported) so the task is confirmedcompletedbefore proceeding. This avoids races. - For challenges spanning multiple VMs, split the script with
# session: [user@]machinemarker lines (e.g.# session: root@leaf-01); commands after a marker run on that VM. Content before the first marker runs on the default machine/user. Seesolve-challengefor the exact chunking rules. - Use
labctl playground tasks <id>(tunnel-free, all machines; add-o yamlfor per-task detail) to discover task names and dependency order. - If the author's solution exists (e.g.,
solution(-\d+)?.md), mirror it as closely as possible (use the same commands, file names, paths, etc).
- No shebang and no
Add
3rd-party/challenges/<name>/.gitignorethat ignores everything except the solution scripts:* !.gitignore !.solution*.shValidate end-to-end twice via
solve-challenge. Invoke thesolve-challengeskill with<name>to apply the script against a fresh attempt and confirm every non-helper task completes. Then invokesolve-challengewith<name>a second time to confirm the solution is not flaky. Both runs must pass. (solve-challengehandles fresh-start, multi-VM session chunks,examinerctl task wait, and the authoritative completion check — do not re-implement that here.)Stop the challenge when done and report the security verdict, sanity findings, and validation results.
Notes
- Prefer the project skills (
pull-content-source,detect-local-content-folder,run-playground-command,list-running-playgrounds) over rawlabctlwhere they fit. - Use polling loops with short sleeps, not single long sleeps, when waiting on init/verification.