tensorfs 0.9.0__tar.gz → 0.9.2__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 (221) hide show
  1. {tensorfs-0.9.0 → tensorfs-0.9.2}/Cargo.lock +3 -3
  2. {tensorfs-0.9.0 → tensorfs-0.9.2}/Cargo.toml +1 -1
  3. {tensorfs-0.9.0 → tensorfs-0.9.2}/PKG-INFO +1 -1
  4. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/ensure.rs +36 -16
  5. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/registry.rs +18 -0
  6. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/transport/download.rs +26 -6
  7. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/unsynced.rs +21 -16
  8. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/conform.rs +50 -0
  9. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/ensure.rs +77 -0
  10. {tensorfs-0.9.0 → tensorfs-0.9.2}/pyproject.toml +1 -1
  11. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/Cargo.toml +0 -0
  12. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/build.rs +0 -0
  13. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/examples/filesystem_parent_death_gate.rs +0 -0
  14. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/examples/h3-swiglu-layout.md +0 -0
  15. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/examples/mine-vectors.rs +0 -0
  16. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/examples/optional-cache-backfill.md +0 -0
  17. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/examples/resident-conversion.md +0 -0
  18. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/examples/resident_conversion_profile.rs +0 -0
  19. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/asset_update.rs +0 -0
  20. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/b64.rs +0 -0
  21. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/bin/tfs/ckpt.rs +0 -0
  22. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/bin/tfs/ensure.rs +0 -0
  23. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/bin/tfs/fetch.rs +0 -0
  24. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/bin/tfs/ingest.rs +0 -0
  25. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/bin/tfs/main.rs +0 -0
  26. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/bin/tfs/repo.rs +0 -0
  27. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/bin/tfs/snap.rs +0 -0
  28. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/bin/tfs/watch.rs +0 -0
  29. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/cache_roots.rs +0 -0
  30. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/canon.rs +0 -0
  31. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/capability.rs +0 -0
  32. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/catalog/lock.rs +0 -0
  33. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/catalog.rs +0 -0
  34. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/cbor.rs +0 -0
  35. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/checkpoint.rs +0 -0
  36. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/checkpoint_root.rs +0 -0
  37. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/corpus.rs +0 -0
  38. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/derived/adoption.rs +0 -0
  39. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/derived/channel.rs +0 -0
  40. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/derived/companion_tests.rs +0 -0
  41. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/derived/estimate.rs +0 -0
  42. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/derived/graft_tests.rs +0 -0
  43. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/derived/group_commit_tests.rs +0 -0
  44. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/derived/history_cost_tests.rs +0 -0
  45. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/derived/next_attempt_tests.rs +0 -0
  46. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/derived/part_rows_tests.rs +0 -0
  47. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/derived/progress.rs +0 -0
  48. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/derived/resume_tests.rs +0 -0
  49. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/derived/retention.rs +0 -0
  50. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/derived/roots.rs +0 -0
  51. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/derived.rs +0 -0
  52. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/descriptors.rs +0 -0
  53. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/disk.rs +0 -0
  54. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/dtype.rs +0 -0
  55. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/durability.rs +0 -0
  56. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/ensure/admission.rs +0 -0
  57. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/ensure/flight.rs +0 -0
  58. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/err.rs +0 -0
  59. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/fetch.rs +0 -0
  60. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/filesystem_identity.rs +0 -0
  61. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/fill.rs +0 -0
  62. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/fit.rs +0 -0
  63. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/gc.rs +0 -0
  64. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/header.rs +0 -0
  65. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/home.rs +0 -0
  66. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/ids.rs +0 -0
  67. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/ingest/carrier.rs +0 -0
  68. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/ingest/convert.rs +0 -0
  69. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/ingest/custody.rs +0 -0
  70. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/ingest/fingerprint.rs +0 -0
  71. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/ingest/h3_lora.rs +0 -0
  72. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/ingest/journal.rs +0 -0
  73. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/ingest/mod.rs +0 -0
  74. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/ingest/narrow.rs +0 -0
  75. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/ingest/preflight.rs +0 -0
  76. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/ingest/routes/anima.routes.json +0 -0
  77. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/ingest/routes/anima.spec.json +0 -0
  78. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/ingest/routes/sdxl.routes.json +0 -0
  79. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/ingest/routes/sdxl.spec.json +0 -0
  80. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/ingest/routes.rs +0 -0
  81. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/ingest/sdxl_lora.rs +0 -0
  82. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/ingest/source.rs +0 -0
  83. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/ingest/stamp.rs +0 -0
  84. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/ingest/transaction.rs +0 -0
  85. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/jcs.rs +0 -0
  86. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/keyed_roots.rs +0 -0
  87. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/lib.rs +0 -0
  88. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/limits.rs +0 -0
  89. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/machine.rs +0 -0
  90. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/manifest.rs +0 -0
  91. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/meta.rs +0 -0
  92. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/object_roots.rs +0 -0
  93. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/origin.rs +0 -0
  94. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/project.rs +0 -0
  95. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/providers.rs +0 -0
  96. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/read.rs +0 -0
  97. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/receipt.rs +0 -0
  98. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/reclaim.rs +0 -0
  99. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/relation.rs +0 -0
  100. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/repo_cache.rs +0 -0
  101. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/repository.rs +0 -0
  102. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/sha256.rs +0 -0
  103. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/source_artifact.rs +0 -0
  104. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/source_model.rs +0 -0
  105. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/spec.rs +0 -0
  106. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/stats.rs +0 -0
  107. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/storage.rs +0 -0
  108. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/store.rs +0 -0
  109. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/transport/api.rs +0 -0
  110. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/transport/credential.rs +0 -0
  111. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/transport/decisions.rs +0 -0
  112. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/transport/dpop.rs +0 -0
  113. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/transport/dpop_tests.rs +0 -0
  114. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/transport/http.rs +0 -0
  115. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/transport/http_reuse_tests.rs +0 -0
  116. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/transport/hub.rs +0 -0
  117. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/transport/ledger.rs +0 -0
  118. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/transport/memory.rs +0 -0
  119. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/transport/mod.rs +0 -0
  120. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/transport/policy.rs +0 -0
  121. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/transport/publish.rs +0 -0
  122. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/transport/pull.rs +0 -0
  123. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/transport/push.rs +0 -0
  124. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/transport/sources.rs +0 -0
  125. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/transport/tests/tail.rs +0 -0
  126. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/transport/tests.rs +0 -0
  127. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/src/vectors.rs +0 -0
  128. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/additive_fields.rs +0 -0
  129. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/anima_hf_profile.rs +0 -0
  130. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/as_is.rs +0 -0
  131. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/catalog_owner_probe.c +0 -0
  132. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/checkpoint_roots.rs +0 -0
  133. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/civitai_anima.rs +0 -0
  134. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/civitai_sdxl_profile.rs +0 -0
  135. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/fd_budget.rs +0 -0
  136. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/fd_headroom.rs +0 -0
  137. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/fetch_faults.rs +0 -0
  138. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/filesystem_parent_death_gate.py +0 -0
  139. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/fit.rs +0 -0
  140. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/fixtures/repo_apply/blobs.jsonl +0 -0
  141. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/fixtures/repo_apply/expected_list.jsonl +0 -0
  142. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/fixtures/repo_apply/expected_repository.json +0 -0
  143. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/fixtures/repo_apply/expected_rows.jsonl +0 -0
  144. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/fixtures/repo_apply/header.cbor +0 -0
  145. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/fixtures/repo_apply/manifest.json +0 -0
  146. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/fixtures/repo_apply/mutation.json +0 -0
  147. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/foreign_json.rs +0 -0
  148. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/h3_lora.rs +0 -0
  149. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/h3_swiglu.rs +0 -0
  150. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/home.rs +0 -0
  151. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/hub_tls.rs +0 -0
  152. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/import_tree.rs +0 -0
  153. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/instrument_profiles.rs +0 -0
  154. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/keyed_roots.rs +0 -0
  155. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/liveness.rs +0 -0
  156. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/owned_store.rs +0 -0
  157. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/qwen_image21_profile.rs +0 -0
  158. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/read_plan.rs +0 -0
  159. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/reclaim.rs +0 -0
  160. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/reclaim_run.rs +0 -0
  161. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/repo_cache.rs +0 -0
  162. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/repo_store.rs +0 -0
  163. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/resident_admission.rs +0 -0
  164. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/routed_single_file.rs +0 -0
  165. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/sdxl_lora.rs +0 -0
  166. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/sharded_cas.rs +0 -0
  167. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/source_artifacts.rs +0 -0
  168. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/source_download.rs +0 -0
  169. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/source_model.rs +0 -0
  170. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/source_plan.rs +0 -0
  171. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/source_prefixes.rs +0 -0
  172. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/source_preflight.rs +0 -0
  173. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/store_boundaries.rs +0 -0
  174. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/tensor_schema.rs +0 -0
  175. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/transfer_memory.rs +0 -0
  176. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/trust_index.rs +0 -0
  177. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/vectors.rs +0 -0
  178. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/version.rs +0 -0
  179. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-core/tests/write_through.rs +0 -0
  180. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-plane/API.md +0 -0
  181. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-plane/Cargo.toml +0 -0
  182. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-plane/src/bin/g1_vmm.rs +0 -0
  183. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-plane/src/bin/g2_overlap.rs +0 -0
  184. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-plane/src/bin/gpu_bench/mod.rs +0 -0
  185. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-plane/src/cuda.rs +0 -0
  186. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-plane/src/cursor.rs +0 -0
  187. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-plane/src/device.rs +0 -0
  188. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-plane/src/faults.rs +0 -0
  189. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-plane/src/host.rs +0 -0
  190. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-plane/src/io.rs +0 -0
  191. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-plane/src/layout.rs +0 -0
  192. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-plane/src/lib.rs +0 -0
  193. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-plane/src/plane.rs +0 -0
  194. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-plane/src/window.rs +0 -0
  195. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-plane/tests/census.rs +0 -0
  196. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-plane/tests/common/mod.rs +0 -0
  197. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-plane/tests/gpu.rs +0 -0
  198. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-plane/tests/host_tier.rs +0 -0
  199. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-plane/tests/layout_identity.rs +0 -0
  200. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-plane/tests/sealed.rs +0 -0
  201. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-plane/tests/window.rs +0 -0
  202. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-py/Cargo.toml +0 -0
  203. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-py/src/docs.rs +0 -0
  204. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-py/src/ensure.rs +0 -0
  205. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-py/src/errors.rs +0 -0
  206. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-py/src/ingest.rs +0 -0
  207. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-py/src/lib.rs +0 -0
  208. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-py/src/plane.rs +0 -0
  209. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-py/src/readplan.rs +0 -0
  210. {tensorfs-0.9.0 → tensorfs-0.9.2}/crates/tensorfs-py/src/store.rs +0 -0
  211. {tensorfs-0.9.0 → tensorfs-0.9.2}/python/tensorfs/__init__.py +0 -0
  212. {tensorfs-0.9.0 → tensorfs-0.9.2}/python/tensorfs/_derived_channel.py +0 -0
  213. {tensorfs-0.9.0 → tensorfs-0.9.2}/python/tensorfs/_ext.pyi +0 -0
  214. {tensorfs-0.9.0 → tensorfs-0.9.2}/python/tensorfs/_source_channel.py +0 -0
  215. {tensorfs-0.9.0 → tensorfs-0.9.2}/python/tensorfs/_tensors.py +0 -0
  216. {tensorfs-0.9.0 → tensorfs-0.9.2}/python/tensorfs/derived.py +0 -0
  217. {tensorfs-0.9.0 → tensorfs-0.9.2}/python/tensorfs/errors.py +0 -0
  218. {tensorfs-0.9.0 → tensorfs-0.9.2}/python/tensorfs/plane.py +0 -0
  219. {tensorfs-0.9.0 → tensorfs-0.9.2}/python/tensorfs/plane.pyi +0 -0
  220. {tensorfs-0.9.0 → tensorfs-0.9.2}/python/tensorfs/py.typed +0 -0
  221. {tensorfs-0.9.0 → tensorfs-0.9.2}/python/tensorfs/records.py +0 -0
