yog 0.0.3

yog: a balls-oriented session manager for lernie loops (egui frontend)
Documentation
#!/usr/bin/env bash
# yog gate — the complete build gate, factored out of .githooks/pre-commit so
# it is content-addressable: bl-speculate's verdict cache (balls design
# docs/design/bl-24e7-speculative-merge-queue.md, adopted for yog in bl-1a5b)
# fingerprints the gate as the content of THIS file,
# scripts/check-line-lengths.sh, scripts/check-coverage.sh and the Makefile,
# plus `rustc -V` — change any of them and every stored verdict silently stops
# matching, which is exactly the invalidation a gate upgrade must cause.
#
# Callers: .githooks/pre-commit (which keeps only the commit-context guard and
# delegates here), the GH Actions speculate workflow
# (.github/workflows/speculate.yml), and `bl-speculate run` build dirs.
#
# Steps, cheap first, one make-target home each so hook, `make check` and CI
# cannot drift (bl-92e2, bl-35bb):
#   0. make leak-scan — BEFORE the verdict cache, and never skipped (bl-167d)
#   1. make fmt-check
#   2. make lint     — line-cap, leak-scan, clippy -D warnings, rules-audit,
#                      cargo-deny
#   3. coverage      — scripts/check-coverage.sh (tarpaulin --fail-under 100)

set -euo pipefail

ROOT="$(git rev-parse --show-toplevel)"
cd "$ROOT"

# When git invokes the hook it exports GIT_DIR, GIT_INDEX_FILE and friends;
# they leak into every git subprocess the gates spawn and silently retarget it
# at THIS repo (tests that `git init` a tempdir included — see
# tests/git_env_scrub.rs). Scrub so the tools run as from a clean shell.
unset $(git rev-parse --local-env-vars)

if ! command -v cargo >/dev/null 2>&1; then
  echo "error: cargo not installed; cannot run the gate." >&2
  exit 1
fi

# THE DISCLOSURE GATE IS NEVER CACHED (bl-167d). Everything below this line
# may be skipped on a verdict-cache hit; this may not. Two reasons, and either
# alone is enough:
#
#   - bl-speculate's gate fingerprint is a FIXED file list compiled into that
#     binary — scripts/pre-commit, scripts/check-line-lengths.sh,
#     scripts/check-coverage.sh, the Makefile, plus `rustc -V`. The scanner is
#     not in it and yog cannot put it there. Rather than ask upstream for a
#     hook (balls bl-6a84) the scan simply stops being cacheable, which is the
#     smaller change and needs nothing from anyone.
#   - a verdict is a claim, and it can arrive from somewhere else: the
#     speculate workflow uploads a verdict store and scripts/speculate-gate
#     imports it. Every other gate step re-derives a build; this one decides
#     whether something leaves the building. It runs on the tree in hand,
#     under the scanner in hand, every time.
#
# ~5s against a gate measured in minutes, and it runs FIRST, so a leak fails
# before a compile starts. `make lint` runs it again on a cache miss; that is
# the price of `lint` staying the whole static gate rather than a subset.
echo "gate: leak-scan (make leak-scan)..." >&2
make leak-scan >&2

# Verdict cache: the gate verdict is a pure function of the tree it tests and
# the gate that tests it. If this exact worktree tree already passed this
# exact gate — an earlier run here, or a speculator ahead of the merge queue —
# the run below would re-execute a known result, so skip it. An absent binary,
# an absent verdict, or any error all fall through to the stock gate
# (fail-open): deleting the cache restores stock behavior exactly.
if command -v bl-speculate >/dev/null 2>&1 && bl-speculate check 2>/dev/null; then
  echo "gate: verdict cache hit — this exact tree already passed this exact gate." >&2
  exit 0
fi

echo "gate: fmt (make fmt-check)..." >&2
make fmt-check >&2

echo "gate: lint (make lint)..." >&2
make lint >&2

echo "gate: coverage (scripts/check-coverage.sh)..." >&2
"$ROOT/scripts/check-coverage.sh"

# Warm the cache with the verdict just earned — the next fold to this exact
# tree (a queued close behind this one, or a retry) skips the whole run.
# Fail-open: recording is never allowed to block a pass.
if command -v bl-speculate >/dev/null 2>&1; then
  bl-speculate record pass 2>/dev/null || true
fi

echo "gate: OK." >&2