Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions docs/audits/audit-hypatia-cache-sha-corruption-2026-06-21.a2ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# SPDX-License-Identifier: MPL-2.0
# Central Reusable actions/cache SHA Corruption — 2026-06-21
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath)
#
# Machine-readable companion to audit-hypatia-cache-sha-corruption-2026-06-21.adoc.
# Sibling to audit-hypatia-pin-orphan-2026-05-27.a2ml (a different SHA-pin class).

[manifest]
schema = "audit/action-sha-corruption/v1"
date = "2026-06-21"
campaign_kind = "central_reusable_action_repin"
human_companion = "audit-hypatia-cache-sha-corruption-2026-06-21.adoc"
sibling_audit = "audit-hypatia-pin-orphan-2026-05-27.a2ml"
umbrella_issue = "hyperpolymath/hypatia#464"
out_of_scope_central_ref = "hyperpolymath/nextgen-typing#69"

[diagnosis]
failure_class = "third_party_action_pin_unresolved_in_central_reusable"
failure_stage = "Prepare all required actions"
failure_banner = "Unable to resolve action actions/cache@d4373f267a887d77f9eb0683a479ec60b1fe5b2b"
corrupt_sha = "d4373f267a887d77f9eb0683a479ec60b1fe5b2b"
corrupt_sha_comment = "# v4.2.0"
likely_source = "corruption of v4.2.2 commit d4323d4df104b026a6aa633fdb11d772146be0bf"
location = "central only — zero consumer workflows carry the SHA"
affected_reusables = [
".github/workflows/hypatia-scan-reusable.yml",
".github/workflows/governance-reusable.yml",
]
observed_failing = ["nextgen-databases#41", "KnotTheory.jl#29", "nextgen-typing#67", "wokelangiser"]

[verification]
method = "git ls-remote https://github.com/actions/cache"
corrupt_sha_resolves = false
repair_pin = "1bd1e32a3bdc45362d1e726936510720a7c30a57"
repair_pin_ref = "refs/tags/v4.2.0"
known_good_v4 = "0057852bfaa89a56745cba8c7296529d2fc39830" # refs/tags/v4 + v4.3.0
known_good_v5 = "27d5ce7f107fe9357f9df03efb73ab90386fccae" # main + v5 + v5.0.5
grep_after_fix = "zero matches for d4373f… across standards + hypatia"

[fix]
pr = "hyperpolymath/standards#394"
merged_at = "2026-06-21T10:52:13Z"
merge_commit = "d72fe5a14e841ac6d78514b53624b6173038ee20"
change = "actions/cache@d4373f… -> actions/cache@1bd1e32a… (# v4.2.0 preserved, now accurate)"
status = "MERGED to standards/main — central root cause resolved + verified"

[propagation]
caveat = "necessary but not sufficient: consumers pin reusables by standards commit SHA, not @main"
consumer_pin_hypatia = "5eb28d7d8790d5389b7b6a5233fe6265a775e3d0"
consumer_pin_most_repos = "861b5e911d9e5dcfb3c0ab3dd2a9a3c8fd0a1613"
staleness_check = "scripts/check-workflow-staleness.sh fails any consumer whose pinned SHA != current standards HEAD"
staleness_red_meaning = "expected drift after #394, not a new defect — signals pending re-enrollment"
re_enroll_target = "d72fe5a (or later standards HEAD)"
re_enroll_tool = "gitbot-fleet enroll-repos"
re_enroll_scope = "out_of_scope (consumer repos + gitbot-fleet are not standards/hypatia)"

[companion_findings_nextgen_databases.k9_pedigree]
file = "verisimdb/connectors/test-infra/deploy.k9.ncl"
error = "Pedigree block missing 'name'"
schema_ref = "k9-svc/pedigree.ncl Metadata.name (String, no default -> mandatory)"
sample_ref = "k9-svc/pandoc/container/deploy.k9.ncl"
fix = "add metadata.name; ideally metadata.version + validation.pedigree_version + trust_level/security_level ('Kennel|'Yard|'Hunt)"
scope = "out_of_scope (nextgen-databases repo-internal, pre-existing)"

[companion_findings_nextgen_databases.trusted_base]
check = "governance / trusted-base"
policy_ref = "docs/TRUSTED-BASE-REDUCTION-POLICY.adoc + scripts/check-trusted-base.sh"
cause = "undocumented soundness-relevant escape hatch in a proof-bearing file"
fix = "discharge / budget / axiom / dated-debt entry in nextgen-databases docs/proof-debt.md"
scope = "out_of_scope (nextgen-databases repo-internal, pre-existing)"

[not_discharged]
consumer_re_enrollment = "gitbot-fleet enroll-repos repin of consumers to d72fe5a+ — tracked on hypatia#464"
nextgen_databases_internal = "K9 pedigree + trusted-base — repo-internal, flagged via hypatia#464 / nextgen-typing#69"
134 changes: 134 additions & 0 deletions docs/audits/audit-hypatia-cache-sha-corruption-2026-06-21.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// SPDX-License-Identifier: CC-BY-SA-4.0
// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell (hyperpolymath)

= Central Reusable actions/cache SHA Corruption — 2026-06-21
:toc:
:toclevels: 2
:source-highlighter: rouge
:icons: font

Companion machine-readable manifest: `audit-hypatia-cache-sha-corruption-2026-06-21.a2ml`.
Sibling to `audit-hypatia-pin-orphan-2026-05-27.adoc` — a *different* SHA-pin
failure class on the same two reusables (that one was the orphaned
`@<standards-sha>` reference to the reusable; this one is a corrupt
third-party action SHA *inside* the reusable).

== Summary

From 2026-06-20/21 the estate-wide `scan / Hypatia Neurosymbolic Analysis`
job failed at the *"Prepare all required actions"* stage — before any scan
step ran — with:

