assay: the Architectonic Grader#

assay mechanizes the 2026-07-02 divisions critique’s apparatus (T1-T5 per-cut tests, the four-step opposition scale, the mapping-fidelity A-7 scale) into a tool that grades every decision in an architectonic at high resolution, then writes a MyST report from the findings. It is read-only on its object: no yaml, sheet, or docstring mutation, ever — every repair is a proposal in the report, not an applied edit.

1 The three stages#

  1. gather builds the dossier: every cell enriched with a provenance-tagged description (sheet > docstring > snapshot, DescriptionSource), cached at $MY_CACHE/arch/assay/dossier.yaml.

  2. grade derives the examination sites from the fold itself and runs the tiered checks below, producing findings.jsonl + spend.json, cached per (site, check) content hash.

  3. report renders one MyST document from findings.jsonl alone — no dossier, no live lattice — plus deterministic SVG grade-heatmaps colored from arch.irix.

run composes all three; each is also independently invocable (gather/grade/report), and report accepts an existing findings directory (--findings-dir) from any prior grade/run.

2 The site taxonomy#

Every decision occupies a site whose shape falls out of the fold’s own two-bit-per-digit structure (sites.py):

Site

Count

What it examines

PairSite

170

one opposition pair per quad per role (adjective / noun)

QuadSite

85

a concrete cell + its 4 children + 2 halves

CellSite

510

one authored cell: name aptness, description fit

EchoSite

172

one per distinct division word, across its recurring uses

PairEchoSite

84

a recurring pair, re-applied at 2 sibling quads

ChainSite

256

a leaf’s composed 4-phrase address, read top-down

3 Tiers and scales#

Tier

Model

Checks

Scale

0 — symbolic

none

sym.theorem1/2/3, sym.grammar, sym.vocab, sym.typo, sym.stale, sym.holes

TestVerdict (pass/strained/fail)

1 — micro-judgments

per-check (models.CHECK_MODELS)

pair.opposition, pair.tests, echo.sense, cell.name, cell.fit

Opposition, TestVerdict, EchoGrade

2 — quad probes

per-check (models.CHECK_MODELS)

quad.blindpair, quad.moments, quad.register, chain.address, pairecho.cut

AxisMatch, TestVerdict, EchoGrade, CutConsistency

3 — synthesis

glm-5.2

one section-scoped connective-prose call per report section

prose, not a grade

Every model output is clamped to its legal grade vocabulary; a failed or unrecognized reply degrades to ungraded (checks.UNGRADED) — never a guessed grade. quad.blindpair adds a second degrade path, unmaskable (checks.UNMASKABLE), for a quad whose masking would leak a name or leave too little text to judge. Tier 3’s synthesizer is deliberately a different model architecture from tiers 1-2’s grader (decorrelation posture) — never reuse --model for --report-model.

4 Cost posture#

Tiers 1-2 route through the LiteLLM gateway (preferred) or direct OpenRouter, under a scoped virtual key (routing.scoped_environ narrows the process environment to LITELLM_*/OPENROUTER_* for the whole batch); every call is cached by (check_version, model, content_hash), so a re-run against an unchanged dossier is free (spend.json reads all zeros). Per-check models (models.CHECK_MODELS, overridable with --model/--check-model) are cache-keyed exactly as before — the model id is part of the cache key, so changing one check’s model re-judges only that check. --no-llm (or no resolvable credential) degrades honestly to tier 0 only, with a report rendered from the scaffold alone — zero LM calls, still a complete, useful document (grade histograms, worst offenders, the hole inventory, the quad.blindpair predicted-vs-observed table).

5 CLI examples#

assay run --no-llm --out /tmp/assay-dry              # tier 0 only, findings + scaffold report
assay run                                             # full tier 0-3 pass, per-check model map
assay run --model google/gemini-2.5-flash             # uniform tier-1/2 model override
assay grade --only 21 --out /tmp/assay-chamber-21     # narrow to one chamber
assay report --findings-dir /tmp/assay-dry --no-llm   # re-render a report from existing findings
assay diff /tmp/assay-old /tmp/assay-new              # symbolic grade diff of two findings dirs
arch.tools.assay.cli.main(argv=None)#

Run the requested assay stage: gather, grade, the full run, or report alone.