aer1-scan 1.0.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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Brennan Zambo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,59 @@
1
+ Metadata-Version: 2.4
2
+ Name: aer1-scan
3
+ Version: 1.0.0
4
+ Summary: Check every Zambo receipt link in a file, a web page, or stdin, right from your terminal. A Zambo receipt proves the saved result of an AI job was not changed after the fact.
5
+ Author: Brennan Zambo
6
+ License: MIT
7
+ Project-URL: Homepage, https://zambo.dev/verify/
8
+ Project-URL: Repository, https://github.com/zambodotdev/aer1-scan
9
+ Keywords: aer-1,zambo,receipts,verification,ai-agents,mcp
10
+ Requires-Python: >=3.9
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Dynamic: license-file
14
+
15
+ # aer1-scan
16
+
17
+ Check every Zambo receipt in the work you were handed, from your terminal.
18
+
19
+ Someone gives you AI work full of receipt links: a pull request, a report, a chat log. Instead of clicking each one, run one command. aer1-scan finds every Zambo receipt in a file, a web page, or piped text, checks each one live, and prints one line per receipt. It sends only the receipt ids, nothing else from the document.
20
+
21
+ A Zambo receipt proves the saved result of an AI job was not changed after the fact. It does not prove the answer was right. It proves the record you are checking is the record that was saved at the time.
22
+
23
+ ## Install
24
+
25
+ Node:
26
+ ```
27
+ npx aer1-scan FILE
28
+ ```
29
+ or `npm install -g aer1-scan`
30
+
31
+ Python:
32
+ ```
33
+ pipx run aer1-scan FILE
34
+ ```
35
+ or `pip install aer1-scan`
36
+
37
+ Same tool, same output, both published from this repo.
38
+
39
+ ## Use
40
+
41
+ ```
42
+ aer1-scan report.md
43
+ aer1-scan https://gist.github.com/zambodotdev/777872582b8dd2feefa43bf1d4fa1acf
44
+ cat chat-log.txt | aer1-scan
45
+ ```
46
+
47
+ Output, one line per receipt:
48
+ ```
49
+ verified 5420f6f0-a635-4010-a7d4-311f7cd6b0ab https://zambo.dev/verify/?id=5420f6f0-a635-4010-a7d4-311f7cd6b0ab
50
+ not found 00000000-0000-4000-8000-000000000000 https://zambo.dev/verify/?id=00000000-0000-4000-8000-000000000000
51
+ ```
52
+
53
+ Exit code is 0 when every receipt verifies, 1 when any does not, so it drops straight into CI and pre-commit hooks.
54
+
55
+ Prefer clicking? The same check runs in your browser at https://zambodotdev.github.io/receipt-scan/
56
+
57
+ Want receipts on your own AI work: add Zambo in one URL, no key, at https://zambo.dev/add/?ref=aer1-scan
58
+
59
+ Founder: Brennan Zambo (https://zambo.dev/founder/). Support: https://zambo.dev/add/?ref=aer1-scan
@@ -0,0 +1,45 @@
1
+ # aer1-scan
2
+
3
+ Check every Zambo receipt in the work you were handed, from your terminal.
4
+
5
+ Someone gives you AI work full of receipt links: a pull request, a report, a chat log. Instead of clicking each one, run one command. aer1-scan finds every Zambo receipt in a file, a web page, or piped text, checks each one live, and prints one line per receipt. It sends only the receipt ids, nothing else from the document.
6
+
7
+ A Zambo receipt proves the saved result of an AI job was not changed after the fact. It does not prove the answer was right. It proves the record you are checking is the record that was saved at the time.
8
+
9
+ ## Install
10
+
11
+ Node:
12
+ ```
13
+ npx aer1-scan FILE
14
+ ```
15
+ or `npm install -g aer1-scan`
16
+
17
+ Python:
18
+ ```
19
+ pipx run aer1-scan FILE
20
+ ```
21
+ or `pip install aer1-scan`
22
+
23
+ Same tool, same output, both published from this repo.
24
+
25
+ ## Use
26
+
27
+ ```
28
+ aer1-scan report.md
29
+ aer1-scan https://gist.github.com/zambodotdev/777872582b8dd2feefa43bf1d4fa1acf
30
+ cat chat-log.txt | aer1-scan
31
+ ```
32
+
33
+ Output, one line per receipt:
34
+ ```
35
+ verified 5420f6f0-a635-4010-a7d4-311f7cd6b0ab https://zambo.dev/verify/?id=5420f6f0-a635-4010-a7d4-311f7cd6b0ab
36
+ not found 00000000-0000-4000-8000-000000000000 https://zambo.dev/verify/?id=00000000-0000-4000-8000-000000000000
37
+ ```
38
+
39
+ Exit code is 0 when every receipt verifies, 1 when any does not, so it drops straight into CI and pre-commit hooks.
40
+
41
+ Prefer clicking? The same check runs in your browser at https://zambodotdev.github.io/receipt-scan/
42
+
43
+ Want receipts on your own AI work: add Zambo in one URL, no key, at https://zambo.dev/add/?ref=aer1-scan
44
+
45
+ Founder: Brennan Zambo (https://zambo.dev/founder/). Support: https://zambo.dev/add/?ref=aer1-scan
@@ -0,0 +1,59 @@
1
+ Metadata-Version: 2.4
2
+ Name: aer1-scan
3
+ Version: 1.0.0
4
+ Summary: Check every Zambo receipt link in a file, a web page, or stdin, right from your terminal. A Zambo receipt proves the saved result of an AI job was not changed after the fact.
5
+ Author: Brennan Zambo
6
+ License: MIT
7
+ Project-URL: Homepage, https://zambo.dev/verify/
8
+ Project-URL: Repository, https://github.com/zambodotdev/aer1-scan
9
+ Keywords: aer-1,zambo,receipts,verification,ai-agents,mcp
10
+ Requires-Python: >=3.9
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Dynamic: license-file
14
+
15
+ # aer1-scan
16
+
17
+ Check every Zambo receipt in the work you were handed, from your terminal.
18
+
19
+ Someone gives you AI work full of receipt links: a pull request, a report, a chat log. Instead of clicking each one, run one command. aer1-scan finds every Zambo receipt in a file, a web page, or piped text, checks each one live, and prints one line per receipt. It sends only the receipt ids, nothing else from the document.
20
+
21
+ A Zambo receipt proves the saved result of an AI job was not changed after the fact. It does not prove the answer was right. It proves the record you are checking is the record that was saved at the time.
22
+
23
+ ## Install
24
+
25
+ Node:
26
+ ```
27
+ npx aer1-scan FILE
28
+ ```
29
+ or `npm install -g aer1-scan`
30
+
31
+ Python:
32
+ ```
33
+ pipx run aer1-scan FILE
34
+ ```
35
+ or `pip install aer1-scan`
36
+
37
+ Same tool, same output, both published from this repo.
38
+
39
+ ## Use
40
+
41
+ ```
42
+ aer1-scan report.md
43
+ aer1-scan https://gist.github.com/zambodotdev/777872582b8dd2feefa43bf1d4fa1acf
44
+ cat chat-log.txt | aer1-scan
45
+ ```
46
+
47
+ Output, one line per receipt:
48
+ ```
49
+ verified 5420f6f0-a635-4010-a7d4-311f7cd6b0ab https://zambo.dev/verify/?id=5420f6f0-a635-4010-a7d4-311f7cd6b0ab
50
+ not found 00000000-0000-4000-8000-000000000000 https://zambo.dev/verify/?id=00000000-0000-4000-8000-000000000000
51
+ ```
52
+
53
+ Exit code is 0 when every receipt verifies, 1 when any does not, so it drops straight into CI and pre-commit hooks.
54
+
55
+ Prefer clicking? The same check runs in your browser at https://zambodotdev.github.io/receipt-scan/
56
+
57
+ Want receipts on your own AI work: add Zambo in one URL, no key, at https://zambo.dev/add/?ref=aer1-scan
58
+
59
+ Founder: Brennan Zambo (https://zambo.dev/founder/). Support: https://zambo.dev/add/?ref=aer1-scan
@@ -0,0 +1,9 @@
1
+ LICENSE
2
+ README.md
3
+ aer1_scan.py
4
+ pyproject.toml
5
+ aer1_scan.egg-info/PKG-INFO
6
+ aer1_scan.egg-info/SOURCES.txt
7
+ aer1_scan.egg-info/dependency_links.txt
8
+ aer1_scan.egg-info/entry_points.txt
9
+ aer1_scan.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ aer1-scan = aer1_scan:main
@@ -0,0 +1 @@
1
+ aer1_scan
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env python3
2
+ """aer1-scan: check every zambo receipt in a file, a web page, or stdin.
3
+
4
+ A zambo receipt proves the saved result of an AI job was not changed
5
+ after the fact. This tool sends only the receipt ids, nothing else.
6
+ Pure standard library, no dependencies.
7
+ """
8
+ import json
9
+ import re
10
+ import sys
11
+ import urllib.error
12
+ import urllib.request
13
+
14
+ UUID = r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
15
+ LINK_RE = re.compile(r"zambo\.dev/[^\s\"'<>\])]*?(" + UUID + r")", re.IGNORECASE)
16
+ BARE_RE = re.compile(r"^\s*(" + UUID + r")\s*$", re.MULTILINE)
17
+ MAX = 50
18
+ TIMEOUT = 20
19
+
20
+
21
+ def raw_url(u):
22
+ try:
23
+ from urllib.parse import urlparse
24
+ p = urlparse(u)
25
+ if p.hostname == "gist.github.com":
26
+ return u.rstrip("/") + "/raw"
27
+ if p.hostname == "github.com" and "/blob/" in p.path:
28
+ return u.replace("github.com", "raw.githubusercontent.com").replace("/blob/", "/")
29
+ except Exception:
30
+ pass
31
+ return u
32
+
33
+
34
+ def extract(text):
35
+ seen = set()
36
+ ids = []
37
+
38
+ def add(rid):
39
+ rid = rid.lower()
40
+ if rid not in seen:
41
+ seen.add(rid)
42
+ ids.append(rid)
43
+
44
+ # A pasted receipt JSON export: its own top-level id is a receipt id.
45
+ if "receipt_schema_version" in text:
46
+ jm = re.search(r'"id"\s*:\s*"(' + UUID + r')"', text, re.IGNORECASE)
47
+ if jm:
48
+ add(jm.group(1))
49
+ for m in LINK_RE.finditer(text):
50
+ if m.group(0).lower().startswith("zambo.dev/workflow/"):
51
+ continue # workflow ids are not receipt ids
52
+ add(m.group(1))
53
+ for m in BARE_RE.finditer(text):
54
+ add(m.group(1))
55
+ return ids[:MAX]
56
+
57
+
58
+ def read_input(arg):
59
+ if not arg or arg == "-":
60
+ return sys.stdin.read()
61
+ if arg.lower().startswith(("http://", "https://")):
62
+ req = urllib.request.Request(raw_url(arg), headers={"User-Agent": "aer1-scan"})
63
+ with urllib.request.urlopen(req, timeout=TIMEOUT) as res:
64
+ return res.read().decode("utf-8", "replace")
65
+ with open(arg, "r", encoding="utf-8", errors="replace") as f:
66
+ return f.read()
67
+
68
+
69
+ def verify(rid):
70
+ req = urllib.request.Request(
71
+ "https://zambo.dev/api/v2/receipt/" + rid + "/verify",
72
+ headers={"User-Agent": "aer1-scan"})
73
+ try:
74
+ with urllib.request.urlopen(req, timeout=TIMEOUT) as res:
75
+ data = json.loads(res.read().decode("utf-8", "replace"))
76
+ except urllib.error.HTTPError as e:
77
+ return "not found" if e.code == 404 else "could not verify"
78
+ except Exception:
79
+ return "could not verify"
80
+ status = data.get("verification_status")
81
+ return "verified" if status == "verified" else str(status or "could not verify")
82
+
83
+
84
+ def main():
85
+ arg = sys.argv[1] if len(sys.argv) > 1 else None
86
+ try:
87
+ text = read_input(arg)
88
+ except Exception as e:
89
+ print("aer1-scan: " + str(e), file=sys.stderr)
90
+ return 1
91
+ ids = extract(text)
92
+ if not ids:
93
+ print("no zambo receipt links found. receipts look like zambo.dev/run/ followed by an id.",
94
+ file=sys.stderr)
95
+ return 1
96
+ failed = False
97
+ for rid in ids:
98
+ state = verify(rid)
99
+ if state != "verified":
100
+ failed = True
101
+ print(state + " " + rid + " https://zambo.dev/verify/?id=" + rid)
102
+ return 1 if failed else 0
103
+
104
+
105
+ if __name__ == "__main__":
106
+ sys.exit(main())
@@ -0,0 +1,25 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "aer1-scan"
7
+ version = "1.0.0"
8
+ description = "Check every Zambo receipt link in a file, a web page, or stdin, right from your terminal. A Zambo receipt proves the saved result of an AI job was not changed after the fact."
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = { text = "MIT" }
12
+ authors = [
13
+ { name = "Brennan Zambo" }
14
+ ]
15
+ keywords = ["aer-1", "zambo", "receipts", "verification", "ai-agents", "mcp"]
16
+
17
+ [project.urls]
18
+ Homepage = "https://zambo.dev/verify/"
19
+ Repository = "https://github.com/zambodotdev/aer1-scan"
20
+
21
+ [project.scripts]
22
+ aer1-scan = "aer1_scan:main"
23
+
24
+ [tool.setuptools]
25
+ py-modules = ["aer1_scan"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+