deepstrike 0.2.63__tar.gz → 0.2.65__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 (253) hide show
  1. {deepstrike-0.2.63 → deepstrike-0.2.65}/Cargo.lock +6 -6
  2. {deepstrike-0.2.63 → deepstrike-0.2.65}/Cargo.toml +3 -3
  3. {deepstrike-0.2.63 → deepstrike-0.2.65}/PKG-INFO +1 -1
  4. deepstrike-0.2.65/crates/deepstrike-core/src/bin/ds-chain-validator.rs +375 -0
  5. deepstrike-0.2.65/crates/deepstrike-core/src/runtime/chain_validator/mod.rs +3714 -0
  6. deepstrike-0.2.65/crates/deepstrike-core/src/runtime/kernel/wire/crash_point.rs +1029 -0
  7. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire.rs +3 -0
  8. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/request_plan.py +9 -7
  9. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/execution_evidence.py +93 -7
  10. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/runner.py +185 -4
  11. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/session_log.py +33 -0
  12. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/session_repair.py +11 -0
  13. {deepstrike-0.2.63 → deepstrike-0.2.65}/pyproject.toml +1 -1
  14. deepstrike-0.2.63/crates/deepstrike-core/src/bin/ds-chain-validator.rs +0 -204
  15. deepstrike-0.2.63/crates/deepstrike-core/src/runtime/chain_validator/mod.rs +0 -1181
  16. {deepstrike-0.2.63 → deepstrike-0.2.65}/LICENSE +0 -0
  17. {deepstrike-0.2.63 → deepstrike-0.2.65}/README.md +0 -0
  18. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/Cargo.toml +0 -0
  19. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/LICENSE +0 -0
  20. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/benches/kernel_baseline.rs +0 -0
  21. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/benches/wait_index_baseline.rs +0 -0
  22. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/benchmark/mod.rs +0 -0
  23. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/compression.rs +0 -0
  24. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/config.rs +0 -0
  25. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/fault.rs +0 -0
  26. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/manager.rs +0 -0
  27. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/measurement.rs +0 -0
  28. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/mod.rs +0 -0
  29. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/partitions.rs +0 -0
  30. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/policy.rs +0 -0
  31. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/pressure.rs +0 -0
  32. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/renderer.rs +0 -0
  33. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/renewal.rs +0 -0
  34. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/skill_catalog.rs +0 -0
  35. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/summarizer.rs +0 -0
  36. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/task_state.rs +0 -0
  37. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/text.rs +0 -0
  38. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/token_engine.rs +0 -0
  39. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/units.rs +0 -0
  40. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/context/utility.rs +0 -0
  41. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/governance/constraint.rs +0 -0
  42. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/governance/mod.rs +0 -0
  43. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/governance/permission.rs +0 -0
  44. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/governance/pipeline.rs +0 -0
  45. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/governance/quota.rs +0 -0
  46. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/governance/rate_limit.rs +0 -0
  47. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/governance/repeat_fuse.rs +0 -0
  48. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/governance/veto.rs +0 -0
  49. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/harness/eval.rs +0 -0
  50. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/harness/mod.rs +0 -0
  51. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/lexical.rs +0 -0
  52. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/lib.rs +0 -0
  53. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/memory/curator.rs +0 -0
  54. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/memory/durable.rs +0 -0
  55. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/memory/mod.rs +0 -0
  56. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/mm/handle.rs +0 -0
  57. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/mm/memory.rs +0 -0
  58. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/mm/mod.rs +0 -0
  59. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/mm/value.rs +0 -0
  60. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/orchestration/mod.rs +0 -0
  61. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/orchestration/task_graph.rs +0 -0
  62. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/orchestration/tournament.rs +0 -0
  63. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/orchestration/workflow/mod.rs +0 -0
  64. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/orchestration/workflow/run.rs +0 -0
  65. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/proc/mod.rs +0 -0
  66. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/event_log.rs +0 -0
  67. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/observation.rs +0 -0
  68. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/binding.rs +0 -0
  69. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/checkpoint.rs +0 -0
  70. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/command.rs +0 -0
  71. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/config.rs +0 -0
  72. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/driver/continuation.rs +0 -0
  73. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/driver/effects.rs +0 -0
  74. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/driver/events.rs +0 -0
  75. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/driver/planning.rs +0 -0
  76. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/driver/projection.rs +0 -0
  77. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/driver/provider.rs +0 -0
  78. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/driver/syscall.rs +0 -0
  79. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/driver/tests.rs +0 -0
  80. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/driver.rs +0 -0
  81. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/effect.rs +0 -0
  82. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/envelope.rs +0 -0
  83. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/event.rs +0 -0
  84. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/fault.rs +0 -0
  85. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/projection.rs +0 -0
  86. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/record.rs +0 -0
  87. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/restore.rs +0 -0
  88. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/root.rs +0 -0
  89. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/scalar.rs +0 -0
  90. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/syscall.rs +0 -0
  91. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/terminal.rs +0 -0
  92. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/tests.rs +0 -0
  93. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel/wire/transaction.rs +0 -0
  94. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/kernel.rs +0 -0
  95. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/mod.rs +0 -0
  96. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/repair.rs +0 -0
  97. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/replay.rs +0 -0
  98. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/runtime/session.rs +0 -0
  99. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/budget_grant.rs +0 -0
  100. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/cross_operation.rs +0 -0
  101. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/entropy.rs +0 -0
  102. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/mailbox.rs +0 -0
  103. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/milestone.rs +0 -0
  104. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/mod.rs +0 -0
  105. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/policy.rs +0 -0
  106. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/rollback.rs +0 -0
  107. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/runnable.rs +0 -0
  108. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/state_machine/cancellation.rs +0 -0
  109. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/state_machine/capability.rs +0 -0
  110. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/state_machine/eviction.rs +0 -0
  111. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/state_machine/gate.rs +0 -0
  112. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/state_machine/milestone_exec.rs +0 -0
  113. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/state_machine/mod.rs +0 -0
  114. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/state_machine/process.rs +0 -0
  115. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/state_machine/signal.rs +0 -0
  116. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/state_machine/tests.rs +0 -0
  117. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/state_machine/workflow.rs +0 -0
  118. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/tcb.rs +0 -0
  119. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/scheduler/wait_index.rs +0 -0
  120. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/signals/attention.rs +0 -0
  121. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/signals/mod.rs +0 -0
  122. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/signals/queue.rs +0 -0
  123. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/signals/router.rs +0 -0
  124. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/syscall/mod.rs +0 -0
  125. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/agent.rs +0 -0
  126. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/capability.rs +0 -0
  127. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/contract.rs +0 -0
  128. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/durable_content.rs +0 -0
  129. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/error.rs +0 -0
  130. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/message.rs +0 -0
  131. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/milestone.rs +0 -0
  132. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/mod.rs +0 -0
  133. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/policy.rs +0 -0
  134. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/result.rs +0 -0
  135. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/signal.rs +0 -0
  136. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/skill.rs +0 -0
  137. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-core/src/types/task.rs +0 -0
  138. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-py/Cargo.toml +0 -0
  139. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-py/LICENSE +0 -0
  140. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-py/src/lib.rs +0 -0
  141. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-tokenizer/Cargo.toml +0 -0
  142. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-tokenizer/LICENSE +0 -0
  143. {deepstrike-0.2.63 → deepstrike-0.2.65}/crates/deepstrike-tokenizer/src/lib.rs +0 -0
  144. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/__init__.py +0 -0
  145. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/agent.py +0 -0
  146. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/agent_ir.py +0 -0
  147. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/collaboration/__init__.py +0 -0
  148. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/collaboration/contract.py +0 -0
  149. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/collaboration/handoff.py +0 -0
  150. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/collaboration/harness.py +0 -0
  151. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/collaboration/modes.py +0 -0
  152. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/collaboration/pool.py +0 -0
  153. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/governance.py +0 -0
  154. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/harness/__init__.py +0 -0
  155. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/harness/harness.py +0 -0
  156. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/harness/judge.py +0 -0
  157. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/kernel/__init__.py +0 -0
  158. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/kernel/canonical.py +0 -0
  159. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/knowledge/__init__.py +0 -0
  160. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/knowledge/source.py +0 -0
  161. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/memory/__init__.py +0 -0
  162. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/memory/agent.py +0 -0
  163. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/memory/durable.py +0 -0
  164. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/memory/extraction.py +0 -0
  165. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/memory/in_memory_store.py +0 -0
  166. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/memory/protocols.py +0 -0
  167. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/memory/ranking.py +0 -0
  168. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/memory/retention.py +0 -0
  169. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/memory/working.py +0 -0
  170. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/__init__.py +0 -0
  171. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/anthropic.py +0 -0
  172. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/anthropic_adapter.py +0 -0
  173. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/anthropic_compatible.py +0 -0
  174. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/base.py +0 -0
  175. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/capability_router.py +0 -0
  176. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/credentials.py +0 -0
  177. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/embedding.py +0 -0
  178. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/factories.py +0 -0
  179. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/gemini.py +0 -0
  180. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/gemini_adapter.py +0 -0
  181. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/model_catalog.py +0 -0
  182. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/model_registry.py +0 -0
  183. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/ollama.py +0 -0
  184. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/ollama_adapter.py +0 -0
  185. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/openai.py +0 -0
  186. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/openai_chat_adapter.py +0 -0
  187. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/openai_responses.py +0 -0
  188. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/protocol_adapter.py +0 -0
  189. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/provider_error.py +0 -0
  190. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/qwen.py +0 -0
  191. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/replay.py +0 -0
  192. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/replay_validator.py +0 -0
  193. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/runtime_registry.py +0 -0
  194. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/stop_reason.py +0 -0
  195. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/stream.py +0 -0
  196. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/usage.py +0 -0
  197. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/providers/vendor_profiles.py +0 -0
  198. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/__init__.py +0 -0
  199. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/archive.py +0 -0
  200. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/canonical_kernel_step.py +0 -0
  201. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/context_policy.py +0 -0
  202. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/credential_vault.py +0 -0
  203. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/durable_content.py +0 -0
  204. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/eval.py +0 -0
  205. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/event_stream.py +0 -0
  206. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/execution_plane.py +0 -0
  207. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/facade.py +0 -0
  208. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/filtered_plane.py +0 -0
  209. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/kernel_event_log.py +0 -0
  210. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/kernel_journal.py +0 -0
  211. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/kernel_step.py +0 -0
  212. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/loop_driver.py +0 -0
  213. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/mcp_proxy_plane.py +0 -0
  214. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/os_profile.py +0 -0
  215. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/os_snapshot.py +0 -0
  216. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/output_schema.py +0 -0
  217. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/payload_store.py +0 -0
  218. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/process_sandbox_plane.py +0 -0
  219. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/provider_replay.py +0 -0
  220. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/reaction_checkpoint.py +0 -0
  221. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/reactive_session.py +0 -0
  222. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/reducers.py +0 -0
  223. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/reliability.py +0 -0
  224. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/remote_vpc_plane.py +0 -0
  225. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/replay_fixture.py +0 -0
  226. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/replay_provider.py +0 -0
  227. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/replay_sanitize.py +0 -0
  228. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/run_group.py +0 -0
  229. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/sub_agent_orchestrator.py +0 -0
  230. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/turn_policy.py +0 -0
  231. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/workflow_control_flow.py +0 -0
  232. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/workflow_store.py +0 -0
  233. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/runtime/worktree_plane.py +0 -0
  234. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/safety/__init__.py +0 -0
  235. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/safety/permissions.py +0 -0
  236. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/signals/__init__.py +0 -0
  237. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/signals/gateway.py +0 -0
  238. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/signals/scheduled.py +0 -0
  239. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/signals/types.py +0 -0
  240. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/skills/__init__.py +0 -0
  241. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/skills/loader.py +0 -0
  242. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/skills/registry.py +0 -0
  243. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/skills/watcher.py +0 -0
  244. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/tools/__init__.py +0 -0
  245. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/tools/builtin/__init__.py +0 -0
  246. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/tools/builtin/read_file.py +0 -0
  247. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/tools/errors.py +0 -0
  248. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/tools/execution.py +0 -0
  249. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/tools/registry.py +0 -0
  250. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/types/__init__.py +0 -0
  251. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/types/agent.py +0 -0
  252. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/types/content.py +0 -0
  253. {deepstrike-0.2.63 → deepstrike-0.2.65}/deepstrike/types/content_policy.py +0 -0
