File size: 2,408 Bytes
54a35ed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
#!/usr/bin/env python3
"""Offline JSON interface. No network, API keys, model download, or pip needed."""
import argparse
import sys
from pathlib import Path
from demo import evaluate_json
from matrix_core import DeterministicMatrixCore, parse_instant, verify_result
from safe_json import MAX_JSON_BYTES, strict_dumps, strict_loads


def _read(path, limit=MAX_JSON_BYTES):
    stream = sys.stdin.buffer if path == "-" else Path(path).open("rb")
    try:
        data = stream.read(limit + 1)
    finally:
        if path != "-":
            stream.close()
    if len(data) > limit:
        raise ValueError("Input exceeds the documented size limit")
    return data.decode("utf-8", errors="strict")


def main(argv=None):
    for stream in (sys.stdout, sys.stderr):
        try:
            stream.reconfigure(encoding="utf-8")
        except (AttributeError, ValueError):
            pass
    parser = argparse.ArgumentParser(description=__doc__)
    commands = parser.add_subparsers(dest="command", required=True)
    matrix = commands.add_parser("matrix", help="Checksum a UTF-8 text file, or - for stdin")
    matrix.add_argument("input")
    matrix.add_argument("--at", required=True, help="Explicit timestamp for reproducible execution")
    verify = commands.add_parser("verify-matrix", help="Verify a saved Matrix JSON result")
    verify.add_argument("input")
    claims = commands.add_parser("claims", help="Evaluate supplied evidence JSON at its evaluation_time")
    claims.add_argument("input")
    claims.add_argument("--batch", action="store_true")
    args = parser.parse_args(argv)
    try:
        text = _read(args.input)
        if args.command == "matrix":
            result = DeterministicMatrixCore().enforce_zero_tolerance_matrix(text, parse_instant(args.at))
            status = 0 if result["valid"] else 2
        elif args.command == "verify-matrix":
            result = verify_result(strict_loads(text))
            status = 0 if result["verified"] else 2
        else:
            result = evaluate_json(text, batch=args.batch)
            status = 0 if result.get("verdict") == "APPROVE" else 3
    except (ValueError, TypeError, UnicodeError, OSError, OverflowError) as exc:
        result = {"valid": False, "error": "INVALID_INPUT", "detail": str(exc)}
        status = 2
    print(strict_dumps(result))
    return status


if __name__ == "__main__":
    sys.exit(main())