Registry stack documentation: machine-readable Markdown.
Index of all pages: https://docs.registrystack.org/llms.txt
Full corpus: https://docs.registrystack.org/llms-full.txt

# Decide your first review request

> Start a local Casework runtime, create a unified review request, claim and answer its task, and poll the structured result.

import QuickstartMeta from '../../../components/QuickstartMeta.astro';

If you are evaluating Registry Casework as a coordinated human-review service, start with one
submitted-context request and one structured answer. You will run the source-free starter, create a
request as its admitted producer, claim and decide the task as Staff, then poll the result as the
producer.

<QuickstartMeta
  outcome="One unified review request created, claimed, answered, and read through the producer polling contract."
  time="About 20 minutes, plus the image download"
  level="Local evaluation only"
  prerequisites={['Linux amd64 or arm64, or macOS on Apple Silicon', 'A Bash or zsh shell', 'Running Docker', 'curl 7.76 or later', 'Python 3', 'An editor']}
/>

{/* Evidence: crates/registry-caseworkctl/src/project.rs, init();
    crates/registry-caseworkctl/tests/dev_lifecycle.rs. */}

## Install Registry Casework

Install both binaries:

```sh
curl -fsSL https://github.com/registrystack/registry-stack/releases/latest/download/casework-install.sh | bash
```

The installer checks release checksums before it writes to `~/.local/bin`. Replace `| bash` with
`| less` when you need to inspect the installer first.

## Create a project

Create the maintained source-free starter:

```sh
mkdir -p tutorial-work
caseworkctl init tutorial-work/casework --template standalone-decision
```

`init` refuses an existing destination.

The starter declares one `decision` review kind with `contextStrategy: submitted`, one answer stage,
the `requester` producer's exact local issuer and subject, and two allowed answer outcomes. It does
not declare a source or completion destination, so the producer polls.

{/* Evidence: crates/registry-casework/install.sh;
    products/casework/examples/standalone-decision/casework.yaml. */}

## Start Casework

:::caution[Use synthetic data only]
The development runtime stores records in a Docker volume and writes private local credentials under
`tutorial-work/casework/.casework/dev/`. Keep that directory out of version control and support
messages.
:::

```sh
caseworkctl dev tutorial-work/casework
caseworkctl dev token requester tutorial-work/casework
caseworkctl dev token staff tutorial-work/casework
```

`dev` returns after Casework is ready and seeds a team serving the `decisions` queue. Token commands
write owner-only header files. If the report names different ports, use its Casework URL rather than
the default in the next command.

```sh
casework_url="http://127.0.0.1:${CASEWORKCTL_DEV_CASEWORK_PORT:-8092}"
headers=tutorial-work/casework/.casework/dev/secrets
```

{/* Evidence: crates/registry-caseworkctl/src/dev/mod.rs, start and fresh_token;
    crates/registry-caseworkctl/src/dev/config.rs. */}

## Create the review request

The subject is immutable across this round. Its `source`, `type`, and `id` provide stable correlation;
`version` and `digest` distinguish the submitted round.

```sh
curl --silent --show-error \
  --header @"$headers/requester.header" \
  --header 'Registry-Casework-Profile: requester' \
  --header 'Idempotency-Key: tutorial-review-1' \
  --header 'Content-Type: application/json' \
  --data '{"kind":"decision","subject":{"source":"standalone","type":"batch","id":"LIC-2026-0041","version":"1","digest":"sha256:0000000000000000000000000000000000000000000000000000000000000001"},"requesterReference":"LIC-2026-0041","context":{"strategy":"submitted","snapshot":{"reference":"LIC-2026-0041","summary":"Review licence batch LIC-2026-0041"}}}' \
  --output tutorial-work/requested.json --write-out 'HTTP %{http_code}\n' \
  "$casework_url/v1/review-requests"
```

