tensorfs 0.3.73__tar.gz → 0.3.75__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 (170) hide show
  1. {tensorfs-0.3.73 → tensorfs-0.3.75}/Cargo.lock +2 -2
  2. {tensorfs-0.3.73 → tensorfs-0.3.75}/Cargo.toml +1 -1
  3. {tensorfs-0.3.73 → tensorfs-0.3.75}/PKG-INFO +1 -1
  4. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/bin/tfs/fetch.rs +2 -3
  5. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/bin/tfs/main.rs +15 -3
  6. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/err.rs +1 -0
  7. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/transport/http.rs +51 -9
  8. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/transport/hub.rs +17 -11
  9. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/transport/mod.rs +1 -1
  10. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/transport/tests.rs +51 -1
  11. tensorfs-0.3.75/crates/tensorfs-core/tests/hub_tls.rs +124 -0
  12. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-py/src/store.rs +3 -3
  13. {tensorfs-0.3.73 → tensorfs-0.3.75}/pyproject.toml +1 -1
  14. {tensorfs-0.3.73 → tensorfs-0.3.75}/python/tensorfs/_ext.pyi +1 -0
  15. {tensorfs-0.3.73 → tensorfs-0.3.75}/python/tensorfs/errors.py +2 -0
  16. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/Cargo.toml +0 -0
  17. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/build.rs +0 -0
  18. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/examples/h3-swiglu-layout.md +0 -0
  19. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/examples/optional-cache-backfill.md +0 -0
  20. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/examples/resident-conversion.md +0 -0
  21. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/examples/resident_conversion_profile.rs +0 -0
  22. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/asset_update.rs +0 -0
  23. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/b64.rs +0 -0
  24. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/bin/tfs/ckpt.rs +0 -0
  25. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/bin/tfs/conform.rs +0 -0
  26. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/bin/tfs/ingest.rs +0 -0
  27. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/bin/tfs/rd.rs +0 -0
  28. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/bin/tfs/repo.rs +0 -0
  29. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/bin/tfs/snap.rs +0 -0
  30. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/bin/tfs/watch.rs +0 -0
  31. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/cache_roots.rs +0 -0
  32. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/canon.rs +0 -0
  33. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/capability.rs +0 -0
  34. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/catalog/lock.rs +0 -0
  35. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/catalog.rs +0 -0
  36. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/cbor.rs +0 -0
  37. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/checkpoint.rs +0 -0
  38. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/checkpoint_root.rs +0 -0
  39. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/corpus.rs +0 -0
  40. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/derived/adoption.rs +0 -0
  41. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/derived/companion_tests.rs +0 -0
  42. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/derived/estimate.rs +0 -0
  43. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/derived/graft_tests.rs +0 -0
  44. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/derived/group_commit_tests.rs +0 -0
  45. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/derived/history_cost_tests.rs +0 -0
  46. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/derived/part_rows_tests.rs +0 -0
  47. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/derived/progress.rs +0 -0
  48. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/derived/resume_tests.rs +0 -0
  49. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/derived/retention.rs +0 -0
  50. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/derived/roots.rs +0 -0
  51. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/derived.rs +0 -0
  52. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/descriptors.rs +0 -0
  53. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/disk.rs +0 -0
  54. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/dtype.rs +0 -0
  55. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/durability.rs +0 -0
  56. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/fetch.rs +0 -0
  57. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/fill.rs +0 -0
  58. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/fit.rs +0 -0
  59. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/gc.rs +0 -0
  60. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/header.rs +0 -0
  61. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/home.rs +0 -0
  62. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/ids.rs +0 -0
  63. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/ingest/carrier.rs +0 -0
  64. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/ingest/convert.rs +0 -0
  65. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/ingest/custody.rs +0 -0
  66. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/ingest/fingerprint.rs +0 -0
  67. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/ingest/gguf.rs +0 -0
  68. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/ingest/h3_lora.rs +0 -0
  69. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/ingest/journal.rs +0 -0
  70. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/ingest/mod.rs +0 -0
  71. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/ingest/narrow.rs +0 -0
  72. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/ingest/preflight.rs +0 -0
  73. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/ingest/routes/sdxl.routes.json +0 -0
  74. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/ingest/routes/sdxl.spec.json +0 -0
  75. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/ingest/routes.rs +0 -0
  76. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/ingest/source.rs +0 -0
  77. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/ingest/stamp.rs +0 -0
  78. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/ingest/transaction.rs +0 -0
  79. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/jcs.rs +0 -0
  80. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/lib.rs +0 -0
  81. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/limits.rs +0 -0
  82. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/machine.rs +0 -0
  83. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/manifest.rs +0 -0
  84. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/meta.rs +0 -0
  85. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/project.rs +0 -0
  86. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/providers.rs +0 -0
  87. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/read.rs +0 -0
  88. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/receipt.rs +0 -0
  89. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/reclaim.rs +0 -0
  90. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/registry.rs +0 -0
  91. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/relation.rs +0 -0
  92. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/repo_cache/identity.rs +0 -0
  93. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/repo_cache.rs +0 -0
  94. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/repository.rs +0 -0
  95. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/sha256.rs +0 -0
  96. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/source_artifact.rs +0 -0
  97. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/spec.rs +0 -0
  98. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/staging.rs +0 -0
  99. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/stats.rs +0 -0
  100. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/storage.rs +0 -0
  101. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/store.rs +0 -0
  102. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/transport/api.rs +0 -0
  103. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/transport/http_reuse_tests.rs +0 -0
  104. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/transport/ledger.rs +0 -0
  105. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/transport/memory.rs +0 -0
  106. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/transport/pace.rs +0 -0
  107. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/transport/policy.rs +0 -0
  108. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/transport/prefix.rs +0 -0
  109. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/transport/pull.rs +0 -0
  110. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/transport/push.rs +0 -0
  111. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/transport/ranged.rs +0 -0
  112. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/transport/speculate.rs +0 -0
  113. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/unsynced.rs +0 -0
  114. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/src/vectors.rs +0 -0
  115. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/additive_fields.rs +0 -0
  116. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/anima_hf_profile.rs +0 -0
  117. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/as_is.rs +0 -0
  118. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/checkpoint_roots.rs +0 -0
  119. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/civitai_sdxl_profile.rs +0 -0
  120. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/fd_budget.rs +0 -0
  121. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/fd_headroom.rs +0 -0
  122. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/fetch_url_progress.rs +0 -0
  123. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/fit.rs +0 -0
  124. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/fixtures/repo_apply/blobs.jsonl +0 -0
  125. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/fixtures/repo_apply/expected_list.jsonl +0 -0
  126. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/fixtures/repo_apply/expected_repository.json +0 -0
  127. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/fixtures/repo_apply/expected_rows.jsonl +0 -0
  128. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/fixtures/repo_apply/header.cbor +0 -0
  129. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/fixtures/repo_apply/manifest.json +0 -0
  130. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/fixtures/repo_apply/mutation.json +0 -0
  131. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/foreign_json.rs +0 -0
  132. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/h3_lora.rs +0 -0
  133. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/h3_swiglu.rs +0 -0
  134. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/home.rs +0 -0
  135. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/import_tree.rs +0 -0
  136. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/instrument_profiles.rs +0 -0
  137. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/liveness.rs +0 -0
  138. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/qwen_image21_profile.rs +0 -0
  139. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/read_plan.rs +0 -0
  140. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/reclaim.rs +0 -0
  141. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/reclaim_run.rs +0 -0
  142. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/repo_cache.rs +0 -0
  143. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/repo_store.rs +0 -0
  144. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/resident_admission.rs +0 -0
  145. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/routed_single_file.rs +0 -0
  146. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/sha256_backends.rs +0 -0
  147. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/sharded_cas.rs +0 -0
  148. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/source_artifacts.rs +0 -0
  149. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/source_download.rs +0 -0
  150. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/source_plan.rs +0 -0
  151. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/source_prefixes.rs +0 -0
  152. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/source_preflight.rs +0 -0
  153. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/staging.rs +0 -0
  154. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/store_boundaries.rs +0 -0
  155. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/tensor_schema.rs +0 -0
  156. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/transfer_memory.rs +0 -0
  157. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/trust_index.rs +0 -0
  158. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/version.rs +0 -0
  159. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-core/tests/write_through.rs +0 -0
  160. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-py/Cargo.toml +0 -0
  161. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-py/src/docs.rs +0 -0
  162. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-py/src/errors.rs +0 -0
  163. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-py/src/ingest.rs +0 -0
  164. {tensorfs-0.3.73 → tensorfs-0.3.75}/crates/tensorfs-py/src/lib.rs +0 -0
  165. {tensorfs-0.3.73 → tensorfs-0.3.75}/python/tensorfs/__init__.py +0 -0
  166. {tensorfs-0.3.73 → tensorfs-0.3.75}/python/tensorfs/_derived_channel.py +0 -0
  167. {tensorfs-0.3.73 → tensorfs-0.3.75}/python/tensorfs/_source_channel.py +0 -0
  168. {tensorfs-0.3.73 → tensorfs-0.3.75}/python/tensorfs/_tensors.py +0 -0
  169. {tensorfs-0.3.73 → tensorfs-0.3.75}/python/tensorfs/derived.py +0 -0
  170. {tensorfs-0.3.73 → tensorfs-0.3.75}/python/tensorfs/py.typed +0 -0
