Your first job
In this tutorial you run notes, the example source, and watch sandcastle tag its notes with
Claude. You need the installation from Install, with its two secrets and the
address of this machine in sources/notes.yaml.
notes is the smallest source that works. It holds three notes in memory and hands each out as a
claude job that asks for one tag. It prints each tag that comes back. It uses only Go’s standard
library: its code is in examples/notes.
1. Start notes
In the folder where you built sandcastle, in a terminal of its own:
go run ./examples/notes -listen 192.168.1.20:8080 \
-token-file ~/.local/share/sandcastle/secrets/notes
Use the address you put in internal:. notes reads its token from the secret you set, and
listens only on that address, never on loopback, which sandcastle never opens. It prints:
… notes: 3 notes waiting at http://192.168.1.20:8080
Leave it running.
2. Check
In a second terminal:
sandcastle check
Among its lines are these:
ok keep: ready
warn source notes: internal exception: the gate lets 192.168.1.20:8080 through for notes.home.arpa
warn source notes: http:// is outside the promise: nothing encrypts the way to 192.168.1.20:8080
ok source notes: reachable, 3 waiting
ok capability claude: usable
ok capability ocr: usable
The keep reached notes through the gate, with the token, and notes says three notes wait. The
two warn lines are there because notes lives inside your network: the gate lets that one
address through for it. Reach a service inside your network says what that
opens. capability claude: usable means the Claude API took the key and knows the model.
Every line is explained in Check messages.
3. Let the core ask now
The core asked notes while nothing listened, and waits longer after each failure. Restart it, so
it asks at once:
systemctl --user restart sandcastle
4. Watch the tags come back
In the first terminal, notes prints a line for each note, such as:
note 1 tagged "recipes"
The tag is the model’s choice. The core takes one job each time it asks, every 30 seconds, so the three notes are tagged one after the other, within about a minute.
5. See what sandcastle kept
The core’s journal has a line for each job:
journalctl --user -u sandcastle -n 20
… msg=job source=notes job=1 capability=claude status=succeeded seconds=… error="" input_tokens=… output_tokens=…
Each job left a folder with its record:
ls ~/.local/share/sandcastle/jobs/notes/1
cat ~/.local/share/sandcastle/jobs/notes/1/meta.json
meta.json says "status": "succeeded", with the tokens the job spent. The files are described in
Files and folders.
What happened
For each note, the core asked the keep to claim a job from notes. The keep added the token and
sent the request out through the gate. The core started a box for the job, with no network and no
secret. The box read the job and handed back the prompt and the schema. The keep sent them to the
Claude API with the key. The box checked the reply against the schema, and the core sent it back
to notes.
Stop notes with Ctrl-C when you are done. It forgets its notes when it stops. To put your own
source in its place, see Add a source. To write one, see
How a source talks to sandcastle.