--- id: ADR-0001 title: "Stage 0 library stack: schemas, pure fold, and validators" status: accepted date: 2026-07-28 decided_by: Bernd accepted_at: "2026-07-29" workstream: TREV-WP-0002 (trust-service-foundation) alternatives_considered: [TypeScript/Node, Go] --- # ADR-0001 — Stage 0 Library Stack (Schemas, Pure Fold, Validators) ## Status **Accepted 2026-07-29** by the maintainer (Bernd), confirming the stack already implemented under `workplans/TREV-WP-0002-trust-service-foundation.md` T02–T06: Python 3.11+, `jsonschema`, `pytest`, `hatchling` src-layout, SHA-256 canonical-serialization hash chain, Ed25519 signing. This decision locks implementation technology for Stage 0 schema/fold work only (§ Scope below) — it does not extend to a future hosted Trust Service ADR. ## Scope This decision covers **only** the Stage 0 deliverables of WP-0002: - JSON Schema (or equivalent) definitions for Phase Manifest, Target Ledger Entry, Extension Contract, Transaction Allocation, Conversion Attestation; - a pure, deterministic Outstanding Target fold; - offline conformance validators; - a golden Phase package and its test suite. It explicitly does **not** cover: hosted Phase/Extension Registry services, multi-tenant ledger APIs, a metrics product, or a federation protocol (`SCOPE.md` §3–§4). Those require a separate, later ADR once a Trust Service implementation workplan exists. ## Context `specs/TechnicalSpecificationDocument.md` §10 is deliberately non-binding on language, runtime, and storage. Something has to be chosen to write the Stage 0 library, but the choice should be cheap to revisit later since the hosted Trust Service is a different, larger decision. Requirements pulled from TSD §3, §6 and `specs/OpenQuestions-WorkingDefaults.md` Q14: - deterministic, pure computation (no hidden state, no floating-point order sensitivity) for the Outstanding Target fold; - JSON-Schema-shaped validation that a non-Python tool could later reimplement against the same `.schema.json` files; - SHA-256 canonical-serialization hash chaining and Ed25519 signatures over the same canonical bytes; - a test suite runnable offline, with no network services. ## Decision **Python 3.11+, `jsonschema` for schema validation, dataclasses for typed domain objects, `pytest` for the conformance suite, `hatchling` src-layout packaging.** Canonical serialization for hashing: JSON with sorted keys, no insignificant whitespace, UTF-8 encoding (`json.dumps(..., sort_keys=True, separators=(",", ":"))`), hashed with SHA-256. Signatures: Ed25519 via `cryptography` or `PyNaCl`, over the same canonical bytes. ## Rationale | What Stage 0 needs | Python fit | |---|---| | JSON Schema authoring and validation | `jsonschema` is a direct, widely-used implementation | | Pure fold over ledger entries | Trivial with dataclasses + `functools.reduce`; no framework needed | | Canonical serialization + hashing | Stdlib `json` + `hashlib` sufficient | | Ed25519 signing for examples | `cryptography` covers this without custom crypto code | | Offline conformance test suite | `pytest` is the de facto standard; matches this workspace's other Python repos (e.g. `shard-wiki`) | | Low ceremony for a schema/fold library, not a service | Python's scripting ergonomics outweigh static-typing benefits at this scope | ### Why not TypeScript/Node Would be a reasonable alternative if the primary consumer were browser-based tooling (cf. `binect-js`), but Stage 0 has no UI deliverable — it is a schema + pure-function library consumed by CLI/tests. Node adds packaging overhead (npm registry, `package.json` versioning discipline) without a corresponding benefit here. ### Why not Go Go would fit well if this were becoming a long-lived, standalone, performance-sensitive service (cf. `key-cape` ADR-0001's reasoning) — but Stage 0 is explicitly **not** the hosted Trust Service. A statically-typed, compiled toolchain is more ceremony than a schema/fold/test library needs at this stage. Revisit for the later hosted-service ADR. ## Consequences ### Positive - Fast path to a working, testable schema + fold library. - `jsonschema` files are directly reusable by a future non-Python implementation (hosted service ADR is unconstrained by this choice). - Matches existing Python conventions in this workspace (pytest, hatchling src-layout) for reviewer familiarity. ### Negative / risks - Python's dynamic typing means domain-model discipline must be enforced by convention (dataclasses + docstrings + tests), not the compiler. - Should not be read as a decision about the hosted Trust Service's stack — that is explicitly deferred and must not be assumed to inherit this choice without its own ADR. ### Compensating guardrails 1. Typed domain objects (`dataclasses`, `frozen=True` where the schema marks a field immutable) — no raw dicts crossing function boundaries in `fold.py` or `conversion.py`. 2. All schema validation goes through the `.schema.json` files under `schemas/` — no ad hoc field checks duplicated in Python without a corresponding schema entry. 3. The fold function must be pure: same `(manifest, entries)` input always produces the same Outstanding Target output, with no I/O. ## Revisit trigger Reconsider this decision when a hosted Trust Service implementation workplan is opened (`SCOPE.md` §3 "Production Trust Service"). That decision should weigh multi-tenant hosting, storage, and operational concerns not in scope here, and may reasonably choose a different stack without invalidating this one.