forjar 1.31.0

Rust-native Infrastructure as Code — bare-metal first, BLAKE3 state, provenance tracing
Documentation
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
#!/usr/bin/env python3
"""Quorum evidence checks -- Refs #390.

WHY THIS EXISTS. The owner's rule is that a quorum's intermediate results AND its
conclusion must be attached to the PR as evidence and metadata. Audited on the
gate's own first PR, that was not happening: the receipt carried the 17 REFUTED
claim texts and the 43 CONFIRMED ones existed only as the integer 43, while the
lane summaries, judge scores and independent review lived in agent-local state
(~36 MB) and /tmp (~9.6 MB) -- both gone on reboot. A verdict whose evidence
evaporates is an assertion.

WHAT IT PROVES, AND WHAT IT DOES NOT. It proves that scrubbed, untruncated,
diff-cited, unrecycled prose is COMMITTED, matches the tallies, and cites lines
that resolve at the commit the quorum actually read. It does NOT prove a quorum
happened -- nothing here observes seven blind lanes or three judges. On-target
fabrication was priced during design, not waved away: a ~40-line template loop
still passes. This raises the floor from "type an integer" to "write reviewable
prose anchored to the real diff"; it is not a proof of process.

OFFLINE BY CONSTRUCTION. git object DB + re + hashlib. A pre-push hook must never
need the network.
"""
import hashlib
import json
import re
import subprocess
import sys

FILE_MAX, TOTAL_MAX, ITEM_MIN, ANCHOR_MIN = 128 * 1024, 512 * 1024, 180, 0.33
# Round numbers a writer picks as a budget. A body landing EXACTLY on one is a
# truncation tell, not a coincidence -- 18 of 43 quotes in the first digest were
# exactly 600 bytes.
TRUNC_BUDGETS = (200, 300, 400, 500, 600, 800, 1000, 1200, 1400, 1500, 2000, 4000)
ROLES = {"claims", "lanes", "judges", "agy", "pmat", "proposals", "crux"}

SEC_RE = re.compile(r"(?m)^#{2,4}\s+(CONFIRMED|REFUTED)\b")
ITEM_RE = re.compile(r"(?m)^(?=\d+\.\s+\[)")
STOP_RE = re.compile(r"(?m)^(?:\d+\.\s+\[|#)")
SUB_RE = re.compile(r"(?m)^\s*-\s+(evidence|corrected):\s*(.*)$")
# A RELEASE COMMIT MUST BE ABLE TO CITE ITSELF. This matched Rust sources only,
# so the three files a release edits -- Cargo.toml, Cargo.lock, CHANGELOG.md --
# were not citations at all, and v1.25.2's receipt anchored 0 of 19 claims.
# v1.25.0 (0b4f2e3e) and v1.25.1 (813159f2) were pushed `waived` for the same
# reason: the gate was refusing a SHAPE rather than bad evidence, and a gate that
# cannot be passed honestly is what teaches a repo to reach for the waiver.
# The root files are matched AT THE ROOT ONLY -- the lookbehind refuses
# `crates/x/Cargo.toml:3`, which would resolve to a different file than it names.
CIT_RE = re.compile(
    r"\b((?:src|tests|scripts|benches)/[A-Za-z0-9_./-]+\.rs"
    r"|(?<![\w./-])(?:Cargo\.toml|Cargo\.lock|CHANGELOG\.md|README\.md)):(\d+)\b"
)

# forjar#491: the same shape, one level up. A `kind: triage` branch -- classify
# and link, no diff -- touches only docs/audits/**, the roadmap and, since
# PMAT-226, the release ledger docs/roadmaps/releases.yaml. It has no
# Rust file to cite, so under CIT_RE it anchors 0% BY CONSTRUCTION and every
# triage PR was pushed `waived`. For a receipt that declares `kind: triage`, a
# citation into a DOCUMENTATION file the branch touches anchors under the same
# at-base / as-added / must-be-touched rules. ONLY for that kind: widening the
# shape for every receipt would let a code branch anchor its claims on the
# receipt it wrote itself instead of on code, and scripts/quorum-gate.sh refuses
# a `kind: triage` receipt whose diff touches anything outside the triage rail,
# so declaring the kind is not a way around this. `.quorum/evidence/**` is
# deliberately absent: a digest citing itself is circular.
CIT_RE_TRIAGE = re.compile(
    r"\b((?:src|tests|scripts|benches)/[A-Za-z0-9_./-]+\.rs"
    r"|docs/[A-Za-z0-9_./-]+\.(?:md|yaml|jsonl)"
    r"|(?<![\w./-])(?:Cargo\.toml|Cargo\.lock|CHANGELOG\.md|README\.md)):(\d+)\b"
)


