squash

TIER_MAP.md β€” Squash module classification for Phase G coverage gates

Generated: 2026-05-01 Β· companion to AUDIT_BASELINE.md and SQUASH_MASTER_PLAN.md Phase G. Purpose: every module in squash/ is classified into one of five tiers. Coverage / mutation / type-strictness gates apply per tier. CI is configured (Phase 5) to fail on any regression.

Tier definitions and gates

Tier Definition Line cov Branch cov Mutation score mypy Repro test required
0 β€” Cryptographic core Code that signs, hashes, canonicalises, or anchors a payload that the user (or a regulator) will rely on as evidence. A bug here invalidates every attestation. 100% 100% β‰₯ 90% --strict βœ…
1 β€” Signed report emitters Modules that produce a signed certificate, a signed BOM, an Annex-IV-grade report, or a content-addressed registry entry. They consume Tier 0 to produce evidence. β‰₯ 95% β‰₯ 90% β‰₯ 80% --strict βœ…
2 β€” Operational integrations CI hooks, registries, webhooks, gateways, dashboards, billing, governance UI. Side-effecting; integrates with external systems. β‰₯ 85% β‰₯ 75% β‰₯ 60% --strict (best-effort on third-party stubs) optional
3 β€” Internal infra Auth, rate-limiting, persistence, telemetry, plumbing. No direct user-visible attestation. β‰₯ 80% β‰₯ 70% β‰₯ 50% --strict optional
4 β€” Glue / data __init__, py.typed, data/*.json, templates/*, trivially declarative modules. β‰₯ 50% n/a n/a n/a n/a

A module’s tier is the maximum of the tiers of any signature path it lies on. If module X is imported by anything Tier 0, X is at least Tier 1.


Tier 0 β€” Cryptographic core (5)

The vault. 100/100/90 β€” non-negotiable.

Module Why Tier 0
squash/oms_signer.py Ed25519 signing primitive, key handling
squash/anchor.py Transparency-log primitive, in-process canonical-JSON helper (to be replaced with RFC 8785 in Phase 2)
squash/attest.py Root attestation pipeline; produces the signed in-toto-shaped object
squash/slsa.py SLSA in-toto Statement builder (provenance)
squash/chain_attest.py Composite signing across multi-component chains (RAG / agent / ensemble)

Phase 2 work (all five): swap canonical encoder, inject clock, replace uuid.uuid4() with uuid5(NAMESPACE, canonical_payload), add reproducibility test asserting byte-identical SHA-256 across two runs with frozen clock.


Tier 1 β€” Signed report emitters (~40)

Every cert, every BOM, every regulator-facing report. 95/90/80.

Certificate emitters

BOM / SBOM / SARIF / VEX builders

Regulator-facing report generators

Scanners / risk scorers feeding signed payloads


Tier 2 β€” Operational integrations (~30)

CI/CD plumbing, registries, side-effecting connectors. 85/75/60.

Service surface

Workflow / governance

Registries / asset management

Outbound delivery / notifications / billing

squash/integrations/*

All connectors (mlflow.py, wandb.py, huggingface.py, sagemaker.py (if present), vertex.py, ray.py, kubernetes.py, slack.py, teams.py, jira.py, linear.py, github_issues.py, gitlab.py, jenkins.py, azure_devops.py, azure_ad.py, aws_iam.py, gateway.py, gitops.py, helm.py, circleci/*, kubernetes_helm/*, langchain.py).


Tier 3 β€” Internal infra (~10)

Plumbing. 80/70/50.


Tier 4 β€” Glue / data


Mapping summary

Tier Module count Cumulative LOC (approx, wc -l)
0 5 ~3,400
1 ~40 ~30,000
2 ~30 (incl. 19+ integrations) ~22,000 (cli.py alone is 10,829)
3 ~10 ~3,500
4 n/a data + templates only

Total: ~67,900 LOC across squash/. The Phase G mandate: every Tier 0 line is byte-identity-tested, every Tier 1 module gets a reproducibility test, every signed payload uses RFC 8785 + injected clock + uuid5.


How to update this map

A module’s tier changes when its role changes β€” not when its size changes. Specifically:

CI in Phase 5 enforces this map: scripts/check_tier_map.py parses the table and asserts every squash/*.py is listed exactly once.