# SPDX-License-Identifier: MPL-2.0
# Reusable-Workflow Orphan-SHA Pin + BP Name-Prefix Mismatch — 2026-05-27
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath)
#
# Machine-readable companion to audit-hypatia-pin-orphan-2026-05-27.adoc.
# Sidecar to audit-admin-merge-wrapper-sweep-2026-05-26.a2ml (parent campaign).

[manifest]
schema           = "audit/orphan-sha-pin/v1"
date             = "2026-05-27"
campaign_kind    = "reusable_workflow_repin + estate_sweep"
authoring_actor  = "claude-opus-4-7 (1M context)"
authorising_actor = "hyperpolymath (org admin)"
human_companion  = "audit-hypatia-pin-orphan-2026-05-27.adoc"
parent_audit     = "audit-admin-merge-wrapper-sweep-2026-05-26.a2ml"

[diagnosis]
failure_class      = "reusable_workflow_unresolved_orphan_sha"
failure_banner     = "This run likely failed because of a workflow file issue"
failure_signal     = "run.jobs == [] and run.conclusion == 'failure'"
root_cause         = "Sweep PRs pinned to PR-branch HEAD SHA of standards#193 before squash-merge. After merge, that SHA was orphaned (not reachable from standards/main) so GitHub Actions cannot resolve the reusable."
orphan_sha         = "97df762107501909f50bb770e9bc200b6c415600"
orphan_status_vs_main = { ahead_by = 1, behind_by = 24, status = "diverged" }
merge_commit_sha   = "915139d73560e65a8240b8fc7768698658502c89"
merge_commit_status_vs_main = { ahead_by = 0, behind_by = 1, status = "behind" }
content_diff       = "byte-identical (diff -q empty)"

[sibling_class]
name             = "wrapper_prefix_bp_mismatch"
description      = "Reusable resolves and the scan job runs successfully, but the published check name is 'hypatia / Hypatia Neurosymbolic Analysis' (caller-job-name `/` reusable-job-display-name), whereas branch protection still requires the bare pre-wrapper name 'Hypatia Neurosymbolic Analysis'."
required_context_old = "Hypatia Neurosymbolic Analysis"
required_context_new = "hypatia / Hypatia Neurosymbolic Analysis"
fix_method       = "gh api -X PATCH repos/<repo>/branches/main/protection/required_status_checks"
fix_status_typed_wasm = "applied 2026-05-26"
fix_status_estate = "out_of_scope_for_this_audit"

[estate_scope]
search_query     = "@97df762107501909f50bb770e9bc200b6c415600 user:hyperpolymath path:.github/workflows/hypatia-scan.yml"
total_repos      = 100
sweep_session_repos = 99   # excluding typed-wasm which received the fix via PR #75 directly

[sweep]
session_id       = "session-typed-wasm-2026-05-26-27"
filing_pace      = "5_parallel_per_12s"
filing_method    = "github_contents_api + gh_pr_create + auto_merge_squash"
commit_signing   = "github_web_flow (Verified, satisfies required_signatures BP)"
log_files        = [
  "/tmp/hypatia-sweep.log",
  "/tmp/hypatia-sweep-done.log",
  "/tmp/hypatia-sweep-skip.log",
  "/tmp/hypatia-sweep-fail.log",
]

[typed_wasm_local_track]
description      = "typed-wasm received the fix via direct branch edit rather than the sweep, plus two active proof-debt PRs received cherry-picks."
prs              = [
  { number = 75, branch = "ci/hypatia-scan-pin-fix",          off = "main",                                purpose = "primary SHA-pin fix off main" },
  { number = 72, branch = "claude/proof-debt-A-B-2026-05-26", purpose = "proof-debt items 1-8 (statement); SHA fix cherry-picked at commit 5e53490" },
  { number = 74, branch = "claude/items-7-8-witnesses",       purpose = "items 7+8 deepening (4 commits); SHA fix cherry-picked at commit e5c0e87" },
]

[lessons]
[lessons.pin_to_merge_commit]
finding          = "Sweep PRs against not-yet-merged reusables must pin to the merge-commit SHA, not the PR-branch HEAD SHA."
mitigation_options = [
  "Gate the sweep on the parent reusable PR being merged first.",
  "File the sweep PRs with the feature-branch SHA, then a second-pass sweep to repin once the merge lands (this audit's pattern).",
  "Use a `@v1` or branch ref instead of SHA pinning (loses immutability guarantees but is reachable).",
]

[lessons.check_published_check_name]
finding          = "A single test wrapper run on one repo before mass-sweeping would surface the `<caller-job> / <reusable-display-name>` check-name format, allowing the BP context update to be bundled with the sweep."

[lessons.idempotent_repin_sweeps]
finding          = "Contents API + auto-merge SQUASH path applies cleanly across ~100 repos in ~4 minutes at 5-per-12s pacing. Future audits can adopt the same shape."

[not_discharged]
[not_discharged.estate_bp_patch]
description      = "The 99 estate repos still have branch protection requiring the bare `Hypatia Neurosymbolic Analysis` rather than the wrapper-prefixed form. SHA-pin sweep alone does not unblock their PRs from auto-merging through their BP."
recommended_followup = "Per-repo `gh api -X PATCH` of required_status_checks, gated on owner approval."

[not_discharged.sibling_reusables]
description      = "The same orphan-SHA pattern probably exists for the other four reusables in the parent campaign: #187 mirror, #190 secret-scanner, #192 codeql, #205 scorecard."
recommended_followup = "Search the estate for each reusable's feature-branch SHA via `gh search code @<sha>` and apply this audit's fix recipe."

[not_discharged.policy_change]
description      = "Structural prevention requires a standards-repo PR-review checklist item: 'Reusable-workflow sweep PRs MUST pin to merge-commit SHAs.'"
recommended_followup = "Open standards#PR-review-checklist-orphan-sha-gate."
