cc-transcript 14.37.2__tar.gz → 14.39.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/PKG-INFO +1 -1
  2. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/query.py +13 -0
  3. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/snapshot_schema/request.schema.json +28 -4
  4. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/snapshot_schema/response.schema.json +28 -0
  5. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/pyproject.toml +1 -1
  6. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/snapshot.rs +176 -2
  7. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/snapshot_prepared_service.rs +53 -18
  8. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/types.rs +2 -0
  9. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/Cargo.lock +0 -0
  10. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/Cargo.toml +0 -0
  11. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/LICENSE +0 -0
  12. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/README.md +0 -0
  13. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/__init__.py +0 -0
  14. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/__init__.pyi +0 -0
  15. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/_native.pyi +0 -0
  16. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/activity.py +0 -0
  17. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/activity_probe.py +0 -0
  18. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/builders.py +0 -0
  19. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/codex.py +0 -0
  20. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/command.py +0 -0
  21. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/context.py +0 -0
  22. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/corrections.py +0 -0
  23. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/cost.py +0 -0
  24. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/decision_store.py +0 -0
  25. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/decisions.py +0 -0
  26. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/discovery.py +0 -0
  27. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/disktruth.py +0 -0
  28. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/evidence.py +0 -0
  29. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/extract/__init__.py +0 -0
  30. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/extract/correct.py +0 -0
  31. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/facts.py +0 -0
  32. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/filterspec.py +0 -0
  33. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/heartbeats.py +0 -0
  34. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/ids.py +0 -0
  35. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/judge/__init__.py +0 -0
  36. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/judge/llm.py +0 -0
  37. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/judge/similar.py +0 -0
  38. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/judge/verdicts.py +0 -0
  39. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/ledger.py +0 -0
  40. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/literals.py +0 -0
  41. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/mining/__init__.py +0 -0
  42. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/mining/candidates.py +0 -0
  43. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/mining/confidence.py +0 -0
  44. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/mining/engine.py +0 -0
  45. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/mining/formats.py +0 -0
  46. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/mining/sampling.py +0 -0
  47. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/mining/signals.py +0 -0
  48. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/mining/sourcekind.py +0 -0
  49. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/mining/spec.py +0 -0
  50. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/mining/store.py +0 -0
  51. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/models.py +0 -0
  52. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/nlp.py +0 -0
  53. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/notifications.py +0 -0
  54. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/parser.py +0 -0
  55. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/py.typed +0 -0
  56. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/render.py +0 -0
  57. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/sentiment/__init__.py +0 -0
  58. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/sentiment/buckets.py +0 -0
  59. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/sentiment/data/afinn-en-165.tsv +0 -0
  60. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/sentiment/data/domain_overrides.tsv +0 -0
  61. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/sentiment/data/en-ewt.udpipe +0 -0
  62. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/sentiment/engine.py +0 -0
  63. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/sentiment/lexicon.py +0 -0
  64. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/sentiment/scorespec.py +0 -0
  65. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/snapshot_schema/config.schema.json +0 -0
  66. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/snapshot_schema/context.schema.json +0 -0
  67. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/snapshot_schema/tool_registry.schema.json +0 -0
  68. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/snapshots.py +0 -0
  69. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/synthetic.py +0 -0
  70. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/tools.py +0 -0
  71. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/cc_transcript/watch.py +0 -0
  72. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/cli/Cargo.toml +0 -0
  73. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/cli/src/commands/blame.rs +0 -0
  74. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/cli/src/commands/corpus.rs +0 -0
  75. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/cli/src/commands/corrections.rs +0 -0
  76. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/cli/src/commands/digest.rs +0 -0
  77. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/cli/src/commands/facts.rs +0 -0
  78. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/cli/src/commands/grep.rs +0 -0
  79. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/cli/src/commands/list.rs +0 -0
  80. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/cli/src/commands/mod.rs +0 -0
  81. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/cli/src/commands/scratchpad.rs +0 -0
  82. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/cli/src/commands/show.rs +0 -0
  83. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/cli/src/commands/slice.rs +0 -0
  84. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/cli/src/commands/stats.rs +0 -0
  85. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/cli/src/commands/watch.rs +0 -0
  86. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/cli/src/lib.rs +0 -0
  87. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/cli/src/output.rs +0 -0
  88. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/cli/src/target.rs +0 -0
  89. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/cli/src/timearg.rs +0 -0
  90. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/Cargo.toml +0 -0
  91. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/benches/parse.rs +0 -0
  92. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/benches/render.rs +0 -0
  93. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/benches/toolcall.rs +0 -0
  94. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/activity.rs +0 -0
  95. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/actor.rs +0 -0
  96. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/blame.rs +0 -0
  97. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/buckets.rs +0 -0
  98. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/codex/discovery.rs +0 -0
  99. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/codex/lower.rs +0 -0
  100. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/codex/mod.rs +0 -0
  101. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/codex/parse.rs +0 -0
  102. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/codex/probe.rs +0 -0
  103. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/codex/protocol.rs +0 -0
  104. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/codex/types.rs +0 -0
  105. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/command.rs +0 -0
  106. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/context.rs +0 -0
  107. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/corrections.rs +0 -0
  108. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/cost.rs +0 -0
  109. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/discovery.rs +0 -0
  110. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/facts.rs +0 -0
  111. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/feedback.rs +0 -0
  112. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/filter.rs +0 -0
  113. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/gateway.rs +0 -0
  114. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/ids.rs +0 -0
  115. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/judge.rs +0 -0
  116. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/lib.rs +0 -0
  117. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/literals/command.rs +0 -0
  118. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/literals/corrections.rs +0 -0
  119. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/literals/feedback.rs +0 -0
  120. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/literals/mining.rs +0 -0
  121. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/literals/mod.rs +0 -0
  122. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/literals/protocol.rs +0 -0
  123. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/notifications.rs +0 -0
  124. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/parse.rs +0 -0
  125. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/protocol.rs +0 -0
  126. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/pystr.rs +0 -0
  127. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/query.rs +0 -0
  128. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/render.rs +0 -0
  129. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/rng.rs +0 -0
  130. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/scan.rs +0 -0
  131. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/scan_checkpoint.rs +0 -0
  132. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/scan_grep.rs +0 -0
  133. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/scan_grep_stream.rs +0 -0
  134. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/scan_grep_stream_tests.rs +0 -0
  135. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/scan_index.rs +0 -0
  136. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/scan_projection.rs +0 -0
  137. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/scan_regressions.rs +0 -0
  138. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/scan_stream.rs +0 -0
  139. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/schema.rs +0 -0
  140. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/snapshot_activity.rs +0 -0
  141. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/snapshot_codec.rs +0 -0
  142. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/snapshot_codex_append.rs +0 -0
  143. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/snapshot_labels.rs +0 -0
  144. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/snapshot_ledger.rs +0 -0
  145. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/snapshot_ledger_tests.rs +0 -0
  146. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/snapshot_memory.rs +0 -0
  147. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/snapshot_owned.rs +0 -0
  148. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/snapshot_prepared.rs +0 -0
  149. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/snapshot_prepared_disk.rs +0 -0
  150. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/snapshot_projection.rs +0 -0
  151. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/snapshot_regressions.rs +0 -0
  152. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/snapshot_root_warm.rs +0 -0
  153. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/snapshot_text.rs +0 -0
  154. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/sqlite.rs +0 -0
  155. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/toolcall.rs +0 -0
  156. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/value.rs +0 -0
  157. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/src/watch.rs +0 -0
  158. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/tests/sonic_arena_model.rs +0 -0
  159. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/core/tests/std_allocation_model.rs +0 -0
  160. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/Cargo.toml +0 -0
  161. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/build.rs +0 -0
  162. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/data/command_prefix_pins.tsv +0 -0
  163. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/actor_bridge.rs +0 -0
  164. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/bin/stub_gen.rs +0 -0
  165. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/codex.rs +0 -0
  166. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/command.rs +0 -0
  167. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/context.rs +0 -0
  168. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/corrections.rs +0 -0
  169. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/discovery.rs +0 -0
  170. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/feedback.rs +0 -0
  171. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/judge.rs +0 -0
  172. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/lexicon.rs +0 -0
  173. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/lib.rs +0 -0
  174. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/mining.rs +0 -0
  175. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/nlp.rs +0 -0
  176. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/python.rs +0 -0
  177. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/render.rs +0 -0
  178. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/score.rs +0 -0
  179. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/snapshot_decode.rs +0 -0
  180. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/snapshots.rs +0 -0
  181. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/sqlite.rs +0 -0
  182. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/toolcall.rs +0 -0
  183. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/views/attachment.rs +0 -0
  184. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/views/blocks.rs +0 -0
  185. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/views/command.rs +0 -0
  186. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/views/convert.rs +0 -0
  187. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/views/dunder.rs +0 -0
  188. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/views/events.rs +0 -0
  189. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/views/meta.rs +0 -0
  190. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/views/mod.rs +0 -0
  191. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/views/print.rs +0 -0
  192. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/views/store.rs +0 -0
  193. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/views/system.rs +0 -0
  194. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/views/toolcall.rs +0 -0
  195. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/views/toolresult.rs +0 -0
  196. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/views/transcript.rs +0 -0
  197. {cc_transcript-14.37.2 → cc_transcript-14.39.0}/rust/crates/py/src/watch.rs +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cc-transcript
