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.
- palimnex-2.8.0/LICENSE +21 -0
- palimnex-2.8.0/MANIFEST.in +2 -0
- palimnex-2.8.0/PKG-INFO +129 -0
- palimnex-2.8.0/README.md +103 -0
- palimnex-2.8.0/docs/SDK.md +285 -0
- palimnex-2.8.0/palimnex/CHANGELOG.md +272 -0
- palimnex-2.8.0/palimnex/README.md +328 -0
- palimnex-2.8.0/palimnex/__init__.py +10 -0
- palimnex-2.8.0/palimnex/__main__.py +4 -0
- palimnex-2.8.0/palimnex/_offline_fixtures.py +63 -0
- palimnex-2.8.0/palimnex/_offline_redis.py +416 -0
- palimnex-2.8.0/palimnex/adapters.py +244 -0
- palimnex-2.8.0/palimnex/api.py +219 -0
- palimnex-2.8.0/palimnex/audit.py +374 -0
- palimnex-2.8.0/palimnex/cache_v3.py +2455 -0
- palimnex-2.8.0/palimnex/challenge.py +81 -0
- palimnex-2.8.0/palimnex/core.py +3471 -0
- palimnex-2.8.0/palimnex/documents.py +394 -0
- palimnex-2.8.0/palimnex/durable.py +3438 -0
- palimnex-2.8.0/palimnex/evaluation/v25.json +27 -0
- palimnex-2.8.0/palimnex/evaluation/v26.json +19 -0
- palimnex-2.8.0/palimnex/experience.py +283 -0
- palimnex-2.8.0/palimnex/identity.py +110 -0
- palimnex-2.8.0/palimnex/integrity.py +122 -0
- palimnex-2.8.0/palimnex/locators.py +150 -0
- palimnex-2.8.0/palimnex/longitudinal.py +210 -0
- palimnex-2.8.0/palimnex/mcp_server.py +74 -0
- palimnex-2.8.0/palimnex/onboarding.py +413 -0
- palimnex-2.8.0/palimnex/portable.py +979 -0
- palimnex-2.8.0/palimnex/py.typed +0 -0
- palimnex-2.8.0/palimnex/redis_launcher.sh +404 -0
- palimnex-2.8.0/palimnex/retention.py +705 -0
- palimnex-2.8.0/palimnex/retrieval.py +146 -0
- palimnex-2.8.0/palimnex/schemas/audit-graph.v1.schema.json +130 -0
- palimnex-2.8.0/palimnex/schemas/cleanup-plan.v1.schema.json +264 -0
- palimnex-2.8.0/palimnex/schemas/cleanup-plan.v2.schema.json +51 -0
- palimnex-2.8.0/palimnex/schemas/deletion-contract.v1.schema.json +35 -0
- palimnex-2.8.0/palimnex/schemas/deletion-contract.v2.schema.json +22 -0
- palimnex-2.8.0/palimnex/schemas/erasure-tombstone.v1.schema.json +42 -0
- palimnex-2.8.0/palimnex/schemas/event-checkpoint.v1.schema.json +71 -0
- palimnex-2.8.0/palimnex/schemas/logical-export.v1.schema.json +233 -0
- palimnex-2.8.0/palimnex/schemas/memory-event.v1.schema.json +156 -0
- palimnex-2.8.0/palimnex/schemas/memory-pack-manifest.v2.schema.json +82 -0
- palimnex-2.8.0/palimnex/schemas/retention-policy.v1.schema.json +89 -0
- palimnex-2.8.0/palimnex/schemas/signature.v1.schema.json +42 -0
- palimnex-2.8.0/palimnex/schemas/source-locator.v1.schema.json +81 -0
- palimnex-2.8.0/palimnex/schemas/workflow-spec.v1.schema.json +67 -0
- palimnex-2.8.0/palimnex/security.py +365 -0
- palimnex-2.8.0/palimnex/semantic.py +112 -0
- palimnex-2.8.0/palimnex/semantica.py +334 -0
- palimnex-2.8.0/palimnex/tests/__init__.py +1 -0
- palimnex-2.8.0/palimnex/tests/fake_redis.py +5 -0
- palimnex-2.8.0/palimnex/tests/support.py +5 -0
- palimnex-2.8.0/palimnex/tests/test_cache_v3.py +907 -0
- palimnex-2.8.0/palimnex/tests/test_challenge.py +20 -0
- palimnex-2.8.0/palimnex/tests/test_documents.py +123 -0
- palimnex-2.8.0/palimnex/tests/test_durable.py +1764 -0
- palimnex-2.8.0/palimnex/tests/test_experience.py +272 -0
- palimnex-2.8.0/palimnex/tests/test_feature_modes.py +392 -0
- palimnex-2.8.0/palimnex/tests/test_longitudinal.py +61 -0
- palimnex-2.8.0/palimnex/tests/test_mcp.py +75 -0
- palimnex-2.8.0/palimnex/tests/test_onboarding.py +424 -0
- palimnex-2.8.0/palimnex/tests/test_portable.py +1241 -0
- palimnex-2.8.0/palimnex/tests/test_real_checkout_evaluation.py +47 -0
- palimnex-2.8.0/palimnex/tests/test_redis_client.py +183 -0
- palimnex-2.8.0/palimnex/tests/test_redis_launcher.py +307 -0
- palimnex-2.8.0/palimnex/tests/test_retention.py +263 -0
- palimnex-2.8.0/palimnex/tests/test_sdk.py +356 -0
- palimnex-2.8.0/palimnex/tests/test_security.py +243 -0
- palimnex-2.8.0/palimnex/tests/test_semantic.py +57 -0
- palimnex-2.8.0/palimnex/tests/test_semantica.py +231 -0
- palimnex-2.8.0/palimnex/tests/test_version.py +38 -0
- palimnex-2.8.0/palimnex/vcs.py +39 -0
- palimnex-2.8.0/palimnex.egg-info/PKG-INFO +129 -0
- palimnex-2.8.0/palimnex.egg-info/SOURCES.txt +79 -0
- palimnex-2.8.0/palimnex.egg-info/dependency_links.txt +1 -0
- palimnex-2.8.0/palimnex.egg-info/entry_points.txt +3 -0
- palimnex-2.8.0/palimnex.egg-info/requires.txt +17 -0
- palimnex-2.8.0/palimnex.egg-info/top_level.txt +1 -0
- palimnex-2.8.0/pyproject.toml +45 -0
- 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.
|
palimnex-2.8.0/PKG-INFO
ADDED
|
@@ -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).
|
palimnex-2.8.0/README.md
ADDED
|
@@ -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).
|