[ norboten ]
claude · lab claude-05

The Triage Job That Spends Without Limit

· about 40 minutes · runs on ubuntu-26.04-claude · unrated

An unrated lab. It runs on your machine with no account and no network, and everything about it — the faults, the checks, the hints and the reference solution — is in the repository. An attempt on it is recorded on your profile and never moves a rating: only rated labs do. Rated and unrated labs.

The briefing

The site team added a GitHub Actions workflow that asks Claude Code to label new issues. The month's usage report came in at many times the estimate. Nobody can say how many runs there were or how long each took, and one run in the Actions history was cancelled by GitHub after six hours. The workflow is ~/site/.github/workflows/claude-triage.yml; the script it runs is ~/site/ci/triage.sh.

There is no GitHub here. The workflow file is graded as written, and the script is run for real: claude on this machine is the real Claude Code 2.1.270, talking to a scripted model instead of Anthropic. To try the script the way the workflow runs it:

cd ~/site && GITHUB_EVENT_PATH=ci/sample-event.json sh ci/triage.sh

The scripted model this time is one that never finishes: it keeps asking to read files.

This lab runs in a container, as learner with sudo. What is expected, and graded:

  1. Only a newly opened issue starts the job — not edits, not comments, not pull requests.
  2. A model that never stops asking for more is stopped after a few turns.
  3. The run uses Haiku and offers the model no tools; the label comes back as structured output.
  4. The workflow's token can write issues and read contents, nothing more, and the job has a timeout of 15 minutes or less.
  5. No secret and no text from the issue is expanded inside a run: script.

What is graded

This lab runs in a container — Docker or Podman, no VM — so there is no boot to survive: the checks run once, against the state you left.

CheckObjective
01_only_new_issues_start_the_jobTrigger a CI agent job only on the event it is for
02_a_looping_model_is_stoppedCap a headless run's turns, and give it the smallest model and no tools it does not need
03_haiku_with_no_toolsCap a headless run's turns, and give it the smallest model and no tools it does not need
04_least_privilege_and_a_timeoutGive a workflow the least permissions, a timeout, and no secret or untrusted text in its shell
05_nothing_secret_or_untrusted_in_run_scriptsGive a workflow the least permissions, a timeout, and no secret or untrusted text in its shell

Start it

  1. 2Labs
  2. claude-05select this one
  3. udownload it
  4. sstart the machine

Reading

Where the lab's hints send you, level by level, as you ask for them (h, then l opens a journal section in the TUI).

Theory for this lab

4 questions on the same topic, in the lab's Theory tab. They never affect the lab's grade. Three of them, to answer here:

Question 1

A script runs `claude -p "Label this issue" --output-format json` with no --max-turns, and the model keeps asking to read another file. When does the run stop?

Question 2

A triage script calls `claude -p ... --tools "" --json-schema "$schema" --output-format json`. Where is the label, and which tool is the model offered?

Question 3

A workflow step runs `echo "Triaging: ${{ github.event.issue.title }}"`. Why is this a vulnerability?