A successful create returns HTTP `201`. Extract the request identifier. Repeating the exact body and
key recovers the same accepted request; changing the body under that key is refused.

```sh
request_id="$(python3 -c 'import json; print(json.load(open("tutorial-work/requested.json"))["requestId"])')"
```

{/* Evidence: crates/registry-review-protocol/src/lib.rs, ReviewCreateRequest and SubjectBinding;
    crates/registry-casework/src/http.rs, create_review_request. */}

## Claim and answer the task

List the tasks visible to Staff, then extract the first task identifier and revision:

```sh
curl --silent --show-error \
  --header @"$headers/staff.header" \
  --header 'Registry-Casework-Profile: staff' \
  --output tutorial-work/tasks.json \
  "$casework_url/v1/review-tasks?limit=25"
task_id="$(python3 -c 'import json; print(json.load(open("tutorial-work/tasks.json"))["items"][0]["taskId"])')"
task_revision="$(python3 -c 'import json; print(json.load(open("tutorial-work/tasks.json"))["items"][0]["revision"])')"
```

Claim requires the revision the list returned and an idempotency key:

```sh
curl --silent --show-error --request POST \
  --header @"$headers/staff.header" \
  --header 'Registry-Casework-Profile: staff' \
  --header "If-Match: \"$task_revision\"" \
  --header 'Idempotency-Key: tutorial-claim-1' \
  "$casework_url/v1/review-tasks/$task_id/claim"
```

Claim advances the task revision by one. Record the configured answer with that revision:

```sh
curl --silent --show-error --request POST \
  --header @"$headers/staff.header" \
  --header 'Registry-Casework-Profile: staff' \
  --header 'If-Match: "2"' \
  --header 'Idempotency-Key: tutorial-answer-1' \
  --header 'Content-Type: application/json' \
  --data '{"decision":{"type":"answer","outcome":"confirmed"}}' \
  --output /dev/null --write-out 'HTTP %{http_code}\n' \
  "$casework_url/v1/review-tasks/$task_id/decisions"
```

A successful terminal decision returns HTTP `204`. If another actor changed the task revision,
Casework returns a conflict. List the task again before deciding whether to retry.

{/* Evidence: crates/registry-casework/src/http.rs, review_tasks, claim_review_task, and
    decide_review_task; crates/registry-casework-core/src/review.rs, ReviewerDecisionKind. */}

## Poll the result

Use the producer token and the accepted request identifier:

```sh
curl --silent --show-error \
  --header @"$headers/requester.header" \
  --header 'Registry-Casework-Profile: requester' \
  --output tutorial-work/result.json --write-out 'HTTP %{http_code}\n' \
  "$casework_url/v1/review-requests/$request_id/result"
python3 -m json.tool tutorial-work/result.json
```

The result status is `answered` and its outcome is `confirmed`. The producer response contains no
raw reviewer identity, private reason, or draft. Before settlement this endpoint returns HTTP `202`;
after retention erasure it returns HTTP `410`.

{/* Evidence: crates/registry-casework/src/http.rs, get_review_result;
    crates/registry-casework/tests/review_http.rs,
    standalone_structured_answer_can_be_claimed_decided_and_polled_over_http. */}

## Stop Casework

Stop retains the project volume so you can restart and see the same request:

```sh
caseworkctl dev stop tutorial-work/casework
```

When you no longer need the tutorial state, remove the owned development resources:

```sh
caseworkctl dev stop tutorial-work/casework --remove
```

:::caution[Removal discards this tutorial's Casework database]
`--remove` deletes the retained development volume owned by this project. Export anything you need
before running it.
:::

## Next

- [Author a Casework policy](../../configure/casework/) to define staged review and producer admission.
- [Deploy Registry Casework](../../operate/casework/) to serve a reviewed package.
- [How Registry Casework works](../../explanation/how-casework-works/) for context, authority, and retention.
- [Registry Casework API](../../reference/apis/registry-casework/) for the full unified route contract.