Verify write semantics on your deployment¶
Goal: re-derive the claims in Write semantics —
the per-fieldTag-group PUT model and the varField deletion table — on your own Sierra,
using the reversible probe that produced them. Sierra behavior is deployment- and
version-specific; don't take that page's word for it.
The probe (scripts/probe-varfield-write-semantics.py)
is designed to be safe to run:
- It refuses to run against anything that doesn't look non-prod (URL must contain
testortrain). - Every write is snapshot → mutate → observe → restore → verify-restored. A record that
doesn't come back to baseline is flagged loudly (
!! DID NOT RESTORE). - It touches only free-text/local field tags — never barcodes, names, or identity fields — and prints only field structure and content hashes, never contents.
Before you start¶
- A non-production Sierra (test or train server) reachable from your machine.
- An API key/secret for it with read and write scope on patrons, items, and bibs
(Sierra admin: the key's permissions must include record update). A read-only key will
fail at the first PUT with
401/403— that's your key's scope, not a quirk. - A checkout of this repo and uv (the probe imports
sierra_ils_utilsand needs the project's dependencies — plainpython3will typically fail withModuleNotFoundError: httpx).
1. Create a config file for the non-prod system¶
{
"sierra_api_base_url": "https://sierra-test.example.org/iii/sierra-api/v6/",
"sierra_api_key": "...",
"sierra_api_secret": "..."
}
Save it somewhere outside the repo, e.g. ~/.config/sierra/api-test.json.
2. Run the probe¶
SIERRA_API_CONFIG=~/.config/sierra/api-test.json \
uv run python scripts/probe-varfield-write-semantics.py --kinds patron,item,bib
If the probe refuses to run
The guard rejects any base URL that doesn't contain test or train. If your sandbox
is named differently, don't reflexively reach for --allow-prod — that flag means
"mutate whatever this URL points at, I've checked." First confirm the URL really is a
sandbox; only then pass the flag. Never point this script at production.
3. Read the output¶
A healthy run looks like this (record ids truncated by the probe):
host: sierra-test.example.org
=== PATRON ===
group-model on ...0017 (repeated tag 'x', 2 members):
drop ONE (keep siblings): PUT 204 -> dropped 1 of 'x', DELETED
drop ALL (send none) : PUT 204 -> dropped 2 of 'x', SURVIVED
deletion / patron/content on ...0017 tag='x' (PUT-mutates control: True):
content="" -> REMOVED
content=null -> HTTP 400
=== ITEM ===
group-model on ...0204 (repeated tag 'x', 2 members):
drop ONE (keep siblings): PUT 204 -> dropped 1 of 'x', DELETED
drop ALL (send none) : PUT 204 -> dropped 2 of 'x', SURVIVED
deletion / item/content on ...0009 tag='s' (PUT-mutates control: True):
content="" -> BLANK-SHELL
content=null -> HTTP 400
deletion / item/subfields on ...0002 tag='a' (PUT-mutates control: True):
content="" -> HTTP 400
content=null -> HTTP 400
subfields=[] -> HTTP 400
subfields-blank -> BLANK-SHELL
=== BIB ===
... (same shape as item, except patron-style REMOVED never appears)
How each line maps to the write-semantics page:
| Output | Claim it verifies |
|---|---|
drop ONE ... DELETED + drop ALL ... SURVIVED |
The per-fieldTag-group replace model — omission deletes only when a same-tag sibling is still sent |
PUT-mutates control: True |
The positive control: this record's varFields demonstrably change via PUT, so a later SURVIVED/IGNORED can't be a silent no-op. If this is False, discard that section's results |
content="" -> REMOVED (patron) vs -> BLANK-SHELL (item/bib) |
The deletion-table split: blanking fully removes a patron content field but only empties an item/bib one |
-> HTTP 400 rows |
The rejected-payload cells of the deletion table |
no !! DID NOT RESTORE anywhere |
Every probed record was returned to its baseline |
4. If a trial is skipped¶
A line like group-model: no record with a repeated safe tag on item in scanned window — skipped
means the probe couldn't find a suitable record among the first ~2,000 ids and that cell is
unmeasured on your system — don't extrapolate it from the other record types. Widen the scan
(raise pages= in Probe.batch) or point it at a record range you know has repeated notes.
Verify¶
Compare your run against the table and rule in Write semantics. If any outcome differs, trust your run over the page — behavior varies by Sierra version and configuration — and please open an issue with your Sierra version and the probe output so the catalog can record the variance.
Underlying behavior (reference):
Why this method is trustworthy: Discovering quirks yourself