sum-engine 0.5.0__tar.gz → 0.7.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.
Files changed (129) hide show
  1. {sum_engine-0.5.0/sum_engine.egg-info → sum_engine-0.7.0}/PKG-INFO +57 -12
  2. {sum_engine-0.5.0 → sum_engine-0.7.0}/README.md +51 -8
  3. {sum_engine-0.5.0 → sum_engine-0.7.0}/pyproject.toml +14 -5
  4. sum_engine-0.7.0/sum_cli/audit_log.py +171 -0
  5. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_cli/main.py +777 -1
  6. {sum_engine-0.5.0 → sum_engine-0.7.0/sum_engine.egg-info}/PKG-INFO +57 -12
  7. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine.egg-info/SOURCES.txt +52 -0
  8. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine.egg-info/requires.txt +6 -3
  9. sum_engine-0.7.0/sum_engine_internal/agent_surface/__init__.py +22 -0
  10. sum_engine-0.7.0/sum_engine_internal/agent_surface/bind.py +138 -0
  11. sum_engine-0.7.0/sum_engine_internal/agent_surface/mcp_bind.py +677 -0
  12. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/algorithms/syntactic_sieve.py +9 -1
  13. sum_engine-0.7.0/sum_engine_internal/compliance/__init__.py +48 -0
  14. sum_engine-0.7.0/sum_engine_internal/compliance/_predicates.py +86 -0
  15. sum_engine-0.7.0/sum_engine_internal/compliance/eu_ai_act_article_12.py +197 -0
  16. sum_engine-0.7.0/sum_engine_internal/compliance/gdpr_article_30.py +207 -0
  17. sum_engine-0.7.0/sum_engine_internal/compliance/hipaa_164_312_b.py +230 -0
  18. sum_engine-0.7.0/sum_engine_internal/compliance/iso_27001_8_15.py +160 -0
  19. sum_engine-0.7.0/sum_engine_internal/compliance/pci_dss_4_req_10.py +264 -0
  20. sum_engine-0.7.0/sum_engine_internal/compliance/report.py +77 -0
  21. sum_engine-0.7.0/sum_engine_internal/compliance/soc_2_cc_7_2.py +153 -0
  22. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/live_llm_adapter.py +217 -8
  23. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/llm_dispatch.py +203 -16
  24. sum_engine-0.7.0/sum_engine_internal/evidence/__init__.py +45 -0
  25. sum_engine-0.7.0/sum_engine_internal/evidence/chain.py +160 -0
  26. sum_engine-0.7.0/sum_engine_internal/graph_store/__init__.py +26 -0
  27. sum_engine-0.7.0/sum_engine_internal/graph_store/base.py +105 -0
  28. sum_engine-0.7.0/sum_engine_internal/graph_store/egglog_store.py +360 -0
  29. sum_engine-0.7.0/sum_engine_internal/graph_store/unionfind_store.py +206 -0
  30. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/infrastructure/akashic_ledger.py +34 -11
  31. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/infrastructure/canonical_codec.py +374 -0
  32. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/infrastructure/jose_envelope.py +101 -0
  33. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/mcp_server/server.py +23 -1
  34. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/render_receipt/verifier.py +11 -1
  35. sum_engine-0.7.0/sum_engine_internal/research/bootstrap/__init__.py +41 -0
  36. sum_engine-0.7.0/sum_engine_internal/research/bootstrap/multiplier_bootstrap.py +181 -0
  37. sum_engine-0.7.0/sum_engine_internal/research/conformal/__init__.py +44 -0
  38. sum_engine-0.7.0/sum_engine_internal/research/conformal/entropy_baseline.py +182 -0
  39. sum_engine-0.7.0/sum_engine_internal/research/conformal/split_conformal.py +184 -0
  40. sum_engine-0.7.0/sum_engine_internal/research/lsh/__init__.py +19 -0
  41. sum_engine-0.7.0/sum_engine_internal/research/lsh/bundle_index.py +179 -0
  42. sum_engine-0.7.0/sum_engine_internal/research/mmd/__init__.py +54 -0
  43. sum_engine-0.7.0/sum_engine_internal/research/mmd/baseline.py +328 -0
  44. sum_engine-0.7.0/sum_engine_internal/research/mmd/mmd.py +184 -0
  45. sum_engine-0.7.0/sum_engine_internal/research/robust_pca/__init__.py +35 -0
  46. sum_engine-0.7.0/sum_engine_internal/research/robust_pca/axiom_embedding.py +69 -0
  47. sum_engine-0.7.0/sum_engine_internal/research/robust_pca/pcp.py +173 -0
  48. sum_engine-0.7.0/sum_engine_internal/research/sequential/__init__.py +21 -0
  49. sum_engine-0.7.0/sum_engine_internal/research/sequential/sprt.py +183 -0
  50. sum_engine-0.7.0/sum_engine_internal/research/sheaf_laplacian_v2.py +649 -0
  51. sum_engine-0.7.0/sum_engine_internal/research/sheaf_laplacian_v3.py +509 -0
  52. sum_engine-0.7.0/sum_engine_internal/research/sheaf_laplacian_v32.py +170 -0
  53. sum_engine-0.7.0/sum_engine_internal/research/smt_consistency/__init__.py +34 -0
  54. sum_engine-0.7.0/sum_engine_internal/research/smt_consistency/consistency.py +188 -0
  55. sum_engine-0.7.0/sum_engine_internal/research/smt_consistency/predicate_library.py +77 -0
  56. sum_engine-0.7.0/sum_engine_internal/research/spectral_entropy/__init__.py +41 -0
  57. sum_engine-0.7.0/sum_engine_internal/research/spectral_entropy/vn_entropy.py +141 -0
  58. sum_engine-0.7.0/sum_engine_internal/transform_receipt/__init__.py +55 -0
  59. sum_engine-0.7.0/sum_engine_internal/transform_receipt/format.py +215 -0
  60. sum_engine-0.7.0/sum_engine_internal/transform_receipt/sign.py +50 -0
  61. sum_engine-0.7.0/sum_engine_internal/transform_receipt/verifier.py +132 -0
  62. sum_engine-0.7.0/sum_engine_internal/transforms/__init__.py +104 -0
  63. sum_engine-0.7.0/sum_engine_internal/transforms/_base.py +203 -0
  64. sum_engine-0.7.0/sum_engine_internal/transforms/compose.py +304 -0
  65. sum_engine-0.7.0/sum_engine_internal/transforms/extract.py +406 -0
  66. sum_engine-0.7.0/sum_engine_internal/transforms/share.py +231 -0
  67. sum_engine-0.7.0/sum_engine_internal/transforms/slider.py +380 -0
  68. {sum_engine-0.5.0 → sum_engine-0.7.0}/LICENSE +0 -0
  69. {sum_engine-0.5.0 → sum_engine-0.7.0}/setup.cfg +0 -0
  70. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_cli/__init__.py +0 -0
  71. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine.egg-info/dependency_links.txt +0 -0
  72. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine.egg-info/entry_points.txt +0 -0
  73. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine.egg-info/top_level.txt +0 -0
  74. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/__init__.py +0 -0
  75. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/adapters/__init__.py +0 -0
  76. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/adapters/format_pivot.py +0 -0
  77. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/algorithms/__init__.py +0 -0
  78. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/algorithms/causal_discovery.py +0 -0
  79. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/algorithms/chunked_corpus.py +0 -0
  80. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/algorithms/minhash.py +0 -0
  81. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/algorithms/predicate_canon.py +0 -0
  82. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/algorithms/semantic_arithmetic.py +0 -0
  83. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/algorithms/zk_semantics.py +0 -0
  84. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/__init__.py +0 -0
  85. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/automated_scientist.py +0 -0
  86. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/autonomous_agent.py +0 -0
  87. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/causal_triggers.py +0 -0
  88. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/confidence_calibrator.py +0 -0
  89. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/data/__init__.py +0 -0
  90. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/data/common_english_2000.txt +0 -0
  91. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/data/common_english_5000.txt +0 -0
  92. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/epistemic_arbiter.py +0 -0
  93. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/epistemic_loop.py +0 -0
  94. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/extraction_validator.py +0 -0
  95. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/gauge_orchestrator.py +0 -0
  96. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/llm_entailment.py +0 -0
  97. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/mass_semantic_engine.py +0 -0
  98. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/ouroboros.py +0 -0
  99. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/s25_interventions.py +0 -0
  100. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/semantic_dedup.py +0 -0
  101. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/slider_renderer.py +0 -0
  102. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/tome_generator.py +0 -0
  103. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/tome_sliders.py +0 -0
  104. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/vector_bridge.py +0 -0
  105. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/ensemble/venn_abers.py +0 -0
  106. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/infrastructure/__init__.py +0 -0
  107. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/infrastructure/jcs.py +0 -0
  108. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/infrastructure/key_manager.py +0 -0
  109. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/infrastructure/p2p_mesh.py +0 -0
  110. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/infrastructure/prov_o.py +0 -0
  111. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/infrastructure/provenance.py +0 -0
  112. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/infrastructure/rate_limiter.py +0 -0
  113. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/infrastructure/resource_guards.py +0 -0
  114. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/infrastructure/scheme_registry.py +0 -0
  115. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/infrastructure/state_encoding.py +0 -0
  116. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/infrastructure/telemetry.py +0 -0
  117. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/infrastructure/tome_parser.py +0 -0
  118. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/infrastructure/verifiable_credential.py +0 -0
  119. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/infrastructure/zig_bridge.py +0 -0
  120. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/mcp_server/__init__.py +0 -0
  121. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/mcp_server/__main__.py +0 -0
  122. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/mcp_server/errors.py +0 -0
  123. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/merkle_sidecar/__init__.py +0 -0
  124. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/merkle_sidecar/tree.py +0 -0
  125. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/render_receipt/__init__.py +0 -0
  126. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/research/__init__.py +0 -0
  127. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/research/sheaf_laplacian.py +0 -0
  128. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/trust_root/__init__.py +0 -0
  129. {sum_engine-0.5.0 → sum_engine-0.7.0}/sum_engine_internal/trust_root/verifier.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sum-engine