def citation_shape(receipt_kind):
    """The citation regex a receipt of this kind anchors with."""
    return CIT_RE_TRIAGE if receipt_kind == "triage" else CIT_RE

# SHAPE-BASED, never environment-derived. A scanner keyed on "whoever is running
# it" passes clean on every other machine. These sixteen are a DENYLIST and
# cannot prove absence -- a novel credential shape or a customer name in prose
# walks straight through. Named as a limit rather than sold as a guarantee.
LEAKS = [
    ("user_at_ip", re.compile(r"\b[A-Za-z0-9._-]+@(?:\d{1,3}\.){3}\d{1,3}\b")),
    ("sshd_user", re.compile(r"sshd:\s*(?!<)[A-Za-z0-9._-]+@")),
    ("ssh_controlpath", re.compile(r"ControlPath=(?!<)\S+")),
    ("home_path", re.compile(r"/(?:home|Users)/(?!<)[A-Za-z0-9._-]+")),
    ("mac_scratch", re.compile(r"/var/folders/[A-Za-z0-9+_/-]{6,}")),
    ("claude_scratch", re.compile(r"/tmp/claude-\d+")),
    ("session_uuid", re.compile(r"\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b")),
    ("aws_access_key", re.compile(r"AKIA[0-9A-Z]{16}")),
    ("github_token", re.compile(r"gh[pso]_[A-Za-z0-9_]{36,}")),
    ("private_key", re.compile(r"-----BEGIN (?:RSA|EC|DSA|OPENSSH) PRIVATE KEY-----")),
    ("stripe_key", re.compile(r"[sr]k_(?:live|test)_[A-Za-z0-9]{20,}")),
    ("age_secret", re.compile(r"AGE-SECRET-KEY-1[A-Z0-9]{58}")),
    ("jwt", re.compile(r"eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}")),
    ("db_url_creds", re.compile(r"(?i)(?:mysql|postgres|postgresql|mongodb)://[^\s:/]+:[^\s@]+@")),
    ("slack_webhook", re.compile(r"https://hooks\.slack\.com/services/\S+")),
]


def die(msg):
    print(f"\u2717 QUORUM GATE: {msg}", file=sys.stderr)
    sys.exit(1)


def git(*args, binary=False):
    p = subprocess.run(["git", *args], capture_output=True)
    return p.returncode, (p.stdout if binary else p.stdout.decode("utf-8", "replace"))


def blob_at(rev, path):
    rc, out = git("cat-file", "blob", f"{rev}:{path}", binary=True)
    return out if rc == 0 else None


def sections(text):
    heads = list(SEC_RE.finditer(text))
    for i, h in enumerate(heads):
        end = heads[i + 1].start() if i + 1 < len(heads) else len(text)
        yield h.group(1), text[h.end():end]


def items(body):
    out = []
    for part in ITEM_RE.split(body):
        if not re.match(r"\d+\.\s+\[", part):
            continue
        # TIGHT bound. Without it the last item of a section absorbs everything
        # after it and passes every length floor for free.
        m = STOP_RE.search(part, 1)
        out.append(part[:m.start()] if m else part)
    return out


