gargoyle-receipts 0.6.0.dev0__tar.gz → 0.6.1.dev0__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.
- {gargoyle_receipts-0.6.0.dev0/gargoyle_receipts.egg-info → gargoyle_receipts-0.6.1.dev0}/PKG-INFO +2 -2
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/README.md +1 -1
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/cli.py +2 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/evidence.py +7 -4
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0/gargoyle_receipts.egg-info}/PKG-INFO +2 -2
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/pyproject.toml +1 -1
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_cli.py +1 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/LICENSE +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/NOTICE +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/__init__.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/approval.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/approver_cli.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/approver_trust.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/approvers.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/consumer.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/entra_login.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/envelope.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/execution.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/fs_server.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/identity.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/issuer.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/issuer_service.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/jws.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/key_record_source.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/mcp_server.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/notify.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/opa.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/pending_store.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/policy.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/published_record_source.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/replay_cache.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/rules.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/static/approve.html +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/static/approve.js +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/verifier.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle_receipts.egg-info/SOURCES.txt +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle_receipts.egg-info/dependency_links.txt +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle_receipts.egg-info/entry_points.txt +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle_receipts.egg-info/requires.txt +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle_receipts.egg-info/top_level.txt +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/setup.cfg +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_annotations.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_approver_cli.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_approvers.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_canonical.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_console_js.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_consumer.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_entra_identity.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_entra_login.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_evidence.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_execution.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_fs_server.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_historical.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_identity.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_issuer_service.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_jws.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_mcp_proxy.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_mcp_self_issue.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_mcp_server.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_notify.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_opa.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_policy.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_published_record.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_rules.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_stdio_encoding.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_threshold.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_typescript_conformance.py +0 -0
- {gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_wire_spec.py +0 -0
{gargoyle_receipts-0.6.0.dev0/gargoyle_receipts.egg-info → gargoyle_receipts-0.6.1.dev0}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gargoyle-receipts
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.1.dev0
|
|
4
4
|
Summary: Signed, single-use, argument-bound receipts and human-approval holds for agent tool calls.
|
|
5
5
|
Author: Justin LaPorte
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -59,7 +59,7 @@ your MCP server and lets through only what both agreed to.
|
|
|
59
59
|
|
|
60
60
|
[](https://pypi.org/project/gargoyle-receipts/)
|
|
61
61
|
|
|
62
|
-
Status: pre-release (`0.6.
|
|
62
|
+
Status: pre-release (`0.6.1.dev0`, on PyPI as `gargoyle-receipts`). The wire format is `gargoyle/3` and may
|
|
63
63
|
still change before the first release; it is specified in [SPEC.md](SPEC.md).
|
|
64
64
|
|
|
65
65
|
## What a receipt gives you
|
|
@@ -21,7 +21,7 @@ your MCP server and lets through only what both agreed to.
|
|
|
21
21
|
|
|
22
22
|
[](https://pypi.org/project/gargoyle-receipts/)
|
|
23
23
|
|
|
24
|
-
Status: pre-release (`0.6.
|
|
24
|
+
Status: pre-release (`0.6.1.dev0`, on PyPI as `gargoyle-receipts`). The wire format is `gargoyle/3` and may
|
|
25
25
|
still change before the first release; it is specified in [SPEC.md](SPEC.md).
|
|
26
26
|
|
|
27
27
|
## What a receipt gives you
|
|
@@ -244,6 +244,8 @@ def cmd_audit(args) -> int:
|
|
|
244
244
|
for r in v["entries"]:
|
|
245
245
|
# A refused row shows why the executor refused, beside the check outcome.
|
|
246
246
|
why = (" (%s)" % r["verdict"]) if r["kind"] == "refused" and r["verdict"] else ""
|
|
247
|
+
if r.get("released_by"):
|
|
248
|
+
why += " released by " + ", ".join(r["released_by"])
|
|
247
249
|
print("%4s %-5s %-8s %-24s %-28s %s%s" % (r["seq"] if r["seq"] is not None else "?",
|
|
248
250
|
"ok" if r["accepted"] else "FAIL", r["kind"] or "?",
|
|
249
251
|
(r["tool"] or "?")[:24], (r["principal"] or "?")[:28], r["reason"], why))
|
|
@@ -158,8 +158,9 @@ def verify_log(
|
|
|
158
158
|
and describe the call the entry names; a refused entry that carries a
|
|
159
159
|
receipt has it checked for issuer provenance. Returns
|
|
160
160
|
{"accepted", "reason", "tail_sha256", "count", "honored", "refused",
|
|
161
|
-
"entries": [{"seq", "kind", "tool", "principal", "accepted", "reason", "verdict"}, ...]},
|
|
162
|
-
`reason` the verification outcome
|
|
161
|
+
"entries": [{"seq", "kind", "tool", "principal", "accepted", "reason", "verdict", "released_by"}, ...]},
|
|
162
|
+
`reason` the verification outcome, `verdict` what the executor recorded,
|
|
163
|
+
`released_by` the approver key ids of the grants an honored held call carried.
|
|
163
164
|
Verification continues past a bad entry so the report names every one."""
|
|
164
165
|
trust = dict(issuer_public_keys=issuer_public_keys, executor_public_keys=executor_public_keys,
|
|
165
166
|
approver_public_keys=approver_public_keys)
|
|
@@ -177,7 +178,7 @@ def verify_log(
|
|
|
177
178
|
rc = rc if isinstance(rc, dict) else {}
|
|
178
179
|
report.append({"seq": None, "kind": None, "tool": rc.get("tool"), "principal": rc.get("principal"),
|
|
179
180
|
"accepted": False, "reason": REF_EVIDENCE_UNCHAINED if legacy else REF_EVIDENCE_MALFORMED,
|
|
180
|
-
"verdict": None})
|
|
181
|
+
"verdict": None, "released_by": []})
|
|
181
182
|
all_ok = False
|
|
182
183
|
continue
|
|
183
184
|
e = raw
|
|
@@ -203,8 +204,10 @@ def verify_log(
|
|
|
203
204
|
now=_parse_at(e["at"]), historical=True)
|
|
204
205
|
ok, reason = p["accepted"], (ACCEPT_ENTRY_VERIFIED if p["accepted"] else p["reason"])
|
|
205
206
|
counts[e["kind"]] += 1
|
|
207
|
+
released_by = [g.get("approver_key_id") for g in (e["grant"] if isinstance(e["grant"], list) else [e["grant"]])
|
|
208
|
+
if isinstance(g, dict)] if e["grant"] is not None else []
|
|
206
209
|
report.append({"seq": e["seq"], "kind": e["kind"], "tool": e["tool"], "principal": e["principal"],
|
|
207
|
-
"accepted": ok, "reason": reason, "verdict": e["reason"]})
|
|
210
|
+
"accepted": ok, "reason": reason, "verdict": e["reason"], "released_by": released_by})
|
|
208
211
|
all_ok = all_ok and ok
|
|
209
212
|
# The chain continues from what the file says, so one bad entry is
|
|
210
213
|
# reported once rather than cascading into every later one.
|
{gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0/gargoyle_receipts.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gargoyle-receipts
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.1.dev0
|
|
4
4
|
Summary: Signed, single-use, argument-bound receipts and human-approval holds for agent tool calls.
|
|
5
5
|
Author: Justin LaPorte
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -59,7 +59,7 @@ your MCP server and lets through only what both agreed to.
|
|
|
59
59
|
|
|
60
60
|
[](https://pypi.org/project/gargoyle-receipts/)
|
|
61
61
|
|
|
62
|
-
Status: pre-release (`0.6.
|
|
62
|
+
Status: pre-release (`0.6.1.dev0`, on PyPI as `gargoyle-receipts`). The wire format is `gargoyle/3` and may
|
|
63
63
|
still change before the first release; it is specified in [SPEC.md](SPEC.md).
|
|
64
64
|
|
|
65
65
|
## What a receipt gives you
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "gargoyle-receipts"
|
|
7
|
-
version = "0.6.
|
|
7
|
+
version = "0.6.1.dev0"
|
|
8
8
|
description = "Signed, single-use, argument-bound receipts and human-approval holds for agent tool calls."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.12"
|
|
@@ -112,6 +112,7 @@ def test_init_for_a_windows_client_and_audit_log_verification(tmp_path, monkeypa
|
|
|
112
112
|
assert "4 entries (3 honored, 1 refused), 0 failed; chain EVIDENCE_VERIFIED" in out_text
|
|
113
113
|
assert out_text.count(" ok ") == 4 and "refused delete_file" in out_text
|
|
114
114
|
assert "ENTRY_VERIFIED (DESTRUCTIVE_TOOL)" in out_text
|
|
115
|
+
assert "released by approver-1" in out_text # the held write names who released it
|
|
115
116
|
# A tampered entry is caught, and the hash-chain names it: editing the
|
|
116
117
|
# execution receipt inside entry 2 changes its hash.
|
|
117
118
|
lines = log.read_text().splitlines(); e = json.loads(lines[1]); e["execution"]["outputs_sha256"] = "0" * 64
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle/published_record_source.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/gargoyle_receipts.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_published_record.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gargoyle_receipts-0.6.0.dev0 → gargoyle_receipts-0.6.1.dev0}/tests/test_typescript_conformance.py
RENAMED
|
File without changes
|
|
File without changes
|