3
- Version: 0.5.0
3
+ Version: 0.7.0
4
4
  Summary: SUM — bidirectional knowledge distillation with optional cryptographic attestation. Pipe prose, get a CanonicalBundle (HMAC / Ed25519 / W3C VC 2.0), verify anywhere.
5
5
  Author: ototao
6
6
  License: Apache-2.0
@@ -25,9 +25,11 @@ Requires-Dist: cryptography>=41.0.0
25
25
  Requires-Dist: sympy>=1.12
26
26
  Provides-Extra: sieve
27
27
  Requires-Dist: spacy>=3.7.0; extra == "sieve"
28
+ Provides-Extra: openai
29
+ Requires-Dist: openai<3.0.0,>=1.40.0; extra == "openai"
30
+ Requires-Dist: pydantic>=2.0.0; extra == "openai"
28
31
  Provides-Extra: llm
29
- Requires-Dist: openai<3.0.0,>=1.40.0; extra == "llm"
30
- Requires-Dist: pydantic>=2.0.0; extra == "llm"
32
+ Requires-Dist: sum-engine[openai]; extra == "llm"
31
33
  Provides-Extra: anthropic
32
34
  Requires-Dist: anthropic>=0.97.0; extra == "anthropic"
33
35
  Requires-Dist: pydantic>=2.0.0; extra == "anthropic"
@@ -51,7 +53,7 @@ Requires-Dist: build>=1.0.0; extra == "dev"
51
53
  Requires-Dist: hypothesis>=6.0.0; extra == "dev"
52
54
  Provides-Extra: all
53
55
  Requires-Dist: sum-engine[sieve]; extra == "all"
54
- Requires-Dist: sum-engine[llm]; extra == "all"
56
+ Requires-Dist: sum-engine[openai]; extra == "all"
55
57
  Requires-Dist: sum-engine[anthropic]; extra == "all"
56
58
  Requires-Dist: sum-engine[receipt-verify]; extra == "all"
57
59
  Requires-Dist: sum-engine[mcp]; extra == "all"
