tokenfold 0.4.0__tar.gz → 0.4.1__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.0 → tokenfold-0.4.1}/Cargo.lock +10 -10
  2. {tokenfold-0.4.0 → tokenfold-0.4.1}/Cargo.toml +1 -1
  3. {tokenfold-0.4.0 → tokenfold-0.4.1}/PKG-INFO +36 -11
  4. {tokenfold-0.4.0 → tokenfold-0.4.1}/README.md +35 -10
  5. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/benches/THRESHOLDS.toml +1 -1
  6. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/benches/compression_bench.rs +2 -2
  7. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/src/budget.rs +16 -16
  8. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/src/errors.rs +6 -1
  9. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/src/filters.rs +8 -8
  10. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/src/modes.rs +17 -15
  11. tokenfold-0.4.1/crates/tokenfold-core/src/pipeline/mod.rs +1010 -0
  12. tokenfold-0.4.1/crates/tokenfold-core/src/pipeline/tests.rs +1287 -0
  13. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/src/report.rs +5 -5
  14. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/src/retrieval_store.rs +3 -3
  15. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/src/safety.rs +3 -1
  16. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/src/stats.rs +16 -15
  17. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/src/transforms/diff.rs +4 -6
  18. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/src/transforms/json_prune.rs +1 -2
  19. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/src/transforms/logs.rs +4 -4
  20. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/tests/golden.rs +3 -1
  21. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/tests/integration.rs +1 -1
  22. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/tests/property_tests.rs +1 -1
  23. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-py/Cargo.toml +1 -1
  24. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-py/src/lib.rs +255 -31
  25. tokenfold-0.4.0/crates/tokenfold-core/examples/quickstart.rs +0 -83
  26. tokenfold-0.4.0/crates/tokenfold-core/src/pipeline.rs +0 -2301
  27. {tokenfold-0.4.0 → tokenfold-0.4.1}/LICENSE +0 -0
  28. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/Cargo.toml +0 -0
  29. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/src/input.rs +0 -0
  30. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/src/lib.rs +0 -0
  31. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/src/status.rs +0 -0
  32. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/src/token_estimator.rs +0 -0
  33. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/src/transforms/json.rs +0 -0
  34. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/src/transforms/json_dict.rs +0 -0
  35. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/src/transforms/json_fold.rs +0 -0
  36. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/src/transforms/log_fold.rs +0 -0
  37. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/src/transforms/mod.rs +0 -0
  38. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/src/transforms/redaction.rs +0 -0
  39. {tokenfold-0.4.0 → tokenfold-0.4.1}/crates/tokenfold-core/src/transforms/schema.rs +0 -0
  40. {tokenfold-0.4.0 → tokenfold-0.4.1}/pyproject.toml +0 -0
