Skip to content
Registry StackDocsv0.34.0

Decide your first review request

For the operator

View as Markdown

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.

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 SiliconA Bash or zsh shellRunning Dockercurl 7.76 or laterPython 3An editor

Install both binaries:

Terminal window
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 the maintained source-free starter:

Terminal window
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.

Terminal window
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.

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

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

Terminal window
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.

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

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

Terminal window
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:

Terminal window
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:

Terminal window
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.

Use the producer token and the accepted request identifier:

Terminal window
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.

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

Terminal window
caseworkctl dev stop tutorial-work/casework

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

Terminal window
caseworkctl dev stop tutorial-work/casework --remove