CodeRigor

LESSON

Capstone: a mock-model assistant over permitted notes

Compose the complete tool-calling application over a supplied notes snapshot, enforce permissions before searching or reading, and inspect a reproducible transcript.

The capstone is a complete local application with two tools, a bounded loop and a deterministic model adapter. It searches permitted notes, reads one selected record and produces an inspectable JSON transcript. All source, fixtures, tests and command-line instructions are included in the free download. No API key, model subscription or external service is needed.

The adapter is deliberately rule-based. It requests a search, chooses the first returned ID, reads that note and formats the observed record as its final text. That lets you debug protocol and policy mechanics without confusing them with a real model’s quality. The same application boundaries can later sit behind an adapter to an actual LLM.

A complete observed-data loop
start / 3
The mock model chooses a permitted result ID from feedback, then reads the corresponding record before finishing.
A complete observed-data loop
The mock model chooses a permitted result ID from feedback, then reads the corresponding record before finishing.

Validate and copy the notes before calling the model, and freeze the readable IDs. A callback that mutates the caller’s original list should not change the snapshot or permissions in the middle of the run. Closures over copied data make this ownership contract straightforward to test.

Apply permissions in both tools. A read request for a known private ID is denied before returning the body. Search iterates only the permitted IDs before testing the query, so private titles and match information never enter its results. Filtering the final answer after exposing a private tool result would be too late.

Python
notes = {'public': {'title': 'A'}, 'private': {'title': 'B'}}
readable = frozenset({'public'})
print([{'id': key, 'title': notes[key]['title']} for key in sorted(readable)])

This search tool performs a case-folded literal substring check over title, newline and body. It is intentionally different from the ranked lexical engine in Search your own documents. That course is a useful next local extension: if you replace the matcher with ranked retrieval, filter to the authorized corpus first and retain all permission tests.

The downloadable CLI also accepts an explicit replay fixture. Use it to demonstrate a forbidden read, an unknown tool, a repeated call ID or an exhausted budget, then inspect the actual transcript and counters. A final text message is not proof of success by itself. Test task outcome and data exposure separately from the existence of a final response.

Permissions cover both retrieval and direct access
start / 3
The same readable snapshot governs search candidates and individual note reads.
Permissions cover both retrieval and direct access
The same readable snapshot governs search candidates and individual note reads.
Python
allowed = ['a']
snapshot = frozenset(allowed)
allowed.append('private')
print(sorted(snapshot), sorted(allowed))

Run the complete unit suite, the ordinary mock-model command and the denied-read replay from the README. Add one new failure fixture and assert its effect, transcript and stop reason. The result is a useful foundation for a real-model continuation: preserve the registry, object permissions, budgets and evidence when the decisions become nondeterministic.

Download the complete lab. The archive includes runnable code, tests, fixtures and a README.

Watch & read

Free lectures, talks and readings that cover this skill from another angle. All resources →

Watch the tool-and-feedback discussion. Our exercises use a deterministic teaching protocol, not a vendor SDK.