alethech 0.1.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.
alethech-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AliceLabs LLC
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,14 @@
1
+ Metadata-Version: 2.4
2
+ Name: alethech
3
+ Version: 0.1.0
4
+ Summary: Verifiable agent continuity protocol — local-first, zero-LLM, zero-blockchain
5
+ Author: AliceLabs
6
+ License: MIT
7
+ Requires-Python: >=3.10
8
+ License-File: LICENSE
9
+ Requires-Dist: cryptography>=42.0
10
+ Requires-Dist: click>=8.0
11
+ Provides-Extra: dev
12
+ Requires-Dist: pytest>=8.0; extra == "dev"
13
+ Requires-Dist: pytest-cov; extra == "dev"
14
+ Dynamic: license-file
@@ -0,0 +1,98 @@
1
+ # alethech
2
+
3
+ > Verifiable agent continuity protocol — local-first, zero-LLM, zero-blockchain.
4
+ > The art of un-concealing transmission integrity.
5
+
6
+ From Greek **ἀλήθεια** (aletheia, "truth as un-concealment") + **τέχνη** (techne, "art, craft").
7
+ The art of revealing that a memory was not modified after being signed.
8
+
9
+ This is the reference implementation of the protocol specified in `docs/implementacion-nucleo-minimo.md` (rev 2).
10
+
11
+ ## the property
12
+
13
+ > **This memory set forms part of a cryptographically verifiable history associated with a determined identity, whose commits can be independently verified with respect to their integrity, cryptographic authorship, and provenance relations.**
14
+ >
15
+ > **When a reference checkpoint exists, it can additionally be verified that the presented history continues from that checkpoint.**
16
+
17
+ The protocol does NOT prove that the agent's claims are true — only that they were signed by the identity that claims them. The truth being un-concealed is the truth about transmission integrity, not about content.
18
+
19
+ ## status
20
+
21
+ Implementation of rev 2 spec. Six commands. No LLM, no MCP, no MarketNow, no UTA, no network, no P2P, no cloud, no consensus, no trust providers, no marketplace, no skill verification, no multi-agent consensus.
22
+
23
+ ## install
24
+
25
+ ```bash
26
+ pip install alethech
27
+ ```
28
+
29
+ For development:
30
+
31
+ ```bash
32
+ git clone https://github.com/eddyflores100-lang/alethech.git
33
+ cd alethech
34
+ git checkout protocol-rev2
35
+ pip install -e .
36
+ ```
37
+
38
+ ## usage
39
+
40
+ ```bash
41
+ alethech init # generate identity + genesis commit
42
+ alethech commit --content <json-file> # create signed MemoryCommit
43
+ alethech evidence --tool <name> # create signed EvidenceCommit
44
+ --input <file> --output <file>
45
+ alethech verify # verify the whole store, offline
46
+ alethech export --output <dir> # portable package
47
+ alethech import --input <dir> # import external memory
48
+ ```
49
+
50
+ ## what it does NOT do
51
+
52
+ - It does NOT prove that the agent's claims are true. Only that they were signed by the identity that claims them.
53
+ - It does NOT detect rollback without an external checkpoint.
54
+ - It does NOT encrypt content at rest.
55
+ - It does NOT delegate permissions between agents.
56
+ - It does NOT call any LLM.
57
+
58
+ ## what the name means
59
+
60
+ **alethech** comes from:
61
+
62
+ - **aletheia (ἀλήθεια)** — Greek for "truth", more precisely "un-concealment" (Heidegger's reading: truth as the act of revealing what was hidden)
63
+ - **techne (τέχνη)** — Greek for "art, craft, technique"
64
+
65
+ So alethech = "the art of un-concealing". The protocol un-conceals:
66
+ - whether a memory was modified after being signed
67
+ - who signed it
68
+ - when it was signed
69
+ - what its provenance is
70
+ - whether the chain of custody is intact
71
+
72
+ It does NOT un-conceal whether the content is true — that's the agent's responsibility, not the protocol's.
73
+
74
+ ## tests
75
+
76
+ ```bash
77
+ python -m pytest tests/
78
+ ```
79
+
80
+ 34 tests covering:
81
+ - crypto primitives (Ed25519, SHA-256, base64url, base32)
82
+ - JCS canonicalization (RFC 8785)
83
+ - agent_id derivation (cryptographic binding to public_key)
84
+ - MemoryCommit signing, tamper detection, wrong-key rejection
85
+ - EvidenceCommit signing
86
+ - all 6 CLI commands
87
+ - checkpoint emission + rollback detection
88
+ - identity_mismatch detection
89
+ - export/import roundtrip preservation
90
+ - tampered manifest rejection
91
+
92
+ ## license
93
+
94
+ MIT.
95
+
96
+ ## related repositories
97
+
98
+ - The companion project `memex` (Python/ChromaDB memory system) is a separate layer that handles retrieval, MCP, and graph memory. `alethech` is the cryptographic protocol layer that lives on top of `memex` to make its memory verifiable. The two will eventually converge via a write-hook integration.
@@ -0,0 +1,6 @@
1
+ """alethech — verifiable agent continuity protocol.
2
+
3
+ Reference implementation of the protocol specified in rev 2.
4
+ Local-first, zero-LLM, zero-blockchain.
5
+ """
6
+ __version__ = "0.1.0"
@@ -0,0 +1,106 @@
1
+ """JCS (JSON Canonicalization Scheme) — RFC 8785.
2
+
3
+ Serializes JSON to a canonical byte string suitable for hashing and signing.
4
+
5
+ Implementation notes:
6
+ - Object keys sorted by UTF-16 code unit (RFC 8785 §3.2.3).
7
+ - Strings escaped per RFC 8259 (no escaped non-ASCII — UTF-8 direct).
8
+ - Numbers: integer if no fractional/exponent, else minimal float repr.
9
+ - No whitespace, no trailing newline.
10
+ """
11
+ from __future__ import annotations
12
+
13
+ import math
14
+ from typing import Any
15
+
16
+ # Characters that MUST be escaped in JCS (RFC 8259 §7)
17
+ _ESCAPE_MAP = {
18
+ '"': '\\"',
19
+ "\\": "\\\\",
20
+ "\b": "\\b",
21
+ "\f": "\\f",
22
+ "\n": "\\n",
23
+ "\r": "\\r",
24
+ "\t": "\\t",
25
+ }
26
+
27
+
28
+ def _escape_string(s: str) -> str:
29
+ """Escape a string per RFC 8259. Non-ASCII chars are emitted as UTF-8."""
30
+ out = ['"']
31
+ for ch in s:
32
+ if ch in _ESCAPE_MAP:
33
+ out.append(_ESCAPE_MAP[ch])
34
+ elif ord(ch) < 0x20:
35
+ out.append("\\u%04x" % ord(ch))
36
+ else:
37
+ out.append(ch)
38
+ out.append('"')
39
+ return "".join(out)
40
+
41
+
42
+ def _serialize_number(n: float | int) -> str:
43
+ """Serialize a number per RFC 8785 §3.2.2.3."""
44
+ if isinstance(n, bool):
45
+ # bool is a subclass of int — handle before number conversion
46
+ raise TypeError("booleans are not valid JCS values at top level")
47
+
48
+ if isinstance(n, int):
49
+ return str(n)
50
+
51
+ # float
52
+ if n != n: # NaN
53
+ raise ValueError("NaN not representable in JCS")
54
+ if n == math.inf:
55
+ raise ValueError("Infinity not representable in JCS")
56
+ if n == -math.inf:
57
+ raise ValueError("-Infinity not representable in JCS")
58
+
59
+ if n == 0.0:
60
+ # Preserve sign of zero per RFC 8785
61
+ return "-0" if math.copysign(1.0, n) < 0 else "0"
62
+
63
+ # Integer-valued float (e.g. 3.0)
64
+ if n == int(n) and abs(n) < 1e21:
65
+ return str(int(n))
66
+
67
+ # Use repr for shortest round-trippable representation, then strip
68
+ # any trailing exponent that Python adds unnecessarily.
69
+ s = repr(n)
70
+ # Python repr is fine for our purposes — it produces minimal round-trip
71
+ return s
72
+
73
+
74
+ def _serialize_value(v: Any) -> str:
75
+ if v is None:
76
+ return "null"
77
+ if v is True:
78
+ return "true"
79
+ if v is False:
80
+ return "false"
81
+ if isinstance(v, (int, float)):
82
+ return _serialize_number(v)
83
+ if isinstance(v, str):
84
+ return _escape_string(v)
85
+ if isinstance(v, list):
86
+ return "[" + ",".join(_serialize_value(x) for x in v) + "]"
87
+ if isinstance(v, dict):
88
+ # Sort keys by UTF-16 code unit (RFC 8785 §3.2.3)
89
+ items = sorted(v.items(), key=lambda kv: kv[0].encode("utf-16-be"))
90
+ parts = []
91
+ for k, val in items:
92
+ if not isinstance(k, str):
93
+ raise TypeError(f"non-string object key: {k!r}")
94
+ parts.append(_escape_string(k) + ":" + _serialize_value(val))
95
+ return "{" + ",".join(parts) + "}"
96
+ raise TypeError(f"unserializable type: {type(v).__name__}")
97
+
98
+
99
+ def canonical_json(value: Any) -> str:
100
+ """Return the JCS canonical string for the value."""
101
+ return _serialize_value(value)
102
+
103
+
104
+ def canonical_json_bytes(value: Any) -> bytes:
105
+ """Return the JCS canonical bytes for the value (UTF-8 encoded)."""
106
+ return canonical_json(value).encode("utf-8")