def truncated(body):
    n = len(body)
    if n in TRUNC_BUDGETS:
        return f"length is exactly {n} -- a writer budget, not a sentence"
    if body.count("`") % 2 == 1:
        return "ends inside an unclosed backtick span"
    # A THIRD RULE WAS TRIED AND DROPPED: `[A-Za-z0-9_/]$` -> "ends mid-token".
    # Measured against the real #390 corpus it fired on COMPLETE prose -- a 639 B
    # body, well under its 1337 B budget, genuinely ending `bash-exit=127`. Plenty
    # of honest sentences end in a number or an identifier. The two rules above are
    # high precision and caught every actual defect in that corpus (18 bodies at
    # exactly 600 B, 11 unclosed backticks); the third added false refusals and no
    # detection. A gate that cries wolf on good evidence trains people to bypass it.
    return None


def check_entry_shape(e, listed):
    """One manifest entry's path and roles, before anything is read from git."""
    path, rs = e.get("path", ""), e.get("roles", [])
    if not path.startswith(".quorum/evidence/"):
        die(f"evidence path '{path}' is outside .quorum/evidence/")
    if path in listed:
        die(f"evidence path '{path}' is listed twice")
    if not isinstance(rs, list) or not rs or set(rs) - ROLES:
        die(f"evidence '{path}' roles {rs!r}; must be a non-empty subset of {sorted(ROLES)}")
    return path, rs


def committed_blob(e, head, path):
    """The blob the entry names, read from the commit and checked field by field."""
    raw = blob_at(head, path)
    if raw is None:
        die(f"evidence '{path}' is NOT COMMITTED at HEAD.\n"
            f"  The gate reads the tree; CI reviews what was PUSHED.\n"
            f"  Commit it:  git add {path} && git commit")
    bid = git("rev-parse", f"{head}:{path}")[1].strip()
    sha = hashlib.sha256(raw).hexdigest()
    for field, got, want in (("blob", e.get("blob"), bid),
                             ("sha256", e.get("sha256"), sha),
                             ("bytes", e.get("bytes"), len(raw))):
        if got != want:
            die(f"evidence '{path}': receipt {field}={str(got)[:16]}, committed {str(want)[:16]}")
    if len(raw) > FILE_MAX:
        die(f"evidence '{path}' is {len(raw)}B over the {FILE_MAX}B ceiling. Split by role;\n"
            "  the raw journal belongs in an expiring artifact, not in git.")
    return bid, raw


def check_totals_and_roles(ev, total, roles):
    if total != ev.get("total_bytes"):
        die(f"evidence.total_bytes={ev.get('total_bytes')}, committed blobs sum to {total}")
    if total > TOTAL_MAX:
        die(f"evidence totals {total}B over the {TOTAL_MAX}B ceiling")
    for need in ("claims", "lanes", "judges", "agy"):
        if need not in roles:
            die(f"no evidence file carries role '{need}'. The rule names lane summaries,\n"
                "  judge scores and the independent review as evidence -- not only claims.")


def check_manifest(ev, head, blobs):
    listed, roles, total = set(), set(), 0
    for e in ev["files"]:
        path, rs = check_entry_shape(e, listed)
        listed.add(path)
        roles.update(rs)
        bid, raw = committed_blob(e, head, path)
        blobs[path] = (bid, raw)
        total += len(raw)
    check_totals_and_roles(ev, total, roles)
    return listed


def check_provenance(listed, blobs, touched):
    """Anchored to things the pusher did not author: the diff, and origin/main."""
    if not (listed & touched):
        die("no evidence file is touched by this branch. Every listed file already\n"
            "  existed unchanged -- which is exactly what a recycled receipt looks like.")
    rc, out = git("ls-tree", "-r", "origin/main", "--", ".quorum/evidence")
    prior = {ln.split()[2] for ln in out.splitlines() if len(ln.split()) > 2}
    for path, (bid, _) in blobs.items():
        if bid in prior:
            die(f"evidence '{path}' is byte-identical to a blob already on origin/main.\n"
                "  Copying a merged PR's evidence forward is the cheapest forgery there is.")


def check_redaction(blobs):
    for path, (_, raw) in blobs.items():
        text = raw.decode("utf-8", "replace")
        for name, rx in LEAKS:
            m = rx.search(text)
            if m:
                line = text[:m.start()].count("\n") + 1
                die(f"'{path}':{line} leaks {name}: {m.group(0)[:48]!r}\n"
                    "  Scrub it (<user>, <host>, <SCRATCH>, <REPO>) and re-commit.\n"
                    "  THIS REPO IS PUBLIC -- this exact class already leaked once.")