@@ -559,7 +559,7 @@ checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
559
559
 
560
560
  [[package]]
561
561
  name = "tensorfs-core"
562
- version = "0.9.0"
562
+ version = "0.9.2"
563
563
  dependencies = [
564
564
  "base64",
565
565
  "fs2",
@@ -580,7 +580,7 @@ dependencies = [
580
580
 
581
581
  [[package]]
582
582
  name = "tensorfs-plane"
583
- version = "0.9.0"
583
+ version = "0.9.2"
584
584
  dependencies = [
585
585
  "libc",
586
586
  "libloading",
@@ -590,7 +590,7 @@ dependencies = [
590
590
 
591
591
  [[package]]
592
592
  name = "tensorfs-py"
593
- version = "0.9.0"
593
+ version = "0.9.2"
594
594
  dependencies = [
595
595
  "pyo3",
596
596
  "tensorfs-core",
@@ -3,5 +3,5 @@ resolver = "2"
3
3
  members = ["crates/tensorfs-core", "crates/tensorfs-plane", "crates/tensorfs-py"]
4
4
 
5
5
  [workspace.package]
6
- version = "0.9.0"
6
+ version = "0.9.2"
7
7
  edition = "2021"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tensorfs
3
- Version: 0.9.0
3
+ Version: 0.9.2
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Rust
@@ -280,13 +280,9 @@ impl Parts {
280
280
  landing = self.landed.wait(landing).unwrap();
281
281
  }
282
282
  };
283
+ let landed = Landed(self, &mine);
283
284
  let pulled = self.pull(request, &mine);
284
- let mut landing = self.landing.lock().unwrap();
285
- for object in &mine {
286
- landing.remove(&object.sha256);
287
- }
288
- self.landed.notify_all();
289
- drop(landing);
285
+ drop(landed);
290
286
  pulled?;
291
287
  }
292
288
  }
@@ -448,7 +444,8 @@ fn land(
448
444
 
449
445
  let stop = (Mutex::new(false), Condvar::new());
450
446
  let pulled = std::thread::scope(|scope| {
451
- scope.spawn(|| {
447
+ // A sampler the container refuses to start leaves the pull running unsampled.
448
+ let _ = std::thread::Builder::new().spawn_scoped(scope, || {
452
449
  let (mut at, mut last) = (Instant::now(), meter.moved.load(Ordering::Relaxed));
453
450
  let mut stopped = stop.0.lock().unwrap();
454
451
  while !*stopped {
@@ -466,10 +463,8 @@ fn land(
466
463
  });
467
464
  }
468
465
  });
469
- let pulled = attempts(request, &store, &closure, &counters, &on_plan, &on_object);
470
- *stop.0.lock().unwrap() = true;
471
- stop.1.notify_all();
472
- pulled
466
+ let _stop = Stop(&stop);
467
+ attempts(request, &store, closure, &counters, &on_plan, &on_object)
473
468
  });
474
469
  let report = pulled?;
475
470
  record.bytes_done = total;
@@ -518,7 +513,8 @@ fn land(
518
513
  fn ticking<T>(every: Duration, tick: &(dyn Fn() + Sync), work: impl FnOnce() -> T) -> T {
519
514
  let stop = (Mutex::new(false), Condvar::new());
520
515
  std::thread::scope(|scope| {
521
- scope.spawn(|| {
516
+ // A ticker the container refuses to start leaves the work running untold.
517
+ let _ = std::thread::Builder::new().spawn_scoped(scope, || {
522
518
  let mut stopped = stop.0.lock().unwrap();
523
519
  loop {
524
520
  stopped = stop.1.wait_timeout(stopped, every).unwrap().0;
@@ -528,13 +524,37 @@ fn ticking<T>(every: Duration, tick: &(dyn Fn() + Sync), work: impl FnOnce() ->
528
524
  tick();
529
525
  }
530
526
  });
531
- let out = work();
532
- *stop.0.lock().unwrap() = true;
533
- stop.1.notify_all();
534
- out
527
+ let _stop = Stop(&stop);
528
+ work()
535
529
  })
536
530
  }
537
531
 
532
+ /// Takes a fetch's objects off the landing set as its pull ends, by return or by unwind alike:
533
+ /// the fetches waiting on them never wait forever.
534
+ struct Landed<'a>(&'a Parts, &'a [ObjectRef]);
535
+
536
+ impl Drop for Landed<'_> {
537
+ fn drop(&mut self) {
538
+ let mut landing = self.0.landing.lock().unwrap_or_else(std::sync::PoisonError::into_inner);
539
+ for object in self.1 {
540
+ landing.remove(&object.sha256);
541
+ }
542
+ self.0.landed.notify_all();
543
+ }
544
+ }
545
+
546
+ /// Stops a sampling thread as its work ends, by return or by unwind alike: a panic in the
547
+ /// work (a thread the container refused) would otherwise leave its scope waiting forever on
548
+ /// a sampler that never stops, and the pull's flight held (2026-10-15).
549
+ struct Stop<'a>(&'a (Mutex<bool>, Condvar));
550
+
551
+ impl Drop for Stop<'_> {
552
+ fn drop(&mut self) {
553
+ *self.0 .0.lock().unwrap_or_else(std::sync::PoisonError::into_inner) = true;
554
+ self.0 .1.notify_all();
555
+ }
556
+ }
557
+
538
558
  /// Pull until done. A pull that failed on the link is re-attempted; one that landed nothing
539
559
  /// waits a sample first. The ensure is `STALLED` only once no object has landed for the
540
560
  /// ledger's own floor: a blip that spent one attempt's asks in milliseconds measured nothing.
@@ -120,6 +120,7 @@ fn mined(name: &str) -> EncodingVectors {
120
120
  }
121
121
  "nvfp4-w4a4" => include_bytes!("../../../vectors/mined/nvfp4-w4a4.json"),
122
122
  "mxfp8" => include_bytes!("../../../vectors/mined/mxfp8.json"),
123
+ "int8-convrot256" => include_bytes!("../../../vectors/mined/int8-convrot256.json"),
123
124
  other => panic!("no mined vector set {other:?}"),
124
125
  };
125
126
  EncodingVectors::parse_fixture(bytes).expect("mined vectors are frozen canonical data")
@@ -266,6 +267,23 @@ pub fn seeds() -> Vec<Seed> {
266
267
  ],
267
268
  Some(mined("mxfp8")),
268
269
  ),
270
+ // int8 W8A8 with ComfyUI's ConvRot: each row is rotated by the orthonormal regular
271
+ // Hadamard H4(x)H4(x)H4(x)H4 per 256 input channels, then quantized per output row.
272
+ // value[i,j] = scale[i] * (data[i] . H)[j] / 16, the integer Hadamard sum times the
273
+ // f32 scale in f32, then the logical cast. Mined from cozy-runtime's own producer.
274
+ seed(
275
+ "int8-convrot256/1",
276
+ float.clone(),
277
+ Some(2),
278
+ vec![
279
+ ("data", role(set(&[Dtype::I8]), Relation::Same)),
280
+ (
281
+ "scale",
282
+ role(set(&[Dtype::F32]), dims(vec![Dim::Axis { axis: 0 }])),
283
+ ),
284
+ ],
285
+ Some(mined("int8-convrot256")),
286
+ ),
269
287
  Seed {
270
288
  alias: "svdq-microscale/1",
271
289
  vectors: None,
@@ -40,7 +40,8 @@ use std::io::Read;
40
40
  use std::os::unix::fs::{FileExt as _, OpenOptionsExt};
41
41
  use std::path::PathBuf;
42
42
  use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering};
43
- use std::sync::{Arc, Condvar, Mutex};
43
+ use std::panic::AssertUnwindSafe;
44
+ use std::sync::{Arc, Condvar, Mutex, PoisonError};
44
45
  use std::time::{Duration, Instant};
45
46
 
46
47
  /// One request's bytes. Measured on a pod at 128 workers: 4, 8 and 16 MiB chunks all move
@@ -302,12 +303,31 @@ impl Download<'_> {
302
303
  landed: AtomicU64::new(0),
303
304
  writers: Writers::new(),
304
305
  };
305
- std::thread::scope(|scope| {
306
- for slot in 0..streams {
307
- let run = &run;
308
- scope.spawn(move || run.work(slot));
306
+ let streams = std::thread::scope(|scope| {
307
+ // A thread the container refuses to start is backpressure, never a panic: the
308
+ // queue runs on the streams that started, and with none this thread is the walk's
309
+ // one stream. A stream that panics ends the walk: its chunk would keep its peers
310
+ // waiting.
311
+ let mut started = 0;
312
+ while started < streams {
313
+ let (run, slot) = (&run, started);
314
+ let spawned = std::thread::Builder::new().spawn_scoped(scope, move || {
315
+ if std::panic::catch_unwind(AssertUnwindSafe(|| run.work(slot))).is_err() {
316
+ let refusal = Refusal { code: Code::IO_FAILED, detail: "a stream panicked".into() };
317
+ run.fail(&mut run.state.lock().unwrap_or_else(PoisonError::into_inner), refusal);
318
+ run.wake.notify_all();
319
+ }
320
+ });
321
+ if spawned.is_err() {
322
+ break;
323
+ }
324
+ started += 1;
325
+ }
326
+ match started {
327
+ 0 => run.work(0),
328
+ _ => run.watch(&mut observer),
309
329
  }
310
- run.watch(&mut observer);
330
+ started.max(1)
311
331
  });
312
332
  if let Some(observer) = observer.as_mut() {
313
333
  observer.moved(run.landed.load(Ordering::Relaxed));
@@ -167,24 +167,29 @@ fn dead(markers: Vec<Found>) -> Vec<(Found, File)> {
167
167
  fn sync_files(paths: &[PathBuf]) -> Result<()> {
168
168
  let next = AtomicUsize::new(0);
169
169
  let failed: Mutex<Option<Refusal>> = Mutex::new(None);
170
- std::thread::scope(|scope| {
171
- for _ in 0..SYNC_THREADS.min(paths.len()) {
172
- scope.spawn(|| {
173
- while let Some(path) = paths.get(next.fetch_add(1, Ordering::Relaxed)) {
174
- match File::open(path).and_then(|file| file.sync_data()) {
175
- Ok(()) => {}
176
- Err(error) if error.kind() == std::io::ErrorKind::NotFound => {}
177
- Err(error) => {
178
- failed
179
- .lock()
180
- .unwrap_or_else(|error| error.into_inner())
181
- .get_or_insert(io(format!("sync {}", path.display()), error));
182
- return;
183
- }
184
- }
170
+ let sync = || {
171
+ while let Some(path) = paths.get(next.fetch_add(1, Ordering::Relaxed)) {
172
+ match File::open(path).and_then(|file| file.sync_data()) {
173
+ Ok(()) => {}
174
+ Err(error) if error.kind() == std::io::ErrorKind::NotFound => {}
175
+ Err(error) => {
176
+ failed
177
+ .lock()
178
+ .unwrap_or_else(|error| error.into_inner())
179
+ .get_or_insert(io(format!("sync {}", path.display()), error));
180
+ return;
185
181
  }
186
- });
182
+ }
183
+ }
184
+ };
185
+ // This thread syncs too, so a thread the container refuses only slows the batch.
186
+ std::thread::scope(|scope| {
187
+ for _ in 1..SYNC_THREADS.min(paths.len()) {
188
+ if std::thread::Builder::new().spawn_scoped(scope, sync).is_err() {
189
+ break;
190
+ }
187
191
  }
192
+ sync();
188
193
  });
189
194
  match failed
190
195
  .into_inner()
@@ -311,6 +311,51 @@ fn nvfp4_inner(c: &Case, swap: bool, skip_global: bool) -> Option<Vec<u8>> {
311
311
  Some(out)
312
312
  }
313
313
 
314
+ /// int8-convrot256: value[i,j] = f32(sum_k data[i,k] * H[k,j]) * scale[i] / 16 over each
315
+ /// 256-group, H = H4(x)H4(x)H4(x)H4 with H4's -1 where the two base-4 digits sum to 3.
316
+ fn int8_convrot256(c: &Case) -> Option<Vec<u8>> {
317
+ int8_convrot_inner(c, false, false)
318
+ }
319
+ fn int8_convrot_unrotated(c: &Case) -> Option<Vec<u8>> {
320
+ int8_convrot_inner(c, true, false)
321
+ }
322
+ fn int8_convrot_scale_by_column(c: &Case) -> Option<Vec<u8>> {
323
+ int8_convrot_inner(c, false, true)
324
+ }
325
+
326
+ fn hadamard_sign(k: usize, j: usize) -> i32 {
327
+ let mut sign = 1;
328
+ for digit in 0..4 {
329
+ if (k >> (2 * digit)) % 4 + (j >> (2 * digit)) % 4 == 3 {
330
+ sign = -sign;
331
+ }
332
+ }
333
+ sign
334
+ }
335
+
336
+ fn int8_convrot_inner(c: &Case, unrotated: bool, wrong_axis: bool) -> Option<Vec<u8>> {
337
+ let d = role(c, "data")?;
338
+ let s = role(c, "scale")?;
339
+ let rows = *c.logical_shape.first()? as usize;
340
+ let cols = *c.logical_shape.get(1)? as usize;
341
+ let mut out = Vec::new();
342
+ for i in 0..rows {
343
+ for j in 0..cols {
344
+ let group = j - j % 256;
345
+ let q = |k: usize| d.bits[i * cols + group + k] as i8 as i32;
346
+ let sum = if unrotated {
347
+ q(j % 256) * 16
348
+ } else {
349
+ (0..256).map(|k| q(k) * hadamard_sign(k, j % 256)).sum()
350
+ };
351
+ let o = if wrong_axis { (j % rows) * 4 } else { i * 4 };
352
+ let sc = f32::from_le_bytes(s.bits[o..o + 4].try_into().ok()?);
353
+ put_logical(c.logical_dtype, sum as f32 * sc * 0.0625, &mut out);
354
+ }
355
+ }
356
+ Some(out)
357
+ }
358
+
314
359
  fn candidates(alias: &str) -> Vec<Candidate> {
315
360
  let mk = |name, wrong, decode| Candidate {
316
361
  name,
@@ -342,6 +387,11 @@ fn candidates(alias: &str) -> Vec<Candidate> {
342
387
  mk("fp8-scaled-scalar:scale-ignored", true, fp8_scaled_no_scale),
343
388
  mk("fp8-scaled-scalar:f32-math", true, fp8_scaled_f32_math),
344
389
  ],
390
+ "int8-convrot256/1" => vec![
391
+ mk("int8-convrot256", false, int8_convrot256),
392
+ mk("int8-convrot256:unrotated", true, int8_convrot_unrotated),
393
+ mk("int8-convrot256:scale-by-column", true, int8_convrot_scale_by_column),
394
+ ],
345
395
  "mxfp8/1" => vec![
346
396
  mk("mxfp8", false, mxfp8),
347
397
  mk("mxfp8:block-16", true, mxfp8_wrong_block),
@@ -977,3 +977,80 @@ fn a_checkpoint_held_in_part_resolves_once_and_pulls_each_object_once() {
977
977
  let foreign = vec![ObjectRef::of(b"not of this checkpoint")];
978
978
  assert_eq!(fetch(&foreign).unwrap_err().code, tensorfs_core::err::Code::NOT_CONTAINED);
979
979
  }
980
+
981
+ /// A pod's container caps its tasks (a vast RTX 5060 Ti: `pids.max` 1280) below the threads
982
+ /// concurrent pulls start. A stream thread the cap refuses is backpressure: each pull lands on
983
+ /// the streams that started, or on its own thread when none did. On 0.9.0 the refusal panicked
984
+ /// past the pull's sampler and `tfs ensure` never returned, holding the manifest's flight
985
+ /// (TensorD 0.5.30 prepare wedge, 2026-10-15).
986
+ #[test]
987
+ fn concurrent_ensures_whose_stream_threads_the_container_refuses_land() {
988
+ const TASKS: u64 = 64;
989
+ let cap = format!("TasksMax={TASKS}");
990
+ let scope = ["systemd-run", "--user", "--scope", "-q", "-p", cap.as_str()];
991
+ let usable = Command::new(scope[0])
992
+ .args(&scope[1..])
993
+ .arg("true")
994
+ .stdout(Stdio::null())
995
+ .stderr(Stdio::null())
996
+ .status()
997
+ .is_ok_and(|status| status.success());
998
+ if !usable {
999
+ eprintln!("SKIPPED: no systemd user manager to create a task-limited cgroup");
1000
+ return;
1001
+ }
1002
+ let dir = temporary("tasks");
1003
+ // Two cold pulls of 251 objects each, in one task-limited cgroup: each asks for a stream
1004
+ // per object.
1005
+ let pulls: Vec<(PathBuf, Arc<Checkpoint>, Hub)> = (0..2u8)
1006
+ .map(|at| {
1007
+ let root = dir.join(format!("store-{at}"));
1008
+ Store::init(&root).unwrap();
1009
+ let checkpoint = Arc::new(checkpoint(251, 4096, 9 + at));
1010
+ let hub = hub(Arc::clone(&checkpoint), None, Duration::ZERO, serve_all());
1011
+ (root, checkpoint, hub)
1012
+ })
1013
+ .collect();
1014
+ let script: Vec<String> = pulls
1015
+ .iter()
1016
+ .enumerate()
1017
+ .map(|(at, (root, _, hub))| {
1018
+ let inner = ensure(root, &hub.base, &[]);
1019
+ let args: Vec<String> = inner.get_args().map(|a| format!("'{}'", a.to_str().unwrap())).collect();
1020
+ format!("{TFS} {} > {}/out-{at} &", args.join(" "), dir.display())
1021
+ })
1022
+ .collect();
1023
+ let mut child = Command::new(scope[0])
1024
+ .args(&scope[1..])
1025
+ .args(["sh", "-c", &format!("{} wait", script.join(" "))])
1026
+ .env("TFS_CREDENTIAL", "")
1027
+ .spawn()
1028
+ .unwrap();
1029
+ // Test harness bound on a wedged pull; the product has no such limit.
1030
+ let until = std::time::Instant::now() + Duration::from_secs(90);
1031
+ while child.try_wait().unwrap().is_none() {
1032
+ if std::time::Instant::now() > until {
1033
+ let _ = child.kill();
1034
+ panic!("the ensures never ended under {cap}");
1035
+ }
1036
+ std::thread::sleep(Duration::from_millis(100));
1037
+ }
1038
+ let mut streams = 0;
1039
+ for (at, (root, checkpoint, _)) in pulls.iter().enumerate() {
1040
+ let stdout = std::fs::read_to_string(dir.join(format!("out-{at}"))).unwrap();
1041
+ let last = stdout.lines().last().map(parse);
1042
+ let ok = last.as_ref().is_some_and(|line| text(line, "event") == "ensure.result");
1043
+ let run = Run { ok, lines: stdout.lines().map(parse).collect(), stdout };
1044
+ assert_result(&run, checkpoint);
1045
+ let log = std::fs::read_to_string(root.join("logs/transport.log")).unwrap();
1046
+ let walk = log.lines().rfind(|line| line.contains(" walk ")).unwrap().to_string();
1047
+ streams += walk
1048
+ .split_whitespace()
1049
+ .find_map(|field| field.strip_prefix("streams="))
1050
+ .unwrap()
1051
+ .parse::<u64>()
1052
+ .unwrap();
1053
+ }
1054
+ assert!(streams < 2 * 251, "the cap refused none of their streams");
1055
+ let _ = std::fs::remove_dir_all(&dir);
1056
+ }
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "tensorfs"
7
- version = "0.9.0"
7
+ version = "0.9.2"
8
8
  description = "TensorFS — canonical tensor artifact substrate"
9
9
  requires-python = ">=3.12"
10
10
  classifiers = [