palimnex 2.8.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 (81) hide show
  1. palimnex-2.8.0/LICENSE +21 -0
  2. palimnex-2.8.0/MANIFEST.in +2 -0
  3. palimnex-2.8.0/PKG-INFO +129 -0
  4. palimnex-2.8.0/README.md +103 -0
  5. palimnex-2.8.0/docs/SDK.md +285 -0
  6. palimnex-2.8.0/palimnex/CHANGELOG.md +272 -0
  7. palimnex-2.8.0/palimnex/README.md +328 -0
  8. palimnex-2.8.0/palimnex/__init__.py +10 -0
  9. palimnex-2.8.0/palimnex/__main__.py +4 -0
  10. palimnex-2.8.0/palimnex/_offline_fixtures.py +63 -0
  11. palimnex-2.8.0/palimnex/_offline_redis.py +416 -0
  12. palimnex-2.8.0/palimnex/adapters.py +244 -0
  13. palimnex-2.8.0/palimnex/api.py +219 -0
  14. palimnex-2.8.0/palimnex/audit.py +374 -0
  15. palimnex-2.8.0/palimnex/cache_v3.py +2455 -0
  16. palimnex-2.8.0/palimnex/challenge.py +81 -0
  17. palimnex-2.8.0/palimnex/core.py +3471 -0
  18. palimnex-2.8.0/palimnex/documents.py +394 -0
  19. palimnex-2.8.0/palimnex/durable.py +3438 -0
  20. palimnex-2.8.0/palimnex/evaluation/v25.json +27 -0
  21. palimnex-2.8.0/palimnex/evaluation/v26.json +19 -0
  22. palimnex-2.8.0/palimnex/experience.py +283 -0
  23. palimnex-2.8.0/palimnex/identity.py +110 -0
  24. palimnex-2.8.0/palimnex/integrity.py +122 -0
  25. palimnex-2.8.0/palimnex/locators.py +150 -0
  26. palimnex-2.8.0/palimnex/longitudinal.py +210 -0
  27. palimnex-2.8.0/palimnex/mcp_server.py +74 -0
  28. palimnex-2.8.0/palimnex/onboarding.py +413 -0
  29. palimnex-2.8.0/palimnex/portable.py +979 -0
  30. palimnex-2.8.0/palimnex/py.typed +0 -0
  31. palimnex-2.8.0/palimnex/redis_launcher.sh +404 -0
  32. palimnex-2.8.0/palimnex/retention.py +705 -0
  33. palimnex-2.8.0/palimnex/retrieval.py +146 -0
  34. palimnex-2.8.0/palimnex/schemas/audit-graph.v1.schema.json +130 -0
  35. palimnex-2.8.0/palimnex/schemas/cleanup-plan.v1.schema.json +264 -0
  36. palimnex-2.8.0/palimnex/schemas/cleanup-plan.v2.schema.json +51 -0
  37. palimnex-2.8.0/palimnex/schemas/deletion-contract.v1.schema.json +35 -0
  38. palimnex-2.8.0/palimnex/schemas/deletion-contract.v2.schema.json +22 -0
  39. palimnex-2.8.0/palimnex/schemas/erasure-tombstone.v1.schema.json +42 -0
  40. palimnex-2.8.0/palimnex/schemas/event-checkpoint.v1.schema.json +71 -0
  41. palimnex-2.8.0/palimnex/schemas/logical-export.v1.schema.json +233 -0
  42. palimnex-2.8.0/palimnex/schemas/memory-event.v1.schema.json +156 -0
  43. palimnex-2.8.0/palimnex/schemas/memory-pack-manifest.v2.schema.json +82 -0
  44. palimnex-2.8.0/palimnex/schemas/retention-policy.v1.schema.json +89 -0
  45. palimnex-2.8.0/palimnex/schemas/signature.v1.schema.json +42 -0
  46. palimnex-2.8.0/palimnex/schemas/source-locator.v1.schema.json +81 -0
  47. palimnex-2.8.0/palimnex/schemas/workflow-spec.v1.schema.json +67 -0
  48. palimnex-2.8.0/palimnex/security.py +365 -0
  49. palimnex-2.8.0/palimnex/semantic.py +112 -0
  50. palimnex-2.8.0/palimnex/semantica.py +334 -0
  51. palimnex-2.8.0/palimnex/tests/__init__.py +1 -0
  52. palimnex-2.8.0/palimnex/tests/fake_redis.py +5 -0
  53. palimnex-2.8.0/palimnex/tests/support.py +5 -0
  54. palimnex-2.8.0/palimnex/tests/test_cache_v3.py +907 -0
  55. palimnex-2.8.0/palimnex/tests/test_challenge.py +20 -0
  56. palimnex-2.8.0/palimnex/tests/test_documents.py +123 -0
  57. palimnex-2.8.0/palimnex/tests/test_durable.py +1764 -0
  58. palimnex-2.8.0/palimnex/tests/test_experience.py +272 -0
  59. palimnex-2.8.0/palimnex/tests/test_feature_modes.py +392 -0
  60. palimnex-2.8.0/palimnex/tests/test_longitudinal.py +61 -0
  61. palimnex-2.8.0/palimnex/tests/test_mcp.py +75 -0
  62. palimnex-2.8.0/palimnex/tests/test_onboarding.py +424 -0
  63. palimnex-2.8.0/palimnex/tests/test_portable.py +1241 -0
  64. palimnex-2.8.0/palimnex/tests/test_real_checkout_evaluation.py +47 -0
  65. palimnex-2.8.0/palimnex/tests/test_redis_client.py +183 -0
  66. palimnex-2.8.0/palimnex/tests/test_redis_launcher.py +307 -0
  67. palimnex-2.8.0/palimnex/tests/test_retention.py +263 -0
  68. palimnex-2.8.0/palimnex/tests/test_sdk.py +356 -0
  69. palimnex-2.8.0/palimnex/tests/test_security.py +243 -0
  70. palimnex-2.8.0/palimnex/tests/test_semantic.py +57 -0
  71. palimnex-2.8.0/palimnex/tests/test_semantica.py +231 -0
  72. palimnex-2.8.0/palimnex/tests/test_version.py +38 -0
  73. palimnex-2.8.0/palimnex/vcs.py +39 -0
  74. palimnex-2.8.0/palimnex.egg-info/PKG-INFO +129 -0
  75. palimnex-2.8.0/palimnex.egg-info/SOURCES.txt +79 -0
  76. palimnex-2.8.0/palimnex.egg-info/dependency_links.txt +1 -0
  77. palimnex-2.8.0/palimnex.egg-info/entry_points.txt +3 -0
  78. palimnex-2.8.0/palimnex.egg-info/requires.txt +17 -0
  79. palimnex-2.8.0/palimnex.egg-info/top_level.txt +1 -0
  80. palimnex-2.8.0/pyproject.toml +45 -0
  81. palimnex-2.8.0/setup.cfg +4 -0