def check_item(it, kind, dp, seen):
    """One adjudicated claim: distinct headline, over the floor, sublines intact."""
    head_line = re.sub(r"\s+", " ", it.split("\n")[0]).strip().lower()
    if head_line in seen:
        die(f"'{dp}': duplicate claim {head_line[:60]!r} -- "
            "N copies of one sentence is a tally with extra steps")
    seen.add(head_line)
    if len(it) < ITEM_MIN:
        die(f"'{dp}': a {kind} claim is {len(it)}B, floor {ITEM_MIN}B")
    subs = SUB_RE.findall(it)
    if not subs:
        die(f"'{dp}': a {kind} claim carries no '- evidence:'/'- corrected:' subline")
    for _, sb in subs:
        check_subline(sb, kind, dp)


def check_subline(sb, kind, dp):
    why = truncated(sb.rstrip())
    if why:
        die(f"'{dp}': a {kind} subline is TRUNCATED -- {why}.\n"
            f"     ...{sb.rstrip()[-60:]!r}\n"
            "  Fix the EMITTER: a severed citation is unreviewable and no\n"
            "  other tier survives to complete it.")


def check_tallies(counts, want_conf, want_ref):
    # SYMMETRY. The gate used to demand prose for what the panel KILLED and accept
    # a bare integer for what it BLESSED -- strict about the claims nobody
    # fabricates to look good, lax about the ones that ship into the changelog.
    for kind, want, label in (("CONFIRMED", want_conf, "claims_confirmed"),
                              ("REFUTED", want_ref, "claims_refuted")):
        if counts[kind] != want:
            die(f"{label}={want} but the digest carries {counts[kind]} {kind} claims.\n"
                "  A tally that disagrees with its own prose is the black box this gate\n"
                "  already rejects for the refuted side.")


def check_claims(blobs, dp, want_conf, want_ref, base, head, touched, cit_re):
    text = blobs[dp][1].decode("utf-8", "replace")
    counts, seen, adjudicated = {"CONFIRMED": 0, "REFUTED": 0}, set(), []
    for kind, body in sections(text):
        for it in items(body):
            counts[kind] += 1
            adjudicated.append(it)
            check_item(it, kind, dp, seen)
    check_tallies(counts, want_conf, want_ref)
    check_anchors(adjudicated, dp, base, head, touched, cit_re)


def anchors_at_base(src, dp, p, n, touched):
    """Whether a citation that RESOLVES AT THE MERGE BASE anchors its claim.

    This is the strong form. The cited text sits in a tree the pusher did not
    author, so a line number cannot be invented to fit a claim. An out-of-range
    citation is refused BY NAME rather than quietly dropped: a citation the gate
    cannot check is not a citation the gate should count.
    """
    if int(n) > src.count(b"\n") + 1:
        die(f"'{dp}': cites '{p}:{n}' but that file has {src.count(chr(10).encode())+1} lines at base")
    return p in touched


def anchors_as_added(head, dp, p, n, touched):
    """Whether a citation into a file THIS BRANCH ADDS anchors its claim.

    The guarantee is weaker than `anchors_at_base`'s and worth naming rather
    than glossing. It cannot be "resolves against a tree the pusher did not
    author" -- the pusher wrote every line of it. What remains mechanically
    checkable is that the cited line EXISTS in the commit being pushed: the line
    is in the diff by construction, so the citation names real, reviewable text
    and a fabricated line number is refused BY NAME, the same treatment the base
    rule has always given an out-of-range citation.

    Refusing the whole shape instead was measured: it left a release commit --
    Cargo.toml, Cargo.lock, CHANGELOG.md and one new test -- with nothing it
    could cite. A path that is neither at base nor in the diff is neither this
    branch's work nor the tree it started from, and anchors nothing.
    """
    if p not in touched:
        return False
    added = blob_at(head, p)
    if added is None:
        return False
    if int(n) > added.count(b"\n") + 1:
        die(f"'{dp}': cites '{p}:{n}' but that file, which this branch "
            f"ADDS, has {added.count(chr(10).encode())+1} lines at HEAD")
    return True