@@ -254,7 +254,7 @@ dependencies = [
254
254
 
255
255
  [[package]]
256
256
  name = "deepstrike-core"
257
- version = "0.2.63"
257
+ version = "0.2.65"
258
258
  dependencies = [
259
259
  "compact_str",
260
260
  "deepstrike-tokenizer",
@@ -268,7 +268,7 @@ dependencies = [
268
268
 
269
269
  [[package]]
270
270
  name = "deepstrike-node"
271
- version = "0.2.63"
271
+ version = "0.2.65"
272
272
  dependencies = [
273
273
  "compact_str",
274
274
  "deepstrike-core",
@@ -280,7 +280,7 @@ dependencies = [
280
280
 
281
281
  [[package]]
282
282
  name = "deepstrike-py"
283
- version = "0.2.63"
283
+ version = "0.2.65"
284
284
  dependencies = [
285
285
  "compact_str",
286
286
  "deepstrike-core",
@@ -291,7 +291,7 @@ dependencies = [
291
291
 
292
292
  [[package]]
293
293
  name = "deepstrike-sdk"
294
- version = "0.2.63"
294
+ version = "0.2.65"
295
295
  dependencies = [
296
296
  "async-stream",
297
297
  "async-trait",
@@ -327,7 +327,7 @@ dependencies = [
327
327
 
328
328
  [[package]]
329
329
  name = "deepstrike-tokenizer"
330
- version = "0.2.63"
330
+ version = "0.2.65"
331
331
  dependencies = [
332
332
  "pretty_assertions",
333
333
  "tiktoken-rs",
@@ -335,7 +335,7 @@ dependencies = [
335
335
 
336
336
  [[package]]
337
337
  name = "deepstrike-wasm"
338
- version = "0.2.63"
338
+ version = "0.2.65"
339
339
  dependencies = [
340
340
  "compact_str",
341
341
  "deepstrike-core",
@@ -3,13 +3,13 @@ resolver = "2"
3
3
  members = ["crates/deepstrike-core", "crates/deepstrike-tokenizer", "crates/deepstrike-py"]
4
4
 
5
5
  [workspace.package]
6
- version = "0.2.63"
6
+ version = "0.2.65"
7
7
  edition = "2024"
8
8
  repository = "https://github.com/kongusen/deepstrike"
9
9
 
10
10
  [workspace.dependencies]
11
- deepstrike-core = { path = "crates/deepstrike-core", version = "0.2.63" }
12
- deepstrike-tokenizer = { path = "crates/deepstrike-tokenizer", version = "0.2.63" }
11
+ deepstrike-core = { path = "crates/deepstrike-core", version = "0.2.65" }
12
+ deepstrike-tokenizer = { path = "crates/deepstrike-tokenizer", version = "0.2.65" }
13
13
  notify = "6"
14
14
  serde = { version = "1", features = ["derive"] }
15
15
  serde_json = "1"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepstrike
3
- Version: 0.2.63
3
+ Version: 0.2.65
4
4
  Requires-Dist: httpx>=0.27
5
5
  Requires-Dist: pyyaml>=6.0
6
6
  Requires-Dist: anyio>=4.0
@@ -0,0 +1,375 @@
1
+ //! `ds-chain-validator` — the P7-S5 chain validator CLI: rules C1–C4 (batch 1), C6/C8
2
+ //! (batch 3, SessionLog plane), C5 (batch 2, checkpoint plane).
3
+ //!
4
+ //! Host-ops tooling: CI gates and incident triage run the same knife. Input is a journal prefix
5
+ //! — a sequence of kernel record blobs — grouped into per-operation chain segments, each judged
6
+ //! independently. Record bytes are passed through untouched: a verdict is about the bytes the
7
+ //! host durably wrote, never about a re-serialization.
8
+ //!
9
+ //! Exit codes (P7 §3.2): `0` every check green (degraded hops and deferred scope do not count
10
+ //! against green), `1` a violation was proven, `2` the evidence was insufficient (nothing
11
+ //! judgeable, or unparseable blobs and no proven violation). `64` is a usage error.
12
+ //!
13
+ //! Journal input forms, per `--journal` path:
14
+ //! - a directory: every `*.json` file inside (name-sorted), each file one record;
15
+ //! - a file holding one JSON object: one record;
16
+ //! - a file holding a JSON array: its elements, one record each;
17
+ //! - anything else: JSON Lines — one record per non-empty line.
18
+ //!
19
+ //! SessionLog input forms (batch 3), per `--session-log` path:
20
+ //! - a directory: every `*.json`/`*.jsonl` file inside (name-sorted), each file one session
21
+ //! stream — events keep the file's append order, and streams never cross-join;
22
+ //! - a file: one stream — a JSON object (one event), a JSON array (one event per element), or
23
+ //! JSON Lines (one event per non-empty line).
24
+ //!
25
+ //! Checkpoint input forms (batch 2), per `--checkpoint` path — same shapes as the journal:
26
+ //! a directory of `*.json` checkpoints, a JSON object (one checkpoint), a JSON array, or JSON
27
+ //! Lines. A golden-fixture wrapper (a JSON object holding a nested `checkpoint` document
28
+ //! beside its ack/restore metadata) is unwrapped automatically. Without this plane C5 is
29
+ //! deferred, not red; `--strict` arms the re-plan replay.
30
+
31
+ use std::path::{Path, PathBuf};
32
+ use std::process::ExitCode;
33
+
34
+ use deepstrike_core::runtime::chain_validator::{
35
+ ValidationReport, Verdict, validate_journal, validate_with_checkpoint,
36
+ };
37
+
38
+ const USAGE: &str = "Usage: ds-chain-validator [--journal <path>...] [--session-log <path>...] \
39
+ [--checkpoint <path>...] [--strict] [--format human|json]\n\
40
+ \x20 (at least one evidence plane is required)\n\
41
+ \n\
42
+ Validates a kernel journal prefix against P2 §5 rules C1–C5, marking\n\
43
+ degraded evidence per C7. With --session-log, the batch-3 cross-checks\n\
44
+ (C6/C8) join the SessionLog evidence plane against the journal. With\n\
45
+ --checkpoint, the batch-2 rule (C5) anchors each checkpoint against the\n\
46
+ journal: genesis/covered-head/tail digests (C5a) and the launch-token\n\
47
+ ledger (C5b).\n\
48
+ Exit codes: 0 = all green, 1 = violation proven, 2 = evidence insufficient.\n\
49
+ \n\
50
+ --journal <path> record source: directory of *.json records, a JSON\n\
51
+ \x20 object/array file, or a JSONL file (repeatable)\n\
52
+ --session-log <path> session-log source: a directory (each *.json/*.jsonl\n\
53
+ \x20 file is one append-ordered stream) or a single\n\
54
+ \x20 stream file — object/array/JSONL (repeatable)\n\
55
+ --checkpoint <path> checkpoint source: directory of *.json checkpoints,\n\
56
+ \x20 a JSON object/array file, or a JSONL file\n\
57
+ \x20 (repeatable; golden-fixture wrappers holding a\n\
58
+ \x20 nested `checkpoint` are unwrapped). Omit it and\n\
59
+ \x20 C5 is deferred, not red\n\
60
+ --strict with --checkpoint: re-plan the journal prefix from\n\
61
+ \x20 genesis through the covered step and require the\n\
62
+ \x20 re-derived state digest and launch-token ledger to\n\
63
+ \x20 match the checkpoint (costs one full fold)\n\
64
+ --format <mode> human (default) or json";
65
+
66
+ fn main() -> ExitCode {
67
+ let mut journals: Vec<PathBuf> = Vec::new();
68
+ let mut session_logs: Vec<PathBuf> = Vec::new();
69
+ let mut checkpoints: Vec<PathBuf> = Vec::new();
70
+ let mut strict = false;
71
+ let mut format = "human".to_string();
72
+ let mut args = std::env::args().skip(1);
73
+ while let Some(arg) = args.next() {
74
+ match arg.as_str() {
75
+ "--journal" => {
76
+ let Some(path) = args.next() else {
77
+ return usage("--journal requires a path");
78
+ };
79
+ journals.push(PathBuf::from(path));
80
+ }
81
+ "--session-log" => {
82
+ let Some(path) = args.next() else {
83
+ return usage("--session-log requires a path");
84
+ };
85
+ session_logs.push(PathBuf::from(path));
86
+ }
87
+ "--checkpoint" => {
88
+ let Some(path) = args.next() else {
89
+ return usage("--checkpoint requires a path");
90
+ };
91
+ checkpoints.push(PathBuf::from(path));
92
+ }
93
+ "--strict" => strict = true,
94
+ "--format" => {
95
+ let Some(mode) = args.next() else {
96
+ return usage("--format requires human or json");
97
+ };
98
+ if mode != "human" && mode != "json" {
99
+ return usage("--format requires human or json");
100
+ }
101
+ format = mode;
102
+ }
103
+ "--help" | "-h" => {
104
+ println!("{USAGE}");
105
+ return ExitCode::from(0);
106
+ }
107
+ _ => return usage(&format!("unknown argument: {arg}")),
108
+ }
109
+ }
110
+ if journals.is_empty() && session_logs.is_empty() && checkpoints.is_empty() {
111
+ return usage("at least one --journal, --session-log, or --checkpoint path is required");
112
+ }
113
+
114
+ let mut blobs: Vec<Vec<u8>> = Vec::new();
115
+ for path in &journals {
116
+ match read_journal(path, &mut blobs) {
117
+ Ok(count) => eprintln!("read {count} record blob(s) from {}", path.display()),
118
+ Err(message) => {
119
+ eprintln!("ds-chain-validator: {message}");
120
+ return ExitCode::from(2);
121
+ }
122
+ }
123
+ }
124
+
125
+ let mut streams: Vec<Vec<Vec<u8>>> = Vec::new();
126
+ for path in &session_logs {
127
+ let streams_before = streams.len();
128
+ match read_session_log(path, &mut streams) {
129
+ Ok(count) => eprintln!(
130
+ "read {count} session event(s) in {} stream(s) from {}",
131
+ streams.len() - streams_before,
132
+ path.display()
133
+ ),
134
+ Err(message) => {
135
+ eprintln!("ds-chain-validator: {message}");
136
+ return ExitCode::from(2);
137
+ }
138
+ }
139
+ }
140
+
141
+ let mut checkpoint_blobs: Vec<Vec<u8>> = Vec::new();
142
+ for path in &checkpoints {
143
+ match read_checkpoint(path, &mut checkpoint_blobs) {
144
+ Ok(count) => eprintln!("read {count} checkpoint blob(s) from {}", path.display()),
145
+ Err(message) => {
146
+ eprintln!("ds-chain-validator: {message}");
147
+ return ExitCode::from(2);
148
+ }
149
+ }
150
+ }
151
+
152
+ let report = if session_logs.is_empty() && checkpoints.is_empty() {
153
+ validate_journal(&blobs)
154
+ } else {
155
+ validate_with_checkpoint(&blobs, &streams, &checkpoint_blobs, strict)
156
+ };
157
+ match format.as_str() {
158
+ "json" => match serde_json::to_string_pretty(&report) {
159
+ Ok(json) => println!("{json}"),
160
+ Err(error) => {
161
+ eprintln!("ds-chain-validator: could not serialize the report: {error}");
162
+ return ExitCode::from(2);
163
+ }
164
+ },
165
+ _ => print_human(&report),
166
+ }
167
+
168
+ let code = report.exit_code();
169
+ ExitCode::from(u8::try_from(code).unwrap_or(2))
170
+ }
171
+
172
+ fn usage(message: &str) -> ExitCode {
173
+ eprintln!("ds-chain-validator: {message}\n\n{USAGE}");
174
+ ExitCode::from(64)
175
+ }
176
+
177
+ /// Collect record blobs from one journal source. Byte-exactness is the whole game: directory
178
+ /// entries and whole-file objects pass through raw; array elements and JSONL lines are handed
179
+ /// over exactly as found (array elements are re-emitted compactly — safe because the record's
180
+ /// self-digest is computed from its decoded fields, not its input byte layout).
181
+ fn read_journal(path: &Path, blobs: &mut Vec<Vec<u8>>) -> Result<usize, String> {
182
+ let before = blobs.len();
183
+ if path.is_dir() {
184
+ let mut entries: Vec<PathBuf> = std::fs::read_dir(path)
185
+ .map_err(|error| format!("cannot read directory {}: {error}", path.display()))?
186
+ .filter_map(|entry| entry.ok().map(|entry| entry.path()))
187
+ .filter(|entry| {
188
+ entry
189
+ .extension()
190
+ .is_some_and(|extension| extension == "json")
191
+ })
192
+ .collect();
193
+ entries.sort();
194
+ for entry in entries {
195
+ let bytes = std::fs::read(&entry)
196
+ .map_err(|error| format!("cannot read {}: {error}", entry.display()))?;
197
+ blobs.push(bytes);
198
+ }
199
+ return Ok(blobs.len() - before);
200
+ }
201
+ let bytes =
202
+ std::fs::read(path).map_err(|error| format!("cannot read {}: {error}", path.display()))?;
203
+ split_blob_file(&bytes, blobs);
204
+ Ok(blobs.len() - before)
205
+ }
206
+
207
+ /// Collect SessionLog event streams from one session-log source. Unlike the journal plane,
208
+ /// append order within one file is meaningful, so **each file becomes one stream** — for a
209
+ /// directory, every `*.json`/`*.jsonl` file inside (name-sorted); for a single path, the file
210
+ /// itself. Event blobs within a stream preserve the file's order.
211
+ fn read_session_log(path: &Path, streams: &mut Vec<Vec<Vec<u8>>>) -> Result<usize, String> {
212
+ let mut added = 0usize;
213
+ if path.is_dir() {
214
+ let mut entries: Vec<PathBuf> = std::fs::read_dir(path)
215
+ .map_err(|error| format!("cannot read directory {}: {error}", path.display()))?
216
+ .filter_map(|entry| entry.ok().map(|entry| entry.path()))
217
+ .filter(|entry| {
218
+ entry.extension().is_some_and(|extension| {
219
+ extension == "json" || extension == "jsonl"
220
+ })
221
+ })
222
+ .collect();
223
+ entries.sort();
224
+ for entry in entries {
225
+ let bytes = std::fs::read(&entry)
226
+ .map_err(|error| format!("cannot read {}: {error}", entry.display()))?;
227
+ let mut stream = Vec::new();
228
+ split_blob_file(&bytes, &mut stream);
229
+ added += stream.len();
230
+ streams.push(stream);
231
+ }
232
+ return Ok(added);
233
+ }
234
+ let bytes =
235
+ std::fs::read(path).map_err(|error| format!("cannot read {}: {error}", path.display()))?;
236
+ let mut stream = Vec::new();
237
+ split_blob_file(&bytes, &mut stream);
238
+ added += stream.len();
239
+ streams.push(stream);
240
+ Ok(added)
241
+ }
242
+
243
+ /// Collect checkpoint blobs from one checkpoint-plane source — the same shapes the journal
244
+ /// accepts: a directory of `*.json` files (name-sorted), a whole-file JSON object, a JSON
245
+ /// array (one checkpoint per element), or JSON Lines. Bytes pass through untouched, with one
246
+ /// accommodation for the published artifact shape: a blob that parses as a JSON object
247
+ /// carrying a nested `checkpoint` object (the golden-fixture wrapper, which also holds
248
+ /// ack/restore metadata) contributes that nested document instead — re-serialized compactly,
249
+ /// digest-safe because a checkpoint's self-digest is computed from its decoded fields, not
250
+ /// its input byte layout. Every verdict about the bytes belongs to the validator's decoder.
251
+ fn read_checkpoint(path: &Path, blobs: &mut Vec<Vec<u8>>) -> Result<usize, String> {
252
+ let before = blobs.len();
253
+ read_journal(path, blobs)?;
254
+ for blob in &mut blobs[before..] {
255
+ if let Ok(serde_json::Value::Object(map)) =
256
+ serde_json::from_slice::<serde_json::Value>(blob)
257
+ && let Some(nested) = map.get("checkpoint")
258
+ && nested.is_object()
259
+ {
260
+ *blob = serde_json::to_vec(nested).unwrap_or_default();
261
+ }
262
+ }
263
+ Ok(blobs.len() - before)
264
+ }
265
+
266
+ /// Split one file's bytes into blobs: a JSON array yields one blob per element, a single JSON
267
+ /// value yields one blob, anything else parses as JSON Lines. Array elements are re-emitted
268
+ /// compactly — safe for journal records because the record's self-digest is computed from its
269
+ /// decoded fields, not its input byte layout, and safe for SessionLog events because the
270
+ /// session plane is opaque JSON throughout.
271
+ fn split_blob_file(bytes: &[u8], blobs: &mut Vec<Vec<u8>>) {
272
+ match serde_json::from_slice::<serde_json::Value>(bytes) {
273
+ Ok(serde_json::Value::Array(records)) => {
274
+ for record in records {
275
+ blobs.push(serde_json::to_vec(&record).unwrap_or_default());
276
+ }
277
+ }
278
+ Ok(_) => blobs.push(bytes.to_vec()),
279
+ Err(_) => {
280
+ for line in bytes.split(|byte| *byte == b'\n') {
281
+ let line = trim_ascii(line);
282
+ if !line.is_empty() {
283
+ blobs.push(line.to_vec());
284
+ }
285
+ }
286
+ }
287
+ }
288
+ }
289
+
290
+ fn trim_ascii(bytes: &[u8]) -> &[u8] {
291
+ let start = bytes
292
+ .iter()
293
+ .position(|byte| !byte.is_ascii_whitespace())
294
+ .unwrap_or(bytes.len());
295
+ let end = bytes
296
+ .iter()
297
+ .rposition(|byte| !byte.is_ascii_whitespace())
298
+ .map_or(start, |position| position + 1);
299
+ &bytes[start..end]
300
+ }
301
+
302
+ fn print_human(report: &ValidationReport) {
303
+ for segment in &report.segments {
304
+ println!("segment {} ({} hop(s))", segment.operation_id, segment.hops);
305
+ for rule in &segment.rules {
306
+ let label = match rule.verdict {
307
+ Verdict::Pass => "pass",
308
+ Verdict::Fail => "FAIL",
309
+ Verdict::Degraded => "degraded",
310
+ };
311
+ println!(" {} {label}: {}", rule.rule, rule.detail);
312
+ }
313
+ for hop in &segment.degraded_hops {
314
+ println!(
315
+ " degraded hop #{} (step {}): {}",
316
+ hop.ordinal,
317
+ hop.step_seq.map_or("?".to_string(), |seq| seq.to_string()),
318
+ hop.reason,
319
+ );
320
+ }
321
+ }
322
+ if report.unparseable_records > 0 {
323
+ println!(
324
+ "unparseable record blob(s): {} (evidence insufficient, not a violation)",
325
+ report.unparseable_records
326
+ );
327
+ }
328
+ if let Some(events) = report.session_events {
329
+ println!("session-log plane: {events} parseable event(s)");
330
+ }
331
+ if report.unparseable_events > 0 {
332
+ println!(
333
+ "unparseable session event blob(s): {} (evidence insufficient, not a violation)",
334
+ report.unparseable_events
335
+ );
336
+ }
337
+ if let Some(checkpoints) = report.checkpoints {
338
+ println!("checkpoint plane: {checkpoints} parseable checkpoint(s)");
339
+ }
340
+ if report.unparseable_checkpoints > 0 {
341
+ println!(
342
+ "unparseable checkpoint blob(s): {} (evidence insufficient, not a violation)",
343
+ report.unparseable_checkpoints
344
+ );
345
+ }
346
+ for rule in &report.cross_checks {
347
+ let label = match rule.verdict {
348
+ Verdict::Pass => "pass",
349
+ Verdict::Fail => "FAIL",
350
+ Verdict::Degraded => "degraded",
351
+ };
352
+ println!("cross-check {} {label}: {}", rule.rule, rule.detail);
353
+ }
354
+ for rule in &report.checkpoint_checks {
355
+ let label = match rule.verdict {
356
+ Verdict::Pass => "pass",
357
+ Verdict::Fail => "FAIL",
358
+ Verdict::Degraded => "degraded",
359
+ };
360
+ println!("checkpoint-check {} {label}: {}", rule.rule, rule.detail);
361
+ }
362
+ for deferred in &report.deferred {
363
+ println!("deferred: {deferred}");
364
+ }
365
+ let segments = report.segments.len();
366
+ let verdict = match report.exit_code() {
367
+ 0 => "all green",
368
+ 1 => "VIOLATION",
369
+ _ => "evidence insufficient",
370
+ };
371
+ println!(
372
+ "summary: {segments} segment(s), exit {} ({verdict})",
373
+ report.exit_code()
374
+ );
375
+ }