@@ -439,7 +439,7 @@ checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
439
439
 
440
440
  [[package]]
441
441
  name = "tensorfs-core"
442
- version = "0.3.73"
442
+ version = "0.3.75"
443
443
  dependencies = [
444
444
  "fs2",
445
445
  "libc",
@@ -454,7 +454,7 @@ dependencies = [
454
454
 
455
455
  [[package]]
456
456
  name = "tensorfs-py"
457
- version = "0.3.73"
457
+ version = "0.3.75"
458
458
  dependencies = [
459
459
  "pyo3",
460
460
  "tensorfs-core",
@@ -3,5 +3,5 @@ resolver = "2"
3
3
  members = ["crates/tensorfs-core", "crates/tensorfs-py"]
4
4
 
5
5
  [workspace.package]
6
- version = "0.3.73"
6
+ version = "0.3.75"
7
7
  edition = "2021"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tensorfs
3
- Version: 0.3.73
3
+ Version: 0.3.75
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Rust
@@ -192,9 +192,8 @@ fn deadline_of(flags: &Flags) -> Deadline {
192
192
 
193
193
  /// The ONE credential spelling, reaching the child explicitly (tfs-050): `--credential-file
194
194
  /// <path>` or the deliberately-set `TFS_CREDENTIAL` — never argv (world-readable in /proc),
195
- /// never the inherited environment at large. The value is `bearer <token>`, scoped to
196
- /// exactly the named hosts, or empty for anonymous — which is what a rented pod passes,
197
- /// the hub's closure and presign routes taking no credential at all.
195
+ /// never the inherited environment at large. The value is `bearer <token>` or
196
+ /// `worker <id> <token>`, scoped to exactly the named hosts, or empty for anonymous.
198
197
  fn credential_of(
199
198
  flags: &Flags,
200
199
  hosts: Vec<String>,
@@ -39,9 +39,10 @@
39
39
  //! tfs fill <root> <plan> resumable fill: skip only verified objects
40
40
  //!
41
41
  //! The ONE transport (tfs-048/tfs-049/tfs-050). The credential is `--credential-file` or
42
- //! TFS_CREDENTIAL (`bearer <token>`, or empty for anonymous), never bare argv; a
43
- //! URL of `-` arrives on stdin. Flags: --hub <base> --lane --session --streams <n>
44
- //! --streams-start <n> --timeout <s> --allow-hosts a,b,.c --allow-local --max-redirects <n>.
42
+ //! TFS_CREDENTIAL (`bearer <token>`, `worker <id> <token>`, or empty for anonymous), never
43
+ //! bare argv; a URL of `-` arrives on stdin. Flags: --hub <base> --lane --session --streams <n>
44
+ //! --streams-start <n> --timeout <s> --allow-hosts a,b,.c --allow-local --max-redirects <n>
45
+ //! --ca-file <pem> (a private hub's CA, trusted beside the webpki set).
45
46
  //! `--streams` is the most objects in flight (default 128, memory-bounded); the walk starts
46
47
  //! at `--streams-start` (default 16) and doubles while measured goodput follows.
47
48
  //! `tfs fetch` reads and backfills the Store's bound repo cache between the local Store
@@ -202,6 +203,17 @@ fn accept_printed_ids(args: Vec<String>) -> Vec<String> {
202
203
 
203
204
  fn main() -> ExitCode {
204
205
  let (args, flags) = split_flags(std::env::args().skip(1).collect());
206
+ if let Some(path) = flag(&flags, "ca-file") {
207
+ let trusted = fs::read(path)
208
+ .map_err(|e| format!("IO_FAILED: read {path}: {e}"))
209
+ .and_then(|pem| {
210
+ tensorfs_core::transport::trust_roots(&pem).map_err(|r| format!("{r} ({path})"))
211
+ });
212
+ if let Err(refusal) = trusted {
213
+ eprintln!("REFUSED {refusal}");
214
+ return ExitCode::FAILURE;
215
+ }
216
+ }
205
217
  let args = accept_printed_ids(args);
206
218
  let a: Vec<&str> = args.iter().map(|s| s.as_str()).collect();
207
219
  match a.as_slice() {
@@ -189,6 +189,7 @@ codes![
189
189
  REDIRECT_REFUSED,
190
190
  HUB_UNREACHABLE,
191
191
  HUB_REFUSED,
192
+ TLS_UNTRUSTED,
192
193
  REF_NOT_FOUND,
193
194
  CREDENTIAL_REQUIRED,
194
195
  TRANSFER_FAILED,
@@ -30,10 +30,11 @@
30
30
  use crate::err::{refuse, Code, Refusal, Result};
31
31
  use crate::transport::ledger::{Deadline, Ledger};
32
32
  use crate::transport::policy::CheckedUrl;
33
+ use rustls::pki_types::pem::PemObject;
33
34
  use rustls::pki_types::{CertificateDer, ServerName};
34
35
  use std::io::{ErrorKind, Read, Write};
35
36
  use std::net::TcpStream;
36
- use std::sync::{Arc, Mutex};
37
+ use std::sync::{Arc, Mutex, OnceLock};
37
38
  use std::time::{Duration, Instant};
38
39
 
39
40
  const HEAD_MAX_BYTES: usize = 64 * 1024;
@@ -211,13 +212,35 @@ struct Idle {
211
212
  wire: Wire,
212
213
  }
213
214
 
215
+ /// Authorities this process trusts beside the webpki set: a private hub's CA, named by its
216
+ /// caller as a location (`tfs --ca-file`). Set once, before the first exchange.
217
+ static EXTRA_ROOTS: OnceLock<Vec<CertificateDer<'static>>> = OnceLock::new();
218
+
219
+ /// Trust the PEM certificates in `pem` for every client this process builds.
220
+ pub fn trust_roots(pem: &[u8]) -> Result<usize> {
221
+ let roots: Vec<_> = CertificateDer::pem_slice_iter(pem)
222
+ .collect::<std::result::Result<_, _>>()
223
+ .map_err(|e| Refusal {
224
+ code: Code::UNKNOWN_FORMAT,
225
+ detail: format!("not a PEM certificate bundle: {e}"),
226
+ })?;
227
+ let (usable, _) = rustls::RootCertStore::empty().add_parsable_certificates(roots.clone());
228
+ if roots.is_empty() || usable != roots.len() {
229
+ return refuse(Code::UNKNOWN_FORMAT, "holds no usable CA certificate");
230
+ }
231
+ EXTRA_ROOTS.set(roots).map_err(|_| Refusal {
232
+ code: Code::UNKNOWN_FORMAT,
233
+ detail: "this process already chose its trust roots".into(),
234
+ })?;
235
+ Ok(usable)
236
+ }
237
+
214
238
  impl Client {
215
239
  pub fn new() -> Client {
216
- Client::with_extra_roots(&[])
240
+ Client::with_extra_roots(EXTRA_ROOTS.get().map_or(&[], Vec::as_slice))
217
241
  }
218
242
 
219
- /// `extra_roots` exists for tests that stand up a loopback TLS origin under a
220
- /// self-signed authority; production callers pass none and trust the webpki set.
243
+ /// Trusts the webpki set plus `extra_roots`.
221
244
  pub fn with_extra_roots(extra_roots: &[CertificateDer<'static>]) -> Client {
222
245
  let mut roots = rustls::RootCertStore::empty();
223
246
  roots.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
@@ -482,7 +505,9 @@ fn connect(
482
505
  )
483
506
  }
484
507
 
508
+ #[allow(clippy::too_many_arguments)]
485
509
  fn tls_handshake(
510
+ host: &str,
486
511
  sock: &mut TcpStream,
487
512
  conn: &mut rustls::ClientConnection,
488
513
  deadline: Deadline,
@@ -516,10 +541,18 @@ fn tls_handshake(
516
541
  Ok(0) => return refuse(fail, "origin closed the connection mid-handshake"),
517
542
  Ok(_) => {
518
543
  advanced = Instant::now();
519
- conn.process_new_packets().map_err(|e| Refusal {
520
- code: fail,
521
- detail: format!("TLS refused: {e}"),
522
- })?;
544
+ // A certificate or protocol verdict is this client's, and re-asking reaches
545
+ // it again: refused typed, never retried as weather. The alert goes out so
546
+ // the origin logs why.
547
+ if let Err(e) = conn.process_new_packets() {
548
+ let _ = conn.write_tls(sock);
549
+ return refuse(
550
+ Code::TLS_UNTRUSTED,
551
+ format!(
552
+ "{host}: TLS refused: {e}; a private hub names its CA with --ca-file"
553
+ ),
554
+ );
555
+ }
523
556
  }
524
557
  Err(e) if would_block(&e) => {
525
558
  stream_verdict(judge, ledger, advanced, "TLS handshake")?;
@@ -1041,7 +1074,16 @@ pub fn send<'l>(
1041
1074
  })?;
1042
1075
  let mut sock = sock;
1043
1076
  let mut conn = Box::new(conn);
1044
- tls_handshake(&mut sock, &mut conn, deadline, ledger, judge, opened, fail)?;
1077
+ tls_handshake(
1078
+ &checked.host,
1079
+ &mut sock,
1080
+ &mut conn,
1081
+ deadline,
1082
+ ledger,
1083
+ judge,
1084
+ opened,
1085
+ fail,
1086
+ )?;
1045
1087
  Wire::Tls { sock, conn }
1046
1088
  } else {
1047
1089
  Wire::Plain(sock)
@@ -36,9 +36,10 @@
36
36
  //! **The credential arrives as a provider trait, never a credential type**, so one
37
37
  //! implementation serves whatever a caller holds. It is asked per host, so a credential
38
38
  //! stays scoped to the hosts its provider names and cannot leak onto a presigned object
39
- //! host or a redirect target. A rented pod holds nothing at all: the hub's closure and
40
- //! presign routes are PUBLIC (tensorhub owner ruling 2026-09-03, which deleted the signed
41
- //! DownloadDelegation these calls used to present), so the pod fetches as `Anonymous`.
39
+ //! host or a redirect target. Published checkpoints need none; a machine reads its
40
+ //! owner's unpublished checkpoints by presenting its worker capability
41
+ //! (`worker <id> <token>` → `x-cozy-worker-id` + `x-cozy-worker-token`), which the hub
42
+ //! scopes to the machine owner's account.
42
43
 
43
44
  use crate::canon::{self, as_arr, as_obj, as_str, as_uint, Value};
44
45
  use crate::err::{refuse, Code, Refusal, Result};
@@ -103,9 +104,10 @@ impl CredentialProvider for ScopedHeaders {
103
104
  /// The ONE credential spelling every surface passes (tfs-050): exactly one scoped value,
104
105
  /// handed explicitly — a file, one deliberately-set variable — never inherited.
105
106
  ///
106
- /// - `bearer <token>` → `authorization: Bearer <token>`
107
- /// - empty → anonymous, which is what a rented pod uses: the hub's closure and
108
- /// presign routes take no credential.
107
+ /// - `bearer <token>` → `authorization: Bearer <token>`
108
+ /// - `worker <id> <token>` → `x-cozy-worker-id` + `x-cozy-worker-token`: a machine's
109
+ /// worker capability, which the hub's closure and presign read as its owner's grant
110
+ /// - empty → anonymous: published checkpoints only.
109
111
  pub fn credential_from_spec(spec: &str, hosts: Vec<String>) -> Result<ScopedHeaders> {
110
112
  let spec = spec.trim();
111
113
  if spec.is_empty() {
@@ -114,16 +116,20 @@ pub fn credential_from_spec(spec: &str, hosts: Vec<String>) -> Result<ScopedHead
114
116
  headers: Vec::new(),
115
117
  });
116
118
  }
117
- let mut parts = spec.split_whitespace();
118
- let headers = match (parts.next(), parts.next()) {
119
- (Some("bearer"), Some(token)) if parts.next().is_none() => {
119
+ let parts: Vec<&str> = spec.split_whitespace().collect();
120
+ let headers = match parts.as_slice() {
121
+ ["bearer", token] => {
120
122
  vec![("authorization".to_string(), format!("Bearer {token}"))]
121
123
  }
124
+ ["worker", id, token] => vec![
125
+ ("x-cozy-worker-id".to_string(), id.to_string()),
126
+ ("x-cozy-worker-token".to_string(), token.to_string()),
127
+ ],
122
128
  _ => {
123
129
  return refuse(
124
130
  Code::CREDENTIAL_REQUIRED,
125
- "a credential is `bearer <token>` or empty — one scoped value, passed \
126
- explicitly",
131
+ "a credential is `bearer <token>`, `worker <id> <token>` or empty — one \
132
+ scoped value, passed explicitly",
127
133
  )
128
134
  }
129
135
  };
@@ -49,7 +49,7 @@ mod speculate;
49
49
  mod tests;
50
50
 
51
51
  pub use api::{api_get, fetch_prefix, probe_length, Prefix};
52
- pub use http::Client;
52
+ pub use http::{trust_roots, Client};
53
53
  pub use hub::{
54
54
  closure, closure_all, credential_from_spec, presign, Anonymous, Closure, CredentialProvider,
55
55
  HostToken, Presigned, ScopedHeaders,
@@ -3,7 +3,7 @@
3
3
  //! no hub. The ledger tests run at millisecond resolution: the cadence is configuration,
4
4
  //! the RULE under test is production's.
5
5
 
6
- use super::hub::{Anonymous, HostToken};
6
+ use super::hub::{credential_from_spec, Anonymous, HostToken};
7
7
  use super::ledger::{Deadline, Ledger};
8
8
  use super::policy::{self, blocked, SourcePolicy};
9
9
  use super::pull::{absolute_location, fetch_url, pull, ObjectSource, PullRequest};
@@ -2134,6 +2134,56 @@ fn credential_headers_reach_the_hub_and_not_the_object_host() {
2134
2134
  let _ = std::fs::remove_dir_all(root);
2135
2135
  }
2136
2136
 
2137
+ #[test]
2138
+ fn a_worker_capability_reaches_the_hub_calls_as_its_two_headers() {
2139
+ let root = temporary("worker-cred");
2140
+ let store = Store::init(&root).unwrap();
2141
+ let checkpoint = Arc::new(checkpoint(1, 4 * 1024));
2142
+ let checkpoint_for = Arc::clone(&checkpoint);
2143
+ let base_slot: Arc<Mutex<String>> = Arc::default();
2144
+ let dispatch_base = Arc::clone(&base_slot);
2145
+ let dispatch: Dispatch = Arc::new(move |request: &Request| {
2146
+ let base = dispatch_base.lock().unwrap().clone();
2147
+ let machine = request.header("x-cozy-worker-id") == Some("om-machine")
2148
+ && request.header("x-cozy-worker-token") == Some("worker-token");
2149
+ match (request.method.as_str(), request.path.as_str()) {
2150
+ ("POST", _) if !machine => status(
2151
+ 401,
2152
+ br#"{"error":{"code":"worker.unauthorized","message":"m"}}"#,
2153
+ ),
2154
+ ("POST", "/v1/tensorfs/closure") => ok_json(&closure_value(&checkpoint_for, &base)),
2155
+ ("POST", "/v1/tensorfs/presign") => ok_json(&presign_value(&request.body, &base)),
2156
+ ("GET", path) => match checkpoint_for.bodies.get(&path["/obj/".len()..]) {
2157
+ Some(body) => status(200, body),
2158
+ None => status(404, b"absent"),
2159
+ },
2160
+ _ => status(404, b"no route"),
2161
+ }
2162
+ });
2163
+ let origin = origin(dispatch);
2164
+ *base_slot.lock().unwrap() = origin.base.clone();
2165
+ let policy = SourcePolicy::default();
2166
+ let credential =
2167
+ credential_from_spec("worker om-machine worker-token", vec!["127.0.0.1".into()]).unwrap();
2168
+ let mut request = PullRequest::new(&store, &origin.base, "acme/model", &credential, &policy);
2169
+ request.sample_seconds = 0.025;
2170
+ pull(&request).unwrap();
2171
+ let anonymous_root = temporary("worker-cred-anon");
2172
+ let anonymous = Store::init(&anonymous_root).unwrap();
2173
+ let mut refused = PullRequest::new(&anonymous, &origin.base, "acme/model", &Anonymous, &policy);
2174
+ refused.sample_seconds = 0.025;
2175
+ assert!(pull(&refused)
2176
+ .unwrap_err()
2177
+ .detail
2178
+ .contains("worker.unauthorized"));
2179
+ for spec in ["worker om-machine", "worker a b c", "machine a b"] {
2180
+ let refusal = credential_from_spec(spec, vec![]).err().unwrap();
2181
+ assert_eq!(refusal.code, Code::CREDENTIAL_REQUIRED, "{spec}");
2182
+ }
2183
+ let _ = std::fs::remove_dir_all(root);
2184
+ let _ = std::fs::remove_dir_all(anonymous_root);
2185
+ }
2186
+
2137
2187
  // ---------------------------------------------------------------- the predicate
2138
2188
 
2139
2189
  #[test]
@@ -0,0 +1,124 @@
1
+ //! A hub whose certificate this machine does not trust is a verdict, not weather: `tfs fetch`
2
+ //! refuses it typed on the first handshake, and `--ca-file` names the private CA that makes
3
+ //! the same hub reachable.
4
+
5
+ use std::io::{Read, Write};
6
+ use std::net::{SocketAddr, TcpListener, TcpStream};
7
+ use std::process::Command;
8
+ use std::sync::{mpsc, Arc};
9
+
10
+ const ENVELOPE: &str =
11
+ r#"{"error":{"code":"checkpoint_not_found","message":"no such checkpoint"}}"#;
12
+
13
+ /// A loopback hub under a self-signed authority that answers every call it can read with a
14
+ /// typed 404. Every accepted peer is reported before its handshake.
15
+ fn private_hub() -> (u16, String, mpsc::Receiver<SocketAddr>) {
16
+ let key = rcgen::generate_simple_self_signed(vec!["127.0.0.1".into()]).unwrap();
17
+ let cert = rustls::pki_types::CertificateDer::from(key.cert.der().to_vec());
18
+ let private = rustls::pki_types::PrivateKeyDer::try_from(key.key_pair.serialize_der())
19
+ .unwrap()
20
+ .clone_key();
21
+ let config = rustls::ServerConfig::builder_with_provider(Arc::new(
22
+ rustls::crypto::ring::default_provider(),
23
+ ))
24
+ .with_safe_default_protocol_versions()
25
+ .unwrap()
26
+ .with_no_client_auth()
27
+ .with_single_cert(vec![cert], private)
28
+ .unwrap();
29
+ let config = Arc::new(config);
30
+ let listener = TcpListener::bind("127.0.0.1:0").unwrap();
31
+ let port = listener.local_addr().unwrap().port();
32
+ let (peers, accepted) = mpsc::channel();
33
+ std::thread::spawn(move || {
34
+ for socket in listener.incoming() {
35
+ let Ok(socket) = socket else { return };
36
+ let _ = peers.send(socket.peer_addr().unwrap());
37
+ let conn = rustls::ServerConnection::new(Arc::clone(&config)).unwrap();
38
+ let mut stream = rustls::StreamOwned::new(conn, socket);
39
+ let mut head = Vec::new();
40
+ let mut chunk = [0u8; 4096];
41
+ while !head.windows(4).any(|w| w == b"\r\n\r\n") {
42
+ match stream.read(&mut chunk) {
43
+ Ok(n) if n > 0 => head.extend_from_slice(&chunk[..n]),
44
+ _ => break,
45
+ }
46
+ }
47
+ if head.windows(4).any(|w| w == b"\r\n\r\n") {
48
+ let answer = format!(
49
+ "HTTP/1.1 404 Not Found\r\ncontent-type: application/json\r\ncontent-length: {}\r\nconnection: close\r\n\r\n{ENVELOPE}",
50
+ ENVELOPE.len()
51
+ );
52
+ let _ = stream.write_all(answer.as_bytes());
53
+ stream.conn.send_close_notify();
54
+ let _ = stream.flush();
55
+ }
56
+ }
57
+ });
58
+ (port, key.cert.pem(), accepted)
59
+ }
60
+
61
+ /// How many connections reached the hub before this call: a sentinel connection is accepted
62
+ /// after every one queued ahead of it.
63
+ fn connections(port: u16, accepted: &mpsc::Receiver<SocketAddr>) -> usize {
64
+ let sentinel = TcpStream::connect(("127.0.0.1", port)).unwrap();
65
+ let mine = sentinel.local_addr().unwrap();
66
+ accepted.iter().take_while(|peer| *peer != mine).count()
67
+ }
68
+
69
+ fn fetch(root: &std::path::Path, port: u16, extra: &[&str]) -> (bool, String) {
70
+ let out = Command::new(env!("CARGO_BIN_EXE_tfs"))
71
+ .args(["fetch", root.to_str().unwrap(), "proof/model"])
72
+ .args(["--hub", &format!("https://127.0.0.1:{port}")])
73
+ .args(extra)
74
+ .env("TFS_CREDENTIAL", "")
75
+ .output()
76
+ .unwrap();
77
+ (
78
+ out.status.success(),
79
+ String::from_utf8_lossy(&out.stderr).into_owned(),
80
+ )
81
+ }
82
+
83
+ #[test]
84
+ fn an_untrusted_hub_is_refused_once_and_a_named_ca_reaches_it() {
85
+ let dir = std::env::temp_dir().join(format!("tfs-hub-tls-{}", std::process::id()));
86
+ let _ = std::fs::remove_dir_all(&dir);
87
+ std::fs::create_dir_all(&dir).unwrap();
88
+ let root = dir.join("store");
89
+ let init = Command::new(env!("CARGO_BIN_EXE_tfs"))
90
+ .args(["store", "init", root.to_str().unwrap()])
91
+ .output()
92
+ .unwrap();
93
+ assert!(
94
+ init.status.success(),
95
+ "{}",
96
+ String::from_utf8_lossy(&init.stderr)
97
+ );
98
+ let (port, pem, accepted) = private_hub();
99
+
100
+ let (ok, stderr) = fetch(&root, port, &[]);
101
+ assert!(
102
+ !ok && stderr.contains("REFUSED TLS_UNTRUSTED") && stderr.contains("127.0.0.1"),
103
+ "{stderr}"
104
+ );
105
+ assert_eq!(
106
+ connections(port, &accepted),
107
+ 1,
108
+ "an untrusted hub was asked again: {stderr}"
109
+ );
110
+
111
+ let ca = dir.join("hub-ca.pem");
112
+ std::fs::write(&ca, pem).unwrap();
113
+ let (ok, stderr) = fetch(&root, port, &["--ca-file", ca.to_str().unwrap()]);
114
+ assert!(
115
+ !ok && stderr.contains("REFUSED REF_NOT_FOUND") && stderr.contains("checkpoint_not_found"),
116
+ "{stderr}"
117
+ );
118
+
119
+ let garbage = dir.join("garbage.pem");
120
+ std::fs::write(&garbage, "not a certificate").unwrap();
121
+ let (ok, stderr) = fetch(&root, port, &["--ca-file", garbage.to_str().unwrap()]);
122
+ assert!(!ok && stderr.contains("REFUSED UNKNOWN_FORMAT"), "{stderr}");
123
+ let _ = std::fs::remove_dir_all(&dir);
124
+ }
@@ -3590,9 +3590,9 @@ pub fn transfer_streams(wanted: usize) -> usize {
3590
3590
  /// plan against the real store, the 16-way walk presigning `wanted` as it reaches it, and
3591
3591
  /// the completion proof, all in the compiled core.
3592
3592
  ///
3593
- /// `credential` is the one spelling (`bearer <token>`, or empty for anonymous — which is
3594
- /// what a rented pod uses, the hub's closure and presign routes taking no credential),
3595
- /// scoped to the hub's host. `timeout` is the caller's deadline or None for none —
3593
+ /// `credential` is the one spelling (`bearer <token>`, `worker <id> <token>` — a machine's
3594
+ /// worker capability, which reads its owner's unpublished checkpoints — or empty for
3595
+ /// anonymous, published only), scoped to the hub's host. `timeout` is the caller's deadline or None for none —
3596
3596
  /// nothing below invents a number of seconds. `sample_seconds` is the liveness ledger's
3597
3597
  /// RESOLUTION (configuration, never a verdict); leave it defaulted outside tests.
3598
3598
  #[pyfunction]
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "tensorfs"
7
- version = "0.3.73"
7
+ version = "0.3.75"
8
8
  description = "TensorFS — canonical tensor artifact substrate"
9
9
  requires-python = ">=3.12"
10
10
  classifiers = [
@@ -278,6 +278,7 @@ class StoreEra(Refusal): ...
278
278
  class StoreRootAbsent(Refusal): ...
279
279
  class SweepSetIncomplete(Refusal): ...
280
280
  class TensorSchemaMismatch(Refusal): ...
281
+ class TlsUntrusted(Refusal): ...
281
282
  class TotalBytesCap(Refusal): ...
282
283
  class TotalRefsCap(Refusal): ...
283
284
  class TrailingBytes(Refusal): ...
@@ -149,6 +149,7 @@ from ._ext import (
149
149
  StoreRootAbsent,
150
150
  SweepSetIncomplete,
151
151
  TensorSchemaMismatch,
152
+ TlsUntrusted,
152
153
  TotalBytesCap,
153
154
  TotalRefsCap,
154
155
  TrailingBytes,
@@ -306,6 +307,7 @@ __all__ = [
306
307
  "StoreRootAbsent",
307
308
  "SweepSetIncomplete",
308
309
  "TensorSchemaMismatch",
310
+ "TlsUntrusted",
309
311
  "TotalBytesCap",
310
312
  "TotalRefsCap",
311
313
  "TrailingBytes",