palimnex-2.8.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Palimnex contributors
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,2 @@
1
+ include docs/SDK.md
2
+ recursive-include palimnex/tests *.py
@@ -0,0 +1,129 @@
1
+ Metadata-Version: 2.4
2
+ Name: palimnex
3
+ Version: 2.8.0
4
+ Summary: Repository-local evidence, historical memory, and explicit retention controls
5
+ Author: Palimnex contributors
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://edwinkestler.github.io/palimnex/
8
+ Project-URL: Repository, https://github.com/EdwinKestler/palimnex
9
+ Requires-Python: >=3.11
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Provides-Extra: crypto
13
+ Requires-Dist: cryptography>=41; extra == "crypto"
14
+ Provides-Extra: mcp
15
+ Requires-Dist: mcp<2,>=1.12; extra == "mcp"
16
+ Provides-Extra: semantica
17
+ Requires-Dist: semantica>=0.9; extra == "semantica"
18
+ Provides-Extra: test
19
+ Requires-Dist: cryptography>=41; extra == "test"
20
+ Requires-Dist: jsonschema>=4.18; extra == "test"
21
+ Requires-Dist: referencing>=0.28; extra == "test"
22
+ Requires-Dist: build>=1.2; extra == "test"
23
+ Requires-Dist: twine>=6; extra == "test"
24
+ Requires-Dist: mypy>=1.10; extra == "test"
25
+ Dynamic: license-file
26
+
27
+ # Palimnex
28
+
29
+ Palimnex is a repository-local memory system for coding agents. It combines a
30
+ rebuildable Redis source-discovery cache with a durable SQLite historical
31
+ ledger, encrypted portable packs, evidence-aware retrieval, and explicit
32
+ retention and authorized-erasure controls.
33
+
34
+ This repository is the independent continuation of the portable Project Memory
35
+ bundle originally developed inside `btc-usdt-atomic-swap`. Product-facing
36
+ development now belongs here. No live Redis data, SQLite ledger, credentials,
37
+ wallet material, atomic-swap implementation, or repository-specific rollback
38
+ snapshot was copied.
39
+
40
+ The Python distribution version is `2.8.0`, with public SDK and extension API v1.
41
+ Version 2.8.0 adds a replicable `palimnex:audit-graph:v1` export
42
+ and an optional Semantica projector that copies that graph as untrusted
43
+ history with TTL disabled and fail-closed erasure receipts. See
44
+ [the SDK guide](docs/SDK.md) for installation, typed interfaces, source
45
+ resolvers, derivative adapters, signed checkpoints, the audit graph, optional
46
+ Semantica projection, pack identity and MCP.
47
+
48
+ ## Use Palimnex in your repository
49
+
50
+ Palimnex is not yet on PyPI. Install it from a pinned release tag:
51
+
52
+ ```bash
53
+ pipx install "palimnex[crypto] @ git+https://github.com/EdwinKestler/palimnex@v2.8.0"
54
+ ```
55
+
56
+ Before the first run, add `.palimnex/`, `*.pmem` and `*.key` to the
57
+ repository's `.gitignore` so the durable ledger and keys are never committed.
58
+ In 2.8.0 and later, `palimnex init --write` does this and
59
+ writes the configuration, `palimnex redis start` starts the guarded Redis, and
60
+ `palimnex doctor` checks the installation.
61
+ [The installation guide](docs/INSTALL.md) covers configuration, Redis, first
62
+ run, agent instructions and uninstall; [the upgrade guide](docs/UPGRADING.md)
63
+ covers moving between versions.
64
+
65
+ ## Quick start (this repository)
66
+
67
+ Requirements are Python 3.11+, Redis server/CLI for cache-backed integration,
68
+ and the distribution `cryptography` package for encrypted packs and signatures.
69
+ Install development dependencies with `python3 -m pip install -e '.[test,mcp]'`
70
+ inside a virtual environment to run the full gate, including MCP integration.
71
+
72
+ ```bash
73
+ ./scripts/palimnex_redis.sh start
74
+ python3 palimnex.py status
75
+ python3 palimnex.py index --incremental
76
+ python3 palimnex.py validate --deep
77
+ python3 palimnex.py evaluate --limit 5
78
+ python3 palimnex.py ledger-init
79
+ python3 palimnex.py ledger-status
80
+ python3 palimnex.py audit-graph
81
+ ```
82
+
83
+ `ledger-init` is a one-time local write that creates the durable ledger;
84
+ `ledger-status` exits `2` and `audit-graph` fails until it exists.
85
+
86
+ Run the standalone gate with:
87
+
88
+ ```bash
89
+ ./scripts/palimnex_check.sh
90
+ ```
91
+
92
+ Repository source is authoritative. Cache and ledger results are discovery or
93
+ historical evidence, never authorization to execute external actions.
94
+
95
+ ## Layout
96
+
97
+ - `palimnex.py` — repository-root CLI.
98
+ - `palimnex/` — engine, schemas, fixtures, and tests.
99
+ - `docs/` — design, operations, retention, SDK contracts, and the Pages site.
100
+ - `scripts/palimnex_redis.sh` — owner-only Unix-socket Redis launcher.
101
+ - `.palimnex.json` — this repository's safe local configuration.
102
+ - `LICENSE` — MIT license.
103
+ - `.github/workflows/palimnex-check.yml` — CI for the standalone gate.
104
+ - `docs/index.html` — dependency-free GitHub Pages architecture site.
105
+
106
+ See [the installation guide](docs/INSTALL.md), [the upgrade guide](docs/UPGRADING.md),
107
+ [the SDK guide](docs/SDK.md), [the operator runbook](docs/RUNBOOK.md),
108
+ [retention policy](docs/RETENTION.md), [compatibility policy](docs/COMPATIBILITY.md),
109
+ [maintainer initialization prompt](docs/AGENT_INIT_PROMPT.md),
110
+ and [extraction record](docs/PROVENANCE.md).
111
+
112
+ The Pages source can be previewed locally and published from `docs/` by an
113
+ authorized maintainer. See [the Pages guide](docs/PAGES.md) for the workflow
114
+ and branch-source options.
115
+
116
+ ## Safety boundary
117
+
118
+ Palimnex never forgets durable data automatically. Cleanup is a separate,
119
+ authorized transaction that resolves derivatives, enforces holds, removes
120
+ eligible local content and indexes, recomputes dependent facts, verifies local
121
+ stores, and writes a non-reconstructive audit tombstone. Optional Semantica
122
+ copies of the audit graph are untrusted projections: `retention_days` must be
123
+ `None`, and a mandatory store that reports `not_configured`, `unsupported`, or
124
+ `failed` fails the adapter apply. It does not claim forensic deletion from
125
+ SSDs, backups, snapshots, third-party systems, or unmanaged exported copies.
126
+
127
+ ## License
128
+
129
+ Palimnex is released under the MIT License. See [LICENSE](LICENSE).
@@ -0,0 +1,103 @@
1
+ # Palimnex
2
+
3
+ Palimnex is a repository-local memory system for coding agents. It combines a
4
+ rebuildable Redis source-discovery cache with a durable SQLite historical
5
+ ledger, encrypted portable packs, evidence-aware retrieval, and explicit
6
+ retention and authorized-erasure controls.
7
+
8
+ This repository is the independent continuation of the portable Project Memory
9
+ bundle originally developed inside `btc-usdt-atomic-swap`. Product-facing
10
+ development now belongs here. No live Redis data, SQLite ledger, credentials,
11
+ wallet material, atomic-swap implementation, or repository-specific rollback
12
+ snapshot was copied.
13
+
14
+ The Python distribution version is `2.8.0`, with public SDK and extension API v1.
15
+ Version 2.8.0 adds a replicable `palimnex:audit-graph:v1` export
16
+ and an optional Semantica projector that copies that graph as untrusted
17
+ history with TTL disabled and fail-closed erasure receipts. See
18
+ [the SDK guide](docs/SDK.md) for installation, typed interfaces, source
19
+ resolvers, derivative adapters, signed checkpoints, the audit graph, optional
20
+ Semantica projection, pack identity and MCP.
21
+
22
+ ## Use Palimnex in your repository
23
+
24
+ Palimnex is not yet on PyPI. Install it from a pinned release tag:
25
+
26
+ ```bash
27
+ pipx install "palimnex[crypto] @ git+https://github.com/EdwinKestler/palimnex@v2.8.0"
28
+ ```
29
+
30
+ Before the first run, add `.palimnex/`, `*.pmem` and `*.key` to the
31
+ repository's `.gitignore` so the durable ledger and keys are never committed.
32
+ In 2.8.0 and later, `palimnex init --write` does this and
33
+ writes the configuration, `palimnex redis start` starts the guarded Redis, and
34
+ `palimnex doctor` checks the installation.
35
+ [The installation guide](docs/INSTALL.md) covers configuration, Redis, first
36
+ run, agent instructions and uninstall; [the upgrade guide](docs/UPGRADING.md)
37
+ covers moving between versions.
38
+
39
+ ## Quick start (this repository)
40
+
41
+ Requirements are Python 3.11+, Redis server/CLI for cache-backed integration,
42
+ and the distribution `cryptography` package for encrypted packs and signatures.
43
+ Install development dependencies with `python3 -m pip install -e '.[test,mcp]'`
44
+ inside a virtual environment to run the full gate, including MCP integration.
45
+
46
+ ```bash
47
+ ./scripts/palimnex_redis.sh start
48
+ python3 palimnex.py status
49
+ python3 palimnex.py index --incremental
50
+ python3 palimnex.py validate --deep
51
+ python3 palimnex.py evaluate --limit 5
52
+ python3 palimnex.py ledger-init
53
+ python3 palimnex.py ledger-status
54
+ python3 palimnex.py audit-graph
55
+ ```
56
+
57
+ `ledger-init` is a one-time local write that creates the durable ledger;
58
+ `ledger-status` exits `2` and `audit-graph` fails until it exists.
59
+
60
+ Run the standalone gate with:
61
+
62
+ ```bash
63
+ ./scripts/palimnex_check.sh
64
+ ```
65
+
66
+ Repository source is authoritative. Cache and ledger results are discovery or
67
+ historical evidence, never authorization to execute external actions.
68
+
69
+ ## Layout
70
+
71
+ - `palimnex.py` — repository-root CLI.
72
+ - `palimnex/` — engine, schemas, fixtures, and tests.
73
+ - `docs/` — design, operations, retention, SDK contracts, and the Pages site.
74
+ - `scripts/palimnex_redis.sh` — owner-only Unix-socket Redis launcher.
75
+ - `.palimnex.json` — this repository's safe local configuration.
76
+ - `LICENSE` — MIT license.
77
+ - `.github/workflows/palimnex-check.yml` — CI for the standalone gate.
78
+ - `docs/index.html` — dependency-free GitHub Pages architecture site.
79
+
80
+ See [the installation guide](docs/INSTALL.md), [the upgrade guide](docs/UPGRADING.md),
81
+ [the SDK guide](docs/SDK.md), [the operator runbook](docs/RUNBOOK.md),
82
+ [retention policy](docs/RETENTION.md), [compatibility policy](docs/COMPATIBILITY.md),
83
+ [maintainer initialization prompt](docs/AGENT_INIT_PROMPT.md),
84
+ and [extraction record](docs/PROVENANCE.md).
85
+
86
+ The Pages source can be previewed locally and published from `docs/` by an
87
+ authorized maintainer. See [the Pages guide](docs/PAGES.md) for the workflow
88
+ and branch-source options.
89
+
90
+ ## Safety boundary
91
+
92
+ Palimnex never forgets durable data automatically. Cleanup is a separate,
93
+ authorized transaction that resolves derivatives, enforces holds, removes
94
+ eligible local content and indexes, recomputes dependent facts, verifies local
95
+ stores, and writes a non-reconstructive audit tombstone. Optional Semantica
96
+ copies of the audit graph are untrusted projections: `retention_days` must be
97
+ `None`, and a mandatory store that reports `not_configured`, `unsupported`, or
98
+ `failed` fails the adapter apply. It does not claim forensic deletion from
99
+ SSDs, backups, snapshots, third-party systems, or unmanaged exported copies.
100
+
101
+ ## License
102
+
103
+ Palimnex is released under the MIT License. See [LICENSE](LICENSE).
@@ -0,0 +1,285 @@
1
+ # Python SDK and extension contracts
2
+
3
+ The 2.7.0 distribution introduces public Python API v1. `palimnex.api`,
4
+ `palimnex.locators`, `palimnex.adapters`, `palimnex.identity`,
5
+ `palimnex.integrity`, and `palimnex.audit` are supported extension surfaces.
6
+ `palimnex.semantica` is an optional extra surface and is not imported by core.
7
+ Other modules remain implementation details. Breaking changes to these
8
+ interfaces require a new API major version; additive methods do not. Check
9
+ `API_VERSION` and adapter `api_version` before connecting an integration.
10
+ Plugins are supplied explicitly; Palimnex does not auto-import installed entry
11
+ points or fetch plugins.
12
+
13
+ ## Install and open
14
+
15
+ To adopt Palimnex in another repository, install a pinned release tag and
16
+ follow [`INSTALL.md`](INSTALL.md), which also covers the `.gitignore` lines
17
+ that keep `.palimnex/`, `*.pmem` and `*.key` out of Git. For upgrades, see
18
+ [`UPGRADING.md`](UPGRADING.md).
19
+
20
+ To develop Palimnex, build or install the checkout with Python 3.11 or newer:
21
+
22
+ ```bash
23
+ python3 -m venv .venv
24
+ .venv/bin/python -m pip install -e '.[crypto,mcp,test]'
25
+ .venv/bin/python -m build
26
+ .venv/bin/python -m twine check dist/*
27
+ ```
28
+
29
+ The base package has no third-party Python dependencies. `crypto` provides
30
+ encrypted transfer and Ed25519 identity; `mcp` provides the optional protocol
31
+ transport. `test` provides schema validation, type checking and build tools.
32
+ Redis server/CLI remain external prerequisites for source-cache integration.
33
+ SQLite uses Python's standard library. The distribution carries `py.typed`,
34
+ versioned JSON schemas, frozen evaluation resources and offline test helpers.
35
+
36
+ For the installed CLI, change into the target repository or set `PALIMNEX_ROOT`
37
+ before starting the process. `python -m palimnex` and `palimnex` are equivalent.
38
+ The copied `palimnex.py` wrapper preserves script-location rooting unless
39
+ `PALIMNEX_ROOT` explicitly overrides it.
40
+ The SDK always receives an explicit repository root; it never derives a target
41
+ from the installed package directory. A `.palimnex.json` with the project's
42
+ UUID `project_id` is required; `project_slug` defaults to the directory name
43
+ and `durable_ledger_path` to `.palimnex/memory.sqlite3`.
44
+
45
+ ```python
46
+ from pathlib import Path
47
+ from palimnex import Palimnex, Event, Evidence, RecallOptions
48
+ from palimnex.locators import repository_locator
49
+
50
+ root = Path('/path/to/repository')
51
+ client = Palimnex(root, writable=True)
52
+ client.initialize() # explicit; opening a client creates no ledger
53
+ session = client.start_session('review storage behavior')
54
+ source = repository_locator(root, 'docs/DESIGN.md:1-20')
55
+ result = client.record(Event(
56
+ session_id=session['session_id'], kind='fact',
57
+ subject='storage behavior', payload={'observation': 'reviewed source'},
58
+ evidence=(Evidence(source),), retention='durable',
59
+ ))
60
+ client.close_session(session['session_id'], 'review complete')
61
+ reader = Palimnex(root) # read-only SDK methods by default
62
+ history = reader.recall('storage behavior', RecallOptions(limit=5))
63
+ ```
64
+
65
+ The stable request objects are typed dataclasses; results retain the existing
66
+ versioned dictionary envelopes. Defaults exclude restricted/secret results and
67
+ untrusted or stale history. SDK recall uses audit visibility, including session
68
+ records; `visibility='current'` selects durable current memory. Reading never
69
+ promotes trust or grants permission. Writes are synchronous and preserve the
70
+ ledger's transaction semantics. Exceptions remain `ValueError` for invalid
71
+ inputs/state and `PermissionError` for a read-only client. Cryptographic keys
72
+ are never included in result envelopes.
73
+
74
+ Since 2.8.0, three additions make ledger handling
75
+ safer. All are additive to API v1.
76
+
77
+ - Inside a Git work tree, `initialize()` and the first write refuse to create
78
+ a ledger at a path Git does not ignore, before creating any file.
79
+ `initialize(allow_unignored_ledger=True)` is the explicit override.
80
+ - `backup_ledger(target=None)` writes a verified owner-only snapshot, by
81
+ default under `backups/` beside the ledger.
82
+ - `migrate_retention(expected_digest=..., snapshot=True)` writes a verified
83
+ snapshot of the unmigrated ledger before migrating.
84
+
85
+ Later authorized erasure does not remove snapshots.
86
+
87
+ ## Versioned source references
88
+
89
+ `SourceLocator` contains `scheme`, `source_id`, `version`, `range`, and `digest`.
90
+ The serialized prefix is `palimnex:source-locator:v1:` followed by canonical
91
+ JSON inside the existing evidence locator string column. No SQLite migration
92
+ is required. Existing path-and-line evidence continues to work. Older readers
93
+ cannot resolve the new prefix and treat those references as unavailable.
94
+
95
+ Ranges are inclusive one-based `lines` or half-open zero-based `bytes`.
96
+ `digest` is SHA-256 of the selected bytes. Repository versions are the SHA-256
97
+ of the complete file; line selections retain legacy newline normalization.
98
+ Readers verify both version and selected content every time. The resolver
99
+ returns at most one megabyte of UTF-8 source for privacy admission before
100
+ range selection. Resolvers must also bound their own I/O and timeouts.
101
+
102
+ Only `repo` is built in. Applications register a `SourceResolver` instance for
103
+ schemes such as `sqlite`, `document`, `https`, or `semantica`. A resolver returns
104
+ `ResolvedSource(content, version)` for the exact requested identity/version.
105
+ Registration is a trusted-code boundary: callers configure credentials, tenant
106
+ scope, network allowlists, redirects, query binding and timeouts. A URL in a
107
+ locator never triggers a network request by itself. Missing, incompatible,
108
+ changed or unavailable resolvers fail verification. Adapter errors are redacted.
109
+ Semantica is an extension target, not a bundled or live-validated integration.
110
+
111
+ Byte integrity is not factual truth or claim entailment. Existing extractive
112
+ capsule/claim quotation remains limited to admitted repository path locators;
113
+ external evidence is governed and recallable but is not automatically quoted
114
+ into capsules. Imported evidence stays untrusted until locally reverified.
115
+
116
+ ## Derivative backends
117
+
118
+ `DerivativeAdapter` v1 defines `enumerate_derivatives`, `delete`,
119
+ `verify_absent`, `invalidate_projection`, and `produce_receipt`.
120
+ `AdapterRegistry` rejects duplicate identities, protocol mismatch and foreign
121
+ projects. Plans bind event IDs, object versions/digests, adapter/project scope,
122
+ and a five-minute expiry. Apply requires the displayed plan digest and an
123
+ application authorization callback, reevaluated before each deletion. That
124
+ callback must consult the application's current permissions, preservation
125
+ holds, dependencies, and retention rules. Supplying `True` without those checks
126
+ does not implement an authorization policy.
127
+
128
+ The SQLite reference adapter manages its own two namespaced tables using an
129
+ application-supplied connection. Use a separate private database and serialize
130
+ access. `initialize()` and `put()` are explicit writes. Deletes compare object
131
+ generation and content digest, invalidate its projection, and verify both
132
+ stores before a non-content receipt is returned. Changing objects or new
133
+ derivatives requires replanning. Failures propagate; earlier store deletions
134
+ remain effective. Idempotent retries handle already-absent objects and pending
135
+ projection invalidation. Persist operational plans privately for recovery.
136
+ Projection-only survivors remain discoverable when replanning after failure;
137
+ inconsistent generations or payload digests fail closed.
138
+
139
+ These receipts describe logical row/projection absence only. They do not claim
140
+ compaction, backup destruction, replica acknowledgement, or forensic erasure.
141
+ Adapters are trusted implementations whose receipt assertions require backend
142
+ specific acceptance tests. No distributed transaction is implied.
143
+
144
+ The independent coordinator does not bypass the existing retention ledger.
145
+ Registered packs and legacy attempted hot projections continue to block local
146
+ cleanup until a deletion-registry-aware integration is supplied. A generic
147
+ adapter receipt cannot be submitted to clear those blockers. The SDK's
148
+ `plan_erasure`, `authorize_erasure`, and `apply_erasure` retain the existing
149
+ local policy, hold, protected-anchor and digest-bound requirements.
150
+
151
+ ## Signer identity and custody
152
+
153
+ `Ed25519Signer` supports raw private key files created exclusively with mode
154
+ 0600 by `generate_signing_key`. Reuse the existing no-follow owner/file checks.
155
+ Use separate keys for signing, encryption and checkpoint commitments.
156
+ `Signer` v1 also allows an application-provided KMS/HSM implementation whose
157
+ `sign(message)` returns Ed25519 signatures and whose `public_key` is pinned.
158
+ No particular KMS provider is bundled or contacted.
159
+
160
+ `TrustedIdentity(name, public_key)` maps public-key fingerprints to identities
161
+ chosen by the receiver. Sender-supplied names/public keys never establish trust.
162
+ Removing a fingerprint from this map revokes its acceptance; key rotation
163
+ requires an operator-reviewed map change. There is no PKI, discovery or implied
164
+ organizational identity proof beyond that configured binding.
165
+
166
+ Pack v2 ciphertext bytes remain unchanged. An optional detached
167
+ `palimnex:signature:v1` attestation binds SHA-256 of the exact encrypted envelope,
168
+ the `encrypted-pack` domain and signer fingerprint. `export_pack(..., signer=)`
169
+ returns it as `signature`; retain it privately beside the pack. SDK import
170
+ requires a trusted signature by default; `require_signature=False` explicitly
171
+ permits legacy unsigned transfers. The legacy CLI keeps its v2 behavior.
172
+ Verification covers the same bytes passed to decryption. A valid signature
173
+ does not restore event verification, promotion or operating authority.
174
+
175
+ ## Signed event-history checkpoints
176
+
177
+ `checkpoint(commitment_key=..., signer=..., previous=..., trusted=...)` takes a
178
+ consistent SQLite snapshot and builds a domain-separated Merkle tree over
179
+ ordered canonical events, including evidence. A second commitment covers the
180
+ complete typed ledger state (including trust/import and retention controls).
181
+ Leaves and ledger commitments use HMAC-SHA-256 so retained checkpoints do not
182
+ publish direct content digests usable for simple plaintext guessing.
183
+
184
+ Each signed checkpoint carries project/schema, sequence, predecessor hash,
185
+ event count/root, commitment-key identity and local timestamp. `verify_history`
186
+ checks signatures, ordering and continuity against a caller-supplied expected
187
+ tip. `verify_checkpoint` additionally compares the current ledger snapshot.
188
+ Keep the expected tip in an independently controlled location. Without that
189
+ external anchor, an attacker can replace the entire history with an older
190
+ valid prefix. A compromised signer can attest to false states. This is explicit
191
+ checkpointing, not automatic per-write authentication or an independent clock.
192
+ The first checkpoint is a baseline attestation, not retroactive provenance.
193
+
194
+ Checkpointing never changes the ledger schema or writes live state. Store
195
+ returned attestations in a private custody system; they retain counts, timing,
196
+ identifiers and keyed commitments. Authorized cleanup produces a new snapshot
197
+ root; a subsequent checkpoint links to the prior one without retaining erased
198
+ plaintext. Checkpoints, keys and receipts still need their own retention policy.
199
+ Retention-controlled ledgers remain incompatible with replacement imports.
200
+
201
+ ## Replicable audit graph
202
+
203
+ `audit_graph()` builds `palimnex:audit-graph:v1`, a content-addressed graph of
204
+ eligible session, event, evidence, claim, retention-action, and tombstone nodes.
205
+ Edges record `contains`, `evidenced_by`, `supersedes`, `contradicts`,
206
+ `derived_from`, and `forgotten`. Secret records are never included.
207
+ `graph_digest` covers the graph except `created_at`, `graph_digest`, and
208
+ `signature`, so two exports of the same ledger content compare equal.
209
+ Imported history stays labeled historical-only. Forgotten events appear only as
210
+ tombstones with HMAC commitments, never with deleted payloads.
211
+
212
+ This is a Palimnex-native document. It does not require Semantica. Optional
213
+ `signer=` attaches an `audit-graph` Ed25519 signature. `export_audit_graph`
214
+ writes an owner-only JSON file. `export_pack(..., include_audit_graph=True)`
215
+ leaves pack v2 bytes unchanged and writes a sibling `.audit-graph.json`.
216
+ CLI: `python3 palimnex.py audit-graph` and `memory-export --include-audit-graph`.
217
+ The graph is historical evidence and never permission to act.
218
+
219
+ ## Semantica projection
220
+
221
+ `palimnex.semantica` projects an audit graph into a duck-typed Semantica
222
+ `ContextGraph` as untrusted historical copies. It does not import the Semantica
223
+ package. Callers construct `AgentContext(..., retention_days=None)` or a graph
224
+ and pass it in; `bind_semantica()` only checks that TTL is disabled and that
225
+ `add_node`/`add_edge`/`has_node` exist. Default 30-day retention is refused.
226
+
227
+ Projected nodes carry `authority: historical_only`, `authorizes_actions: false`,
228
+ and `valid_until=None`. `SemanticaResolver` reads only the local projection
229
+ index; a `semantica:` locator never opens a network URL. Register it explicitly
230
+ on `Palimnex(..., source_resolvers={"semantica": resolver})`.
231
+
232
+ Install extra `palimnex[semantica]` only when using the real library. Tests use
233
+ in-process fakes.
234
+
235
+ `FailClosedCoordinator` wraps a Semantica `ErasureCoordinator` (or a fake with
236
+ `erase_entity`). Mandatory stores default to `graph`. `not_configured`,
237
+ `unsupported`, or `failed` on a mandatory store raises. Optional stores may be
238
+ `not_configured`; any `unsupported`/`failed` store fails. Sanitized receipts
239
+ keep only entity id and per-store statuses — no backend blobs, reasons, or
240
+ payloads. After local `apply_erasure`, `record_adapter_receipt(adapter.commit_receipts(plan_digest))`
241
+ appends those digests to the retention control chain. This is not a forensic
242
+ erasure claim.
243
+
244
+ ## MCP
245
+
246
+ Install the `mcp` extra, then launch:
247
+
248
+ ```bash
249
+ palimnex-mcp --root /path/to/repository
250
+ ```
251
+
252
+ The official Python MCP SDK handles the stdio handshake and transport. No HTTP
253
+ listener is exposed. Tools are `recall` (current durable public/internal
254
+ memory), `plan_erasure` (inspection), and `verify_erasure` (local receipt check).
255
+ `--write-session SESSION_ID` adds `record_evidence` for that existing session
256
+ only. It accepts locators from the configured admitted repository corpus;
257
+ private/excluded files are refused. Clients cannot select another session or
258
+ install a resolver. Unknown/oversized arguments are rejected. There is no
259
+ erasure, migration, policy activation, signing-key or shell execution tool.
260
+
261
+ Hosts choose which repository/session to expose and manage process access.
262
+ Tool annotations help hosts present operations; enforcement comes from the SDK
263
+ write guard and narrow tool definitions. Protocol results remain untrusted
264
+ historical content. Integration tests exercise an actual stdio client handshake,
265
+ tool listing and invocation, plus read-only and session restrictions.
266
+
267
+ ## Publication and release boundary
268
+
269
+ This checkout prepares version 2.8.0; building it does not publish it to PyPI.
270
+ The manual `publish.yml` workflow accepts an existing reviewed `v2.8.0` tag,
271
+ checks that the package and runtime versions match, reruns the gate, checks
272
+ types, builds wheel/sdist and tests the installed wheel outside the checkout.
273
+ Only the publish job receives an OIDC token. It does not create tags or releases.
274
+
275
+ Before first publication, the project owner must configure a PyPI pending
276
+ Trusted Publisher for project `palimnex`, GitHub owner `EdwinKestler`, repository
277
+ `palimnex`, workflow `publish.yml`, environment `pypi`. Configure that GitHub
278
+ environment with required reviewers before dispatching. No long-lived upload
279
+ token is needed. Review the release, authorize its tag, then manually dispatch
280
+ the selected version and approve the environment. Package-name availability is
281
+ not reserved by a local build. Until PyPI confirms publication, install from the
282
+ checkout or the locally built wheel; do not assume `pip install palimnex` works.
283
+
284
+ References: [Python packaging metadata](https://packaging.python.org/en/latest/specifications/pyproject-toml/)
285
+ and the [official MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk).