Skip to main content

Runbooks

R03 — Content authoring & validation

Hands-on validation a human performs before a wave merges.

docs/runbooks/R03-content-authoring-and-validation.md
On this page

Wave: W2 · Time: ~15 minutes · Cluster needed: no

labctl validate is the gate that keeps every scenario, incident, learning path and challenge honest: required fields present, cross-references resolvable, templates well-formed. This runbook confirms it catches the mistakes an author actually makes, and that the messages point at the exact file, line and reference — not a vague "invalid".

Read this as a reviewer. For every failure message, ask: would this tell me what to fix without opening the loader source?


Preconditions

  • Repo checked out; Go toolchain installed.
  • Nothing here touches a cluster or your machine — validation is pure file I/O.

A scratch external content root for the later steps:

$ export R03_DIR=/tmp/snowops-r03
$ mkdir -p "$R03_DIR"

1. All in-repo content validates clean

$ go run ./cmd/labctl validate ; echo "exit=$?"

Expect: a single success line and exit=0, e.g.

 all content valid 3 challenges, 6 incidents, 1 paths, 13 scenarios

If this fails on an untouched checkout, stop — the repo is broken, not your test.


2. A broken cross-reference names the file, line and reference

Point a scratch path at a scenario that does not exist, and load it as an external root so the repo stays clean:

$ mkdir -p "$R03_DIR/learn/broken"
$ cat > "$R03_DIR/learn/broken/path.yaml" <<'YAML'
name: broken
displayName: Broken Path
modules:
  - name: step-one
    action:
      type: scenario
      ref: this-scenario-does-not-exist
    check:
      name: chk
      type: script
      script: x.sh
YAML
$ SNOWOPS_CONTENT_PATH="$R03_DIR" go run ./cmd/labctl validate ; echo "exit=$?"

Expect: exit=1 and a line naming the file, the line of the bad ref:, and the missing name, e.g.

/tmp/snowops-r03/learn/broken/path.yaml:7: [path/broken] module "step-one" references unknown scenario "this-scenario-does-not-exist"

Reviewer check: the line number should point at the ref: value.


3. An unknown template variable is an error, not a silent blank

$ mkdir -p "$R03_DIR/scenarios/tmpl"
$ cat > "$R03_DIR/scenarios/tmpl/scenario.yaml" <<'YAML'
name: tmpl
displayName: Template Typo
components:
  - name: c1
    type: script
    script: run.sh
checks:
  - name: reachable
    type: http
    url: "http://go-api.{{.DomainSufix}}/health"
YAML
$ SNOWOPS_CONTENT_PATH="$R03_DIR" go run ./cmd/labctl validate ; echo "exit=$?"

Expect: exit=1 and a message about the misspelled key DomainSufix (the correct key is DomainSuffix). A typo must fail here, never resolve to an empty string that breaks a URL at run time.


4. An external content root is discovered and usable

Add a valid scenario to the scratch root and confirm it is counted:

$ rm -rf "$R03_DIR"/learn "$R03_DIR"/scenarios
$ mkdir -p "$R03_DIR/scenarios/my-extra"
$ cat > "$R03_DIR/scenarios/my-extra/scenario.yaml" <<'YAML'
name: my-extra
displayName: My Extra Scenario
components:
  - name: c1
    type: script
    script: run.sh
YAML
$ SNOWOPS_CONTENT_PATH="$R03_DIR" go run ./cmd/labctl validate

Expect: the scenario count rises by one versus step 1, and exit=0. The external root was used without forking the repo (W2-T09).


5. Malformed YAML fails as a problem, not a crash

$ mkdir -p "$R03_DIR/scenarios/garbage"
$ printf 'name: garbage\n\t- : :\n' > "$R03_DIR/scenarios/garbage/scenario.yaml"
$ SNOWOPS_CONTENT_PATH="$R03_DIR" go run ./cmd/labctl validate ; echo "exit=$?"

Expect: exit=1 with a YAML-parse problem for that file — never a panic or stack trace. (The parsers are also fuzzed in CI: make fuzz.)


Cleanup

$ rm -rf "$R03_DIR"

Sign-off

Step Result Notes
1. In-repo content valid
2. Cross-ref names file/line/ref
3. Unknown template key errors
4. External root discovered
5. Malformed YAML → problem, not crash

Message-quality judgement (would each failure guide a fix at 3am?): _____

The incident field notes

One real Kubernetes failure a week — the symptom, the commands that found it, and the fix. Written from actual lab runs, not from memory.

You'll get the Kubernetes Incident Response Field Guide, plus occasional emails about new scenarios, posts and paid offerings such as courses and workshops. Unsubscribe any time.