1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#!/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)
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.
if ! ; then
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.
# 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 && ; then
fi
# 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 ; then
||
fi