3
- Version: 14.37.2
3
+ Version: 14.39.0
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Environment :: Console
6
6
  Classifier: Intended Audience :: Developers
@@ -51,6 +51,7 @@ if TYPE_CHECKING:
51
51
  DEEP_LIFT_BUDGET = 1024 * 1024 * 1024
52
52
  DEEP_LIFT_FENCE = 64
53
53
  IDLE_SECONDS_BEFORE_RELEASE = 900
54
+ SYNTHETIC_MODEL = "<synthetic>"
54
55
 
55
56
  type LiftStamp = tuple[int, int, int, int]
56
57
  type LiftKey = tuple[Path, int, ToolUseId | None]
@@ -542,6 +543,18 @@ class Session:
542
543
  """Every event in the window, in order."""
543
544
  return tuple(event for turn in self.turns for event in turn.events)
544
545
 
546
+ @cached_property
547
+ def model(self) -> str | None:
548
+ """The model behind the window's last non-synthetic assistant event, or ``None`` before the first reply."""
549
+ return next(
550
+ (
551
+ event.model
552
+ for event in reversed(self.events)
553
+ if isinstance(event, AssistantEvent) and event.model != SYNTHETIC_MODEL
554
+ ),
555
+ None,
556
+ )
557
+
545
558
  @cached_property