@@ -66,9 +68,15 @@ Dynamic: license-file
66
68
  [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
67
69
  [![Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
68
70
 
69
- > **A cross-runtime trust surface for LLM-rendered text.** Three runtimes (Python, Node, modern browsers) produce byte-identical Ed25519 signatures over the same JCS-canonical bytes. Every render through the hosted Worker carries a detached-JWS receipt (`sum.render_receipt.v1`) that any third party can verify offline against `/.well-known/jwks.json`. Live at https://sum-demo.ototao.workers.dev.
71
+ > **SUM lets people and agents transform knowledge without losing the ability to verify what changed, what stayed the same, who signed it, and what remains unproven.**
70
72
 
71
- That is the load-bearing claim and what makes SUM different from a generic summarisation tool. The cryptographic side is **mechanically proven**three independent verifier implementations agreeing byte-for-byte on every signed bundle, locked in CI on every PR. The semantic side (extraction quality, slider fact preservation) is **empirically measured** with explicit per-corpus numbers and explicit per-corpus boundaries; SUM does not blur the line between the two. [`docs/PROOF_BOUNDARY.md`](docs/PROOF_BOUNDARY.md) is the arbiter.
73
+ Every transformation extract triples from prose, render a tome at a controlled slider position, compose bundles across documents, share a render emits a cryptographically-signed receipt that any third party can verify offline. The receipt attests *that the transformation happened and what its inputs were*. Separate per-axis benchmarks attest *how much the transformation preserved meaning*. Both are kept honest by separate proof discipline — and the project never blurs the line between them.
74
+
75
+ *Live trust loop:* https://sum-demo.ototao.workers.dev — three runtimes (Python, Node, modern browsers) produce byte-identical Ed25519 signatures over the same JCS-canonical bytes; verify offline against `/.well-known/jwks.json`. Mechanically proven; locked in CI on every PR.
76
+
77
+ **Built for:** journalists working under deepfake-era citation requirements, academic survey writers who need provenance back to source PDFs, agentic-AI builders who need their agents to pass verifiable evidence and not just messages, and regulated-domain content (EU AI Act Article 12, FTC AI disclosure, HIPAA, SOC 2, PCI DSS) where "we say it's true" isn't enough.
78
+
79
+ The cryptographic side is **mechanically proven** — three independent verifier implementations agreeing byte-for-byte on every signed bundle, locked in CI on every PR. The semantic side (extraction quality, slider fact preservation) is **empirically measured** with explicit per-corpus numbers and explicit per-corpus boundaries. [`docs/PROOF_BOUNDARY.md`](docs/PROOF_BOUNDARY.md) is the arbiter.
72
80
 
73
81
  Headline supporting numbers (each links to its source of truth):
74
82
 
@@ -110,14 +118,29 @@ A minimal Node verifier using `jose` + `canonicalize` is in [`docs/RENDER_RECEIP
110
118
  | Surface | Status | Verifies |
111
119
  |---|---|---|
112
120
  | `pip install 'sum-engine[sieve]'` — `sum attest` / `sum verify` / `sum render` / `sum resolve` / `sum ledger` / `sum inspect` / `sum schema` | shipped on PyPI ≥ 0.4.1 | structural reconstruction; HMAC-SHA256 + Ed25519 signatures (W3C VC 2.0 `eddsa-jcs-2022`); bidirectional `sum attest` ↔ `sum render` symmetry from the shell |
113
- | Cloudflare Worker at `sum-demo.ototao.workers.dev` | shipped | `/api/render` → tome + `render_receipt`; `/.well-known/jwks.json` → JWKS; `/api/qid` → Wikidata resolver |
121
+ | Cloudflare Worker at `sum-demo.ototao.workers.dev` | shipped | `/api/render` → tome + `render_receipt`; `/api/transform` → generic transform-registry dispatch + `sum.transform_receipt.v1`; `/api/complete` → LLM proxy; `/api/qid` → Wikidata resolver; `/.well-known/jwks.json` + `/.well-known/revoked-kids.json` → trust-loop endpoints. Public LLM-axis routes are rate-limited per IP — see [`docs/PUBLIC_API_RATE_LIMITS.md`](docs/PUBLIC_API_RATE_LIMITS.md) (5/day operator-keyed demo; 100/hr with BYO key via `X-Render-LLM-Key-Anthropic` / `-OpenAI`). |
114
122
  | Single-file browser demo (`single_file_demo/index.html`) | shipped | paste prose → in-browser attest → CanonicalBundle JSON; same bytes verify under `node standalone_verifier/verify.js` (Chrome / Firefox / Safari with WebCrypto Ed25519 support) |
115
123
  | Cross-runtime trust triangle | locked by CI (`make xruntime`) | K1 / K1-mw / K2 / K3 / K4 — Python ↔ Node ↔ Browser agree byte-for-byte on valid bundles. `make xruntime-adversarial` adds A1–A6 rejection-class equivalence. |
116
- | 5-axis slider rendering surface | density actioned deterministically; length / formality / audience / perspective LLM-conditioned via the Worker (Anthropic, Cloudflare AI Gateway optional) | bench: median LLM-axis fact preservation 1.000, p10 0.769 (long, n=16) / 0.818 (short, n=8), order preservation 1.000 wherever measurable |
124
+ | 5-axis slider rendering surface | density actioned deterministically; length / formality / audience / perspective LLM-conditioned. Two dispatch paths: Worker `/api/render` (Anthropic + Cloudflare AI Gateway optional) producing `sum.render_receipt.v1`, OR Python `sum transform apply slider` (OpenAI via `OPENAI_API_KEY`) producing `sum.transform_receipt.v1` | bench: median LLM-axis fact preservation 1.000, p10 0.769 (long, n=16) / 0.818 (short, n=8), order preservation 1.000 wherever measurable. Tightening worktrail at [`docs/BENCH_HARDENING_FROM_QCVV.md`](docs/BENCH_HARDENING_FROM_QCVV.md) adds iteration-stability + DKW worst-case bounds + capability-region headlines |
117
125
  | MCP server (`sum-mcp` console script) | shipped | five tools (`extract` / `attest` / `verify` / `inspect` / `schema`) exposed over stdio; bundles attested via MCP verify byte-identically through the CLI / Node / browser verifiers |
126
+ | Transform substrate (`sum.transform_receipt.v1` + registry) | shipped (CLI in repo HEAD; PyPI catch-up tag pending) | `sum transform list` / `sum transform apply <name>` — three registered transforms (`slider` / `extract` / `compose`); receipts via Ed25519 / JCS / detached JWS just like render-receipts; 20-fixture cross-runtime K-matrix locks accept + reject across Python ↔ Node ↔ browser; T4 `source_chain_hash` binds receipts to source byte ranges; T5 `ShareableRender` round-trips signed renders for offline verification; T6 multi-school extract runs two extractors in tandem for adversarial-divergence detection. Wire spec at [`docs/TRANSFORM_RECEIPT_FORMAT.md`](docs/TRANSFORM_RECEIPT_FORMAT.md); design at [`docs/TRANSFORM_REGISTRY.md`](docs/TRANSFORM_REGISTRY.md). |
127
+ | Replay-defense window (`signed_at_out_of_window`) | shipped | opt-in `max_age_seconds` parameter across all four verifier surfaces (Python render / Python transform / JS render / JS transform). Default-off preserves archival use; receivers opt in per use-case (agent-swarm 60s, real-time 600s, newsletter 1d, legal-discovery no window). |
128
+ | `sum verify --explain` layered output | shipped | Per-dimension report (`sum.verify_explained.v1`): cryptographic integrity / canonical reconstruction / axiom consistency / extraction provenance / source evidence coverage / semantic preservation / truth of content. Each carries `epistemic_status` (`provable` / `certified` / `empirical-benchmark` / `not-asserted`). Truth of content is ALWAYS `not_asserted` — locked by test. |
129
+ | Negative-control corpus (T5 of bench-hardening) | shipped | 20 hand-authored documents across 5 failure modes (ambiguous coref / predicate-alias / contradictions / entity-resolution-adversarial / non-extractable). Runner exits 1 if observed failures don't match annotations. Baseline at [`fixtures/bench_receipts/negative_control_2026-05-17.json`](fixtures/bench_receipts/negative_control_2026-05-17.json). |
130
+ | Compliance validators (six regimes) | shipped | `sum compliance check --regime <id> --audit-log <path>` — EU AI Act Article 12, GDPR Article 30, HIPAA § 164.312(b), ISO/IEC 27001 A.8.15, SOC 2 CC 7.2, PCI DSS v4.0 Req 10. All six produce the same `sum.compliance_report.v1` schema; per-regime docs at `docs/COMPLIANCE_*.md`. |
118
131
 
119
132
  The slider's product claim — *axis changes do not lose facts* — is the load-bearing empirical result. It is verified by NLI audit on every embedding-flagged "loss" cell; full attribution in [`docs/SLIDER_CONTRACT.md`](docs/SLIDER_CONTRACT.md).
120
133
 
134
+ ## Strategic context
135
+
136
+ The operational compass — read in this order if you want the project's intent + how it operates + where it's going:
137
+
138
+ - [`docs/CHARTER_2026-05-17.md`](docs/CHARTER_2026-05-17.md) — intent, the Why, strategy, objectives, success criteria, constraints, and the operational loop. The compass every other doc resolves to.
139
+ - [`docs/PRODUCT_DELIBERATION_2026-05-14.md`](docs/PRODUCT_DELIBERATION_2026-05-14.md) — three-option strategic analysis + grant-outcome decision tree.
140
+ - [`docs/ZENITH_FRAMING_2026-05-16.md`](docs/ZENITH_FRAMING_2026-05-16.md) — destination framing (SUM as chain-of-custody for AI-transformed knowledge) plus three new concepts (Perspective Receipts, Trust Profiles, Epistemic Nutrition Label) on the design queue.
141
+ - [`docs/BENCH_HARDENING_FROM_QCVV.md`](docs/BENCH_HARDENING_FROM_QCVV.md) — five-task empirical-benchmark hardening plan (T1–T5; T5 shipped, T1–T4 queued).
142
+ - [`docs/DOGFOOD_QUICKSTART.md`](docs/DOGFOOD_QUICKSTART.md) — five-minute guide to running SUM on your own writing.
143
+
121
144
  ### LLM narrative round-trip — closed across measured corpora (2026-04-28)
122
145
 
123
146
  The hardest measurement in `PROOF_BOUNDARY.md` is the full LLM narrative round-trip (`text → LLM-extract → axioms → LLM-generate → prose' → LLM-extract → axioms'`). The unprompted-pipeline baseline on `seed_v1` was **drift = 107.75% / exact-match recall = 0.12** — facts preserved, keys not.
@@ -165,7 +188,7 @@ The reverse direction also runs under explicit slider control. The local path ac
165
188
  sum render --density 0.5 < bundle.json
166
189
  # → keeps the lex-prefix half of the axioms; @sliders header records what was requested
167
190
 
168
- sum render --length 0.9 --use-worker https://sum.ototao.com --json < bundle.json
191
+ sum render --length 0.9 --use-worker https://sum-demo.ototao.workers.dev --json < bundle.json
169
192
  # → LLM-conditioned tome + signed render_receipt (sum.render_receipt.v1) on stdout
170
193
  ```
171
194
 
@@ -192,7 +215,7 @@ pip install 'sum-engine[mcp,sieve]'
192
215
 
193
216
  ### Calling SUM over HTTP
194
217
 
195
- The hosted Worker at `https://sum.ototao.com` exposes `/api/render`, `/api/complete`, `/api/qid`, and the `/.well-known/{jwks,revoked-kids}.json` verification surfaces. [`docs/API_REFERENCE.md`](docs/API_REFERENCE.md) is the wire spec — request/response shapes, error codes, the six-step receipt-verification flow, working Node + Python examples. Use this when the caller is a web app, mobile app, or server-side service; use the MCP server when the caller is a local LLM client.
218
+ The hosted Worker at `https://sum-demo.ototao.workers.dev` exposes `/api/render`, `/api/complete`, `/api/qid`, and the `/.well-known/{jwks,revoked-kids}.json` verification surfaces. [`docs/API_REFERENCE.md`](docs/API_REFERENCE.md) is the wire spec — request/response shapes, error codes, the six-step receipt-verification flow, working Node + Python examples. Use this when the caller is a web app, mobile app, or server-side service; use the MCP server when the caller is a local LLM client.
196
219
 
197
220
  ---
198
221
 
@@ -228,7 +251,29 @@ Below the slider sits the substrate that earlier phases shipped and verified. Po
228
251
  - **Bundle public-key attestation (provable).** Ed25519-signed CanonicalBundles are tamper-detectable by any third party in any of the three runtimes. [`docs/PROOF_BOUNDARY.md`](docs/PROOF_BOUNDARY.md) §1.3.1.
229
252
  - **Merkle hash-chain integrity (provable, including under concurrent writers).** [`docs/PROOF_BOUNDARY.md`](docs/PROOF_BOUNDARY.md) §1.7.
230
253
  - **Extraction F1 (empirical-benchmark).** 1.000 on `seed_v1` (50 simple-SVO docs); 0.762 with precision 1.000 on `seed_v2` (20-doc difficulty corpus). Every remaining `seed_v2` failure is a recall miss, not a truth inversion. [`docs/PROOF_BOUNDARY.md`](docs/PROOF_BOUNDARY.md) §2.1.
231
- - **103 numbered features**, each with a reproducible verification command, in [`docs/FEATURE_CATALOG.md`](docs/FEATURE_CATALOG.md).
254
+ - **168 numbered features**, each with a reproducible verification command, in [`docs/FEATURE_CATALOG.md`](docs/FEATURE_CATALOG.md).
255
+
256
+ ### Research substrate (under `sum_engine_internal/research/`)
257
+
258
+ Less-surfaced but shipped:
259
+
260
+ - **MinHash-LSH bundle similarity index** (`research/lsh/`) — near-duplicate bundle detection at scale.
261
+ - **Robust PCA corruption score** (`research/robust_pca/`) — `corruption_score` field in bundle metadata; flags adversarially-perturbed bundles.
262
+ - **Sequential & conformal-prediction** (`research/sequential/`, `research/conformal/`) — bench-side confidence bounds with documented coverage guarantees.
263
+ - **MMD distribution distance** (`research/mmd/`) — `axiom_distribution_mmd` field on bundles; surfaces when an attested bundle is structurally unlike its baseline corpus.
264
+ - **Spectral entropy** (`research/spectral_entropy/`) — axiom-graph entropy on every bundle, with confidence interval.
265
+ - **Bootstrap multiplier spike detection** (`research/bootstrap/`) — see [`docs/MULTIPLIER_BOOTSTRAP_SPIKE_FINDINGS.md`](docs/MULTIPLIER_BOOTSTRAP_SPIKE_FINDINGS.md).
266
+ - **SMT consistency checking** (`research/smt_consistency/`) — z3-backed `axiom_consistency_check` on every bundle.
267
+ - **Sheaf-Laplacian hallucination detection** — see [`docs/SHEAF_HALLUCINATION_DETECTOR.md`](docs/SHEAF_HALLUCINATION_DETECTOR.md) (research direction).
268
+
269
+ ### Other substrate-adjacent surfaces
270
+
271
+ - **Trust-root manifest** (`sum_engine_internal/trust_root/`) — operator-issued signed manifest binding kid lifecycle, revocation policy, and verifier expectations.
272
+ - **Merkle sidecar format** (`sum_engine_internal/merkle_sidecar/`) — see [`docs/MERKLE_SIDECAR_FORMAT.md`](docs/MERKLE_SIDECAR_FORMAT.md).
273
+ - **Evidence-chain layer** (`sum_engine_internal/evidence/`) — substrate behind `source_chain_hash` (T4).
274
+ - **Algorithm registry** — see [`docs/ALGORITHM_REGISTRY.md`](docs/ALGORITHM_REGISTRY.md) (the in-tree list of permitted signing algs; crypto-agility gate).
275
+ - **Audit log format** — every CLI operation can emit `sum.audit_log.v1` events; see [`docs/AUDIT_LOG_FORMAT.md`](docs/AUDIT_LOG_FORMAT.md).
276
+ - **Agent surface** (`sum_engine_internal/agent_surface/`) — see [`docs/AGENT_SURFACE_FINDINGS.md`](docs/AGENT_SURFACE_FINDINGS.md).
232
277
 
233
278
  ---
234
279
 
@@ -275,7 +320,7 @@ Source anchoring in the bundle schema, bundle explorer / viewer, `sum verify --e
275
320
 
276
321
  ```bash
277
322
  make install # editable install with sieve + dev extras
278
- make test # full pytest run (1000+ tests)
323
+ make test # full pytest run (2000+ tests)
279
324
  make xruntime # cross-runtime K1/K1-mw/K2/K3/K4 (Python ↔ Node)
280
325
  make xruntime-adversarial # rejection-matrix A1–A6
281
326
  make fortress # 21-check pure-math invariants
@@ -5,9 +5,15 @@
5
5
  [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
6
6
  [![Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
7
7
 
8
- > **A cross-runtime trust surface for LLM-rendered text.** Three runtimes (Python, Node, modern browsers) produce byte-identical Ed25519 signatures over the same JCS-canonical bytes. Every render through the hosted Worker carries a detached-JWS receipt (`sum.render_receipt.v1`) that any third party can verify offline against `/.well-known/jwks.json`. Live at https://sum-demo.ototao.workers.dev.
8
+ > **SUM lets people and agents transform knowledge without losing the ability to verify what changed, what stayed the same, who signed it, and what remains unproven.**
9
9
 
10
- That is the load-bearing claim and what makes SUM different from a generic summarisation tool. The cryptographic side is **mechanically proven**three independent verifier implementations agreeing byte-for-byte on every signed bundle, locked in CI on every PR. The semantic side (extraction quality, slider fact preservation) is **empirically measured** with explicit per-corpus numbers and explicit per-corpus boundaries; SUM does not blur the line between the two. [`docs/PROOF_BOUNDARY.md`](docs/PROOF_BOUNDARY.md) is the arbiter.
10
+ Every transformation extract triples from prose, render a tome at a controlled slider position, compose bundles across documents, share a render emits a cryptographically-signed receipt that any third party can verify offline. The receipt attests *that the transformation happened and what its inputs were*. Separate per-axis benchmarks attest *how much the transformation preserved meaning*. Both are kept honest by separate proof discipline — and the project never blurs the line between them.
11
+
12
+ *Live trust loop:* https://sum-demo.ototao.workers.dev — three runtimes (Python, Node, modern browsers) produce byte-identical Ed25519 signatures over the same JCS-canonical bytes; verify offline against `/.well-known/jwks.json`. Mechanically proven; locked in CI on every PR.
13
+
14
+ **Built for:** journalists working under deepfake-era citation requirements, academic survey writers who need provenance back to source PDFs, agentic-AI builders who need their agents to pass verifiable evidence and not just messages, and regulated-domain content (EU AI Act Article 12, FTC AI disclosure, HIPAA, SOC 2, PCI DSS) where "we say it's true" isn't enough.
15
+
16
+ The cryptographic side is **mechanically proven** — three independent verifier implementations agreeing byte-for-byte on every signed bundle, locked in CI on every PR. The semantic side (extraction quality, slider fact preservation) is **empirically measured** with explicit per-corpus numbers and explicit per-corpus boundaries. [`docs/PROOF_BOUNDARY.md`](docs/PROOF_BOUNDARY.md) is the arbiter.
11
17
 
12
18
  Headline supporting numbers (each links to its source of truth):
13
19
 
@@ -49,14 +55,29 @@ A minimal Node verifier using `jose` + `canonicalize` is in [`docs/RENDER_RECEIP
49
55
  | Surface | Status | Verifies |
50
56
  |---|---|---|
51
57
  | `pip install 'sum-engine[sieve]'` — `sum attest` / `sum verify` / `sum render` / `sum resolve` / `sum ledger` / `sum inspect` / `sum schema` | shipped on PyPI ≥ 0.4.1 | structural reconstruction; HMAC-SHA256 + Ed25519 signatures (W3C VC 2.0 `eddsa-jcs-2022`); bidirectional `sum attest` ↔ `sum render` symmetry from the shell |
52
- | Cloudflare Worker at `sum-demo.ototao.workers.dev` | shipped | `/api/render` → tome + `render_receipt`; `/.well-known/jwks.json` → JWKS; `/api/qid` → Wikidata resolver |
58
+ | Cloudflare Worker at `sum-demo.ototao.workers.dev` | shipped | `/api/render` → tome + `render_receipt`; `/api/transform` → generic transform-registry dispatch + `sum.transform_receipt.v1`; `/api/complete` → LLM proxy; `/api/qid` → Wikidata resolver; `/.well-known/jwks.json` + `/.well-known/revoked-kids.json` → trust-loop endpoints. Public LLM-axis routes are rate-limited per IP — see [`docs/PUBLIC_API_RATE_LIMITS.md`](docs/PUBLIC_API_RATE_LIMITS.md) (5/day operator-keyed demo; 100/hr with BYO key via `X-Render-LLM-Key-Anthropic` / `-OpenAI`). |
53
59
  | Single-file browser demo (`single_file_demo/index.html`) | shipped | paste prose → in-browser attest → CanonicalBundle JSON; same bytes verify under `node standalone_verifier/verify.js` (Chrome / Firefox / Safari with WebCrypto Ed25519 support) |
54
60
  | Cross-runtime trust triangle | locked by CI (`make xruntime`) | K1 / K1-mw / K2 / K3 / K4 — Python ↔ Node ↔ Browser agree byte-for-byte on valid bundles. `make xruntime-adversarial` adds A1–A6 rejection-class equivalence. |
55
- | 5-axis slider rendering surface | density actioned deterministically; length / formality / audience / perspective LLM-conditioned via the Worker (Anthropic, Cloudflare AI Gateway optional) | bench: median LLM-axis fact preservation 1.000, p10 0.769 (long, n=16) / 0.818 (short, n=8), order preservation 1.000 wherever measurable |
61
+ | 5-axis slider rendering surface | density actioned deterministically; length / formality / audience / perspective LLM-conditioned. Two dispatch paths: Worker `/api/render` (Anthropic + Cloudflare AI Gateway optional) producing `sum.render_receipt.v1`, OR Python `sum transform apply slider` (OpenAI via `OPENAI_API_KEY`) producing `sum.transform_receipt.v1` | bench: median LLM-axis fact preservation 1.000, p10 0.769 (long, n=16) / 0.818 (short, n=8), order preservation 1.000 wherever measurable. Tightening worktrail at [`docs/BENCH_HARDENING_FROM_QCVV.md`](docs/BENCH_HARDENING_FROM_QCVV.md) adds iteration-stability + DKW worst-case bounds + capability-region headlines |
56
62
  | MCP server (`sum-mcp` console script) | shipped | five tools (`extract` / `attest` / `verify` / `inspect` / `schema`) exposed over stdio; bundles attested via MCP verify byte-identically through the CLI / Node / browser verifiers |
63
+ | Transform substrate (`sum.transform_receipt.v1` + registry) | shipped (CLI in repo HEAD; PyPI catch-up tag pending) | `sum transform list` / `sum transform apply <name>` — three registered transforms (`slider` / `extract` / `compose`); receipts via Ed25519 / JCS / detached JWS just like render-receipts; 20-fixture cross-runtime K-matrix locks accept + reject across Python ↔ Node ↔ browser; T4 `source_chain_hash` binds receipts to source byte ranges; T5 `ShareableRender` round-trips signed renders for offline verification; T6 multi-school extract runs two extractors in tandem for adversarial-divergence detection. Wire spec at [`docs/TRANSFORM_RECEIPT_FORMAT.md`](docs/TRANSFORM_RECEIPT_FORMAT.md); design at [`docs/TRANSFORM_REGISTRY.md`](docs/TRANSFORM_REGISTRY.md). |
64
+ | Replay-defense window (`signed_at_out_of_window`) | shipped | opt-in `max_age_seconds` parameter across all four verifier surfaces (Python render / Python transform / JS render / JS transform). Default-off preserves archival use; receivers opt in per use-case (agent-swarm 60s, real-time 600s, newsletter 1d, legal-discovery no window). |
65
+ | `sum verify --explain` layered output | shipped | Per-dimension report (`sum.verify_explained.v1`): cryptographic integrity / canonical reconstruction / axiom consistency / extraction provenance / source evidence coverage / semantic preservation / truth of content. Each carries `epistemic_status` (`provable` / `certified` / `empirical-benchmark` / `not-asserted`). Truth of content is ALWAYS `not_asserted` — locked by test. |
66
+ | Negative-control corpus (T5 of bench-hardening) | shipped | 20 hand-authored documents across 5 failure modes (ambiguous coref / predicate-alias / contradictions / entity-resolution-adversarial / non-extractable). Runner exits 1 if observed failures don't match annotations. Baseline at [`fixtures/bench_receipts/negative_control_2026-05-17.json`](fixtures/bench_receipts/negative_control_2026-05-17.json). |
67
+ | Compliance validators (six regimes) | shipped | `sum compliance check --regime <id> --audit-log <path>` — EU AI Act Article 12, GDPR Article 30, HIPAA § 164.312(b), ISO/IEC 27001 A.8.15, SOC 2 CC 7.2, PCI DSS v4.0 Req 10. All six produce the same `sum.compliance_report.v1` schema; per-regime docs at `docs/COMPLIANCE_*.md`. |
57
68
 
58
69
  The slider's product claim — *axis changes do not lose facts* — is the load-bearing empirical result. It is verified by NLI audit on every embedding-flagged "loss" cell; full attribution in [`docs/SLIDER_CONTRACT.md`](docs/SLIDER_CONTRACT.md).
59
70
 
71
+ ## Strategic context
72
+
73
+ The operational compass — read in this order if you want the project's intent + how it operates + where it's going:
74
+
75
+ - [`docs/CHARTER_2026-05-17.md`](docs/CHARTER_2026-05-17.md) — intent, the Why, strategy, objectives, success criteria, constraints, and the operational loop. The compass every other doc resolves to.
76
+ - [`docs/PRODUCT_DELIBERATION_2026-05-14.md`](docs/PRODUCT_DELIBERATION_2026-05-14.md) — three-option strategic analysis + grant-outcome decision tree.
77
+ - [`docs/ZENITH_FRAMING_2026-05-16.md`](docs/ZENITH_FRAMING_2026-05-16.md) — destination framing (SUM as chain-of-custody for AI-transformed knowledge) plus three new concepts (Perspective Receipts, Trust Profiles, Epistemic Nutrition Label) on the design queue.
78
+ - [`docs/BENCH_HARDENING_FROM_QCVV.md`](docs/BENCH_HARDENING_FROM_QCVV.md) — five-task empirical-benchmark hardening plan (T1–T5; T5 shipped, T1–T4 queued).
79
+ - [`docs/DOGFOOD_QUICKSTART.md`](docs/DOGFOOD_QUICKSTART.md) — five-minute guide to running SUM on your own writing.
80
+
60
81
  ### LLM narrative round-trip — closed across measured corpora (2026-04-28)
61
82
 
62
83
  The hardest measurement in `PROOF_BOUNDARY.md` is the full LLM narrative round-trip (`text → LLM-extract → axioms → LLM-generate → prose' → LLM-extract → axioms'`). The unprompted-pipeline baseline on `seed_v1` was **drift = 107.75% / exact-match recall = 0.12** — facts preserved, keys not.
@@ -104,7 +125,7 @@ The reverse direction also runs under explicit slider control. The local path ac
104
125
  sum render --density 0.5 < bundle.json
105
126
  # → keeps the lex-prefix half of the axioms; @sliders header records what was requested
106
127
 
107
- sum render --length 0.9 --use-worker https://sum.ototao.com --json < bundle.json
128
+ sum render --length 0.9 --use-worker https://sum-demo.ototao.workers.dev --json < bundle.json
108
129
  # → LLM-conditioned tome + signed render_receipt (sum.render_receipt.v1) on stdout
109
130
  ```
110
131
 
@@ -131,7 +152,7 @@ pip install 'sum-engine[mcp,sieve]'
131
152
 
132
153
  ### Calling SUM over HTTP
133
154
 
134
- The hosted Worker at `https://sum.ototao.com` exposes `/api/render`, `/api/complete`, `/api/qid`, and the `/.well-known/{jwks,revoked-kids}.json` verification surfaces. [`docs/API_REFERENCE.md`](docs/API_REFERENCE.md) is the wire spec — request/response shapes, error codes, the six-step receipt-verification flow, working Node + Python examples. Use this when the caller is a web app, mobile app, or server-side service; use the MCP server when the caller is a local LLM client.
155
+ The hosted Worker at `https://sum-demo.ototao.workers.dev` exposes `/api/render`, `/api/complete`, `/api/qid`, and the `/.well-known/{jwks,revoked-kids}.json` verification surfaces. [`docs/API_REFERENCE.md`](docs/API_REFERENCE.md) is the wire spec — request/response shapes, error codes, the six-step receipt-verification flow, working Node + Python examples. Use this when the caller is a web app, mobile app, or server-side service; use the MCP server when the caller is a local LLM client.
135
156
 
136
157
  ---
137
158
 
@@ -167,7 +188,29 @@ Below the slider sits the substrate that earlier phases shipped and verified. Po
167
188
  - **Bundle public-key attestation (provable).** Ed25519-signed CanonicalBundles are tamper-detectable by any third party in any of the three runtimes. [`docs/PROOF_BOUNDARY.md`](docs/PROOF_BOUNDARY.md) §1.3.1.
168
189
  - **Merkle hash-chain integrity (provable, including under concurrent writers).** [`docs/PROOF_BOUNDARY.md`](docs/PROOF_BOUNDARY.md) §1.7.
169
190
  - **Extraction F1 (empirical-benchmark).** 1.000 on `seed_v1` (50 simple-SVO docs); 0.762 with precision 1.000 on `seed_v2` (20-doc difficulty corpus). Every remaining `seed_v2` failure is a recall miss, not a truth inversion. [`docs/PROOF_BOUNDARY.md`](docs/PROOF_BOUNDARY.md) §2.1.
170
- - **103 numbered features**, each with a reproducible verification command, in [`docs/FEATURE_CATALOG.md`](docs/FEATURE_CATALOG.md).
191
+ - **168 numbered features**, each with a reproducible verification command, in [`docs/FEATURE_CATALOG.md`](docs/FEATURE_CATALOG.md).
192
+
193
+ ### Research substrate (under `sum_engine_internal/research/`)
194
+
195
+ Less-surfaced but shipped:
196
+
197
+ - **MinHash-LSH bundle similarity index** (`research/lsh/`) — near-duplicate bundle detection at scale.
198
+ - **Robust PCA corruption score** (`research/robust_pca/`) — `corruption_score` field in bundle metadata; flags adversarially-perturbed bundles.
199
+ - **Sequential & conformal-prediction** (`research/sequential/`, `research/conformal/`) — bench-side confidence bounds with documented coverage guarantees.
200
+ - **MMD distribution distance** (`research/mmd/`) — `axiom_distribution_mmd` field on bundles; surfaces when an attested bundle is structurally unlike its baseline corpus.
201
+ - **Spectral entropy** (`research/spectral_entropy/`) — axiom-graph entropy on every bundle, with confidence interval.
202
+ - **Bootstrap multiplier spike detection** (`research/bootstrap/`) — see [`docs/MULTIPLIER_BOOTSTRAP_SPIKE_FINDINGS.md`](docs/MULTIPLIER_BOOTSTRAP_SPIKE_FINDINGS.md).
203
+ - **SMT consistency checking** (`research/smt_consistency/`) — z3-backed `axiom_consistency_check` on every bundle.
204
+ - **Sheaf-Laplacian hallucination detection** — see [`docs/SHEAF_HALLUCINATION_DETECTOR.md`](docs/SHEAF_HALLUCINATION_DETECTOR.md) (research direction).
205
+
206
+ ### Other substrate-adjacent surfaces
207
+
208
+ - **Trust-root manifest** (`sum_engine_internal/trust_root/`) — operator-issued signed manifest binding kid lifecycle, revocation policy, and verifier expectations.
209
+ - **Merkle sidecar format** (`sum_engine_internal/merkle_sidecar/`) — see [`docs/MERKLE_SIDECAR_FORMAT.md`](docs/MERKLE_SIDECAR_FORMAT.md).
210
+ - **Evidence-chain layer** (`sum_engine_internal/evidence/`) — substrate behind `source_chain_hash` (T4).
211
+ - **Algorithm registry** — see [`docs/ALGORITHM_REGISTRY.md`](docs/ALGORITHM_REGISTRY.md) (the in-tree list of permitted signing algs; crypto-agility gate).
212
+ - **Audit log format** — every CLI operation can emit `sum.audit_log.v1` events; see [`docs/AUDIT_LOG_FORMAT.md`](docs/AUDIT_LOG_FORMAT.md).
213
+ - **Agent surface** (`sum_engine_internal/agent_surface/`) — see [`docs/AGENT_SURFACE_FINDINGS.md`](docs/AGENT_SURFACE_FINDINGS.md).
171
214
 
172
215
  ---
173
216
 
@@ -214,7 +257,7 @@ Source anchoring in the bundle schema, bundle explorer / viewer, `sum verify --e
214
257
 
215
258
  ```bash
216
259
  make install # editable install with sieve + dev extras
217
- make test # full pytest run (1000+ tests)
260
+ make test # full pytest run (2000+ tests)
218
261
  make xruntime # cross-runtime K1/K1-mw/K2/K3/K4 (Python ↔ Node)
219
262
  make xruntime-adversarial # rejection-matrix A1–A6
220
263
  make fortress # 21-check pure-math invariants
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "sum-engine"
7
- version = "0.5.0"
7
+ version = "0.7.0"
8
8
  description = "SUM — bidirectional knowledge distillation with optional cryptographic attestation. Pipe prose, get a CanonicalBundle (HMAC / Ed25519 / W3C VC 2.0), verify anywhere."
9
9
  readme = "README.md"
10
10
  license = { text = "Apache-2.0" }
@@ -39,10 +39,19 @@ dependencies = [
39
39
  [project.optional-dependencies]
40
40
  # Dependency-injection extras. Users pick the extractor they want:
41
41
  # pip install sum-engine[sieve] # deterministic, offline spaCy path
42
- # pip install sum-engine[llm] # OpenAI structured-output path
43
- # pip install sum-engine[all] # both, plus dev tooling
42
+ # pip install sum-engine[openai] # OpenAI structured-output path
43
+ # pip install sum-engine[llm] # alias for [openai] (legacy name)
44
+ # pip install sum-engine[all] # everything, plus dev tooling
44
45
  sieve = ["spacy>=3.7.0"]
45
- llm = ["openai>=1.40.0,<3.0.0", "pydantic>=2.0.0"]
46
+ # `[openai]` is the canonical, vendor-named extra; `[llm]` is kept as a
47
+ # back-compat alias because it predates the multi-provider dispatcher
48
+ # (Anthropic and OpenAI now have their own named extras). Both install
49
+ # identical dependencies — the openai SDK plus pydantic for structured
50
+ # outputs. The vendor adapter is at
51
+ # sum_engine_internal/ensemble/llm_dispatch.py::OpenAIAdapter; the
52
+ # render-path TS companion is worker/src/routes/render.ts::callOpenAI.
53
+ openai = ["openai>=1.40.0,<3.0.0", "pydantic>=2.0.0"]
54
+ llm = ["sum-engine[openai]"]
46
55
  # Anthropic Messages-API adapter (Claude family). Installed alongside
47
56
  # [llm] for the §2.5 frontier-LLM benchmark runs that compare
48
57
  # generator-side interventions across providers. The runner picks
@@ -107,7 +116,7 @@ dev = [
107
116
  ]
108
117
  all = [
109
118
  "sum-engine[sieve]",
110
- "sum-engine[llm]",
119
+ "sum-engine[openai]",
111
120
  "sum-engine[anthropic]",
112
121
  "sum-engine[receipt-verify]",
113
122
  "sum-engine[mcp]",
@@ -0,0 +1,171 @@
1
+ """sum_cli.audit_log — universal audit-log streaming for compliance.
2
+
3
+ When the ``SUM_AUDIT_LOG`` environment variable is set to a file path,
4
+ every ``sum attest`` / ``sum verify`` / ``sum render`` operation
5
+ appends a single JSONL row to that file describing what was done.
6
+
7
+ This is the regime-agnostic foundation of the compliance primitives
8
+ direction (Path 3). A specific regime (GDPR-Art-30, HIPAA-164.514,
9
+ EU AI Act Annex IV, etc.) can be implemented as a downstream
10
+ consumer of this audit log: tail the file, validate per-regime
11
+ required fields, raise on policy violation. The audit log itself
12
+ makes no regime-specific assumptions — it records *what happened*
13
+ verbatim so any auditor can reconstruct the operation.
14
+
15
+ Schema: ``sum.audit_log.v1`` — additive; new optional fields may
16
+ appear in future minor versions; consumers should ignore unknown
17
+ keys.
18
+
19
+ Required fields per row:
20
+ - ``schema`` = ``"sum.audit_log.v1"``
21
+ - ``timestamp`` (ISO 8601 UTC, e.g. ``"2026-05-01T18:35:14.123Z"``)
22
+ - ``operation`` ∈ ``{"attest", "verify", "render"}``
23
+ - ``cli_version`` (the ``sum-cli`` version that produced the row)
24
+
25
+ Operation-specific optional fields:
26
+ - attest: ``source_uri``, ``state_integer_digits``, ``axiom_count``,
27
+ ``extractor``, ``signed`` (bool — Ed25519 attached?),
28
+ ``hmac`` (bool), ``branch``
29
+ - verify: ``state_integer_digits``, ``axiom_count``, ``signatures``
30
+ ``{ed25519, hmac}``, ``branch``, ``ok`` (bool)
31
+ - render: ``axiom_count_input``, ``mode`` (``"local-deterministic"``
32
+ or ``"worker"``), ``sliders``, ``render_receipt_kid`` (if
33
+ worker), ``worker_url`` (if worker)
34
+
35
+ Failures (exit code != 0) emit a row with ``error`` field describing
36
+ the failure class. Audit-log writes themselves never fail loudly —
37
+ if ``SUM_AUDIT_LOG`` points at a non-writable path, the operation
38
+ proceeds and the failure is reported on stderr only when ``--verbose``
39
+ is set; the audit semantics fail-open by design (a non-functional
40
+ audit destination should not break the trust loop).
41
+
42
+ Env var precedence:
43
+ 1. ``SUM_AUDIT_LOG`` env var (path to JSONL file; appended to)
44
+ 2. unset → no audit logging
45
+
46
+ The path may be ``-`` for stdout (rare; mostly useful for piping
47
+ into another tool); otherwise treated as a file path with append-mode
48
+ open.
49
+
50
+ Concurrency: writes are O_APPEND on POSIX, so multiple sum
51
+ processes writing to the same audit log produce a serialised
52
+ ordering (atomic per write() up to PIPE_BUF on most systems —
53
+ single-line JSONL records well under that bound). We write each
54
+ row in one ``f.write()`` call to maximise atomicity.
55
+ """
56
+ from __future__ import annotations
57
+
58
+ import json
59
+ import os
60
+ import sys
61
+ from datetime import datetime, timezone
62
+ from typing import Any
63
+
64
+
65
+ _AUDIT_LOG_SCHEMA = "sum.audit_log.v1"
66
+
67
+
68
+ def _audit_log_path() -> str | None:
69
+ """Return the configured audit-log destination, or None if unset."""
70
+ p = os.environ.get("SUM_AUDIT_LOG")
71
+ if p is None or p == "":
72
+ return None
73
+ return p
74
+
75
+
76
+ def _identity_fields() -> dict[str, Any]:
77
+ """Optional identity fields populated from env vars.
78
+
79
+ Sprint 4 of the intensification path to arXiv (PR #140). Closes
80
+ the PCI DSS Req 10.2.2 user-identification gap named in
81
+ ``docs/COMPLIANCE_PCI_DSS_4_REQ_10.md``. Three env vars are
82
+ consulted; each populated value becomes an optional field on
83
+ the audit-log row:
84
+
85
+ - ``SUM_AUDIT_USER_ID`` → ``user_id`` field. Per PCI Req 10.2.2,
86
+ "user identification" is the FIRST required field for each
87
+ audit-log event. Operators running SUM behind an
88
+ authenticating proxy populate this from the proxy's session
89
+ identity at process start.
90
+ - ``SUM_AUDIT_HOST_ID`` → ``host_id`` field. Multi-host
91
+ deployments (clusters, k8s pods, container fleets) use this
92
+ to attribute events to specific compute units.
93
+ - ``SUM_AUDIT_IP_ADDRESS`` → ``ip_address`` field. Network-
94
+ layer origination, useful for incident-response / forensic
95
+ analysis under PCI Req 10.2.2's "origination of event"
96
+ requirement.
97
+
98
+ All three are *optional*. An unset env var produces an absent
99
+ field (not a null value). The audit-log schema stays at
100
+ ``sum.audit_log.v1``; these are additive optional fields under
101
+ the existing schema's "consumers should ignore unknown keys"
102
+ convention. Backward compat: rows without these fields still
103
+ pass every existing validator.
104
+
105
+ PCI DSS validator R7 (``pci-dss-4-req-10.user-identification-
106
+ recommended``, added in the same PR as this function) treats
107
+ a missing ``user_id`` as a Req 10.2.2 violation in compliance-
108
+ mode runs.
109
+ """
110
+ out: dict[str, Any] = {}
111
+ for env_var, field in (
112
+ ("SUM_AUDIT_USER_ID", "user_id"),
113
+ ("SUM_AUDIT_HOST_ID", "host_id"),
114
+ ("SUM_AUDIT_IP_ADDRESS", "ip_address"),
115
+ ):
116
+ value = os.environ.get(env_var)
117
+ if value: # non-empty (skips both None and empty string)
118
+ out[field] = value
119
+ return out
120
+
121
+
122
+ def emit_audit_event(operation: str, payload: dict[str, Any]) -> None:
123
+ """Append a single JSONL row to the audit log if configured.
124
+
125
+ Fail-open: if the audit destination is unwritable, the operation
126
+ proceeds normally; the failure is silent unless verbose stderr
127
+ is enabled by the caller. Audit logging is *advisory* — the
128
+ canonical bundle / receipt still carries the load-bearing trust
129
+ properties; the audit log is for downstream compliance tools
130
+ to ingest.
131
+
132
+ Identity fields (``user_id`` / ``host_id`` / ``ip_address``) are
133
+ populated from env vars by :func:`_identity_fields`. They appear
134
+ on the row only when the corresponding env var is set; absent
135
+ env vars produce absent fields (not null values). The
136
+ ``payload`` argument takes precedence over identity fields if
137
+ a caller passes overlapping keys — useful for tests that want
138
+ to pin specific identity values without touching the
139
+ environment.
140
+ """
141
+ path = _audit_log_path()
142
+ if path is None:
143
+ return
144
+
145
+ from sum_cli import __version__
146
+
147
+ row = {
148
+ "schema": _AUDIT_LOG_SCHEMA,
149
+ "timestamp": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.")
150
+ + f"{datetime.now(timezone.utc).microsecond // 1000:03d}Z",
151
+ "operation": operation,
152
+ "cli_version": __version__,
153
+ # Identity fields from env, then payload last so the caller
154
+ # wins on overlap (intentional for test seams).
155
+ **_identity_fields(),
156
+ **payload,
157
+ }
158
+ line = json.dumps(row, separators=(",", ":")) + "\n"
159
+
160
+ try:
161
+ if path == "-":
162
+ sys.stdout.write(line)
163
+ sys.stdout.flush()
164
+ else:
165
+ with open(path, "a", encoding="utf-8") as f:
166
+ f.write(line)
167
+ except OSError:
168
+ # Fail-open: audit destination unavailable; do not block
169
+ # the operation. The canonical bundle / receipt remains the
170
+ # load-bearing trust artifact.
171
+ pass