tokenfold 0.4.1__tar.gz → 0.5.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 (40) hide show
  1. {tokenfold-0.4.1 → tokenfold-0.5.0}/Cargo.lock +63 -19
  2. {tokenfold-0.4.1 → tokenfold-0.5.0}/Cargo.toml +3 -2
  3. {tokenfold-0.4.1 → tokenfold-0.5.0}/PKG-INFO +63 -49
  4. {tokenfold-0.4.1 → tokenfold-0.5.0}/README.md +62 -48
  5. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/Cargo.toml +2 -0
  6. tokenfold-0.5.0/crates/tokenfold-core/README.md +29 -0
  7. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/benches/THRESHOLDS.toml +3 -4
  8. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/benches/compression_bench.rs +3 -3
  9. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/budget.rs +56 -29
  10. tokenfold-0.5.0/crates/tokenfold-core/src/codec.rs +116 -0
  11. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/lib.rs +3 -1
  12. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/modes.rs +34 -34
  13. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/pipeline/mod.rs +236 -116
  14. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/pipeline/tests.rs +15 -11
  15. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/report.rs +75 -9
  16. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/retrieval_store.rs +344 -40
  17. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/stats.rs +10 -10
  18. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/status.rs +1 -16
  19. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/diff.rs +1 -1
  20. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/json_prune.rs +51 -30
  21. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/tests/integration.rs +12 -17
  22. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-py/Cargo.toml +1 -1
  23. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-py/src/lib.rs +293 -300
  24. {tokenfold-0.4.1 → tokenfold-0.5.0}/LICENSE +0 -0
  25. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/errors.rs +0 -0
  26. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/filters.rs +0 -0
  27. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/input.rs +0 -0
  28. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/safety.rs +0 -0
  29. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/token_estimator.rs +0 -0
  30. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/json.rs +0 -0
  31. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/json_dict.rs +0 -0
  32. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/json_fold.rs +0 -0
  33. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/log_fold.rs +0 -0
  34. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/logs.rs +0 -0
  35. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/mod.rs +0 -0
  36. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/redaction.rs +0 -0
  37. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/schema.rs +0 -0
  38. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/tests/golden.rs +0 -0
  39. {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/tests/property_tests.rs +0 -0
  40. {tokenfold-0.4.1 → tokenfold-0.5.0}/pyproject.toml +0 -0
@@ -206,7 +206,7 @@ dependencies = [
206
206
  "heck",
207
207
  "proc-macro2",
208
208
  "quote",
209
- "syn",
209
+ "syn 2.0.118",
210
210
  ]
211
211
 
212
212
  [[package]]
@@ -270,7 +270,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
270
270
  dependencies = [
271
271
  "proc-macro2",
272
272
  "quote",
273
- "syn",
273
+ "syn 2.0.118",
274
274
  ]
275
275
 
276
276
  [[package]]
@@ -620,7 +620,7 @@ dependencies = [
620
620
  "proc-macro2",
621
621
  "pyo3-macros-backend",
622
622
  "quote",
623
- "syn",
623
+ "syn 2.0.118",
624
624
  ]
625
625
 
626
626
  [[package]]
@@ -632,7 +632,7 @@ dependencies = [
632
632
  "heck",
633
633
  "proc-macro2",
634
634
  "quote",
635
- "syn",
635
+ "syn 2.0.118",
636
636
  ]
637
637
 
638
638
  [[package]]
@@ -860,7 +860,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
860
860
  dependencies = [
861
861
  "proc-macro2",
862
862
  "quote",
863
- "syn",
863
+ "syn 2.0.118",
864
864
  ]
865
865
 
866
866
  [[package]]
@@ -945,6 +945,17 @@ dependencies = [
945
945
  "unicode-ident",
946
946
  ]
947
947
 
948
+ [[package]]
949
+ name = "syn"
950
+ version = "3.0.4"
951
+ source = "registry+https://github.com/rust-lang/crates.io-index"
952
+ checksum = "e6275cddf4610d1775e6d1fe9469b2e77d0f39fd98fb7450901b821e0c53649f"
953
+ dependencies = [
954
+ "proc-macro2",
955
+ "quote",
956
+ "unicode-ident",
957
+ ]
958
+
948
959
  [[package]]
949
960
  name = "target-lexicon"
950
961
  version = "0.13.5"
@@ -970,7 +981,16 @@ version = "1.0.69"
970
981
  source = "registry+https://github.com/rust-lang/crates.io-index"
971
982
  checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
972
983
  dependencies = [
973
- "thiserror-impl",
984
+ "thiserror-impl 1.0.69",
985
+ ]
986
+
987
+ [[package]]
988
+ name = "thiserror"
989
+ version = "2.0.20"
990
+ source = "registry+https://github.com/rust-lang/crates.io-index"
991
+ checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f"
992
+ dependencies = [
993
+ "thiserror-impl 2.0.20",
974
994
  ]
975
995
 
976
996
  [[package]]
@@ -981,7 +1001,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
981
1001
  dependencies = [
982
1002
  "proc-macro2",
983
1003
  "quote",
984
- "syn",
1004
+ "syn 2.0.118",
1005
+ ]
1006
+
1007
+ [[package]]
1008
+ name = "thiserror-impl"
1009
+ version = "2.0.20"
1010
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1011
+ checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af"
1012
+ dependencies = [
1013
+ "proc-macro2",
1014
+ "quote",
1015
+ "syn 3.0.4",
985
1016
  ]
986
1017
 
987
1018
  [[package]]
@@ -1013,7 +1044,7 @@ dependencies = [
1013
1044
 
1014
1045
  [[package]]
1015
1046
  name = "tokenfold-adapters"
1016
- version = "0.4.1"
1047
+ version = "0.5.0"
1017
1048
  dependencies = [
1018
1049
  "serde",
1019
1050
  "serde_json",
@@ -1022,7 +1053,7 @@ dependencies = [
1022
1053
 
1023
1054
  [[package]]
1024
1055
  name = "tokenfold-admin"
1025
- version = "0.4.1"
1056
+ version = "0.5.0"
1026
1057
  dependencies = [
1027
1058
  "ed25519-dalek",
1028
1059
  "serde",
@@ -1032,7 +1063,7 @@ dependencies = [
1032
1063
 
1033
1064
  [[package]]
1034
1065
  name = "tokenfold-cli"
1035
- version = "0.4.1"
1066
+ version = "0.5.0"
1036
1067
  dependencies = [
1037
1068
  "clap",
1038
1069
  "serde",
@@ -1045,39 +1076,40 @@ dependencies = [
1045
1076
 
1046
1077
  [[package]]
1047
1078
  name = "tokenfold-core"
1048
- version = "0.4.1"
1079
+ version = "0.5.0"
1049
1080
  dependencies = [
1050
1081
  "proptest",
1051
1082
  "regex",
1052
1083
  "serde",
1053
1084
  "serde_json",
1054
1085
  "sha2",
1055
- "thiserror",
1086
+ "thiserror 1.0.69",
1056
1087
  "tiktoken-rs",
1057
1088
  "toml",
1089
+ "toon-format",
1058
1090
  ]
1059
1091
 
1060
1092
  [[package]]
1061
1093
  name = "tokenfold-image"
1062
- version = "0.4.1"
1094
+ version = "0.5.0"
1063
1095
 
1064
1096
  [[package]]
1065
1097
  name = "tokenfold-learn"
1066
- version = "0.4.1"
1098
+ version = "0.5.0"
1067
1099
  dependencies = [
1068
1100
  "tokenfold-core",
1069
1101
  ]
1070
1102
 
1071
1103
  [[package]]
1072
1104
  name = "tokenfold-output"
1073
- version = "0.4.1"
1105
+ version = "0.5.0"
1074
1106
  dependencies = [
1075
1107
  "tokenfold-core",
1076
1108
  ]
1077
1109
 
1078
1110
  [[package]]
1079
1111
  name = "tokenfold-proxy"
1080
- version = "0.4.1"
1112
+ version = "0.5.0"
1081
1113
  dependencies = [
1082
1114
  "clap",
1083
1115
  "serde",
@@ -1089,7 +1121,7 @@ dependencies = [
1089
1121
 
1090
1122
  [[package]]
1091
1123
  name = "tokenfold-py"
1092
- version = "0.4.1"
1124
+ version = "0.5.0"
1093
1125
  dependencies = [
1094
1126
  "pyo3",
1095
1127
  "serde_json",
@@ -1098,7 +1130,7 @@ dependencies = [
1098
1130
 
1099
1131
  [[package]]
1100
1132
  name = "tokenfold-rag"
1101
- version = "0.4.1"
1133
+ version = "0.5.0"
1102
1134
 
1103
1135
  [[package]]
1104
1136
  name = "toml"
@@ -1141,6 +1173,18 @@ version = "0.1.2"
1141
1173
  source = "registry+https://github.com/rust-lang/crates.io-index"
1142
1174
  checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
1143
1175
 
1176
+ [[package]]
1177
+ name = "toon-format"
1178
+ version = "0.5.0"
1179
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1180
+ checksum = "8f89570c1a68d73941f728cca32a4345b2ffca36667ad921af336c60309a3e7e"
1181
+ dependencies = [
1182
+ "indexmap",
1183
+ "serde",
1184
+ "serde_json",
1185
+ "thiserror 2.0.20",
1186
+ ]
1187
+
1144
1188
  [[package]]
1145
1189
  name = "typenum"
1146
1190
  version = "1.20.1"
@@ -1364,7 +1408,7 @@ checksum = "e2e817b7b52d0c7358d3246da9d69935ebb18116b2b102b4230dac079b4862f5"
1364
1408
  dependencies = [
1365
1409
  "proc-macro2",
1366
1410
  "quote",
1367
- "syn",
1411
+ "syn 2.0.118",
1368
1412
  ]
1369
1413
 
1370
1414
  [[package]]
@@ -3,9 +3,9 @@ resolver = "2"
3
3
  members = ["crates/tokenfold-core", "crates/tokenfold-py"]
4
4
 
5
5
  [workspace.package]
6
- version = "0.4.1"
6
+ version = "0.5.0"
7
7
  edition = "2024"
8
- rust-version = "1.97"
8
+ rust-version = "1.98"
9
9
  license = "Apache-2.0"
10
10
  repository = "https://github.com/snchimata/tokenfold"
11
11
 
@@ -18,6 +18,7 @@ clap = { version = "4", features = ["derive"] }
18
18
 
19
19
  tiktoken-rs = "0.7"
20
20
  sha2 = "0.10"
21
+ toon-format = { version = "0.5", default-features = false }
21
22
 
22
23
  proptest = "1"
23
24
  toml = "0.8"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tokenfold
3
- Version: 0.4.1
3
+ Version: 0.5.0
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: Apache Software License
@@ -20,19 +20,19 @@ Keywords: llm,tokens,compression,tokenizer,openai,json,prompt-engineering,cli,to
20
20
  Requires-Python: >=3.9
21
21
  Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
22
22
 
23
- <div align="center">
23
+ <div align="center">
24
24
 
25
25
  # TOKENFOLD
26
26
 
27
27
  **Send less noise. Fit more context. Pay for fewer input tokens.**
28
28
 
29
- **Up to 92% fewer input tokens · lossless by default · exact receipts**
29
+ **Up to 92% fewer input tokens · lossless by default · exact receipts**
30
30
 
31
- CLI · Python · TypeScript · Rust · proxy · MCP · local-first · provider-neutral
31
+ CLI · Python · TypeScript · Rust · proxy · MCP · local-first · provider-neutral
32
32
 
33
33
  [![CI](https://img.shields.io/github/actions/workflow/status/snchimata/tokenfold/ci.yml?branch=main&label=tests&logo=github&style=flat-square)](https://github.com/snchimata/tokenfold/actions/workflows/ci.yml) [![Coverage](https://img.shields.io/github/actions/workflow/status/snchimata/tokenfold/ci.yml?branch=main&label=coverage&logo=github&style=flat-square)](https://github.com/snchimata/tokenfold/actions/workflows/ci.yml) [![GitHub Release](https://img.shields.io/github/v/release/snchimata/tokenfold?logo=github&style=flat-square)](https://github.com/snchimata/tokenfold/releases/latest) [![PyPI](https://img.shields.io/pypi/v/tokenfold?label=PyPI&style=flat-square)](https://pypi.org/project/tokenfold/) [![npm](https://img.shields.io/npm/v/tokenfold?label=npm&logo=npm&style=flat-square)](https://www.npmjs.com/package/tokenfold) [![Rust](https://img.shields.io/crates/v/tokenfold-core?label=Rust&style=flat-square)](https://docs.rs/crate/tokenfold-core/latest) [![License](https://img.shields.io/badge/license-Apache--2.0-blue?style=flat-square)](https://github.com/snchimata/tokenfold/blob/main/LICENSE)
34
34
 
35
- [Measured results](#measured-results) · [Platform](#one-platform-two-engines) · [Quick start](#quick-start) · [Lossy pruning](#recoverable-lossy-pruning) · [Select model](#tokenfold-select) · [Reproduce](#reproduce-the-results)
35
+ [Measured results](#measured-results) · [Platform](#one-platform-two-engines) · [Quick start](#quick-start) · [Lossy pruning](#recoverable-lossy-pruning) · [Select model](#tokenfold-select) · [Reproduce](#reproduce-the-results)
36
36
 
37
37
  </div>
38
38
 
@@ -44,18 +44,21 @@ CLI · Python · TypeScript · Rust · proxy · MCP · local-first · provider-n
44
44
 
45
45
  | Search / RAG results | Repetitive JSON | API responses | Tool schemas |
46
46
  | :---: | :---: | :---: | :---: |
47
- | **91.7% fewer tokens** | **67.6% fewer tokens** | **61.3% fewer tokens** | **45.6% fewer tokens** |
48
- | 84,032 → 6,951 | 50-record payload | 30-record payload | 1.8 MB OpenAI fixture |
47
+ | **91.7% fewer tokens** | **67.6% fewer tokens** | **63.9% fewer tokens** | **45.6% fewer tokens** |
48
+ | 84,032 → 6,951 | 50-record payload | 30-record payload | 1.8 MB OpenAI fixture |
49
49
  | opt-in, recoverable | lossless | lossless | lossless |
50
50
 
51
- All four use exact `o200k_base` counts in balanced mode. The 91.7% showcase
51
+ All four use exact `o200k_base` counts in balanced preset. The 91.7% showcase
52
52
  keeps the planted `503` result inline and makes the other 98 long rows
53
53
  retrievable by hash. Run it with `python examples/lossy_pruning.py`.
54
+ The versioned inputs and source provenance for these headline figures live in
55
+ [`tests/fixtures/readme_metrics.json`](tests/fixtures/readme_metrics.json).
54
56
 
55
57
  ### Fine-tuned relevance ranking
56
58
 
57
- [Tokenfold Select][tokenfold-select] is the optional query-aware model for
59
+ [Tokenfold Select][tokenfold-select] is an optional external query-aware model for
58
60
  choosing what fills a tight context window after structural compression ends.
61
+ It is distributed and evaluated separately; Tokenfold Core does not invoke it.
59
62
 
60
63
  | Token budget kept | Tokenfold Select task success | BM25 reference | Lift |
61
64
  | ---: | ---: | ---: | ---: |
@@ -70,6 +73,8 @@ three-seed repeated subsampling over roughly 73,000 training and 24,000
70
73
  held-out fixtures per run; the [model card][tokenfold-select] publishes the
71
74
  training recipe and full baseline set. Here, task success means the literal
72
75
  gold answer survived selection under the stated budget.
76
+ These are source-reported external results, pinned by model revision in the
77
+ [metric manifest](tests/fixtures/readme_metrics.json); Core CI does not reproduce them.
73
78
 
74
79
  ## One platform, two engines
75
80
 
@@ -78,7 +83,7 @@ gold answer survived selection under the stated budget.
78
83
  | **Tokenfold Core** | Fast deterministic compression for JSON, schemas, provider requests, logs, diffs, and command output |
79
84
  | **Recoverable pruning** | Drop low-signal JSON rows only after storing them locally; fetch any omission with `tokenfold retrieve` |
80
85
  | **Tokenfold Select** | LoRA-fine-tuned, query-aware span ranking with up to **15.8% lift** over BM25 at the same budget |
81
- | **Budget control** | Conservative, balanced, and aggressive modes; nine task scopes; `--target-tokens` with honest best-effort reporting |
86
+ | **Budget control** | Conservative, balanced, and aggressive presets; nine task scopes; `--target-tokens` with honest best-effort reporting |
82
87
  | **Exact receipts** | Before/after token counts, applied transforms, warnings, provenance, and final status on every call |
83
88
  | **Realized savings** | `gain`, `stats`, and `session` report measured savings; `learn` proposes policy improvements without silently applying them |
84
89
  | **Every integration** | CLI, Python, TypeScript, Rust, HTTP proxy, and MCP share the same Core engine and report shape |
@@ -86,11 +91,11 @@ gold answer survived selection under the stated budget.
86
91
 
87
92
  ### Lossless or recoverable lossy
88
93
 
89
- | | Lossless — default | Recoverable lossy — opt-in |
94
+ | | Lossless — default | Recoverable lossy — opt-in |
90
95
  | --- | --- | --- |
91
96
  | **What it does** | Minifies, folds repeated keys into columns, and stores repeated values once | Adds deterministic ranking and retrieval markers for selected array rows |
92
97
  | **Best on** | Uniform records, schemas, logs, diffs | Search results, mixed event feeds, agent traces, long arrays |
93
- | **Measured here** | **45.6–67.6%** fewer tokens | **39.3–91.7%** fewer tokens |
98
+ | **Measured here** | **45.6–67.6%** fewer tokens | **51.7–91.7%** fewer tokens |
94
99
  | **Recovery** | All data remains in the payload | Every emitted marker resolves through the local retrieval store |
95
100
 
96
101
  ## Quick start
@@ -104,7 +109,7 @@ cargo add tokenfold-core # Rust library
104
109
  cargo install tokenfold-cli # Rust CLI
105
110
  ```
106
111
 
107
- Or download a signed CLI build for Linux, macOS, or Windows from
112
+ Or download a checksummed CLI build for Linux, macOS, or Windows from
108
113
  [GitHub Releases](https://github.com/snchimata/tokenfold/releases/latest) and
109
114
  verify it with the adjacent `.sha256` file.
110
115
 
@@ -121,11 +126,12 @@ Python uses the same Core engine and typed receipt:
121
126
  import json
122
127
  from pathlib import Path
123
128
 
124
- from tokenfold import CompressionMode, compress_openai_payload
129
+ from tokenfold import InputFormat, Preset, compress
125
130
 
126
- result = compress_openai_payload(
127
- Path("request.json").read_text(),
128
- mode=CompressionMode.BALANCED,
131
+ result = compress(
132
+ Path("request.json").read_bytes(),
133
+ format=InputFormat.OPENAI_JSON,
134
+ preset=Preset.BALANCED,
129
135
  )
130
136
  compressed_request = json.loads(result.payload)
131
137
  print(f"saved {result.report.saved_tokens} tokens ({result.saved_pct():.1f}%)")
@@ -133,15 +139,18 @@ print(f"saved {result.report.saved_tokens} tokens ({result.saved_pct():.1f}%)")
133
139
 
134
140
  | Surface | Best for | Start here |
135
141
  | --- | --- | --- |
136
- | CLI | Files, stdin, diffs, and command output | `tokenfold compress`, `inspect`, `diff`, `wrap` |
142
+ | CLI | Files and stdin | `tokenfold compress`, `inspect`, `decode`, `retrieve` |
137
143
  | Python | Applications and evaluation pipelines | `pip install tokenfold` |
138
144
  | TypeScript | Node.js applications and automation | `npm install tokenfold` |
139
145
  | Rust | Native embedding | `cargo add tokenfold-core` |
140
146
  | HTTP proxy | Transparent provider-shaped traffic | Build `tokenfold-proxy` |
141
147
  | MCP | Agents and editors | `tokenfold mcp serve` |
142
148
 
143
- `tokenfold init --agent <agent>` installs a durable host integration;
144
- `tokenfold doctor` verifies it. Trusted filters for Git, build, and test output
149
+ `tokenfold init --agent claude-code` merges a project-scoped `.mcp.json` entry without replacing
150
+ other servers; `tokenfold doctor --agent claude-code` verifies it. Codex can use the same stdio
151
+ server with `codex mcp add tokenfold -- tokenfold mcp serve`. See
152
+ [`docs/configuration.md`](docs/configuration.md) for tested MCP JSON/TOML and every environment
153
+ override. Trusted filters for Git, build, and test output
145
154
  are available through `tokenfold filters list`.
146
155
 
147
156
  Runnable examples, one per surface, all under [`examples/`](examples):
@@ -153,49 +162,50 @@ cargo run -p tokenfold-core --example quickstart # Rust: the embedded core API
153
162
  python examples/lossy_pruning.py # CLI: opt-in recoverable pruning, end to end
154
163
  ```
155
164
 
156
- [`examples/quickstart.ipynb`](examples/quickstart.ipynb) is the notebook form of the
157
- Python quickstart, one operation per cell.
165
+ [`examples/quickstart.ipynb`](examples/quickstart.ipynb) is the guided tour of the whole
166
+ Python surface: everything `quickstart.py` shows, plus previews, budgets and presets,
167
+ provider payloads, recoverable pruning with retrieval, and where Tokenfold Select fits.
158
168
 
159
169
  ## Recoverable lossy pruning
160
170
 
161
- Lossless folding has a ceiling on heterogeneous arrays. `--lossy` ranks rows,
171
+ Lossless folding has a ceiling on heterogeneous arrays. `--prune` ranks rows,
162
172
  keeps the strongest signals, and replaces selected rows with compact
163
173
  `{"$tf_ref": {...}}` handles. A row leaves the payload only after the local
164
174
  store accepts it.
165
175
 
166
176
  ```bash
167
177
  tokenfold compress examples/incident_feed.json --format json \
168
- --lossy heuristic --lossy-ratio 0.35 --output feed.compact.json
178
+ --prune --keep-ratio 0.35 --output feed.compact.json
169
179
  ```
170
180
 
171
181
  On the bundled 40-event feed:
172
182
 
173
183
  | Mode | Exact tokens | Reduction | Events kept | Incident kept |
174
184
  | --- | ---: | ---: | ---: | :---: |
175
- | Lossless | 2,840 | 28.1% | 40 | ✅ |
176
- | `--lossy-ratio 0.35` | 2,399 | **39.3%** | 13 | ✅ |
177
- | `--lossy-ratio 0.05` | 2,192 | **44.5%** | 2 | ✅ |
185
+ | Lossless | 6,144 | 14.9% | 40 | ✅ |
186
+ | `--keep-ratio 0.35` | 3,485 | **51.7%** | 13 | ✅ |
187
+ | `--keep-ratio 0.05` | 2,294 | **68.2%** | 1 | ✅ |
178
188
 
179
189
  The planted `503` with `success: false` and `retries: 7` survives every shown
180
- setting because typed failure signals outrank position and length. Long rows
190
+ setting because typed failure signals outrank position and length — at
191
+ `--keep-ratio 0.05` it is the only row kept. Long rows
181
192
  amortize marker overhead further: the 100-result showcase reaches **91.7%**.
182
193
 
183
194
  Fetch a dropped row:
184
195
 
185
196
  ```bash
186
- tokenfold retrieve 978339a8898fedde3c5b0662a213f12ae4ad1b7fe6771f62b3c3d74d87389a4c
197
+ tokenfold retrieve cb13cc59cca0c218c579cd1d4b3cbab58d6dea265eb995cc9c00faf0cd0a6856
187
198
  # {"seq":1,"ts":"2026-08-15T00:01:11Z","subsystem":"index-writer",...}
188
199
  ```
189
200
 
190
201
  What the flags mean:
191
202
 
192
- - `--lossy-ratio` is an aggression hint over eligible array items. Lower keeps
203
+ - `--keep-ratio` is an aggression hint over eligible array items. Lower keeps
193
204
  fewer rows; it is not a whole-document guarantee.
194
205
  - `--target-tokens` is the whole-document goal. Tokenfold stops when it reaches
195
206
  the target losslessly and reports `best_effort` when the safe transform set
196
- cannot reach it (`unreachable_target` when protected content alone exceeds
197
- the target).
198
- - `--lossy-preserve <path>` protects a named array; nested paths conservatively
207
+ cannot reach it (`unreachable` when protected content alone exceeds the target).
208
+ - `--preserve <path>` protects a named array; nested paths conservatively
199
209
  protect their nearest eligible ancestor.
200
210
  - Generic JSON only: lossy pruning does not run on OpenAI or Anthropic message
201
211
  payloads.
@@ -205,18 +215,18 @@ What the flags mean:
205
215
  Preview the projected savings with no store writes:
206
216
 
207
217
  ```bash
208
- tokenfold compress examples/incident_feed.json --format json \
209
- --lossy heuristic --lossy-ratio 0.35 --dry-run
218
+ tokenfold inspect examples/incident_feed.json --format json \
219
+ --prune --keep-ratio 0.35
210
220
  ```
211
221
 
212
222
  The same flags, and the same fail-closed contract, from Python and TypeScript:
213
223
 
214
224
  ```python
215
- from tokenfold import CompressionPolicy, InputFormat, LossyPath, compress, retrieve
225
+ from tokenfold import InputFormat, PruningPolicy, compress, retrieve
216
226
 
217
- policy = CompressionPolicy(lossy=LossyPath.HEURISTIC, lossy_ratio=0.35)
218
- result = compress(feed_bytes, format=InputFormat.JSON, policy=policy)
219
- original = retrieve(marker["$tf_ref"]["hash"]) # any dropped row, verbatim
227
+ pruning = PruningPolicy(keep_ratio=0.35)
228
+ result = compress(feed_bytes, format=InputFormat.JSON, pruning=pruning)
229
+ original = retrieve(marker["$tf_ref"]) # any dropped row, verbatim
220
230
  ```
221
231
 
222
232
  ```ts
@@ -224,8 +234,7 @@ import { compress, retrieve } from "tokenfold";
224
234
 
225
235
  const { payload, report } = await compress(feed, {
226
236
  format: "json",
227
- lossy: "heuristic",
228
- lossyRatio: 0.35,
237
+ pruning: { keepRatio: 0.35 },
229
238
  });
230
239
  const original = await retrieve(hash); // any dropped row, verbatim
231
240
  ```
@@ -234,9 +243,8 @@ const original = await retrieve(hash); // any dropped row, verbatim
234
243
  <summary><strong>Current Phase 1 constraints</strong></summary>
235
244
 
236
245
  Treat `$tf_ref` as reserved and do not enable lossy pruning on documents that
237
- already contain retrieval markers. A filesystem failure after partial writes
238
- may also leave unreferenced entries until their configured TTL expires. Both
239
- require location-based transactional materialization before promotion.
246
+ already contain retrieval markers. Filesystem entries are published under a
247
+ cross-process lock, and a refused batch leaves every candidate inline.
240
248
 
241
249
  Preview is a projection rather than a filesystem transaction, so a real run may
242
250
  keep more rows if storage becomes unavailable.
@@ -250,8 +258,8 @@ keep more rows if storage becomes unavailable.
250
258
  Tokenfold Select is an Apache-2.0 LoRA adapter on
251
259
  `ibm-granite/granite-embedding-reranker-english-r2`. It scores candidate spans
252
260
  against a query; your allocator applies the token budget and force-keeps
253
- required content. Core remains model-free and deterministic, while Select adds
254
- relevance when lexical heuristics stop being enough.
261
+ required content. It is a separately distributed companion: Core remains
262
+ model-free and deterministic and neither loads nor invokes Select.
255
263
 
256
264
  | | Tokenfold Core | Tokenfold Select |
257
265
  | --- | --- | --- |
@@ -318,6 +326,12 @@ training data, and limitations.
318
326
  - **Local control:** detected secrets are redacted before reports or storage;
319
327
  policy learning changes configuration only with `--apply`.
320
328
 
329
+ The offline fidelity gate uses deterministic lexical-overlap, critical-token,
330
+ and containment proxies. Those checks catch regressions but do not establish
331
+ semantic equivalence or downstream task success. Runtime `quality` fields are
332
+ absent unless a versioned evaluator has supplied data; applications should run
333
+ their own representative task evaluation before enabling lossy pruning.
334
+
321
335
  ## Reproduce the results
322
336
 
323
337
  ```bash
@@ -332,8 +346,8 @@ cargo run --release --locked -p tokenfold-cli -- \
332
346
  inspect examples/api_response.json --format json
333
347
  ```
334
348
 
335
- The small bundled API response reports 382 → 206 tokens, a **46.1% lossless
336
- reduction**. Benchmark sources and thresholds live in [CHANGELOG.md](https://github.com/snchimata/tokenfold/blob/main/CHANGELOG.md)
349
+ The bundled 30-record API response reports 3,812 → 1,376 tokens, a **63.9%
350
+ lossless reduction**. Benchmark sources and thresholds live in [CHANGELOG.md](https://github.com/snchimata/tokenfold/blob/main/CHANGELOG.md)
337
351
  and [`crates/tokenfold-core/benches/THRESHOLDS.toml`](https://github.com/snchimata/tokenfold/blob/main/crates/tokenfold-core/benches/THRESHOLDS.toml).
338
352
 
339
353
  ## Contributing
@@ -362,7 +376,7 @@ tokens your application can stop sending today.
362
376
  pip install tokenfold
363
377
  ```
364
378
 
365
- If Tokenfold earns a place in your stack, a ⭐ on
379
+ If Tokenfold earns a place in your stack, a ⭐ on
366
380
  [GitHub](https://github.com/snchimata/tokenfold) helps the next team find it.
367
381
 
368
382
  [tokenfold-select]: https://huggingface.co/snchimata/tokenfold-select