# Validation record **PASSED — live Azure/GitHub rehearsal and verified cleanup, 10 November 2026.** All 23 required checks were satisfied across 39 recorded live check events, with nine of nine independent evidence observations passing and zero missing checks. The final accepted status and original-source hashes are in [live-status.json](live-status.json). Local tests, real cloud observations and the later archive/publication audits are separate evidence categories. ## Local checks The final documentation audit checks nine numbered blocks, seventeen code blocks, two tables, four complete learning sections, eight knowledge questions, internal anchors/local links and positive intrinsic image dimensions. Fifteen PowerShell snippets parse and use declared controller parameters; parsing did not execute them. See [docs-quality.json](evidence/docs-quality.json) and [doc-command-parse.json](evidence/doc-command-parse.json) for the checked snapshot. The archive/receipt links are generated at the subsequent release step. The source-bound [local report](evidence/local-tests.json) records **116 passing PowerShell Pester tests, 40 passing Python pipeline tests and six passing Terraform mock-provider tests**. Parser/analyzer errors are zero; **19 analyzer warnings are disclosed separately**, including presentation, naming, parameter-review and ShouldProcess rules. Bash syntax and Terraform fmt results retain their original timestamps/source bindings. These local tests do not establish Azure/GitHub behavior; the observed checks below do. ## Live acceptance | Area | Required observation | Status | |---|---|---| | Preflight | Exact tenant/subscription/repository authorization, current rates, quota/image/address checks, capture access and private baseline | Passed | | Foundation | Only owned resources; private runner without managed identity/public IP/inbound access; private Entra-authenticated Blob backend | Passed; deployed and finally verified absent | | Federation | Safe claims actually issued by this new main-branch repository; exact issuer/subject/audience on both identities | Passed with fresh independent identity evidence | | Baseline | Successful saved plan and original binary apply; scoped deployment identity; independent Reader control | Passed | | Plan guard | Real refusals for wrong/expired/consumed/mismatched approval or artifact; fresh semantic comparison and metadata checks | Four real refusals completed before the later journal-only head change; per-run provenance retained | | OIDC fault | Exact deployment subject corruption fails token exchange; fresh independent control succeeds; first/repeated repair | Fourth fresh fault accepted; first and repeated fresh repairs passed | | StateLock | Owned bounded lease causes intended lock failure; release only owned ID; state hash/serial invariants; post-release availability | Fresh replacement proof passed: verified native exit 1, serial 3 → 3, same SHA256, recovery plan 0, HEAD available | | Drift | Only owned exercise marker changes; canary preserved; exact reviewed correction; repeated repair/no-change results | Passed, including reviewed original-binary repair and repeated recovery | | Logs | Actual backend operations/identity/lease evidence; no fabricated storage event for pre-storage OIDC failure | Passed: 11 matching lease rows, two held-lease property reads and one owned drift-repair write; no HTTP 409 required | | Final state | Intended configuration, no unexpected drift and correct artifact consumption/deletion observations | Passed: workload and Foundation zero drift | | Captures | 20 genuine privacy-reviewed images: six Portal, eight CLI, six GitHub | Passed; conceptual cover is separate | | Cleanup | Exact workload destroy/Foundation absence twice, disabled workflows/runtime removal and unrelated baseline preservation | Passed twice; all 27 baseline resources preserved | | Operating limit | Six-hour active forecast ≤€15, €5 cleanup reserve, cleanup starts by 4½ hours and absence before six hours | Passed; repeated absence was verified under 2½ hours after paid start | ## Operational history 10 November 2026, 17:35 UTC: read-only Preflight passed with a current six-hour active forecast of €5.07 and €5 reserved separately for cleanup. The reviewed Foundation plan contained 27 creates, zero updates and zero deletes. Paid deployment began at **18:09:29.3285785Z**. This forecast and operational limit are not an Azure-enforced spending cap or a final invoice. The original OIDC injection was recorded at **2026-11-10T18:47:55.8846318Z**. The first attempt ran 48 seconds after the successful PUT: fresh control passed, but deployment token exchange also succeeded. It failed with `EXPECTED_OIDC_FAILURE_DID_NOT_OCCUR`, ran zero Terraform commands and is **not accepted fault evidence**. Three initial attempts did not establish the intended rejection. Without further configuration changes, the fourth fresh attempt passed at **2026-11-10T19:09:26.588027Z**, observing `AADSTS700213`. First and repeated fresh repairs passed at **19:11:43Z** and **19:14:03Z** on the same date. Keep the three unproved attempts separate from these accepted observations. [Microsoft's FIC considerations](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-considerations#time-for-federated-credential-changes-to-propagate) document propagation/cache delays and recommend retries. That supports investigating propagation; it does not prove why an individual exchange succeeded or promise that five minutes is sufficient. The StateLock workflow at **2026-11-10T19:17:24.898159Z** reported its own 60-second lease acquisition/release, recovery plan exit 0, post-release HEAD availability and the same state SHA256/serial **2 → 2**. Its original native journal/stream bytes were cleared from `RUNNER_TEMP` before the outer collector could copy them. Those bytes are unrecoverable; this attempt does **not** complete the native intended-failure diagnostic proof, and no verbatim message is asserted. The correction moved only private journals/command streams to a protected per-job directory under `RUNNER_WORKSPACE`. Authentication material, Terraform data and plans remained in `RUNNER_TEMP`. Commit `f059dda492d16f4812b05345edf687e75c78f8ea` was then rehearsed with fresh Validate and StateLock jobs. All four real guard refusals completed **before** this head change, and their original run/artifact/commit bindings remain intact. Historical evidence is not relabeled as execution of the new commit. The replacement native Terraform invocation at **2026-11-10T19:57:04.568475Z** returned exit **1** after its five-second lock timeout, with verified excerpts `Error: Error acquiring the state lock`, `Error message: state blob is already locked` and `blob metadata "terraformlockid" was empty`. The original journal and stderr bytes were retrieved and matched the workflow's published diagnostic hashes. State SHA256 stayed equal and serial remained **3 → 3**; owned-lease release, recovery plan exit 0 and post-release availability passed. Accepted native SHA256: `96ba93e340240efcb9f1c3b706dccb91d1f4ebb6446fd27b9458447fd2aa838a`; stderr SHA256: `eeefc1287cff5c54beb14e81c90c362399610e84f24299f2cbbaacfc8d8a181d`. Typed log correlation passed with **11 matching lease rows**, including acquisition (201), two `GetBlobProperties` rows during the held lease (200), and release (200), under the exact owned blob/principal/window with a maximum five-second clock-skew allowance. One successful owned NSG drift-repair write also matched. No HTTP 409 was observed or required: the [pinned backend](https://raw.githubusercontent.com/hashicorp/terraform/v1.15.8/internal/backend/remote-state/azure/client.go) can return its local lock rejection before AcquireLease. The Drift correction affected one owned NSG tag and preserved the canary. First repair and repeated repair passed; the independent repeated-recovery observation is **19:33:31.352569Z**. Final workload validation was observed at **20:00:50.474573Z**, and the Foundation detailed-exit-code no-drift check passed at **20:01:59.5187684Z**. The four real guard refusals all stopped before Terraform started: wrong hash at **18:39:13.432520Z**, consumed plan at **18:40:49.573387Z**, artifact mismatch at **18:42:08.900758Z**, and genuinely expired plan at **19:35:25.306294Z**. Their original source hashes and typed refusal codes remain in live-status. The reviewed workload Destroy succeeded, followed by exact owned-group absence at **20:26:29.5525439Z** and repeated cleanup at **20:33:15.2285538Z**. Both unrelated-baseline checks preserved all **27** resources. The private repository and its workflow history remain retained with **seven disabled workflows, zero runner registrations and zero runtime artifacts**; Azure trust and paid workshop resources were removed. ## Captures and sanitized source reports All **20** genuine captures are recorded in [capture-plan.json](capture-plan.json), privacy reviewed and checksum bound, with six Portal, eight CLI and six GitHub images. The AI synthwave cover is labeled separately. Crop/blackout provenance retains original capture timestamps and source hashes; no generated UI evidence is used. Eight allowlisted retained CLI input records are included in `docs/evidence/retained-cli/`: [01](evidence/retained-cli/01.json), [07](evidence/retained-cli/07.json), [10](evidence/retained-cli/10.json), [14](evidence/retained-cli/14.json), [15](evidence/retained-cli/15.json), [17](evidence/retained-cli/17.json), [19](evidence/retained-cli/19.json), [20](evidence/retained-cli/20.json). They preserve actual original execution facts and label later display preparation; they do not rerun commands. Record real authoring/prerequisite failures separately from the intended exercises. A runner offline condition, an unrelated timeout, missing logs or a management failure does not establish the intended fault. Later evaluation/display of retained evidence must keep its original execution time and be labeled as a later evaluation/display. Raw logs, JWTs/credentials, runner tokens, binary plans/plan JSON, Terraform state, private configuration and original images stay outside the public release. Archive integrity, deterministic extraction and the final private-material scan are recorded by the **subsequent actual release build** in the external `.zip.receipt.json`/`.zip.sha256`; this document does not pre-claim that later audit or Wix publication.