----
Unable to resolve action `actions/cache@d4373f267a887d77f9eb0683a479ec60b1fe5b2b`
(unable to find version d4373f267a887d77f9eb0683a479ec60b1fe5b2b)
----

The corrupt SHA was **not** present in any consumer workflow. It was pinned
once, centrally, in the two reusable workflows that every estate repo calls:

* `.github/workflows/hypatia-scan-reusable.yml`
* `.github/workflows/governance-reusable.yml`

Observed failing on `nextgen-databases#41`, `KnotTheory.jl#29`,
`nextgen-typing#67` (and, per PR #394, `wokelangiser`).

== Root cause

`d4373f267a887d77f9eb0683a479ec60b1fe5b2b` does not correspond to any
`actions/cache` ref. It is a corruption of v4.2.2's real commit
`d4323d4df104b026a6aa633fdb11d772146be0bf` — the version comment read
`# v4.2.0`, but the hash matched neither v4.2.0 nor v4.2.2. GitHub Actions
resolves a `uses:` SHA as a commit; an unknown SHA fails the whole job at
parse stage, so no consumer scan ever started.

== Verification

Upstream resolution via `git ls-remote https://github.com/actions/cache`:

[cols="2,3,1", options="header"]
|===
| SHA | Upstream ref | Resolves?

| `d4373f26…` (the corrupt pin) | (none) | ✗ bogus
| `d4323d4d…` (v4.2.2 — the likely typo source) | `refs/tags/v4.2.2` | ✓
| `1bd1e32a…` (the repair pin) | `refs/tags/v4.2.0` | ✓
| `0057852b…` (estate "most common") | `refs/tags/v4` + `v4.3.0` | ✓
| `27d5ce7f…` (estate, used across hypatia) | `main` + `v5` + `v5.0.5` | ✓
|===

`git grep d4373f267a887d77f9eb0683a479ec60b1fe5b2b` across standards and
hypatia → zero matches after the fix.

== Fix — standards#394 (merged 2026-06-21T10:52Z, commit `d72fe5a`)

Both reusables re-pinned, preserving the documented version:

[source,diff]
----
- uses: actions/cache@d4373f267a887d77f9eb0683a479ec60b1fe5b2b # v4.2.0
+ uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
----

`1bd1e32a…` is the genuine immutable `v4.2.0` commit, so the `# v4.2.0`
comment is now accurate. This is a surgical hash repair, not a version bump
to the moving `v4` tag.

== Propagation caveat — necessary but not yet sufficient

Consumers do **not** pin these reusables to `@main`. They pin a specific
`standards` commit SHA, e.g.:

----
uses: hyperpolymath/standards/.github/workflows/hypatia-scan-reusable.yml@5eb28d7d… (hypatia itself)
uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@861b5e91… (most consumers)
----

Because the repair landed as a *new* `standards` HEAD (`d72fe5a`), every
consumer still pinned at a pre-#394 SHA keeps dereferencing the broken cache
pin until it is re-enrolled to a post-#394 SHA. This is exactly what
`scripts/check-workflow-staleness.sh` reports — it fails any consumer whose
pinned SHA != current standards HEAD ("Workflow pins Hypatia reusable before
cache/baseline-delay fix. Refresh to current standards SHA.").

Therefore the post-#394 `governance / Check Workflow Staleness` red is
**expected drift**, not a new defect: it is the signal that the estate
re-enrollment pass (gitbot-fleet `enroll-repos`, repinning consumers to
`d72fe5a` or later) is still pending. Re-enrollment is the propagation
mechanism; until it runs, an affected consumer sees both the cache failure
(if its pinned SHA predates #394) and the staleness failure.

== Companion findings — out of scope (central), recorded for the backlog

These surfaced on `nextgen-databases` alongside the central failure. They are
**repo-internal**, pre-existing, and not addressed by #394:

. *K9 pedigree validation.* `verisimdb/connectors/test-infra/deploy.k9.ncl`
fails "Pedigree block missing 'name'". In `k9-svc/pedigree.ncl`,
`Metadata.name | String` is the only metadata field with no `default`, so
it is mandatory. Fix: add `metadata.name`; per the canonical
`k9-svc/pandoc/container/deploy.k9.ncl` sample, ideally also
`metadata.version` + `validation.pedigree_version` and a leash level —
`trust_level`/`security_level` ∈ `'Kennel | 'Yard | 'Hunt` (a
shell-running `deploy.k9.ncl` is `'Hunt`).
. *Trusted-base reduction policy.* The `governance / trusted-base` job (per
`docs/TRUSTED-BASE-REDUCTION-POLICY.adoc` + `scripts/check-trusted-base.sh`)
is red: a soundness-relevant escape hatch in a proof-bearing file in
`nextgen-databases` is undocumented. Disposition is per-repo — discharge,
budget (`// TRUSTED:`), axiom (`// AXIOM:`), or a dated debt entry in that
repo's `docs/proof-debt.md`.

== What this audit does NOT discharge

* The consumer re-enrollment pass (gitbot-fleet `enroll-repos` → repin
consumers to `d72fe5a`+). Out of scope for standards + hypatia; tracked on
hypatia#464.
* The two `nextgen-databases` repo-internal findings above. Out of scope
(that repo); flagged for its maintainers via hypatia#464 / nextgen-typing#69.

== Cross-references

* Fix PR: `hyperpolymath/standards#394` (merged 2026-06-21).
* Estate CI-health umbrella: `hyperpolymath/hypatia#464`.
* "Out of scope — central" list: `hyperpolymath/nextgen-typing#69`.
* Sibling SHA-pin audit: `audit-hypatia-pin-orphan-2026-05-27.adoc`.
Loading