Evaluation Policy¶
Evidence Classes¶
- Synthetic fixtures verify deterministic schema, parsing, status, and artifact mechanics.
- Sanitized real fixtures may verify extraction quality only when their rights, restrictions, checksums, expected inventory, and field judgments are recorded.
- Historical narrative results are context only and cannot pass a threshold.
Deterministic routing mechanics and live provider quality are different evidence classes. A passing mechanics run does not establish mAI Factory, gateway-route, or exact-model quality.
Required Metrics¶
The canonical thresholds are in
tests/fixtures/golden/quality-thresholds.toml.
| Metric | Meaning |
|---|---|
exact_schema_compatibility |
Exact legacy keys, nesting, types, defaults, nulls, enums, and ordering |
variable_recall |
Expected questionnaire variables recovered |
field_accuracy |
Approved field judgments matched |
dense_repeated_table_recall |
Expected rows recovered from repeated dense tables |
Synthetic fixtures can satisfy exact schema compatibility but cannot establish real-document recall or field accuracy. Those metrics remain unavailable until an approved corpus exists.
Routing mechanics¶
This is a repository-maintainer command. It requires a source checkout and is not part of the installed package CLI or SDK. Run it without provider credentials:
uv run python scripts/evaluate_routing.py --manifest tests/fixtures/routing/manifest.toml
The evaluator compares expected, first-pass, and post-review snapshots. It uses multiset edge scoring so parallel directed edges remain distinct. It reports:
- node and accepted-edge precision and recall;
- target accuracy, where a missing or unresolved expected route is a miss;
- normalized condition-AST exact match with
raw_textexcluded from identity; - terminal and loop classification exact match;
- unresolved-route and invented accepted source-ID counts; and
- first-pass to post-review deltas.
The report contains metrics and SHA-256 digests, not questionnaire text, reviewer prose, or unresolved raw references. Zero denominators are reported as unavailable, not as perfect scores. A separate 1,000-node/3,000-edge run records hardware, duration, and peak traced memory without a cross-platform time limit.
Optional model-quality capture¶
An optional protected live test is not_run unless a human approves one
sanitized dry-run summary for an authorized source, gateway route, credential
environment-variable name, request and token ceilings, temporary-output policy,
and stop conditions. No provider call occurs as part of the deterministic package
gates.
A dynamic route can support only a gateway-route claim. An exact backend quality claim requires a pinned backend and separate application evidence. The packaged adapters retain configured route identity and the response ID, not a dynamic backend model identity. A missing or failed capture limits quality claims but does not weaken or block deterministic mechanics evidence.
Authoritative quality command¶
Run the complete deterministic quality gate from a source checkout:
uv run python scripts/evaluate_quality.py --manifest tests/fixtures/golden/manifest.toml --thresholds tests/fixtures/golden/quality-thresholds.toml --offline
The command blocks Python socket connections, validates both approved manifests,
checks exact SVIS serialization, and reuses the routing evaluator. Its JSON report
at .cache/quality/evaluation.json names every threshold, baseline, value,
availability state, and result. The synthetic baseline can pass exact schema and
routing mechanics only. variable_recall, field_accuracy, and
dense_repeated_table_recall stay explicitly unavailable until an approved real
corpus exists. An unavailable metric does not become a synthetic quality claim.
Security boundaries¶
Security has two separate commands:
uv run python scripts/run_security_gates.py collect --output-dir .cache/security
uv run python scripts/run_security_gates.py verify --reports .cache/security --allowlist security/allowlist.toml
collect invokes pip-audit, Bandit, and detect-secrets. Only the dependency
advisory lookup is network-enabled. Static and tracked-file secret scans are local.
Collection writes machine-readable scanner envelopes even when a scanner reports
findings; collection does not decide policy.
Bandit and detect-secrets are labeled tool-offline, not network-blocked.
Their selected modes have no network function, but the collection command does
not install an operating-system sandbox around scanner child processes. The
authoritative verify process still enforces its in-process socket boundary.
verify blocks Python socket connections before it reads evidence. It rejects
missing, malformed, stale, future-dated, incomplete, or wrong-boundary reports. It
also requires every allowlist entry to name its scanner, exact finding fingerprint,
owner, rationale, and future expiry. This command is the only authoritative
security policy exit. .secrets.baseline separately records reviewed synthetic
values and checksums with an owner, rationale, and expiry. The current dependency
allowlist has short-lived entries for diskcache and accelerate,
which are transitive dependencies without a currently compatible fixed release.
Workflow policy is also local and deterministic:
uv run python scripts/check_workflow_policy.py .github/workflows
It requires reviewed immutable action SHAs, top-level contents: read, no tag
trigger, and no package publication. The only deployment exception is the approved
GitHub Pages workflow in deploy-docs.yml, with job-scoped pages: write and
id-token: write as recorded in docs/legal-disposition.md.
Package and SBOM evidence¶
After dependency and wheelhouse preparation, run the artifact checks offline:
uv build
uv run twine check --strict dist/*.whl dist/*.tar.gz
uv run check-wheel-contents dist/*.whl
uv run python scripts/build_wheel_sbom.py --wheel dist/survey_scribe-0.1.1-py3-none-any.whl --wheelhouse .cache/wheelhouse --output dist/sbom.cdx.json
UV_OFFLINE=1 uv run pytest tests/package
The wheelhouse preparation step is the last package-job network boundary. SBOM
generation and package tests then run with UV_OFFLINE=1. The SBOM command
installs only the exact wheel and locked runtime wheels in a temporary environment.
It validates CycloneDX 1.6, root name/version, direct dependency names, and the
exact wheel SHA-256. Package tests verify the same artifact's contents and block
network during import and CLI smoke checks.
CI runs all required test categories with pytest-socket --disable-socket
--allow-unix-socket and the configured 95 percent coverage floor. The
Unix-socket exception is required by Python's local asyncio event loop and does
not permit TCP provider traffic.
Documentation and browser evidence use an explicit browser-install boundary:
uv run playwright install chromium
UV_OFFLINE=1 uv run mkdocs build --strict --clean
UV_OFFLINE=1 uv run linkchecker --ignore-url='^https?://' site/
UV_OFFLINE=1 uv run pytest --disable-socket --allow-unix-socket tests/docs tests/browser
The browser tests fulfill a virtual local origin only from generated site/
files and reject every external route. The locally pinned
axe-playwright-python==0.1.8 package embeds axe-core 4.12.1. Browser checks fail on
serious or critical WCAG 2 A/AA and WCAG 2.1 AA violations on every desktop and
mobile route. Deterministic checks also cover one page heading, heading order,
unique IDs, keyboard behavior, mobile overflow, and playground policy. No live
provider call is part of these commands.
Golden extraction manifest requirements¶
Each fixture record must include path, kind, rights basis, restrictions,
SHA-256, expected variable count, field-judgment status, provider/model identity,
and prompt version. Approved sanitized source and output records must bind each
other by ID and digest. The output stores a recorded actual_output, an expected
variable-ID inventory, independent JSON-pointer field judgments, and explicit
dense-table row-variable inventories. Validation fails on a missing pair, stale
checksum, invalid judgment, unknown rights basis, or missing threshold.
Routing source manifests instead declare source-only, benchmark-ineligible fixtures. The routing mechanics manifest declares repository-generated synthetic artifacts, checksums, and restrictions against provider calls, quality claims, source text, and reviewer prose.
Reproducibility¶
Golden evaluation is offline by default. Provider calls are never made by pull request tests. Any future recorded response must be synthetic or sanitized and must omit credentials, raw headers, and restricted questionnaire text.