« Phase 15 · Warmup · Track Overview

Lab 01 — The Evidence Engine

The problem

An examiner sits down with one question:

"On 12 March, an agent initiated a payment of AED 250,000 for customer X. Show me: who authorized it, what the agent was permitted to do at that moment, what data it used to decide, which model version produced the decision, which policy version allowed it, and who reviewed it."

You have logs. You have traces. You have an audit table. And you cannot answer, because:

  • the policy decision is in the control plane's store, the inference record is in the gateway's ledger, the retrieval is in the search service's log, and nothing joins them;
  • the model version was recorded but the prompt version was not, and somebody edited the prompt in February;
  • the retrieval snapshot was never pinned, so nobody can say which documents the agent saw;
  • and the approval is a Teams message.

Six months of work exists and none of it is evidence. Evidence is a linked set of records with shared join keys, generated as a by-product of serving — and anything assembled afterwards is a reconstruction, which an examiner can tell.

You build the engine that generates it, and that refuses to produce a pack with a hole in it.

What you build

#ComponentWhat it does
1assign_tier, TIER_POLICIESimpact-based tiering that drives autonomy, validation and evals
2ModelConfigurationthe agent configuration is the model — fingerprinted
3ModelInventorythe register, and the promotion gate
4LineageGraphancestors (the examiner's question) and descendants (the impact query)
5ResidencyCheckerproved per record, not asserted from config
6check_reproducibilitythe six pins, and the caveats you must state
7ThirdPartyRegisterconcentration risk, and exit readiness that means something
8EvidenceGeneratora signed, hash-chained pack that fails loudly
9control_coveragea control that emits no artifact does not exist

Key concepts

ConceptWhereWhy it matters
Tier by impact, not techniqueassign_tier"is it an LLM?" is not a risk question
A tier must change somethingTierPolicyone that changes nothing is a label
Tier drives autonomymax_autonomywired to Phase 10, not filed
The reason is recordedtier_reasonsa bare tier is one nobody can challenge
The configuration is the modelModelConfigurationso a prompt edit is a model change
A config change invalidates validationrecord_changeand drops it out of production
The owner cannot validatevalidatethat check is the whole of "independent"
The inventory is the gatepromotethe only thing that keeps it current
Every blocker at oncepromoteone-at-a-time teaches teams to resent the gate
trace_id is the designArtifactretrofitting it loses the first N months forever
Causal order at write timeadda graph you cannot walk is not evidence
Ancestors = the examiner's questionancestors"what did it use to decide?"
Descendants = the impact querydescendants"this was wrong; what did it affect?"
Orphans are worse than gapsorphansa disconnected artifact looks like evidence
Residency is proved per recordResidencyCheckerconfig says what should; records say what did
Unprovable is a violationcheck_tracea record without a region is not evidence
The forgotten pinretrieval_snapshotthe corpus moves; the query does not reproduce
State the caveatcaveatsbit-reproducibility for a sampled model will be tested
An untested exit is a documentExitReadinessthe only convincing answer is live traffic
Concentration aggregates per providerassess_concentrationtwo models, one vendor, one risk
Generated, not assembledEvidenceGeneratora reconstruction has gaps it cannot explain
Missing artifacts fail loudlygeneratean engineering problem, not an audit finding
Chain and signatureverifyone catches an edit, the other catches a re-hash
Silent controls must be namedcontrol_coveragethey need other evidence, and you must know which

Files

FileRole
lab.pyyour implementation
solution.pyreference; python solution.py runs an eight-part worked session
test_lab.py124 tests
requirements.txtpytest

Run

pip install -r requirements.txt
pytest test_lab.py -v
LAB_MODULE=solution pytest test_lab.py -v
python solution.py

Success criteria

  • All 124 tests green against your lab.py.
  • An irreversible action is Tier 1 regardless of value; a Tier 3 assignment still gives a reason.
  • A higher tier caps autonomy lower, demands more eval cases, and monitors more often.
  • The fingerprint ignores config_id and version, and changes for prompt, retrieval, tools, guardrails and temperature.
  • A model with no owner, no business sponsor or no purpose cannot be registered.
  • The owner cannot validate their own model.
  • promote reports every blocker, not the first.
  • A prompt change resets validation to not_submitted and removes it from production.
  • An artifact deriving from an unknown parent is refused at write time.
  • A diamond reports each ancestor once; a cycle is detected.
  • An out-of-region inference is flagged and a record with no region is flagged.
  • A trace missing only the retrieval snapshot is reported as non-reproducible.
  • A non-zero temperature is a caveat, not a failure.
  • Traffic share aggregates per provider, not per model.
  • A LIVE exit path needs no exit test; an IDENTIFIED one is a finding.
  • A 250,000 action with no approval record fails with the artifact named.
  • Editing, dropping or re-signing an artifact all break verification.
  • Coverage is generated from the catalogue and names the silent controls.

How this maps to the real stack

This labThe real thingWhat we simplified
ModelInventoryan internal GRC system, ServiceNow, or a model-risk platformno workflow, no approvals routing, no attestations
assign_tiera bank's own model-risk tiering standardfour inputs; a real one has twenty and a committee
LineageGraphOpenLineage/Marquez, Purview, or an internal lineage servicein-memory; no persistence, no cross-system federation
Artifactrecords in six different stores, joined on a trace idone store; the join is the hard part in reality
ResidencyCheckera query over inference logs + Azure Policy compliance stateno real logs, no region metadata from the platform
check_reproducibilitya deployment manifest plus an eval harnesspins as strings; no actual re-execution
ThirdPartyRegistera vendor-risk system with contracts attachedno contract text, no renewal dates, no assessments
EvidenceGeneratora report generator over the audit storeno persistence, no access control, no redaction for the recipient
CONTROL_CATALOGUEa control library mapped to a framework, in a GRC toolhand-maintained; a real one is versioned and attested

Honest limits. The lineage graph is in-memory and single-system; the genuinely hard part in production is that the six artifact kinds live in six stores with different retention, different access control and different query languages, and federating them is most of the work. There is no redaction: an evidence pack shown to an external examiner should not contain another customer's data, and deciding what to withhold without breaking the chain is a real design problem. The reproducibility check verifies that pins exist, not that re-execution works — the only honest test is to actually re-run against the pinned snapshot, which needs the snapshot to still exist, which is a retention decision. Residency is checked from records the platform emitted about itself, so it inherits their trustworthiness — pair it with Phase 13's topology proof rather than relying on either alone. And tiering here is a function of four booleans; a real standard has a committee, precedent, and appeals.

Extensions

  1. Federate the lineage. Put the artifacts in three different stores with three different schemas and join them at query time. The pain you feel is the actual problem.
  2. Redaction for external disclosure. Produce a pack for an examiner that omits other customers' data while keeping the chain verifiable — which means hashing what you withhold and proving the omission is complete.
  3. Actually re-execute. Take a pinned trace, restore the retrieval snapshot, re-run, and diff. Then discover which pins were insufficient.
  4. Retention tiering. Evidence for 7 years, debugging traces for 30 days. Model the archive, the restore path, and the cost.
  5. Attestation. Publish the pack's chain head to an append-only external store hourly, so the chain becomes tamper-resistant rather than tamper-evident (Phase 10).
  6. A validation pack template for an agentic system: scope, limitations, eval results, red-team results, monitoring plan, and the conditions under which approval lapses.
  7. Continuous control monitoring. Run verify_control_evidence over a sample of production traces daily, and alert when a control stops emitting — which is how you find out a control was removed by a refactor.
  8. Map to the EU AI Act. Add its obligations as a framework in the catalogue and see which controls you already have and which you do not.

Interview / resume bullets

  • "Built the platform's evidence engine: every layer emits a lineage artifact keyed on a shared trace id, so an examiner's question — who authorized this, under which policy, using what data, from which model version — is answered by a generated, signed, hash-chained pack rather than by a reconstruction."
  • "Made the pack generator refuse to produce an incomplete bundle, naming the missing artifact — so an evidence gap surfaces as an engineering ticket during development rather than as an audit finding two years later."
  • "Argued and implemented that the agent configuration as a whole is the model: a prompt, retrieval, tool-set or guardrail change invalidates validation and removes the agent from production, which brought agentic systems inside the bank's existing SR 11-7 framework."
  • "Tiered models by business impact rather than technique, and wired the tier to the autonomy band — so risk classification determines what an agent may do without a human, instead of sitting in a register."
  • "Proved data residency per inference record rather than asserting it from configuration, and paired it with a network reachability proof so the claim held from two independent directions."
  • "Replaced a paper exit plan with an exit-readiness ladder where the top rung is live production traffic on the alternative — which turned concentration risk from a paragraph into an architecture."