546
559
  def tool_calls(self) -> ToolCallQuery:
547
560
  """The window's tool calls as a chainable query."""
@@ -1032,6 +1032,20 @@
1032
1032
  "PrepareGraph": {
1033
1033
  "additionalProperties": false,
1034
1034
  "properties": {
1035
+ "active_since_unix_ms": {
1036
+ "anyOf": [
1037
+ {
1038
+ "exclusiveMinimum": 0,
1039
+ "maximum": 9007199254740991,
1040
+ "type": "integer"
1041
+ },
1042
+ {
1043
+ "type": "null"
1044
+ }
1045
+ ],
1046
+ "default": null,
1047
+ "title": "Active Since Unix Ms"
1048
+ },
1035
1049
  "deadline_unix_ms": {
1036
1050
  "exclusiveMinimum": 0,
1037
1051
  "maximum": 9007199254740991,
@@ -1045,7 +1059,6 @@
1045
1059
  "pattern": "^/",
1046
1060
  "type": "string"
1047
1061
  },
1048
- "maxItems": 1024,
1049
1062
  "title": "Direct Paths",
1050
1063
  "type": "array"
1051
1064
  },
@@ -1085,7 +1098,6 @@
1085
1098
  "minLength": 1,
1086
1099
  "type": "string"
1087
1100
  },
1088
- "maxItems": 1024,
1089
1101
  "title": "Thread Ids",
1090
1102
  "type": "array"
1091
1103
  },
@@ -2341,6 +2353,20 @@
2341
2353
  "WarmRegistered": {
2342
2354
  "additionalProperties": false,
2343
2355
  "properties": {
2356
+ "active_since_unix_ms": {
2357
+ "anyOf": [
2358
+ {
2359
+ "exclusiveMinimum": 0,
2360
+ "maximum": 9007199254740991,
2361
+ "type": "integer"
2362
+ },
2363
+ {
2364
+ "type": "null"
2365
+ }
2366
+ ],
2367
+ "default": null,
2368
+ "title": "Active Since Unix Ms"
2369
+ },
2344
2370
  "classifier": {
2345
2371
  "$ref": "#/$defs/Classifier"
2346
2372
  },
@@ -2357,7 +2383,6 @@
2357
2383
  "pattern": "^/",
2358
2384
  "type": "string"
2359
2385
  },
2360
- "maxItems": 1024,
2361
2386
  "title": "Direct Paths",
2362
2387
  "type": "array"
2363
2388
  },
@@ -2416,7 +2441,6 @@
2416
2441
  "minLength": 1,
2417
2442
  "type": "string"
2418
2443
  },
2419
- "maxItems": 1024,
2420
2444
  "title": "Thread Ids",
2421
2445
  "type": "array"
2422
2446
  }
@@ -247,6 +247,19 @@
247
247
  "title": "Lease Expires Unix Ms",
248
248
  "type": "integer"
249
249
  },
