# Sovereign Circuit — Calibration Method

**Batch 1 · Rubric SCGR1/1.0 · `rubric_hash` `91ffd02632bdaa504bd33fad2e77466dd649f2fad44f066e02a480634a336f79`**

This document explains what the grading rubric does not yet know, and how the
first batch of real hardware is going to tell it.

---

## 1. What is established and what is not

The rubric replaced adjectives with counts. That part is real and it is tested:
`grade()` is deterministic, 247 checks pass against it, the same observation
sheet always produces the same grade token, and the same grade token always
produces the same `rubric_hash`. Two parties can each grade a unit
independently, seal their sheets, reveal, and have a machine tell them whether
they actually disagree.

None of that says the numbers are right.

Every band edge in the rubric — 2 scratches, 5 dents, 1mm of hinge play — was
chosen to be defensible, not because anyone measured it. They are consistent
with how the refurbishment industry draws its own lines: the R2v3-aligned
grading scales published by [CDR Global](https://cdrglobal.com/wp-content/uploads/2022/11/CDR-Grading-Scale-alignment-with-R2v3-REC-Effective-042022-1.pdf)
use the same shape of criteria, and R2v3's equipment-categorisation logic works
the same way, as [MCDCG's clause-by-clause analysis](https://mcdcg.com/blog/r2/the-r2v3-second-draft-standard-analysis-part-17-r2-equipment-categorization/)
sets out. Borrowing the shape of a standard is not the same as validating a
threshold against your own stock.

So the honest statement of status is: **the rubric is internally consistent and
externally uncalibrated.** Batch 1 exists to change the second half of that
sentence.

---

## 2. The failure this is designed to prevent

The obvious way to calibrate is to have two experienced people grade twenty
machines and see whether they agree. That method is worthless, because the
second person will look at the first person's numbers and agree with them. What
you measure is deference, not reliability, and it will look like excellent
agreement.

So the workbook enforces the same discipline the protocol enforces on price:
**both readings are taken and recorded before either is seen.** Grader A and
Grader B fill separate sheets, blind, and the sheets are combined only
afterwards. This is the paper version of the commit-and-reveal round described
in `SPEC.md`, and it is there for the same reason — a figure produced after
seeing the counterparty's figure carries no information.

If the two graders talk during a unit, that unit is spent. Discard it rather
than keep it.

---

## 3. What each disagreement actually means

The workbook and `calibrate.py` separate three things that are easy to confuse.

**A field that differs a lot but never changes the grade** is cheap noise. It
costs bench time to measure and it buys no decisions. If a field is in this
category across a whole batch, the correct response is to consider removing the
field, not to tighten its tolerance.

**A field that differs rarely but flips the grade almost every time it differs**
is the dangerous one. The whole grade is resting on one person's eyesight on
one measurement. That field needs a specified measurement method — a tool, a
lighting condition, a defined vantage point — before anyone touches its
threshold.

**A Class M field that differs at all** is not a grading problem. Class M fields
are machine readings: SMART counters, battery registers, TPM version. Two
different readings off one instrument means the reading procedure is broken, and
no threshold change will fix it. The protocol voids these rounds deliberately,
and it voids them even when both sheets happen to derive the same grade,
because the point is that the instrument was not read reliably.

`calibrate.py` reports these three categories separately so that a threshold
never gets moved to paper over a measurement defect.

---

## 4. Threshold placement and the distribution

A threshold sitting in the middle of the densest part of the distribution
maximises disputes. If most real units count 2 to 4 scratches and the C6 ceiling
is 2, then a large fraction of stock sits one scratch away from a band change,
every one of those units is a potential argument, and the two-phase ordering
will be doing a lot of work for no benefit.

The same threshold placed at a genuine gap in the distribution produces almost
no disputes and carries the same information. So `calibrate.py` prints the
observed distribution of every counted field, and the question to ask of each
threshold is not "is this number fair?" but "does this number fall in a gap?"

Where a band turns out to be empty in real stock — no unit ever lands in it —
the band should be merged rather than kept for symmetry. Tidy tables are not a
goal.

---

## 5. Sample size, stated plainly

Twenty units is a pilot. It is enough to find measurement-protocol defects and
thresholds that are obviously in the wrong place. It is not enough to set a
threshold precisely, and it is nowhere near enough for anything with a failure
rate or a time dimension.

| What you want to settle | Units needed | Batch 1 verdict |
| --- | --- | --- |
| Is the measurement method reliable? | 20 | Yes — this is Batch 1's real output |
| Are cosmetic band edges roughly right? | 20–40 | Directional only |
| Where exactly should a cosmetic edge sit? | 40+ | No |
| Do SMART counters predict failure in *our* stock? | ~100 + time | No |
| Does hinge play at 1–2mm progress? | ~100 + longitudinal | No |

Storage-failure thresholds deserve a specific note. The rubric currently treats
any non-zero SMART 5 (reallocated sectors) or 197 (pending sectors) as
disqualifying. That follows the conservative reading of
[Backblaze's published SMART statistics](https://www.backblaze.com/blog/hard-drive-smart-stats/),
where those attributes correlate strongly with failure across a very large
population. But that is a population-level finding across drive models we do not
necessarily stock. A small non-zero count on a specific model in our own fleet
may well be tolerable, and only our own fleet data can say so. Until then, the
conservative threshold stays — being wrong in the direction of not placing a
marginal drive with a family is the acceptable direction to be wrong in.

**The instruction that matters: where the table says a threshold cannot be
settled by Batch 1, record the data and leave the number alone.** Moving a
threshold on twenty units and calling it calibrated is worse than leaving it as
an admitted guess, because it launders a guess into a measurement.

---

## 6. Changing a threshold changes the hash

`rubric_hash` covers the field registry and the band logic. Any threshold change
produces a different hash, and every grade token issued under the old hash
becomes non-comparable to tokens issued under the new one. `grade_token` binds
the rubric hash for exactly this reason — so that a grade cannot be silently
re-interpreted under different rules later.

Consequences:

- **Never recalibrate mid-batch.** Grade the whole batch under one hash.
- **Bump the rubric version** on any threshold change (`SCGR1/1.0` → `SCGR1/1.1`)
  and republish the vector file, so an auditor can tell which rules a historical
  grade was issued under.
- **Keep the old version readable.** A unit graded in Batch 1 and re-graded in
  Batch 4 should show both grades and both hashes, not a rewritten history.

---

## 7. Running the batch

1. Log each unit on **Batch log** — ID, make, model, serial, source, date.
2. Record the intended tier as a **guess, before grading.** Comparing that
   guess to the derived tier afterwards shows where the rubric and experienced
   judgement disagree. Where they do, one of the two is wrong and it is worth
   knowing which. Recording the guess afterwards tells you nothing.
3. Grader A fills the unit's column on **Observe A**; Grader B fills the same
   column on **Observe B**. Blind. Separate sheets, separate machines, or
   printed and kept apart.
4. Enter every field. A blank is not a weaker observation, it is an ungradeable
   one, and `calibrate.py` refuses the unit rather than defaulting the gaps.
   Every field's default is printed next to it — enter it explicitly.
5. Record **how** each measurement was taken in the method notes. Two people
   with a ruler and a caliper will disagree, and that is a protocol finding.
6. Run `python calibrate.py`. Read the report. Write down what you changed and
   why, including what you decided not to change.

---

## 8. Files

| File | What it is |
| --- | --- |
| `sovereign-circuit-batch-1-calibration.xlsx` | The worksheet. Read me, Batch log, Observe A, Observe B, Thresholds, Results. |
| `make_calibration_workbook.py` | Regenerates the workbook from the live field registry, so the sheet can never drift from the rubric. |
| `calibrate.py` | Reads filled sheets, grades and reconciles every pair, reports divergence and distributions, writes the Results sheet. |
| `refimpl/station.py` | Enforces grade-before-price at the test station. |
| `refimpl/test_station.py` | 99 checks, including a recorded guard-removal exercise. |

The workbook is generated from `grading.FIELDS` rather than typed by hand. If a
field is added to the rubric, regenerate the workbook — the sheet cannot fall
out of sync with the code that grades it.

---

## 9. What this is not

This produces no valuation and it is not an appraisal instrument. It records
physical condition. Price is a separate protocol round that cannot open until a
grade is published, and nothing in this workbook should be described to a
customer as an appraisal or as insurance. The distinction between a warranty or
service contract and an insurance product is a legal one with regulatory
consequences, as [IRMI's treatment of the subject](https://www.irmi.com/articles/expert-commentary/warranty-service-contract-and-insurance)
sets out, and it needs counsel before any of this language reaches a customer.
