proofgate-runtime 0.1.0__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {proofgate_runtime-0.1.0 → proofgate_runtime-0.2.0}/PKG-INFO +9 -5
- {proofgate_runtime-0.1.0 → proofgate_runtime-0.2.0}/README.md +8 -4
- {proofgate_runtime-0.1.0 → proofgate_runtime-0.2.0}/pyproject.toml +1 -1
- {proofgate_runtime-0.1.0 → proofgate_runtime-0.2.0}/src/proofgate_runtime/__init__.py +1 -1
- {proofgate_runtime-0.1.0 → proofgate_runtime-0.2.0}/src/proofgate_runtime/cli.py +12 -6
- {proofgate_runtime-0.1.0 → proofgate_runtime-0.2.0}/src/proofgate_runtime/mcp_server.py +10 -3
- {proofgate_runtime-0.1.0 → proofgate_runtime-0.2.0}/src/proofgate_runtime/receipts.py +4 -3
- {proofgate_runtime-0.1.0 → proofgate_runtime-0.2.0}/src/proofgate_runtime.egg-info/PKG-INFO +9 -5
- {proofgate_runtime-0.1.0 → proofgate_runtime-0.2.0}/tests/test_receipts.py +4 -3
- {proofgate_runtime-0.1.0 → proofgate_runtime-0.2.0}/LICENSE +0 -0
- {proofgate_runtime-0.1.0 → proofgate_runtime-0.2.0}/setup.cfg +0 -0
- {proofgate_runtime-0.1.0 → proofgate_runtime-0.2.0}/src/proofgate_runtime/claims.py +0 -0
- {proofgate_runtime-0.1.0 → proofgate_runtime-0.2.0}/src/proofgate_runtime/guard.py +0 -0
- {proofgate_runtime-0.1.0 → proofgate_runtime-0.2.0}/src/proofgate_runtime.egg-info/SOURCES.txt +0 -0
- {proofgate_runtime-0.1.0 → proofgate_runtime-0.2.0}/src/proofgate_runtime.egg-info/dependency_links.txt +0 -0
- {proofgate_runtime-0.1.0 → proofgate_runtime-0.2.0}/src/proofgate_runtime.egg-info/entry_points.txt +0 -0
- {proofgate_runtime-0.1.0 → proofgate_runtime-0.2.0}/src/proofgate_runtime.egg-info/top_level.txt +0 -0
- {proofgate_runtime-0.1.0 → proofgate_runtime-0.2.0}/tests/test_claims.py +0 -0
- {proofgate_runtime-0.1.0 → proofgate_runtime-0.2.0}/tests/test_guard.py +0 -0
- {proofgate_runtime-0.1.0 → proofgate_runtime-0.2.0}/tests/test_mcp.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: proofgate-runtime
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Evidence-first claim verification, signed receipts, lite injection guard and MCP server (stdlib only).
|
|
5
5
|
Author-email: gamAI <info@gamai.io>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -19,7 +19,7 @@ Dynamic: license-file
|
|
|
19
19
|
# ProofGate Runtime
|
|
20
20
|
|
|
21
21
|
**Evidence-first claim verification, signed receipts, and a lite injection guard for AI agents.**
|
|
22
|
-
[](https://pypi.org/project/proofgate-runtime/) v0.
|
|
22
|
+
[](https://pypi.org/project/proofgate-runtime/) v0.2.0 · Python 3.10+ · stdlib only · Apache-2.0
|
|
23
23
|
|
|
24
24
|
Agent says "done". ProofGate asks: **where is the evidence?**
|
|
25
25
|
|
|
@@ -72,7 +72,7 @@ echo '{"posted":true,"total":"2808.00"}' > result.json
|
|
|
72
72
|
printf 'shared-secret' > key.bin
|
|
73
73
|
|
|
74
74
|
proofgate make-receipt intent.json result.json --key-file key.bin > receipt.json
|
|
75
|
-
proofgate verify-receipt receipt.json --key-file key.bin
|
|
75
|
+
proofgate verify-receipt receipt.json --key-file key.bin
|
|
76
76
|
```
|
|
77
77
|
|
|
78
78
|
Tamper with `result.json` or the receipt and verification fails closed.
|
|
@@ -107,8 +107,8 @@ Tools: `verify_claims`, `make_receipt`, `verify_receipt`, `check_injection`, `ru
|
|
|
107
107
|
- **No anchor/lease service.** That is [`sigil`](https://github.com/gamai-io/sigil) (grants, receipts, anchor, MCP middleware). ProofGate v0.1 is the local verification core.
|
|
108
108
|
- **No embedding-based guard.** This is the lexical layer; the full multilingual cascade is [`gamai-guard`](https://github.com/gamai-io/gamai-guard).
|
|
109
109
|
- **No independent security audit.** Treat v0.1 as a reference implementation, not a certified product.
|
|
110
|
-
- **MCP receipts are
|
|
111
|
-
- **PyPI 0.
|
|
110
|
+
- **MCP receipts are signed only when `PROOFGATE_HMAC_KEY` is set** and are rejected as unsigned otherwise. Set it in the server environment; never put the key in a client or in git.
|
|
111
|
+
- **PyPI 0.2.0 is available.** Install with `pip install proofgate-runtime`.
|
|
112
112
|
|
|
113
113
|
## Design rules
|
|
114
114
|
|
|
@@ -126,6 +126,10 @@ Tools: `verify_claims`, `make_receipt`, `verify_receipt`, `check_injection`, `ru
|
|
|
126
126
|
- [`evidence-gate-runtime`](https://github.com/gamai-io/evidence-gate-runtime) — fuller runtime with replay.
|
|
127
127
|
- [`floor-copilot`](https://github.com/gamai-io/floor-copilot) — production case study: invoice intake with 17% VAT gate.
|
|
128
128
|
|
|
129
|
+
## v0.2 breaking change
|
|
130
|
+
|
|
131
|
+
`verify_receipt()` now requires a valid signature by default. For legacy unsigned receipts, call `verify_receipt(..., require_signature=False)` or the CLI with `--allow-unsigned`. Create signed receipts with `proofgate make-receipt ... --key-file`; the MCP server signs when `PROOFGATE_HMAC_KEY` is set.
|
|
132
|
+
|
|
129
133
|
## Honest status
|
|
130
134
|
|
|
131
135
|
- Claim verification: tested (BHS/EU/US money formats, predicates, tamper detection).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# ProofGate Runtime
|
|
2
2
|
|
|
3
3
|
**Evidence-first claim verification, signed receipts, and a lite injection guard for AI agents.**
|
|
4
|
-
[](https://pypi.org/project/proofgate-runtime/) v0.
|
|
4
|
+
[](https://pypi.org/project/proofgate-runtime/) v0.2.0 · Python 3.10+ · stdlib only · Apache-2.0
|
|
5
5
|
|
|
6
6
|
Agent says "done". ProofGate asks: **where is the evidence?**
|
|
7
7
|
|
|
@@ -54,7 +54,7 @@ echo '{"posted":true,"total":"2808.00"}' > result.json
|
|
|
54
54
|
printf 'shared-secret' > key.bin
|
|
55
55
|
|
|
56
56
|
proofgate make-receipt intent.json result.json --key-file key.bin > receipt.json
|
|
57
|
-
proofgate verify-receipt receipt.json --key-file key.bin
|
|
57
|
+
proofgate verify-receipt receipt.json --key-file key.bin
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
Tamper with `result.json` or the receipt and verification fails closed.
|
|
@@ -89,8 +89,8 @@ Tools: `verify_claims`, `make_receipt`, `verify_receipt`, `check_injection`, `ru
|
|
|
89
89
|
- **No anchor/lease service.** That is [`sigil`](https://github.com/gamai-io/sigil) (grants, receipts, anchor, MCP middleware). ProofGate v0.1 is the local verification core.
|
|
90
90
|
- **No embedding-based guard.** This is the lexical layer; the full multilingual cascade is [`gamai-guard`](https://github.com/gamai-io/gamai-guard).
|
|
91
91
|
- **No independent security audit.** Treat v0.1 as a reference implementation, not a certified product.
|
|
92
|
-
- **MCP receipts are
|
|
93
|
-
- **PyPI 0.
|
|
92
|
+
- **MCP receipts are signed only when `PROOFGATE_HMAC_KEY` is set** and are rejected as unsigned otherwise. Set it in the server environment; never put the key in a client or in git.
|
|
93
|
+
- **PyPI 0.2.0 is available.** Install with `pip install proofgate-runtime`.
|
|
94
94
|
|
|
95
95
|
## Design rules
|
|
96
96
|
|
|
@@ -108,6 +108,10 @@ Tools: `verify_claims`, `make_receipt`, `verify_receipt`, `check_injection`, `ru
|
|
|
108
108
|
- [`evidence-gate-runtime`](https://github.com/gamai-io/evidence-gate-runtime) — fuller runtime with replay.
|
|
109
109
|
- [`floor-copilot`](https://github.com/gamai-io/floor-copilot) — production case study: invoice intake with 17% VAT gate.
|
|
110
110
|
|
|
111
|
+
## v0.2 breaking change
|
|
112
|
+
|
|
113
|
+
`verify_receipt()` now requires a valid signature by default. For legacy unsigned receipts, call `verify_receipt(..., require_signature=False)` or the CLI with `--allow-unsigned`. Create signed receipts with `proofgate make-receipt ... --key-file`; the MCP server signs when `PROOFGATE_HMAC_KEY` is set.
|
|
114
|
+
|
|
111
115
|
## Honest status
|
|
112
116
|
|
|
113
117
|
- Claim verification: tested (BHS/EU/US money formats, predicates, tamper detection).
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "proofgate-runtime"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.2.0"
|
|
8
8
|
description = "Evidence-first claim verification, signed receipts, lite injection guard and MCP server (stdlib only)."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -3,7 +3,7 @@ from .claims import evaluate, check, verify, demo, EvidenceError
|
|
|
3
3
|
from .guard import check_injection
|
|
4
4
|
from .receipts import make_receipt, verify_receipt, verify_chain, canonical_json, sha256_hex
|
|
5
5
|
|
|
6
|
-
__version__ = "0.
|
|
6
|
+
__version__ = "0.2.0"
|
|
7
7
|
|
|
8
8
|
__all__ = [
|
|
9
9
|
"evaluate", "check", "verify", "demo", "EvidenceError",
|
|
@@ -43,12 +43,13 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
43
43
|
m = sub.add_parser("make-receipt", help="create a receipt from intent/result JSON files")
|
|
44
44
|
m.add_argument("intent")
|
|
45
45
|
m.add_argument("result")
|
|
46
|
-
m.add_argument("--key-file", default=None, help="
|
|
46
|
+
m.add_argument("--key-file", default=None, help="HMAC key file (required unless --allow-unsigned)")
|
|
47
|
+
m.add_argument("--allow-unsigned", action="store_true", help="create an unsigned receipt (not recommended)")
|
|
47
48
|
|
|
48
49
|
v = sub.add_parser("verify-receipt", help="verify a receipt JSON file")
|
|
49
50
|
v.add_argument("receipt")
|
|
50
51
|
v.add_argument("--key-file", default=None)
|
|
51
|
-
v.add_argument("--
|
|
52
|
+
v.add_argument("--allow-unsigned", action="store_true", help="accept an unsigned receipt")
|
|
52
53
|
|
|
53
54
|
g = sub.add_parser("check-injection", help="lexical prompt-injection pre-filter")
|
|
54
55
|
g.add_argument("text")
|
|
@@ -63,12 +64,17 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
63
64
|
_print(check(claims or [], args.reported_hash))
|
|
64
65
|
return 0
|
|
65
66
|
if args.cmd == "make-receipt":
|
|
66
|
-
|
|
67
|
+
key = _key(args.key_file)
|
|
68
|
+
if key is None and not args.allow_unsigned:
|
|
69
|
+
print("refusing unsigned receipt: pass --key-file or --allow-unsigned", file=sys.stderr)
|
|
70
|
+
return 2
|
|
71
|
+
_print(make_receipt(_load(args.intent), _load(args.result), key=key))
|
|
67
72
|
return 0
|
|
68
73
|
if args.cmd == "verify-receipt":
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
74
|
+
res = verify_receipt(_load(args.receipt), key=_key(args.key_file),
|
|
75
|
+
require_signature=not args.allow_unsigned)
|
|
76
|
+
_print(res)
|
|
77
|
+
return 0 if res["valid"] else 1
|
|
72
78
|
if args.cmd == "check-injection":
|
|
73
79
|
_print(check_injection(args.text, args.tool))
|
|
74
80
|
return 0
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import json
|
|
6
|
+
import os
|
|
6
7
|
import sys
|
|
7
8
|
from typing import Any
|
|
8
9
|
|
|
@@ -74,18 +75,24 @@ def call_tool(name: str, args: dict) -> dict:
|
|
|
74
75
|
if name == "make_receipt":
|
|
75
76
|
if "intent" not in args or "result" not in args:
|
|
76
77
|
return _text({"error": "intent and result are required"}, True)
|
|
77
|
-
|
|
78
|
+
key = os.environ.get("PROOFGATE_HMAC_KEY") or None
|
|
79
|
+
rec = make_receipt(args["intent"], args["result"], key=key, meta=args.get("meta"))
|
|
80
|
+
if not key:
|
|
81
|
+
rec["_warning"] = "unsigned: set PROOFGATE_HMAC_KEY to sign MCP receipts"
|
|
82
|
+
return _text(rec)
|
|
78
83
|
if name == "verify_receipt":
|
|
79
84
|
if not isinstance(args.get("receipt"), dict):
|
|
80
85
|
return _text({"error": "receipt object is required"}, True)
|
|
81
|
-
return _text(verify_receipt(args["receipt"],
|
|
86
|
+
return _text(verify_receipt(args["receipt"],
|
|
87
|
+
require_signature=bool(args.get("require_signature", True))))
|
|
82
88
|
if name == "check_injection":
|
|
83
89
|
return _text(check_injection(args.get("text", ""), args.get("tool")))
|
|
84
90
|
if name == "runtime_info":
|
|
85
91
|
return _text({"name": "proofgate-runtime", "version": __version__,
|
|
86
92
|
"capabilities": ["verify_claims", "make_receipt", "verify_receipt",
|
|
87
93
|
"check_injection_lite"],
|
|
88
|
-
"signed_receipts": "HMAC-SHA256
|
|
94
|
+
"signed_receipts": "HMAC-SHA256; MCP uses PROOFGATE_HMAC_KEY; unsigned rejected by default",
|
|
95
|
+
"require_signature_default": True})
|
|
89
96
|
return _text({"error": "unknown tool: %s" % name}, True)
|
|
90
97
|
|
|
91
98
|
|
|
@@ -61,7 +61,7 @@ def make_receipt(intent: Any, result: Any, key: str | bytes | None = None,
|
|
|
61
61
|
|
|
62
62
|
|
|
63
63
|
def verify_receipt(receipt: dict, key: str | bytes | None = None,
|
|
64
|
-
require_signature: bool =
|
|
64
|
+
require_signature: bool = True) -> dict:
|
|
65
65
|
"""Verify hashes and, when present, the signature. Fail closed."""
|
|
66
66
|
errors: list[str] = []
|
|
67
67
|
if not isinstance(receipt, dict):
|
|
@@ -100,14 +100,15 @@ def verify_receipt(receipt: dict, key: str | bytes | None = None,
|
|
|
100
100
|
"receipt_hash": receipt.get("receipt_hash")}
|
|
101
101
|
|
|
102
102
|
|
|
103
|
-
def verify_chain(receipts: list[dict], key: str | bytes | None = None
|
|
103
|
+
def verify_chain(receipts: list[dict], key: str | bytes | None = None,
|
|
104
|
+
require_signature: bool = True) -> dict:
|
|
104
105
|
"""Verify a simple prev_hash chain (first prev_hash = GENESIS)."""
|
|
105
106
|
errors: list[str] = []
|
|
106
107
|
prev = "GENESIS"
|
|
107
108
|
for i, rec in enumerate(receipts or []):
|
|
108
109
|
if rec.get("prev_hash") != prev:
|
|
109
110
|
errors.append("E_CHAIN_AT_%d" % i)
|
|
110
|
-
res = verify_receipt(rec, key=key)
|
|
111
|
+
res = verify_receipt(rec, key=key, require_signature=require_signature)
|
|
111
112
|
if not res["valid"]:
|
|
112
113
|
errors.extend("%s@%d" % (e, i) for e in res["errors"])
|
|
113
114
|
prev = rec.get("receipt_hash", "")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: proofgate-runtime
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Evidence-first claim verification, signed receipts, lite injection guard and MCP server (stdlib only).
|
|
5
5
|
Author-email: gamAI <info@gamai.io>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -19,7 +19,7 @@ Dynamic: license-file
|
|
|
19
19
|
# ProofGate Runtime
|
|
20
20
|
|
|
21
21
|
**Evidence-first claim verification, signed receipts, and a lite injection guard for AI agents.**
|
|
22
|
-
[](https://pypi.org/project/proofgate-runtime/) v0.
|
|
22
|
+
[](https://pypi.org/project/proofgate-runtime/) v0.2.0 · Python 3.10+ · stdlib only · Apache-2.0
|
|
23
23
|
|
|
24
24
|
Agent says "done". ProofGate asks: **where is the evidence?**
|
|
25
25
|
|
|
@@ -72,7 +72,7 @@ echo '{"posted":true,"total":"2808.00"}' > result.json
|
|
|
72
72
|
printf 'shared-secret' > key.bin
|
|
73
73
|
|
|
74
74
|
proofgate make-receipt intent.json result.json --key-file key.bin > receipt.json
|
|
75
|
-
proofgate verify-receipt receipt.json --key-file key.bin
|
|
75
|
+
proofgate verify-receipt receipt.json --key-file key.bin
|
|
76
76
|
```
|
|
77
77
|
|
|
78
78
|
Tamper with `result.json` or the receipt and verification fails closed.
|
|
@@ -107,8 +107,8 @@ Tools: `verify_claims`, `make_receipt`, `verify_receipt`, `check_injection`, `ru
|
|
|
107
107
|
- **No anchor/lease service.** That is [`sigil`](https://github.com/gamai-io/sigil) (grants, receipts, anchor, MCP middleware). ProofGate v0.1 is the local verification core.
|
|
108
108
|
- **No embedding-based guard.** This is the lexical layer; the full multilingual cascade is [`gamai-guard`](https://github.com/gamai-io/gamai-guard).
|
|
109
109
|
- **No independent security audit.** Treat v0.1 as a reference implementation, not a certified product.
|
|
110
|
-
- **MCP receipts are
|
|
111
|
-
- **PyPI 0.
|
|
110
|
+
- **MCP receipts are signed only when `PROOFGATE_HMAC_KEY` is set** and are rejected as unsigned otherwise. Set it in the server environment; never put the key in a client or in git.
|
|
111
|
+
- **PyPI 0.2.0 is available.** Install with `pip install proofgate-runtime`.
|
|
112
112
|
|
|
113
113
|
## Design rules
|
|
114
114
|
|
|
@@ -126,6 +126,10 @@ Tools: `verify_claims`, `make_receipt`, `verify_receipt`, `check_injection`, `ru
|
|
|
126
126
|
- [`evidence-gate-runtime`](https://github.com/gamai-io/evidence-gate-runtime) — fuller runtime with replay.
|
|
127
127
|
- [`floor-copilot`](https://github.com/gamai-io/floor-copilot) — production case study: invoice intake with 17% VAT gate.
|
|
128
128
|
|
|
129
|
+
## v0.2 breaking change
|
|
130
|
+
|
|
131
|
+
`verify_receipt()` now requires a valid signature by default. For legacy unsigned receipts, call `verify_receipt(..., require_signature=False)` or the CLI with `--allow-unsigned`. Create signed receipts with `proofgate make-receipt ... --key-file`; the MCP server signs when `PROOFGATE_HMAC_KEY` is set.
|
|
132
|
+
|
|
129
133
|
## Honest status
|
|
130
134
|
|
|
131
135
|
- Claim verification: tested (BHS/EU/US money formats, predicates, tamper detection).
|
|
@@ -6,9 +6,10 @@ from proofgate_runtime.receipts import make_receipt, verify_receipt, canonical_j
|
|
|
6
6
|
class ReceiptTests(unittest.TestCase):
|
|
7
7
|
def test_unsigned_receipt(self):
|
|
8
8
|
r = make_receipt({"op": "x"}, {"ok": True})
|
|
9
|
-
out = verify_receipt(r)
|
|
9
|
+
out = verify_receipt(r, require_signature=False)
|
|
10
10
|
self.assertTrue(out["valid"], out)
|
|
11
11
|
self.assertFalse(out["signed"])
|
|
12
|
+
self.assertFalse(verify_receipt(r)["valid"])
|
|
12
13
|
|
|
13
14
|
def test_signed_receipt(self):
|
|
14
15
|
r = make_receipt({"op": "x"}, {"ok": True}, key="secret")
|
|
@@ -29,9 +30,9 @@ class ReceiptTests(unittest.TestCase):
|
|
|
29
30
|
self.assertFalse(out["valid"])
|
|
30
31
|
self.assertIn("E_RESULT_DIGEST", out["errors"])
|
|
31
32
|
|
|
32
|
-
def
|
|
33
|
+
def test_require_signature_default(self):
|
|
33
34
|
r = make_receipt({"op": "x"}, {"ok": True})
|
|
34
|
-
out = verify_receipt(r
|
|
35
|
+
out = verify_receipt(r)
|
|
35
36
|
self.assertFalse(out["valid"])
|
|
36
37
|
self.assertIn("E_UNSIGNED", out["errors"])
|
|
37
38
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{proofgate_runtime-0.1.0 → proofgate_runtime-0.2.0}/src/proofgate_runtime.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{proofgate_runtime-0.1.0 → proofgate_runtime-0.2.0}/src/proofgate_runtime.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{proofgate_runtime-0.1.0 → proofgate_runtime-0.2.0}/src/proofgate_runtime.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|