250
+ "model": {
251
+ "anyOf": [
252
+ {
253
+ "maxLength": 256,
254
+ "minLength": 1,
255
+ "type": "string"
256
+ },
257
+ {
258
+ "type": "null"
259
+ }
260
+ ],
261
+ "title": "Model"
262
+ },
250
263
  "mtime_ns": {
251
264
  "pattern": "^[0-9]+$",
252
265
  "title": "Mtime Ns",
@@ -293,6 +306,19 @@
293
306
  "minimum": 0,
294
307
  "title": "Window Start",
295
308
  "type": "integer"
309
+ },
310
+ "window_started_unix_ms": {
311
+ "anyOf": [
312
+ {
313
+ "exclusiveMinimum": 0,
314
+ "maximum": 9007199254740991,
315
+ "type": "integer"
316
+ },
317
+ {
318
+ "type": "null"
319
+ }
320
+ ],
321
+ "title": "Window Started Unix Ms"
296
322
  }
297
323
  },
298
324
  "required": [
@@ -308,6 +334,8 @@
308
334
  "parser_version",
309
335
  "source_bytes",
310
336
  "window_start",
337
+ "window_started_unix_ms",
338
+ "model",
311
339
  "committed_bytes",
312
340
  "event_count",
313
341
  "turn_count",
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "cc-transcript"
3
- version = "14.37.2" # informational — releases stamp the version from the git tag
3
+ version = "14.39.0" # informational — releases stamp the version from the git tag
4
4
  description = "Grep every Claude Code session you've ever run."
5
5
  readme = "README.md"
6
6
  license = "PolyForm-Noncommercial-1.0.0"
@@ -30,7 +30,7 @@ use crate::snapshot_memory::{
30
30
  arena_bytes, arena_charge, dom_parse_bound, entry_charge, MemoryCharge, SourceArena,
31
31
  };
32
32
  use crate::snapshot_projection::JSON_LITERAL_OBJECT_CAPACITY;
33
- use crate::types::Entry;
33
+ use crate::types::{Entry, SYNTHETIC_MODEL};
34
34
 
35
35
  pub const SCHEMA: &str = "cc-transcript.snapshot/1";
36
36
  pub const PARSER_VERSION: &str = "cc-transcript.snapshot/1";
@@ -369,6 +369,30 @@ impl TranscriptSnapshot {
369
369
  .collect()
370
370
  }
371
371
 
372
+ pub fn window_started_unix_ms(&self) -> Option<i64> {
373
+ if self.window_start == 0 {
374
+ return None;
375
+ }
376
+ self.chunks
377
+ .iter()
378
+ .flat_map(|chunk| chunk.entries.iter())
379
+ .find_map(Entry::meta)
380
+ .map(|meta| meta.timestamp.timestamp_millis())
381
+ }
382
+
383
+ pub fn model(&self) -> Option<&str> {
384
+ self.chunks
385
+ .iter()
386
+ .rev()
387
+ .flat_map(|chunk| chunk.entries.iter().rev())
388
+ .find_map(|entry| match entry {
389
+ Entry::Assistant(assistant) if assistant.model != SYNTHETIC_MODEL => {
390
+ Some(assistant.model.as_str())
391
+ }
392
+ _ => None,
393
+ })
394
+ }
395
+
372
396
  pub fn entry(&self, position: usize) -> &Entry {
373
397
  let at = self.chunks.partition_point(|chunk| chunk.start <= position) - 1;
374
398
  &self.chunks[at].entries[position - self.chunks[at].start]
@@ -2923,6 +2947,24 @@ fn tail_bytes(request: &Value) -> Result<Option<u64>, SnapshotError> {
2923
2947
  .transpose()
2924
2948
  }
2925
2949
 
2950
+ fn active_since_ns(request: &Value) -> Result<Option<i128>, SnapshotError> {
2951
+ request
2952
+ .get("active_since_unix_ms")
2953
+ .filter(|value| !value.is_null())
2954
+ .map(|value| {
2955
+ value
2956
+ .as_u64()
2957
+ .filter(|since| *since > 0)
2958
+ .map(|since| i128::from(since) * 1_000_000)
2959
+ .ok_or_else(|| invalid("active_since_unix_ms must be a positive integer"))
2960
+ })
2961
+ .transpose()
2962
+ }
2963
+
2964
+ fn active(source: &PreparedSourceRef, since: Option<i128>) -> bool {
2965
+ since.is_none_or(|since| source.stamp.mtime_ns >= since)
2966
+ }
2967
+
2926
2968
  fn io_error(error: std::io::Error) -> SnapshotError {
2927
2969
  let status = match error.kind() {
2928
2970
  std::io::ErrorKind::NotFound => Status::Missing,
@@ -5539,7 +5581,7 @@ impl NativeStore {
5539
5581
  "device": snapshot.stamp.identity.device.to_string(), "inode": snapshot.stamp.identity.inode.to_string(),
5540
5582
  "mtime_ns": snapshot.stamp.mtime_ns.to_string(), "ctime_ns": snapshot.stamp.ctime_ns.to_string(),
5541
5583
  "provider": snapshot.provider.as_str(), "parser_version": PARSER_VERSION,
5542
- "source_bytes": snapshot.stamp.size, "window_start": snapshot.window_start, "committed_bytes": snapshot.committed_bytes,
5584
+ "source_bytes": snapshot.stamp.size, "window_start": snapshot.window_start, "window_started_unix_ms": snapshot.window_started_unix_ms(), "model": snapshot.model(), "committed_bytes": snapshot.committed_bytes,
5543
5585
  "event_count": snapshot.event_count, "turn_count": snapshot.activity.turn_count(),
5544
5586
  "classifier": classifier, "provisional_tail": snapshot.provisional_tail,"lease_expires_unix_ms":expires})
5545
5587
  }
@@ -11988,6 +12030,10 @@ mod tests {
11988
12030
  let response = windowed(&store, &source.path, 4096, &owner);
11989
12031
  let description = &response["data"]["description"];
11990
12032
  assert_eq!(description["window_start"].as_u64(), Some(start));
12033
+ assert_eq!(
12034
+ description["window_started_unix_ms"].as_u64(),
12035
+ Some(1_767_323_045_000)
12036
+ );
11991
12037
  assert_eq!(description["source_bytes"].as_u64(), Some(size));
11992
12038
  assert_eq!(description["committed_bytes"].as_u64(), Some(size));
11993
12039
  assert_eq!(
@@ -12274,6 +12320,37 @@ mod tests {
12274
12320
  );
12275
12321
  }
12276
12322
 
12323
+ #[test]
12324
+ fn acquire_describes_the_latest_non_synthetic_model() {
12325
+ let reply = |uuid: &str, model: &str| {
12326
+ format!(
12327
+ r#"{{"type":"assistant","uuid":"{uuid}","sessionId":"s","timestamp":"2026-01-02T03:04:06Z","message":{{"model":"{model}","content":[{{"type":"text","text":"ok"}}]}}}}"#
12328
+ )
12329
+ };
12330
+ let source = Source::new(&format!(
12331
+ "{}{}\n{}\n{}\n{}",
12332
+ users(0..2),
12333
+ reply("older", "claude-opus-4-7"),
12334
+ reply("newer", "claude-opus-5-5"),
12335
+ reply("error", SYNTHETIC_MODEL),
12336
+ users(2..3)
12337
+ ));
12338
+ let silent = Source::new(&users(0..3));
12339
+ let store = windowed_store();
12340
+ let owner = context("a");
12341
+ let model = |path: &Path| {
12342
+ finish(
12343
+ &store,
12344
+ store.request(&acquire(path), &owner, &Cancellation::default()),
12345
+ &owner,
12346
+ )["data"]["description"]["model"]
12347
+ .clone()
12348
+ };
12349
+
12350
+ assert_eq!(model(&source.path), json!("claude-opus-5-5"));
12351
+ assert_eq!(model(&silent.path), json!(null));
12352
+ }
12353
+
12277
12354
  #[test]
12278
12355
  fn null_tail_bytes_is_a_whole_file_acquire() {
12279
12356
  let source = Source::new(&users(0..200));
@@ -12299,6 +12376,7 @@ mod tests {
12299
12376
  unwindowed["data"]["description"]["window_start"].as_u64(),
12300
12377
  Some(0)
12301
12378
  );
12379
+ assert!(unwindowed["data"]["description"]["window_started_unix_ms"].is_null());
12302
12380
  }
12303
12381
 
12304
12382
  #[test]
@@ -14029,6 +14107,102 @@ mod tests {
14029
14107
  assert_eq!(changed["status"].as_str(), Some("changed"), "{changed:?}");
14030
14108
  }
14031
14109
 
14110
+ #[test]
14111
+ fn registered_graph_admits_only_members_active_since_the_cutoff() {
14112
+ let tool = |name: &str| {
14113
+ format!(
14114
+ r#"{{"type":"assistant","uuid":"{name}","sessionId":"s","timestamp":"2026-01-02T03:04:06Z","message":{{"model":"test","content":[{{"type":"tool_use","id":"{name}","name":"{name}","input":{{}}}}]}}}}"#
14115
+ )
14116
+ };
14117
+ let source = Source::new(&format!("{}\n", user("root")));
14118
+ let stale = std::time::SystemTime::now() - std::time::Duration::from_secs(3600);
14119
+ let ids: Vec<String> = (0..1030).map(|index| format!("thread-{index}")).collect();
14120
+ for id in &ids {
14121
+ let path = source.directory.join(format!("{id}.jsonl"));
14122
+ let body = match id.as_str() {
14123
+ "thread-3" => format!("{}\n{}\n", user(id), tool("Grep")),
14124
+ "thread-7" => format!("{}\n{}\n", user(id), tool("Read")),
14125
+ _ => format!("{}\n", user(id)),
14126
+ };
14127
+ std::fs::write(&path, body).unwrap();
14128
+ if id != "thread-7" {
14129
+ File::options()
14130
+ .write(true)
14131
+ .open(&path)
14132
+ .unwrap()
14133
+ .set_modified(stale)
14134
+ .unwrap();
14135
+ }
14136
+ }
14137
+ let store = store();
14138
+ let owner = context("a");
14139
+ let mut background = owner.clone();
14140
+ background.insert("work_class", json!("background"));
14141
+ let root = finish(
14142
+ &store,
14143
+ store.request(&acquire(&source.path), &owner, &Cancellation::default()),
14144
+ &owner,
14145
+ );
14146
+ let mut template = acquire(&source.path);
14147
+ template["limits"].insert("max_discovery_entries", json!(20_000));
14148
+ let since = now_ms() - 60_000;
14149
+ let warm = || {
14150
+ let mut request = json!({"schema":SCHEMA,"id":"warm","operation":"warm_registered","classifier":{"id":"native","version":"1"},"thread_ids":ids,"roots":[source.directory.to_string_lossy().as_ref()],"direct_paths":[],"start_index":0,"membership_revision":null,"active_since_unix_ms":since,"deadline_unix_ms":template["deadline_unix_ms"],"limits":template["limits"]});
14151
+ for _ in 0..12 {
14152
+ let reply = store.request(&request, &background, &Cancellation::default());
14153
+ assert_eq!(reply["status"].as_str(), Some("ok"), "{reply:?}");
14154
+ if reply["data"]["complete"].as_bool() == Some(true) {
14155
+ return;
14156
+ }
14157
+ request.insert("start_index", reply["data"]["next_index"].clone());
14158
+ request.insert(
14159
+ "membership_revision",
14160
+ reply["data"]["membership_revision"].clone(),
14161
+ );
14162
+ }
14163
+ panic!("registered warming did not complete");
14164
+ };
14165
+ let prepare = json!({"schema":SCHEMA,"id":"prepare","operation":"prepare_graph","view":{"handle":handle(&root),"classifier":{"id":"native","version":"1"},"selectors":[],"attachments":[]},"thread_ids":ids,"roots":[source.directory.to_string_lossy().as_ref()],"direct_paths":[],"active_since_unix_ms":since,"deadline_unix_ms":template["deadline_unix_ms"],"limits":template["limits"]});
14166
+ let has = |graph: &Value, name: &str| {
14167
+ let result = finish_prepared(
14168
+ &store,
14169
+ store.request(&json!({"schema":SCHEMA,"id":"query","operation":"query_graph","handle":graph["data"]["handle"],"selectors":[],"query":{"kind":"has_tool","pattern":name,"subagents":true},"deadline_unix_ms":template["deadline_unix_ms"],"limits":template["limits"]}), &owner, &Cancellation::default()),
14170
+ &owner,
14171
+ );
14172
+ assert_eq!(result["status"].as_str(), Some("ok"), "{result:?}");
14173
+ result["data"]["value"].as_bool().unwrap()
14174
+ };
14175
+ warm();
14176
+ let graph = finish_prepared(
14177
+ &store,
14178
+ store.request(&prepare, &owner, &Cancellation::default()),
14179
+ &owner,
14180
+ );
14181
+ assert_eq!(graph["status"].as_str(), Some("ok"), "{graph:?}");
14182
+ assert!(has(&graph, "Read"));
14183
+ assert!(!has(&graph, "Grep"));
14184
+ std::fs::OpenOptions::new()
14185
+ .append(true)
14186
+ .open(source.directory.join("thread-3.jsonl"))
14187
+ .unwrap()
14188
+ .write_all(format!("{}\n", user("resumed")).as_bytes())
14189
+ .unwrap();
14190
+ let stale_membership = store.request(&prepare, &owner, &Cancellation::default());
14191
+ assert_eq!(
14192
+ stale_membership["status"].as_str(),
14193
+ Some("incomplete"),
14194
+ "{stale_membership:?}"
14195
+ );
14196
+ warm();
14197
+ let resumed = finish_prepared(
14198
+ &store,
14199
+ store.request(&prepare, &owner, &Cancellation::default()),
14200
+ &owner,
14201
+ );
14202
+ assert_eq!(resumed["status"].as_str(), Some("ok"), "{resumed:?}");
14203
+ assert!(has(&resumed, "Grep"));
14204
+ }
14205
+
14032
14206
  #[test]
14033
14207
  fn background_warming_preserves_a_foreground_load_slot() {
14034
14208
  let source = Source::new(&format!("{}\n", user("root")));
@@ -654,6 +654,7 @@ impl NativeStore {
654
654
  "thread_ids": request["thread_ids"],
655
655
  "roots": request["roots"],
656
656
  "direct_paths": request["direct_paths"],
657
+ "active_since_unix_ms": request["active_since_unix_ms"],
657
658
  "registry_generation": context["registry_generation"],
658
659
  "admission": context["admission"],
659
660
  "authority": context["authority"],
@@ -767,13 +768,14 @@ impl NativeStore {
767
768
  .get("roots")
768
769
  .and_then(Value::as_array)
769
770
  .ok_or_else(|| invalid("missing roots"))?;
770
- let direct = request
771
+ request
771
772
  .get("direct_paths")
772
773
  .and_then(Value::as_array)
773
774
  .ok_or_else(|| invalid("missing direct_paths"))?;
774
- if ids.len() > 1024 || roots.len() > 64 || direct.len() > 1024 {
775
+ if roots.len() > 64 {
775
776
  return Err(invalid("prepared registry input exceeds its bound"));
776
777
  }
778
+ let since = active_since_ns(request)?;
777
779
  if !ids.is_empty() {
778
780
  let key = Self::warm_membership_key(request, context)?;
779
781
  let (members, sidechain_dirs, complete) = self
@@ -814,14 +816,20 @@ impl NativeStore {
814
816
  Some(index) => (&members[..index], &members[index + 1..]),
815
817
  None => (&members[..], &members[members.len()..]),
816
818
  };
817
- let others = || before.iter().chain(after);
819
+ let others = || {
820
+ before
821
+ .iter()
822
+ .chain(after)
823
+ .filter(move |source| active(source, since))
824
+ };
825
+ let copied = shared.is_some() || since.is_some();
818
826
  let graph_id = self.token("prepared-graph");
819
827
  let stamps_bytes = (others().count() + 1) * size_of::<(PathBuf, SourceStamp)>()
820
828
  + root.canonical_path.as_os_str().len()
821
829
  + others()
822
830
  .map(|source| source.path.as_os_str().len())
823
831
  .sum::<usize>();
824
- let buffers: usize = if shared.is_some() {
832
+ let buffers: usize = if copied {
825
833
  arc_slice_bytes::<PreparedSourceRef>(others().count())
826
834
  + others()
827
835
  .map(|source| source.path.as_os_str().len())
@@ -845,7 +853,7 @@ impl NativeStore {
845
853
  + stamps_bytes
846
854
  + buffers,
847
855
  )?;
848
- let sources: Arc<[PreparedSourceRef]> = if shared.is_some() {
856
+ let sources: Arc<[PreparedSourceRef]> = if copied {
849
857
  #[cfg(test)]
850
858
  self.registered_sources.fetch_add(1, Ordering::Relaxed);
851
859
  others().cloned().collect()
@@ -1154,7 +1162,26 @@ impl NativeStore {
1154
1162
  if build.seen.contains(&stamp.identity.file()) {
1155
1163
  continue;
1156
1164
  }
1157
- if build.seen.len() >= build.remaining.max_sources {
1165
+ if active_since_ns(&build.request)?.is_some_and(|since| stamp.mtime_ns < since) {
1166
+ self.extend_projection_reservation(
1167
+ reservation,
1168
+ context,
1169
+ set_growth(&build.seen, 1) + canonical.as_os_str().len(),
1170
+ )?;
1171
+ let predicted = (set_capacity_for(&build.seen, 1), build.tasks.capacity());
1172
+ build.seen.insert(stamp.identity.file());
1173
+ build.tasks.push(GraphTask::List {
1174
+ parent: canonical,
1175
+ depth: depth + 1,
1176
+ });
1177
+ assert_eq!(
1178
+ (build.seen.capacity(), build.tasks.capacity()),
1179
+ predicted,
1180
+ "prepared build collections landed off their predicted capacities"
1181
+ );
1182
+ continue;
1183
+ }
1184
+ if build.stamps.len() >= build.remaining.max_sources {
1158
1185
  return Err(SnapshotError::new(
1159
1186
  Status::Incomplete,
1160
1187
  "prepared graph source budget exhausted",
@@ -1363,9 +1390,12 @@ impl NativeStore {
1363
1390
  )?;
1364
1391
  #[cfg(test)]
1365
1392
  self.warm_records.fetch_add(1, Ordering::Relaxed);
1393
+ let since = active_since_ns(request)?;
1366
1394
  let mut located = HashMap::new();
1367
- if !ids.is_empty() {
1368
- let location = json!({"schema":SCHEMA,"id":"warm-registered-locate","operation":"locate","session_ids":ids,"roots":roots,"deadline_unix_ms":remaining.deadline_unix_ms,"limits":remaining.to_json()});
1395
+ for chunk in ids.chunks(1024.min(remaining.max_items)) {
1396
+ let mut bounds = *remaining;
1397
+ bounds.max_sources = chunk.len();
1398
+ let location = json!({"schema":SCHEMA,"id":"warm-registered-locate","operation":"locate","session_ids":chunk,"roots":roots,"deadline_unix_ms":remaining.deadline_unix_ms,"limits":bounds.to_json()});
1369
1399
  let before = usage[17];
1370
1400
  let mut outcome = self.locate(&location, context, cancel, usage)?;
1371
1401
  loop {
@@ -1434,12 +1464,6 @@ impl NativeStore {
1434
1464
  let mut examined = 0usize;
1435
1465
  while examined < members.len() {
1436
1466
  cancel.check(remaining.deadline_unix_ms)?;
1437
- if members.len() > remaining.max_sources {
1438
- return Err(SnapshotError::new(
1439
- Status::Incomplete,
1440
- "registered source bound exhausted",
1441
- ));
1442
- }
1443
1467
  let source = &members[examined];
1444
1468
  let directory = sidechain_directory(
1445
1469
  source
@@ -1522,6 +1546,12 @@ impl NativeStore {
1522
1546
  }
1523
1547
  examined += 1;
1524
1548
  }
1549
+ if members.iter().filter(|member| active(member, since)).count() > remaining.max_sources {
1550
+ return Err(SnapshotError::new(
1551
+ Status::Incomplete,
1552
+ "registered source bound exhausted",
1553
+ ));
1554
+ }
1525
1555
  let mut digest = Sha256::new();
1526
1556
  for source in &members {
1527
1557
  digest.update(source.path.as_os_str().as_encoded_bytes());
@@ -1597,16 +1627,16 @@ impl NativeStore {
1597
1627
  if request["classifier"] != json!({"id":"native","version":"1"}) {
1598
1628
  return Err(invalid("registered warming requires the native classifier"));
1599
1629
  }
1600
- let ids = request["thread_ids"]
1630
+ request["thread_ids"]
1601
1631
  .as_array()
1602
1632
  .ok_or_else(|| invalid("missing registered thread ids"))?;
1603
1633
  let roots = request["roots"]
1604
1634
  .as_array()
1605
1635
  .ok_or_else(|| invalid("missing registered roots"))?;
1606
- let direct = request["direct_paths"]
1636
+ request["direct_paths"]
1607
1637
  .as_array()
1608
1638
  .ok_or_else(|| invalid("missing registered direct paths"))?;
1609
- if ids.len() > 1024 || roots.len() > 64 || direct.len() > 1024 {
1639
+ if roots.len() > 64 {
1610
1640
  return Err(invalid("registered warming input exceeds its bound"));
1611
1641
  }
1612
1642
  let start = number(request, "start_index")?;
@@ -1661,11 +1691,16 @@ impl NativeStore {
1661
1691
  "registered warming membership changed",
1662
1692
  ));
1663
1693
  }
1694
+ let since = active_since_ns(request)?;
1664
1695
  let mut next = start;
1665
1696
  let mut steps = 0usize;
1666
1697
  'warming: while next < members.len() && steps < 8 {
1667
1698
  cancel.check(remaining.deadline_unix_ms)?;
1668
1699
  let source = &members[next];
1700
+ if !active(source, since) {
1701
+ next += 1;
1702
+ continue;
1703
+ }
1669
1704
  let before_read = usage[1];
1670
1705
  let before_events = usage[3];
1671
1706
  let (stamp, mut outcome) = match self.prepared_source(
@@ -1777,7 +1812,7 @@ impl NativeStore {
1777
1812
  "registered warming membership changed",
1778
1813
  ));
1779
1814
  }
1780
- for source in members.iter() {
1815
+ for source in members.iter().filter(|source| active(source, since)) {
1781
1816
  cancel.check(remaining.deadline_unix_ms)?;
1782
1817
  let key = crate::snapshot_prepared_disk::PreparedDiskKey::new(
1783
1818
  source.stamp,
@@ -432,6 +432,8 @@ pub struct AttachmentEntry {
432
432
  pub detail: AttachmentDetail,
433
433
  }
434
434
 
435
+ pub const SYNTHETIC_MODEL: &str = "<synthetic>";
436
+
435
437
  /// One parsed JSONL transcript line. Each line is parsed exactly once into this
436
438
  /// model; Python objects are materialized from it afterwards.
437
439
  #[derive(Debug, serde::Serialize, serde::Deserialize)]
File without changes