epistemic-ledger 0.12.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.
- epistemic_ledger-0.12.0/LICENSE +21 -0
- epistemic_ledger-0.12.0/PKG-INFO +120 -0
- epistemic_ledger-0.12.0/README-PyPI.md +79 -0
- epistemic_ledger-0.12.0/README.md +119 -0
- epistemic_ledger-0.12.0/pyproject.toml +117 -0
- epistemic_ledger-0.12.0/setup.cfg +4 -0
- epistemic_ledger-0.12.0/src/epistemic_ledger/__init__.py +55 -0
- epistemic_ledger-0.12.0/src/epistemic_ledger/__main__.py +6 -0
- epistemic_ledger-0.12.0/src/epistemic_ledger/cli.py +115 -0
- epistemic_ledger-0.12.0/src/epistemic_ledger/consolidation.py +317 -0
- epistemic_ledger-0.12.0/src/epistemic_ledger/ed25519.py +144 -0
- epistemic_ledger-0.12.0/src/epistemic_ledger/elicit.py +67 -0
- epistemic_ledger-0.12.0/src/epistemic_ledger/ledger.py +2134 -0
- epistemic_ledger-0.12.0/src/epistemic_ledger/policies.py +62 -0
- epistemic_ledger-0.12.0/src/epistemic_ledger/py.typed +0 -0
- epistemic_ledger-0.12.0/src/epistemic_ledger.egg-info/PKG-INFO +120 -0
- epistemic_ledger-0.12.0/src/epistemic_ledger.egg-info/SOURCES.txt +25 -0
- epistemic_ledger-0.12.0/src/epistemic_ledger.egg-info/dependency_links.txt +1 -0
- epistemic_ledger-0.12.0/src/epistemic_ledger.egg-info/entry_points.txt +2 -0
- epistemic_ledger-0.12.0/src/epistemic_ledger.egg-info/requires.txt +14 -0
- epistemic_ledger-0.12.0/src/epistemic_ledger.egg-info/top_level.txt +1 -0
- epistemic_ledger-0.12.0/tests/test_cli.py +44 -0
- epistemic_ledger-0.12.0/tests/test_error_paths.py +81 -0
- epistemic_ledger-0.12.0/tests/test_ledger.py +1187 -0
- epistemic_ledger-0.12.0/tests/test_newsroom.py +52 -0
- epistemic_ledger-0.12.0/tests/test_properties.py +85 -0
- epistemic_ledger-0.12.0/tests/test_scoring_units.py +47 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Axiovex Systems, 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,120 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: epistemic-ledger
|
|
3
|
+
Version: 0.12.0
|
|
4
|
+
Summary: A living epistemic ledger: append-only conclusions with fluid certainty scores, revised as new facts arrive.
|
|
5
|
+
Author: Axiovex Systems, LLC
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/AXIOVEX/epistemic-ledger
|
|
8
|
+
Project-URL: Documentation, https://epistemic-ledger.readthedocs.io/
|
|
9
|
+
Project-URL: Repository, https://github.com/AXIOVEX/epistemic-ledger
|
|
10
|
+
Project-URL: Issues, https://github.com/AXIOVEX/epistemic-ledger/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/AXIOVEX/epistemic-ledger/blob/main/CHANGELOG.md
|
|
12
|
+
Keywords: epistemology,belief-revision,bitemporal,event-sourcing,truth-maintenance,agent-memory,knowledge-graph
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Intended Audience :: Science/Research
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
23
|
+
Classifier: Topic :: Database
|
|
24
|
+
Classifier: Typing :: Typed
|
|
25
|
+
Requires-Python: >=3.10
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
30
|
+
Requires-Dist: pytest-cov>=5; extra == "dev"
|
|
31
|
+
Requires-Dist: hypothesis>=6; extra == "dev"
|
|
32
|
+
Requires-Dist: ruff>=0.6; extra == "dev"
|
|
33
|
+
Requires-Dist: mypy>=1.11; extra == "dev"
|
|
34
|
+
Requires-Dist: build>=1.2; extra == "dev"
|
|
35
|
+
Requires-Dist: twine>=5; extra == "dev"
|
|
36
|
+
Provides-Extra: docs
|
|
37
|
+
Requires-Dist: mkdocs>=1.6; extra == "docs"
|
|
38
|
+
Requires-Dist: mkdocs-material>=9.5; extra == "docs"
|
|
39
|
+
Requires-Dist: mkdocstrings[python]>=0.26; extra == "docs"
|
|
40
|
+
Dynamic: license-file
|
|
41
|
+
|
|
42
|
+
# Epistemic Ledger
|
|
43
|
+
|
|
44
|
+
A living epistemic ledger: an append-only database where every
|
|
45
|
+
conclusion carries a fluid certainty score, and new facts automatically
|
|
46
|
+
trigger re-evaluation of the conclusions — and their dependents — that
|
|
47
|
+
they affect, instead of any judgment ever being final.
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install epistemic-ledger
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
from epistemic_ledger import Ledger
|
|
55
|
+
|
|
56
|
+
ledger = Ledger("my-ledger")
|
|
57
|
+
claim = ledger.assert_claim("the bridge design is safe", 0.60)
|
|
58
|
+
fact = ledger.ingest_evidence("load test passed", 0.90)["fact_id"]
|
|
59
|
+
ledger.add_support(claim, fact, "evidential", p_given=0.95, p_given_not=0.30)
|
|
60
|
+
print(ledger.get_score(claim)) # the score moved; the history kept both
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## The four properties
|
|
64
|
+
|
|
65
|
+
1. **Append-only records.** Conclusions are never changed or deleted.
|
|
66
|
+
A correction is a new record that supersedes the old one; the full
|
|
67
|
+
history of what was believed, and when, stays queryable.
|
|
68
|
+
2. **Fluid certainty scores.** Every conclusion carries a score that
|
|
69
|
+
moves as evidence accumulates — today's result is tomorrow's
|
|
70
|
+
starting point — instead of a one-time yes-or-no verdict.
|
|
71
|
+
3. **Dependency-tracked revisits.** Each conclusion records *why* it
|
|
72
|
+
is held. When a new fact arrives, the change spreads along the
|
|
73
|
+
dependency graph and re-evaluates exactly the conclusions it
|
|
74
|
+
touches, plus their dependents.
|
|
75
|
+
4. **A trigger discipline.** Not every new fact warrants a revisit.
|
|
76
|
+
A layered rule — dirty-flagging, precise invalidation, then a
|
|
77
|
+
materiality threshold — decides when recomputation is required.
|
|
78
|
+
|
|
79
|
+
## What is inside
|
|
80
|
+
|
|
81
|
+
- An event-sourced, bitemporal store (append-only JSONL event log as
|
|
82
|
+
the write model, SQLite bitemporal tables as the read model).
|
|
83
|
+
- A revisit loop using Jeffrey conditionalization for uncertain
|
|
84
|
+
evidence, with an early cutoff and materiality flags.
|
|
85
|
+
- Joint likelihoods (noisy-AND / noisy-OR), Dempster–Shafer belief
|
|
86
|
+
intervals where ignorance must be explicit, and automatic
|
|
87
|
+
contradiction detection with entrenchment-ordered resolution.
|
|
88
|
+
- Governance: writer trust tiers, signed verdicts (Ed25519), named
|
|
89
|
+
graph authority ceilings, and predicate policies — all stored as
|
|
90
|
+
bitemporal facts in the ledger they govern.
|
|
91
|
+
- A hardened single-writer store with replay verification
|
|
92
|
+
(`epistemic-ledger verify <dir>`).
|
|
93
|
+
- The five kill criteria the design set for itself, instrumented from
|
|
94
|
+
day one (`epistemic-ledger kill-metrics <dir>`).
|
|
95
|
+
- An offline LLM consolidation pass and caller-owned abstention
|
|
96
|
+
policies.
|
|
97
|
+
|
|
98
|
+
Standard library only. No dependencies, no network at runtime.
|
|
99
|
+
|
|
100
|
+
## Command line
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
epistemic-ledger demo # end-to-end scenario
|
|
104
|
+
epistemic-ledger verify path/to/ledger # integrity check
|
|
105
|
+
epistemic-ledger kill-metrics path/to/ledger
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Documentation
|
|
109
|
+
|
|
110
|
+
Full documentation — the framing paper, the design memos, the measured
|
|
111
|
+
results, and the API reference — is at
|
|
112
|
+
https://epistemic-ledger.readthedocs.io/ and in the GitHub repository:
|
|
113
|
+
https://github.com/AXIOVEX/epistemic-ledger
|
|
114
|
+
|
|
115
|
+
## License
|
|
116
|
+
|
|
117
|
+
The code is under the MIT License (see `LICENSE` in the repository).
|
|
118
|
+
The framing paper, design memos, and research documents in `docs/`
|
|
119
|
+
remain all rights reserved, © 2026 Axiovex Systems, LLC (see
|
|
120
|
+
`LICENSE-DOCS.txt` in the repository).
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Epistemic Ledger
|
|
2
|
+
|
|
3
|
+
A living epistemic ledger: an append-only database where every
|
|
4
|
+
conclusion carries a fluid certainty score, and new facts automatically
|
|
5
|
+
trigger re-evaluation of the conclusions — and their dependents — that
|
|
6
|
+
they affect, instead of any judgment ever being final.
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
pip install epistemic-ledger
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
```python
|
|
13
|
+
from epistemic_ledger import Ledger
|
|
14
|
+
|
|
15
|
+
ledger = Ledger("my-ledger")
|
|
16
|
+
claim = ledger.assert_claim("the bridge design is safe", 0.60)
|
|
17
|
+
fact = ledger.ingest_evidence("load test passed", 0.90)["fact_id"]
|
|
18
|
+
ledger.add_support(claim, fact, "evidential", p_given=0.95, p_given_not=0.30)
|
|
19
|
+
print(ledger.get_score(claim)) # the score moved; the history kept both
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## The four properties
|
|
23
|
+
|
|
24
|
+
1. **Append-only records.** Conclusions are never changed or deleted.
|
|
25
|
+
A correction is a new record that supersedes the old one; the full
|
|
26
|
+
history of what was believed, and when, stays queryable.
|
|
27
|
+
2. **Fluid certainty scores.** Every conclusion carries a score that
|
|
28
|
+
moves as evidence accumulates — today's result is tomorrow's
|
|
29
|
+
starting point — instead of a one-time yes-or-no verdict.
|
|
30
|
+
3. **Dependency-tracked revisits.** Each conclusion records *why* it
|
|
31
|
+
is held. When a new fact arrives, the change spreads along the
|
|
32
|
+
dependency graph and re-evaluates exactly the conclusions it
|
|
33
|
+
touches, plus their dependents.
|
|
34
|
+
4. **A trigger discipline.** Not every new fact warrants a revisit.
|
|
35
|
+
A layered rule — dirty-flagging, precise invalidation, then a
|
|
36
|
+
materiality threshold — decides when recomputation is required.
|
|
37
|
+
|
|
38
|
+
## What is inside
|
|
39
|
+
|
|
40
|
+
- An event-sourced, bitemporal store (append-only JSONL event log as
|
|
41
|
+
the write model, SQLite bitemporal tables as the read model).
|
|
42
|
+
- A revisit loop using Jeffrey conditionalization for uncertain
|
|
43
|
+
evidence, with an early cutoff and materiality flags.
|
|
44
|
+
- Joint likelihoods (noisy-AND / noisy-OR), Dempster–Shafer belief
|
|
45
|
+
intervals where ignorance must be explicit, and automatic
|
|
46
|
+
contradiction detection with entrenchment-ordered resolution.
|
|
47
|
+
- Governance: writer trust tiers, signed verdicts (Ed25519), named
|
|
48
|
+
graph authority ceilings, and predicate policies — all stored as
|
|
49
|
+
bitemporal facts in the ledger they govern.
|
|
50
|
+
- A hardened single-writer store with replay verification
|
|
51
|
+
(`epistemic-ledger verify <dir>`).
|
|
52
|
+
- The five kill criteria the design set for itself, instrumented from
|
|
53
|
+
day one (`epistemic-ledger kill-metrics <dir>`).
|
|
54
|
+
- An offline LLM consolidation pass and caller-owned abstention
|
|
55
|
+
policies.
|
|
56
|
+
|
|
57
|
+
Standard library only. No dependencies, no network at runtime.
|
|
58
|
+
|
|
59
|
+
## Command line
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
epistemic-ledger demo # end-to-end scenario
|
|
63
|
+
epistemic-ledger verify path/to/ledger # integrity check
|
|
64
|
+
epistemic-ledger kill-metrics path/to/ledger
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Documentation
|
|
68
|
+
|
|
69
|
+
Full documentation — the framing paper, the design memos, the measured
|
|
70
|
+
results, and the API reference — is at
|
|
71
|
+
https://epistemic-ledger.readthedocs.io/ and in the GitHub repository:
|
|
72
|
+
https://github.com/AXIOVEX/epistemic-ledger
|
|
73
|
+
|
|
74
|
+
## License
|
|
75
|
+
|
|
76
|
+
The code is under the MIT License (see `LICENSE` in the repository).
|
|
77
|
+
The framing paper, design memos, and research documents in `docs/`
|
|
78
|
+
remain all rights reserved, © 2026 Axiovex Systems, LLC (see
|
|
79
|
+
`LICENSE-DOCS.txt` in the repository).
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Epistemic Ledger
|
|
2
|
+
|
|
3
|
+
[](https://github.com/AXIOVEX/epistemic-ledger/actions/workflows/ci.yml)
|
|
4
|
+
[](https://codecov.io/gh/AXIOVEX/epistemic-ledger)
|
|
5
|
+
[](https://pypi.org/project/epistemic-ledger/)
|
|
6
|
+
[](https://epistemic-ledger.readthedocs.io/)
|
|
7
|
+
[](https://pypi.org/project/epistemic-ledger/)
|
|
8
|
+
|
|
9
|
+
> A living epistemic scoring system where every conclusion lives in an append-only database with a fluid certainty score, and new facts automatically trigger re-evaluation of the conclusions — and their dependents — that they affect, instead of any judgment ever being final.
|
|
10
|
+
|
|
11
|
+
Databases are deeply flawed: there is no built-in way to keep challenging the data, to know how true any of it is, or to update it as the evidence comes in. The epistemic ledger is an attempt to fix that — an append-only epistemic database over which an active feedback loop runs, so records are never destroyed but certainty stays fluid, and the system corrects itself, including its previously built structure.
|
|
12
|
+
|
|
13
|
+
## Status
|
|
14
|
+
|
|
15
|
+
**Implemented and validated** (v0.11.1, 2026-10-09). The framing below became a working prototype: an event-sourced, bitemporal ledger with a dependency-propagated revisit loop, learned entrenchment, Dempster-Shafer intervals, joint likelihoods, contradiction detection and resolution, governance (writer tiers, signed verdicts, escalation, named-graph authority ceilings, predicate policies), an offline LLM consolidation pass, and a hardened single-writer store with integrity verification. See [`docs/PAPER.md`](docs/PAPER.md) for the framing paper, `docs/DESIGN-*.md` for the design memos, and `docs/research/` for the raw research notes with provenance.
|
|
16
|
+
|
|
17
|
+
Measured results so far, each with its own report in `docs/`:
|
|
18
|
+
|
|
19
|
+
- **Revision value** (CONTEXT-CLEANUP-01, REPO-HISTORY-VALIDATION): the revisit loop eliminates 70.6% of naive staleness errors on dependency chains, 62.8% with joint likelihoods, 81.0% on this repository's own git history.
|
|
20
|
+
- **Trigger discipline** (TRIGGER-STRESS-01): epsilon 0.005 balances recall 0.96 / precision 0.72; the cutoff earns its keep.
|
|
21
|
+
- **Adversarial newsroom** (NEWSROOM-01, LOCAL-EXTRACTION-01): against adversarial sources the ledger eliminates 20.8% (modeled extraction) to 22.2% (real LLM extraction, local Qwen3-8B, $0) of a frozen baseline's errors — 51-61% on derived claims.
|
|
22
|
+
- **Free prose** (FREETEXT-01): on authored non-template text the advantage thins to 16.8% / 43.5% derived and becomes seed-dependent; the report states the sensitivity plainly.
|
|
23
|
+
- **Independent prose** (INDIE-CORPUS-01): on text authored by a different model family (GPT-4.1), the advantage reproduces at 21.1% / 49.7% derived with a different failure anatomy — the authorship caveat is retired.
|
|
24
|
+
- **Kill bars** (KILL-BARS-01): every gate threshold re-measured across all workload families; two adjusted under a pre-stated rule, one held at its definitional value on the record.
|
|
25
|
+
- **LLM consolidation** (CONSOLIDATION-01, LOCAL-CONSOLIDATION-01): the offline pass matches frontier-model precision/recall locally at $0 — in its thinking configuration; the no-thinking configuration fails, measurably.
|
|
26
|
+
- **Churn and calibration** (CHURN-01, CALIBRATION-01): conflict-normalized material churn gates at 8; a proposed agent-tempering fix was tested and *refuted* — reported as a negative.
|
|
27
|
+
- **Override loop** (OVERRIDE-CAL-01): v0.11.1 makes manual scores propagate through the revisit loop (they previously updated one claim and stopped); scripted-reviewer personas put the override-rate bar on a measurement for the first time (observed 0.020-0.035 vs the 0.20 bar). Human-reviewer calibration remains the honest residual.
|
|
28
|
+
- **Real published copy** (REALWIRE-01): on verbatim sentences from the published record, extraction accuracy collapses to 0.481 — the local extractor answers "is this true?" instead of "what does this sentence say" — while the bookkeeping edge survives, compressed (4.1% facts / 17.6% derived, vs 21.1% / 49.7% on authored prose).
|
|
29
|
+
- **Stance failure, diagnosed** (STANCE-01, STANCE-02): frozen diagnostic studies isolate the mechanism — proposition-level prior interference, with a dose-response over familiarity — and test the fixes: a hosted frontier model passes every bar (REALWIRE 0.977); prompt-level structure trades bias for abstention; proposition masking maps a structural ceiling on real copy.
|
|
30
|
+
- **Proof package** (2026-10-09): the post-freeze claims re-measured on the frozen downstream protocol. A base-model upgrade (Qwen3.5-9B, identical prompts) cuts local downstream error 0.4637 → 0.3194; structured variants (0.3073, 0.3300) do not separate from the plain baseline outside seed noise. Production default: baseline prompt on Qwen3.5-9B, structured escalation where abstention is acceptable, frontier arm as the only strong-band configuration. A supervised fastText floor (0.618 on REALWIRE stance) and a five-model fold bench accompany the result.
|
|
31
|
+
- **Ported into production tooling**: the measured defaults ship in the deterministic Applied Epistemic Engineering engine (`aee` 1.4.0 on PyPI — policy gates, per-source reliability, materiality review queue) and the Spec Kit AEE extension 1.2.0, with the transfer map recorded in that repository.
|
|
32
|
+
- **Measured, killed** (LORA-01, 2026-10-20): a LoRA adapter trained on truth-orthogonal stance data improved held-out assertion accuracy (0.903 → 0.972) but failed the frozen primary bar (+0.10 improvement required, +0.069 measured) and learned to abstain on real published copy (14/131 REALWIRE sentences), regressing REALWIRE-T. Killed as a production candidate under its predeclared criteria; the production default (Q35A) is unchanged. Full record in docs/LORA-01.md.
|
|
33
|
+
- **Measured, killed** (LORA-02, 2026-10-20): the successor adapter - trained with near-miss distractors against LORA-01's abstention failure and judged by headroom-based error-reduction bars - fixed every held-out assert error (0.958 to 1.000) but abstained on 30% of REALWIRE and damaged deny accuracy on real copy (REALWIRE-T deny 0.891 to 0.655). Killed under its frozen bars; across both LoRA studies, stance training on authored sentences does not transfer to real published copy. Production default (Q35A) unchanged. Full record in docs/LORA-02.md.
|
|
34
|
+
|
|
35
|
+
## Install
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install epistemic-ledger
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
from epistemic_ledger import Ledger
|
|
43
|
+
|
|
44
|
+
ledger = Ledger("my-ledger")
|
|
45
|
+
claim = ledger.assert_claim("the bridge design is safe", 0.60)
|
|
46
|
+
fact = ledger.ingest_evidence("load test passed", 0.90)["fact_id"]
|
|
47
|
+
ledger.add_support(claim, fact, "evidential", p_given=0.95, p_given_not=0.30)
|
|
48
|
+
print(ledger.get_score(claim))
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Command line: `epistemic-ledger demo`, `epistemic-ledger verify <dir>`,
|
|
52
|
+
`epistemic-ledger kill-metrics <dir>`. Full documentation:
|
|
53
|
+
https://epistemic-ledger.readthedocs.io/
|
|
54
|
+
|
|
55
|
+
## The idea in brief
|
|
56
|
+
|
|
57
|
+
1. **Append-only records.** Conclusions are never mutated or deleted. Corrections are new records that supersede old ones — the full history of what was believed, and when, stays queryable.
|
|
58
|
+
2. **Fluid certainty scores.** Every conclusion carries a score that moves as evidence accumulates — today's posterior is tomorrow's prior — rather than a one-time binary verdict.
|
|
59
|
+
3. **Dependency-tracked revisits.** Each conclusion records *why* it is held. When a new fact arrives, the system propagates the change along the dependency graph and re-evaluates exactly the conclusions it touches, plus their dependents.
|
|
60
|
+
4. **A trigger discipline.** Not every new fact warrants a revisit. The system needs a principled answer to *when* — from coarse dirty-flagging up through precise invalidation to judgmental materiality thresholds.
|
|
61
|
+
|
|
62
|
+
## Research foundations
|
|
63
|
+
|
|
64
|
+
Eight threads were surveyed to frame the design (canonical references in [`docs/PAPER.md`](docs/PAPER.md)):
|
|
65
|
+
|
|
66
|
+
| # | Thread | What it gives the ledger |
|
|
67
|
+
|---|--------|--------------------------|
|
|
68
|
+
| 1 | Bitemporal data modeling | Valid time vs. transaction time; retroactive correction without mutation |
|
|
69
|
+
| 2 | Belief revision (AGM) | Minimal-change revision; epistemic entrenchment as the "what to give up" rule |
|
|
70
|
+
| 3 | Truth maintenance (JTMS/ATMS) | Justification-tracked beliefs; dependency-directed retraction |
|
|
71
|
+
| 4 | Event sourcing | Append-only log; state as replay; compensating events |
|
|
72
|
+
| 5 | Incremental recomputation | Invalidation propagation; early cutoff; DBSP's formal delta theory |
|
|
73
|
+
| 6 | Change-impact analysis | The trigger problem: dirty flags → precise invalidation → materiality |
|
|
74
|
+
| 7 | Non-binary epistemic scoring | Sequential Bayes; Jeffrey kinematics for uncertain evidence |
|
|
75
|
+
| 8 | LLM memory & context cleanup | Offline consolidation; RAG freshness; bitemporal knowledge graphs |
|
|
76
|
+
|
|
77
|
+
The closest existing systems to the whole: **Zep/Graphiti**-style bitemporal knowledge graphs (event time + ingestion time per edge, non-lossy retroactive correction), with TOKI (bitemporal contradiction resolution for agent memory), SodaMem (temporal graph memory with provenance and supersession edges), Engram (bi-temporal memory with invalidation and supersession chains), and MemTX (belief-commit protocol that repairs derived records when a belief is retracted) as close on other axes — none carries a certainty score revised as evidence accumulates, and none has the ledger's materiality rule for when a change warrants a revisit.
|
|
78
|
+
|
|
79
|
+
## Why this matters beyond one project
|
|
80
|
+
|
|
81
|
+
The same machinery answers a pressing LLM problem: **context cleanup**. Retrieval freshness, offline memory consolidation, and principled invalidation of stale context are exactly the ledger's operations applied to an agent's working memory. Whatever is built here generalizes.
|
|
82
|
+
|
|
83
|
+
## Repository layout
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
.
|
|
87
|
+
├── README.md # This file
|
|
88
|
+
├── LICENSE # MIT (code); docs/ stays all rights reserved — see NOTICE.md
|
|
89
|
+
├── docs/
|
|
90
|
+
│ ├── PAPER.md # The framing paper
|
|
91
|
+
│ ├── DESIGN-01-record-schema-scoring.md # Record schema + scoring calculus
|
|
92
|
+
│ ├── DESIGN-02-contradiction-resolution.md # Entrenchment-ordered contraction
|
|
93
|
+
│ ├── DESIGN-03-learned-entrenchment.md # Calibration-derived entrenchment
|
|
94
|
+
│ ├── DESIGN-04-ds-intervals.md # D–S intervals: keep-or-cut verdict
|
|
95
|
+
│ ├── TRIGGER-STRESS-01.md # Trigger-discipline stress test report
|
|
96
|
+
│ ├── CONTEXT-CLEANUP-01.md # LLM context-cleanup experiment report
|
|
97
|
+
│ └── research/ # Raw research notes with provenance (2026-09-30)
|
|
98
|
+
│ └── BIBLIOGRAPHY.md # Annotated bibliography: primary-source verification (2026-10-01)
|
|
99
|
+
├── src/epistemic_ledger/ # The package (stdlib-only Python)
|
|
100
|
+
├── tests/ # Test suite
|
|
101
|
+
├── prototype/ # Research scripts + compatibility shims
|
|
102
|
+
│ ├── validation/ # Measured-result harnesses (not shipped)
|
|
103
|
+
│ └── demo.py # End-to-end scenario
|
|
104
|
+
└── .gitignore
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Prototype v0.1
|
|
108
|
+
|
|
109
|
+
A working implementation of Design Memo 01's §8 scope — now the shipped package under `src/epistemic_ledger/`, with the research harnesses remaining in [`prototype/`](prototype/): append-only JSONL event log, SQLite bitemporal claim table, Jeffrey-update revisit loop with early cutoff, one materiality rule, the four queries (`BELIEVED_AT` / `CHANGED` / `DEPENDS_ON` / `WHY`), and all five kill criteria instrumented from day one.
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
pip install -e ".[dev]" # from the repo root
|
|
113
|
+
epistemic-ledger demo # end-to-end scenario
|
|
114
|
+
python -m pytest # the full test suite
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## License
|
|
118
|
+
|
|
119
|
+
Code: MIT — see [LICENSE](LICENSE). The framing paper, design memos, and research documents under `docs/` remain all rights reserved, © 2026 Axiovex Systems, LLC — see [LICENSE-DOCS.txt](LICENSE-DOCS.txt) and [NOTICE.md](NOTICE.md).
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "epistemic-ledger"
|
|
7
|
+
version = "0.12.0"
|
|
8
|
+
description = "A living epistemic ledger: append-only conclusions with fluid certainty scores, revised as new facts arrive."
|
|
9
|
+
readme = "README-PyPI.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [
|
|
14
|
+
{ name = "Axiovex Systems, LLC" },
|
|
15
|
+
]
|
|
16
|
+
keywords = [
|
|
17
|
+
"epistemology",
|
|
18
|
+
"belief-revision",
|
|
19
|
+
"bitemporal",
|
|
20
|
+
"event-sourcing",
|
|
21
|
+
"truth-maintenance",
|
|
22
|
+
"agent-memory",
|
|
23
|
+
"knowledge-graph",
|
|
24
|
+
]
|
|
25
|
+
classifiers = [
|
|
26
|
+
"Development Status :: 4 - Beta",
|
|
27
|
+
"Intended Audience :: Developers",
|
|
28
|
+
"Intended Audience :: Science/Research",
|
|
29
|
+
"Programming Language :: Python :: 3",
|
|
30
|
+
"Programming Language :: Python :: 3.10",
|
|
31
|
+
"Programming Language :: Python :: 3.11",
|
|
32
|
+
"Programming Language :: Python :: 3.12",
|
|
33
|
+
"Programming Language :: Python :: 3.13",
|
|
34
|
+
"Programming Language :: Python :: 3.14",
|
|
35
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
36
|
+
"Topic :: Database",
|
|
37
|
+
"Typing :: Typed",
|
|
38
|
+
]
|
|
39
|
+
dependencies = []
|
|
40
|
+
|
|
41
|
+
[project.optional-dependencies]
|
|
42
|
+
dev = [
|
|
43
|
+
"pytest>=8",
|
|
44
|
+
"pytest-cov>=5",
|
|
45
|
+
"hypothesis>=6",
|
|
46
|
+
"ruff>=0.6",
|
|
47
|
+
"mypy>=1.11",
|
|
48
|
+
"build>=1.2",
|
|
49
|
+
"twine>=5",
|
|
50
|
+
]
|
|
51
|
+
docs = [
|
|
52
|
+
"mkdocs>=1.6",
|
|
53
|
+
"mkdocs-material>=9.5",
|
|
54
|
+
"mkdocstrings[python]>=0.26",
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
[project.scripts]
|
|
58
|
+
epistemic-ledger = "epistemic_ledger.cli:main"
|
|
59
|
+
|
|
60
|
+
[project.urls]
|
|
61
|
+
Homepage = "https://github.com/AXIOVEX/epistemic-ledger"
|
|
62
|
+
Documentation = "https://epistemic-ledger.readthedocs.io/"
|
|
63
|
+
Repository = "https://github.com/AXIOVEX/epistemic-ledger"
|
|
64
|
+
Issues = "https://github.com/AXIOVEX/epistemic-ledger/issues"
|
|
65
|
+
Changelog = "https://github.com/AXIOVEX/epistemic-ledger/blob/main/CHANGELOG.md"
|
|
66
|
+
|
|
67
|
+
[tool.setuptools.packages.find]
|
|
68
|
+
where = ["src"]
|
|
69
|
+
|
|
70
|
+
[tool.setuptools.package-data]
|
|
71
|
+
epistemic_ledger = ["py.typed"]
|
|
72
|
+
|
|
73
|
+
[tool.pytest.ini_options]
|
|
74
|
+
testpaths = ["tests"]
|
|
75
|
+
addopts = "-q"
|
|
76
|
+
markers = [
|
|
77
|
+
"property: property-based tests (Hypothesis)",
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
[tool.coverage.run]
|
|
81
|
+
source = ["epistemic_ledger"]
|
|
82
|
+
branch = true
|
|
83
|
+
omit = [
|
|
84
|
+
"*/epistemic_ledger/__main__.py", # 3-line entry shim, exercised via the CLI tests' subprocess check
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
[tool.coverage.report]
|
|
88
|
+
show_missing = true
|
|
89
|
+
skip_covered = false
|
|
90
|
+
|
|
91
|
+
[tool.ruff]
|
|
92
|
+
line-length = 88
|
|
93
|
+
target-version = "py310"
|
|
94
|
+
|
|
95
|
+
[tool.ruff.lint]
|
|
96
|
+
select = ["E", "F", "I", "UP", "B"]
|
|
97
|
+
ignore = [
|
|
98
|
+
"E501", # line length is a formatter concern; long data lines exist in the research-derived core
|
|
99
|
+
"B008",
|
|
100
|
+
]
|
|
101
|
+
|
|
102
|
+
[tool.ruff.lint.per-file-ignores]
|
|
103
|
+
# The ported suite predates the package: it imports in per-feature
|
|
104
|
+
# sections on purpose and keeps scenario-setup locals. Its behavior is
|
|
105
|
+
# the contract; new test files are held to the full rule set.
|
|
106
|
+
"tests/test_ledger.py" = ["E401", "E402", "I001", "F401", "F811", "F841", "UP031", "E741", "B007"]
|
|
107
|
+
"tests/test_newsroom.py" = ["E402"]
|
|
108
|
+
|
|
109
|
+
[tool.mypy]
|
|
110
|
+
python_version = "3.10"
|
|
111
|
+
warn_unused_ignores = false
|
|
112
|
+
ignore_missing_imports = true
|
|
113
|
+
# The core predates typing; strictness is being raised module by module.
|
|
114
|
+
# The gate today: mypy must parse and check the package with no errors
|
|
115
|
+
# under these settings; new modules (cli, __init__) are fully annotated
|
|
116
|
+
# in practice and checked the same way.
|
|
117
|
+
check_untyped_defs = true
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""Living Epistemic Ledger.
|
|
2
|
+
|
|
3
|
+
An append-only epistemic database: every conclusion carries a fluid
|
|
4
|
+
certainty score, and new facts trigger re-evaluation of the conclusions
|
|
5
|
+
they touch, plus their dependents. Nothing is ever deleted; corrections
|
|
6
|
+
are new records that supersede old ones.
|
|
7
|
+
|
|
8
|
+
Public API:
|
|
9
|
+
Ledger -- the ledger itself (event log + bitemporal store)
|
|
10
|
+
jeffrey -- Jeffrey conditionalization for uncertain evidence
|
|
11
|
+
dempster_combine -- Dempster's rule for belief masses
|
|
12
|
+
interval_to_mass -- convert a [belief, plausibility] interval to a mass
|
|
13
|
+
|
|
14
|
+
Submodules:
|
|
15
|
+
epistemic_ledger.ledger -- core store, revisit loop, queries
|
|
16
|
+
epistemic_ledger.consolidation -- offline LLM consolidation pass
|
|
17
|
+
epistemic_ledger.policies -- caller-owned abstention policies
|
|
18
|
+
epistemic_ledger.elicit -- likelihood elicitation helpers
|
|
19
|
+
epistemic_ledger.ed25519 -- vendored Ed25519 (RFC 8032) for
|
|
20
|
+
signed governance verdicts
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
24
|
+
|
|
25
|
+
from .ledger import (
|
|
26
|
+
COMBO_KINDS,
|
|
27
|
+
ENTRENCHMENT_TIERS,
|
|
28
|
+
GATED_ACTIONS,
|
|
29
|
+
SUPPORT_KINDS,
|
|
30
|
+
TIER_ENTRENCHMENT,
|
|
31
|
+
WRITER_TIERS,
|
|
32
|
+
Ledger,
|
|
33
|
+
dempster_combine,
|
|
34
|
+
interval_to_mass,
|
|
35
|
+
jeffrey,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
try:
|
|
39
|
+
__version__ = version("epistemic-ledger")
|
|
40
|
+
except PackageNotFoundError: # source checkout without an install
|
|
41
|
+
__version__ = "0+unknown"
|
|
42
|
+
|
|
43
|
+
__all__ = [
|
|
44
|
+
"COMBO_KINDS",
|
|
45
|
+
"ENTRENCHMENT_TIERS",
|
|
46
|
+
"GATED_ACTIONS",
|
|
47
|
+
"SUPPORT_KINDS",
|
|
48
|
+
"TIER_ENTRENCHMENT",
|
|
49
|
+
"WRITER_TIERS",
|
|
50
|
+
"Ledger",
|
|
51
|
+
"__version__",
|
|
52
|
+
"dempster_combine",
|
|
53
|
+
"interval_to_mass",
|
|
54
|
+
"jeffrey",
|
|
55
|
+
]
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"""Command-line interface for the living epistemic ledger.
|
|
2
|
+
|
|
3
|
+
Commands:
|
|
4
|
+
epistemic-ledger demo run the end-to-end scenario
|
|
5
|
+
epistemic-ledger verify <ledger-dir> integrity-check a ledger store
|
|
6
|
+
epistemic-ledger kill-metrics <ledger-dir>
|
|
7
|
+
print the five kill metrics
|
|
8
|
+
as JSON
|
|
9
|
+
|
|
10
|
+
Exit codes: 0 on success, 1 when a check reports problems, 2 on usage
|
|
11
|
+
or open errors.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import argparse
|
|
15
|
+
import json
|
|
16
|
+
import shutil
|
|
17
|
+
import sys
|
|
18
|
+
import tempfile
|
|
19
|
+
|
|
20
|
+
from . import __version__
|
|
21
|
+
from .ledger import Ledger
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def run_demo():
|
|
25
|
+
"""The bridge scenario from the framing work, end to end."""
|
|
26
|
+
d = tempfile.mkdtemp(prefix="ledger-demo-")
|
|
27
|
+
try:
|
|
28
|
+
L = Ledger(d)
|
|
29
|
+
|
|
30
|
+
safe = L.assert_claim("bridge design is safe", 0.60)
|
|
31
|
+
ships = L.assert_claim("project ships on time", 0.55)
|
|
32
|
+
L.add_support(ships, safe, "deductive", p_given=0.90, p_given_not=0.20)
|
|
33
|
+
print(f"day 1: safe={L.get_score(safe):.3f} ships={L.get_score(ships):.3f}")
|
|
34
|
+
|
|
35
|
+
r = L.ingest_evidence("load test passed", 0.90)
|
|
36
|
+
fact = r["fact_id"]
|
|
37
|
+
before = L.get_score(safe)
|
|
38
|
+
L.add_support(safe, fact, "evidential", p_given=0.95, p_given_not=0.30)
|
|
39
|
+
L._revisit(fact, {fact: 0.90})
|
|
40
|
+
print(
|
|
41
|
+
f"day 2: load test passed -> safe={L.get_score(safe):.3f} "
|
|
42
|
+
f"({L.get_score(safe) - before:+.3f}), "
|
|
43
|
+
f"ships={L.get_score(ships):.3f}"
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
r = L.ingest_evidence("steel supplier delayed 6 weeks", 0.85)
|
|
47
|
+
delay = r["fact_id"]
|
|
48
|
+
before = L.get_score(ships)
|
|
49
|
+
L.add_support(ships, delay, "evidential", p_given=0.15, p_given_not=0.70)
|
|
50
|
+
r = L._revisit(delay, {delay: 0.85})
|
|
51
|
+
print(
|
|
52
|
+
f"day 3: supplier delay -> ships={L.get_score(ships):.3f} "
|
|
53
|
+
f"({L.get_score(ships) - before:+.3f}); "
|
|
54
|
+
f"flags raised: {len(r['flags'])}"
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
print("\nWHY(ships):")
|
|
58
|
+
for w in L.why(ships):
|
|
59
|
+
print(f" <- {w['statement']!r} score={w['score']:.3f} kind={w['kind']}")
|
|
60
|
+
print(f"\nDEPENDS_ON(delay): {len(L.depends_on(delay))} claim(s) in closure")
|
|
61
|
+
|
|
62
|
+
L.record_outcome(safe, True)
|
|
63
|
+
L.record_outcome(ships, False)
|
|
64
|
+
m = L.kill_metrics()
|
|
65
|
+
print(
|
|
66
|
+
f"\nkill metrics: brier={m['brier']:.3f} "
|
|
67
|
+
f"fanout_max={m['fanout']['max']} "
|
|
68
|
+
f"override_rate={m['override_rate']} "
|
|
69
|
+
f"revisits={len(m['trigger_log'])}"
|
|
70
|
+
)
|
|
71
|
+
L.close()
|
|
72
|
+
finally:
|
|
73
|
+
shutil.rmtree(d, ignore_errors=True)
|
|
74
|
+
return 0
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def main(argv=None):
|
|
78
|
+
parser = argparse.ArgumentParser(
|
|
79
|
+
prog="epistemic-ledger",
|
|
80
|
+
description="Living epistemic ledger: append-only conclusions "
|
|
81
|
+
"with fluid certainty scores.",
|
|
82
|
+
)
|
|
83
|
+
parser.add_argument(
|
|
84
|
+
"--version", action="version", version=f"epistemic-ledger {__version__}"
|
|
85
|
+
)
|
|
86
|
+
sub = parser.add_subparsers(dest="command", required=True)
|
|
87
|
+
sub.add_parser("demo", help="run the end-to-end demo scenario")
|
|
88
|
+
p_verify = sub.add_parser("verify", help="integrity-check a ledger store")
|
|
89
|
+
p_verify.add_argument("ledger_dir")
|
|
90
|
+
p_km = sub.add_parser("kill-metrics", help="print a ledger's kill metrics as JSON")
|
|
91
|
+
p_km.add_argument("ledger_dir")
|
|
92
|
+
args = parser.parse_args(argv)
|
|
93
|
+
|
|
94
|
+
if args.command == "demo":
|
|
95
|
+
return run_demo()
|
|
96
|
+
try:
|
|
97
|
+
L = Ledger(args.ledger_dir)
|
|
98
|
+
except Exception as exc: # an unopenable store is a usage error
|
|
99
|
+
print(f"error: cannot open ledger at {args.ledger_dir}: {exc}", file=sys.stderr)
|
|
100
|
+
return 2
|
|
101
|
+
try:
|
|
102
|
+
if args.command == "verify":
|
|
103
|
+
result = L.verify_store()
|
|
104
|
+
print(json.dumps(result, indent=2, default=str))
|
|
105
|
+
return 0 if result.get("ok") else 1
|
|
106
|
+
if args.command == "kill-metrics":
|
|
107
|
+
print(json.dumps(L.kill_metrics(), indent=2, default=str))
|
|
108
|
+
return 0
|
|
109
|
+
finally:
|
|
110
|
+
L.close()
|
|
111
|
+
return 2
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
if __name__ == "__main__":
|
|
115
|
+
raise SystemExit(main())
|