feat: validator, bundle builder and release checks for 0.1.0
- Add tools/validate.py: validates packages, and with --correction runs proposed corrections through the gate against a package without writing anything (spec/11 §11.4). The gate now refuses a proposal that fails the correction schema, rule correction.schema. - tools/load.py validates every package before loading, and with --bundle --built-from builds a scienting-bundle/1 with the FTS5 search index and bundle_meta (spec/13 §13.5). Search rows are defined per unit (sentence, cell, equation outside a sentence, figure-text) with the parent kind as context. - Roster keys carry a role, and a key with the role owner may revoke any receipt (spec/08 §8.7, spec/20); roster schema, store table and the fixture roster updated. The checker signs a trial revocation to prove the rule both ways. - A qa: receipt raises the nodes it sampled except those in its errors (spec/08 §8.2); the example paper's fidelity counts become 27 F3, 13 F2, 4 F1 and 1 F0. - The destination chooses the keyed scheme, not the text policy: hmac-team between the team's machines, hkdf-pages outside the team (spec/05 §5.8, spec/12 §12.5). - A TextQuoteSelector must repeat the anchor's plain quote and is absent for hashed or keyed anchors (spec/18 §18.3). - Add fixtures/records/suspect.json, a scienting-suspect/1 record. - Oracle: hashes are kept incrementally and checked after every correction against a full recomputation; load and write refuse unsafe manifest paths; Ed25519, HKDF and schema validation come from the cryptography and jsonschema packages; canonical JSON uses the built-in encoder with an exact RFC 8785 fallback. - The tools need Python 3.14 with cryptography and jsonschema; the py310 CI environment is dropped and the workflow runs the default only. - Resolve every [CHECK] note in the docs, READMEs and context; add CONTRIBUTING.md; every tool answers --help and refuses unknown options. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
89 files changed
+1141
-513
No files matched your search
+37
-1
@@ -1,11 +1,18 @@
|
||||
"""Canonical JSON, RFC 8785 (JSON Canonicalization Scheme).
|
||||
|
||||
Non-normative.
|
||||
The normative rule is spec/01-conventions.md; this module exists so the vectors can be generated and checked.
|
||||
The normative rule is spec/01-conventions.md.
|
||||
Most values serialize through the standard library's C encoder, which escapes strings exactly as RFC 8785 does.
|
||||
Values it would write differently take the exact path below: floats, integers beyond 2^53, and member names
|
||||
outside the Basic Multilingual Plane, which RFC 8785 sorts by UTF-16 code units rather than by code points.
|
||||
"""
|
||||
|
||||
import json
|
||||
import math
|
||||
|
||||
_C = json.JSONEncoder(ensure_ascii=False, separators=(",", ":"), sort_keys=True, allow_nan=False)
|
||||
_EXACT_INT = 2**53
|
||||
|
||||
_ESC = {
|
||||
0x08: "\\b",
|
||||
0x09: "\\t",
|
||||
@@ -82,8 +89,37 @@ def _key(s):
|
||||
return s.encode("utf-16-be")
|
||||
|
||||
|
||||
def _fast(v):
|
||||
"""True when the C encoder writes `v` exactly as RFC 8785 does."""
|
||||
t = type(v)
|
||||
if t is str or v is None or t is bool:
|
||||
return True
|
||||
if t is int:
|
||||
return -_EXACT_INT <= v <= _EXACT_INT
|
||||
if t is dict:
|
||||
for k, x in v.items():
|
||||
if type(k) is not str or (not k.isascii() and max(k) > "\uffff") or not _fast(x):
|
||||
return False
|
||||
return True
|
||||
if t is list or t is tuple:
|
||||
return all(_fast(x) for x in v)
|
||||
return False
|
||||
|
||||
|
||||
def dumps(value):
|
||||
"""Serialize `value` to canonical JSON text."""
|
||||
if _fast(value):
|
||||
text = _C.encode(value)
|
||||
if not text.isascii():
|
||||
try:
|
||||
text.encode("utf-8")
|
||||
except UnicodeEncodeError:
|
||||
raise ValueError("lone surrogate in string") from None
|
||||
return text
|
||||
return _exact(value)
|
||||
|
||||
|
||||
def _exact(value):
|
||||
if value is None:
|
||||
return "null"
|
||||
if value is True:
|
||||
|
||||
Reference in new issue
Block a user