@@ -1013,7 +1013,7 @@ dependencies = [
1013
1013
 
1014
1014
  [[package]]
1015
1015
  name = "tokenfold-adapters"
1016
- version = "0.4.0"
1016
+ version = "0.4.1"
1017
1017
  dependencies = [
1018
1018
  "serde",
1019
1019
  "serde_json",
@@ -1022,7 +1022,7 @@ dependencies = [
1022
1022
 
1023
1023
  [[package]]
1024
1024
  name = "tokenfold-admin"
1025
- version = "0.4.0"
1025
+ version = "0.4.1"
1026
1026
  dependencies = [
1027
1027
  "ed25519-dalek",
1028
1028
  "serde",
@@ -1032,7 +1032,7 @@ dependencies = [
1032
1032
 
1033
1033
  [[package]]
1034
1034
  name = "tokenfold-cli"
1035
- version = "0.4.0"
1035
+ version = "0.4.1"
1036
1036
  dependencies = [
1037
1037
  "clap",
1038
1038
  "serde",
@@ -1045,7 +1045,7 @@ dependencies = [
1045
1045
 
1046
1046
  [[package]]
1047
1047
  name = "tokenfold-core"
1048
- version = "0.4.0"
1048
+ version = "0.4.1"
1049
1049
  dependencies = [
1050
1050
  "proptest",
1051
1051
  "regex",
@@ -1059,25 +1059,25 @@ dependencies = [
1059
1059
 
1060
1060
  [[package]]
1061
1061
  name = "tokenfold-image"
1062
- version = "0.4.0"
1062
+ version = "0.4.1"
1063
1063
 
1064
1064
  [[package]]
1065
1065
  name = "tokenfold-learn"
1066
- version = "0.4.0"
1066
+ version = "0.4.1"
1067
1067
  dependencies = [
1068
1068
  "tokenfold-core",
1069
1069
  ]
1070
1070
 
1071
1071
  [[package]]
1072
1072
  name = "tokenfold-output"
1073
- version = "0.4.0"
1073
+ version = "0.4.1"
1074
1074
  dependencies = [
1075
1075
  "tokenfold-core",
1076
1076
  ]
1077
1077
 
1078
1078
  [[package]]
1079
1079
  name = "tokenfold-proxy"
1080
- version = "0.4.0"
1080
+ version = "0.4.1"
1081
1081
  dependencies = [
1082
1082
  "clap",
1083
1083
  "serde",
@@ -1089,7 +1089,7 @@ dependencies = [
1089
1089
 
1090
1090
  [[package]]
1091
1091
  name = "tokenfold-py"
1092
- version = "0.4.0"
1092
+ version = "0.4.1"
1093
1093
  dependencies = [
1094
1094
  "pyo3",
1095
1095
  "serde_json",
@@ -1098,7 +1098,7 @@ dependencies = [
1098
1098
 
1099
1099
  [[package]]
1100
1100
  name = "tokenfold-rag"
1101
- version = "0.4.0"
1101
+ version = "0.4.1"
1102
1102
 
1103
1103
  [[package]]
1104
1104
  name = "toml"
@@ -3,7 +3,7 @@ resolver = "2"
3
3
  members = ["crates/tokenfold-core", "crates/tokenfold-py"]
4
4
 
5
5
  [workspace.package]
6
- version = "0.4.0"
6
+ version = "0.4.1"
7
7
  edition = "2024"
8
8
  rust-version = "1.97"
9
9
  license = "Apache-2.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tokenfold
3
- Version: 0.4.0
3
+ Version: 0.4.1
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: Apache Software License
@@ -30,7 +30,7 @@ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
30
30
 
31
31
  CLI · Python · TypeScript · Rust · proxy · MCP · local-first · provider-neutral
32
32
 
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)](LICENSE)
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
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
 
@@ -144,13 +144,18 @@ print(f"saved {result.report.saved_tokens} tokens ({result.saved_pct():.1f}%)")
144
144
  `tokenfold doctor` verifies it. Trusted filters for Git, build, and test output
145
145
  are available through `tokenfold filters list`.
146
146
 
147
- Runnable examples:
147
+ Runnable examples, one per surface, all under [`examples/`](examples):
148
148
 
149
149
  ```bash
150
- python examples/quickstart.py
151
- python examples/lossy_pruning.py
150
+ python examples/quickstart.py # Python: compress messages, request bodies, JSON data
151
+ node examples/quickstart.mjs # TypeScript/Node: compress, inspect, read the receipt
152
+ cargo run -p tokenfold-core --example quickstart # Rust: the embedded core API
153
+ python examples/lossy_pruning.py # CLI: opt-in recoverable pruning, end to end
152
154
  ```
153
155
 
156
+ [`examples/quickstart.ipynb`](examples/quickstart.ipynb) is the notebook form of the
157
+ Python quickstart, one operation per cell.
158
+
154
159
  ## Recoverable lossy pruning
155
160
 
156
161
  Lossless folding has a ceiling on heterogeneous arrays. `--lossy` ranks rows,
@@ -204,6 +209,27 @@ tokenfold compress examples/incident_feed.json --format json \
204
209
  --lossy heuristic --lossy-ratio 0.35 --dry-run
205
210
  ```
206
211
 
212
+ The same flags, and the same fail-closed contract, from Python and TypeScript:
213
+
214
+ ```python
215
+ from tokenfold import CompressionPolicy, InputFormat, LossyPath, compress, retrieve
216
+
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
220
+ ```
221
+
222
+ ```ts
223
+ import { compress, retrieve } from "tokenfold";
224
+
225
+ const { payload, report } = await compress(feed, {
226
+ format: "json",
227
+ lossy: "heuristic",
228
+ lossyRatio: 0.35,
229
+ });
230
+ const original = await retrieve(hash); // any dropped row, verbatim
231
+ ```
232
+
207
233
  <details>
208
234
  <summary><strong>Current Phase 1 constraints</strong></summary>
209
235
 
@@ -212,9 +238,8 @@ already contain retrieval markers. A filesystem failure after partial writes
212
238
  may also leave unreferenced entries until their configured TTL expires. Both
213
239
  require location-based transactional materialization before promotion.
214
240
 
215
- Lossy pruning is CLI-only today; Python and TypeScript remain lossless. Preview
216
- is a projection rather than a filesystem transaction, so a real run may keep
217
- more rows if storage becomes unavailable.
241
+ Preview is a projection rather than a filesystem transaction, so a real run may
242
+ keep more rows if storage becomes unavailable.
218
243
 
219
244
  </details>
220
245
 
@@ -308,8 +333,8 @@ cargo run --release --locked -p tokenfold-cli -- \
308
333
  ```
309
334
 
310
335
  The small bundled API response reports 382 → 206 tokens, a **46.1% lossless
311
- reduction**. Benchmark sources and thresholds live in [CHANGELOG.md](CHANGELOG.md)
312
- and [`crates/tokenfold-core/benches/THRESHOLDS.toml`](crates/tokenfold-core/benches/THRESHOLDS.toml).
336
+ reduction**. Benchmark sources and thresholds live in [CHANGELOG.md](https://github.com/snchimata/tokenfold/blob/main/CHANGELOG.md)
337
+ and [`crates/tokenfold-core/benches/THRESHOLDS.toml`](https://github.com/snchimata/tokenfold/blob/main/crates/tokenfold-core/benches/THRESHOLDS.toml).
313
338
 
314
339
  ## Contributing
315
340
 
@@ -326,7 +351,7 @@ cd packages/tokenfold && npm ci && npm test
326
351
 
327
352
  ## License
328
353
 
329
- [Apache-2.0](LICENSE)
354
+ [Apache-2.0](https://github.com/snchimata/tokenfold/blob/main/LICENSE)
330
355
 
331
356
  ---
332
357
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  CLI · Python · TypeScript · Rust · proxy · MCP · local-first · provider-neutral
10
10
 
11
- [![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)](LICENSE)
11
+ [![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)
12
12
 
13
13
  [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)
14
14
 
@@ -122,13 +122,18 @@ print(f"saved {result.report.saved_tokens} tokens ({result.saved_pct():.1f}%)")
122
122
  `tokenfold doctor` verifies it. Trusted filters for Git, build, and test output
123
123
  are available through `tokenfold filters list`.
124
124
 
125
- Runnable examples:
125
+ Runnable examples, one per surface, all under [`examples/`](examples):
126
126
 
127
127
  ```bash
128
- python examples/quickstart.py
129
- python examples/lossy_pruning.py
128
+ python examples/quickstart.py # Python: compress messages, request bodies, JSON data
129
+ node examples/quickstart.mjs # TypeScript/Node: compress, inspect, read the receipt
130
+ cargo run -p tokenfold-core --example quickstart # Rust: the embedded core API
131
+ python examples/lossy_pruning.py # CLI: opt-in recoverable pruning, end to end
130
132
  ```
131
133
 
134
+ [`examples/quickstart.ipynb`](examples/quickstart.ipynb) is the notebook form of the
135
+ Python quickstart, one operation per cell.
136
+
132
137
  ## Recoverable lossy pruning
133
138
 
134
139
  Lossless folding has a ceiling on heterogeneous arrays. `--lossy` ranks rows,
@@ -182,6 +187,27 @@ tokenfold compress examples/incident_feed.json --format json \
182
187
  --lossy heuristic --lossy-ratio 0.35 --dry-run
183
188
  ```
184
189
 
190
+ The same flags, and the same fail-closed contract, from Python and TypeScript:
191
+
192
+ ```python
193
+ from tokenfold import CompressionPolicy, InputFormat, LossyPath, compress, retrieve
194
+
195
+ policy = CompressionPolicy(lossy=LossyPath.HEURISTIC, lossy_ratio=0.35)
196
+ result = compress(feed_bytes, format=InputFormat.JSON, policy=policy)
197
+ original = retrieve(marker["$tf_ref"]["hash"]) # any dropped row, verbatim
198
+ ```
199
+
200
+ ```ts
201
+ import { compress, retrieve } from "tokenfold";
202
+
203
+ const { payload, report } = await compress(feed, {
204
+ format: "json",
205
+ lossy: "heuristic",
206
+ lossyRatio: 0.35,
207
+ });
208
+ const original = await retrieve(hash); // any dropped row, verbatim
209
+ ```
210
+
185
211
  <details>
186
212
  <summary><strong>Current Phase 1 constraints</strong></summary>
187
213
 
@@ -190,9 +216,8 @@ already contain retrieval markers. A filesystem failure after partial writes
190
216
  may also leave unreferenced entries until their configured TTL expires. Both
191
217
  require location-based transactional materialization before promotion.
192
218
 
193
- Lossy pruning is CLI-only today; Python and TypeScript remain lossless. Preview
194
- is a projection rather than a filesystem transaction, so a real run may keep
195
- more rows if storage becomes unavailable.
219
+ Preview is a projection rather than a filesystem transaction, so a real run may
220
+ keep more rows if storage becomes unavailable.
196
221
 
197
222
  </details>
198
223
 
@@ -286,8 +311,8 @@ cargo run --release --locked -p tokenfold-cli -- \
286
311
  ```
287
312
 
288
313
  The small bundled API response reports 382 → 206 tokens, a **46.1% lossless
289
- reduction**. Benchmark sources and thresholds live in [CHANGELOG.md](CHANGELOG.md)
290
- and [`crates/tokenfold-core/benches/THRESHOLDS.toml`](crates/tokenfold-core/benches/THRESHOLDS.toml).
314
+ reduction**. Benchmark sources and thresholds live in [CHANGELOG.md](https://github.com/snchimata/tokenfold/blob/main/CHANGELOG.md)
315
+ and [`crates/tokenfold-core/benches/THRESHOLDS.toml`](https://github.com/snchimata/tokenfold/blob/main/crates/tokenfold-core/benches/THRESHOLDS.toml).
291
316
 
292
317
  ## Contributing
293
318
 
@@ -304,7 +329,7 @@ cd packages/tokenfold && npm ci && npm test
304
329
 
305
330
  ## License
306
331
 
307
- [Apache-2.0](LICENSE)
332
+ [Apache-2.0](https://github.com/snchimata/tokenfold/blob/main/LICENSE)
308
333
 
309
334
  ---
310
335
 
@@ -2,7 +2,7 @@
2
2
  # Measured 2026-07-11 on AMD Ryzen 7 9800X3D (8c/16t), 31GB RAM, Windows, rustc 1.97.0,
3
3
  # `cargo bench -p tokenfold-core` release profile. See CHANGELOG.md for the full reproducibility
4
4
  # record. Thresholds carry ~1.3-1.5x headroom over the measured baseline for runner variance;
5
- # tighten once `bench-regression` has run on a dedicated CI runner (R-014).
5
+ # tighten once `bench-regression` has run on a dedicated, fixed-spec CI runner.
6
6
  #
7
7
  # p95 latency — dominated by TiktokenEstimator::o200k_base() reloading BPE ranks on every
8
8
  # `compress()` call (the public API doesn't cache the estimator across calls) plus tiktoken-rs's
@@ -1,6 +1,6 @@
1
- //! Task 7 benchmark suite (ROADMAP.md Phase 4 / ENGINEERING.md "Benchmark Tests").
1
+ //! Benchmark suite for `compress`: a p95-latency and bytes-allocated regression gate.
2
2
  //!
3
- //! ponytail: ENGINEERING.md names `criterion` + `divan` as the tools here. Both pull in real
3
+ //! ponytail: the conventional picks here are `criterion` + `divan`. Both pull in real
4
4
  //! dependency trees (criterion: plotting/serde chain; divan: its own harness+macros) for what
5
5
  //! this project actually needs: a p95-latency and bytes-allocated regression gate against a
6
6
  //! checked-in threshold file. `std::time::Instant` + a custom counting `GlobalAlloc` do the same
@@ -5,9 +5,9 @@ use crate::input::{CompressionInput, InputFormat};
5
5
  use crate::token_estimator::TokenEstimator;
6
6
 
7
7
  /// Placeholder floor for `retrieval_ttl_seconds` whenever `lossy` is set — see
8
- /// `CompressionPolicyBuilder::build`'s lossy validation. The design doc lists the exact policy
9
- /// as an open owner decision (docs/solution-design/lossy-json-compression.md §8), not yet
10
- /// confirmed; this value only needs to be "clearly more than instant," not final.
8
+ /// `CompressionPolicyBuilder::build`'s lossy validation. The exact retention policy is still an
9
+ /// open owner decision, not yet confirmed; this value only needs to be "clearly more than
10
+ /// instant," not final.
11
11
  const MIN_LOSSY_TTL_SECONDS: u64 = 86_400;
12
12
 
13
13
  // NOT Eq: `lossy_ratio` holds an f64 (same precedent as `CompressionOutput`/`CompressionReport`).
@@ -29,30 +29,30 @@ pub struct CompressionPolicy {
29
29
  /// entry doesn't enable it for the current mode. Still requires `experimental` for any
30
30
  /// transform whose `ModeEntry.experimental == true` (see `modes::pipeline_for`).
31
31
  pub enable: Vec<String>,
32
- /// F-045: when true, and the full pre-transform input contains no secret-shaped content,
32
+ /// When true, and the full pre-transform input contains no secret-shaped content,
33
33
  /// `pipeline::compress_with_estimator` persists it to the reversible evidence store
34
34
  /// (`retrieval_backend`/`retrieval_store_path`) under its SHA-256 hash.
35
35
  pub store_originals: bool,
36
- /// F-045: the namespace stored-original entries are keyed under (see
36
+ /// The evidence-store namespace stored-original entries are keyed under (see
37
37
  /// `retrieval_store::RetrievalStore::store`).
38
38
  pub retrieval_namespace: String,
39
- /// F-045: TTL passed to `RetrievalStore::store` for newly stored originals. `None` means
39
+ /// TTL passed to `RetrievalStore::store` for newly stored originals. `None` means
40
40
  /// "use `retrieval_store::DEFAULT_TTL_SECONDS`" (this is a *default*, not "never expire" —
41
41
  /// that per-entry meaning belongs to `RetrievalStore::store`'s own `ttl_seconds` parameter).
42
42
  pub retrieval_ttl_seconds: Option<u64>,
43
- /// F-045: backend name passed to `RetrievalStore::open` ("memory" | "filesystem" |
43
+ /// Backend name passed to `RetrievalStore::open` ("memory" | "filesystem" |
44
44
  /// "sqlite" — the latter fails clearly, handled as best-effort skip, see
45
45
  /// `pipeline::maybe_store_originals`).
46
46
  pub retrieval_backend: String,
47
- /// F-045: filesystem backend root override. `None` means
47
+ /// Filesystem backend root override. `None` means
48
48
  /// `retrieval_store::default_store_path()`.
49
49
  pub retrieval_store_path: Option<PathBuf>,
50
- /// Opt-in lossy JSON array-item selection (`docs/solution-design/lossy-json-compression.md`,
51
- /// local-only). `None` (the default) means the lossless pipeline is untouched — this field
52
- /// is set only by an explicit CLI flag, never derived from `mode`/`experimental`, and is
53
- /// deliberately NOT part of `modes.rs`/`ALL_ENTRIES`: it is a fundamentally different
54
- /// category (data-lossy, not just structurally-lossy-but-reversible) from every other
55
- /// transform in this crate. See `pipeline::apply_lossy_reduction`.
50
+ /// Opt-in lossy JSON array-item selection: array items are dropped and replaced by a
51
+ /// recoverable `$tf_ref` marker. `None` (the default) means the lossless pipeline is
52
+ /// untouched — this field is set only by an explicit CLI flag, never derived from
53
+ /// `mode`/`experimental`, and is deliberately NOT part of `modes.rs`/`ALL_ENTRIES`: it is a
54
+ /// fundamentally different category (data-lossy, not just structurally-lossy-but-reversible)
55
+ /// from every other transform in this crate. See `pipeline::apply_lossy_reduction`.
56
56
  pub lossy: Option<LossyPath>,
57
57
  /// BEST-EFFORT selection hint, not an enforced budget: how aggressively to prune, as the
58
58
  /// fraction (0.0..=1.0) of the prunable pool's own estimated token cost to keep when `lossy`
@@ -422,8 +422,8 @@ fn message_content_bytes(message: &serde_json::Value) -> Option<Vec<u8>> {
422
422
  }
423
423
  }
424
424
 
425
- /// Keeps file names and hunk headers, matching the `diff_compaction` (F-013) contract of what
426
- /// must survive compaction. Each kept line is its own segment.
425
+ /// Keeps file names and hunk headers, matching the `diff_compaction` contract of what must
426
+ /// survive compaction. Each kept line is its own segment.
427
427
  fn extract_diff_protected(bytes: &[u8]) -> Vec<Vec<u8>> {
428
428
  let text = String::from_utf8_lossy(bytes);
429
429
  let mut segments = Vec::new();
@@ -17,7 +17,12 @@ pub enum TokenFoldError {
17
17
  }
18
18
 
19
19
  impl TokenFoldError {
20
- /// CLI exit code per the Error Taxonomy table (PLAN.md / INTERFACES.md §1.4).
20
+ /// Stable CLI exit code for this error: 2 invalid input, 3 safety/redaction violation,
21
+ /// 4 estimator failure, 5 bad configuration, 6 internal or I/O failure. Every successful
22
+ /// [`crate::Status`] outcome — including `UnreachableTarget`, which is a typed result and
23
+ /// not an error — exits 0. The proxy's HTTP status mapping and the Python binding's
24
+ /// exception hierarchy are derived from these same buckets, so the numbering is a public
25
+ /// contract; `exit_codes_match_error_taxonomy_table` below pins it.
21
26
  pub fn exit_code(&self) -> i32 {
22
27
  match self {
23
28
  TokenFoldError::InvalidInput(_) => 2,
@@ -1,5 +1,5 @@
1
- //! F-047: declarative command-output filter registry (`roadmap.md` F-047, `interfaces.md`
2
- //! §7.2 "Filter Pack Contract" and §7.3 "Filter Trust Contract").
1
+ //! Declarative command-output filter registry: the filter-pack schema, its stage-execution
2
+ //! engine, and the trust store that gates project- and user-authored packs.
3
3
  //!
4
4
  //! Filter packs are TOML documents describing an ordered list of pure text-transform "stages"
5
5
  //! (`strip_ansi`, `replace`, `keep_lines`, `strip_lines`, `head`, `tail`, `max_lines`,
@@ -218,7 +218,7 @@ impl FixtureCheck {
218
218
  }
219
219
 
220
220
  // ---------------------------------------------------------------------------------------------
221
- // Regex complexity guard (R-017 defense-in-depth; see module doc)
221
+ // Regex complexity guard (defense-in-depth against hostile filter patterns; see module doc)
222
222
  // ---------------------------------------------------------------------------------------------
223
223
 
224
224
  fn check_pattern_safety(pattern: &str) -> Result<(), TokenFoldError> {
@@ -407,7 +407,7 @@ pub fn never_worse(raw: &[u8], filtered: &[u8]) -> NeverWorseOutcome {
407
407
  }
408
408
 
409
409
  // ---------------------------------------------------------------------------------------------
410
- // Trust store (interfaces.md §7.3)
410
+ // Trust store
411
411
  // ---------------------------------------------------------------------------------------------
412
412
 
413
413
  #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
@@ -541,7 +541,7 @@ pub struct FilterLookup<'a> {
541
541
  pub project_filters_path: Option<&'a Path>,
542
542
  pub user_filters_path: Option<&'a Path>,
543
543
  pub trust_store_path: &'a Path,
544
- /// `TOKENFOLD_TRUST_PROJECT_FILTERS=1` (interfaces.md §7.3): bypasses the trust-store check
544
+ /// `TOKENFOLD_TRUST_PROJECT_FILTERS=1`: bypasses the trust-store check
545
545
  /// for the *project* tier only (its literal name is the documented CI override, not a
546
546
  /// generic "trust everything" switch) — user-tier filters always require an explicit
547
547
  /// `filters trust` regardless of this flag.
@@ -642,10 +642,10 @@ pub fn parse_pack_file(path: &Path) -> Result<FilterPack, TokenFoldError> {
642
642
  }
643
643
 
644
644
  // ---------------------------------------------------------------------------------------------
645
- // Built-ins (D-002 dogfooding scope: git diff, git status, cargo build/test log framing)
645
+ // Built-ins (solo-dogfooding scope: git diff, git status, cargo build/test log framing)
646
646
  // ---------------------------------------------------------------------------------------------
647
647
 
648
- /// D-002's resolved first consumer is solo dogfooding (git diffs, build/test logs, agent
648
+ /// This project's first consumer is solo dogfooding (git diffs, build/test logs, agent
649
649
  /// tool-call JSON) — these three built-ins deliberately cover only that, not a broad command
650
650
  /// library. Encoded as Rust struct literals rather than parsed TOML strings: for packs this
651
651
  /// small, embedding multi-line fixture text in Rust raw strings and building the structs
@@ -785,7 +785,7 @@ fn build_test_log_pack() -> FilterPack {
785
785
  version: "1.0.0".to_string(),
786
786
  },
787
787
  filters: vec![Filter {
788
- // Generic cargo build/test log filter (D-002 dogfooding scope: this repo's own
788
+ // Generic cargo build/test log filter (dogfooding scope: this repo's own
789
789
  // `cargo test`/`cargo build`); `match_command = ["cargo"]` fires on any cargo
790
790
  // subcommand rather than one filter per subcommand, keeping this a single built-in.
791
791
  id: "cargo-build-test-log".to_string(),
@@ -4,7 +4,7 @@
4
4
  //! cannot be disabled (see `budget::CompressionPolicyBuilder::build`).
5
5
  //!
6
6
  //! `tests/fixtures/mode_matrix.toml` mirrors this table for cross-surface testing
7
- //! (INTERFACES.md Part 2 is the authoritative reference for both).
7
+ //! (this table is authoritative; the fixture must be kept in sync with it).
8
8
 
9
9
  use crate::budget::{CompressionMode, TaskScope};
10
10
  use crate::input::InputFormat;
@@ -71,12 +71,12 @@ impl ModeEntry {
71
71
  }
72
72
  }
73
73
 
74
- // Canonical ordered table — order here IS the pipeline execution order (INTERFACES.md Part 2:
75
- // lossless before lossy, higher-savings before lower-savings, within each mode).
74
+ // Canonical ordered table — order here IS the pipeline execution order (lossless before lossy,
75
+ // higher-savings before lower-savings, within each mode).
76
76
  //
77
- // ponytail: `table_compaction` is intentionally omitted. The First Consumer worksheet
78
- // (plan.md) doesn't name tables among the dominant payload types, so F-019 stays out of
79
- // scope until a consumer worksheet asks for it (roadmap.md F-019 dependency).
77
+ // ponytail: `table_compaction` is intentionally omitted. Tabular payloads aren't among this
78
+ // project's dominant input types, so a table transform stays out of scope until a real consumer
79
+ // asks for it.
80
80
  pub static ALL_ENTRIES: &[ModeEntry] = &[
81
81
  ModeEntry {
82
82
  transform_id: TransformId::JsonMinify,
@@ -164,11 +164,11 @@ pub static ALL_ENTRIES: &[ModeEntry] = &[
164
164
  ModeEntry {
165
165
  transform_id: TransformId::LogCompaction,
166
166
  version: "1.0.0",
167
- // Promoted out of --experimental (roadmap.md Phase 5 Task 9, 2026-07-12): the
168
- // full-lossy-promotion fidelity gate clears every D-005 draft threshold cleanly
167
+ // Promoted out of --experimental (Phase 5 fidelity gate, 2026-07-12): the
168
+ // full-lossy-promotion gate profile clears every draft fidelity threshold cleanly
169
169
  // (quality_retention=1.0, contrastive_failure_rate=0.0, critical_token_survival_rate=1.0).
170
- // conservative_enabled stays false — per plan.md's mode table, Conservative never runs
171
- // lossy-with-evidence transforms at all, same convention table_compaction documents.
170
+ // conservative_enabled stays false — Conservative never runs lossy-with-evidence
171
+ // transforms at all, same convention table_compaction documents.
172
172
  conservative_enabled: false,
173
173
  balanced_enabled: true,
174
174
  aggressive_enabled: true,
@@ -182,12 +182,14 @@ pub static ALL_ENTRIES: &[ModeEntry] = &[
182
182
  ModeEntry {
183
183
  transform_id: TransformId::DiffCompaction,
184
184
  version: "1.0.0",
185
- // Stays --experimental (roadmap.md Phase 5 Task 9, 2026-07-12 re-investigation): the
185
+ // Stays --experimental (Phase 5 fidelity gate, 2026-07-12 re-investigation): the
186
186
  // full-lossy-promotion gate's per_variant breakdown checked the default (body-preserving,
187
187
  // task_scope != ChangeSummary) and header-only (TaskScope::ChangeSummary) forms
188
- // separately, as F-013 requires, and BOTH miss the D-005 draft thresholds on their own
189
- // (default: quality_retention=0.36, contrastive_failure_rate=0.5, critical_token_survival=
190
- // 0.5). Root cause: compact_diff has no fallback for non-diff-shaped input — it drops
188
+ // separately, as diff_compaction's two documented forms require, and BOTH miss the draft
189
+ // fidelity thresholds on their own — the bar is quality_retention >= 0.95,
190
+ // contrastive_failure_rate <= 0.005, critical_token_survival >= 0.99, and the default form
191
+ // measured quality_retention=0.36, contrastive_failure_rate=0.5, critical_token_survival=
192
+ // 0.5. Root cause: compact_diff has no fallback for non-diff-shaped input — it drops
191
193
  // everything, critical tokens included, when no line matches a unified-diff prefix. See
192
194
  // eval/tasks/FIXTURES.md's "Scorer status" section for the full measured breakdown.
193
195
  conservative_enabled: false,
@@ -205,7 +207,7 @@ pub static ALL_ENTRIES: &[ModeEntry] = &[
205
207
  ],
206
208
  },
207
209
  // v0.2+ entries (table_compaction, prose_extraction, code_digest, conversation) added
208
- // here after their fidelity approval / D-002 scope decisions land.
210
+ // here after their fidelity approval / scope decisions land.
209
211
  ];
210
212
 
211
213
  /// Returns the ordered, applicable transform list for a given (mode, task_scope, format).