# Task style and voice

A SkillCred task is either a hands-on sandbox exercise or a Markdown-authored choice question. Both types live in `task.en.md`, where you write the prompt the candidate sees.

At a glance

| Area | The shape |
| --- | --- |
| Sandbox skeleton | Frontmatter → `# Task` → directive → optional structure → closing reminder. |
| Choice skeleton | Frontmatter → prompt → one final top-level task list. |
| Voice | Bare imperative for sandbox tasks; direct question or instruction for choice prompts. |
| Plain language | Common words, short sentences, one name per thing. Prompts travel across first languages. |
| Frontmatter | Use `type: sandbox` or `type: choice`. |
| Sandbox heading | `# Task` is the only H1, and it becomes the panel title. |
| Sandbox paths | Absolute paths only. |
| Copy targets | Anything the candidate copies sits in a fenced code block. |
| Sandbox admonitions | One severity per role: `info`, `warning`, `note`, `danger`, `abstract`, `tip`. |
| Sandbox closer | One of three canonical reminders, used verbatim. |

If you have never built a sandbox item before, the [Quickstart](https://skills.staging.lf-cert.cloud/docs/quickstart/index.md) walks you through your first one.

## Orientation

Your task file lives at:

```
items/<id>/task.en.md
```

For a sandbox item, the sandbox renders the file into the candidate's [instructions tool](https://skills.staging.lf-cert.cloud/docs/sandbox/tools/#instructions), a fixed panel on the left of their browser. The candidate cannot edit the file or see its source; everything they read comes from the rendered Markdown. Choice items render as questions with selectable answers.

About these examples

The **Source** block is exactly what you write in `task.en.md`. The **Rendered preview** below it is how the candidate sees that source in their instructions panel.

## Sandbox document skeleton

Every sandbox task has the same shape:

1. **State the goal.** One short imperative sentence at the top.
2. **Give the candidate what they need.** Paths, commands, expected values, each in a fenced block so they can copy with a click.

Many sandbox tasks also close with a short reminder (see [Sandbox closing notes](#sandbox-closing-notes)).

Here is the smallest complete task. Copy it and adapt as you go.

**Source**

**task.en.md**

````
---
type: sandbox
---

# Task

Edit the file:

```text
/home/tux/.vimrc
```

Add a line that enables line numbers.

!!! warning

    Save your changes. Unsaved work will not be scored.
````

**Rendered preview**

Task

Edit the file:

```
/home/tux/.vimrc
```

Add a line that enables line numbers.

Warning

Save your changes. Unsaved work will not be scored.

## Sandbox voice

The directive at the top of every sandbox task is a bare imperative: a verb-first sentence with no subject. *Edit the file:* reads cleaner than *You should edit the file:* and gets the candidate moving immediately. The candidate is the implicit subject of every imperative; there is no need to address them explicitly.

A few habits keep that voice consistent across the catalog:

- Open with a verb. Common starters: *Use*, *Create*, *Modify*, *Configure*, *Append*, *Convert*, *Fix*, *Write*, *Run*, *Identify*.
- Leave first person out of the prompt: no *we*, no *let's*, no *I*. The candidate does the work; the prompt belongs to them.
- Explicit *you* is fine inside an admonition body when you are addressing the candidate directly. The directive itself stays subject-free.
- Use the fewest sentences necessary to convey the starting state. More than one is fine when the scenario genuinely needs it; narration starts when context exceeds what the candidate needs to begin.
- The tone is procedural, not conversational. Humor and encouragement read well in tutorials, but not in a scored hands-on objective.

**Source**

**task.en.md**

````
# Task

Use Vim to edit the configuration file:

```text
/home/tux/.vimrc
```

Set the color scheme to `torte` and enable line numbers.
````

**Rendered preview**

Task

Use Vim to edit the configuration file:

```
/home/tux/.vimrc
```

Set the color scheme to `torte` and enable line numbers.

When the scenario needs context (a starting state, a precondition), one short declarative sentence leads in, and the directive follows:

**Source**

**task.en.md**

````
# Task

The Git repository has merge conflicts on the `feature` branch. The repository is at:

```text
/home/tux/repository
```

Resolve the conflicts so that `feature` can be fast-forward merged into `main`.
````

**Rendered preview**

Task

The Git repository has merge conflicts on the `feature` branch. The repository is at:

```
/home/tux/repository
```

Resolve the conflicts so that `feature` can be fast-forward merged into `main`.

## Plain language

SkillCred candidates come from many countries and many first-language backgrounds. The prompt should read just as clearly for every one of them, whatever their fluency in English.

A few habits keep prompts accessible:

- Pick the most common word for the meaning. *Use* reads more clearly than *leverage*, *start* than *commence*, *after* than *following*.
- Avoid idioms and figures of speech. *Wrap up*, *the clock is ticking*, *out of the box* carry meaning that does not translate.
- Use the same name for the same thing throughout the prompt. If you call a file a `Dockerfile` once, do not switch to *image definition* later.
- Spell out unfamiliar abbreviations the first time. Familiar names the task is built around (`HTTP`, `YAML`, `kubectl`) need no expansion.

The two prompts below say the same thing. The first leans on idioms and shifts vocabulary; the second is plain.

**Source**

**harder to read**

````
# Task

Get the hang of Vim's spell checker and knock out the misspelled words in:

```text
/home/tux/notes.md
```

Wrap up before the time runs out.
````

**Rendered preview**

Task

Get the hang of Vim's spell checker and knock out the misspelled words in:

```
/home/tux/notes.md
```

Wrap up before the time runs out.

**Source**

**easier to read**

````
# Task

Correct the spelling mistakes in the file:

```text
/home/tux/notes.md
```

Use Vim's spell checker to find them.
````

**Rendered preview**

Task

Correct the spelling mistakes in the file:

```
/home/tux/notes.md
```

Use Vim's spell checker to find them.

## Frontmatter

The first few lines of every `task.en.md` file are a small YAML block between two `---` lines. The platform reads it when assembling the exam; the candidate never sees it.

The `type` field classifies the task:

- `type: sandbox` identifies a hands-on task backed by a sandbox.
- `type: choice` identifies a question authored as a Markdown task list.

Use one flat `type` field. The examples in the rest of this page show the frontmatter appropriate to each task type.

**Source**

**task.en.md**

```
---
type: sandbox
---

# Task

Customize Vim with these requirements:
```

**Rendered preview**

Task

Customize Vim with these requirements:

## Choice task grammar

A choice item contains a prompt followed by one top-level task list.

**task.en.md**

```
---
type: choice
---

Which image is smallest?

- [ ] `ubuntu:24.04`
- [x] `alpine:3.20`
- [ ] `debian:12`
```

Follow these rules:

- Put the complete prompt before the first top-level task list. That first list is the answer list.
- Give every top-level answer an explicit `[ ]` or `[x]` marker. Checked answers are correct; unchecked answers are incorrect.
- Provide at least two answers and check at least one. Check every correct answer when the question has more than one.
- Keep nested paragraphs, code blocks, and lists indented under their answer. A nested list is content within that answer, not another set of choices.
- Make the answer list the final top-level block. Do not put a heading, paragraph, code block, list, or other top-level content after it.
- Use Markdown formatting, links, images, inline code, and fenced code as needed, but do not use raw HTML in the prompt or answers.

The platform assigns answer identifiers and selection behavior. Authors supply only the prompt, answer text, and correct markers.

## Sandbox headings

For a sandbox task, `# Task` becomes the title at the top of the candidate's instructions panel. It is the one H1 in the file, and it carries enough weight that the file rarely needs any other heading.

Two exceptions show up in practice:

- `### Example output` for prompts that include a small sample of the expected result.
- `### Information` for a labeled block of reference data the candidate needs while solving.

Anything else (*Objective*, *Prerequisites*, *Verification*, or a descriptive H1 like `# Build a Greeting Image`) adds visual weight without adding information. The directive is the objective; the closing reminder is the verification cue.

**Source**

**task.en.md**

````
# Task

Write a JSONPath expression that returns the `title` of every movie.

### Example output

```json
["The Matrix", "Inception"]
```
````

**Rendered preview**

Task

Write a JSONPath expression that returns the `title` of every movie.

Example output

```
["The Matrix", "Inception"]
```

## Sentence length and density

Candidates have limited time during an exam. Short prompts let them spend it on the work, not on parsing instructions.

A few guidelines that keep tasks scannable:

- The directive itself is usually one sentence, around 25 words or fewer.
- For parallel conditions, such as a group of settings or properties to configure, prose with inline `{.copy}` spans is preferred. Numbered lists imply a sequence that may not exist, and they expand simple requirements into visual bulk.
- Numbered lists fit ordered procedures where the candidate must do step A before step B. Bullets and tables fit reference data (key/value pairs, acceptance criteria) that does not flow naturally as prose.
- A typical task body is under 40 lines, short enough that the candidate reads it once and moves on. Tabular input data and bundled reference material can push that ceiling, but the directive itself stays compact.
- The task must include every value and constraint the candidate needs to solve it, but it should not mirror the internal scoring check list. The prompt structure serves the candidate's understanding, not the grader's implementation.

**Source**

**task.en.md**

````
# Task

Modify the script at:

```text
/home/tux/healthcheck.sh
```

Make the script:

1. Run the `healthcheck` binary.
2. Append both STDOUT and STDERR to:

   ```text
   /var/log/stats.log
   ```

3. Exit with the same status code as `healthcheck`.
````

**Rendered preview**

Task

Modify the script at:

```
/home/tux/healthcheck.sh
```

Make the script:

1. Run the `healthcheck` binary.
2. Append both STDOUT and STDERR to:

   ```
   /var/log/stats.log
   ```
3. Exit with the same status code as `healthcheck`.

## Code and copy targets

Every fenced code block and inline `` `value`{.copy} `` span in the candidate's instructions panel comes with a one-click copy button. That detail saves the candidate from retyping long paths and exact commands during an exam, and it shapes how SkillCred tasks present copy targets.

Three forms to choose from:

- **Fenced block** — a path, command, multi-line value, or sequence of commands the candidate copies.
- **Inline `{.copy}`** — a short value the candidate copies that reads naturally in the prose around it: `` `my-namespace`{.copy} ``, `` `3000`{.copy} ``.
- **Plain inline backtick** — something you are naming in prose, not asking the candidate to copy.

Common copy targets the candidate paths through during a task:

- A file path they open or edit.
- A command they run.
- An image tag, a URL, a configuration value.
- An exact string they enter into a tool.

And things that read more naturally as inline backticks, because the candidate is reading rather than copying:

- `feature`, `main`, or another branch name mentioned in passing.
- A field name like `title` or a config key like `replicas`.
- A status code like `200` or `404`.
- The `tux` user when you name them in prose.

When a copy target is short, `` `value`{.copy} `` keeps the prose intact. When it is long, contains slashes, or warrants its own visual weight, pull it onto its own fenced line. The candidate notices the difference at exam time.

### Tag every fenced block with a language

The opening backticks take a short language tag right after them. The tag tells the panel how to color the block and hints at what the candidate is looking at:

- `text` for paths, tags, URLs, and exact strings (anything that is not a real language).
- `bash` for shell commands.
- `json`, `yaml`, `python`, `dockerfile`, and so on for source code and data.

Unlabeled fences and the older 4-space-indented code style render without color or framing, so they are best left out of task files.

### Tables and lists are tight quarters

Inside a table cell, plain backticks work for prose names and `` `value`{.copy} `` works for copy targets — a fenced block would break the cell layout. Inside a numbered or bulleted list, a fenced block can be indented three spaces under the marker and it renders cleanly as part of that list item.

### Keyboard keys

When the candidate has to press a key or a chord (`Ctrl+D`, `Enter`, `Shift+Tab`), the keys go between `++` markers. The panel renders them as styled key glyphs the candidate recognizes immediately.

**Source**

**task.en.md**

```
Exit the editor with ++ctrl+d++.
```

**Rendered preview**

Exit the editor with `Ctrl`+`D`.

### Choosing the right form

Here is the same task written two ways. The first leaves the candidate with two values they have to retype:

**Source**

**harder for the candidate**

```
# Task

Modify the script at `/home/tux/healthcheck.sh` and build the image tagged `linux-foundation-education/hello:1.0`.
```

**Rendered preview**

Task

Modify the script at `/home/tux/healthcheck.sh` and build the image tagged `linux-foundation-education/hello:1.0`.

The fenced version gives the candidate a copy button on each value:

**Source**

**easier for the candidate**

````
# Task

Modify the script at:

```text
/home/tux/healthcheck.sh
```

Build the image and tag it as:

```text
linux-foundation-education/hello:1.0
```
````

**Rendered preview**

Task

Modify the script at:

```
/home/tux/healthcheck.sh
```

Build the image and tag it as:

```
linux-foundation-education/hello:1.0
```

Commands the candidate runs are copy targets too. A `bash` fence colors the command and exposes a copy button:

**Source**

**task.en.md**

````
# Task

Apply the manifest with:

```bash
kubectl apply -f /home/tux/deployment.yaml
```
````

**Rendered preview**

Task

Apply the manifest with:

```
kubectl apply -f /home/tux/deployment.yaml
```

## Sandbox paths

Every path in a sandbox task is absolute. Candidate-owned files live under `/home/tux/...`; system-managed files live under their usual roots (`/etc`, `/var`, `/opt`, `/usr`, `/srv`).

The default candidate user is `tux`, but the candidate may switch users during a task. A `sudo` command, an `su` to root, or a service-account shell all change which home directory `~` points to. A path like `~/my-file.txt` resolves to whichever user is currently logged in, so it can suddenly point to a place the file is not. Absolute paths sidestep that confusion entirely.

A few habits that follow from the rule:

- Spell out the full path (`/home/tux/notes.md`) rather than the tilde (`~/notes.md`).
- Avoid relative paths (`./foo`, `../bar`); they depend on the candidate's working directory.
- Name `tux` as the actor when the default user is doing the work. Name other users explicitly when the task requires them (`root` via `sudo`, a service account).

**Source**

**task.en.md**

````
# Task

Append a license header to every shell script under:

```text
/home/tux/scripts
```

Use the header file at:

```text
/etc/license-headers/sh.txt
```

Run the rewrite as the `tux` user.
````

**Rendered preview**

Task

Append a license header to every shell script under:

```
/home/tux/scripts
```

Use the header file at:

```
/etc/license-headers/sh.txt
```

Run the rewrite as the `tux` user.

## Lists, tables, emphasis

Lists and tables both have their moment. Numbered lists work well for ordered procedures the candidate follows top-to-bottom. Bullet lists fit unordered constraints, resources, or acceptance criteria. Tables shine when you have three or more key/value rows that line up neatly.

A few small details that keep the page tidy:

- Ordered-list markers stay plain (`1.`, `2.`, `3.`). Some editors emit `1\.`; that backslash renders literally in the panel.
- Emphasis lives in `**bold**` and admonition severity, not in ALL-CAPS. The exceptions are domain literals like `STDOUT` and `STDERR`, which are the actual names of the things.
- The format name is `Markdown`, with a capital M.

**Source**

**task.en.md**

```
# Task

Add the following key-value pairs to the top-level JSON object:

| Key | Value |
| --- | --- |
| `watermelon` | `green` |
| `lemon` | `yellow` |
| `cherry` | `red` |

Do not change the existing keys or values.
```

**Rendered preview**

Task

Add the following key-value pairs to the top-level JSON object:

| Key | Value |
| --- | --- |
| `watermelon` | `green` |
| `lemon` | `yellow` |
| `cherry` | `red` |

Do not change the existing keys or values.

## Admonition vocabulary

Admonitions are the color-coded callout boxes the panel renders from `!!! type` lines. Each color carries a different meaning, so picking the right one helps the candidate spot what matters at a glance.

| When you want to say… | Reach for |
| --- | --- |
| This is a hard prohibition; doing it invalidates the candidate's work. | `!!! danger` |
| A soft constraint, or a save-or-apply closing note. | `!!! warning` |
| A permissive caveat, an autosave reminder, or a version note. | `!!! info` |
| Offer a small hint for a detail the item does not measure. | `!!! tip` open, or `??? tip "Hint: <topic>"` only when the hint is long. |
| Point at a man page, reference document, or other outside material the candidate may need. | `!!! abstract "Reference Documentation"` |
| List the restricted tools or resources for the task. | `!!! info "Restricted environment"` or `!!! info "Available tools"` |

Hints are scarce on a scored exam. The candidate is expected to bring the knowledge the item tests, so a hint that hands over part of the answer weakens the measurement. Keep hints to the edges of the task: a pointer at the man page for a tool the item leans on but does not test, or a small `!!! tip` for a mechanical detail that is not what the item measures. When you point at documentation, name it and show the exact command.

Prefer an open admonition over a collapsible `??? tip`. Hiding the hint behind a click rarely helps during a timed exam, and the candidate reads the whole task at once when it stays open. Reserve `???` for a hint long enough that collapsing it keeps the panel readable. Labs are different: a learner works at their own pace, so a collapsible hint lets them choose how much help they want, and it is encouraged there. See [Collapsible hints](https://skills.staging.lf-cert.cloud/docs/labs/instruction-style/#collapsible-hints) in the lab guide.

The body of an admonition or collapsible block starts after a blank line, indented four spaces under the `!!! type` or `??? type` line. A few examples covering the different roles:

**Source**

**hard prohibition**

```
!!! danger

    Do not modify any task definitions or create a new Pipeline.
```

**Rendered preview**

Danger

Do not modify any task definitions or create a new Pipeline.

**Source**

**soft constraint**

```
!!! warning

    Do not move, delete, or change any other content.
```

**Rendered preview**

Warning

Do not move, delete, or change any other content.

**Source**

**permissive caveat**

```
!!! info

    The commit message is not scored.
```

**Rendered preview**

Info

The commit message is not scored.

**Source**

**pointer at a man page**

````
!!! abstract "Reference Documentation"

    ```bash
    man tar
    ```
````

**Rendered preview**

Reference Documentation

```
man tar
```

**Source**

**reference link**

```
!!! abstract "Reference Documentation"

    See `pipelines.md` for the full `Pipeline` schema.
```

**Rendered preview**

Reference Documentation

See `pipelines.md` for the full `Pipeline` schema.

## Sandbox closing notes

Most sandbox tasks end with a short closing note that tells the candidate how to wrap up. Three notes below cover almost every situation. Pick the one that matches your task and use the wording verbatim; candidates learn these phrases across many tasks and rely on them.

**Source**

**manual-save file-edit tasks**

```
!!! warning

    Save your changes. Unsaved work will not be scored.
```

**Rendered preview**

Warning

Save your changes. Unsaved work will not be scored.

**Source**

**auto-save editor tasks**

```
!!! info

    The editor is configured to automatically save any changes. There is no need to manually save the file.
```

**Rendered preview**

Info

The editor is configured to automatically save any changes. There is no need to manually save the file.

**Source**

**cluster-apply tasks**

```
!!! warning

    Save your changes and apply them to the cluster. Unsaved or unapplied work will not be scored.
```

**Rendered preview**

Warning

Save your changes and apply them to the cluster. Unsaved or unapplied work will not be scored.

## Constraint phrasing

Every now and then a task needs to tell the candidate not to do something. The canonical phrasing is `Do not <verb> ...`, with the severity carried by the admonition color around it.

Two habits keep the wording calm:

- *Do not* is spelled out: no *Don't*, no *Do NOT*. The phrase already carries the prohibition.
- `**only**` sits right next to the verb or condition it constrains, so the candidate spots the limit immediately.

**Source**

**task.en.md**

```
Change the script so that `make apply` runs **only** if `pre-commit run --all-files` exits with a zero status.

!!! warning

    Do not add extra commits.
```

**Rendered preview**

Change the script so that `make apply` runs **only** if `pre-commit run --all-files` exits with a zero status.

Warning

Do not add extra commits.

## Common pitfalls

These are the patterns reviewers push back on most often. Each collapsible shows the problem and the fix.

Tildes or relative paths

```
Edit `~/notes.md` and the script in `./bin/run.sh`.
```

Tildes and relative paths assume the candidate's working directory. Absolute paths in fenced `text` blocks line up across every sandbox task: `/home/tux/notes.md` and `/home/tux/bin/run.sh`.


Emoji or icons in the task

```
# Task

🚀 Build a container image and tag it as `sc109:demo`.
```

Decorative icons distract from a procedural prompt and may not localize. Plain text reads cleanly in every locale.


First-person voice

```
# Task

We will modify the script so that input lines are also converted to lowercase.
```

The candidate does the work, not "we". The bare imperative *Modify the script so that ...* reads more directly.


Heading-level inversion (`## Context` above `# Task`)

```
## Context

The Git repository at `/home/tux/repository` has merge conflicts.

# Task

Resolve the conflicts.
```

`# Task` is the panel title. Setup context fits in a sentence underneath it, not in an H2 above.


Escaped ordered-list markers

```
# Task

1\. Create a new Helm chart at `/home/tux/game-mullet`.

2\. Add a dependent chart.
```

Some editors emit `1\.` to escape the period. The candidate sees the backslash literally. Plain `1.`, `2.`, `3.` render the way the candidate expects.


Unlabeled fences

````
Run this binary:

```
/opt/refactored-doodle/bin/space-invention
```
````

Every fence takes a short language tag so the panel can color and frame it. `text` for plain literals, `bash` for commands, `json` / `yaml` / `python` / `dockerfile` for data and source.


ALL-CAPS emphasis

```
Do NOT configure the Bash prompt globally. Only configure it for the `tux` user.
```

The admonition severity and `**bold**` carry weight already. *Do not* and `**only**` read calmer and keep the rest of the prompt easy to scan.


Lowercase `markdown`

```
Recreate the following table in markdown.
```

The format name is capitalized: `Markdown`.


Friendly reminder where the canonical closer belongs

```
Don't forget to save your changes to the script.
```

The closing notes are canonical phrases candidates learn to recognize. Use the exact wording from [Sandbox closing notes](#sandbox-closing-notes) so the prompt feels familiar.


Two admonitions of the same color in a row

```
!!! warning

    Do not add extra commits.

!!! warning

    Do not push to the remote.
```

Merging them into one admonition with a bulleted body reads as a single rule, not two stacked.


Typos in task text

```
Sort the entries so they are properly formated.
```

A quick spellcheck before the pull request keeps the prompt tidy.

## Related pages

- **[Sandbox author workflow](https://skills.staging.lf-cert.cloud/docs/skillcred/author-workflow/index.md)**

Step-by-step contribution flow for an assigned sandbox item.

- **[Blueprint reference](https://skills.staging.lf-cert.cloud/docs/skillcred/blueprint-reference/index.md)**

Fields and constraints enforced by `skills validate item`.

- **[Quickstart](https://skills.staging.lf-cert.cloud/docs/quickstart/index.md)**

Practice the sandbox CLI and the item lifecycle end-to-end.