def check_anchors(adjudicated, dp, base, head, touched, cit_re):
    """A citation must resolve IN THE TREE and name a file this diff touches.

    This is the check with teeth, because it is anchored to the merge-base tree --
    something the pusher did not author. It is the free-rider defence the gate
    already applies to falsification.test_file, extended from the test to the
    reasoning. File-level, not hunk-level: hunk-level was measured at 25% on real
    data and would have failed honest work.

    Two resolutions anchor and they carry different guarantees: `anchors_at_base`
    is the strong one, `anchors_as_added` the weaker one a release commit needs
    in order to be able to cite itself. Both are consulted for EVERY citation,
    never short-circuited, so an out-of-range line number is still refused once a
    claim is already anchored by an earlier citation.
    """
    anchored = 0
    for it in adjudicated:
        hit = False
        for p, n in cit_re.findall(it):
            src = blob_at(base, p)
            if src is None:
                hit = anchors_as_added(head, dp, p, n, touched) or hit
            else:
                hit = anchors_at_base(src, dp, p, n, touched) or hit
        anchored += 1 if hit else 0
    if adjudicated:
        rate = anchored / len(adjudicated)
        if rate < ANCHOR_MIN:
            die(f"only {anchored}/{len(adjudicated)} ({rate:.0%}) adjudicated claims cite a\n"
                f"  file:line inside this branch's own diff; floor is {ANCHOR_MIN:.0%}.\n"
                "  Prose about code the branch never touched is not evidence FOR this change.")


def receipt_identity(r, base):
    """The receipt's kind, base and evidence list, each refused by name."""
    # forjar#491: the kind decides which citation shape anchors. A receipt that
    # declares no kind is a code receipt, and nothing about it changes.
    receipt_kind = r.get("kind", "code")
    if receipt_kind not in ("code", "triage"):
        die(f"receipt kind={receipt_kind!r} is not one of code | triage")
    got = r.get("base_commit")
    if not got:
        die(f"receipt is missing 'base_commit'. Without it every file:line citation\n"
            f"  rots the moment this branch's own fix moves a line. Set it to {base}.")
    if got != base:
        die(f"receipt base_commit={got[:12]}... but the merge-base is {base[:12]}...")
    ev = r.get("evidence")
    if not isinstance(ev, dict) or not ev.get("files"):
        die("receipt has no evidence.files[]. A verdict with no attached reasoning is\n"
            "  the bare integer the owner's rule rejects.")
    return receipt_kind, ev


def main():
    receipt, want_conf, want_ref, touched_raw, base, head = sys.argv[1:7]
    want_conf, want_ref = int(want_conf), int(want_ref)
    touched = set(filter(None, touched_raw.splitlines()))
    try:
        r = json.load(open(receipt))
    except Exception as e:
        die(f"{receipt} is not valid JSON: {e}")

    # ONLY base_commit is recorded. `head_commit` was in the design and is
    # SELF-REFERENTIAL: committing the receipt changes HEAD, which invalidates the
    # head_commit the receipt just recorded, forever. Blob ids are safe in the
    # manifest because git blobs are content-addressed and do not move when a new
    # commit is made -- HEAD is not. Nothing is lost: `diff_sha256` already binds
    # the content of HEAD, which is what head_commit was reaching for.
    receipt_kind, ev = receipt_identity(r, base)

    blobs = {}
    listed = check_manifest(ev, head, blobs)
    check_provenance(listed, blobs, touched)
    check_redaction(blobs)
    dp = ev.get("claims_digest")
    if dp not in blobs:
        die("evidence.claims_digest must name one of evidence.files[]")
    check_claims(blobs, dp, want_conf, want_ref, base, head, touched,
                 citation_shape(receipt_kind))
    kind_note = " (kind: triage -- documentation the branch touches anchors)" \
        if receipt_kind == "triage" else ""
    print(f"  evidence: {len(blobs)} files, {ev['total_bytes']}B, "
          f"{want_conf} confirmed + {want_ref} refuted, redaction clean{kind_note}")


if __name__ == "__main__":
    main()